func TestCompileAndRun(t *testing.T) { var testProgram = `/$/ {}` store := &metrics.Store{} lines := make(chan string) w := watcher.NewFakeWatcher() fs := &afero.MemMapFs{} o := LoaderOptions{store, lines, w, fs, false, false, true} l, err := NewLoader(o) if err != nil { t.Fatalf("couldn't create loader: %s", err) } if err := l.CompileAndRun("Test", strings.NewReader(testProgram)); err != nil { t.Errorf("CompileAndRun returned error: %s", err) } l.handleMu.Lock() if len(l.handles) < 1 { t.Errorf("no vm handles: %v", l.handles) } l.handleMu.Unlock() l.handleMu.Lock() c := l.handles["Test"].done if c == nil { t.Errorf("No done channel in handles: %v", l.handles) } l.handleMu.Unlock() close(lines) <-c { l.handleMu.Lock() defer l.handleMu.Unlock() if len(l.handles) != 0 { t.Errorf("some vm handles: %v", l.handles) } } }
func makeTestTail(t *testing.T) (*Tailer, chan string, *watcher.FakeWatcher, afero.Fs) { fs := &afero.MemMapFs{} w := watcher.NewFakeWatcher() lines := make(chan string, 1) o := Options{lines, w, fs} ta, err := New(o) if err != nil { t.Fatal(err) } return ta, lines, w, fs }
func TestExamplePrograms(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode") } for _, tc := range exampleProgramTests { w := watcher.NewFakeWatcher() o := mtail.Options{Progs: tc.programfile, W: w} mtail, err := mtail.New(o) if err != nil { t.Fatalf("create mtail failed: %s", err) } if err := mtail.OneShot(tc.logfile); err != nil { t.Errorf("Oneshot failed for %s: %s", tc.logfile, err) continue } // Dirty hack to create json files :) if false { j, err := os.Create(tc.jsonfile) if err != nil { t.Errorf("%s: could not open json file: %s", tc.jsonfile, err) continue } defer j.Close() if err := mtail.WriteMetrics(j); err != nil { t.Errorf("couldn't marshall metrics: %q", err) continue } } j, err := os.Open(tc.jsonfile) if err != nil { t.Fatalf("%s: could not open json file: %s", tc.jsonfile, err) } defer j.Close() var m, ex bytes.Buffer mtail.Close() mtail.WriteMetrics(&m) m.WriteString("\n") // Golden data has trailing newline. if _, err := ex.ReadFrom(j); err != nil { t.Fatalf("Coldn't read from json: %s", err) } diff := pretty.Compare(m.String(), ex.String()) if len(diff) > 0 { t.Errorf("%s: metrics don't match:\n%s", tc.programfile, diff) } } }
func CompileAndLoad(programfile string, ms *metrics.Store, lines chan string) (*vm.Loader, error) { p, err := os.Open(programfile) if err != nil { return nil, fmt.Errorf("%s: could not open program file: %s", programfile, err) } defer p.Close() name := filepath.Base(programfile) w := watcher.NewFakeWatcher() o := vm.LoaderOptions{W: w, Store: ms, Lines: lines, SyslogUseCurrentYear: false} l, err := vm.NewLoader(o) if err != nil { return nil, fmt.Errorf("couldn't create program loader: %s", err) } if pErr := l.CompileAndRun(name, p); pErr != nil { return nil, fmt.Errorf("couldn't compile program: %s: %s", programfile, pErr) } return l, nil }
func benchmarkProgram(b *testing.B, programfile string, logfile string) { w := watcher.NewFakeWatcher() o := mtail.Options{Progs: programfile, W: w} mtail, err := mtail.New(o) if err != nil { b.Fatalf("Failed to create mtail: %s", err) } b.ResetTimer() for i := 0; i < b.N; i++ { if err := mtail.OneShot(logfile); err != nil { b.Errorf("OneShot log parse failed: %s", err) } } b.StopTimer() mtail.Close() l, err := strconv.ParseInt(vm.LineCount.String(), 10, 64) if err != nil { b.Fatalf("strconv.ParseInt failed: %s", err) return } b.SetBytes(l) }
func TestNewLoader(t *testing.T) { w := watcher.NewFakeWatcher() store := &metrics.Store{} inLines := make(chan string) fs := &afero.MemMapFs{} o := LoaderOptions{store, inLines, w, fs, false, false, true} l, err := NewLoader(o) if err != nil { t.Fatalf("couldn't create loader: %s", err) } done := make(chan struct{}) outLines := make(chan string) handle := &vmHandle{outLines, done} l.handleMu.Lock() l.handles["test"] = handle l.handleMu.Unlock() go func() { for _ = range outLines { } close(done) }() close(inLines) <-outLines }
func TestProcessEvents(t *testing.T) { for _, tt := range testProcessEvents { w := watcher.NewFakeWatcher() w.Add(".") store := &metrics.Store{} lines := make(chan string) fs := &afero.MemMapFs{} o := LoaderOptions{store, lines, w, fs, false, false, true} l, err := NewLoader(o) if err != nil { t.Fatalf("couldn't create loader: %s", err) } for i := range tt.events { e := tt.events[i] switch e := e.(type) { case watcher.CreateEvent: if e.Pathname != "notexist.mtail" { _, err := fs.Create(e.Pathname) if err != nil { t.Fatalf("Create failed for %s: %s", e.Pathname, err) } } w.InjectCreate(e.Pathname) case watcher.DeleteEvent: err := fs.Remove(e.Pathname) if err != nil { t.Fatalf("Remove failed for %s: %s", e.Pathname, err) } w.InjectDelete(e.Pathname) case watcher.UpdateEvent: if e.Pathname != "notexist.mtail" { f, err := fs.Open(e.Pathname) if err != nil { t.Fatalf("Couldn't open file %s for test: %s", e.Pathname, err) } _, err = f.WriteString(testProgram) if err != nil { t.Fatalf("Couldn't write file contents: %s", err) } if err = f.Close(); err != nil { t.Fatalf("Close failed: %s", err) } } w.InjectUpdate(e.Pathname) } } // ugh; figure out something to synchronise after LoadProg time.Sleep(10 * time.Millisecond) var programs []string l.handleMu.RLock() for program := range l.handles { programs = append(programs, program) } l.handleMu.RUnlock() l.handleMu.RLock() if diff := pretty.Compare(programs, tt.expectedPrograms); len(diff) > 0 { t.Errorf("%s: loaded programs don't match. l.handles: %+#v\n%s", tt.name, l.handles, diff) } l.handleMu.RUnlock() close(lines) } }