Hack: simplify the creation of test directories
This commit is contained in:
parent
02ddaad5d9
commit
5a85456d48
4 changed files with 85 additions and 69 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue