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  }