Browse code

Add unit test for hanging kill + fix other tests behaviour

Guillaume J. Charmes authored on 2013/04/12 08:21:19
Showing 4 changed files
... ...
@@ -59,6 +59,20 @@ func assertPipe(input, output string, r io.Reader, w io.Writer, count int) error
59 59
 	return nil
60 60
 }
61 61
 
62
+func cmdWait(srv *Server, container *Container) error {
63
+	stdout, stdoutPipe := io.Pipe()
64
+
65
+	go func() {
66
+		srv.CmdWait(nil, stdoutPipe, container.Id)
67
+	}()
68
+
69
+	if _, err := bufio.NewReader(stdout).ReadString('\n'); err != nil {
70
+		return err
71
+	}
72
+	// Cleanup pipes
73
+	return closeWrap(stdout, stdoutPipe)
74
+}
75
+
62 76
 // TestRunHostname checks that 'docker run -h' correctly sets a custom hostname
63 77
 func TestRunHostname(t *testing.T) {
64 78
 	runtime, err := newTestRuntime()
... ...
@@ -89,7 +103,9 @@ func TestRunHostname(t *testing.T) {
89 89
 
90 90
 	setTimeout(t, "CmdRun timed out", 2*time.Second, func() {
91 91
 		<-c
92
+		cmdWait(srv, srv.runtime.List()[0])
92 93
 	})
94
+
93 95
 }
94 96
 
95 97
 func TestRunExit(t *testing.T) {
... ...
@@ -129,6 +145,7 @@ func TestRunExit(t *testing.T) {
129 129
 	// as the process exited, CmdRun must finish and unblock. Wait for it
130 130
 	setTimeout(t, "Waiting for CmdRun timed out", 2*time.Second, func() {
131 131
 		<-c1
132
+		cmdWait(srv, container)
132 133
 	})
133 134
 
134 135
 	// Make sure that the client has been disconnected
... ...
@@ -551,15 +551,15 @@ func (container *Container) kill() error {
551 551
 		return nil
552 552
 	}
553 553
 
554
-	// Sending SIGINT to the process via lxc
554
+	// Sending SIGKILL to the process via lxc
555 555
 	output, err := exec.Command("lxc-kill", "-n", container.Id, "9").CombinedOutput()
556 556
 	if err != nil {
557
-		Debugf("error killing container %s (%s, %s)", container.Id, output, err)
557
+		log.Printf("error killing container %s (%s, %s)", container.Id, output, err)
558 558
 	}
559 559
 
560 560
 	// 2. Wait for the process to die, in last resort, try to kill the process directly
561 561
 	if err := container.WaitTimeout(10 * time.Second); err != nil {
562
-		log.Printf("Container %s failed to exit within 10 seconds of SIGINT - trying direct SIGKILL", container.Id)
562
+		log.Printf("Container %s failed to exit within 10 seconds of lxc SIGKILL - trying direct SIGKILL", container.Id)
563 563
 		if err := container.cmd.Process.Kill(); err != nil {
564 564
 			return err
565 565
 		}
... ...
@@ -324,6 +324,54 @@ func TestOutput(t *testing.T) {
324 324
 	}
325 325
 }
326 326
 
327
+func TestKillDifferentUser(t *testing.T) {
328
+	runtime, err := newTestRuntime()
329
+	if err != nil {
330
+		t.Fatal(err)
331
+	}
332
+	defer nuke(runtime)
333
+	container, err := runtime.Create(&Config{
334
+		Image: GetTestImage(runtime).Id,
335
+		Cmd:   []string{"tail", "-f", "/etc/resolv.conf"},
336
+		User:  "daemon",
337
+	},
338
+	)
339
+	if err != nil {
340
+		t.Fatal(err)
341
+	}
342
+	defer runtime.Destroy(container)
343
+
344
+	if container.State.Running {
345
+		t.Errorf("Container shouldn't be running")
346
+	}
347
+	if err := container.Start(); err != nil {
348
+		t.Fatal(err)
349
+	}
350
+
351
+	// Give some time to lxc to spawn the process (setuid might take some time)
352
+	container.WaitTimeout(500 * time.Millisecond)
353
+
354
+	if !container.State.Running {
355
+		t.Errorf("Container should be running")
356
+	}
357
+
358
+	if err := container.Kill(); err != nil {
359
+		t.Fatal(err)
360
+	}
361
+
362
+	if container.State.Running {
363
+		t.Errorf("Container shouldn't be running")
364
+	}
365
+	container.Wait()
366
+	if container.State.Running {
367
+		t.Errorf("Container shouldn't be running")
368
+	}
369
+	// Try stopping twice
370
+	if err := container.Kill(); err != nil {
371
+		t.Fatal(err)
372
+	}
373
+}
374
+
327 375
 func TestKill(t *testing.T) {
328 376
 	runtime, err := newTestRuntime()
329 377
 	if err != nil {
... ...
@@ -346,6 +394,10 @@ func TestKill(t *testing.T) {
346 346
 	if err := container.Start(); err != nil {
347 347
 		t.Fatal(err)
348 348
 	}
349
+
350
+	// Give some time to lxc to spawn the process
351
+	container.WaitTimeout(500 * time.Millisecond)
352
+
349 353
 	if !container.State.Running {
350 354
 		t.Errorf("Container should be running")
351 355
 	}
... ...
@@ -657,6 +709,10 @@ func TestMultipleContainers(t *testing.T) {
657 657
 		t.Fatal(err)
658 658
 	}
659 659
 
660
+	// Make sure they are running before trying to kill them
661
+	container1.WaitTimeout(250 * time.Millisecond)
662
+	container2.WaitTimeout(250 * time.Millisecond)
663
+
660 664
 	// If we are here, both containers should be running
661 665
 	if !container1.State.Running {
662 666
 		t.Fatal("Container not running")
... ...
@@ -17,7 +17,6 @@ const testLayerPath string = "/var/lib/docker/docker-ut.tar"
17 17
 const unitTestImageName string = "docker-ut"
18 18
 
19 19
 var unitTestStoreBase string
20
-var srv *Server
21 20
 
22 21
 func nuke(runtime *Runtime) error {
23 22
 	var wg sync.WaitGroup