func TestAceValidator(t *testing.T) {
	newStringSet := func(strs ...string) map[string]struct{} {
		m := make(map[string]struct{}, len(strs))
		for _, s := range strs {
			m[s] = struct{}{}
		}
		return m
	}
	expected := []map[string]struct{}{
		newStringSet("prestart"),
		newStringSet("main", "sidekick"),
		// newStringSet("poststop"), // Disabled by caseyc for #2870
	}
	pattern := `ace-validator-(?:main|sidekick)\[\d+\]: ([[:alpha:]]+) OK`

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	if err := ctx.LaunchMDS(); err != nil {
		t.Fatalf("Cannot launch metadata service: %v", err)
	}

	aceMain := testutils.GetValueFromEnvOrPanic("RKT_ACE_MAIN_IMAGE")
	aceSidekick := testutils.GetValueFromEnvOrPanic("RKT_ACE_SIDEKICK_IMAGE")

	rktArgs := fmt.Sprintf("--debug --insecure-options=image run --mds-register --volume database,kind=empty %s %s",
		aceMain, aceSidekick)
	rktCmd := fmt.Sprintf("%s %s", ctx.Cmd(), rktArgs)

	child := spawnOrFail(t, rktCmd)
	defer waitOrFail(t, child, 0)

	out := ""
	for _, set := range expected {
		for len(set) > 0 {
			results, o, err := expectRegexWithOutput(child, pattern)
			out += o
			if err != nil {
				var keys []string
				for k := range set {
					keys = append(keys, fmt.Sprintf("%q", k))
				}
				ex := strings.Join(keys, " or ")
				t.Fatalf("Expected %s, but not found: %v\nOutput: %v", ex, err, out)
			}
			if len(results) != 2 {
				t.Fatalf("Unexpected regex results, expected a whole match and one submatch, got %#v", results)
			}
			aceStage := results[1]
			if _, ok := set[aceStage]; ok {
				t.Logf("Got expected ACE stage %q", aceStage)
				delete(set, aceStage)
			} else {
				t.Logf("Ignoring unknown ACE stage %q", aceStage)
			}
		}
	}
}
Beispiel #2
0
func runServer(t *testing.T, auth taas.Type) *taas.Server {
	actool := testutils.GetValueFromEnvOrPanic("ACTOOL")
	gotool := testutils.GetValueFromEnvOrPanic("GO")
	server, err := taas.NewServerWithPaths(auth, 20, actool, gotool)
	if err != nil {
		t.Fatalf("Could not start server: %v", err)
	}
	go serverHandler(t, server)
	return server
}
Beispiel #3
0
func prepareTestNet(t *testing.T, ctx *testutils.RktRunCtx, nt networkTemplateT) (netdir string) {
	configdir := ctx.LocalDir()
	netdir = filepath.Join(configdir, "net.d")
	err := os.MkdirAll(netdir, 0644)
	if err != nil {
		t.Fatalf("Cannot create netdir: %v", err)
	}
	err = writeNetwork(t, nt, netdir)
	if err != nil {
		t.Fatalf("Cannot write network file: %v", err)
	}

	// If we're proxying the CNI call, then make sure it's in the netdir
	if nt.Type == "cniproxy" {
		dest := filepath.Join(netdir, "cniproxy")
		err := fileutil.CopyRegularFile(testutils.GetValueFromEnvOrPanic("RKT_CNI_PROXY"), dest)
		if err != nil {
			t.Fatalf("Cannot copy cniproxy")
		}
		os.Chmod(dest, 0755)
		if err != nil {
			t.Fatalf("Cannot chmod cniproxy")
		}
	}
	return netdir
}
Beispiel #4
0
func patchACI(inputFileName, newFileName string, args ...string) string {
	var allArgs []string

	actool := testutils.GetValueFromEnvOrPanic("ACTOOL")
	tmpDir := testutils.GetValueFromEnvOrPanic("FUNCTIONAL_TMP")

	imagePath, err := filepath.Abs(filepath.Join(tmpDir, newFileName))
	if err != nil {
		panic(fmt.Sprintf("Cannot create ACI: %v\n", err))
	}
	allArgs = append(allArgs, "patch-manifest")
	allArgs = append(allArgs, "--no-compression")
	allArgs = append(allArgs, "--overwrite")
	allArgs = append(allArgs, args...)
	allArgs = append(allArgs, inputFileName)
	allArgs = append(allArgs, imagePath)

	output, err := exec.Command(actool, allArgs...).CombinedOutput()
	if err != nil {
		panic(fmt.Sprintf("Cannot create ACI: %v: %s\n", err, output))
	}
	return imagePath
}
func generatePodManifestFile(t *testing.T, manifest *schema.PodManifest) string {
	tmpDir := testutils.GetValueFromEnvOrPanic("FUNCTIONAL_TMP")
	f, err := ioutil.TempFile(tmpDir, "rkt-test-manifest-")
	if err != nil {
		t.Fatalf("Cannot create tmp pod manifest: %v", err)
	}

	data, err := json.Marshal(manifest)
	if err != nil {
		t.Fatalf("Cannot marshal pod manifest: %v", err)
	}
	if err := ioutil.WriteFile(f.Name(), data, 0600); err != nil {
		t.Fatalf("Cannot write pod manifest file: %v", err)
	}
	return f.Name()
}
Beispiel #6
0
func newStubStage1Setup(t *testing.T, serverSetup *taas.ServerSetup) *stubStage1Setup {
	ctx := testutils.NewRktRunCtx()
	defer func() {
		if ctx != nil {
			ctx.Cleanup()
		}
	}()

	var server *taas.Server
	stubStage1 := testutils.GetValueFromEnvOrPanic("STUB_STAGE1")
	if serverSetup != nil {
		server = runServer(t, serverSetup)
		defer func() {
			if server != nil {
				server.Close()
			}
		}()
		fileSet := map[string]string{
			filepath.Base(stubStage1): stubStage1,
		}
		if err := server.UpdateFileSet(fileSet); err != nil {
			t.Fatalf("Failed to populate a file list in test aci server: %v", err)
		}
	}

	setup := &stubStage1Setup{
		t:       t,
		ctx:     ctx,
		server:  server,
		name:    "localhost/rkt-stub-stage1",
		version: "0.0.1",
		path:    stubStage1,
	}
	ctx = nil
	server = nil
	return setup
}
// TestImageRender tests 'rkt image render', it will import some existing empty
// image with a dependency on an image with the inspect binary, render it with
// rkt image render and check that the exported image has the /inspect file and
// that its hash matches the original inspect binary hash
func TestImageRender(t *testing.T) {
	baseImage := getInspectImagePath()
	emptyImage := getEmptyImagePath()

	testImageName := "coreos.com/rkt-image-render-test"

	inspectFile := testutils.GetValueFromEnvOrPanic("INSPECT_BINARY")
	inspectHash := getHashOrPanic(inspectFile)

	expectManifest := strings.Replace(manifestRenderTemplate, "IMG_NAME", testImageName, -1)

	tmpDir := createTempDirOrPanic("rkt-TestImageRender-")
	defer os.RemoveAll(tmpDir)

	tmpManifest, err := ioutil.TempFile(tmpDir, "manifest")
	if err != nil {
		panic(fmt.Sprintf("Cannot create temp manifest: %v", err))
	}
	if err := ioutil.WriteFile(tmpManifest.Name(), []byte(expectManifest), 0600); err != nil {
		panic(fmt.Sprintf("Cannot write to temp manifest: %v", err))
	}
	defer os.Remove(tmpManifest.Name())

	testImage := patchACI(emptyImage, "rkt-inspect-image-render.aci", "--manifest", tmpManifest.Name())
	defer os.Remove(testImage)
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	_ = importImageAndFetchHash(t, ctx, "", baseImage)
	testImageShortHash := importImageAndFetchHash(t, ctx, "", testImage)

	tests := []struct {
		image        string
		shouldFind   bool
		expectedHash string
	}{
		{
			testImageName,
			true,
			inspectHash,
		},
		{
			testImageShortHash,
			true,
			inspectHash,
		},
		{
			"sha512-not-existed",
			false,
			"",
		},
		{
			"some~random~aci~name",
			false,
			"",
		},
	}

	for i, tt := range tests {
		outputPath := filepath.Join(tmpDir, fmt.Sprintf("rendered-%d", i))
		runCmd := fmt.Sprintf("%s image render --rootfs-only %s %s", ctx.Cmd(), tt.image, outputPath)
		t.Logf("Running 'image render' test #%v: %v", i, runCmd)
		spawnAndWaitOrFail(t, runCmd, tt.shouldFind)

		if !tt.shouldFind {
			continue
		}

		renderedInspectHash, err := getHash(filepath.Join(outputPath, "inspect"))
		if err != nil {
			t.Fatalf("Cannot get rendered inspect binary's hash")
		}
		if renderedInspectHash != tt.expectedHash {
			t.Fatalf("Expected /inspect hash %q but got %s", tt.expectedHash, renderedInspectHash)
		}
	}
}
Beispiel #8
0
// TestImageExtract tests 'rkt image extract', it will import some existing
// image with the inspect binary, extract it with rkt image extract and check
// that the exported /inspect hash matches the original inspect binary hash
func TestImageExtract(t *testing.T) {
	testImage := getInspectImagePath()
	testImageName := "coreos.com/rkt-inspect"

	inspectFile := testutils.GetValueFromEnvOrPanic("INSPECT_BINARY")
	inspectHash := getHashOrPanic(inspectFile)

	tmpDir := createTempDirOrPanic("rkt-TestImageRender-")
	defer os.RemoveAll(tmpDir)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	testImageShortHash := importImageAndFetchHash(t, ctx, testImage)

	tests := []struct {
		image        string
		shouldFind   bool
		expectedHash string
	}{
		{
			testImageName,
			true,
			inspectHash,
		},
		{
			testImageShortHash,
			true,
			inspectHash,
		},
		{
			"sha512-not-existed",
			false,
			"",
		},
		{
			"some~random~aci~name",
			false,
			"",
		},
	}

	for i, tt := range tests {
		outputPath := filepath.Join(tmpDir, fmt.Sprintf("extracted-%d", i))
		runCmd := fmt.Sprintf("%s image extract --rootfs-only %s %s", ctx.Cmd(), tt.image, outputPath)
		t.Logf("Running 'image extract' test #%v: %v", i, runCmd)
		spawnAndWaitOrFail(t, runCmd, tt.shouldFind)

		if !tt.shouldFind {
			continue
		}

		extractedInspectHash, err := getHash(filepath.Join(outputPath, "inspect"))
		if err != nil {
			t.Fatalf("Cannot get rendered inspect binary's hash")
		}
		if extractedInspectHash != tt.expectedHash {
			t.Fatalf("Expected /inspect hash %q but got %s", tt.expectedHash, extractedInspectHash)
		}
	}
}
Beispiel #9
0
func getInspectImagePath() string {
	return testutils.GetValueFromEnvOrPanic("RKT_INSPECT_IMAGE")
}
Beispiel #10
0
func getEmptyImagePath() string {
	return testutils.GetValueFromEnvOrPanic("RKT_EMPTY_IMAGE")
}
Beispiel #11
0
func TestEnv(t *testing.T) {
	printVarFromManifestImage := patchTestACI("rkt-inspect-print-var-from-manifest.aci", "--exec=/inspect --print-env=VAR_FROM_MANIFEST")
	defer os.Remove(printVarFromManifestImage)
	printVarOtherImage := patchTestACI("rkt-inspect-print-var-other.aci", "--exec=/inspect --print-env=VAR_OTHER")
	defer os.Remove(printVarOtherImage)
	printTermHostImage := patchTestACI("rkt-inspect-print-term-host.aci", "--exec=/inspect --print-env=TERM")
	defer os.Remove(printTermHostImage)
	checkPathImage := patchTestACI("rkt-inspect-check-path.aci", "--exec=/inspect --check-path")
	defer os.Remove(checkPathImage)
	sleepImage := patchTestACI("rkt-inspect-sleep.aci", "--exec=/inspect --read-stdin")
	defer os.Remove(sleepImage)
	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	term := testutils.GetValueFromEnvOrPanic("TERM")
	replacePlaceholders := func(cmd string) string {
		fixed := cmd
		fixed = strings.Replace(fixed, "^RKT_BIN^", ctx.Cmd(), -1)
		fixed = strings.Replace(fixed, "^PRINT_VAR_FROM_MANIFEST^", printVarFromManifestImage, -1)
		fixed = strings.Replace(fixed, "^PRINT_VAR_OTHER^", printVarOtherImage, -1)
		fixed = strings.Replace(fixed, "^PRINT_TERM_HOST^", printTermHostImage, -1)
		fixed = strings.Replace(fixed, "^CHECK_PATH^", checkPathImage, -1)
		fixed = strings.Replace(fixed, "^SLEEP^", sleepImage, -1)
		fixed = strings.Replace(fixed, "^HOST_TERM^", term, -1)
		return fixed
	}
	for i, tt := range envTests {
		// change dynamic variables from expected result
		tt.runExpect = replacePlaceholders(tt.runExpect)

		// 'run' tests
		runCmd := replacePlaceholders(tt.runCmd)
		t.Logf("Running 'run' test #%v", i)
		runRktAndCheckOutput(t, runCmd, tt.runExpect, false)

		// 'enter' tests
		sleepCmd := replacePlaceholders(tt.sleepCmd)
		t.Logf("Running 'enter' test #%v", i)
		child := spawnOrFail(t, sleepCmd)

		if err := expectWithOutput(child, "Enter text:"); err != nil {
			t.Fatalf("Waited for the prompt but not found #%v: %v", i, err)
		}

		enterCmd := replacePlaceholders(tt.enterCmd)
		t.Logf("Running 'enter' test #%v", i)
		enterChild := spawnOrFail(t, enterCmd)

		if err := expectWithOutput(enterChild, tt.runExpect); err != nil {
			t.Fatalf("Expected %q but not found: %v", tt.runExpect, err)
		}

		waitOrFail(t, enterChild, 0)

		if err := child.SendLine("Bye"); err != nil {
			t.Fatalf("rkt couldn't write to the container: %v", err)
		}
		if err := expectWithOutput(child, "Received text: Bye"); err != nil {
			t.Fatalf("Expected Bye but not found #%v: %v", i, err)
		}

		waitOrFail(t, child, 0)
		ctx.Reset()
	}
}