package main
import (
- "regexp"
+ "bufio"
+ "bytes"
+ "io"
+ "log"
+ "math/rand"
"testing"
+ "time"
)
-func TestOpenAndReadAllFail(t *testing.T) {
- log_chan := make(chan string)
+// Test that CopyPipeToChildLog works even on lines longer than
+// bufio.MaxScanTokenSize.
+func TestCopyPipeToChildLogLongLines(t *testing.T) {
+ logger, logBuf := bufLogger()
+
+ pipeIn, pipeOut := io.Pipe()
+ copied := make(chan bool)
go func() {
- defer close(log_chan)
- if x, err := OpenAndReadAll("/nonexistent/file", log_chan); err == nil {
- t.Fatalf("Expected error, got %v", x)
+ copyPipeToChildLog(pipeIn, logger)
+ close(copied)
+ }()
+
+ sentBytes := make([]byte, bufio.MaxScanTokenSize+MaxLogLine+(1<<22))
+ go func() {
+ pipeOut.Write([]byte("before\n"))
+
+ for i := range sentBytes {
+ // Some bytes that aren't newlines:
+ sentBytes[i] = byte((rand.Int() & 0xff) | 0x80)
}
+ sentBytes[len(sentBytes)-1] = '\n'
+ pipeOut.Write(sentBytes)
+
+ pipeOut.Write([]byte("after"))
+ pipeOut.Close()
}()
- if _, ok := <-log_chan; !ok {
- t.Fatalf("Expected error message about nonexistent file")
- }
- if msg, ok := <-log_chan; ok {
- t.Fatalf("Expected channel to close, got %s", msg)
+
+ if before, err := logBuf.ReadBytes('\n'); err != nil || string(before) != "before\n" {
+ t.Fatalf("\"before\n\" not received (got \"%s\", %s)", before, err)
}
-}
-func TestOpenAndReadAllSuccess(t *testing.T) {
- log_chan := make(chan string)
- go func() {
- defer close(log_chan)
- data, err := OpenAndReadAll("./crunchstat_test.go", log_chan)
+ var receivedBytes []byte
+ done := false
+ for !done {
+ line, err := logBuf.ReadBytes('\n')
if err != nil {
- t.Fatalf("got error %s", err)
+ t.Fatal(err)
}
- if matched, err := regexp.MatchString("^package main\n", string(data)); err != nil || !matched {
- t.Fatalf("data failed regexp: %s", err)
+ if len(line) >= 5 && string(line[0:5]) == "[...]" {
+ if receivedBytes == nil {
+ t.Fatal("Beginning of line reported as continuation")
+ }
+ line = line[5:]
}
- }()
- if msg, ok := <-log_chan; ok {
- t.Fatalf("Expected channel to close, got %s", msg)
+ if len(line) >= 6 && string(line[len(line)-6:]) == "[...]\n" {
+ line = line[:len(line)-6]
+ } else {
+ done = true
+ }
+ receivedBytes = append(receivedBytes, line...)
+ }
+ if bytes.Compare(receivedBytes, sentBytes) != 0 {
+ t.Fatalf("sent %d bytes, got %d different bytes", len(sentBytes), len(receivedBytes))
+ }
+
+ if after, err := logBuf.ReadBytes('\n'); err != nil || string(after) != "after\n" {
+ t.Fatalf("\"after\n\" not received (got \"%s\", %s)", after, err)
}
+
+ select {
+ case <-time.After(time.Second):
+ t.Fatal("Timeout")
+ case <-copied:
+ // Done.
+ }
+}
+
+func bufLogger() (*log.Logger, *bufio.Reader) {
+ r, w := io.Pipe()
+ logger := log.New(w, "", 0)
+ return logger, bufio.NewReader(r)
}