-
-
Save cpuguy83/e538793de18c762608358ee0eaddc197 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package loggerutils | |
import ( | |
"io" | |
"io/ioutil" | |
"os" | |
"sync/atomic" | |
"testing" | |
"time" | |
"github.com/docker/docker/daemon/logger" | |
"gotest.tools/assert" | |
) | |
func TestFollowLogsProducerGone(t *testing.T) { | |
lw := logger.NewLogWatcher() | |
f, err := ioutil.TempFile("", t.Name()) | |
assert.NilError(t, err) | |
defer os.Remove(f.Name()) | |
defer f.Close() | |
var closed int32 | |
closeLogger := func() { | |
f.Close() | |
atomic.StoreInt32(&closed, 1) | |
lw.ProducerGone() | |
} | |
var readAfterClose int | |
makeDecoder := func(rdr io.Reader) func() (*logger.Message, error) { | |
return func() (*logger.Message, error) { | |
if atomic.LoadInt32(&closed) == 1 { | |
// simulate extra messages to send after the logger is closed | |
if readAfterClose > 2 { | |
return nil, io.EOF | |
} | |
readAfterClose++ | |
} | |
return &logger.Message{}, nil | |
} | |
} | |
var since, until time.Time | |
followLogsDone := make(chan struct{}) | |
go func() { | |
followLogs(f, lw, make(chan interface{}), makeDecoder, since, until) | |
close(followLogsDone) | |
}() | |
select { | |
case <-lw.Msg: | |
case err := <-lw.Err: | |
assert.NilError(t, err) | |
case <-followLogsDone: | |
t.Fatal("follow logs finished unexpectedly") | |
case <-time.After(60 * time.Second): | |
t.Fatal("timeout waiting for log message") | |
} | |
closeLogger() | |
// should get two more log messages | |
for i := 0; i < 2; i++ { | |
select { | |
case <-lw.Msg: | |
case err := <-lw.Err: | |
assert.NilError(t, err) | |
case <-followLogsDone: | |
t.Fatal("follow logs should not be done") | |
case <-time.After(60 * time.Second): | |
t.Fatal("timeout waiting for log messages") | |
} | |
} | |
select { | |
case <-followLogsDone: | |
case <-time.After(60 * time.Second): | |
t.Fatal("timeout waiting for followLogs to finish") | |
} | |
select { | |
case <-lw.WatchConsumerGone(): | |
t.Fatal("consumer should not have exited") | |
default: | |
} | |
} | |
func TestFollowLogsConsumerGone(t *testing.T) { | |
lw := logger.NewLogWatcher() | |
f, err := ioutil.TempFile("", t.Name()) | |
assert.NilError(t, err) | |
defer os.Remove(f.Name()) | |
defer f.Close() | |
makeDecoder := func(rdr io.Reader) func() (*logger.Message, error) { | |
return func() (*logger.Message, error) { | |
return &logger.Message{}, nil | |
} | |
} | |
followLogsDone := make(chan struct{}) | |
var since, until time.Time | |
go func() { | |
followLogs(f, lw, make(chan interface{}), makeDecoder, since, until) | |
close(followLogsDone) | |
}() | |
select { | |
case <-lw.Msg: | |
case err := <-lw.Err: | |
assert.NilError(t, err) | |
case <-followLogsDone: | |
t.Fatal("follow logs finished unexpectedly") | |
case <-time.After(60 * time.Second): | |
t.Fatal("timeout waiting for log message") | |
} | |
lw.ConsumerGone() | |
select { | |
case <-followLogsDone: | |
case <-time.After(60 * time.Second): | |
t.Fatal("timeout waiting for follow logs to finish") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment