func TestInvalidateMultipleBlocks(t *testing.T) { nc := message.NewNullTerminator() nc.Start() defer nc.Close() c := NewCacheMap(8, 4096, nc.In) tests.Assert(t, c != nil) defer c.Close() // Insert some values in the addressmap for i := uint32(0); i < 4; i++ { // The key is block number c.addressmap[uint64(i)] = i } // This value should still be on the addressmap c.addressmap[8] = 8 iopkt := &message.IoPkt{ Address: 0, Blocks: 8, } c.Invalidate(iopkt) tests.Assert(t, c.stats.invalidations == uint64(iopkt.Blocks)) tests.Assert(t, c.stats.invalidatehits == 4) tests.Assert(t, c.addressmap[8] == 8) }
func TestNewCacheMap(t *testing.T) { nc := message.NewNullTerminator() nc.Start() defer nc.Close() c := NewCacheMap(8, 4096, nc.In) tests.Assert(t, c != nil) c.Close() }
func TestCacheMapConcurrency(t *testing.T) { var wgIo, wgRet sync.WaitGroup nc := message.NewNullTerminator() nc.Start() defer nc.Close() c := NewCacheMap(300, 4096, nc.In) // Start up response server returnch := make(chan *message.Message, 100) quit := make(chan struct{}) wgRet.Add(1) go response_handler(&wgRet, quit, returnch) // Create 100 clients 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++ { var msg *message.Message switch r.Intn(2) { case 0: msg = message.NewMsgGet() case 1: msg = message.NewMsgPut() } iopkt := msg.IoPkt() iopkt.Buffer = make([]byte, 4096) // Maximum "disk" size is 10 times bigger than cache iopkt.Address = uint64(r.Int63n(3000)) msg.RetChan = returnch // Send request msg.TimeStart() switch msg.Type { case message.MsgGet: c.Get(msg) case message.MsgPut: c.Invalidate(iopkt) c.Put(msg) } // Simulate waiting for more work by sleeping // anywhere from 100usecs to 10ms time.Sleep(time.Microsecond * time.Duration((r.Intn(10000) + 100))) } }() } // Wait for all clients to finish wgIo.Wait() // Send receiver a message that all clients have shut down fmt.Print(c) c.Close() close(quit) // Wait for receiver to finish emptying its channel wgRet.Wait() }