diff --git a/backends/dockerclient.go b/backends/dockerclient.go index be26bbf682..38127c4474 100644 --- a/backends/dockerclient.go +++ b/backends/dockerclient.go @@ -204,7 +204,7 @@ func (c *container) start(ctx *beam.Message) error { func (c *container) stop(ctx *beam.Message) error { path := fmt.Sprintf("/containers/%s/stop", c.id) - resp, err := c.backend.client.call("POST", path, "{}") + resp, err := c.backend.client.call("POST", path, "") if err != nil { return err } diff --git a/backends/dockerclient_test.go b/backends/dockerclient_test.go new file mode 100644 index 0000000000..4c5948893a --- /dev/null +++ b/backends/dockerclient_test.go @@ -0,0 +1,186 @@ +package backends + +import ( + "github.com/docker/libswarm/beam" + + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "reflect" + "strings" + "testing" +) + +type requestStub struct { + reqMethod string + reqPath string + reqBody string + + resStatus int + resBody string +} + +func TestBackendSpawn(t *testing.T) { + instance(t, nil) +} + +func TestAttachAndStart(t *testing.T) { + i := instance(t, nil) + _, _, err := i.Attach("") + if err != nil { + t.Fatal(err) + } + err = i.Start() + if err != nil { + t.Fatal(err) + } +} + +func TestLs(t *testing.T) { + server := makeServer(t, &requestStub{ + reqMethod: "GET", + reqPath: "/containers/json", + resBody: ` + [ + {"Names": ["/foo"]}, + {"Names": ["/bar"]} + ] + `, + }) + i := instance(t, server) + names, err := i.Ls() + if err != nil { + t.Fatal(err) + } + expected := []string{"foo", "bar"} + if !reflect.DeepEqual(names, expected) { + t.Fatalf("expected %#v, got %#v", expected, names) + } +} + +func TestSpawn(t *testing.T) { + server := makeServer(t, &requestStub{ + reqMethod: "POST", + reqPath: "/containers/create", + reqBody: "{}", + + resStatus: 201, + resBody: "{}", + }) + i := instance(t, server) + _, err := i.Spawn("{}") + if err != nil { + t.Fatal(err) + } +} + +func TestAttachToChild(t *testing.T) { + name := "foo" + server := makeServer(t, &requestStub{ + reqMethod: "GET", + reqPath: fmt.Sprintf("/containers/%s/json", name), + + resBody: "{}", + }) + i := instance(t, server) + child(t, server, i, name) +} + +func TestStartChild(t *testing.T) { + name := "foo" + server := makeServer(t, &requestStub{ + reqMethod: "GET", + reqPath: fmt.Sprintf("/containers/%s/json", name), + + resBody: "{}", + }, &requestStub{ + reqMethod: "POST", + reqPath: fmt.Sprintf("/containers/%s/start", name), + reqBody: "{}", + + resStatus: 204, + }) + i := instance(t, server) + c := child(t, server, i, name) + err := c.Start() + if err != nil { + t.Fatal(err) + } +} + +func TestStopChild(t *testing.T) { + name := "foo" + server := makeServer(t, &requestStub{ + reqMethod: "GET", + reqPath: fmt.Sprintf("/containers/%s/json", name), + + resBody: "{}", + }, &requestStub{ + reqMethod: "POST", + reqPath: fmt.Sprintf("/containers/%s/stop", name), + + resStatus: 204, + }) + i := instance(t, server) + c := child(t, server, i, name) + err := c.Stop() + if err != nil { + t.Fatal(err) + } +} + +func makeServer(t *testing.T, stubs ...*requestStub) *httptest.Server { + for _, stub := range stubs { + stub.reqPath = fmt.Sprintf("/v1.11%s", stub.reqPath) + } + + stubSummaries := []string{} + for _, stub := range stubs { + stubSummaries = append(stubSummaries, fmt.Sprintf("%s %s", stub.reqMethod, stub.reqPath)) + } + + return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + for _, stub := range stubs { + if r.Method == stub.reqMethod && r.URL.Path == stub.reqPath { + body, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Fatal(err) + } + if string(body) != stub.reqBody { + t.Fatalf("expected body: %#v, got body: %#v", stub.reqBody, string(body)) + } + + if stub.resStatus > 0 { + w.WriteHeader(stub.resStatus) + } + w.Write([]byte(stub.resBody)) + return + } + } + + t.Fatalf("Unexpected request: '%s %s'.\nStubs: %#v", r.Method, r.URL.Path, stubSummaries) + })) +} + +func instance(t *testing.T, server *httptest.Server) *beam.Object { + url := "tcp://localhost:4243" + if server != nil { + url = strings.Replace(server.URL, "http://", "tcp://", 1) + } + + backend := DockerClient() + instance, err := beam.Obj(backend).Spawn(url) + if err != nil { + t.Fatal(err) + } + return instance +} + +func child(t *testing.T, server *httptest.Server, i *beam.Object, name string) *beam.Object { + _, child, err := i.Attach(name) + if err != nil { + t.Fatal(err) + } + return child +}