Browse code

Merge pull request #10806 from ahmetalpbalkan/win-cli/TestSave-fix

integration-cli: use pipes for save/load tests

Jessie Frazelle authored on 2015/02/19 15:42:06
Showing 2 changed files
... ...
@@ -14,14 +14,6 @@ import (
14 14
 
15 15
 // save a repo using gz compression and try to load it using stdout
16 16
 func TestSaveXzAndLoadRepoStdout(t *testing.T) {
17
-	tempDir, err := ioutil.TempDir("", "test-save-xz-gz-load-repo-stdout")
18
-	if err != nil {
19
-		t.Fatal(err)
20
-	}
21
-	defer os.RemoveAll(tempDir)
22
-
23
-	tarballPath := filepath.Join(tempDir, "foobar-save-load-test.tar.xz.gz")
24
-
25 17
 	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
26 18
 	out, _, err := runCommandWithOutput(runCmd)
27 19
 	if err != nil {
... ...
@@ -50,18 +42,17 @@ func TestSaveXzAndLoadRepoStdout(t *testing.T) {
50 50
 		t.Fatalf("the repo should exist before saving it: %v %v", before, err)
51 51
 	}
52 52
 
53
-	saveCmdTemplate := `%v save %v | xz -c | gzip -c > %s`
54
-	saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName, tarballPath)
55
-	saveCmd := exec.Command("bash", "-c", saveCmdFinal)
56
-	out, _, err = runCommandWithOutput(saveCmd)
53
+	repoTarball, _, err := runCommandPipelineWithOutput(
54
+		exec.Command(dockerBinary, "save", repoName),
55
+		exec.Command("xz", "-c"),
56
+		exec.Command("gzip", "-c"))
57 57
 	if err != nil {
58 58
 		t.Fatalf("failed to save repo: %v %v", out, err)
59 59
 	}
60
-
61 60
 	deleteImages(repoName)
62 61
 
63
-	loadCmdFinal := fmt.Sprintf(`cat %s | docker load`, tarballPath)
64
-	loadCmd := exec.Command("bash", "-c", loadCmdFinal)
62
+	loadCmd := exec.Command(dockerBinary, "load")
63
+	loadCmd.Stdin = strings.NewReader(repoTarball)
65 64
 	out, _, err = runCommandWithOutput(loadCmd)
66 65
 	if err == nil {
67 66
 		t.Fatalf("expected error, but succeeded with no error and output: %v", out)
... ...
@@ -73,7 +64,6 @@ func TestSaveXzAndLoadRepoStdout(t *testing.T) {
73 73
 		t.Fatalf("the repo should not exist: %v", after)
74 74
 	}
75 75
 
76
-	deleteContainer(cleanedContainerID)
77 76
 	deleteImages(repoName)
78 77
 
79 78
 	logDone("load - save a repo with xz compression & load it using stdout")
... ...
@@ -81,14 +71,6 @@ func TestSaveXzAndLoadRepoStdout(t *testing.T) {
81 81
 
82 82
 // save a repo using xz+gz compression and try to load it using stdout
83 83
 func TestSaveXzGzAndLoadRepoStdout(t *testing.T) {
84
-	tempDir, err := ioutil.TempDir("", "test-save-xz-gz-load-repo-stdout")
85
-	if err != nil {
86
-		t.Fatal(err)
87
-	}
88
-	defer os.RemoveAll(tempDir)
89
-
90
-	tarballPath := filepath.Join(tempDir, "foobar-save-load-test.tar.xz.gz")
91
-
92 84
 	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
93 85
 	out, _, err := runCommandWithOutput(runCmd)
94 86
 	if err != nil {
... ...
@@ -117,18 +99,18 @@ func TestSaveXzGzAndLoadRepoStdout(t *testing.T) {
117 117
 		t.Fatalf("the repo should exist before saving it: %v %v", before, err)
118 118
 	}
119 119
 
120
-	saveCmdTemplate := `%v save %v | xz -c | gzip -c > %s`
121
-	saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName, tarballPath)
122
-	saveCmd := exec.Command("bash", "-c", saveCmdFinal)
123
-	out, _, err = runCommandWithOutput(saveCmd)
120
+	out, _, err = runCommandPipelineWithOutput(
121
+		exec.Command(dockerBinary, "save", repoName),
122
+		exec.Command("xz", "-c"),
123
+		exec.Command("gzip", "-c"))
124 124
 	if err != nil {
125 125
 		t.Fatalf("failed to save repo: %v %v", out, err)
126 126
 	}
127 127
 
128 128
 	deleteImages(repoName)
129 129
 
130
-	loadCmdFinal := fmt.Sprintf(`cat %s | docker load`, tarballPath)
131
-	loadCmd := exec.Command("bash", "-c", loadCmdFinal)
130
+	loadCmd := exec.Command(dockerBinary, "load")
131
+	loadCmd.Stdin = strings.NewReader(out)
132 132
 	out, _, err = runCommandWithOutput(loadCmd)
133 133
 	if err == nil {
134 134
 		t.Fatalf("expected error, but succeeded with no error and output: %v", out)
... ...
@@ -149,43 +131,40 @@ func TestSaveXzGzAndLoadRepoStdout(t *testing.T) {
149 149
 func TestSaveSingleTag(t *testing.T) {
150 150
 	repoName := "foobar-save-single-tag-test"
151 151
 
152
-	tagCmdFinal := fmt.Sprintf("%v tag busybox:latest %v:latest", dockerBinary, repoName)
153
-	tagCmd := exec.Command("bash", "-c", tagCmdFinal)
152
+	tagCmd := exec.Command(dockerBinary, "tag", "busybox:latest", fmt.Sprintf("%v:latest", repoName))
153
+	defer deleteImages(repoName)
154 154
 	if out, _, err := runCommandWithOutput(tagCmd); err != nil {
155 155
 		t.Fatalf("failed to tag repo: %s, %v", out, err)
156 156
 	}
157 157
 
158
-	idCmdFinal := fmt.Sprintf("%v images -q --no-trunc %v", dockerBinary, repoName)
159
-	idCmd := exec.Command("bash", "-c", idCmdFinal)
158
+	idCmd := exec.Command(dockerBinary, "images", "-q", "--no-trunc", repoName)
160 159
 	out, _, err := runCommandWithOutput(idCmd)
161 160
 	if err != nil {
162 161
 		t.Fatalf("failed to get repo ID: %s, %v", out, err)
163 162
 	}
164
-
165 163
 	cleanedImageID := stripTrailingCharacters(out)
166 164
 
167
-	saveCmdFinal := fmt.Sprintf("%v save %v:latest | tar t | grep -E '(^repositories$|%v)'", dockerBinary, repoName, cleanedImageID)
168
-	saveCmd := exec.Command("bash", "-c", saveCmdFinal)
169
-	if out, _, err = runCommandWithOutput(saveCmd); err != nil {
165
+	out, _, err = runCommandPipelineWithOutput(
166
+		exec.Command(dockerBinary, "save", fmt.Sprintf("%v:latest", repoName)),
167
+		exec.Command("tar", "t"),
168
+		exec.Command("grep", "-E", fmt.Sprintf("(^repositories$|%v)", cleanedImageID)))
169
+	if err != nil {
170 170
 		t.Fatalf("failed to save repo with image ID and 'repositories' file: %s, %v", out, err)
171 171
 	}
172 172
 
173
-	deleteImages(repoName)
174
-
175 173
 	logDone("save - save a specific image:tag")
176 174
 }
177 175
 
178 176
 func TestSaveImageId(t *testing.T) {
179 177
 	repoName := "foobar-save-image-id-test"
180 178
 
181
-	tagCmdFinal := fmt.Sprintf("%v tag emptyfs:latest %v:latest", dockerBinary, repoName)
182
-	tagCmd := exec.Command("bash", "-c", tagCmdFinal)
179
+	tagCmd := exec.Command(dockerBinary, "tag", "emptyfs:latest", fmt.Sprintf("%v:latest", repoName))
180
+	defer deleteImages(repoName)
183 181
 	if out, _, err := runCommandWithOutput(tagCmd); err != nil {
184 182
 		t.Fatalf("failed to tag repo: %s, %v", out, err)
185 183
 	}
186 184
 
187
-	idLongCmdFinal := fmt.Sprintf("%v images -q --no-trunc %v", dockerBinary, repoName)
188
-	idLongCmd := exec.Command("bash", "-c", idLongCmdFinal)
185
+	idLongCmd := exec.Command(dockerBinary, "images", "-q", "--no-trunc", repoName)
189 186
 	out, _, err := runCommandWithOutput(idLongCmd)
190 187
 	if err != nil {
191 188
 		t.Fatalf("failed to get repo ID: %s, %v", out, err)
... ...
@@ -193,8 +172,7 @@ func TestSaveImageId(t *testing.T) {
193 193
 
194 194
 	cleanedLongImageID := stripTrailingCharacters(out)
195 195
 
196
-	idShortCmdFinal := fmt.Sprintf("%v images -q %v", dockerBinary, repoName)
197
-	idShortCmd := exec.Command("bash", "-c", idShortCmdFinal)
196
+	idShortCmd := exec.Command(dockerBinary, "images", "-q", repoName)
198 197
 	out, _, err = runCommandWithOutput(idShortCmd)
199 198
 	if err != nil {
200 199
 		t.Fatalf("failed to get repo short ID: %s, %v", out, err)
... ...
@@ -202,13 +180,32 @@ func TestSaveImageId(t *testing.T) {
202 202
 
203 203
 	cleanedShortImageID := stripTrailingCharacters(out)
204 204
 
205
-	saveCmdFinal := fmt.Sprintf("%v save %v | tar t | grep %v", dockerBinary, cleanedShortImageID, cleanedLongImageID)
206
-	saveCmd := exec.Command("bash", "-c", saveCmdFinal)
207
-	if out, _, err = runCommandWithOutput(saveCmd); err != nil {
208
-		t.Fatalf("failed to save repo with image ID: %s, %v", out, err)
205
+	saveCmd := exec.Command(dockerBinary, "save", cleanedShortImageID)
206
+	tarCmd := exec.Command("tar", "t")
207
+	tarCmd.Stdin, err = saveCmd.StdoutPipe()
208
+	if err != nil {
209
+		t.Fatalf("cannot set stdout pipe for tar: %v", err)
210
+	}
211
+	grepCmd := exec.Command("grep", cleanedLongImageID)
212
+	grepCmd.Stdin, err = tarCmd.StdoutPipe()
213
+	if err != nil {
214
+		t.Fatalf("cannot set stdout pipe for grep: %v", err)
209 215
 	}
210 216
 
211
-	deleteImages(repoName)
217
+	if err = tarCmd.Start(); err != nil {
218
+		t.Fatalf("tar failed with error: %v", err)
219
+	}
220
+	if err = saveCmd.Start(); err != nil {
221
+		t.Fatalf("docker save failed with error: %v", err)
222
+	}
223
+	defer saveCmd.Wait()
224
+	defer tarCmd.Wait()
225
+
226
+	out, _, err = runCommandWithOutput(grepCmd)
227
+
228
+	if err != nil {
229
+		t.Fatalf("failed to save repo with image ID: %s, %v", out, err)
230
+	}
212 231
 
213 232
 	logDone("save - save a image by ID")
214 233
 }
... ...
@@ -222,6 +219,7 @@ func TestSaveAndLoadRepoFlags(t *testing.T) {
222 222
 	}
223 223
 
224 224
 	cleanedContainerID := stripTrailingCharacters(out)
225
+	defer deleteContainer(cleanedContainerID)
225 226
 
226 227
 	repoName := "foobar-save-load-test"
227 228
 
... ...
@@ -231,6 +229,7 @@ func TestSaveAndLoadRepoFlags(t *testing.T) {
231 231
 	}
232 232
 
233 233
 	commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, repoName)
234
+	deleteImages(repoName)
234 235
 	if out, _, err = runCommandWithOutput(commitCmd); err != nil {
235 236
 		t.Fatalf("failed to commit container: %s, %v", out, err)
236 237
 	}
... ...
@@ -239,21 +238,14 @@ func TestSaveAndLoadRepoFlags(t *testing.T) {
239 239
 	before, _, err := runCommandWithOutput(inspectCmd)
240 240
 	if err != nil {
241 241
 		t.Fatalf("the repo should exist before saving it: %s, %v", before, err)
242
-	}
243 242
 
244
-	saveCmdTemplate := `%v save -o /tmp/foobar-save-load-test.tar %v`
245
-	saveCmdFinal := fmt.Sprintf(saveCmdTemplate, dockerBinary, repoName)
246
-	saveCmd := exec.Command("bash", "-c", saveCmdFinal)
247
-	if out, _, err = runCommandWithOutput(saveCmd); err != nil {
248
-		t.Fatalf("failed to save repo: %s, %v", out, err)
249 243
 	}
250 244
 
251
-	deleteImages(repoName)
252
-
253
-	loadCmdFinal := `docker load -i /tmp/foobar-save-load-test.tar`
254
-	loadCmd := exec.Command("bash", "-c", loadCmdFinal)
255
-	if out, _, err = runCommandWithOutput(loadCmd); err != nil {
256
-		t.Fatalf("failed to load repo: %s, %v", out, err)
245
+	out, _, err = runCommandPipelineWithOutput(
246
+		exec.Command(dockerBinary, "save", repoName),
247
+		exec.Command(dockerBinary, "load"))
248
+	if err != nil {
249
+		t.Fatalf("failed to save and load repo: %s, %v", out, err)
257 250
 	}
258 251
 
259 252
 	inspectCmd = exec.Command(dockerBinary, "inspect", repoName)
... ...
@@ -266,11 +258,6 @@ func TestSaveAndLoadRepoFlags(t *testing.T) {
266 266
 		t.Fatalf("inspect is not the same after a save / load")
267 267
 	}
268 268
 
269
-	deleteContainer(cleanedContainerID)
270
-	deleteImages(repoName)
271
-
272
-	os.Remove("/tmp/foobar-save-load-test.tar")
273
-
274 269
 	logDone("save - save a repo using -o && load a repo using -i")
275 270
 }
276 271
 
... ...
@@ -278,29 +265,29 @@ func TestSaveMultipleNames(t *testing.T) {
278 278
 	repoName := "foobar-save-multi-name-test"
279 279
 
280 280
 	// Make one image
281
-	tagCmdFinal := fmt.Sprintf("%v tag emptyfs:latest %v-one:latest", dockerBinary, repoName)
282
-	tagCmd := exec.Command("bash", "-c", tagCmdFinal)
281
+	tagCmd := exec.Command(dockerBinary, "tag", "emptyfs:latest", fmt.Sprintf("%v-one:latest", repoName))
283 282
 	if out, _, err := runCommandWithOutput(tagCmd); err != nil {
284 283
 		t.Fatalf("failed to tag repo: %s, %v", out, err)
285 284
 	}
286 285
 	defer deleteImages(repoName + "-one")
287 286
 
288 287
 	// Make two images
289
-	tagCmdFinal = fmt.Sprintf("%v tag emptyfs:latest %v-two:latest", dockerBinary, repoName)
290
-	tagCmd = exec.Command("bash", "-c", tagCmdFinal)
291
-	if out, _, err := runCommandWithOutput(tagCmd); err != nil {
288
+	tagCmd = exec.Command(dockerBinary, "tag", "emptyfs:latest", fmt.Sprintf("%v-two:latest", repoName))
289
+	out, _, err := runCommandWithOutput(tagCmd)
290
+	if err != nil {
292 291
 		t.Fatalf("failed to tag repo: %s, %v", out, err)
293 292
 	}
294 293
 	defer deleteImages(repoName + "-two")
295 294
 
296
-	saveCmdFinal := fmt.Sprintf("%v save %v-one %v-two:latest | tar xO repositories | grep -q -E '(-one|-two)'", dockerBinary, repoName, repoName)
297
-	saveCmd := exec.Command("bash", "-c", saveCmdFinal)
298
-	if out, _, err := runCommandWithOutput(saveCmd); err != nil {
295
+	out, _, err = runCommandPipelineWithOutput(
296
+		exec.Command(dockerBinary, "save", fmt.Sprintf("%v-one", repoName), fmt.Sprintf("%v-two:latest", repoName)),
297
+		exec.Command("tar", "xO", "repositories"),
298
+		exec.Command("grep", "-q", "-E", "(-one|-two)"),
299
+	)
300
+	if err != nil {
299 301
 		t.Fatalf("failed to save multiple repos: %s, %v", out, err)
300 302
 	}
301 303
 
302
-	deleteImages(repoName)
303
-
304 304
 	logDone("save - save by multiple names")
305 305
 }
306 306
 
... ...
@@ -316,14 +303,13 @@ func TestSaveRepoWithMultipleImages(t *testing.T) {
316 316
 			t.Fatalf("failed to create a container: %v %v", out, err)
317 317
 		}
318 318
 		cleanedContainerID := stripTrailingCharacters(out)
319
+		defer deleteContainer(cleanedContainerID)
319 320
 
320 321
 		commitCmd := exec.Command(dockerBinary, "commit", cleanedContainerID, tag)
321 322
 		if out, _, err = runCommandWithOutput(commitCmd); err != nil {
322 323
 			t.Fatalf("failed to commit container: %v %v", out, err)
323 324
 		}
324 325
 		imageID := stripTrailingCharacters(out)
325
-
326
-		deleteContainer(cleanedContainerID)
327 326
 		return imageID
328 327
 	}
329 328
 
... ...
@@ -332,23 +318,25 @@ func TestSaveRepoWithMultipleImages(t *testing.T) {
332 332
 	tagBar := repoName + ":bar"
333 333
 
334 334
 	idFoo := makeImage("busybox:latest", tagFoo)
335
+	defer deleteImages(idFoo)
335 336
 	idBar := makeImage("busybox:latest", tagBar)
337
+	defer deleteImages(idBar)
336 338
 
337 339
 	deleteImages(repoName)
338 340
 
339 341
 	// create the archive
340
-	saveCmdFinal := fmt.Sprintf("%v save %v | tar t | grep 'VERSION' |cut -d / -f1", dockerBinary, repoName)
341
-	saveCmd := exec.Command("bash", "-c", saveCmdFinal)
342
-	out, _, err := runCommandWithOutput(saveCmd)
342
+	out, _, err := runCommandPipelineWithOutput(
343
+		exec.Command(dockerBinary, "save", repoName),
344
+		exec.Command("tar", "t"),
345
+		exec.Command("grep", "VERSION"),
346
+		exec.Command("cut", "-d", "/", "-f1"))
343 347
 	if err != nil {
344 348
 		t.Fatalf("failed to save multiple images: %s, %v", out, err)
345 349
 	}
346 350
 	actual := strings.Split(stripTrailingCharacters(out), "\n")
347 351
 
348 352
 	// make the list of expected layers
349
-	historyCmdFinal := fmt.Sprintf("%v history -q --no-trunc %v", dockerBinary, "busybox:latest")
350
-	historyCmd := exec.Command("bash", "-c", historyCmdFinal)
351
-	out, _, err = runCommandWithOutput(historyCmd)
353
+	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "history", "-q", "--no-trunc", "busybox:latest"))
352 354
 	if err != nil {
353 355
 		t.Fatalf("failed to get history: %s, %v", out, err)
354 356
 	}
... ...
@@ -3,6 +3,7 @@ package main
3 3
 import (
4 4
 	"bytes"
5 5
 	"encoding/json"
6
+	"errors"
6 7
 	"fmt"
7 8
 	"io"
8 9
 	"math/rand"
... ...
@@ -95,6 +96,40 @@ func runCommand(cmd *exec.Cmd) (exitCode int, err error) {
95 95
 	return
96 96
 }
97 97
 
98
+func runCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, exitCode int, err error) {
99
+	if len(cmds) < 2 {
100
+		return "", 0, errors.New("pipeline does not have multiple cmds")
101
+	}
102
+
103
+	// connect stdin of each cmd to stdout pipe of previous cmd
104
+	for i, cmd := range cmds {
105
+		if i > 0 {
106
+			prevCmd := cmds[i-1]
107
+			cmd.Stdin, err = prevCmd.StdoutPipe()
108
+			if err != nil {
109
+				return "", 0, fmt.Errorf("cannot set stdout pipe for %s: %v", cmd.Path, err)
110
+			}
111
+		}
112
+	}
113
+
114
+	// start all cmds except the last
115
+	for _, cmd := range cmds[:len(cmds)-1] {
116
+		if err = cmd.Start(); err != nil {
117
+			return "", 0, fmt.Errorf("starting %s failed with error: %v", cmd.Path, err)
118
+		}
119
+	}
120
+
121
+	defer func() {
122
+		// wait all cmds except the last to release their resources
123
+		for _, cmd := range cmds[:len(cmds)-1] {
124
+			cmd.Wait()
125
+		}
126
+	}()
127
+
128
+	// wait on last cmd
129
+	return runCommandWithOutput(cmds[len(cmds)-1])
130
+}
131
+
98 132
 func logDone(message string) {
99 133
 	fmt.Printf("[PASSED]: %s\n", message)
100 134
 }