github.com/wozhu6104/docker@v20.10.10+incompatible/client/service_logs_test.go (about) 1 package client // import "github.com/docker/docker/client" 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "log" 10 "net/http" 11 "os" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/docker/docker/api/types" 17 "github.com/docker/docker/errdefs" 18 "gotest.tools/v3/assert" 19 is "gotest.tools/v3/assert/cmp" 20 ) 21 22 func TestServiceLogsError(t *testing.T) { 23 client := &Client{ 24 client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), 25 } 26 _, err := client.ServiceLogs(context.Background(), "service_id", types.ContainerLogsOptions{}) 27 if !errdefs.IsSystem(err) { 28 t.Fatalf("expected a Server Error, got %[1]T: %[1]v", err) 29 } 30 _, err = client.ServiceLogs(context.Background(), "service_id", types.ContainerLogsOptions{ 31 Since: "2006-01-02TZ", 32 }) 33 assert.Check(t, is.ErrorContains(err, `parsing time "2006-01-02TZ"`)) 34 } 35 36 func TestServiceLogs(t *testing.T) { 37 expectedURL := "/services/service_id/logs" 38 cases := []struct { 39 options types.ContainerLogsOptions 40 expectedQueryParams map[string]string 41 expectedError string 42 }{ 43 { 44 expectedQueryParams: map[string]string{ 45 "tail": "", 46 }, 47 }, 48 { 49 options: types.ContainerLogsOptions{ 50 Tail: "any", 51 }, 52 expectedQueryParams: map[string]string{ 53 "tail": "any", 54 }, 55 }, 56 { 57 options: types.ContainerLogsOptions{ 58 ShowStdout: true, 59 ShowStderr: true, 60 Timestamps: true, 61 Details: true, 62 Follow: true, 63 }, 64 expectedQueryParams: map[string]string{ 65 "tail": "", 66 "stdout": "1", 67 "stderr": "1", 68 "timestamps": "1", 69 "details": "1", 70 "follow": "1", 71 }, 72 }, 73 { 74 options: types.ContainerLogsOptions{ 75 // timestamp will be passed as is 76 Since: "1136073600.000000001", 77 }, 78 expectedQueryParams: map[string]string{ 79 "tail": "", 80 "since": "1136073600.000000001", 81 }, 82 }, 83 { 84 options: types.ContainerLogsOptions{ 85 // An complete invalid date will not be passed 86 Since: "invalid value", 87 }, 88 expectedError: `invalid value for "since": failed to parse value as time or duration: "invalid value"`, 89 }, 90 } 91 for _, logCase := range cases { 92 client := &Client{ 93 client: newMockClient(func(r *http.Request) (*http.Response, error) { 94 if !strings.HasPrefix(r.URL.Path, expectedURL) { 95 return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, r.URL) 96 } 97 // Check query parameters 98 query := r.URL.Query() 99 for key, expected := range logCase.expectedQueryParams { 100 actual := query.Get(key) 101 if actual != expected { 102 return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual) 103 } 104 } 105 return &http.Response{ 106 StatusCode: http.StatusOK, 107 Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))), 108 }, nil 109 }), 110 } 111 body, err := client.ServiceLogs(context.Background(), "service_id", logCase.options) 112 if logCase.expectedError != "" { 113 assert.Check(t, is.Error(err, logCase.expectedError)) 114 continue 115 } 116 assert.NilError(t, err) 117 defer body.Close() 118 content, err := ioutil.ReadAll(body) 119 assert.NilError(t, err) 120 assert.Check(t, is.Contains(string(content), "response")) 121 } 122 } 123 124 func ExampleClient_ServiceLogs_withTimeout() { 125 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 126 defer cancel() 127 128 client, _ := NewClientWithOpts(FromEnv) 129 reader, err := client.ServiceLogs(ctx, "service_id", types.ContainerLogsOptions{}) 130 if err != nil { 131 log.Fatal(err) 132 } 133 134 _, err = io.Copy(os.Stdout, reader) 135 if err != nil && err != io.EOF { 136 log.Fatal(err) 137 } 138 }