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