func TestChannel(t *testing.T) { logger := New("logger", 1) lastValue := sync2.AtomicString{} svm := sync2.ServiceManager{} svm.Go(func(svc *sync2.ServiceContext) error { ch := logger.Subscribe() defer logger.Unsubscribe(ch) for svc.IsRunning() { lastValue.Set((<-ch).(*logMessage).Format(nil)) } return nil }) time.Sleep(10 * time.Millisecond) if sz := logger.size.Get(); sz != 1 { t.Errorf("want 1, got %d", sz) } logger.Send(&logMessage{"val2"}) time.Sleep(10 * time.Millisecond) if lastValue.Get() != "val2\n" { t.Errorf("want val2\\n, got %q", lastValue.Get()) } go logger.Send(&logMessage{"val3"}) svm.Stop() time.Sleep(10 * time.Millisecond) if sz := logger.size.Get(); sz != 0 { t.Errorf("want 0, got %d", sz) } }
func (f *fileInfo) WaitForChange(svm *sync2.ServiceManager) error { for { // Stop waiting if we're shutting down if svm.State() != sync2.SERVICE_RUNNING { return io.EOF } time.Sleep(100 * time.Millisecond) fi, err := f.handle.Stat() if err != nil { return fmt.Errorf("stat error: %v", err) } if fi.Size() != f.pos { return nil } } }
func TestFileInfo(t *testing.T) { fname := path.Join(os.TempDir(), "binlog_streamer.test") writer, err := os.Create(fname) if err != nil { t.Fatal(err) } defer os.Remove(fname) var file fileInfo err = file.Init(fname, 0) if err != nil { t.Fatal(err) } ch := make(chan []byte, 10) var svm = sync2.ServiceManager{} svm.Go(func(svc *sync2.ServiceContext) error { for svm.State() == sync2.SERVICE_RUNNING { file.WaitForChange(svc) b := make([]byte, 128) n, err := file.handle.Read(b) if err != nil { ch <- []byte(err.Error()) } file.Set(file.lastPos + int64(n)) ch <- b[:n] } return nil }) want := "Message1" writer.WriteString(want) writer.Sync() got := string(<-ch) if want != got { t.Errorf("want %v, got %v", want, got) } want = "Message2" writer.WriteString(want) writer.Sync() got = string(<-ch) if want != got { t.Errorf("want %v, got %v", want, got) } time.Sleep(200 * time.Millisecond) want = "Message3" writer.WriteString(want) writer.Sync() got = string(<-ch) if want != got { t.Errorf("want %v, got %v", want, got) } want = "EOF" svm.Stop() got = string(<-ch) if want != got { t.Errorf("want %v, got %v", want, got) } }
func TestChannel(t *testing.T) { logger := New("logger", 1) lastValue := sync2.AtomicString{} svm := sync2.ServiceManager{} svm.Go(func(_ *sync2.ServiceManager) { ch := logger.Subscribe(nil) defer logger.Unsubscribe(ch) for svm.State() == sync2.SERVICE_RUNNING { lastValue.Set(<-ch) } }) time.Sleep(10 * time.Millisecond) if sz := logger.size.Get(); sz != 1 { t.Errorf("want 1, got %d", sz) } logger.Send(&logMessage{"val2"}) time.Sleep(10 * time.Millisecond) if lastValue.Get() != "val2\n" { t.Errorf("want val2\\n, got %q", lastValue.Get()) } go logger.Send(&logMessage{"val3"}) svm.Stop() time.Sleep(10 * time.Millisecond) if sz := logger.size.Get(); sz != 0 { t.Errorf("want 0, got %d", sz) } }
func BenchmarkConnStreamerParseEvents(b *testing.B) { filename := testfiles.Locate("binlog_test/vt-0000062347-bin.000001") var svm sync2.ServiceManager count := 0 bls := &binlogConnStreamer{dbname: "vt_test_database", sendTransaction: func(tx *proto.BinlogTransaction) error { count++ return nil }} for i := 0; i < b.N; i++ { events := readEvents(b, filename) svm.Go(func(svc *sync2.ServiceContext) error { _, err := bls.parseEvents(svc, events) return err }) if err := svm.Join(); err != ServerEOF { b.Errorf("%v", err) } } b.Logf("%d transactions processed", count) }
func BenchmarkFileStreamerParseEvents(b *testing.B) { filename := testfiles.Locate("binlog_test/vt-0000062347-bin.000001") var svm sync2.ServiceManager count := 0 bls := newTestBinlogFileStreamer("vt_test_database", "", myproto.ReplicationPosition{}, func(tx *proto.BinlogTransaction) error { count++ return nil }) for i := 0; i < b.N; i++ { if err := bls.file.Init(filename, 0); err != nil { b.Fatalf("%v", err) } svm.Go(bls.run) if err := svm.Join(); err != nil { b.Errorf("%v", err) } bls.file.Close() } b.Logf("%d transactions processed", count) }
func TestHTTP(t *testing.T) { l, err := net.Listen("tcp", ":0") if err != nil { t.Fatal(err) } addr := l.Addr().String() go http.Serve(l, nil) logger := New("logger", 1) logger.ServeLogs("/log", func(params url.Values, x interface{}) string { return x.(*logMessage).Format(params) }) // This should not block logger.Send(&logMessage{"val1"}) lastValue := sync2.AtomicString{} svm := sync2.ServiceManager{} svm.Go(func(svc *sync2.ServiceContext) error { resp, err := http.Get(fmt.Sprintf("http://%s/log", addr)) if err != nil { t.Fatal(err) } defer resp.Body.Close() buf := make([]byte, 100) for svc.IsRunning() { n, err := resp.Body.Read(buf) if err != nil { t.Fatal(err) } lastValue.Set(string(buf[:n])) } return nil }) time.Sleep(100 * time.Millisecond) if sz := logger.size.Get(); sz != 1 { t.Errorf("want 1, got %d", sz) } logger.Send(&logMessage{"val2"}) time.Sleep(100 * time.Millisecond) if lastValue.Get() != "val2\n" { t.Errorf("want val2\\n, got %q", lastValue.Get()) } // This part of the test is flaky. // Uncomment for one-time testing. /* // This send will unblock the http client // which will allow it to see the stop request // from svm. go logger.Send(&logMessage{"val3"}) svm.Stop() // You have to send a few times before the writer // returns an error. for i := 0; i < 10; i++ { time.Sleep(100 * time.Millisecond) logger.Send(&logMessage{"val4"}) } time.Sleep(100 * time.Millisecond) if sz := logger.size.Get(); sz != 0 { t.Errorf("want 0, got %d", sz) } */ }