Merge branch '8016-crunchrun-crunchstat'
[arvados.git] / services / crunchstat / crunchstat_test.go
1 package main
2
3 import (
4         "bufio"
5         "bytes"
6         "io"
7         "log"
8         "math/rand"
9         "testing"
10         "time"
11 )
12
13 // Test that CopyPipeToChildLog works even on lines longer than
14 // bufio.MaxScanTokenSize.
15 func TestCopyPipeToChildLogLongLines(t *testing.T) {
16         logger, logBuf := bufLogger()
17
18         pipeIn, pipeOut := io.Pipe()
19         copied := make(chan bool)
20         go func() {
21                 copyPipeToChildLog(pipeIn, logger)
22                 close(copied)
23         }()
24
25         sentBytes := make([]byte, bufio.MaxScanTokenSize+MaxLogLine+(1<<22))
26         go func() {
27                 pipeOut.Write([]byte("before\n"))
28
29                 for i := range sentBytes {
30                         // Some bytes that aren't newlines:
31                         sentBytes[i] = byte((rand.Int() & 0xff) | 0x80)
32                 }
33                 sentBytes[len(sentBytes)-1] = '\n'
34                 pipeOut.Write(sentBytes)
35
36                 pipeOut.Write([]byte("after"))
37                 pipeOut.Close()
38         }()
39
40         if before, err := logBuf.ReadBytes('\n'); err != nil || string(before) != "before\n" {
41                 t.Fatalf("\"before\n\" not received (got \"%s\", %s)", before, err)
42         }
43
44         var receivedBytes []byte
45         done := false
46         for !done {
47                 line, err := logBuf.ReadBytes('\n')
48                 if err != nil {
49                         t.Fatal(err)
50                 }
51                 if len(line) >= 5 && string(line[0:5]) == "[...]" {
52                         if receivedBytes == nil {
53                                 t.Fatal("Beginning of line reported as continuation")
54                         }
55                         line = line[5:]
56                 }
57                 if len(line) >= 6 && string(line[len(line)-6:]) == "[...]\n" {
58                         line = line[:len(line)-6]
59                 } else {
60                         done = true
61                 }
62                 receivedBytes = append(receivedBytes, line...)
63         }
64         if bytes.Compare(receivedBytes, sentBytes) != 0 {
65                 t.Fatalf("sent %d bytes, got %d different bytes", len(sentBytes), len(receivedBytes))
66         }
67
68         if after, err := logBuf.ReadBytes('\n'); err != nil || string(after) != "after\n" {
69                 t.Fatalf("\"after\n\" not received (got \"%s\", %s)", after, err)
70         }
71
72         select {
73         case <-time.After(time.Second):
74                 t.Fatal("Timeout")
75         case <-copied:
76                 // Done.
77         }
78 }
79
80 func bufLogger() (*log.Logger, *bufio.Reader) {
81         r, w := io.Pipe()
82         logger := log.New(w, "", 0)
83         return logger, bufio.NewReader(r)
84 }