// Should wrap four times func TestWrapPut(t *testing.T) { // Simple log blocks := uint32(16) testcachefile := tests.Tempfile() err := tests.CreateFile(testcachefile, 16*4096) tests.Assert(t, nil == err) defer os.Remove(testcachefile) l, logblocks, err := NewLog(testcachefile, 4096, 2, 4096*2, false) tests.Assert(t, err == nil) tests.Assert(t, l != nil) tests.Assert(t, blocks == logblocks) l.Start() here := make(chan *message.Message) wraps := uint32(4) // Write enough blocks to wrap around the log // as many times as determined by the value in 'wraps' for io := uint32(0); io < (blocks * wraps); io++ { buf := make([]byte, 4096) buf[0] = byte(io) msg := message.NewMsgPut() msg.RetChan = here iopkt := msg.IoPkt() iopkt.Buffer = buf iopkt.LogBlock = io % blocks l.Msgchan <- msg <-here } // Close will also empty all the channels l.Close() // Check that we have wrapped the correct number of times tests.Assert(t, l.Stats().Wraps == uint64(wraps)) }
func TestSpcOpen(t *testing.T) { // initialize var cache *cache.CacheMap usedirectio := false blocksize := 4 * KB s := NewSpcInfo(cache, usedirectio, blocksize) // Get a test file tmpfile := tests.Tempfile() // No file exists err := s.Open(1, tmpfile) tests.Assert(t, err != nil) // Create the file and open it err = tests.CreateFile(tmpfile, 16*4*KB) tests.Assert(t, err == nil) defer os.Remove(tmpfile) // Now open, and it should work err = s.Open(1, tmpfile) tests.Assert(t, err == nil) }
func TestLogConcurrency(t *testing.T) { // Simple log blocks := uint32(240) bs := uint32(4096) blocks_per_segment := uint32(2) buffercache := uint32(4096 * 24) testcachefile := tests.Tempfile() tests.Assert(t, nil == tests.CreateFile(testcachefile, int64(blocks*4096))) defer os.Remove(testcachefile) l, logblocks, err := NewLog(testcachefile, bs, blocks_per_segment, buffercache, false) tests.Assert(t, err == nil) tests.Assert(t, l != nil) tests.Assert(t, blocks == logblocks) l.Start() here := make(chan *message.Message) // Fill the log for io := uint32(0); io < blocks; io++ { buf := make([]byte, 4096) buf[0] = byte(io) msg := message.NewMsgPut() msg.RetChan = here iopkt := msg.IoPkt() iopkt.Buffer = buf iopkt.LogBlock = io l.Msgchan <- msg <-here } var wgIo, wgRet sync.WaitGroup // Start up response server returnch := make(chan *message.Message, 100) quit := make(chan struct{}) wgRet.Add(1) go logtest_response_handler(t, &wgRet, quit, returnch) // Create 100 readers for i := 0; i < 100; i++ { wgIo.Add(1) go func() { defer wgIo.Done() r := rand.New(rand.NewSource(time.Now().UnixNano())) // Each client to send 1k IOs for io := 0; io < 1000; io++ { msg := message.NewMsgGet() iopkt := msg.IoPkt() iopkt.Buffer = make([]byte, bs) // Maximum "disk" size is 10 times bigger than cache iopkt.LogBlock = uint32(r.Int31n(int32(blocks))) msg.RetChan = returnch // Send request msg.TimeStart() l.Msgchan <- msg // Simulate waiting for more work by sleeping // anywhere from 100usecs to 10ms time.Sleep(time.Microsecond * time.Duration((r.Intn(10000) + 100))) } }() } // Write to the log while the readers are reading r := rand.New(rand.NewSource(time.Now().UnixNano())) for wrap := 0; wrap < 30; wrap++ { for io := uint32(0); io < blocks; io++ { buf := make([]byte, 4096) buf[0] = byte(io) msg := message.NewMsgPut() msg.RetChan = returnch iopkt := msg.IoPkt() iopkt.Buffer = buf iopkt.LogBlock = io msg.TimeStart() l.Msgchan <- msg time.Sleep(time.Microsecond * time.Duration((r.Intn(1000) + 100))) } } // Wait for all clients to finish wgIo.Wait() // Send receiver a message that all clients have shut down close(quit) // Wait for receiver to finish emptying its channel wgRet.Wait() // Cleanup fmt.Print(l) l.Close() os.Remove(testcachefile) }
func TestReadCorrectness(t *testing.T) { // Simple log blocks := uint32(240) bs := uint32(4096) blocks_per_segment := uint32(2) buffercache := uint32(4096 * 10) testcachefile := tests.Tempfile() tests.Assert(t, nil == tests.CreateFile(testcachefile, int64(blocks*4096))) defer os.Remove(testcachefile) l, logblocks, err := NewLog(testcachefile, bs, blocks_per_segment, buffercache, false) tests.Assert(t, err == nil) tests.Assert(t, l != nil) tests.Assert(t, blocks == logblocks) l.Start() here := make(chan *message.Message) // Write enough blocks in the log to reach // the end. for io := uint32(0); io < blocks; io++ { buf := make([]byte, 4096) // Save the block number in the buffer // so that we can check it later. For simplicity // we have made sure the block number is only // one byte. buf[0] = byte(io) msg := message.NewMsgPut() msg.RetChan = here iopkt := msg.IoPkt() iopkt.Buffer = buf iopkt.LogBlock = io l.Msgchan <- msg <-here } buf := make([]byte, 4096) msg := message.NewMsgGet() msg.RetChan = here iopkt := msg.IoPkt() iopkt.Buffer = buf iopkt.LogBlock = blocks - 1 l.Msgchan <- msg <-here tests.Assert(t, buf[0] == uint8(blocks-1)) for io := uint32(0); io < blocks; io++ { buf := make([]byte, 4096) msg := message.NewMsgGet() msg.RetChan = here iopkt := msg.IoPkt() iopkt.Buffer = buf iopkt.LogBlock = io l.Msgchan <- msg // Wait here for the response <-here // Check the block number is correct tests.Assert(t, buf[0] == uint8(io)) } l.Close() }