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>
| ... | ... |
@@ -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 |
+} |