PageRenderTime 59ms CodeModel.GetById 45ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/rkt_fly_test.go

https://gitlab.com/admin-github-cloud/rkt
Go | 251 lines | 196 code | 33 blank | 22 comment | 39 complexity | 33ccc8c63855188cba7b3964d8261dee MD5 | raw file
  1. // Copyright 2016 The rkt Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // +build fly
  15. package main
  16. import (
  17. "fmt"
  18. "io/ioutil"
  19. "os"
  20. "path"
  21. "path/filepath"
  22. "strings"
  23. "testing"
  24. "github.com/appc/spec/schema"
  25. "github.com/appc/spec/schema/types"
  26. "github.com/coreos/rkt/tests/testutils"
  27. )
  28. func TestFlyNetns(t *testing.T) {
  29. testImageArgs := []string{"--exec=/inspect --print-netns"}
  30. testImage := patchTestACI("rkt-inspect-stage1-fly.aci", testImageArgs...)
  31. defer os.Remove(testImage)
  32. ctx := testutils.NewRktRunCtx()
  33. defer ctx.Cleanup()
  34. cmd := fmt.Sprintf("%s --debug --insecure-options=image run %s", ctx.Cmd(), testImage)
  35. child := spawnOrFail(t, cmd)
  36. ctx.RegisterChild(child)
  37. defer waitOrFail(t, child, 0)
  38. expectedRegex := `NetNS: (net:\[\d+\])`
  39. result, out, err := expectRegexWithOutput(child, expectedRegex)
  40. if err != nil {
  41. t.Fatalf("Error: %v\nOutput: %v", err, out)
  42. }
  43. ns, err := os.Readlink("/proc/self/ns/net")
  44. if err != nil {
  45. t.Fatalf("Cannot evaluate NetNS symlink: %v", err)
  46. }
  47. if nsChanged := ns != result[1]; nsChanged {
  48. t.Fatalf("container left host netns")
  49. }
  50. }
  51. func TestFlyMountCLI(t *testing.T) {
  52. tmpDir := createTempDirOrPanic("rkt-mount-test-")
  53. defer os.RemoveAll(tmpDir)
  54. mountSrcFile := filepath.Join(tmpDir, "hello")
  55. if err := ioutil.WriteFile(mountSrcFile, []byte("world"), 0600); err != nil {
  56. t.Fatalf("Cannot write file: %v", err)
  57. }
  58. testImageArgs := []string{fmt.Sprintf("--exec=/inspect --read-file --file-name %s", mountSrcFile)}
  59. testImage := patchTestACI("rkt-inspect-stage1-fly.aci", testImageArgs...)
  60. defer os.Remove(testImage)
  61. ctx := testutils.NewRktRunCtx()
  62. defer ctx.Cleanup()
  63. testParams := []struct {
  64. mountParam string
  65. expectedExit int
  66. }{
  67. {
  68. fmt.Sprintf(
  69. "--volume=test,kind=host,source=%s --mount volume=test,target=%s",
  70. mountSrcFile, mountSrcFile,
  71. ),
  72. 0,
  73. },
  74. {
  75. fmt.Sprintf(
  76. "--volume=test1,kind=host,source=%s --mount volume=test1,target=%s --volume=test2,kind=host,source=%s --mount volume=test1,target=%s",
  77. mountSrcFile, mountSrcFile,
  78. mountSrcFile, mountSrcFile,
  79. ),
  80. 1, /* TODO: decide on consistency with other stage1s */
  81. },
  82. }
  83. for _, testParam := range testParams {
  84. cmd := fmt.Sprintf("%s --debug --insecure-options=image run %s %s", ctx.Cmd(), testImage, testParam.mountParam)
  85. child := spawnOrFail(t, cmd)
  86. ctx.RegisterChild(child)
  87. waitOrFail(t, child, testParam.expectedExit)
  88. }
  89. }
  90. // TODO: unite this with rkt_run_pod_manifest_test.go
  91. type imagePatch struct {
  92. name string
  93. patches []string
  94. }
  95. const baseAppName = "rkt-inspect"
  96. func verifyHostFile(t *testing.T, tmpdir, filename string, i int, expectedResult string) {
  97. filePath := path.Join(tmpdir, filename)
  98. defer os.Remove(filePath)
  99. // Verify the file is written to host.
  100. if strings.Contains(expectedResult, "host:") {
  101. data, err := ioutil.ReadFile(filePath)
  102. if err != nil {
  103. t.Fatalf("%d: Cannot read the host file: %v", i, err)
  104. }
  105. if string(data) != expectedResult {
  106. t.Fatalf("%d: Expecting %q in the host file, but saw %q", i, expectedResult, data)
  107. }
  108. }
  109. }
  110. func TestFlyMountPodManifest(t *testing.T) {
  111. ctx := testutils.NewRktRunCtx()
  112. defer ctx.Cleanup()
  113. tmpdir := createTempDirOrPanic("rkt-tests.")
  114. defer os.RemoveAll(tmpdir)
  115. tests := []struct {
  116. // [image name]:[image patches]
  117. images []imagePatch
  118. podManifest *schema.PodManifest
  119. expectedExit int
  120. expectedResult string
  121. }{
  122. {
  123. // Simple read after write with volume mounted in a read-only rootfs.
  124. []imagePatch{
  125. {"rkt-test-run-pod-manifest-read-only-rootfs-vol-rw.aci", []string{}},
  126. },
  127. &schema.PodManifest{
  128. Apps: []schema.RuntimeApp{
  129. {
  130. Name: baseAppName,
  131. App: &types.App{
  132. Exec: []string{"/inspect", "--write-file", "--read-file"},
  133. User: "0",
  134. Group: "0",
  135. Environment: []types.EnvironmentVariable{
  136. {"FILE", "/dir1/file"},
  137. {"CONTENT", "host:foo"},
  138. },
  139. MountPoints: []types.MountPoint{
  140. {
  141. Name: "dir1",
  142. Path: "/dir1",
  143. ReadOnly: false,
  144. },
  145. },
  146. },
  147. ReadOnlyRootFS: true,
  148. },
  149. },
  150. Volumes: []types.Volume{
  151. {
  152. Name: "dir1",
  153. Kind: "host",
  154. Source: tmpdir,
  155. },
  156. },
  157. },
  158. 0,
  159. "host:foo",
  160. },
  161. }
  162. for i, tt := range tests {
  163. var hashesToRemove []string
  164. for j, v := range tt.images {
  165. hash, err := patchImportAndFetchHash(v.name, v.patches, t, ctx)
  166. if err != nil {
  167. t.Fatalf("%v", err)
  168. }
  169. hashesToRemove = append(hashesToRemove, hash)
  170. imgName := types.MustACIdentifier(v.name)
  171. imgID, err := types.NewHash(hash)
  172. if err != nil {
  173. t.Fatalf("Cannot generate types.Hash from %v: %v", hash, err)
  174. }
  175. ra := &tt.podManifest.Apps[j]
  176. ra.Image.Name = imgName
  177. ra.Image.ID = *imgID
  178. }
  179. tt.podManifest.ACKind = schema.PodManifestKind
  180. tt.podManifest.ACVersion = schema.AppContainerVersion
  181. manifestFile := generatePodManifestFile(t, tt.podManifest)
  182. defer os.Remove(manifestFile)
  183. // 1. Test 'rkt run'.
  184. runCmd := fmt.Sprintf("%s run --mds-register=false --pod-manifest=%s", ctx.Cmd(), manifestFile)
  185. t.Logf("Running 'run' test #%v", i)
  186. child := spawnOrFail(t, runCmd)
  187. ctx.RegisterChild(child)
  188. if tt.expectedResult != "" {
  189. if _, out, err := expectRegexWithOutput(child, tt.expectedResult); err != nil {
  190. t.Errorf("Expected %q but not found: %v\n%s", tt.expectedResult, err, out)
  191. continue
  192. }
  193. }
  194. waitOrFail(t, child, tt.expectedExit)
  195. verifyHostFile(t, tmpdir, "file", i, tt.expectedResult)
  196. // 2. Test 'rkt prepare' + 'rkt run-prepared'.
  197. rktCmd := fmt.Sprintf("%s --insecure-options=image prepare --pod-manifest=%s",
  198. ctx.Cmd(), manifestFile)
  199. uuid := runRktAndGetUUID(t, rktCmd)
  200. runPreparedCmd := fmt.Sprintf("%s run-prepared --mds-register=false %s", ctx.Cmd(), uuid)
  201. t.Logf("Running 'run-prepared' test #%v", i)
  202. child = spawnOrFail(t, runPreparedCmd)
  203. if tt.expectedResult != "" {
  204. if _, out, err := expectRegexWithOutput(child, tt.expectedResult); err != nil {
  205. t.Errorf("Expected %q but not found: %v\n%s", tt.expectedResult, err, out)
  206. continue
  207. }
  208. }
  209. waitOrFail(t, child, tt.expectedExit)
  210. verifyHostFile(t, tmpdir, "file", i, tt.expectedResult)
  211. // we run the garbage collector and remove the imported images to save
  212. // space
  213. runGC(t, ctx)
  214. for _, h := range hashesToRemove {
  215. removeFromCas(t, ctx, h)
  216. }
  217. }
  218. }