From 118e8e1470ce80cc4bffd13a964dcc77e76bfa2f Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 12 Apr 2022 13:37:35 +0100 Subject: [PATCH] test makefiles: add --sparse, --zero, --pattern and --ascii flags --- cmd/test/makefiles/makefiles.go | 78 ++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/cmd/test/makefiles/makefiles.go b/cmd/test/makefiles/makefiles.go index 0771ec084..ac8e2041d 100644 --- a/cmd/test/makefiles/makefiles.go +++ b/cmd/test/makefiles/makefiles.go @@ -5,6 +5,7 @@ package makefiles import ( "io" "log" + "math" "math/rand" "os" "path/filepath" @@ -16,6 +17,7 @@ import ( "github.com/rclone/rclone/fs/config/flags" "github.com/rclone/rclone/lib/file" "github.com/rclone/rclone/lib/random" + "github.com/rclone/rclone/lib/readers" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -30,9 +32,14 @@ var ( minFileNameLength = 4 maxFileNameLength = 12 seed = int64(1) + zero = false + sparse = false + ascii = false + pattern = false // Globals randSource *rand.Rand + source io.Reader directoriesToCreate int totalDirectories int fileNames = map[string]struct{}{} // keep a note of which file name we've used already @@ -55,18 +62,13 @@ func init() { // Common flags to makefiles and makefile for _, f := range []*pflag.FlagSet{makefilesFlags, makefileFlags} { flags.Int64VarP(f, &seed, "seed", "", seed, "Seed for the random number generator (0 for random)") + flags.BoolVarP(f, &zero, "zero", "", zero, "Fill files with ASCII 0x00") + flags.BoolVarP(f, &sparse, "sparse", "", sparse, "Make the files sparse (appear to be filled with ASCII 0x00)") + flags.BoolVarP(f, &ascii, "ascii", "", ascii, "Fill files with random ASCII printable bytes only") + flags.BoolVarP(f, &pattern, "pattern", "", ascii, "Fill files with a periodic pattern") } } -// common initialisation for makefiles and makefile -func commonInit() { - if seed == 0 { - seed = time.Now().UnixNano() - fs.Logf(nil, "Using random seed = %d", seed) - } - randSource = rand.New(rand.NewSource(seed)) -} - var makefilesCmd = &cobra.Command{ Use: "makefiles ", Short: `Make a random file hierarchy in a directory`, @@ -96,7 +98,7 @@ var makefilesCmd = &cobra.Command{ } var makefileCmd = &cobra.Command{ - Use: "makefile []+", + Use: "makefile []+ [flags]", Short: `Make files with random contents of the size given`, Run: func(command *cobra.Command, args []string) { cmd.CheckArgs(1, 1e6, command, args) @@ -120,6 +122,56 @@ var makefileCmd = &cobra.Command{ }, } +func bool2int(b bool) int { + if b { + return 1 + } + return 0 +} + +// common initialisation for makefiles and makefile +func commonInit() { + if seed == 0 { + seed = time.Now().UnixNano() + fs.Logf(nil, "Using random seed = %d", seed) + } + randSource = rand.New(rand.NewSource(seed)) + if bool2int(zero)+bool2int(sparse)+bool2int(ascii)+bool2int(pattern) > 1 { + log.Fatal("Can only supply one of --zero, --sparse, --ascii or --pattern") + } + switch { + case zero, sparse: + source = zeroReader{} + case ascii: + source = asciiReader{} + case pattern: + source = readers.NewPatternReader(math.MaxInt64) + default: + source = randSource + } +} + +type zeroReader struct{} + +// Read a chunk of zeroes +func (zeroReader) Read(p []byte) (n int, err error) { + for i := range p { + p[i] = 0 + } + return len(p), nil +} + +type asciiReader struct{} + +// Read a chunk of printable ASCII characters +func (asciiReader) Read(p []byte) (n int, err error) { + n, err = randSource.Read(p) + for i := range p[:n] { + p[i] = (p[i] % (0x7F - 0x20)) + 0x20 + } + return n, err +} + // fileName creates a unique random file or directory name func fileName() (name string) { for { @@ -184,7 +236,11 @@ func writeFile(dir, name string, size int64) { if err != nil { log.Fatalf("Failed to open file %q: %v", path, err) } - _, err = io.CopyN(fd, randSource, size) + if sparse { + err = fd.Truncate(size) + } else { + _, err = io.CopyN(fd, source, size) + } if err != nil { log.Fatalf("Failed to write %v bytes to file %q: %v", size, path, err) }