github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/vfs/make_open_tests.go (about) 1 // This makes the open test suite 2 // 3 // Run with go run make_open_tests.go | gofmt > open_test.go 4 // 5 //+build none 6 7 // FIXME include read too? 8 9 package main 10 11 import ( 12 "fmt" 13 "io" 14 "io/ioutil" 15 "log" 16 "os" 17 "strings" 18 19 "github.com/ncw/rclone/lib/file" 20 ) 21 22 // Interprets err into a vfs error 23 func whichError(err error) string { 24 switch err { 25 case nil: 26 return "nil" 27 case io.EOF: 28 return "io.EOF" 29 } 30 s := err.Error() 31 switch { 32 case strings.Contains(s, "no such file or directory"): 33 return "ENOENT" 34 case strings.Contains(s, "bad file descriptor"): 35 return "EBADF" 36 case strings.Contains(s, "file exists"): 37 return "EEXIST" 38 } 39 log.Fatalf("Unknown error: %v", err) 40 return "" 41 } 42 43 // test Opening, reading and writing the file handle with the flags given 44 func test(fileName string, flags int, mode string) { 45 // first try with file not existing 46 _, err := os.Stat(fileName) 47 if !os.IsNotExist(err) { 48 log.Fatalf("File must not exist") 49 } 50 f, openNonExistentErr := file.OpenFile(fileName, flags, 0666) 51 52 var readNonExistentErr error 53 var writeNonExistentErr error 54 if openNonExistentErr == nil { 55 // read some bytes 56 buf := []byte{0, 0} 57 _, readNonExistentErr = f.Read(buf) 58 59 // write some bytes 60 _, writeNonExistentErr = f.Write([]byte("hello")) 61 62 // close 63 err = f.Close() 64 if err != nil { 65 log.Fatalf("failed to close: %v", err) 66 } 67 } 68 69 // write the file 70 f, err = file.Create(fileName) 71 if err != nil { 72 log.Fatalf("failed to create: %v", err) 73 } 74 n, err := f.Write([]byte("hello")) 75 if n != 5 || err != nil { 76 log.Fatalf("failed to write n=%d: %v", n, err) 77 } 78 // close 79 err = f.Close() 80 if err != nil { 81 log.Fatalf("failed to close: %v", err) 82 } 83 84 // then open file and try with file existing 85 86 f, openExistingErr := file.OpenFile(fileName, flags, 0666) 87 var readExistingErr error 88 var writeExistingErr error 89 if openExistingErr == nil { 90 // read some bytes 91 buf := []byte{0, 0} 92 _, readExistingErr = f.Read(buf) 93 94 // write some bytes 95 _, writeExistingErr = f.Write([]byte("HEL")) 96 97 // close 98 err = f.Close() 99 if err != nil { 100 log.Fatalf("failed to close: %v", err) 101 } 102 } 103 104 // read the file 105 f, err = file.Open(fileName) 106 if err != nil { 107 log.Fatalf("failed to open: %v", err) 108 } 109 var buf = make([]byte, 64) 110 n, err = f.Read(buf) 111 if err != nil && err != io.EOF { 112 log.Fatalf("failed to read n=%d: %v", n, err) 113 } 114 err = f.Close() 115 if err != nil { 116 log.Fatalf("failed to close: %v", err) 117 } 118 contents := string(buf[:n]) 119 120 // remove file 121 err = os.Remove(fileName) 122 if err != nil { 123 log.Fatalf("failed to remove: %v", err) 124 } 125 126 // output the struct 127 fmt.Printf(`{ 128 flags: %s, 129 what: %q, 130 openNonExistentErr: %s, 131 readNonExistentErr: %s, 132 writeNonExistentErr: %s, 133 openExistingErr: %s, 134 readExistingErr: %s, 135 writeExistingErr: %s, 136 contents: %q, 137 },`, 138 mode, 139 mode, 140 whichError(openNonExistentErr), 141 whichError(readNonExistentErr), 142 whichError(writeNonExistentErr), 143 whichError(openExistingErr), 144 whichError(readExistingErr), 145 whichError(writeExistingErr), 146 contents) 147 } 148 149 func main() { 150 fmt.Printf(`// data generated by go run make_open_tests.go | gofmt > open_test.go 151 152 package vfs 153 154 import ( 155 "os" 156 "io" 157 ) 158 159 // openTest describes a test of OpenFile 160 type openTest struct{ 161 flags int 162 what string 163 openNonExistentErr error 164 readNonExistentErr error 165 writeNonExistentErr error 166 openExistingErr error 167 readExistingErr error 168 writeExistingErr error 169 contents string 170 } 171 172 // openTests is a suite of tests for OpenFile with all possible 173 // combination of flags. This obeys Unix semantics even on Windows. 174 var openTests = []openTest{ 175 `) 176 f, err := ioutil.TempFile("", "open-test") 177 if err != nil { 178 log.Fatal(err) 179 } 180 fileName := f.Name() 181 _ = f.Close() 182 err = os.Remove(fileName) 183 if err != nil { 184 log.Fatalf("failed to remove: %v", err) 185 } 186 for _, rwMode := range []int{os.O_RDONLY, os.O_WRONLY, os.O_RDWR} { 187 flags0 := rwMode 188 parts0 := []string{"os.O_RDONLY", "os.O_WRONLY", "os.O_RDWR"}[rwMode : rwMode+1] 189 for _, appendMode := range []int{0, os.O_APPEND} { 190 flags1 := flags0 | appendMode 191 parts1 := parts0 192 if appendMode != 0 { 193 parts1 = append(parts1, "os.O_APPEND") 194 } 195 for _, createMode := range []int{0, os.O_CREATE} { 196 flags2 := flags1 | createMode 197 parts2 := parts1 198 if createMode != 0 { 199 parts2 = append(parts2, "os.O_CREATE") 200 } 201 for _, exclMode := range []int{0, os.O_EXCL} { 202 flags3 := flags2 | exclMode 203 parts3 := parts2 204 if exclMode != 0 { 205 parts3 = append(parts2, "os.O_EXCL") 206 } 207 for _, syncMode := range []int{0, os.O_SYNC} { 208 flags4 := flags3 | syncMode 209 parts4 := parts3 210 if syncMode != 0 { 211 parts4 = append(parts4, "os.O_SYNC") 212 } 213 for _, truncMode := range []int{0, os.O_TRUNC} { 214 flags5 := flags4 | truncMode 215 parts5 := parts4 216 if truncMode != 0 { 217 parts5 = append(parts5, "os.O_TRUNC") 218 } 219 textMode := strings.Join(parts5, "|") 220 flags := flags5 221 222 test(fileName, flags, textMode) 223 } 224 } 225 } 226 } 227 } 228 } 229 fmt.Printf("\n}\n") 230 }