github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/client/container_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 TestContainerLogsNotFoundError(t *testing.T) { 23 client := &Client{ 24 client: newMockClient(errorMock(http.StatusNotFound, "Not found")), 25 } 26 _, err := client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{}) 27 if !IsErrNotFound(err) { 28 t.Fatalf("expected a not found error, got %v", err) 29 } 30 } 31 32 func TestContainerLogsError(t *testing.T) { 33 client := &Client{ 34 client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), 35 } 36 _, err := client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{}) 37 if !errdefs.IsSystem(err) { 38 t.Fatalf("expected a Server Error, got %[1]T: %[1]v", err) 39 } 40 _, err = client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{ 41 Since: "2006-01-02TZ", 42 }) 43 assert.Check(t, is.ErrorContains(err, `parsing time "2006-01-02TZ"`)) 44 _, err = client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{ 45 Until: "2006-01-02TZ", 46 }) 47 assert.Check(t, is.ErrorContains(err, `parsing time "2006-01-02TZ"`)) 48 } 49 50 func TestContainerLogs(t *testing.T) { 51 expectedURL := "/containers/container_id/logs" 52 cases := []struct { 53 options types.ContainerLogsOptions 54 expectedQueryParams map[string]string 55 expectedError string 56 }{ 57 { 58 expectedQueryParams: map[string]string{ 59 "tail": "", 60 }, 61 }, 62 { 63 options: types.ContainerLogsOptions{ 64 Tail: "any", 65 }, 66 expectedQueryParams: map[string]string{ 67 "tail": "any", 68 }, 69 }, 70 { 71 options: types.ContainerLogsOptions{ 72 ShowStdout: true, 73 ShowStderr: true, 74 Timestamps: true, 75 Details: true, 76 Follow: true, 77 }, 78 expectedQueryParams: map[string]string{ 79 "tail": "", 80 "stdout": "1", 81 "stderr": "1", 82 "timestamps": "1", 83 "details": "1", 84 "follow": "1", 85 }, 86 }, 87 { 88 options: types.ContainerLogsOptions{ 89 // timestamp will be passed as is 90 Since: "1136073600.000000001", 91 }, 92 expectedQueryParams: map[string]string{ 93 "tail": "", 94 "since": "1136073600.000000001", 95 }, 96 }, 97 { 98 options: types.ContainerLogsOptions{ 99 // timestamp will be passed as is 100 Until: "1136073600.000000001", 101 }, 102 expectedQueryParams: map[string]string{ 103 "tail": "", 104 "until": "1136073600.000000001", 105 }, 106 }, 107 { 108 options: types.ContainerLogsOptions{ 109 // An complete invalid date will not be passed 110 Since: "invalid value", 111 }, 112 expectedError: `invalid value for "since": failed to parse value as time or duration: "invalid value"`, 113 }, 114 { 115 options: types.ContainerLogsOptions{ 116 // An complete invalid date will not be passed 117 Until: "invalid value", 118 }, 119 expectedError: `invalid value for "until": failed to parse value as time or duration: "invalid value"`, 120 }, 121 } 122 for _, logCase := range cases { 123 client := &Client{ 124 client: newMockClient(func(r *http.Request) (*http.Response, error) { 125 if !strings.HasPrefix(r.URL.Path, expectedURL) { 126 return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, r.URL) 127 } 128 // Check query parameters 129 query := r.URL.Query() 130 for key, expected := range logCase.expectedQueryParams { 131 actual := query.Get(key) 132 if actual != expected { 133 return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual) 134 } 135 } 136 return &http.Response{ 137 StatusCode: http.StatusOK, 138 Body: ioutil.NopCloser(bytes.NewReader([]byte("response"))), 139 }, nil 140 }), 141 } 142 body, err := client.ContainerLogs(context.Background(), "container_id", logCase.options) 143 if logCase.expectedError != "" { 144 assert.Check(t, is.Error(err, logCase.expectedError)) 145 continue 146 } 147 assert.NilError(t, err) 148 defer body.Close() 149 content, err := ioutil.ReadAll(body) 150 assert.NilError(t, err) 151 assert.Check(t, is.Contains(string(content), "response")) 152 } 153 } 154 155 func ExampleClient_ContainerLogs_withTimeout() { 156 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 157 defer cancel() 158 159 client, _ := NewClientWithOpts(FromEnv) 160 reader, err := client.ContainerLogs(ctx, "container_id", types.ContainerLogsOptions{}) 161 if err != nil { 162 log.Fatal(err) 163 } 164 165 _, err = io.Copy(os.Stdout, reader) 166 if err != nil && err != io.EOF { 167 log.Fatal(err) 168 } 169 }