// 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 { time.Sleep(delay) total++ n, rerr := vdi.ReadAt(buf[:], offset) if rerr != nil { err = rerr failed++ } 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]) failed++ } else { log.Printf("Complete reading %d payloads", total) } offset += n } return total, failed, err }
// 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 }