Пример #1
0
func TestGetContainersByName(t *testing.T) {
	eng := engine.New()
	name := "container_name"
	var called bool
	eng.Register("container_inspect", func(job *engine.Job) engine.Status {
		called = true
		if job.Args[0] != name {
			t.Errorf("name != '%s': %#v", name, job.Args[0])
		}
		if api.APIVERSION.LessThan("1.12") && !job.GetenvBool("dirty") {
			t.Errorf("dirty env variable not set")
		} else if api.APIVERSION.GreaterThanOrEqualTo("1.12") && job.GetenvBool("dirty") {
			t.Errorf("dirty env variable set when it shouldn't")
		}
		v := &engine.Env{}
		v.SetBool("dirty", true)
		if _, err := v.WriteTo(job.Stdout); err != nil {
			return job.Error(err)
		}
		return engine.StatusOK
	})
	r := serveRequest("GET", "/containers/"+name+"/json", nil, eng, t)
	if !called {
		t.Fatal("handler was not called")
	}
	assertContentType(r, "application/json", t)
	var stdoutJson interface{}
	if err := json.Unmarshal(r.Body.Bytes(), &stdoutJson); err != nil {
		t.Fatalf("%#v", err)
	}
	if stdoutJson.(map[string]interface{})["dirty"].(float64) != 1 {
		t.Fatalf("%#v", stdoutJson)
	}
}
Пример #2
0
func TestAllocatePortDetection(t *testing.T) {
	eng := engine.New()
	eng.Logging = false

	freePort := findFreePort(t)

	// Init driver
	job := eng.Job("initdriver")
	if res := InitDriver(job); res != engine.StatusOK {
		t.Fatal("Failed to initialize network driver")
	}

	// Allocate interface
	job = eng.Job("allocate_interface", "container_id")
	if res := Allocate(job); res != engine.StatusOK {
		t.Fatal("Failed to allocate network interface")
	}

	// Allocate same port twice, expect failure on second call
	job = newPortAllocationJob(eng, freePort)
	if res := AllocatePort(job); res != engine.StatusOK {
		t.Fatal("Failed to find a free port to allocate")
	}
	if res := AllocatePort(job); res == engine.StatusOK {
		t.Fatal("Duplicate port allocation granted by AllocatePort")
	}
}
Пример #3
0
func TestGetInfo(t *testing.T) {
	eng := engine.New()
	var called bool
	eng.Register("info", func(job *engine.Job) engine.Status {
		called = true
		v := &engine.Env{}
		v.SetInt("Containers", 1)
		v.SetInt("Images", 42000)
		if _, err := v.WriteTo(job.Stdout); err != nil {
			return job.Error(err)
		}
		return engine.StatusOK
	})
	r := serveRequest("GET", "/info", nil, eng, t)
	if !called {
		t.Fatalf("handler was not called")
	}
	v := readEnv(r.Body, t)
	if v.GetInt("Images") != 42000 {
		t.Fatalf("%#v\n", v)
	}
	if v.GetInt("Containers") != 1 {
		t.Fatalf("%#v\n", v)
	}
	assertContentType(r, "application/json", t)
}
Пример #4
0
func TestLogsNoStreams(t *testing.T) {
	eng := engine.New()
	var inspect bool
	var logs bool
	eng.Register("container_inspect", func(job *engine.Job) engine.Status {
		inspect = true
		if len(job.Args) == 0 {
			t.Fatal("Job arguments is empty")
		}
		if job.Args[0] != "test" {
			t.Fatalf("Container name %s, must be test", job.Args[0])
		}
		return engine.StatusOK
	})
	eng.Register("logs", func(job *engine.Job) engine.Status {
		logs = true
		return engine.StatusOK
	})
	r := serveRequest("GET", "/containers/test/logs", nil, eng, t)
	if r.Code != http.StatusBadRequest {
		t.Fatalf("Got status %d, expected %d", r.Code, http.StatusBadRequest)
	}
	if inspect {
		t.Fatal("container_inspect job was called, but it shouldn't")
	}
	if logs {
		t.Fatal("logs job was called, but it shouldn't")
	}
	res := strings.TrimSpace(r.Body.String())
	expected := "Bad parameters: you must choose at least one stream"
	if !strings.Contains(res, expected) {
		t.Fatalf("Output %s, expected %s in it", res, expected)
	}
}
Пример #5
0
func TestGetVersion(t *testing.T) {
	eng := engine.New()
	var called bool
	eng.Register("version", func(job *engine.Job) engine.Status {
		called = true
		v := &engine.Env{}
		v.SetJson("Version", "42.1")
		v.Set("ApiVersion", "1.1.1.1.1")
		v.Set("GoVersion", "2.42")
		v.Set("Os", "Linux")
		v.Set("Arch", "x86_64")
		if _, err := v.WriteTo(job.Stdout); err != nil {
			return job.Error(err)
		}
		return engine.StatusOK
	})
	r := serveRequest("GET", "/version", nil, eng, t)
	if !called {
		t.Fatalf("handler was not called")
	}
	v := readEnv(r.Body, t)
	if v.Get("Version") != "42.1" {
		t.Fatalf("%#v\n", v)
	}
	if r.HeaderMap.Get("Content-Type") != "application/json" {
		t.Fatalf("%#v\n", r)
	}
}
Пример #6
0
func TestGetImagesHistory(t *testing.T) {
	eng := engine.New()
	imageName := "docker-test-image"
	var called bool
	eng.Register("history", func(job *engine.Job) engine.Status {
		called = true
		if len(job.Args) == 0 {
			t.Fatal("Job arguments is empty")
		}
		if job.Args[0] != imageName {
			t.Fatalf("name != '%s': %#v", imageName, job.Args[0])
		}
		v := &engine.Env{}
		if _, err := v.WriteTo(job.Stdout); err != nil {
			return job.Error(err)
		}
		return engine.StatusOK
	})
	r := serveRequest("GET", "/images/"+imageName+"/history", nil, eng, t)
	if !called {
		t.Fatalf("handler was not called")
	}
	if r.Code != http.StatusOK {
		t.Fatalf("Got status %d, expected %d", r.Code, http.StatusOK)
	}
	if r.HeaderMap.Get("Content-Type") != "application/json" {
		t.Fatalf("%#v\n", r)
	}
}
Пример #7
0
func TestGetImagesJSONLegacyFormat(t *testing.T) {
	eng := engine.New()
	var called bool
	eng.Register("images", func(job *engine.Job) engine.Status {
		called = true
		outsLegacy := engine.NewTable("Created", 0)
		outsLegacy.Add(createEnvFromGetImagesJSONStruct(sampleImage))
		if _, err := outsLegacy.WriteListTo(job.Stdout); err != nil {
			return job.Error(err)
		}
		return engine.StatusOK
	})
	r := serveRequestUsingVersion("GET", "/images/json", "1.6", nil, eng, t)
	if !called {
		t.Fatal("handler was not called")
	}
	assertHttpNotError(r, t)
	assertContentType(r, "application/json", t)
	images := engine.NewTable("Created", 0)
	if _, err := images.ReadListFrom(r.Body.Bytes()); err != nil {
		t.Fatal(err)
	}
	if images.Len() != 1 {
		t.Fatalf("Expected 1 image, %d found", images.Len())
	}
	image := images.Data[0]
	if image.Get("Tag") != "test-tag" {
		t.Errorf("Expected tag 'test-tag', found '%s'", image.Get("Tag"))
	}
	if image.Get("Repository") != "test-name" {
		t.Errorf("Expected repository 'test-name', found '%s'", image.Get("Repository"))
	}
}
Пример #8
0
func TestGetImagesJSON(t *testing.T) {
	eng := engine.New()
	var called bool
	eng.Register("images", func(job *engine.Job) engine.Status {
		called = true
		v := createEnvFromGetImagesJSONStruct(sampleImage)
		if _, err := v.WriteTo(job.Stdout); err != nil {
			return job.Error(err)
		}
		return engine.StatusOK
	})
	r := serveRequest("GET", "/images/json", nil, eng, t)
	if !called {
		t.Fatal("handler was not called")
	}
	assertHttpNotError(r, t)
	assertContentType(r, "application/json", t)
	var observed getImagesJSONStruct
	if err := json.Unmarshal(r.Body.Bytes(), &observed); err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(observed, sampleImage) {
		t.Errorf("Expected %#v but got %#v", sampleImage, observed)
	}
}
Пример #9
0
func newTestEngine(t log.Fataler, autorestart bool, root string) *engine.Engine {
	if root == "" {
		if dir, err := newTestDirectory(unitTestStoreBase); err != nil {
			t.Fatal(err)
		} else {
			root = dir
		}
	}
	os.MkdirAll(root, 0700)

	eng := engine.New()
	// Load default plugins
	builtins.Register(eng)
	// (This is manually copied and modified from main() until we have a more generic plugin system)
	cfg := &daemon.Config{
		Root:        root,
		AutoRestart: autorestart,
		ExecDriver:  "native",
		// Either InterContainerCommunication or EnableIptables must be set,
		// otherwise NewDaemon will fail because of conflicting settings.
		InterContainerCommunication: true,
	}
	d, err := daemon.NewDaemon(cfg, eng)
	if err != nil {
		t.Fatal(err)
	}
	if err := d.Install(eng); err != nil {
		t.Fatal(err)
	}
	return eng
}
Пример #10
0
func TestLogs(t *testing.T) {
	eng := engine.New()
	var inspect bool
	var logs bool
	eng.Register("container_inspect", func(job *engine.Job) engine.Status {
		inspect = true
		if len(job.Args) == 0 {
			t.Fatal("Job arguments is empty")
		}
		if job.Args[0] != "test" {
			t.Fatalf("Container name %s, must be test", job.Args[0])
		}
		return engine.StatusOK
	})
	expected := "logs"
	eng.Register("logs", func(job *engine.Job) engine.Status {
		logs = true
		if len(job.Args) == 0 {
			t.Fatal("Job arguments is empty")
		}
		if job.Args[0] != "test" {
			t.Fatalf("Container name %s, must be test", job.Args[0])
		}
		follow := job.Getenv("follow")
		if follow != "1" {
			t.Fatalf("follow: %s, must be 1", follow)
		}
		stdout := job.Getenv("stdout")
		if stdout != "1" {
			t.Fatalf("stdout %s, must be 1", stdout)
		}
		stderr := job.Getenv("stderr")
		if stderr != "" {
			t.Fatalf("stderr %s, must be empty", stderr)
		}
		timestamps := job.Getenv("timestamps")
		if timestamps != "1" {
			t.Fatalf("timestamps %s, must be 1", timestamps)
		}
		job.Stdout.Write([]byte(expected))
		return engine.StatusOK
	})
	r := serveRequest("GET", "/containers/test/logs?follow=1&stdout=1&timestamps=1", nil, eng, t)
	if r.Code != http.StatusOK {
		t.Fatalf("Got status %d, expected %d", r.Code, http.StatusOK)
	}
	if !inspect {
		t.Fatal("container_inspect job was not called")
	}
	if !logs {
		t.Fatal("logs job was not called")
	}
	res := r.Body.String()
	if res != expected {
		t.Fatalf("Output %s, expected %s", res, expected)
	}
}
Пример #11
0
func TestLogEvents(t *testing.T) {
	e := New()
	eng := engine.New()
	if err := e.Install(eng); err != nil {
		t.Fatal(err)
	}

	for i := 0; i < eventsLimit+16; i++ {
		action := fmt.Sprintf("action_%d", i)
		id := fmt.Sprintf("cont_%d", i)
		from := fmt.Sprintf("image_%d", i)
		job := eng.Job("log", action, id, from)
		if err := job.Run(); err != nil {
			t.Fatal(err)
		}
	}
	time.Sleep(50 * time.Millisecond)
	if len(e.events) != eventsLimit {
		t.Fatalf("Must be %d events, got %d", eventsLimit, len(e.events))
	}

	job := eng.Job("events")
	job.SetenvInt64("since", 1)
	job.SetenvInt64("until", time.Now().Unix())
	buf := bytes.NewBuffer(nil)
	job.Stdout.Add(buf)
	if err := job.Run(); err != nil {
		t.Fatal(err)
	}
	buf = bytes.NewBuffer(buf.Bytes())
	dec := json.NewDecoder(buf)
	var msgs []utils.JSONMessage
	for {
		var jm utils.JSONMessage
		if err := dec.Decode(&jm); err != nil {
			if err == io.EOF {
				break
			}
			t.Fatal(err)
		}
		msgs = append(msgs, jm)
	}
	if len(msgs) != eventsLimit {
		t.Fatalf("Must be %d events, got %d", eventsLimit, len(msgs))
	}
	first := msgs[0]
	if first.Status != "action_16" {
		t.Fatalf("First action is %s, must be action_15", first.Status)
	}
	last := msgs[len(msgs)-1]
	if last.Status != "action_79" {
		t.Fatalf("First action is %s, must be action_79", first.Status)
	}
}
Пример #12
0
func mainDaemon() {
	if flag.NArg() != 0 {
		flag.Usage()
		return
	}
	eng := engine.New()
	signal.Trap(eng.Shutdown)
	// Load builtins
	if err := builtins.Register(eng); err != nil {
		log.Fatal(err)
	}

	// load the daemon in the background so we can immediately start
	// the http api so that connections don't fail while the daemon
	// is booting
	go func() {
		d, err := daemon.NewDaemon(daemonCfg, eng)
		if err != nil {
			log.Fatal(err)
		}
		if err := d.Install(eng); err != nil {
			log.Fatal(err)
		}
		// after the daemon is done setting up we can tell the api to start
		// accepting connections
		if err := eng.Job("acceptconnections").Run(); err != nil {
			log.Fatal(err)
		}
	}()
	// TODO actually have a resolved graphdriver to show?
	log.Printf("docker daemon: %s %s; execdriver: %s; graphdriver: %s",
		dockerversion.VERSION,
		dockerversion.GITCOMMIT,
		daemonCfg.ExecDriver,
		daemonCfg.GraphDriver,
	)

	// Serve api
	job := eng.Job("serveapi", flHosts...)
	job.SetenvBool("Logging", true)
	job.SetenvBool("EnableCors", *flEnableCors)
	job.Setenv("Version", dockerversion.VERSION)
	job.Setenv("SocketGroup", *flSocketGroup)

	job.SetenvBool("Tls", *flTls)
	job.SetenvBool("TlsVerify", *flTlsVerify)
	job.Setenv("TlsCa", *flCa)
	job.Setenv("TlsCert", *flCert)
	job.Setenv("TlsKey", *flKey)
	job.SetenvBool("BufferRequests", true)
	if err := job.Run(); err != nil {
		log.Fatal(err)
	}
}
Пример #13
0
func TestGetImagesJSONAll(t *testing.T) {
	eng := engine.New()
	allFilter := "-1"
	eng.Register("images", func(job *engine.Job) engine.Status {
		allFilter = job.Getenv("all")
		return engine.StatusOK
	})
	serveRequest("GET", "/images/json?all=1", nil, eng, t)
	if allFilter != "1" {
		t.Errorf("%#v", allFilter)
	}
}
Пример #14
0
func TestGetImagesJSONFilters(t *testing.T) {
	eng := engine.New()
	filter := "nothing"
	eng.Register("images", func(job *engine.Job) engine.Status {
		filter = job.Getenv("filters")
		return engine.StatusOK
	})
	serveRequest("GET", "/images/json?filters=nnnn", nil, eng, t)
	if filter != "nnnn" {
		t.Errorf("%#v", filter)
	}
}
Пример #15
0
func TestEventsCountJob(t *testing.T) {
	e := New()
	eng := engine.New()
	if err := e.Install(eng); err != nil {
		t.Fatal(err)
	}
	l1 := make(chan *utils.JSONMessage)
	l2 := make(chan *utils.JSONMessage)
	e.subscribe(l1)
	e.subscribe(l2)
	job := eng.Job("subscribers_count")
	env, _ := job.Stdout.AddEnv()
	if err := job.Run(); err != nil {
		t.Fatal(err)
	}
	count := env.GetInt("count")
	if count != 2 {
		t.Fatalf("There must be 2 subscribers, got %d", count)
	}
}
Пример #16
0
func TestGetEvents(t *testing.T) {
	eng := engine.New()
	var called bool
	eng.Register("events", func(job *engine.Job) engine.Status {
		called = true
		since := job.Getenv("since")
		if since != "1" {
			t.Fatalf("'since' should be 1, found %#v instead", since)
		}
		until := job.Getenv("until")
		if until != "0" {
			t.Fatalf("'until' should be 0, found %#v instead", until)
		}
		v := &engine.Env{}
		v.Set("since", since)
		v.Set("until", until)
		if _, err := v.WriteTo(job.Stdout); err != nil {
			return job.Error(err)
		}
		return engine.StatusOK
	})
	r := serveRequest("GET", "/events?since=1&until=0", nil, eng, t)
	if !called {
		t.Fatal("handler was not called")
	}
	assertContentType(r, "application/json", t)
	var stdout_json struct {
		Since int
		Until int
	}
	if err := json.Unmarshal(r.Body.Bytes(), &stdout_json); err != nil {
		t.Fatal(err)
	}
	if stdout_json.Since != 1 {
		t.Errorf("since != 1: %#v", stdout_json.Since)
	}
	if stdout_json.Until != 0 {
		t.Errorf("until != 0: %#v", stdout_json.Until)
	}
}
Пример #17
0
func TestDeleteContainers(t *testing.T) {
	eng := engine.New()
	name := "foo"
	var called bool
	eng.Register("delete", func(job *engine.Job) engine.Status {
		called = true
		if len(job.Args) == 0 {
			t.Fatalf("Job arguments is empty")
		}
		if job.Args[0] != name {
			t.Fatalf("name != '%s': %#v", name, job.Args[0])
		}
		return engine.StatusOK
	})
	r := serveRequest("DELETE", "/containers/"+name, nil, eng, t)
	if !called {
		t.Fatalf("handler was not called")
	}
	if r.Code != http.StatusNoContent {
		t.Fatalf("Got status %d, expected %d", r.Code, http.StatusNoContent)
	}
}