func buildFileMonitor(fileChangeDelay time.Duration) (filemonitor.FileMonitor, error) { if portStr := os.Getenv(listenerPortVar); portStr != "" { port, err := strconv.Atoi(portStr) if err != nil { return nil, fmt.Errorf("%s must be an integer or empty string: %v", listenerPortVar, err) } ln, err := net.ListenTCP("tcp", &net.TCPAddr{ IP: net.ParseIP("127.0.0.1"), Port: port, }) if err != nil { return nil, err } return filemonitor.NewFileListener(fileChangeDelay, ln), nil } monitor, err := filemonitor.NewFileMonitor(fileChangeDelay) if err != nil { return nil, err } return monitor, nil }
func TestFileListener(t *testing.T) { ln, err := net.ListenTCP("tcp", &net.TCPAddr{ IP: net.ParseIP("127.0.0.1"), Port: 0, }) if err != nil { t.Fatal(err) } slog.SetTraceLogger(slog.NewTraceLogger(os.Stderr)) fl := filemonitor.NewFileListener(filemonitor.DefaultFileChangeDelay, ln) defer fl.Close() // We should be able to add a file without connecting anything if err := fl.Add("foo"); err != nil { t.Fatal(err) } conn, err := net.DialTCP("tcp", nil, ln.Addr().(*net.TCPAddr)) if err != nil { t.Fatal(err) } defer conn.Close() scanner := bufio.NewScanner(conn) // Can write files files := fl.Listen() if err := checkWrite(files, conn); err != nil { t.Fatal(err) } // Can read a file add operation want := "bar" if err := fl.Add(want); err != nil { t.Fatal(err) } conn.SetReadDeadline(time.Now().Add(time.Second)) if err := checkScan(scanner, want); err != nil { t.Fatal(err) } // Can create a second connection conn2, err := net.DialTCP("tcp", nil, ln.Addr().(*net.TCPAddr)) if err != nil { t.Fatal(err) } defer conn2.Close() scanner2 := bufio.NewScanner(conn2) // Can write a file to the second connection if err := checkWrite(files, conn2); err != nil { t.Fatal(err) } // Can read the same file Add from two connections want = "baz" if err := fl.Add(want); err != nil { t.Fatal(err) } conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) conn2.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) for i, s := range []*bufio.Scanner{scanner, scanner2} { if err := checkScan(s, want); err != nil { t.Errorf("%d: %v", i, err) } } // Can shutdown properly if err := fl.Close(); err != nil { t.Fatal(err) } for i, c := range []net.Conn{conn, conn2} { buf := make([]byte, 10) c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) if b, err := c.Read(buf); err == nil { t.Fatalf("%d: expected EOF reading closed connection but read %d bytes: %s", i, b, buf) } else if err != io.EOF { t.Fatalf("%d: expected EOF but got %v", i, err) } } }