diff --git a/client/client_mock_test.go b/client/client_mock_test.go new file mode 100644 index 000000000..c3dfc1704 --- /dev/null +++ b/client/client_mock_test.go @@ -0,0 +1,42 @@ +package client + +import ( + "bytes" + "encoding/json" + "io/ioutil" + "net/http" + + "github.com/alibaba/pouch/apis/types" +) + +type transportFunc func(*http.Request) (*http.Response, error) + +func (transFunc transportFunc) RoundTrip(req *http.Request) (*http.Response, error) { + return transFunc(req) +} + +func newMockClient(handler func(*http.Request) (*http.Response, error)) *http.Client { + return &http.Client{ + Transport: transportFunc(handler), + } +} + +func errorMockResponse(statusCode int, message string) func(req *http.Request) (*http.Response, error) { + return func(req *http.Request) (*http.Response, error) { + header := http.Header{} + header.Set("Content-Type", "application/json") + + body, err := json.Marshal(&types.Error{ + Message: message, + }) + if err != nil { + return nil, err + } + + return &http.Response{ + StatusCode: statusCode, + Body: ioutil.NopCloser(bytes.NewReader(body)), + Header: header, + }, nil + } +} diff --git a/client/container.go b/client/container.go index 06b2ec9a2..ede80e0cb 100644 --- a/client/container.go +++ b/client/container.go @@ -37,19 +37,6 @@ func (client *APIClient) ContainerCreate(ctx context.Context, config types.Conta return container, err } -// ContainerStart starts a created container. -func (client *APIClient) ContainerStart(ctx context.Context, name, detachKeys string) error { - q := url.Values{} - if detachKeys != "" { - q.Set("detachKeys", detachKeys) - } - - resp, err := client.post(ctx, "/containers/"+name+"/start", q, nil, nil) - ensureCloseReader(resp) - - return err -} - // ContainerStop stops a container. func (client *APIClient) ContainerStop(ctx context.Context, name string, timeout string) error { q := url.Values{} diff --git a/client/container_start.go b/client/container_start.go new file mode 100644 index 000000000..1c448af91 --- /dev/null +++ b/client/container_start.go @@ -0,0 +1,19 @@ +package client + +import ( + "context" + "net/url" +) + +// ContainerStart starts a created container. +func (client *APIClient) ContainerStart(ctx context.Context, name, detachKeys string) error { + q := url.Values{} + if detachKeys != "" { + q.Set("detachKeys", detachKeys) + } + + resp, err := client.post(ctx, "/containers/"+name+"/start", q, nil, nil) + ensureCloseReader(resp) + + return err +} diff --git a/client/container_start_test.go b/client/container_start_test.go new file mode 100644 index 000000000..3964974a1 --- /dev/null +++ b/client/container_start_test.go @@ -0,0 +1,50 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" + "testing" +) + +func TestContainerStartError(t *testing.T) { + client := &APIClient{ + HTTPCli: newMockClient(errorMockResponse(http.StatusInternalServerError, "Server error")), + } + err := client.ContainerStart(context.Background(), "nothing", "") + if err == nil || !strings.Contains(err.Error(), "Server error") { + t.Fatalf("expected a Server Error, got %v", err) + } +} + +func TestContainerStart(t *testing.T) { + expectedURL := "/containers/container_id/start" + + httpClient := newMockClient(func(req *http.Request) (*http.Response, error) { + if !strings.HasPrefix(req.URL.Path, expectedURL) { + return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) + } + if req.Header.Get("Content-Type") == "application/json" { + var startConfig interface{} + if err := json.NewDecoder(req.Body).Decode(&startConfig); err != nil { + return nil, fmt.Errorf("failed to parse json: %v", err) + } + } + return &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), + }, nil + }) + + client := &APIClient{ + HTTPCli: httpClient, + } + + if err := client.ContainerStart(context.Background(), "container_id", ""); err != nil { + t.Fatal(err) + } +}