Browse code

TestFollowLogsProducerGone: add

This should test that
- all the messages produced are delivered (i.e. not lost)
- followLogs() exits

Loosely based on the test having the same name by Brian Goff, see
https://gist.github.com/cpuguy83/e538793de18c762608358ee0eaddc197

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>

Kir Kolyshkin authored on 2018/08/29 11:58:47
Showing 1 changed files
... ...
@@ -117,3 +117,87 @@ func TestFollowLogsConsumerGone(t *testing.T) {
117 117
 		t.Fatal("timeout waiting for followLogs() to finish")
118 118
 	}
119 119
 }
120
+
121
+func TestFollowLogsProducerGone(t *testing.T) {
122
+	lw := logger.NewLogWatcher()
123
+
124
+	f, err := ioutil.TempFile("", t.Name())
125
+	assert.NilError(t, err)
126
+	defer os.Remove(f.Name())
127
+
128
+	var sent, received, closed int
129
+	makeDecoder := func(rdr io.Reader) func() (*logger.Message, error) {
130
+		return func() (*logger.Message, error) {
131
+			if closed == 1 {
132
+				closed++
133
+				t.Logf("logDecode() closed after sending %d messages\n", sent)
134
+				return nil, io.EOF
135
+			} else if closed > 1 {
136
+				t.Fatal("logDecode() called after closing!")
137
+				return nil, io.EOF
138
+			}
139
+			sent++
140
+			return &logger.Message{}, nil
141
+		}
142
+	}
143
+	var since, until time.Time
144
+
145
+	followLogsDone := make(chan struct{})
146
+	go func() {
147
+		followLogs(f, lw, make(chan interface{}), makeDecoder, since, until)
148
+		close(followLogsDone)
149
+	}()
150
+
151
+	// read 1 message
152
+	select {
153
+	case <-lw.Msg:
154
+		received++
155
+	case err := <-lw.Err:
156
+		assert.NilError(t, err)
157
+	case <-followLogsDone:
158
+		t.Fatal("followLogs() finished unexpectedly")
159
+	case <-time.After(10 * time.Second):
160
+		t.Fatal("timeout waiting for log message")
161
+	}
162
+
163
+	// "stop" the "container"
164
+	closed = 1
165
+	lw.ProducerGone()
166
+
167
+	// should receive all the messages sent
168
+	readDone := make(chan struct{})
169
+	go func() {
170
+		defer close(readDone)
171
+		for {
172
+			select {
173
+			case <-lw.Msg:
174
+				received++
175
+				if received == sent {
176
+					return
177
+				}
178
+			case err := <-lw.Err:
179
+				assert.NilError(t, err)
180
+			}
181
+		}
182
+	}()
183
+	select {
184
+	case <-readDone:
185
+	case <-time.After(30 * time.Second):
186
+		t.Fatalf("timeout waiting for log messages to be read (sent: %d, received: %d", sent, received)
187
+	}
188
+
189
+	t.Logf("messages sent: %d, received: %d", sent, received)
190
+
191
+	// followLogs() should be done by now
192
+	select {
193
+	case <-followLogsDone:
194
+	case <-time.After(30 * time.Second):
195
+		t.Fatal("timeout waiting for followLogs() to finish")
196
+	}
197
+
198
+	select {
199
+	case <-lw.WatchConsumerGone():
200
+		t.Fatal("consumer should not have exited")
201
+	default:
202
+	}
203
+}