github.com/nycdavid/zeus@v0.0.0-20201208104106-9ba439429e03/go/filemonitor/filelistener_test.go (about) 1 package filemonitor_test 2 3 import ( 4 "bufio" 5 "errors" 6 "fmt" 7 "io" 8 "math/rand" 9 "net" 10 "os" 11 "testing" 12 "time" 13 14 "github.com/burke/zeus/go/filemonitor" 15 slog "github.com/burke/zeus/go/shinylog" 16 ) 17 18 func TestFileListener(t *testing.T) { 19 ln, err := net.ListenTCP("tcp", &net.TCPAddr{ 20 IP: net.ParseIP("127.0.0.1"), 21 Port: 0, 22 }) 23 if err != nil { 24 t.Fatal(err) 25 } 26 27 slog.SetTraceLogger(slog.NewTraceLogger(os.Stderr)) 28 fl := filemonitor.NewFileListener(filemonitor.DefaultFileChangeDelay, ln) 29 defer fl.Close() 30 31 // We should be able to add a file without connecting anything 32 if err := fl.Add("foo"); err != nil { 33 t.Fatal(err) 34 } 35 36 conn, err := net.DialTCP("tcp", nil, ln.Addr().(*net.TCPAddr)) 37 if err != nil { 38 t.Fatal(err) 39 } 40 defer conn.Close() 41 scanner := bufio.NewScanner(conn) 42 43 // Can write files 44 files := fl.Listen() 45 if err := checkWrite(files, conn); err != nil { 46 t.Fatal(err) 47 } 48 49 // Can read a file add operation 50 want := "bar" 51 if err := fl.Add(want); err != nil { 52 t.Fatal(err) 53 } 54 conn.SetReadDeadline(time.Now().Add(time.Second)) 55 if err := checkScan(scanner, want); err != nil { 56 t.Fatal(err) 57 } 58 59 // Can create a second connection 60 conn2, err := net.DialTCP("tcp", nil, ln.Addr().(*net.TCPAddr)) 61 if err != nil { 62 t.Fatal(err) 63 } 64 defer conn2.Close() 65 scanner2 := bufio.NewScanner(conn2) 66 67 // Can write a file to the second connection 68 if err := checkWrite(files, conn2); err != nil { 69 t.Fatal(err) 70 } 71 72 // Can read the same file Add from two connections 73 want = "baz" 74 if err := fl.Add(want); err != nil { 75 t.Fatal(err) 76 } 77 78 conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 79 conn2.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 80 81 for i, s := range []*bufio.Scanner{scanner, scanner2} { 82 if err := checkScan(s, want); err != nil { 83 t.Errorf("%d: %v", i, err) 84 } 85 } 86 87 // Can shutdown properly 88 if err := fl.Close(); err != nil { 89 t.Fatal(err) 90 } 91 92 for i, c := range []net.Conn{conn, conn2} { 93 buf := make([]byte, 10) 94 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 95 if b, err := c.Read(buf); err == nil { 96 t.Fatalf("%d: expected EOF reading closed connection but read %d bytes: %s", i, b, buf) 97 } else if err != io.EOF { 98 t.Fatalf("%d: expected EOF but got %v", i, err) 99 } 100 } 101 } 102 103 func checkScan(scanner *bufio.Scanner, want string) error { 104 if scanner.Scan() { 105 if have := scanner.Text(); have != want { 106 return fmt.Errorf("expected %q, got %q", want, have) 107 } 108 } else { 109 if err := scanner.Err(); err != nil { 110 return err 111 } 112 return errors.New("Unexpected EOF") 113 } 114 115 return nil 116 } 117 118 func checkWrite(files <-chan []string, conn net.Conn) error { 119 cases := make([]string, 2) 120 for i := range cases { 121 cases[i] = fmt.Sprintf("file%d", rand.Int()) 122 } 123 124 for i, want := range cases { 125 conn.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)) 126 if _, err := conn.Write([]byte(want + "\n")); err != nil { 127 return fmt.Errorf("Error writing %d: %v", i, err) 128 } 129 } 130 131 if err := expectChanges(files, cases[:]); err != nil { 132 return err 133 } 134 135 return nil 136 }