func Test_Journal_GetJournal(t *testing.T) { logging.InitForTesting(logging.NOTICE) logger := logging.MustGetLogger("journal") tempDir, err := ioutil.TempDir("", "journal") if err != nil { t.FailNow() } defer os.RemoveAll(tempDir) factory := NewFileJournalGroupFactory( logger, rand.NewSource(0), func() time.Time { return time.Date(2014, 1, 1, 0, 0, 0, 0, time.UTC) }, ".log", os.FileMode(0644), 0, ) dummyWorker := &DummyWorker{} tempFile := filepath.Join(tempDir, "test") t.Log(tempFile) journalGroup, err := factory.GetJournalGroup(tempFile, dummyWorker) if err != nil { t.FailNow() } journal1 := journalGroup.GetJournal("key") if journal1 == nil { t.FailNow() } journal2 := journalGroup.GetJournal("key") if journal2 == nil { t.Fail() } if journal1 != journal2 { t.Fail() } }
func Test_Journal_EmitRotating(t *testing.T) { logging.InitForTesting(logging.NOTICE) logger := logging.MustGetLogger("journal") tempDir, err := ioutil.TempDir("", "journal") if err != nil { t.FailNow() } defer os.RemoveAll(tempDir) factory := NewFileJournalGroupFactory( logger, rand.NewSource(0), func() time.Time { return time.Date(2014, 1, 1, 0, 0, 0, 0, time.UTC) }, ".log", os.FileMode(0644), 8, ) dummyWorker := &DummyWorker{} tempFile := filepath.Join(tempDir, "test") t.Log(tempFile) journalGroup, err := factory.GetJournalGroup(tempFile, dummyWorker) if err != nil { t.FailNow() } journal := journalGroup.GetFileJournal("key") defer journal.Dispose() err = journal.Write([]byte("test1")) if err != nil { t.FailNow() } err = journal.Write([]byte("test2")) if err != nil { t.FailNow() } err = journal.Write([]byte("test3")) if err != nil { t.FailNow() } err = journal.Write([]byte("test4")) if err != nil { t.FailNow() } err = journal.Write([]byte("test5")) if err != nil { t.FailNow() } t.Logf("journal.chunks.count=%d", journal.chunks.count) t.Logf("journal.chunks.first.Size=%d", journal.chunks.first.Size) if journal.chunks.count != 5 { t.Fail() } if journal.chunks.first.Size != 5 { t.Fail() } }
func Test_Journal_Concurrency(t *testing.T) { logging.InitForTesting(logging.NOTICE) logger := logging.MustGetLogger("journal") tempDir, err := ioutil.TempDir("", "journal") if err != nil { t.FailNow() } defer os.RemoveAll(tempDir) factory := NewFileJournalGroupFactory( logger, rand.NewSource(0), func() time.Time { return time.Date(2014, 1, 1, 0, 0, 0, 0, time.UTC) }, ".log", os.FileMode(0644), 16, ) dummyWorker := &DummyWorker{} tempFile := filepath.Join(tempDir, "test") t.Log(tempFile) journalGroup, err := factory.GetJournalGroup(tempFile, dummyWorker) if err != nil { t.FailNow() } journal := journalGroup.GetFileJournal("key") defer journal.Dispose() cond := sync.Cond{L: &sync.Mutex{}} count := int64(0) outerWg := sync.WaitGroup{} doFlush := func() { journal.Flush(func(chunk JournalChunk) interface{} { defer chunk.Dispose() reader, err := chunk.Reader() if err != nil { t.Log(err.Error()) t.FailNow() } defer reader.Close() c, err := countLines(reader) if err != nil { t.Log(err.Error()) t.FailNow() } atomic.AddInt64(&count, int64(c)) return nil }) } for j := 0; j < 10; j += 1 { outerWg.Add(1) go func(j int) { defer outerWg.Done() wg := sync.WaitGroup{} starting := sync.WaitGroup{} for i := 0; i < 10; i += 1 { wg.Add(1) starting.Add(1) go func(i int) { defer wg.Done() starting.Done() cond.L.Lock() cond.Wait() cond.L.Unlock() for k := 0; k < 3; k += 1 { data := fmt.Sprintf("test%d\n", i) err = journal.Write([]byte(data)) if err != nil { t.Log(err.Error()) t.FailNow() } } }(i) } starting.Wait() cond.Broadcast() runtime.Gosched() doFlush() wg.Wait() }(j) } outerWg.Wait() doFlush() if count != 300 { t.Logf("%d", count) t.Fail() } }
func Test_Journal_FlushListener(t *testing.T) { logging.InitForTesting(logging.NOTICE) logger := logging.MustGetLogger("journal") tempDir, err := ioutil.TempDir("", "journal") if err != nil { t.FailNow() } defer os.RemoveAll(tempDir) factory := NewFileJournalGroupFactory( logger, rand.NewSource(0), func() time.Time { return time.Date(2014, 1, 1, 0, 0, 0, 0, time.UTC) }, ".log", os.FileMode(0644), 8, ) dummyWorker := &DummyWorker{} tempFile := filepath.Join(tempDir, "test") t.Log(tempFile) journalGroup, err := factory.GetJournalGroup(tempFile, dummyWorker) if err != nil { t.FailNow() } journal := journalGroup.GetFileJournal("key") defer journal.Dispose() listener := &DummyChunkListener{ t: t, chunks: make([]FileJournalChunk, 0, 5), } journal.AddFlushListener(listener) journal.AddFlushListener(listener) err = journal.Write([]byte("test1")) if err != nil { t.FailNow() } err = journal.Write([]byte("test2")) if err != nil { t.FailNow() } err = journal.Write([]byte("test3")) if err != nil { t.FailNow() } err = journal.Write([]byte("test4")) if err != nil { t.FailNow() } err = journal.Write([]byte("test5")) if err != nil { t.FailNow() } t.Logf("journal.chunks.count=%d", journal.chunks.count) t.Logf("journal.chunks.first.Size=%d", journal.chunks.first.Size) t.Logf("len(listener.chunks)=%d", len(listener.chunks)) if journal.chunks.count != 5 { t.Fail() } if journal.chunks.first.Size != 5 { t.Fail() } if len(listener.chunks) != 4 { t.Fail() } readAll := func(chunk FileJournalChunk) string { reader, err := chunk.getReader() if err != nil { t.FailNow() } defer reader.Close() bytes, err := ioutil.ReadAll(reader) if err != nil { t.FailNow() } return string(bytes) } if readAll(listener.chunks[0]) != "test1" { t.Fail() } if readAll(listener.chunks[1]) != "test2" { t.Fail() } if readAll(listener.chunks[2]) != "test3" { t.Fail() } if readAll(listener.chunks[3]) != "test4" { t.Fail() } journal.Flush(nil) t.Logf("journal.chunks.count=%d", journal.chunks.count) t.Logf("journal.chunks.first.Size=%d", journal.chunks.first.Size) if journal.chunks.count != 1 { t.Fail() } if journal.chunks.first.Type != JournalFileType('b') { t.Fail() } }
func Test_Journal_Scanning_MultipleHead(t *testing.T) { logging.InitForTesting(logging.NOTICE) logger := logging.MustGetLogger("journal") tempDir, err := ioutil.TempDir("", "journal") if err != nil { t.FailNow() } defer os.RemoveAll(tempDir) tm := time.Date(2014, 1, 1, 0, 0, 0, 0, time.UTC) prefix := filepath.Join(tempDir, "test") suffix := ".log" createFile := func(key string, type_ JournalFileType, o int) (string, error) { path := prefix + "." + BuildJournalPath(key, type_, tm.Add(time.Duration(-o*1e9)), 0).VariablePortion + suffix file, err := os.Create(path) if err != nil { return "", err } _, err = file.Write([]byte(fmt.Sprintf("%08d", o))) if err != nil { return "", err } file.Close() t.Log(path) return path, nil } paths := make([]string, 4) { path, err := createFile("key", JournalFileType('b'), 0) if err != nil { t.FailNow() } paths[0] = path } { path, err := createFile("key", JournalFileType('b'), 1) if err != nil { t.FailNow() } paths[1] = path } { path, err := createFile("key", JournalFileType('q'), 2) if err != nil { t.FailNow() } paths[2] = path } { path, err := createFile("key", JournalFileType('q'), 3) if err != nil { t.FailNow() } paths[3] = path } factory := NewFileJournalGroupFactory( logger, rand.NewSource(0), func() time.Time { return tm }, suffix, os.FileMode(0644), 8, ) dummyWorker := &DummyWorker{} _, err = factory.GetJournalGroup(prefix, dummyWorker) if err == nil { t.FailNow() } t.Log(err.Error()) if err.Error() != "multiple chunk heads found" { t.Fail() } }
func Test_Journal_Scanning_Ok(t *testing.T) { logging.InitForTesting(logging.NOTICE) logger := logging.MustGetLogger("journal") tm := time.Date(2014, 1, 1, 0, 0, 0, 0, time.UTC) for i := 1; i < 100; i++ { tempDir, err := ioutil.TempDir("", "journal") if err != nil { t.FailNow() } defer os.RemoveAll(tempDir) prefix := filepath.Join(tempDir, "test") suffix := ".log" makePaths := func(n int, key string) []string { paths := make([]string, n) for i := 0; i < len(paths); i += 1 { type_ := JournalFileType('q') if i == 0 { type_ = JournalFileType('b') } path := prefix + "." + BuildJournalPath(key, type_, tm.Add(time.Duration(-i*1e9)), 0).VariablePortion + suffix paths[i] = path } return paths } paths := makePaths(i, "key") shuffledPaths := make([]string, len(paths)) copy(shuffledPaths, paths) shuffle(shuffledPaths) for j, path := range shuffledPaths { file, err := os.Create(path) if err != nil { t.FailNow() } _, err = file.Write([]byte(fmt.Sprintf("%08d", j))) if err != nil { t.FailNow() } file.Close() } factory := NewFileJournalGroupFactory( logger, rand.NewSource(0), func() time.Time { return tm }, suffix, os.FileMode(0644), 8, ) dummyWorker := &DummyWorker{} journalGroup, err := factory.GetJournalGroup(prefix, dummyWorker) if err != nil { t.FailNow() } journal := journalGroup.GetFileJournal("key") defer journal.Dispose() t.Logf("journal.chunks.count=%d", journal.chunks.count) t.Logf("journal.chunks.first.Size=%d", journal.chunks.first.Size) if journal.chunks.count != i { t.Fail() } j := 0 for chunk := journal.chunks.first; chunk != nil; chunk = chunk.head.next { if chunk.Path != paths[j] { t.Fail() } j += 1 } journal.Flush(nil) os.RemoveAll(tempDir) t.Logf("journal.chunks.count=%d", journal.chunks.count) if journal.chunks.count != 1 { t.Fail() } } }