Browse code

Convert TestGetImagesJSON into several unit tests

Docker-DCO-1.1-Signed-off-by: Guilherme Salgado <gsalgado@gmail.com> (github: gsalgado)

Guilherme Salgado authored on 2014/07/02 17:01:19
Showing 2 changed files
... ...
@@ -7,11 +7,13 @@ import (
7 7
 	"io"
8 8
 	"net/http"
9 9
 	"net/http/httptest"
10
+	"reflect"
10 11
 	"strings"
11 12
 	"testing"
12 13
 
13 14
 	"github.com/dotcloud/docker/api"
14 15
 	"github.com/dotcloud/docker/engine"
16
+	"github.com/dotcloud/docker/pkg/version"
15 17
 )
16 18
 
17 19
 func TestGetBoolParam(t *testing.T) {
... ...
@@ -111,8 +113,105 @@ func TestGetInfo(t *testing.T) {
111 111
 	if v.GetInt("Containers") != 1 {
112 112
 		t.Fatalf("%#v\n", v)
113 113
 	}
114
-	if r.HeaderMap.Get("Content-Type") != "application/json" {
115
-		t.Fatalf("%#v\n", r)
114
+	assertContentType(r, "application/json", t)
115
+}
116
+
117
+func TestGetImagesJSON(t *testing.T) {
118
+	eng := engine.New()
119
+	var called bool
120
+	eng.Register("images", func(job *engine.Job) engine.Status {
121
+		called = true
122
+		v := createEnvFromGetImagesJSONStruct(sampleImage)
123
+		if _, err := v.WriteTo(job.Stdout); err != nil {
124
+			return job.Error(err)
125
+		}
126
+		return engine.StatusOK
127
+	})
128
+	r := serveRequest("GET", "/images/json", nil, eng, t)
129
+	if !called {
130
+		t.Fatal("handler was not called")
131
+	}
132
+	assertHttpNotError(r, t)
133
+	assertContentType(r, "application/json", t)
134
+	var observed getImagesJSONStruct
135
+	if err := json.Unmarshal(r.Body.Bytes(), &observed); err != nil {
136
+		t.Fatal(err)
137
+	}
138
+	if !reflect.DeepEqual(observed, sampleImage) {
139
+		t.Errorf("Expected %#v but got %#v", sampleImage, observed)
140
+	}
141
+}
142
+
143
+func TestGetImagesJSONFilter(t *testing.T) {
144
+	eng := engine.New()
145
+	filter := "nothing"
146
+	eng.Register("images", func(job *engine.Job) engine.Status {
147
+		filter = job.Getenv("filter")
148
+		return engine.StatusOK
149
+	})
150
+	serveRequest("GET", "/images/json?filter=aaaa", nil, eng, t)
151
+	if filter != "aaaa" {
152
+		t.Errorf("%#v", filter)
153
+	}
154
+}
155
+
156
+func TestGetImagesJSONFilters(t *testing.T) {
157
+	eng := engine.New()
158
+	filter := "nothing"
159
+	eng.Register("images", func(job *engine.Job) engine.Status {
160
+		filter = job.Getenv("filters")
161
+		return engine.StatusOK
162
+	})
163
+	serveRequest("GET", "/images/json?filters=nnnn", nil, eng, t)
164
+	if filter != "nnnn" {
165
+		t.Errorf("%#v", filter)
166
+	}
167
+}
168
+
169
+func TestGetImagesJSONAll(t *testing.T) {
170
+	eng := engine.New()
171
+	allFilter := "-1"
172
+	eng.Register("images", func(job *engine.Job) engine.Status {
173
+		allFilter = job.Getenv("all")
174
+		return engine.StatusOK
175
+	})
176
+	serveRequest("GET", "/images/json?all=1", nil, eng, t)
177
+	if allFilter != "1" {
178
+		t.Errorf("%#v", allFilter)
179
+	}
180
+}
181
+
182
+func TestGetImagesJSONLegacyFormat(t *testing.T) {
183
+	eng := engine.New()
184
+	var called bool
185
+	eng.Register("images", func(job *engine.Job) engine.Status {
186
+		called = true
187
+		outsLegacy := engine.NewTable("Created", 0)
188
+		outsLegacy.Add(createEnvFromGetImagesJSONStruct(sampleImage))
189
+		if _, err := outsLegacy.WriteListTo(job.Stdout); err != nil {
190
+			return job.Error(err)
191
+		}
192
+		return engine.StatusOK
193
+	})
194
+	r := serveRequestUsingVersion("GET", "/images/json", "1.6", nil, eng, t)
195
+	if !called {
196
+		t.Fatal("handler was not called")
197
+	}
198
+	assertHttpNotError(r, t)
199
+	assertContentType(r, "application/json", t)
200
+	images := engine.NewTable("Created", 0)
201
+	if _, err := images.ReadListFrom(r.Body.Bytes()); err != nil {
202
+		t.Fatal(err)
203
+	}
204
+	if images.Len() != 1 {
205
+		t.Fatalf("Expected 1 image, %d found", images.Len())
206
+	}
207
+	image := images.Data[0]
208
+	if image.Get("Tag") != "test-tag" {
209
+		t.Errorf("Expected tag 'test-tag', found '%s'", image.Get("Tag"))
210
+	}
211
+	if image.Get("Repository") != "test-name" {
212
+		t.Errorf("Expected repository 'test-name', found '%s'", image.Get("Repository"))
116 213
 	}
117 214
 }
118 215
 
... ...
@@ -123,12 +222,12 @@ func TestGetContainersByName(t *testing.T) {
123 123
 	eng.Register("container_inspect", func(job *engine.Job) engine.Status {
124 124
 		called = true
125 125
 		if job.Args[0] != name {
126
-			t.Fatalf("name != '%s': %#v", name, job.Args[0])
126
+			t.Errorf("name != '%s': %#v", name, job.Args[0])
127 127
 		}
128 128
 		if api.APIVERSION.LessThan("1.12") && !job.GetenvBool("dirty") {
129
-			t.Fatal("dirty env variable not set")
129
+			t.Errorf("dirty env variable not set")
130 130
 		} else if api.APIVERSION.GreaterThanOrEqualTo("1.12") && job.GetenvBool("dirty") {
131
-			t.Fatal("dirty env variable set when it shouldn't")
131
+			t.Errorf("dirty env variable set when it shouldn't")
132 132
 		}
133 133
 		v := &engine.Env{}
134 134
 		v.SetBool("dirty", true)
... ...
@@ -141,9 +240,7 @@ func TestGetContainersByName(t *testing.T) {
141 141
 	if !called {
142 142
 		t.Fatal("handler was not called")
143 143
 	}
144
-	if r.HeaderMap.Get("Content-Type") != "application/json" {
145
-		t.Fatalf("%#v\n", r)
146
-	}
144
+	assertContentType(r, "application/json", t)
147 145
 	var stdoutJson interface{}
148 146
 	if err := json.Unmarshal(r.Body.Bytes(), &stdoutJson); err != nil {
149 147
 		t.Fatalf("%#v", err)
... ...
@@ -178,21 +275,19 @@ func TestGetEvents(t *testing.T) {
178 178
 	if !called {
179 179
 		t.Fatal("handler was not called")
180 180
 	}
181
-	if r.HeaderMap.Get("Content-Type") != "application/json" {
182
-		t.Fatalf("%#v\n", r)
183
-	}
181
+	assertContentType(r, "application/json", t)
184 182
 	var stdout_json struct {
185 183
 		Since int
186 184
 		Until int
187 185
 	}
188 186
 	if err := json.Unmarshal(r.Body.Bytes(), &stdout_json); err != nil {
189
-		t.Fatalf("%#v", err)
187
+		t.Fatal(err)
190 188
 	}
191 189
 	if stdout_json.Since != 1 {
192
-		t.Fatalf("since != 1: %#v", stdout_json.Since)
190
+		t.Errorf("since != 1: %#v", stdout_json.Since)
193 191
 	}
194 192
 	if stdout_json.Until != 0 {
195
-		t.Fatalf("until != 0: %#v", stdout_json.Until)
193
+		t.Errorf("until != 0: %#v", stdout_json.Until)
196 194
 	}
197 195
 }
198 196
 
... ...
@@ -357,12 +452,16 @@ func TestGetImagesByName(t *testing.T) {
357 357
 }
358 358
 
359 359
 func serveRequest(method, target string, body io.Reader, eng *engine.Engine, t *testing.T) *httptest.ResponseRecorder {
360
+	return serveRequestUsingVersion(method, target, api.APIVERSION, body, eng, t)
361
+}
362
+
363
+func serveRequestUsingVersion(method, target string, version version.Version, body io.Reader, eng *engine.Engine, t *testing.T) *httptest.ResponseRecorder {
360 364
 	r := httptest.NewRecorder()
361 365
 	req, err := http.NewRequest(method, target, body)
362 366
 	if err != nil {
363 367
 		t.Fatal(err)
364 368
 	}
365
-	if err := ServeRequest(eng, api.APIVERSION, r, req); err != nil {
369
+	if err := ServeRequest(eng, version, r, req); err != nil {
366 370
 		t.Fatal(err)
367 371
 	}
368 372
 	return r
... ...
@@ -388,3 +487,46 @@ func toJson(data interface{}, t *testing.T) io.Reader {
388 388
 	}
389 389
 	return &buf
390 390
 }
391
+
392
+func assertContentType(recorder *httptest.ResponseRecorder, content_type string, t *testing.T) {
393
+	if recorder.HeaderMap.Get("Content-Type") != content_type {
394
+		t.Fatalf("%#v\n", recorder)
395
+	}
396
+}
397
+
398
+// XXX: Duplicated from integration/utils_test.go, but maybe that's OK as that
399
+// should die as soon as we converted all integration tests?
400
+// assertHttpNotError expect the given response to not have an error.
401
+// Otherwise the it causes the test to fail.
402
+func assertHttpNotError(r *httptest.ResponseRecorder, t *testing.T) {
403
+	// Non-error http status are [200, 400)
404
+	if r.Code < http.StatusOK || r.Code >= http.StatusBadRequest {
405
+		t.Fatal(fmt.Errorf("Unexpected http error: %v", r.Code))
406
+	}
407
+}
408
+
409
+func createEnvFromGetImagesJSONStruct(data getImagesJSONStruct) *engine.Env {
410
+	v := &engine.Env{}
411
+	v.SetList("RepoTags", data.RepoTags)
412
+	v.Set("Id", data.Id)
413
+	v.SetInt64("Created", data.Created)
414
+	v.SetInt64("Size", data.Size)
415
+	v.SetInt64("VirtualSize", data.VirtualSize)
416
+	return v
417
+}
418
+
419
+type getImagesJSONStruct struct {
420
+	RepoTags    []string
421
+	Id          string
422
+	Created     int64
423
+	Size        int64
424
+	VirtualSize int64
425
+}
426
+
427
+var sampleImage getImagesJSONStruct = getImagesJSONStruct{
428
+	RepoTags:    []string{"test-name:test-tag"},
429
+	Id:          "ID",
430
+	Created:     999,
431
+	Size:        777,
432
+	VirtualSize: 666,
433
+}
... ...
@@ -9,7 +9,6 @@ import (
9 9
 	"net"
10 10
 	"net/http"
11 11
 	"net/http/httptest"
12
-	"strings"
13 12
 	"testing"
14 13
 	"time"
15 14
 
... ...
@@ -20,109 +19,6 @@ import (
20 20
 	"github.com/dotcloud/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
21 21
 )
22 22
 
23
-func TestGetImagesJSON(t *testing.T) {
24
-	eng := NewTestEngine(t)
25
-	defer mkDaemonFromEngine(eng, t).Nuke()
26
-
27
-	job := eng.Job("images")
28
-	initialImages, err := job.Stdout.AddListTable()
29
-	if err != nil {
30
-		t.Fatal(err)
31
-	}
32
-	if err := job.Run(); err != nil {
33
-		t.Fatal(err)
34
-	}
35
-
36
-	req, err := http.NewRequest("GET", "/images/json?all=0", nil)
37
-	if err != nil {
38
-		t.Fatal(err)
39
-	}
40
-
41
-	r := httptest.NewRecorder()
42
-
43
-	if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
44
-		t.Fatal(err)
45
-	}
46
-	assertHttpNotError(r, t)
47
-
48
-	images := engine.NewTable("Created", 0)
49
-	if _, err := images.ReadListFrom(r.Body.Bytes()); err != nil {
50
-		t.Fatal(err)
51
-	}
52
-
53
-	if images.Len() != initialImages.Len() {
54
-		t.Errorf("Expected %d image, %d found", initialImages.Len(), images.Len())
55
-	}
56
-
57
-	found := false
58
-	for _, img := range images.Data {
59
-		if strings.Contains(img.GetList("RepoTags")[0], unitTestImageName) {
60
-			found = true
61
-			break
62
-		}
63
-	}
64
-	if !found {
65
-		t.Errorf("Expected image %s, %+v found", unitTestImageName, images)
66
-	}
67
-
68
-	r2 := httptest.NewRecorder()
69
-
70
-	// all=1
71
-
72
-	initialImages = getAllImages(eng, t)
73
-
74
-	req2, err := http.NewRequest("GET", "/images/json?all=true", nil)
75
-	if err != nil {
76
-		t.Fatal(err)
77
-	}
78
-	if err := server.ServeRequest(eng, api.APIVERSION, r2, req2); err != nil {
79
-		t.Fatal(err)
80
-	}
81
-	assertHttpNotError(r2, t)
82
-
83
-	images2 := engine.NewTable("Id", 0)
84
-	if _, err := images2.ReadListFrom(r2.Body.Bytes()); err != nil {
85
-		t.Fatal(err)
86
-	}
87
-
88
-	if images2.Len() != initialImages.Len() {
89
-		t.Errorf("Expected %d image, %d found", initialImages.Len(), images2.Len())
90
-	}
91
-
92
-	found = false
93
-	for _, img := range images2.Data {
94
-		if img.Get("Id") == unitTestImageID {
95
-			found = true
96
-			break
97
-		}
98
-	}
99
-	if !found {
100
-		t.Errorf("Retrieved image Id differs, expected %s, received %+v", unitTestImageID, images2)
101
-	}
102
-
103
-	r3 := httptest.NewRecorder()
104
-
105
-	// filter=a
106
-	req3, err := http.NewRequest("GET", "/images/json?filter=aaaaaaaaaa", nil)
107
-	if err != nil {
108
-		t.Fatal(err)
109
-	}
110
-
111
-	if err := server.ServeRequest(eng, api.APIVERSION, r3, req3); err != nil {
112
-		t.Fatal(err)
113
-	}
114
-	assertHttpNotError(r3, t)
115
-
116
-	images3 := engine.NewTable("Id", 0)
117
-	if _, err := images3.ReadListFrom(r3.Body.Bytes()); err != nil {
118
-		t.Fatal(err)
119
-	}
120
-
121
-	if images3.Len() != 0 {
122
-		t.Errorf("Expected 0 image, %d found", images3.Len())
123
-	}
124
-}
125
-
126 23
 func TestGetContainersJSON(t *testing.T) {
127 24
 	eng := NewTestEngine(t)
128 25
 	defer mkDaemonFromEngine(eng, t).Nuke()