Browse code

Re-enable api integration tests using only public remote API.

Solomon Hykes authored on 2013/11/16 09:05:57
Showing 3 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,20 @@
0
+package docker
1
+
2
+import (
3
+	"testing"
4
+)
5
+
6
+func TestJsonContentType(t *testing.T) {
7
+	if !matchesContentType("application/json", "application/json") {
8
+		t.Fail()
9
+	}
10
+
11
+	if !matchesContentType("application/json; charset=utf-8", "application/json") {
12
+		t.Fail()
13
+	}
14
+
15
+	if matchesContentType("dockerapplication/json", "application/json") {
16
+		t.Fail()
17
+	}
18
+}
19
+
... ...
@@ -1,83 +1,73 @@
1 1
 package docker
2 2
 
3 3
 import (
4
-	_ "archive/tar"
5
-	_ "bufio"
6
-	_ "bytes"
4
+	"archive/tar"
5
+	"bufio"
6
+	"bytes"
7 7
 	"encoding/json"
8
+	"fmt"
8 9
 	"github.com/dotcloud/docker"
9 10
 	"github.com/dotcloud/docker/utils"
10 11
 	"io"
11
-	_ "net"
12
+	"net"
12 13
 	"net/http"
13 14
 	"net/http/httptest"
14
-	_ "os"
15
-	_ "path"
16
-	_ "strings"
15
+	"strings"
17 16
 	"testing"
18 17
 	"time"
19 18
 )
20 19
 
21
-/*
22
-func TestGetVersion(t *testing.T) {
23
-	runtime := mkRuntime()
24
-	defer nuke(runtime)
25 20
 
26
-	srv := &docker.Server{runtime: runtime}
21
+func TestGetVersion(t *testing.T) {
22
+	eng := NewTestEngine(t)
23
+	defer mkRuntimeFromEngine(eng, t).Nuke()
24
+	srv := mkServerFromEngine(eng, t)
27 25
 
28 26
 	var err error
29 27
 	r := httptest.NewRecorder()
30 28
 
31
-	// FIXME getting the version should require an actual running Server
32
-	if err := getVersion(srv, docker.APIVERSION, r, nil, nil); err != nil {
33
-		t.Fatal(err)
34
-	}
35
-
36
-	v := &APIVersion{}
37
-	if err = json.Unmarshal(r.Body.Bytes(), v); err != nil {
29
+	req, err := http.NewRequest("GET", "/version", nil)
30
+	if err != nil {
38 31
 		t.Fatal(err)
39 32
 	}
40
-	if v.Version != VERSION {
41
-		t.Errorf("Expected version %s, %s found", VERSION, v.Version)
42
-	}
43
-}
44
-
45
-	var err error
46
-	r := httptest.NewRecorder()
47
-
48 33
 	// FIXME getting the version should require an actual running Server
49
-	if err := getVersion(&docker.Server{}, docker.APIVERSION, r, nil, nil); err != nil {
34
+	if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
50 35
 		t.Fatal(err)
51 36
 	}
37
+	assertHttpNotError(r, t)
52 38
 
53
-	v := &APIVersion{}
39
+	v := &docker.APIVersion{}
54 40
 	if err = json.Unmarshal(r.Body.Bytes(), v); err != nil {
55 41
 		t.Fatal(err)
56 42
 	}
57
-	if v.Version != VERSION {
58
-		t.Errorf("Expected version %s, %s found", VERSION, v.Version)
43
+	if v.Version != docker.VERSION {
44
+		t.Errorf("Expected version %s, %s found", docker.VERSION, v.Version)
59 45
 	}
60 46
 }
61 47
 
62 48
 
63 49
 func TestGetInfo(t *testing.T) {
64
-	runtime := mkRuntime(t)
65
-	defer nuke(runtime)
66
-
67
-	srv := &docker.Server{runtime: runtime}
50
+	eng := NewTestEngine(t)
51
+	defer mkRuntimeFromEngine(eng, t).Nuke()
52
+	srv := mkServerFromEngine(eng, t)
68 53
 
69
-	initialImages, err := srv.runtime.graph.Map()
54
+	initialImages, err := srv.Images(false, "")
70 55
 	if err != nil {
71 56
 		t.Fatal(err)
72 57
 	}
73 58
 
59
+	req, err := http.NewRequest("GET", "/info", nil)
60
+	if err != nil {
61
+		t.Fatal(err)
62
+	}
74 63
 	r := httptest.NewRecorder()
75 64
 
76
-	if err := getInfo(srv, docker.APIVERSION, r, nil, nil); err != nil {
65
+	if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
77 66
 		t.Fatal(err)
78 67
 	}
68
+        assertHttpNotError(r, t)
79 69
 
80
-	infos := &APIInfo{}
70
+	infos := &docker.APIInfo{}
81 71
 	err = json.Unmarshal(r.Body.Bytes(), infos)
82 72
 	if err != nil {
83 73
 		t.Fatal(err)
... ...
@@ -86,7 +76,6 @@ func TestGetInfo(t *testing.T) {
86 86
 		t.Errorf("Expected images: %d, %d found", len(initialImages), infos.Images)
87 87
 	}
88 88
 }
89
-*/
90 89
 
91 90
 func TestGetEvents(t *testing.T) {
92 91
 	eng := NewTestEngine(t)
... ...
@@ -116,6 +105,7 @@ func TestGetEvents(t *testing.T) {
116 116
 		if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
117 117
 			t.Fatal(err)
118 118
 		}
119
+		assertHttpNotError(r, t)
119 120
 	})
120 121
 
121 122
 	dec := json.NewDecoder(r.Body)
... ...
@@ -133,13 +123,10 @@ func TestGetEvents(t *testing.T) {
133 133
 
134 134
 }
135 135
 
