Example #1
// readFromVDI returns the count of total reads the corresponding VDI was subject to
// along with the no. of failed attempts, with the last seen error.
func readFromVDI(vdi *picard.VDI, vdiChan <-chan *vdiData, delay time.Duration) (int, int, error) {
	// size of the buffer should be equal to twice the size of
	// random payload.
	var buf [8]byte
	var total, failed, offset int
	var err error

	for vdat := range vdiChan {

		n, rerr := vdi.ReadAt(buf[:], offset)
		if rerr != nil {
			err = rerr
		} else if !reflect.DeepEqual(vdat.payload, buf[:n]) {
			// This will register the error within `err` at a high level scope
			// and continue processing remaining reads increasing the count
			// of failures.
			err = fmt.Errorf("new payload does not match original. New: %+v, Old: %+v", vdat.payload, buf[:n])
		} else {
			log.Printf("Complete reading %d payloads", total)

		offset += n
	return total, failed, err
Example #2
// writeToVDI sends data packets to the vdi interface upto the
// count number that is defined within the function. If there is
// an error, it returns the no. of packets sent until the error
// occurred.
func writeToVDI(vdi *picard.VDI, vdiChan chan<- *vdiData, count int) (int, error) {
	defer close(vdiChan)

	var offset int
	for i := 0; i < count; i++ {
		buf := randPayload()
		if _, err := vdi.WriteAt(buf, offset); err != nil {
			return i, err
		vdiChan <- &vdiData{buf}
		offset += len(buf)
	return count, nil