github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/cmd/mount/test/seeker.go (about) 1 //go:build ignore 2 3 // Read two files with lots of seeking to stress test the seek code 4 package main 5 6 import ( 7 "bytes" 8 "flag" 9 "io" 10 "log" 11 "math/rand" 12 "os" 13 "time" 14 ) 15 16 var ( 17 // Flags 18 iterations = flag.Int("n", 1e6, "Iterations to try") 19 maxBlockSize = flag.Int("b", 1024*1024, "Max block size to read") 20 ) 21 22 func init() { 23 rand.Seed(time.Now().UnixNano()) 24 } 25 26 func randomSeekTest(size int64, in1, in2 *os.File, file1, file2 string) { 27 start := rand.Int63n(size) 28 blockSize := rand.Intn(*maxBlockSize) 29 if int64(blockSize) > size-start { 30 blockSize = int(size - start) 31 } 32 log.Printf("Reading %d from %d", blockSize, start) 33 34 _, err := in1.Seek(start, io.SeekStart) 35 if err != nil { 36 log.Fatalf("Seek failed on %q: %v", file1, err) 37 } 38 _, err = in2.Seek(start, io.SeekStart) 39 if err != nil { 40 log.Fatalf("Seek failed on %q: %v", file2, err) 41 } 42 43 buf1 := make([]byte, blockSize) 44 n1, err := io.ReadFull(in1, buf1) 45 if err != nil { 46 log.Fatalf("Read failed on %q: %v", file1, err) 47 } 48 49 buf2 := make([]byte, blockSize) 50 n2, err := io.ReadFull(in2, buf2) 51 if err != nil { 52 log.Fatalf("Read failed on %q: %v", file2, err) 53 } 54 55 if n1 != n2 { 56 log.Fatalf("Read different lengths %d (%q) != %d (%q)", n1, file1, n2, file2) 57 } 58 59 if !bytes.Equal(buf1, buf2) { 60 log.Printf("Dumping different blocks") 61 err = os.WriteFile("/tmp/z1", buf1, 0777) 62 if err != nil { 63 log.Fatalf("Failed to write /tmp/z1: %v", err) 64 } 65 err = os.WriteFile("/tmp/z2", buf2, 0777) 66 if err != nil { 67 log.Fatalf("Failed to write /tmp/z2: %v", err) 68 } 69 log.Fatalf("Read different contents - saved in /tmp/z1 and /tmp/z2") 70 } 71 } 72 73 func main() { 74 flag.Parse() 75 args := flag.Args() 76 if len(args) != 2 { 77 log.Fatalf("Require 2 files as argument") 78 } 79 file1, file2 := args[0], args[1] 80 in1, err := os.Open(file1) 81 if err != nil { 82 log.Fatalf("Couldn't open %q: %v", file1, err) 83 } 84 in2, err := os.Open(file2) 85 if err != nil { 86 log.Fatalf("Couldn't open %q: %v", file2, err) 87 } 88 89 fi1, err := in1.Stat() 90 if err != nil { 91 log.Fatalf("Couldn't stat %q: %v", file1, err) 92 } 93 fi2, err := in2.Stat() 94 if err != nil { 95 log.Fatalf("Couldn't stat %q: %v", file2, err) 96 } 97 98 if fi1.Size() != fi2.Size() { 99 log.Fatalf("Files not the same size") 100 } 101 102 for i := 0; i < *iterations; i++ { 103 randomSeekTest(fi1.Size(), in1, in2, file1, file2) 104 } 105 106 err = in1.Close() 107 if err != nil { 108 log.Fatalf("Error closing %q: %v", file1, err) 109 } 110 err = in2.Close() 111 if err != nil { 112 log.Fatalf("Error closing %q: %v", file2, err) 113 } 114 }