136
-/*
137
-
138 136
 func TestGetImagesJSON(t *testing.T) {
139
-	runtime := mkRuntime(t)
140
-	defer nuke(runtime)
141
-
142
-	srv := &docker.Server{runtime: runtime}
137
+	eng := NewTestEngine(t)
138
+	defer mkRuntimeFromEngine(eng, t).Nuke()
139
+	srv := mkServerFromEngine(eng, t)
143 140
 
144 141
 	// all=0
145 142
 
... ...
@@ -155,11 +142,12 @@ func TestGetImagesJSON(t *testing.T) {
155 155
 
156 156
 	r := httptest.NewRecorder()
157 157
 
158
-	if err := getImagesJSON(srv, docker.APIVERSION, r, req, nil); err != nil {
158
+	if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
159 159
 		t.Fatal(err)
160 160
 	}
161
+        assertHttpNotError(r, t)
161 162
 
162
-	images := []APIImages{}
163
+	images := []docker.APIImages{}
163 164
 	if err := json.Unmarshal(r.Body.Bytes(), &images); err != nil {
164 165
 		t.Fatal(err)
165 166
 	}
... ...
@@ -192,12 +180,13 @@ func TestGetImagesJSON(t *testing.T) {
192 192
 	if err != nil {
193 193
 		t.Fatal(err)
194 194
 	}
195
-
196
-	if err := getImagesJSON(srv, docker.APIVERSION, r2, req2, nil); err != nil {
195
+	if err := docker.ServeRequest(srv, docker.APIVERSION, r2, req2); err != nil {
197 196
 		t.Fatal(err)
198 197
 	}
198
+        assertHttpNotError(r2, t)
199 199
 
200
-	images2 := []APIImages{}
200
+
201
+	images2 := []docker.APIImages{}
201 202
 	if err := json.Unmarshal(r2.Body.Bytes(), &images2); err != nil {
202 203
 		t.Fatal(err)
203 204
 	}
... ...
@@ -208,13 +197,13 @@ func TestGetImagesJSON(t *testing.T) {
208 208
 
209 209
 	found = false
210 210
 	for _, img := range images2 {
211
-		if img.ID == GetTestImage(runtime).ID {
211
+		if img.ID == unitTestImageID {
212 212
 			found = true
213 213
 			break
214 214
 		}
215 215
 	}
216 216
 	if !found {
217
-		t.Errorf("Retrieved image Id differs, expected %s, received %+v", GetTestImage(runtime).ID, images2)
217
+		t.Errorf("Retrieved image Id differs, expected %s, received %+v", unitTestImageID, images2)
218 218
 	}
219 219
 
220 220
 	r3 := httptest.NewRecorder()
... ...
@@ -225,11 +214,12 @@ func TestGetImagesJSON(t *testing.T) {
225 225
 		t.Fatal(err)
226 226
 	}
227 227
 
228
-	if err := getImagesJSON(srv, docker.APIVERSION, r3, req3, nil); err != nil {
229
-		t.Fatal(err)
230
-	}
228
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r3, req3); err != nil {
229
+            t.Fatal(err)
230
+        }
231
+        assertHttpNotError(r3, t)
231 232
 
232
-	images3 := []APIImages{}
233
+	images3 := []docker.APIImages{}
233 234
 	if err := json.Unmarshal(r3.Body.Bytes(), &images3); err != nil {
234 235
 		t.Fatal(err)
235 236
 	}
... ...
@@ -246,34 +236,32 @@ func TestGetImagesJSON(t *testing.T) {
246 246
 		t.Fatal(err)
247 247
 	}
248 248
 
249
-	err = getImagesJSON(srv, docker.APIVERSION, r4, req4, nil)
250
-	if err == nil {
251
-		t.Fatalf("Error expected, received none")
252
-	}
253
-
254
-	if !strings.HasPrefix(err.Error(), "Bad parameter") {
255
-		t.Fatalf("Error should starts with \"Bad parameter\"")
249
+	if err := docker.ServeRequest(srv, docker.APIVERSION, r4, req4); err != nil {
250
+		t.Fatal(err)
256 251
 	}
257
-	http.Error(r4, err.Error(), http.StatusBadRequest)
258
-
252
+	// Don't assert against HTTP error since we expect an error
259 253
 	if r4.Code != http.StatusBadRequest {
260 254
 		t.Fatalf("%d Bad Request expected, received %d\n", http.StatusBadRequest, r4.Code)
261 255
 	}
262 256
 }
263 257
 
264 258
 func TestGetImagesHistory(t *testing.T) {
265
-	runtime := mkRuntime(t)
266
-	defer nuke(runtime)
267
-
268
-	srv := &docker.Server{runtime: runtime}
259
+	eng := NewTestEngine(t)
260
+	defer mkRuntimeFromEngine(eng, t).Nuke()
261
+	srv := mkServerFromEngine(eng, t)
269 262
 
270 263
 	r := httptest.NewRecorder()
271 264
 
272
-	if err := getImagesHistory(srv, docker.APIVERSION, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
265
+	req, err := http.NewRequest("GET", fmt.Sprintf("/images/%s/history", unitTestImageName), nil)
266
+	if err != nil {
267
+		t.Fatal(err)
268
+	}
269
+	if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
273 270
 		t.Fatal(err)
274 271
 	}
272
+        assertHttpNotError(r, t)
275 273
 
276
-	history := []APIHistory{}
274
+	history := []docker.APIHistory{}
277 275
 	if err := json.Unmarshal(r.Body.Bytes(), &history); err != nil {
278 276
 		t.Fatal(err)
279 277
 	}
... ...
@@ -283,15 +271,20 @@ func TestGetImagesHistory(t *testing.T) {
283 283
 }
284 284
 
285 285
 func TestGetImagesByName(t *testing.T) {
286
-	runtime := mkRuntime(t)
287
-	defer nuke(runtime)
286
+        eng := NewTestEngine(t)
287
+        defer mkRuntimeFromEngine(eng, t).Nuke()
288
+        srv := mkServerFromEngine(eng, t)
288 289
 
289
-	srv := &docker.Server{runtime: runtime}
290
+	req, err := http.NewRequest("GET", "/images/"+unitTestImageName+"/json", nil)
291
+	if err != nil {
292
+	    t.Fatal(err)
293
+	}
290 294
 
291 295
 	r := httptest.NewRecorder()
292
-	if err := getImagesByName(srv, docker.APIVERSION, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
293
-		t.Fatal(err)
294
-	}
296
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
297
+            t.Fatal(err)
298
+        }
299
+        assertHttpNotError(r, t)
295 300
 
296 301
 	img := &docker.Image{}
297 302
 	if err := json.Unmarshal(r.Body.Bytes(), img); err != nil {
... ...
@@ -303,21 +296,16 @@ func TestGetImagesByName(t *testing.T) {
303 303
 }
304 304
 
305 305
 func TestGetContainersJSON(t *testing.T) {
306
-	runtime := mkRuntime(t)
307
-	defer nuke(runtime)
308
-
309
-	srv := &docker.Server{runtime: runtime}
306
+        eng := NewTestEngine(t)
307
+        defer mkRuntimeFromEngine(eng, t).Nuke()
308
+        srv := mkServerFromEngine(eng, t)
310 309
 
311
-	beginLen := runtime.containers.Len()
310
+	beginLen := len(srv.Containers(true, false, -1, "", ""))
312 311
 
313
-	container, _, err := runtime.Create(&Config{
314
-		Image: GetTestImage(runtime).ID,
312
+        containerID := createTestContainer(eng, &docker.Config{
313
+		Image: unitTestImageID,
315 314
 		Cmd:   []string{"echo", "test"},
316
-	}, "")
317
-	if err != nil {
318
-		t.Fatal(err)
319
-	}
320
-	defer runtime.Destroy(container)
315
+	}, t)
321 316
 
322 317
 	req, err := http.NewRequest("GET", "/containers/json?all=1", nil)
323 318
 	if err != nil {
... ...
@@ -325,48 +313,47 @@ func TestGetContainersJSON(t *testing.T) {
325 325
 	}
326 326
 
327 327
 	r := httptest.NewRecorder()
328
-	if err := getContainersJSON(srv, docker.APIVERSION, r, req, nil); err != nil {
329
-		t.Fatal(err)
330
-	}
331
-	containers := []APIContainers{}
328
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
329
+            t.Fatal(err)
330
+        }
331
+        assertHttpNotError(r, t)
332
+	containers := []docker.APIContainers{}
332 333
 	if err := json.Unmarshal(r.Body.Bytes(), &containers); err != nil {
333 334
 		t.Fatal(err)
334 335
 	}
335 336
 	if len(containers) != beginLen+1 {
336 337
 		t.Fatalf("Expected %d container, %d found (started with: %d)", beginLen+1, len(containers), beginLen)
337 338
 	}
338
-	if containers[0].ID != container.ID {
339
-		t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", container.ID, containers[0].ID)
339
+	if containers[0].ID != containerID {
340
+		t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", containerID, containers[0].ID)
340 341
 	}
341 342
 }
342 343
 
343 344
 func TestGetContainersExport(t *testing.T) {
344
-	runtime := mkRuntime(t)
345
-	defer nuke(runtime)
346
-
347
-	srv := &docker.Server{runtime: runtime}
345
+        eng := NewTestEngine(t)
346
+        defer mkRuntimeFromEngine(eng, t).Nuke()
347
+        srv := mkServerFromEngine(eng, t)
348 348
 
349 349
 	// Create a container and remove a file
350
-	container, _, err := runtime.Create(
351
-		&Config{
352
-			Image: GetTestImage(runtime).ID,
350
+        containerID := createTestContainer(eng,
351
+		&docker.Config{
352
+			Image: unitTestImageID,
353 353
 			Cmd:   []string{"touch", "/test"},
354 354
 		},
355
-		"",
355
+		t,
356 356
 	)
357
-	if err != nil {
358
-		t.Fatal(err)
359
-	}
360
-	defer runtime.Destroy(container)
361
-
362
-	if err := container.Run(); err != nil {
363
-		t.Fatal(err)
364
-	}
357
+	containerRun(eng, containerID, t)
365 358
 
366 359
 	r := httptest.NewRecorder()
367
-	if err = getContainersExport(srv, docker.APIVERSION, r, nil, map[string]string{"name": container.ID}); err != nil {
360
+
361
+	req, err := http.NewRequest("GET", "/containers/" + containerID + "/export", nil)
362
+	if err != nil {
368 363
 		t.Fatal(err)
369 364
 	}
365
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
366
+            t.Fatal(err)
367
+        }
368
+        assertHttpNotError(r, t)
370 369
 
371 370
 	if r.Code != http.StatusOK {
372 371
 		t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
... ...
@@ -392,33 +379,30 @@ func TestGetContainersExport(t *testing.T) {
392 392
 }
393 393
 
394 394
 func TestGetContainersChanges(t *testing.T) {
395
-	runtime := mkRuntime(t)
396
-	defer nuke(runtime)
397
-
398
-	srv := &docker.Server{runtime: runtime}
395
+        eng := NewTestEngine(t)
396
+        defer mkRuntimeFromEngine(eng, t).Nuke()
397
+        srv := mkServerFromEngine(eng, t)
399 398
 
400 399
 	// Create a container and remove a file
401
-	container, _, err := runtime.Create(
402
-		&Config{
403
-			Image: GetTestImage(runtime).ID,
400
+        containerID := createTestContainer(eng,
401
+		&docker.Config{
402
+			Image: unitTestImageID,
404 403
 			Cmd:   []string{"/bin/rm", "/etc/passwd"},
405 404
 		},
406
-		"",
405
+		t,
407 406
 	)
408
-	if err != nil {
409
-		t.Fatal(err)
410
-	}
411
-	defer runtime.Destroy(container)
412
-
413
-	if err := container.Run(); err != nil {
414
-		t.Fatal(err)
415
-	}
407
+        containerRun(eng, containerID, t)
416 408
 
417 409
 	r := httptest.NewRecorder()
418
-	if err := getContainersChanges(srv, docker.APIVERSION, r, nil, map[string]string{"name": container.ID}); err != nil {
419
-		t.Fatal(err)
410
+	req, err := http.NewRequest("GET", "/containers/"+containerID+"/changes", nil)
411
+	if err != nil {
412
+	    t.Fatal(err)
420 413
 	}
421
-	changes := []Change{}
414
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
415
+            t.Fatal(err)
416
+        }
417
+        assertHttpNotError(r, t)
418
+	changes := []docker.Change{}
422 419
 	if err := json.Unmarshal(r.Body.Bytes(), &changes); err != nil {
423 420
 		t.Fatal(err)
424 421
 	}
... ...
@@ -437,64 +421,57 @@ func TestGetContainersChanges(t *testing.T) {
437 437
 
438 438
 func TestGetContainersTop(t *testing.T) {
439 439
 	t.Skip("Fixme. Skipping test for now. Reported error when testing using dind: 'api_test.go:527: Expected 2 processes, found 0.'")
440
-	runtime := mkRuntime(t)
441
-	defer nuke(runtime)
440
+        eng := NewTestEngine(t)
441
+        defer mkRuntimeFromEngine(eng, t).Nuke()
442
+        srv := mkServerFromEngine(eng, t)
442 443
 
443
-	srv := &docker.Server{runtime: runtime}
444
-
445
-	container, _, err := runtime.Create(
446
-		&Config{
447
-			Image:     GetTestImage(runtime).ID,
444
+        containerID := createTestContainer(eng,
445
+		&docker.Config{
446
+			Image:     unitTestImageID,
448 447
 			Cmd:       []string{"/bin/sh", "-c", "cat"},
449 448
 			OpenStdin: true,
450 449
 		},
451
-		"",
450
+		t,
452 451
 	)
453
-	if err != nil {
454
-		t.Fatal(err)
455
-	}
456
-	defer runtime.Destroy(container)
457 452
 	defer func() {
458 453
 		// Make sure the process dies before destroying runtime
459
-		container.stdin.Close()
460
-		container.WaitTimeout(2 * time.Second)
454
+		containerKill(eng, containerID, t)
455
+		containerWait(eng, containerID, t)
461 456
 	}()
462 457
 
463
-	if err := container.Start(); err != nil {
464
-		t.Fatal(err)
465
-	}
458
+	startContainer(eng, containerID, t)
466 459
 
467 460
 	setTimeout(t, "Waiting for the container to be started timed out", 10*time.Second, func() {
468 461
 		for {
469
-			if container.State.Running {
462
+			if containerRunning(eng, containerID, t) {
470 463
 				break
471 464
 			}
472 465
 			time.Sleep(10 * time.Millisecond)
473 466
 		}
474 467
 	})
475 468
 
476
-	if !container.State.Running {
469
+	if !containerRunning(eng, containerID, t) {
477 470
 		t.Fatalf("Container should be running")
478 471
 	}
479 472
 
480 473
 	// Make sure sh spawn up cat
481 474
 	setTimeout(t, "read/write assertion timed out", 2*time.Second, func() {
482
-		in, _ := container.StdinPipe()
483
-		out, _ := container.StdoutPipe()
475
+		in, out := containerAttach(eng, containerID, t)
484 476
 		if err := assertPipe("hello\n", "hello", out, in, 15); err != nil {
485 477
 			t.Fatal(err)
486 478
 		}
487 479
 	})
488 480
 
489 481
 	r := httptest.NewRecorder()
490
-	req, err := http.NewRequest("GET", "/"+container.ID+"/top?ps_args=u", bytes.NewReader([]byte{}))
482
+	req, err := http.NewRequest("GET", "/"+containerID+"/top?ps_args=u", bytes.NewReader([]byte{}))
491 483
 	if err != nil {
492 484
 		t.Fatal(err)
493 485
 	}
494
-	if err := getContainersTop(srv, docker.APIVERSION, r, req, map[string]string{"name": container.ID}); err != nil {
495
-		t.Fatal(err)
496
-	}
497
-	procs := APITop{}
486
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
487
+            t.Fatal(err)
488
+        }
489
+        assertHttpNotError(r, t)
490
+	procs := docker.APITop{}
498 491
 	if err := json.Unmarshal(r.Body.Bytes(), &procs); err != nil {
499 492
 		t.Fatal(err)
500 493
 	}
... ...
@@ -518,90 +495,83 @@ func TestGetContainersTop(t *testing.T) {
518 518
 }
519 519
 
520 520
 func TestGetContainersByName(t *testing.T) {
521
-	runtime := mkRuntime(t)
522
-	defer nuke(runtime)
523
-
524
-	srv := &docker.Server{runtime: runtime}
521
+        eng := NewTestEngine(t)
522
+        defer mkRuntimeFromEngine(eng, t).Nuke()
523
+        srv := mkServerFromEngine(eng, t)
525 524
 
526 525
 	// Create a container and remove a file
527
-	container, _, err := runtime.Create(
528
-		&Config{
529
-			Image: GetTestImage(runtime).ID,
526
+        containerID := createTestContainer(eng,
527
+		&docker.Config{
528
+			Image: unitTestImageID,
530 529
 			Cmd:   []string{"echo", "test"},
531 530
 		},
532
-		"",
531
+		t,
533 532
 	)
534
-	if err != nil {
535
-		t.Fatal(err)
536
-	}
537
-	defer runtime.Destroy(container)
538 533
 
539 534
 	r := httptest.NewRecorder()
540
-	if err := getContainersByName(srv, docker.APIVERSION, r, nil, map[string]string{"name": container.ID}); err != nil {
541
-		t.Fatal(err)
535
+	req, err := http.NewRequest("GET", "/containers/"+containerID+"/json", nil)
536
+	if err != nil {
537
+	    t.Fatal(err)
542 538
 	}
539
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
540
+            t.Fatal(err)
541
+        }
542
+        assertHttpNotError(r, t)
543 543
 	outContainer := &docker.Container{}
544 544
 	if err := json.Unmarshal(r.Body.Bytes(), outContainer); err != nil {
545 545
 		t.Fatal(err)
546 546
 	}
547
-	if outContainer.ID != container.ID {
548
-		t.Fatalf("Wrong containers retrieved. Expected %s, received %s", container.ID, outContainer.ID)
547
+	if outContainer.ID != containerID {
548
+		t.Fatalf("Wrong containers retrieved. Expected %s, received %s", containerID, outContainer.ID)
549 549
 	}
550 550
 }
551 551
 
552 552
 func TestPostCommit(t *testing.T) {
553
-	runtime := mkRuntime(t)
554
-	defer nuke(runtime)
555
-
556
-	srv := &docker.Server{runtime: runtime}
553
+        eng := NewTestEngine(t)
554
+        defer mkRuntimeFromEngine(eng, t).Nuke()
555
+        srv := mkServerFromEngine(eng, t)
557 556
 
558 557
 	// Create a container and remove a file
559
-	container, _, err := runtime.Create(
560
-		&Config{
561
-			Image: GetTestImage(runtime).ID,
558
+        containerID := createTestContainer(eng,
559
+		&docker.Config{
560
+			Image: unitTestImageID,
562 561
 			Cmd:   []string{"touch", "/test"},
563 562
 		},
564
-		"",
563
+		t,
565 564
 	)
566
-	if err != nil {
567
-		t.Fatal(err)
568
-	}
569
-	defer runtime.Destroy(container)
570 565
 
571
-	if err := container.Run(); err != nil {
572
-		t.Fatal(err)
573
-	}
566
+        containerRun(eng, containerID, t)
574 567
 
575
-	req, err := http.NewRequest("POST", "/commit?repo=testrepo&testtag=tag&container="+container.ID, bytes.NewReader([]byte{}))
568
+	req, err := http.NewRequest("POST", "/commit?repo=testrepo&testtag=tag&container="+containerID, bytes.NewReader([]byte{}))
576 569
 	if err != nil {
577 570
 		t.Fatal(err)
578 571
 	}
579 572
 
580 573
 	r := httptest.NewRecorder()
581
-	if err := postCommit(srv, docker.APIVERSION, r, req, nil); err != nil {
582
-		t.Fatal(err)
583
-	}
574
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
575
+            t.Fatal(err)
576
+        }
577
+        assertHttpNotError(r, t)
584 578
 	if r.Code != http.StatusCreated {
585 579
 		t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
586 580
 	}
587 581
 
588
-	apiID := &APIID{}
582
+	apiID := &docker.APIID{}
589 583
 	if err := json.Unmarshal(r.Body.Bytes(), apiID); err != nil {
590 584
 		t.Fatal(err)
591 585
 	}
592
-	if _, err := runtime.graph.Get(apiID.ID); err != nil {
593
-		t.Fatalf("The image has not been commited")
586
+	if _, err := srv.ImageInspect(apiID.ID); err != nil {
587
+		t.Fatalf("The image has not been committed")
594 588
 	}
595 589
 }
596 590
 
597 591
 func TestPostContainersCreate(t *testing.T) {
598 592
 	eng := NewTestEngine(t)
593
+	defer mkRuntimeFromEngine(eng, t).Nuke()
599 594
 	srv := mkServerFromEngine(eng, t)
600
-	runtime := srv.runtime
601
-	defer nuke(runtime)
602 595
 
603
-	configJSON, err := json.Marshal(&Config{
604
-		Image:  GetTestImage(runtime).ID,
596
+	configJSON, err := json.Marshal(&docker.Config{
597
+		Image:  unitTestImageID,
605 598
 		Memory: 33554432,
606 599
 		Cmd:    []string{"touch", "/test"},
607 600
 	})
... ...
@@ -615,150 +585,132 @@ func TestPostContainersCreate(t *testing.T) {
615 615
 	}
616 616
 
617 617
 	r := httptest.NewRecorder()
618
-	if err := postContainersCreate(srv, docker.APIVERSION, r, req, nil); err != nil {
619
-		t.Fatal(err)
620
-	}
618
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
619
+            t.Fatal(err)
620
+        }
621
+        assertHttpNotError(r, t)
621 622
 	if r.Code != http.StatusCreated {
622 623
 		t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
623 624
 	}
624 625
 
625
-	apiRun := &APIRun{}
626
+	apiRun := &docker.APIRun{}
626 627
 	if err := json.Unmarshal(r.Body.Bytes(), apiRun); err != nil {
627 628
 		t.Fatal(err)
628 629
 	}
630
+	containerID := apiRun.ID
629 631
 
630
-	container := srv.runtime.Get(apiRun.ID)
631
-	if container == nil {
632
-		t.Fatalf("Container not created")
633
-	}
634
-
635
-	if err := container.Run(); err != nil {
636
-		t.Fatal(err)
637
-	}
632
+	containerAssertExists(eng, containerID, t)
633
+        containerRun(eng, containerID, t)
638 634
 
639
-	if _, err := os.Stat(path.Join(container.rwPath(), "test")); err != nil {
640
-		if os.IsNotExist(err) {
641
-			utils.Debugf("Err: %s", err)
642
-			t.Fatalf("The test file has not been created")
643
-		}
644
-		t.Fatal(err)
635
+	if !containerFileExists(eng, containerID, "test", t) {
636
+		t.Fatal("Test file was not created")
645 637
 	}
646 638
 }
647 639
 
648 640
 func TestPostContainersKill(t *testing.T) {
649
-	runtime := mkRuntime(t)
650
-	defer nuke(runtime)
641
+        eng := NewTestEngine(t)
642
+        defer mkRuntimeFromEngine(eng, t).Nuke()
643
+        srv := mkServerFromEngine(eng, t)
651 644
 
652
-	srv := &docker.Server{runtime: runtime}
653
-
654
-	container, _, err := runtime.Create(
655
-		&Config{
656
-			Image:     GetTestImage(runtime).ID,
645
+        containerID := createTestContainer(eng,
646
+		&docker.Config{
647
+			Image:     unitTestImageID,
657 648
 			Cmd:       []string{"/bin/cat"},
658 649
 			OpenStdin: true,
659 650
 		},
660
-		"",
651
+		t,
661 652
 	)
662
-	if err != nil {
663
-		t.Fatal(err)
664
-	}
665
-	defer runtime.Destroy(container)
666 653
 
667
-	if err := container.Start(); err != nil {
668
-		t.Fatal(err)
669
-	}
654
+        startContainer(eng, containerID, t)
670 655
 
671 656
 	// Give some time to the process to start
672
-	container.WaitTimeout(500 * time.Millisecond)
657
+	containerWaitTimeout(eng, containerID, t)
673 658
 
674
-	if !container.State.Running {
659
+	if !containerRunning(eng, containerID, t) {
675 660
 		t.Errorf("Container should be running")
676 661
 	}
677 662
 
678 663
 	r := httptest.NewRecorder()
679
-	if err := postContainersKill(srv, docker.APIVERSION, r, nil, map[string]string{"name": container.ID}); err != nil {
680
-		t.Fatal(err)
664
+	req, err := http.NewRequest("POST", "/containers/"+containerID+"/kill", bytes.NewReader([]byte{}))
665
+	if err != nil {
666
+	    t.Fatal(err)
681 667
 	}
668
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
669
+            t.Fatal(err)
670
+        }
671
+        assertHttpNotError(r, t)
682 672
 	if r.Code != http.StatusNoContent {
683 673
 		t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
684 674
 	}
685
-	if container.State.Running {
675
+	if containerRunning(eng, containerID, t) {
686 676
 		t.Fatalf("The container hasn't been killed")
687 677
 	}
688 678
 }
689 679
 
690 680
 func TestPostContainersRestart(t *testing.T) {
691
-	runtime := mkRuntime(t)
692
-	defer nuke(runtime)
681
+        eng := NewTestEngine(t)
682
+        defer mkRuntimeFromEngine(eng, t).Nuke()
683
+        srv := mkServerFromEngine(eng, t)
693 684
 
694
-	srv := &docker.Server{runtime: runtime}
695
-
696
-	container, _, err := runtime.Create(
697
-		&Config{
698
-			Image:     GetTestImage(runtime).ID,
685
+        containerID := createTestContainer(eng,
686
+		&docker.Config{
687
+			Image:     unitTestImageID,
699 688
 			Cmd:       []string{"/bin/top"},
700 689
 			OpenStdin: true,
701 690
 		},
702
-		"",
691
+		t,
703 692
 	)
704
-	if err != nil {
705
-		t.Fatal(err)
706
-	}
707
-	defer runtime.Destroy(container)
708 693
 
709
-	if err := container.Start(); err != nil {
710
-		t.Fatal(err)
711
-	}
694
+        startContainer(eng, containerID, t)
712 695
 
713 696
 	// Give some time to the process to start
714
-	container.WaitTimeout(500 * time.Millisecond)
697
+	containerWaitTimeout(eng, containerID, t)
715 698
 
716
-	if !container.State.Running {
699
+	if !containerRunning(eng, containerID, t) {
717 700
 		t.Errorf("Container should be running")
718 701
 	}
719 702
 
720
-	req, err := http.NewRequest("POST", "/containers/"+container.ID+"/restart?t=1", bytes.NewReader([]byte{}))
703
+	req, err := http.NewRequest("POST", "/containers/"+containerID+"/restart?t=1", bytes.NewReader([]byte{}))
721 704
 	if err != nil {
722 705
 		t.Fatal(err)
723 706
 	}
724 707
 	r := httptest.NewRecorder()
725
-	if err := postContainersRestart(srv, docker.APIVERSION, r, req, map[string]string{"name": container.ID}); err != nil {
726
-		t.Fatal(err)
727
-	}
708
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
709
+            t.Fatal(err)
710
+        }
711
+        assertHttpNotError(r, t)
728 712
 	if r.Code != http.StatusNoContent {
729 713
 		t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
730 714
 	}
731 715
 
732 716
 	// Give some time to the process to restart
733
-	container.WaitTimeout(500 * time.Millisecond)
717
+	containerWaitTimeout(eng, containerID, t)
734 718
 
735
-	if !container.State.Running {
719
+	if !containerRunning(eng, containerID, t) {
736 720
 		t.Fatalf("Container should be running")
737 721
 	}
738 722
 
739
-	if err := container.Kill(); err != nil {
740
-		t.Fatal(err)
741
-	}
723
+        containerKill(eng, containerID, t)
742 724
 }
743 725
 
744 726
 func TestPostContainersStart(t *testing.T) {
745 727
 	eng := NewTestEngine(t)
728
+	defer mkRuntimeFromEngine(eng, t).Nuke()
746 729
 	srv := mkServerFromEngine(eng, t)
747
-	runtime := srv.runtime
748
-	defer nuke(runtime)
749 730
 
750
-	id := createTestContainer(
731
+	containerID := createTestContainer(
751 732
 		eng,
752
-		&Config{
753
-			Image:     GetTestImage(runtime).ID,
733
+		&docker.Config{
734
+			Image:     unitTestImageID,
754 735
 			Cmd:       []string{"/bin/cat"},
755 736
 			OpenStdin: true,
756 737
 		},
757
-		t)
738
+		t,
739
+	)
758 740
 
759
-	hostConfigJSON, err := json.Marshal(&HostConfig{})
741
+	hostConfigJSON, err := json.Marshal(&docker.HostConfig{})
760 742
 
761
-	req, err := http.NewRequest("POST", "/containers/"+id+"/start", bytes.NewReader(hostConfigJSON))
743
+	req, err := http.NewRequest("POST", "/containers/"+containerID+"/start", bytes.NewReader(hostConfigJSON))
762 744
 	if err != nil {
763 745
 		t.Fatal(err)
764 746
 	}
... ...
@@ -766,110 +718,101 @@ func TestPostContainersStart(t *testing.T) {
766 766
 	req.Header.Set("Content-Type", "application/json")
767 767
 
768 768
 	r := httptest.NewRecorder()
769
-	if err := postContainersStart(srv, docker.APIVERSION, r, req, map[string]string{"name": id}); err != nil {
770
-		t.Fatal(err)
771
-	}
769
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
770
+            t.Fatal(err)
771
+        }
772
+        assertHttpNotError(r, t)
772 773
 	if r.Code != http.StatusNoContent {
773 774
 		t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
774 775
 	}
775 776
 
776
-	container := runtime.Get(id)
777
-	if container == nil {
778
-		t.Fatalf("Container %s was not created", id)
779
-	}
777
+	containerAssertExists(eng, containerID, t)
780 778
 	// Give some time to the process to start
781 779
 	// FIXME: use Wait once it's available as a job
782
-	container.WaitTimeout(500 * time.Millisecond)
783
-	if !container.State.Running {
780
+	containerWaitTimeout(eng, containerID, t)
781
+	if !containerRunning(eng, containerID, t) {
784 782
 		t.Errorf("Container should be running")
785 783
 	}
786 784
 
787 785
 	r = httptest.NewRecorder()
788
-	if err = postContainersStart(srv, docker.APIVERSION, r, req, map[string]string{"name": id}); err == nil {
789
-		t.Fatalf("A running container should be able to be started")
790
-	}
791
-
792
-	if err := container.Kill(); err != nil {
786
+	if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
793 787
 		t.Fatal(err)
794 788
 	}
789
+	// Starting an already started container should return an error
790
+	// FIXME: verify a precise error code. There is a possible bug here
791
+	// which causes this to return 404 even though the container exists.
792
+	assertHttpError(r, t)
793
+	containerAssertExists(eng, containerID, t)
794
+        containerKill(eng, containerID, t)
795 795
 }
796 796
 
797 797
 func TestPostContainersStop(t *testing.T) {
798
-	runtime := mkRuntime(t)
799
-	defer nuke(runtime)
800
-
801
-	srv := &docker.Server{runtime: runtime}
798
+        eng := NewTestEngine(t)
799
+        defer mkRuntimeFromEngine(eng, t).Nuke()
800
+        srv := mkServerFromEngine(eng, t)
802 801
 
803
-	container, _, err := runtime.Create(
804
-		&Config{
805
-			Image:     GetTestImage(runtime).ID,
802
+        containerID := createTestContainer(eng,
803
+		&docker.Config{
804
+			Image:     unitTestImageID,
806 805
 			Cmd:       []string{"/bin/top"},
807 806
 			OpenStdin: true,
808 807
 		},
809
-		"",
808
+		t,
810 809
 	)
811
-	if err != nil {
812
-		t.Fatal(err)
813
-	}
814
-	defer runtime.Destroy(container)
815 810
 
816
-	if err := container.Start(); err != nil {
817
-		t.Fatal(err)
818
-	}
811
+        startContainer(eng, containerID, t)
819 812
 
820 813
 	// Give some time to the process to start
821
-	container.WaitTimeout(500 * time.Millisecond)
814
+	containerWaitTimeout(eng, containerID, t)
822 815
 
823
-	if !container.State.Running {
816
+	if !containerRunning(eng, containerID, t) {
824 817
 		t.Errorf("Container should be running")
825 818
 	}
826 819
 
827 820
 	// Note: as it is a POST request, it requires a body.
828
-	req, err := http.NewRequest("POST", "/containers/"+container.ID+"/stop?t=1", bytes.NewReader([]byte{}))
821
+	req, err := http.NewRequest("POST", "/containers/"+containerID+"/stop?t=1", bytes.NewReader([]byte{}))
829 822
 	if err != nil {
830 823
 		t.Fatal(err)
831 824
 	}
832 825
 	r := httptest.NewRecorder()
833
-	if err := postContainersStop(srv, docker.APIVERSION, r, req, map[string]string{"name": container.ID}); err != nil {
834
-		t.Fatal(err)
835
-	}
826
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
827
+            t.Fatal(err)
828
+        }
829
+        assertHttpNotError(r, t)
836 830
 	if r.Code != http.StatusNoContent {
837 831
 		t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
838 832
 	}
839
-	if container.State.Running {
833
+	if containerRunning(eng, containerID, t) {
840 834
 		t.Fatalf("The container hasn't been stopped")
841 835
 	}
842 836
 }
843 837
 
844 838
 func TestPostContainersWait(t *testing.T) {
845
-	runtime := mkRuntime(t)
846
-	defer nuke(runtime)
847
-
848
-	srv := &docker.Server{runtime: runtime}
839
+        eng := NewTestEngine(t)
840
+        defer mkRuntimeFromEngine(eng, t).Nuke()
841
+        srv := mkServerFromEngine(eng, t)
849 842
 
850
-	container, _, err := runtime.Create(
851
-		&Config{
852
-			Image:     GetTestImage(runtime).ID,
843
+        containerID := createTestContainer(eng,
844
+		&docker.Config{
845
+			Image:     unitTestImageID,
853 846
 			Cmd:       []string{"/bin/sleep", "1"},
854 847
 			OpenStdin: true,
855 848
 		},
856
-		"",
849
+		t,
857 850
 	)
858
-	if err != nil {
859
-		t.Fatal(err)
860
-	}
861
-	defer runtime.Destroy(container)
862
-
863
-	if err := container.Start(); err != nil {
864
-		t.Fatal(err)
865
-	}
851
+        startContainer(eng, containerID, t)
866 852
 
867 853
 	setTimeout(t, "Wait timed out", 3*time.Second, func() {
868 854
 		r := httptest.NewRecorder()
869
-		if err := postContainersWait(srv, docker.APIVERSION, r, nil, map[string]string{"name": container.ID}); err != nil {
870
-			t.Fatal(err)
855
+		req, err := http.NewRequest("POST", "/containers/"+containerID+"/wait", bytes.NewReader([]byte{}))
856
+		if err != nil {
857
+		    t.Fatal(err)
871 858
 		}
872
-		apiWait := &APIWait{}
859
+		if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
860
+		    t.Fatal(err)
861
+		}
862
+        assertHttpNotError(r, t)
863
+		apiWait := &docker.APIWait{}
873 864
 		if err := json.Unmarshal(r.Body.Bytes(), apiWait); err != nil {
874 865
 			t.Fatal(err)
875 866
 		}
... ...
@@ -878,34 +821,26 @@ func TestPostContainersWait(t *testing.T) {
878 878
 		}
879 879
 	})
880 880
 
881
-	if container.State.Running {
881
+	if containerRunning(eng, containerID, t) {
882 882
 		t.Fatalf("The container should be stopped after wait")
883 883
 	}
884 884
 }
885 885
 
886 886
 func TestPostContainersAttach(t *testing.T) {
887
-	runtime := mkRuntime(t)
888
-	defer nuke(runtime)
889
-
890
-	srv := &docker.Server{runtime: runtime}
887
+        eng := NewTestEngine(t)
888
+        defer mkRuntimeFromEngine(eng, t).Nuke()
889
+        srv := mkServerFromEngine(eng, t)
891 890
 
892
-	container, _, err := runtime.Create(
893
-		&Config{
894
-			Image:     GetTestImage(runtime).ID,
891
+        containerID := createTestContainer(eng,
892
+		&docker.Config{
893
+			Image:     unitTestImageID,
895 894
 			Cmd:       []string{"/bin/cat"},
896 895
 			OpenStdin: true,
897 896
 		},
898
-		"",
897
+		t,
899 898
 	)
900
-	if err != nil {
901
-		t.Fatal(err)
902
-	}
903
-	defer runtime.Destroy(container)
904
-
905 899
 	// Start the process
906
-	if err := container.Start(); err != nil {
907
-		t.Fatal(err)
908
-	}
900
+        startContainer(eng, containerID, t)
909 901
 
910 902
 	stdin, stdinPipe := io.Pipe()
911 903
 	stdout, stdoutPipe := io.Pipe()
... ...
@@ -913,7 +848,7 @@ func TestPostContainersAttach(t *testing.T) {
913 913
 	// Try to avoid the timeout in destroy. Best effort, don't check error
914 914
 	defer func() {
915 915
 		closeWrap(stdin, stdinPipe, stdout, stdoutPipe)
916
-		container.Kill()
916
+		containerKill(eng, containerID, t)
917 917
 	}()
918 918
 
919 919
 	// Attach to it
... ...
@@ -927,14 +862,15 @@ func TestPostContainersAttach(t *testing.T) {
927 927
 			out:              stdoutPipe,
928 928
 		}
929 929
 
930
-		req, err := http.NewRequest("POST", "/containers/"+container.ID+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{}))
930
+		req, err := http.NewRequest("POST", "/containers/"+containerID+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{}))
931 931
 		if err != nil {
932 932
 			t.Fatal(err)
933 933
 		}
934 934
 
935
-		if err := postContainersAttach(srv, docker.APIVERSION, r, req, map[string]string{"name": container.ID}); err != nil {
936
-			t.Fatal(err)
935
+		if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
936
+		    t.Fatal(err)
937 937
 		}
938
+        assertHttpNotError(r.ResponseRecorder, t)
938 939
 	}()
939 940
 
940 941
 	// Acknowledge hijack
... ...
@@ -961,40 +897,29 @@ func TestPostContainersAttach(t *testing.T) {
961 961
 
962 962
 	// We closed stdin, expect /bin/cat to still be running
963 963
 	// Wait a little bit to make sure container.monitor() did his thing
964
-	err = container.WaitTimeout(500 * time.Millisecond)
965
-	if err == nil || !container.State.Running {
966
-		t.Fatalf("/bin/cat is not running after closing stdin")
967
-	}
964
+	containerWaitTimeout(eng, containerID, t)
968 965
 
969 966
 	// Try to avoid the timeout in destroy. Best effort, don't check error
970
-	cStdin, _ := container.StdinPipe()
967
+	cStdin, _ := containerAttach(eng, containerID, t)
971 968
 	cStdin.Close()
972
-	container.Wait()
969
+	containerWait(eng, containerID, t)
973 970
 }
974 971
 
975 972
 func TestPostContainersAttachStderr(t *testing.T) {
976
-	runtime := mkRuntime(t)
977
-	defer nuke(runtime)
978
-
979
-	srv := &docker.Server{runtime: runtime}
973
+        eng := NewTestEngine(t)
974
+        defer mkRuntimeFromEngine(eng, t).Nuke()
975
+        srv := mkServerFromEngine(eng, t)
980 976
 
981
-	container, _, err := runtime.Create(
982
-		&Config{
983
-			Image:     GetTestImage(runtime).ID,
977
+        containerID := createTestContainer(eng,
978
+		&docker.Config{
979
+			Image:     unitTestImageID,
984 980
 			Cmd:       []string{"/bin/sh", "-c", "/bin/cat >&2"},
985 981
 			OpenStdin: true,
986 982
 		},
987
-		"",
983
+		t,
988 984
 	)
989
-	if err != nil {
990
-		t.Fatal(err)
991
-	}
992
-	defer runtime.Destroy(container)
993
-
994 985
 	// Start the process
995
-	if err := container.Start(); err != nil {
996
-		t.Fatal(err)
997
-	}
986
+        startContainer(eng, containerID, t)
998 987
 
999 988
 	stdin, stdinPipe := io.Pipe()
1000 989
 	stdout, stdoutPipe := io.Pipe()
... ...
@@ -1002,7 +927,7 @@ func TestPostContainersAttachStderr(t *testing.T) {
1002 1002
 	// Try to avoid the timeout in destroy. Best effort, don't check error
1003 1003
 	defer func() {
1004 1004
 		closeWrap(stdin, stdinPipe, stdout, stdoutPipe)
1005
-		container.Kill()
1005
+		containerKill(eng, containerID, t)
1006 1006
 	}()
1007 1007
 
1008 1008
 	// Attach to it
... ...
@@ -1016,14 +941,15 @@ func TestPostContainersAttachStderr(t *testing.T) {
1016 1016
 			out:              stdoutPipe,
1017 1017
 		}
1018 1018
 
1019
-		req, err := http.NewRequest("POST", "/containers/"+container.ID+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{}))
1019
+		req, err := http.NewRequest("POST", "/containers/"+containerID+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{}))
1020 1020
 		if err != nil {
1021 1021
 			t.Fatal(err)
1022 1022
 		}
1023 1023
 
1024
-		if err := postContainersAttach(srv, docker.APIVERSION, r, req, map[string]string{"name": container.ID}); err != nil {
1024
+		if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
1025 1025
 			t.Fatal(err)
1026 1026
 		}
1027
+        assertHttpNotError(r.ResponseRecorder, t)
1027 1028
 	}()
1028 1029
 
1029 1030
 	// Acknowledge hijack
... ...
@@ -1050,104 +976,76 @@ func TestPostContainersAttachStderr(t *testing.T) {
1050 1050
 
1051 1051
 	// We closed stdin, expect /bin/cat to still be running
1052 1052
 	// Wait a little bit to make sure container.monitor() did his thing
1053
-	err = container.WaitTimeout(500 * time.Millisecond)
1054
-	if err == nil || !container.State.Running {
1055
-		t.Fatalf("/bin/cat is not running after closing stdin")
1056
-	}
1053
+	containerWaitTimeout(eng, containerID, t)
1057 1054
 
1058 1055
 	// Try to avoid the timeout in destroy. Best effort, don't check error
1059
-	cStdin, _ := container.StdinPipe()
1056
+	cStdin, _ := containerAttach(eng, containerID, t)
1060 1057
 	cStdin.Close()
1061
-	container.Wait()
1058
+	containerWait(eng, containerID, t)
1062 1059
 }
1063 1060
 
1064 1061
 // FIXME: Test deleting running container
1065 1062
 // FIXME: Test deleting container with volume
1066 1063
 // FIXME: Test deleting volume in use by other container
1067 1064
 func TestDeleteContainers(t *testing.T) {
1068
-	runtime := mkRuntime(t)
1069
-	defer nuke(runtime)
1070
-
1071
-	srv := &docker.Server{runtime: runtime}
1072
-
1073
-	container, _, err := runtime.Create(&Config{
1074
-		Image: GetTestImage(runtime).ID,
1075
-		Cmd:   []string{"touch", "/test"},
1076
-	}, "")
1077
-	if err != nil {
1078
-		t.Fatal(err)
1079
-	}
1080
-	defer runtime.Destroy(container)
1065
+        eng := NewTestEngine(t)
1066
+        defer mkRuntimeFromEngine(eng, t).Nuke()
1067
+        srv := mkServerFromEngine(eng, t)
1081 1068
 
1082
-	if err := container.Run(); err != nil {
1083
-		t.Fatal(err)
1084
-	}
1085
-
1086
-	req, err := http.NewRequest("DELETE", "/containers/"+container.ID, nil)
1069
+        containerID := createTestContainer(eng,
1070
+		&docker.Config{
1071
+			Image: unitTestImageID,
1072
+			Cmd:   []string{"touch", "/test"},
1073
+		},
1074
+		t,
1075
+	)
1076
+	req, err := http.NewRequest("DELETE", "/containers/"+containerID, nil)
1087 1077
 	if err != nil {
1088 1078
 		t.Fatal(err)
1089 1079
 	}
1090 1080
 	r := httptest.NewRecorder()
1091
-	if err := deleteContainers(srv, docker.APIVERSION, r, req, map[string]string{"name": container.ID}); err != nil {
1092
-		t.Fatal(err)
1093
-	}
1081
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
1082
+            t.Fatal(err)
1083
+        }
1084
+        assertHttpNotError(r, t)
1094 1085
 	if r.Code != http.StatusNoContent {
1095 1086
 		t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
1096 1087
 	}
1097
-
1098
-	if c := runtime.Get(container.ID); c != nil {
1099
-		t.Fatalf("The container as not been deleted")
1100
-	}
1101
-
1102
-	if _, err := os.Stat(path.Join(container.rwPath(), "test")); err == nil {
1103
-		t.Fatalf("The test file has not been deleted")
1104
-	}
1088
+	containerAssertNotExists(eng, containerID, t)
1105 1089
 }
1106 1090
 
1107 1091
 func TestOptionsRoute(t *testing.T) {
1108
-	runtime := mkRuntime(t)
1109
-	defer nuke(runtime)
1110
-
1111
-	runtime.config.EnableCors = true
1112
-	srv := &docker.Server{runtime: runtime}
1113
-
1092
+	eng := NewTestEngine(t)
1093
+	defer mkRuntimeFromEngine(eng, t).Nuke()
1094
+	srv := mkServerFromEngine(eng, t)
1114 1095
 	r := httptest.NewRecorder()
1115
-	router, err := createRouter(srv, false)
1096
+	req, err := http.NewRequest("OPTIONS", "/", nil)
1116 1097
 	if err != nil {
1117 1098
 		t.Fatal(err)
1118 1099
 	}
1119
-
1120
-	req, err := http.NewRequest("OPTIONS", "/", nil)
1121
-	if err != nil {
1100
+	if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
1122 1101
 		t.Fatal(err)
1123 1102
 	}
1124
-
1125
-	router.ServeHTTP(r, req)
1103
+        assertHttpNotError(r, t)
1126 1104
 	if r.Code != http.StatusOK {
1127 1105
 		t.Errorf("Expected response for OPTIONS request to be \"200\", %v found.", r.Code)
1128 1106
 	}
1129 1107
 }
1130 1108
 
1131 1109
 func TestGetEnabledCors(t *testing.T) {
1132
-	runtime := mkRuntime(t)
1133
-	defer nuke(runtime)
1134
-
1135
-	runtime.config.EnableCors = true
1136
-	srv := &docker.Server{runtime: runtime}
1137
-
1110
+	eng := NewTestEngine(t)
1111
+	defer mkRuntimeFromEngine(eng, t).Nuke()
1112
+	srv := mkServerFromEngine(eng, t)
1138 1113
 	r := httptest.NewRecorder()
1139 1114
 
1140
-	router, err := createRouter(srv, false)
1115
+	req, err := http.NewRequest("GET", "/version", nil)
1141 1116
 	if err != nil {
1142 1117
 		t.Fatal(err)
1143 1118
 	}
1144
-
1145
-	req, err := http.NewRequest("GET", "/version", nil)
1146
-	if err != nil {
1119
+	if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
1147 1120
 		t.Fatal(err)
1148 1121
 	}
1149
-
1150
-	router.ServeHTTP(r, req)
1122
+        assertHttpNotError(r, t)
1151 1123
 	if r.Code != http.StatusOK {
1152 1124
 		t.Errorf("Expected response for OPTIONS request to be \"200\", %v found.", r.Code)
1153 1125
 	}
... ...
@@ -1168,20 +1066,18 @@ func TestGetEnabledCors(t *testing.T) {
1168 1168
 }
1169 1169
 
1170 1170
 func TestDeleteImages(t *testing.T) {
1171
-	runtime := mkRuntime(t)
1172
-	defer nuke(runtime)
1173
-
1174
-	srv := &docker.Server{runtime: runtime}
1171
+        eng := NewTestEngine(t)
1172
+        defer mkRuntimeFromEngine(eng, t).Nuke()
1173
+        srv := mkServerFromEngine(eng, t)
1175 1174
 
1176 1175
 	initialImages, err := srv.Images(false, "")
1177 1176
 	if err != nil {
1178 1177
 		t.Fatal(err)
1179 1178
 	}
1180 1179
 
1181
-	if err := srv.runtime.repositories.Set("test", "test", unitTestImageName, true); err != nil {
1180
+	if err := srv.ContainerTag(unitTestImageName, "test", "test", false); err != nil {
1182 1181
 		t.Fatal(err)
1183 1182
 	}
1184
-
1185 1183
 	images, err := srv.Images(false, "")
1186 1184
 	if err != nil {
1187 1185
 		t.Fatal(err)
... ...
@@ -1197,8 +1093,11 @@ func TestDeleteImages(t *testing.T) {
1197 1197
 	}
1198 1198
 
1199 1199
 	r := httptest.NewRecorder()
1200
-	if err := deleteImages(srv, docker.APIVERSION, r, req, map[string]string{"name": unitTestImageID}); err == nil {
1201
-		t.Fatalf("Expected conflict error, got none")
1200
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
1201
+            t.Fatal(err)
1202
+        }
1203
+	if r.Code != http.StatusConflict {
1204
+		t.Fatalf("Expected http status 409-conflict, got %v", r.Code)
1202 1205
 	}
1203 1206
 
1204 1207
 	req2, err := http.NewRequest("DELETE", "/images/test:test", nil)
... ...
@@ -1207,14 +1106,15 @@ func TestDeleteImages(t *testing.T) {
1207 1207
 	}
1208 1208
 
1209 1209
 	r2 := httptest.NewRecorder()
1210
-	if err := deleteImages(srv, docker.APIVERSION, r2, req2, map[string]string{"name": "test:test"}); err != nil {
1211
-		t.Fatal(err)
1212
-	}
1210
+        if err := docker.ServeRequest(srv, docker.APIVERSION, r2, req2); err != nil {
1211
+            t.Fatal(err)
1212
+        }
1213
+        assertHttpNotError(r2, t)
1213 1214
 	if r2.Code != http.StatusOK {
1214 1215
 		t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
1215 1216
 	}
1216 1217
 
1217
-	var outs []APIRmi
1218
+	var outs []docker.APIRmi
1218 1219
 	if err := json.Unmarshal(r2.Body.Bytes(), &outs); err != nil {
1219 1220
 		t.Fatal(err)
1220 1221
 	}
... ...
@@ -1231,59 +1131,38 @@ func TestDeleteImages(t *testing.T) {
1231 1231
 	}
1232 1232
 }
1233 1233
 
1234
-func TestJsonContentType(t *testing.T) {
1235
-	if !matchesContentType("application/json", "application/json") {
1236
-		t.Fail()
1237
-	}
1238
-
1239
-	if !matchesContentType("application/json; charset=utf-8", "application/json") {
1240
-		t.Fail()
1241
-	}
1242
-
1243
-	if matchesContentType("dockerapplication/json", "application/json") {
1244
-		t.Fail()
1245
-	}
1246
-}
1247
-
1248 1234
 func TestPostContainersCopy(t *testing.T) {
1249
-	runtime := mkRuntime(t)
1250
-	defer nuke(runtime)
1251
-
1252
-	srv := &docker.Server{runtime: runtime}
1235
+        eng := NewTestEngine(t)
1236
+        defer mkRuntimeFromEngine(eng, t).Nuke()
1237
+        srv := mkServerFromEngine(eng, t)
1253 1238
 
1254 1239
 	// Create a container and remove a file
1255
-	container, _, err := runtime.Create(
1256
-		&Config{
1257
-			Image: GetTestImage(runtime).ID,
1240
+        containerID := createTestContainer(eng,
1241
+		&docker.Config{
1242
+			Image: unitTestImageID,
1258 1243
 			Cmd:   []string{"touch", "/test.txt"},
1259 1244
 		},
1260
-		"",
1245
+		t,
1261 1246
 	)
1262
-	if err != nil {
1263
-		t.Fatal(err)
1264
-	}
1265
-	defer runtime.Destroy(container)
1266
-
1267
-	if err := container.Run(); err != nil {
1268
-		t.Fatal(err)
1269
-	}
1247
+        containerRun(eng, containerID, t)
1270 1248
 
1271 1249
 	r := httptest.NewRecorder()
1272
-	copyData := APICopy{HostPath: ".", Resource: "/test.txt"}
1250
+	copyData := docker.APICopy{HostPath: ".", Resource: "/test.txt"}
1273 1251
 
1274 1252
 	jsonData, err := json.Marshal(copyData)
1275 1253
 	if err != nil {
1276 1254
 		t.Fatal(err)
1277 1255
 	}
1278 1256
 
1279
-	req, err := http.NewRequest("POST", "/containers/"+container.ID+"/copy", bytes.NewReader(jsonData))
1257
+	req, err := http.NewRequest("POST", "/containers/"+containerID+"/copy", bytes.NewReader(jsonData))
1280 1258
 	if err != nil {
1281 1259
 		t.Fatal(err)
1282 1260
 	}
1283 1261
 	req.Header.Add("Content-Type", "application/json")
1284
-	if err = postContainersCopy(srv, docker.APIVERSION, r, req, map[string]string{"name": container.ID}); err != nil {
1262
+	if err := docker.ServeRequest(srv, docker.APIVERSION, r, req); err != nil {
1285 1263
 		t.Fatal(err)
1286 1264
 	}
1265
+        assertHttpNotError(r, t)
1287 1266
 
1288 1267
 	if r.Code != http.StatusOK {
1289 1268
 		t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
... ...
@@ -1334,4 +1213,3 @@ func (t *hijackTester) Hijack() (net.Conn, *bufio.ReadWriter, error) {
1334 1334
 	}
1335 1335
 	return conn, bufrw, nil
1336 1336
 }
1337
-*/
... ...
@@ -6,12 +6,16 @@ import (
6 6
 	"github.com/dotcloud/docker"
7 7
 	"github.com/dotcloud/docker/engine"
8 8
 	"github.com/dotcloud/docker/utils"
9
+	"fmt"
9 10
 	"io"
10 11
 	"io/ioutil"
12
+	"net/http"
13
+	"net/http/httptest"
11 14
 	"os"
12 15
 	"path"
13 16
 	"strings"
14 17
 	"testing"
18
+	"time"
15 19
 )
16 20
 
17 21
 // This file contains utility functions for docker's unit test suite.
... ...
@@ -53,6 +57,105 @@ func createTestContainer(eng *engine.Engine, config *docker.Config, f utils.Fata
53 53
 	return createNamedTestContainer(eng, config, f, "")
54 54
 }
55 55
 
56
+func startContainer(eng *engine.Engine, id string, t utils.Fataler) {
57
+	job := eng.Job("start", id)
58
+	if err := job.Run(); err != nil {
59
+		t.Fatal(err)
60
+	}
61
+}
62
+
63
+
64
+func containerRun(eng *engine.Engine, id string, t utils.Fataler) {
65
+	startContainer(eng, id, t)
66
+	containerWait(eng, id, t)
67
+}
68
+
69
+func containerFileExists(eng *engine.Engine, id, dir string, t utils.Fataler) bool {
70
+	c := getContainer(eng, id, t)
71
+	if err := c.EnsureMounted(); err != nil {
72
+		t.Fatal(err)
73
+	}
74
+	if _, err := os.Stat(path.Join(c.RootfsPath(), dir)); err != nil {
75
+		if os.IsNotExist(err) {
76
+			return false
77
+		}
78
+		t.Fatal(err)
79
+	}
80
+	return true
81
+}
82
+
83
+func containerAttach(eng *engine.Engine, id string, t utils.Fataler) (io.WriteCloser, io.ReadCloser) {
84
+	c := getContainer(eng, id, t)
85
+	i, err := c.StdinPipe()
86
+	if err != nil {
87
+		t.Fatal(err)
88
+	}
89
+	o, err := c.StdoutPipe()
90
+	if err != nil {
91
+		t.Fatal(err)
92
+	}
93
+	return i, o
94
+}
95
+
96
+
97
+func containerWait(eng *engine.Engine, id string, t utils.Fataler) int {
98
+	return getContainer(eng, id, t).Wait()
99
+}
100
+
101
+
102
+func containerWaitTimeout(eng *engine.Engine, id string, t utils.Fataler) error {
103
+	return getContainer(eng, id, t).WaitTimeout(500 * time.Millisecond)
104
+}
105
+
106
+func containerKill(eng *engine.Engine, id string, t utils.Fataler) {
107
+	if err := getContainer(eng, id, t).Kill(); err != nil {
108
+		t.Fatal(err)
109
+	}
110
+}
111
+
112
+func containerRunning(eng *engine.Engine, id string, t utils.Fataler) bool {
113
+	return getContainer(eng, id, t).State.Running
114
+}
115
+
116
+func containerAssertExists(eng *engine.Engine, id string, t utils.Fataler) {
117
+	getContainer(eng, id, t)
118
+}
119
+
120
+func containerAssertNotExists(eng *engine.Engine, id string, t utils.Fataler) {
121
+	runtime := mkRuntimeFromEngine(eng, t)
122
+	if c := runtime.Get(id); c != nil {
123
+		t.Fatal(fmt.Errorf("Container %s should not exist", id))
124
+	}
125
+}
126
+
127
+// assertHttpNotError expect the given response to not have an error.
128
+// Otherwise the it causes the test to fail.
129
+func assertHttpNotError(r *httptest.ResponseRecorder, t utils.Fataler) {
130
+	// Non-error http status are [200, 400)
131
+	if r.Code < http.StatusOK || r.Code >= http.StatusBadRequest {
132
+		t.Fatal(fmt.Errorf("Unexpected http error: %v", r.Code))
133
+	}
134
+}
135
+
136
+
137
+// assertHttpError expect the given response to have an error.
138
+// Otherwise the it causes the test to fail.
139
+func assertHttpError(r *httptest.ResponseRecorder, t utils.Fataler) {
140
+	// Non-error http status are [200, 400)
141
+	if !(r.Code < http.StatusOK || r.Code >= http.StatusBadRequest) {
142
+		t.Fatal(fmt.Errorf("Unexpected http success code: %v", r.Code))
143
+	}
144
+}
145
+
146
+func getContainer(eng *engine.Engine, id string, t utils.Fataler) *docker.Container {
147
+	runtime := mkRuntimeFromEngine(eng, t)
148
+	c := runtime.Get(id)
149
+	if c == nil  {
150
+		t.Fatal(fmt.Errorf("No such container: %s", id))
151
+	}
152
+	return c
153
+}
154
+
56 155
 func mkServerFromEngine(eng *engine.Engine, t utils.Fataler) *docker.Server {
57 156
 	iSrv := eng.Hack_GetGlobalVar("httpapi.server")
58 157
 	if iSrv == nil {
... ...
@@ -91,6 +194,8 @@ func NewTestEngine(t utils.Fataler) *engine.Engine {
91 91
 	job := eng.Job("initapi")
92 92
 	job.Setenv("Root", root)
93 93
 	job.SetenvBool("AutoRestart", false)
94
+	// TestGetEnabledCors and TestOptionsRoute require EnableCors=true
95
+	job.SetenvBool("EnableCors", true)
94 96
 	if err := job.Run(); err != nil {
95 97
 		t.Fatal(err)
96 98
 	}