diff --git a/test b/test index 8606b10..fecd750 100755 --- a/test +++ b/test @@ -54,13 +54,12 @@ if [ -n "${vetRes}" ]; then exit 255 fi -# Functional tests are more dangerous than unit tests: they use 'sudo' and access -# /var/lib/rkt/ directly. Only run them inside well-known CI systems. +# Functional tests use 'sudo' to run as root - it's more dangerous +# than unit tests and may require typing a password. Only run them +# inside well-known CI systems. if [ "$CI" == true ] ; then if [ "${CIRCLECI}" == true -o "${SEMAPHORE}" == true ] ; then echo "Checking functional tests..." - # Run destructive tests too - export RKT_ENABLE_DESTRUCTIVE_TESTS=1 (cd tests && ./test) else echo "Functional tests disabled." diff --git a/tests/rkt_auth_test.go b/tests/rkt_auth_test.go index 04f9339..06020da 100644 --- a/tests/rkt_auth_test.go +++ b/tests/rkt_auth_test.go @@ -23,16 +23,15 @@ import ( "testing" "github.com/coreos/rkt/Godeps/_workspace/src/github.com/ThomasRooney/gexpect" - "github.com/coreos/rkt/common" taas "github.com/coreos/rkt/tests/test-auth-server/aci" ) func TestAuthSanity(t *testing.T) { - skipDestructive(t) - removeDataDir(t) + ctx := newRktRunCtx() + defer ctx.cleanup() server := runServer(t, taas.None) defer server.Close() - successfulRunRkt(t, server.URL, "sanity") + expectedRunRkt(ctx, t, server.URL, "sanity", authSuccessfulDownload) } const ( @@ -40,50 +39,62 @@ const ( authFailedDownload = "error downloading ACI: bad HTTP status code: 401" ) +type authConfDir int + +const ( + authConfDirNone authConfDir = iota + authConfDirLocal + authConfDirSystem +) + type genericAuthTest struct { name string - useServerConf bool - confDir string + confDir authConfDir expectedLine string } func TestAuthBasic(t *testing.T) { tests := []genericAuthTest{ - {"basic-no-config", false, "", authFailedDownload}, - {"basic-local-config", true, common.DefaultLocalConfigDir, authSuccessfulDownload}, - {"basic-system-config", true, common.DefaultSystemConfigDir, authSuccessfulDownload}, + {"basic-no-config", authConfDirNone, authFailedDownload}, + {"basic-local-config", authConfDirLocal, authSuccessfulDownload}, + {"basic-system-config", authConfDirSystem, authSuccessfulDownload}, } testAuthGeneric(t, taas.Basic, tests) } func TestAuthOauth(t *testing.T) { tests := []genericAuthTest{ - {"oauth-no-config", false, "", authFailedDownload}, - {"oauth-local-config", true, common.DefaultLocalConfigDir, authSuccessfulDownload}, - {"oauth-system-config", true, common.DefaultSystemConfigDir, authSuccessfulDownload}, + {"oauth-no-config", authConfDirNone, authFailedDownload}, + {"oauth-local-config", authConfDirLocal, authSuccessfulDownload}, + {"oauth-system-config", authConfDirSystem, authSuccessfulDownload}, } testAuthGeneric(t, taas.Oauth, tests) } func testAuthGeneric(t *testing.T, auth taas.Type, tests []genericAuthTest) { - skipDestructive(t) - removeDataDir(t) - defer removeAllConfig(t) server := runServer(t, auth) defer server.Close() + ctx := newRktRunCtx() + defer ctx.cleanup() for _, tt := range tests { - removeAllConfig(t) - if tt.useServerConf { - writeConfig(t, tt.confDir, "test.json", server.Conf) + switch tt.confDir { + case authConfDirNone: + // no config to write + case authConfDirLocal: + writeConfig(t, ctx.localDir(), "test.json", server.Conf) + case authConfDirSystem: + writeConfig(t, ctx.systemDir(), "test.json", server.Conf) + default: + panic("Wrong config directory") } - expectedRunRkt(t, server.URL, tt.name, tt.expectedLine) + expectedRunRkt(ctx, t, server.URL, tt.name, tt.expectedLine) + ctx.reset() } } func TestAuthOverride(t *testing.T) { - skipDestructive(t) - removeDataDir(t) - defer removeAllConfig(t) + ctx := newRktRunCtx() + defer ctx.cleanup() server := runServer(t, taas.Oauth) defer server.Close() tests := []struct { @@ -97,18 +108,15 @@ func TestAuthOverride(t *testing.T) { {getInvalidOAuthConfig(server.Conf), server.Conf, "invalid-system-valid-local", authFailedDownload, authSuccessfulDownload}, } for _, tt := range tests { - removeAllConfig(t) - writeSystemConfig(t, "test.json", tt.systemConfig) - expectedRunRkt(t, server.URL, tt.name+"-1", tt.resultBeforeOverride) - writeLocalConfig(t, "test.json", tt.localConfig) - expectedRunRkt(t, server.URL, tt.name+"-2", tt.resultAfterOverride) + writeConfig(t, ctx.systemDir(), "test.json", tt.systemConfig) + expectedRunRkt(ctx, t, server.URL, tt.name+"-1", tt.resultBeforeOverride) + writeConfig(t, ctx.localDir(), "test.json", tt.localConfig) + expectedRunRkt(ctx, t, server.URL, tt.name+"-2", tt.resultAfterOverride) + ctx.reset() } } func TestAuthIgnore(t *testing.T) { - skipDestructive(t) - removeDataDir(t) - defer removeAllConfig(t) server := runServer(t, taas.Oauth) defer server.Close() testAuthIgnoreBogusFiles(t, server) @@ -116,21 +124,23 @@ func TestAuthIgnore(t *testing.T) { } func testAuthIgnoreBogusFiles(t *testing.T, server *taas.Server) { - removeAllConfig(t) - writeSystemConfig(t, "README", "This is system config") - writeLocalConfig(t, "README", "This is local config") - writeSystemConfig(t, "test.notjson", server.Conf) - writeLocalConfig(t, "test.notjson", server.Conf) - failedRunRkt(t, server.URL, "oauth-bogus-files") + ctx := newRktRunCtx() + defer ctx.cleanup() + writeConfig(t, ctx.systemDir(), "README", "This is system config") + writeConfig(t, ctx.localDir(), "README", "This is local config") + writeConfig(t, ctx.systemDir(), "test.notjson", server.Conf) + writeConfig(t, ctx.localDir(), "test.notjson", server.Conf) + expectedRunRkt(ctx, t, server.URL, "oauth-bogus-files", authFailedDownload) } func testAuthIgnoreSubdirectories(t *testing.T, server *taas.Server) { - removeAllConfig(t) - localSubdir := filepath.Join(common.DefaultLocalConfigDir, "subdir") - systemSubdir := filepath.Join(common.DefaultSystemConfigDir, "subdir") + ctx := newRktRunCtx() + defer ctx.cleanup() + localSubdir := filepath.Join(ctx.localDir(), "subdir") + systemSubdir := filepath.Join(ctx.systemDir(), "subdir") writeConfig(t, localSubdir, "test.json", server.Conf) writeConfig(t, systemSubdir, "test.json", server.Conf) - failedRunRkt(t, server.URL, "oauth-subdirectories") + expectedRunRkt(ctx, t, server.URL, "oauth-subdirectories", authFailedDownload) } func runServer(t *testing.T, auth taas.Type) *taas.Server { @@ -153,61 +163,21 @@ func serverHandler(t *testing.T, server *taas.Server) { } } -func successfulRunRkt(t *testing.T, host, dir string) { - expectedRunRkt(t, host, dir, authSuccessfulDownload) -} - -func failedRunRkt(t *testing.T, host, dir string) { - expectedRunRkt(t, host, dir, authFailedDownload) -} - -func expectedRunRkt(t *testing.T, host, dir, line string) { - child := runRkt(t, host, dir) - defer child.Wait() - if err := child.Expect(line); err != nil { - t.Fatalf("Didn't receive expected output %q", line) - } -} - -// TODO (krnowak): Use --dir option when we also add -// --system-config-dir and --local-config-dir options. Then we can -// remove destructive tests checks. - -// runRkt tries to fetch and run a prog.aci from host within given -// directory on host. Note that directory can be anything - it's +// expectedRunRkt tries to fetch and run a prog.aci from host within +// given directory on host. Note that directory can be anything - it's // useful for ensuring that image name is unique and for descriptive // purposes. -func runRkt(t *testing.T, host, dir string) *gexpect.ExpectSubprocess { - cmd := fmt.Sprintf(`../bin/rkt --debug --insecure-skip-verify run %s/%s/prog.aci`, host, dir) +func expectedRunRkt(ctx *rktRunCtx, t *testing.T, host, dir, line string) { + cmd := fmt.Sprintf(`%s --debug --insecure-skip-verify run %s/%s/prog.aci`, ctx.cmd(), host, dir) t.Logf("Running rkt: %s", cmd) child, err := gexpect.Spawn(cmd) if err != nil { t.Fatalf("Failed to run rkt: %v", err) } - return child -} - -func removeAllConfig(t *testing.T) { - dirs := []string{ - authDir(common.DefaultLocalConfigDir), - authDir(common.DefaultSystemConfigDir), + defer child.Wait() + if err := child.Expect(line); err != nil { + t.Fatalf("Didn't receive expected output %q", line) } - for _, p := range dirs { - if err := os.RemoveAll(p); err != nil { - t.Fatalf("Failed to remove config directory %q: %v", p, err) - } - if err := os.MkdirAll(p, 0755); err != nil { - t.Fatalf("Failed to create config directory %q: %v", p, err) - } - } -} - -func writeLocalConfig(t *testing.T, filename, contents string) { - writeConfig(t, common.DefaultLocalConfigDir, filename, contents) -} - -func writeSystemConfig(t *testing.T, filename, contents string) { - writeConfig(t, common.DefaultSystemConfigDir, filename, contents) } func writeConfig(t *testing.T, baseDir, filename, contents string) { diff --git a/tests/rkt_caps_test.go b/tests/rkt_caps_test.go index 10b8c3a..b923e0a 100644 --- a/tests/rkt_caps_test.go +++ b/tests/rkt_caps_test.go @@ -74,6 +74,9 @@ var capsTests = []struct { } func TestCaps(t *testing.T) { + ctx := newRktRunCtx() + defer ctx.cleanup() + for i, tt := range capsTests { var stage1FileName = "rkt-inspect-print-caps-stage1.aci" var stage2FileName = "rkt-inspect-print-caps-stage2.aci" @@ -91,7 +94,7 @@ func TestCaps(t *testing.T) { for _, stage := range []int{1, 2} { t.Logf("Running test #%v: %v [stage %v]", i, tt.testName, stage) - cmd := fmt.Sprintf("../bin/rkt --debug --insecure-skip-verify run --set-env=CAPABILITY=%d ./rkt-inspect-print-caps-stage%d.aci", int(tt.capa), stage) + cmd := fmt.Sprintf("%s --debug --insecure-skip-verify run --set-env=CAPABILITY=%d ./rkt-inspect-print-caps-stage%d.aci", ctx.cmd(), int(tt.capa), stage) t.Logf("Command: %v", cmd) child, err := gexpect.Spawn(cmd) if err != nil { @@ -119,10 +122,14 @@ func TestCaps(t *testing.T) { t.Fatalf("rkt didn't terminate correctly: %v", err) } } + ctx.reset() } } func TestNonRootCaps(t *testing.T) { + ctx := newRktRunCtx() + defer ctx.cleanup() + for i, tt := range capsTests { var fileName = "rkt-inspect-print-caps-nonroot.aci" var args []string @@ -135,7 +142,7 @@ func TestNonRootCaps(t *testing.T) { t.Logf("Running test #%v: %v [non-root]", i, tt.testName) - cmd := fmt.Sprintf("../bin/rkt --debug --insecure-skip-verify run --set-env=CAPABILITY=%d ./%s", int(tt.capa), fileName) + cmd := fmt.Sprintf("%s --debug --insecure-skip-verify run --set-env=CAPABILITY=%d ./%s", ctx.cmd(), int(tt.capa), fileName) t.Logf("Command: %v", cmd) child, err := gexpect.Spawn(cmd) if err != nil { @@ -162,5 +169,6 @@ func TestNonRootCaps(t *testing.T) { if err != nil { t.Fatalf("rkt didn't terminate correctly: %v", err) } + ctx.reset() } } diff --git a/tests/rkt_env_test.go b/tests/rkt_env_test.go index 2c3bdec..6bebbbb 100644 --- a/tests/rkt_env_test.go +++ b/tests/rkt_env_test.go @@ -16,6 +16,7 @@ package main import ( "os" + "strings" "testing" "github.com/coreos/rkt/Godeps/_workspace/src/github.com/ThomasRooney/gexpect" @@ -28,40 +29,40 @@ var envTests = []struct { enterCmd string }{ { - `../bin/rkt --debug --insecure-skip-verify run ./rkt-inspect-print-var-from-manifest.aci`, + `^RKT_BIN^ --debug --insecure-skip-verify run ./rkt-inspect-print-var-from-manifest.aci`, "VAR_FROM_MANIFEST=manifest", - `../bin/rkt --debug --insecure-skip-verify run ./rkt-inspect-sleep.aci`, - `/bin/sh -c "../bin/rkt --debug enter $(../bin/rkt list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_FROM_MANIFEST"`, + `^RKT_BIN^ --debug --insecure-skip-verify run ./rkt-inspect-sleep.aci`, + `/bin/sh -c "^RKT_BIN^ --debug enter $(^RKT_BIN^ list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_FROM_MANIFEST"`, }, { - `../bin/rkt --debug --insecure-skip-verify run --set-env=VAR_OTHER=setenv ./rkt-inspect-print-var-other.aci`, + `^RKT_BIN^ --debug --insecure-skip-verify run --set-env=VAR_OTHER=setenv ./rkt-inspect-print-var-other.aci`, "VAR_OTHER=setenv", - `../bin/rkt --debug --insecure-skip-verify run --set-env=VAR_OTHER=setenv ./rkt-inspect-sleep.aci`, - `/bin/sh -c "../bin/rkt --debug enter $(../bin/rkt list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_OTHER"`, + `^RKT_BIN^ --debug --insecure-skip-verify run --set-env=VAR_OTHER=setenv ./rkt-inspect-sleep.aci`, + `/bin/sh -c "^RKT_BIN^ --debug enter $(^RKT_BIN^ list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_OTHER"`, }, { - `../bin/rkt --debug --insecure-skip-verify run --set-env=VAR_FROM_MANIFEST=setenv ./rkt-inspect-print-var-from-manifest.aci`, + `^RKT_BIN^ --debug --insecure-skip-verify run --set-env=VAR_FROM_MANIFEST=setenv ./rkt-inspect-print-var-from-manifest.aci`, "VAR_FROM_MANIFEST=setenv", - `../bin/rkt --debug --insecure-skip-verify run --set-env=VAR_FROM_MANIFEST=setenv ./rkt-inspect-sleep.aci`, - `/bin/sh -c "../bin/rkt --debug enter $(../bin/rkt list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_FROM_MANIFEST"`, + `^RKT_BIN^ --debug --insecure-skip-verify run --set-env=VAR_FROM_MANIFEST=setenv ./rkt-inspect-sleep.aci`, + `/bin/sh -c "^RKT_BIN^ --debug enter $(^RKT_BIN^ list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_FROM_MANIFEST"`, }, { - `/bin/sh -c "export VAR_OTHER=host ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-print-var-other.aci"`, + `/bin/sh -c "export VAR_OTHER=host ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-print-var-other.aci"`, "VAR_OTHER=host", - `/bin/sh -c "export VAR_OTHER=host ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-sleep.aci"`, - `/bin/sh -c "export VAR_OTHER=host ; ../bin/rkt --debug enter $(../bin/rkt list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_OTHER"`, + `/bin/sh -c "export VAR_OTHER=host ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-sleep.aci"`, + `/bin/sh -c "export VAR_OTHER=host ; ^RKT_BIN^ --debug enter $(^RKT_BIN^ list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_OTHER"`, }, { - `/bin/sh -c "export VAR_FROM_MANIFEST=host ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-print-var-from-manifest.aci"`, + `/bin/sh -c "export VAR_FROM_MANIFEST=host ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-print-var-from-manifest.aci"`, "VAR_FROM_MANIFEST=manifest", - `/bin/sh -c "export VAR_FROM_MANIFEST=host ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-sleep.aci"`, - `/bin/sh -c "export VAR_FROM_MANIFEST=host ; ../bin/rkt --debug enter $(../bin/rkt list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_FROM_MANIFEST"`, + `/bin/sh -c "export VAR_FROM_MANIFEST=host ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-sleep.aci"`, + `/bin/sh -c "export VAR_FROM_MANIFEST=host ; ^RKT_BIN^ --debug enter $(^RKT_BIN^ list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_FROM_MANIFEST"`, }, { - `/bin/sh -c "export VAR_OTHER=host ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true --set-env=VAR_OTHER=setenv ./rkt-inspect-print-var-other.aci"`, + `/bin/sh -c "export VAR_OTHER=host ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true --set-env=VAR_OTHER=setenv ./rkt-inspect-print-var-other.aci"`, "VAR_OTHER=setenv", - `/bin/sh -c "export VAR_OTHER=host ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true --set-env=VAR_OTHER=setenv ./rkt-inspect-sleep.aci"`, - `/bin/sh -c "export VAR_OTHER=host ; ../bin/rkt --debug enter $(../bin/rkt list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_OTHER"`, + `/bin/sh -c "export VAR_OTHER=host ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true --set-env=VAR_OTHER=setenv ./rkt-inspect-sleep.aci"`, + `/bin/sh -c "export VAR_OTHER=host ; ^RKT_BIN^ --debug enter $(^RKT_BIN^ list --full|grep running|awk '{print $1}') /inspect --print-env=VAR_OTHER"`, }, } @@ -72,11 +73,14 @@ func TestEnv(t *testing.T) { defer os.Remove("rkt-inspect-print-var-other.aci") patchTestACI("rkt-inspect-sleep.aci", "--exec=/inspect --print-msg=Hello --sleep=84000") defer os.Remove("rkt-inspect-sleep.aci") + ctx := newRktRunCtx() + defer ctx.cleanup() for i, tt := range envTests { // 'run' tests - t.Logf("Running 'run' test #%v: %v", i, tt.runCmd) - child, err := gexpect.Spawn(tt.runCmd) + runCmd := strings.Replace(tt.runCmd, "^RKT_BIN^", ctx.cmd(), -1) + t.Logf("Running 'run' test #%v: %v", i, runCmd) + child, err := gexpect.Spawn(runCmd) if err != nil { t.Fatalf("Cannot exec rkt #%v: %v", i, err) } @@ -92,8 +96,9 @@ func TestEnv(t *testing.T) { } // 'enter' tests - t.Logf("Running 'enter' test #%v: sleep: %v", i, tt.sleepCmd) - child, err = gexpect.Spawn(tt.sleepCmd) + sleepCmd := strings.Replace(tt.sleepCmd, "^RKT_BIN^", ctx.cmd(), -1) + t.Logf("Running 'enter' test #%v: sleep: %v", i, sleepCmd) + child, err = gexpect.Spawn(sleepCmd) if err != nil { t.Fatalf("Cannot exec rkt #%v: %v", i, err) } @@ -103,8 +108,9 @@ func TestEnv(t *testing.T) { t.Fatalf("Expected %q but not found", tt.runExpect) } - t.Logf("Running 'enter' test #%v: enter: %v", i, tt.enterCmd) - enterChild, err := gexpect.Spawn(tt.enterCmd) + enterCmd := strings.Replace(tt.enterCmd, "^RKT_BIN^", ctx.cmd(), -1) + t.Logf("Running 'enter' test #%v: enter: %v", i, enterCmd) + enterChild, err := gexpect.Spawn(enterCmd) if err != nil { t.Fatalf("Cannot exec rkt #%v: %v", i, err) } @@ -122,5 +128,6 @@ func TestEnv(t *testing.T) { if err != nil { t.Fatalf("rkt didn't terminate correctly: %v", err) } + ctx.reset() } } diff --git a/tests/rkt_exit_test.go b/tests/rkt_exit_test.go index 3d21bef..318347b 100644 --- a/tests/rkt_exit_test.go +++ b/tests/rkt_exit_test.go @@ -15,6 +15,7 @@ package main import ( + "fmt" "os" "strings" "testing" @@ -25,8 +26,10 @@ import ( func TestSuccess(t *testing.T) { patchTestACI("rkt-inspect-exit0.aci", "--exec=/inspect --print-msg=Hello --exit-code=0") defer os.Remove("rkt-inspect-exit0.aci") + ctx := newRktRunCtx() + defer ctx.cleanup() - child, err := gexpect.Spawn("../bin/rkt --debug --insecure-skip-verify run ./rkt-inspect-exit0.aci") + child, err := gexpect.Spawn(fmt.Sprintf("%s --debug --insecure-skip-verify run ./rkt-inspect-exit0.aci", ctx.cmd())) if err != nil { t.Fatalf("Cannot exec rkt") } @@ -55,8 +58,10 @@ func TestSuccess(t *testing.T) { func TestFailure(t *testing.T) { patchTestACI("rkt-inspect-exit20.aci", "--exec=/inspect --print-msg=Hello --exit-code=20") defer os.Remove("rkt-inspect-exit20.aci") + ctx := newRktRunCtx() + defer ctx.cleanup() - child, err := gexpect.Spawn("../bin/rkt --debug --insecure-skip-verify run ./rkt-inspect-exit20.aci") + child, err := gexpect.Spawn(fmt.Sprintf("%s --debug --insecure-skip-verify run ./rkt-inspect-exit20.aci", ctx.cmd())) if err != nil { t.Fatalf("Cannot exec rkt") } diff --git a/tests/rkt_interactive_test.go b/tests/rkt_interactive_test.go index 27a9e87..3e4cef5 100644 --- a/tests/rkt_interactive_test.go +++ b/tests/rkt_interactive_test.go @@ -15,6 +15,7 @@ package main import ( + "fmt" "os" "testing" "time" @@ -25,55 +26,58 @@ import ( var interactiveTests = []struct { testName string aciBuildArgs []string - rktCmd string + rktArgs string say string expect string }{ { `Check tty without interactive`, []string{"--exec=/inspect --check-tty"}, - `../bin/rkt --debug --insecure-skip-verify run rkt-inspect-interactive.aci`, + `--debug --insecure-skip-verify run rkt-inspect-interactive.aci`, ``, `stdin is not a terminal`, }, { `Check tty without interactive (with parameter)`, []string{"--exec=/inspect"}, - `../bin/rkt --debug --insecure-skip-verify run rkt-inspect-interactive.aci -- --check-tty`, + `--debug --insecure-skip-verify run rkt-inspect-interactive.aci -- --check-tty`, ``, `stdin is not a terminal`, }, { `Check tty with interactive`, []string{"--exec=/inspect --check-tty"}, - `../bin/rkt --debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci`, + `--debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci`, ``, `stdin is a terminal`, }, { `Check tty with interactive (with parameter)`, []string{"--exec=/inspect"}, - `../bin/rkt --debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci -- --check-tty`, + `--debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci -- --check-tty`, ``, `stdin is a terminal`, }, { `Reading from stdin`, []string{"--exec=/inspect --read-stdin"}, - `../bin/rkt --debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci`, + `--debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci`, `Saluton`, `Received text: Saluton`, }, { `Reading from stdin (with parameter)`, []string{"--exec=/inspect"}, - `../bin/rkt --debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci -- --read-stdin`, + `--debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci -- --read-stdin`, `Saluton`, `Received text: Saluton`, }, } func TestInteractive(t *testing.T) { + ctx := newRktRunCtx() + defer ctx.cleanup() + for i, tt := range interactiveTests { t.Logf("Running test #%v: %v", i, tt.testName) @@ -81,8 +85,9 @@ func TestInteractive(t *testing.T) { patchTestACI(aciFileName, tt.aciBuildArgs...) defer os.Remove(aciFileName) - t.Logf("Command: %v", tt.rktCmd) - child, err := gexpect.Spawn(tt.rktCmd) + rktCmd := fmt.Sprintf("%s %s", ctx.cmd(), tt.rktArgs) + t.Logf("Command: %v", rktCmd) + child, err := gexpect.Spawn(rktCmd) if err != nil { t.Fatalf("Cannot exec rkt #%v: %v", i, err) } diff --git a/tests/rkt_tests.go b/tests/rkt_tests.go index 97c9e8a..e092340 100644 --- a/tests/rkt_tests.go +++ b/tests/rkt_tests.go @@ -16,30 +16,127 @@ package main import ( "fmt" + "io/ioutil" "os" "os/exec" - "testing" + "strings" ) -const enableDestructiveTestsEnvVar = "RKT_ENABLE_DESTRUCTIVE_TESTS" +// dirDesc structure manages one directory and provides an option for +// rkt invocations +type dirDesc struct { + dir string // directory path + desc string // directory description, mostly for failure cases + prefix string // temporary directory prefix + option string // rkt option for given directory +} -func skipDestructive(t *testing.T) { - if !destructiveTestsEnabled() { - t.Skipf("%s envvar is not specified or has value different than 1, skipping the test", enableDestructiveTestsEnvVar) +// newDirDesc creates dirDesc instance managing a temporary directory. +func newDirDesc(prefix, desc, option string) *dirDesc { + dir := &dirDesc{ + dir: "", + desc: desc, + prefix: prefix, + option: option, + } + dir.reset() + return dir +} + +// reset removes the managed directory and recreates it +func (d *dirDesc) reset() { + d.cleanup() + dir, err := ioutil.TempDir("", d.prefix) + if err != nil { + panic(fmt.Sprintf("Failed to create temporary %s directory: %v", d.desc, err)) + } + d.dir = dir +} + +// cleanup removes the managed directory. After cleanup this instance +// cannot be used for anything, until it is reset. +func (d *dirDesc) cleanup() { + if d.dir == "" { + return + } + if err := os.RemoveAll(d.dir); err != nil { + panic(fmt.Sprintf("Failed to remove temporary %s directory %q: %s", d.desc, d.dir, err)) + } + d.dir = "" +} + +// rktOption returns option for rkt invocation +func (d *dirDesc) rktOption() string { + d.ensureValid() + return fmt.Sprintf("--%s='%s'", d.option, d.dir) +} + +func (d *dirDesc) ensureValid() { + if d.dir == "" { + panic(fmt.Sprintf("A temporary %s directory is not set up", d.desc)) } } -func removeDataDir(t *testing.T) { - if !destructiveTestsEnabled() { - panic("Trying to remove datadir when destructive tests are disabled") - } - if err := os.RemoveAll("/var/lib/rkt"); err != nil { - t.Fatalf("Failed to remove /var/lib/rkt: %v", err) +type rktRunCtx struct { + directories []*dirDesc + useDefaults bool +} + +func newRktRunCtx() *rktRunCtx { + return &rktRunCtx{ + directories: []*dirDesc{ + newDirDesc("datadir-", "data", "dir"), + newDirDesc("localdir-", "local configuration", "local-config"), + newDirDesc("systemdir-", "system configuration", "system-config"), + }, } } -func destructiveTestsEnabled() bool { - return os.Getenv(enableDestructiveTestsEnvVar) == "1" +func (ctx *rktRunCtx) dataDir() string { + return ctx.dir(0) +} + +func (ctx *rktRunCtx) localDir() string { + return ctx.dir(1) +} + +func (ctx *rktRunCtx) systemDir() string { + return ctx.dir(2) +} + +func (ctx *rktRunCtx) dir(idx int) string { + ctx.ensureValid() + if idx < len(ctx.directories) { + return ctx.directories[idx].dir + } + panic("Directory index out of bounds") +} + +func (ctx *rktRunCtx) reset() { + for _, d := range ctx.directories { + d.reset() + } +} + +func (ctx *rktRunCtx) cleanup() { + for _, d := range ctx.directories { + d.cleanup() + } +} + +func (ctx *rktRunCtx) cmd() string { + ctx.ensureValid() + opts := make([]string, 0, len(ctx.directories)) + for _, d := range ctx.directories { + opts = append(opts, d.rktOption()) + } + return fmt.Sprintf("../bin/rkt %s", strings.Join(opts, " ")) +} + +func (ctx *rktRunCtx) ensureValid() { + for _, d := range ctx.directories { + d.ensureValid() + } } func patchTestACI(newFileName string, args ...string) { diff --git a/tests/rkt_volume_test.go b/tests/rkt_volume_test.go index c07d530..c15ec1f 100644 --- a/tests/rkt_volume_test.go +++ b/tests/rkt_volume_test.go @@ -31,35 +31,35 @@ var volTests = []struct { }{ // Check that we can read files in the ACI { - `/bin/sh -c "export FILE=/dir1/file ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-read-file.aci"`, + `/bin/sh -c "export FILE=/dir1/file ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-read-file.aci"`, `<<>>`, }, // Check that we can read files from a volume (both ro and rw) { - `/bin/sh -c "export FILE=/dir1/file ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true --volume=dir1,kind=host,source=$TMPDIR ./rkt-inspect-vol-rw-read-file.aci"`, + `/bin/sh -c "export FILE=/dir1/file ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true --volume=dir1,kind=host,source=^TMPDIR^ ./rkt-inspect-vol-rw-read-file.aci"`, `<<>>`, }, { - `/bin/sh -c "export FILE=/dir1/file ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true --volume=dir1,kind=host,source=$TMPDIR ./rkt-inspect-vol-ro-read-file.aci"`, + `/bin/sh -c "export FILE=/dir1/file ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true --volume=dir1,kind=host,source=^TMPDIR^ ./rkt-inspect-vol-ro-read-file.aci"`, `<<>>`, }, // Check that we can write to files in the ACI { - `/bin/sh -c "export FILE=/dir1/file CONTENT=1 ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-write-file.aci"`, + `/bin/sh -c "export FILE=/dir1/file CONTENT=1 ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true ./rkt-inspect-write-file.aci"`, `<<<1>>>`, }, // Check that we can write files to a volume (both ro and rw) { - `/bin/sh -c "export FILE=/dir1/file CONTENT=2 ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true --volume=dir1,kind=host,source=$TMPDIR ./rkt-inspect-vol-rw-write-file.aci"`, + `/bin/sh -c "export FILE=/dir1/file CONTENT=2 ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true --volume=dir1,kind=host,source=^TMPDIR^ ./rkt-inspect-vol-rw-write-file.aci"`, `<<<2>>>`, }, { - `/bin/sh -c "export FILE=/dir1/file CONTENT=3 ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true --volume=dir1,kind=host,source=$TMPDIR ./rkt-inspect-vol-ro-write-file.aci"`, + `/bin/sh -c "export FILE=/dir1/file CONTENT=3 ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true --volume=dir1,kind=host,source=^TMPDIR^ ./rkt-inspect-vol-ro-write-file.aci"`, `Cannot write to file "/dir1/file": open /dir1/file: read-only file system`, }, // Check that the volume still contain the file previously written { - `/bin/sh -c "export FILE=/dir1/file ; ../bin/rkt --debug --insecure-skip-verify run --inherit-env=true --volume=dir1,kind=host,source=$TMPDIR ./rkt-inspect-vol-ro-read-file.aci"`, + `/bin/sh -c "export FILE=/dir1/file ; ^RKT_BIN^ --debug --insecure-skip-verify run --inherit-env=true --volume=dir1,kind=host,source=^TMPDIR^ ./rkt-inspect-vol-ro-read-file.aci"`, `<<<2>>>`, }, } @@ -77,22 +77,24 @@ func TestVolumes(t *testing.T) { defer os.Remove("rkt-inspect-vol-ro-read-file.aci") patchTestACI("rkt-inspect-vol-ro-write-file.aci", "--exec=/inspect --write-file --read-file", "--mounts=dir1,path=/dir1,readOnly=true") defer os.Remove("rkt-inspect-vol-ro-write-file.aci") + ctx := newRktRunCtx() + defer ctx.cleanup() tmpdir, err := ioutil.TempDir("", "rkt-tests.") if err != nil { t.Fatalf("Cannot create temporary directory: %v", err) } - defer os.Remove(tmpdir) + defer os.RemoveAll(tmpdir) tmpfile := filepath.Join(tmpdir, "file") err = ioutil.WriteFile(tmpfile, []byte("host"), 0600) if err != nil { t.Fatalf("Cannot create temporary file: %v", err) } - defer os.Remove(tmpfile) for i, tt := range volTests { - cmd := strings.Replace(tt.rktCmd, "$TMPDIR", tmpdir, -1) + cmd := strings.Replace(tt.rktCmd, "^TMPDIR^", tmpdir, -1) + cmd = strings.Replace(cmd, "^RKT_BIN^", ctx.cmd(), -1) t.Logf("Running test #%v: %v", i, cmd) diff --git a/tests/test b/tests/test index 9fa6ee1..784bbb1 100755 --- a/tests/test +++ b/tests/test @@ -18,5 +18,4 @@ # version as the system-wide installed go. GO=`which go` -sudo GOPATH="${PWD}/../gopath" RKT_ENABLE_DESTRUCTIVE_TESTS="$RKT_ENABLE_DESTRUCTIVE_TESTS" GOROOT="$GOROOT" $GO test -v $* - +sudo GOPATH="${PWD}/../gopath" GOROOT="$GOROOT" $GO test -v $*