Ejemplo n.º 1
0
// 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))
}
Ejemplo n.º 2
0
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)
}
Ejemplo n.º 3
0
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)

}
Ejemplo n.º 4
0
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()
}