Browse code

Engine: fix a timeout bug in Sender/Receiver

Docker-DCO-1.1-Signed-off-by: Solomon Hykes <solomon@docker.com> (github: shykes)

Solomon Hykes authored on 2014/05/04 09:21:53
Showing 2 changed files
... ...
@@ -90,6 +90,8 @@ func (rcv *Receiver) Run() error {
90 90
 			f.Close()
91 91
 			return err
92 92
 		}
93
+		f.Close()
94
+		defer peer.Close()
93 95
 		cmd := data.Message(p).Get("cmd")
94 96
 		job := rcv.Engine.Job(cmd[0], cmd[1:]...)
95 97
 		stdout, err := beam.SendRPipe(peer, data.Empty().Set("cmd", "log", "stdout").Bytes())
... ...
@@ -1,3 +1,74 @@
1 1
 package engine
2 2
 
3
-import ()
3
+import (
4
+	"bytes"
5
+	"fmt"
6
+	"github.com/dotcloud/docker/pkg/beam"
7
+	"strings"
8
+	"testing"
9
+	"time"
10
+)
11
+
12
+func TestHelloWorld(t *testing.T) {
13
+	testRemote(t,
14
+
15
+		// Sender side
16
+		func(eng *Engine) {
17
+			job := eng.Job("echo", "hello", "world")
18
+			out := &bytes.Buffer{}
19
+			job.Stdout.Add(out)
20
+			job.Run()
21
+			if job.status != StatusOK {
22
+				t.Fatalf("#%v", job.StatusCode())
23
+			}
24
+			if out.String() != "hello world\n" {
25
+				t.Fatalf("%#v", out.String())
26
+			}
27
+		},
28
+
29
+		// Receiver side
30
+		func(eng *Engine) {
31
+			eng.Register("echo", func(job *Job) Status {
32
+				fmt.Fprintf(job.Stdout, "%s\n", strings.Join(job.Args, " "))
33
+				return StatusOK
34
+			})
35
+		},
36
+	)
37
+}
38
+
39
+func testRemote(t *testing.T, senderSide, receiverSide func(*Engine)) {
40
+	sndConn, rcvConn, err := beam.USocketPair()
41
+	if err != nil {
42
+		t.Fatal(err)
43
+	}
44
+	defer sndConn.Close()
45
+	defer rcvConn.Close()
46
+	sender := NewSender(sndConn)
47
+	receiver := NewReceiver(rcvConn)
48
+
49
+	// Setup the sender side
50
+	eng := New()
51
+	sender.Install(eng)
52
+
53
+	// Setup the receiver side
54
+	receiverSide(receiver.Engine)
55
+	go receiver.Run()
56
+
57
+	timeout(t, func() {
58
+		senderSide(eng)
59
+	})
60
+}
61
+
62
+func timeout(t *testing.T, f func()) {
63
+	onTimeout := time.After(100 * time.Millisecond)
64
+	onDone := make(chan bool)
65
+	go func() {
66
+		f()
67
+		close(onDone)
68
+	}()
69
+	select {
70
+	case <-onTimeout:
71
+		t.Fatalf("timeout")
72
+	case <-onDone:
73
+	}
74
+}