From c13616829073ffd8846ef2eb3c1c20c484161837 Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Sun, 27 Oct 2013 07:13:45 +0000 Subject: [PATCH] Hack: simplify the creation of test directories Upstream-commit: 5a85456d481a5f88fc0efc02c41b3bff987c0ed1 Component: engine --- components/engine/runtime_test.go | 45 ++++++++------- components/engine/server_test.go | 7 +-- components/engine/utils/utils.go | 6 ++ components/engine/utils_test.go | 96 +++++++++++++++++-------------- 4 files changed, 85 insertions(+), 69 deletions(-) diff --git a/components/engine/runtime_test.go b/components/engine/runtime_test.go index 4e46b7b6d0..4aac2f3442 100644 --- a/components/engine/runtime_test.go +++ b/components/engine/runtime_test.go @@ -3,6 +3,7 @@ package docker import ( "bytes" "fmt" + "github.com/dotcloud/docker/engine" "github.com/dotcloud/docker/sysinit" "github.com/dotcloud/docker/utils" "io" @@ -17,6 +18,7 @@ import ( "syscall" "testing" "time" + "net/url" ) const ( @@ -118,22 +120,19 @@ func init() { } func setupBaseImage() { - config := &DaemonConfig{ - Root: unitTestStoreBase, - AutoRestart: false, - BridgeIface: unitTestNetworkBridge, - } - runtime, err := NewRuntimeFromDirectory(config) + eng, err := engine.New(unitTestStoreBase) if err != nil { + log.Fatalf("Can't initialize engine at %s: %s", unitTestStoreBase, err) + } + job := eng.Job("initapi") + job.Setenv("Root", unitTestStoreBase) + job.SetenvBool("Autorestart", false) + job.Setenv("BridgeIface", unitTestNetworkBridge) + if err := job.Run(); err != nil { log.Fatalf("Unable to create a runtime for tests:", err) } - - // Create the "Server" - srv := &Server{ - runtime: runtime, - pullingPool: make(map[string]struct{}), - pushingPool: make(map[string]struct{}), - } + srv := mkServerFromEngine(eng, log.New(os.Stderr, "", 0)) + runtime := srv.runtime // If the unit test is not found, try to download it. if img, err := runtime.repositories.LookupImage(unitTestImageName); err != nil || img.ID != unitTestImageID { @@ -149,18 +148,22 @@ func spawnGlobalDaemon() { utils.Debugf("Global runtime already exists. Skipping.") return } - globalRuntime = mkRuntime(log.New(os.Stderr, "", 0)) - srv := &Server{ - runtime: globalRuntime, - pullingPool: make(map[string]struct{}), - pushingPool: make(map[string]struct{}), - } + t := log.New(os.Stderr, "", 0) + eng := NewTestEngine(t) + srv := mkServerFromEngine(eng, t) + globalRuntime = srv.runtime // Spawn a Daemon go func() { utils.Debugf("Spawning global daemon for integration tests") - if err := ListenAndServe(testDaemonProto, testDaemonAddr, srv, os.Getenv("DEBUG") != ""); err != nil { - log.Fatalf("Unable to spawn the test daemon:", err) + listenURL := &url.URL{ + Scheme: testDaemonProto, + Host: testDaemonAddr, + } + job := eng.Job("serveapi", listenURL.String()) + job.SetenvBool("Logging", os.Getenv("DEBUG") != "") + if err := job.Run(); err != nil { + log.Fatalf("Unable to spawn the test daemon: %s", err) } }() // Give some time to ListenAndServer to actually start diff --git a/components/engine/server_test.go b/components/engine/server_test.go index 20894f8fe1..a4bfb0155f 100644 --- a/components/engine/server_test.go +++ b/components/engine/server_test.go @@ -1,7 +1,6 @@ package docker import ( - "github.com/dotcloud/docker/engine" "github.com/dotcloud/docker/utils" "strings" "testing" @@ -110,7 +109,7 @@ func TestCreateRm(t *testing.T) { } func TestCreateRmVolumes(t *testing.T) { - eng := engine.NewTestEngine(t) + eng := NewTestEngine(t) srv := mkServerFromEngine(eng, t) runtime := srv.runtime @@ -174,7 +173,7 @@ func TestCommit(t *testing.T) { } func TestCreateStartRestartStopStartKillRm(t *testing.T) { - eng := engine.NewTestEngine(t) + eng := NewTestEngine(t) srv := mkServerFromEngine(eng, t) runtime := srv.runtime defer nuke(runtime) @@ -397,7 +396,7 @@ func TestLogEvent(t *testing.T) { } func TestRmi(t *testing.T) { - eng := engine.NewTestEngine(t) + eng := NewTestEngine(t) srv := mkServerFromEngine(eng, t) runtime := srv.runtime defer nuke(runtime) diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go index cadd095031..5fd5e4e5b9 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -27,6 +27,12 @@ var ( INITSHA1 string // sha1sum of separate static dockerinit, if Docker itself was compiled dynamically via ./hack/make.sh dynbinary ) +// A common interface to access the Fatal method of +// both testing.B and testing.T. +type Fataler interface { + Fatal(args ...interface{}) +} + // ListOpts type type ListOpts []string diff --git a/components/engine/utils_test.go b/components/engine/utils_test.go index 282954285c..95e12b6393 100644 --- a/components/engine/utils_test.go +++ b/components/engine/utils_test.go @@ -21,27 +21,24 @@ var globalTestID string // Create a temporary runtime suitable for unit testing. // Call t.Fatal() at the first error. -func mkRuntime(f Fataler) *Runtime { - // Use the caller function name as a prefix. - // This helps trace temp directories back to their test. - pc, _, _, _ := runtime.Caller(1) - callerLongName := runtime.FuncForPC(pc).Name() - parts := strings.Split(callerLongName, ".") - callerShortName := parts[len(parts)-1] - if globalTestID == "" { - globalTestID = GenerateID()[:4] - } - prefix := fmt.Sprintf("docker-test%s-%s-", globalTestID, callerShortName) - utils.Debugf("prefix = '%s'", prefix) - - runtime, err := newTestRuntime(prefix) +func mkRuntime(f utils.Fataler) *Runtime { + root, err := newTestDirectory(unitTestStoreBase) if err != nil { f.Fatal(err) } - return runtime + config := &DaemonConfig{ + Root: root, + AutoRestart: false, + } + r, err := NewRuntimeFromDirectory(config) + if err != nil { + f.Fatal(err) + } + r.UpdateCapabilities(true) + return r } -func mkServerFromEngine(eng *engine.Engine, t Fataler) *Server { +func mkServerFromEngine(eng *engine.Engine, t utils.Fataler) *Server { iSrv := eng.Hack_GetGlobalVar("httpapi.server") if iSrv == nil { t.Fatal("Legacy server field not set in engine") @@ -53,42 +50,53 @@ func mkServerFromEngine(eng *engine.Engine, t Fataler) *Server { return srv } -// A common interface to access the Fatal method of -// both testing.B and testing.T. -type Fataler interface { - Fatal(args ...interface{}) + +func NewTestEngine(t utils.Fataler) *engine.Engine { + root, err := newTestDirectory(unitTestStoreBase) + if err != nil { + t.Fatal(err) + } + eng, err := engine.New(root) + if err != nil { + t.Fatal(err) + } + // Load default plugins + // (This is manually copied and modified from main() until we have a more generic plugin system) + job := eng.Job("initapi") + job.Setenv("Root", root) + job.SetenvBool("AutoRestart", false) + if err := job.Run(); err != nil { + t.Fatal(err) + } + return eng } -func newTestRuntime(prefix string) (runtime *Runtime, err error) { +func newTestDirectory(templateDir string) (dir string, err error) { + if globalTestID == "" { + globalTestID = GenerateID()[:4] + } + prefix := fmt.Sprintf("docker-test%s-%s-", globalTestID, getCallerName(2)) if prefix == "" { prefix = "docker-test-" } - utils.Debugf("prefix = %s", prefix) - utils.Debugf("newTestRuntime start") - root, err := ioutil.TempDir("", prefix) - defer func() { - utils.Debugf("newTestRuntime: %s", root) - }() - if err != nil { - return nil, err + dir, err = ioutil.TempDir("", prefix) + if err = os.Remove(dir); err != nil { + return } - if err := os.Remove(root); err != nil { - return nil, err - } - if err := utils.CopyDirectory(unitTestStoreBase, root); err != nil { - return nil, err + if err = utils.CopyDirectory(templateDir, dir); err != nil { + return } + return +} - config := &DaemonConfig{ - Root: root, - AutoRestart: false, - } - runtime, err = NewRuntimeFromDirectory(config) - if err != nil { - return nil, err - } - runtime.UpdateCapabilities(true) - return runtime, nil +func getCallerName(depth int) string { + // Use the caller function name as a prefix. + // This helps trace temp directories back to their test. + pc, _, _, _ := runtime.Caller(depth + 1) + callerLongName := runtime.FuncForPC(pc).Name() + parts := strings.Split(callerLongName, ".") + callerShortName := parts[len(parts)-1] + return callerShortName } // Write `content` to the file at path `dst`, creating it if necessary,