test makefiles: add --seed flag and make data generated repeatable #5214

This commit is contained in:
Nick Craig-Wood 2021-04-10 13:42:17 +01:00
parent 813bf029d4
commit 60dcafe04d
2 changed files with 26 additions and 10 deletions

View file

@ -3,12 +3,12 @@
package makefiles
import (
cryptrand "crypto/rand"
"io"
"log"
"math/rand"
"os"
"path/filepath"
"time"
"github.com/rclone/rclone/cmd"
"github.com/rclone/rclone/cmd/test"
@ -27,8 +27,10 @@ var (
maxFileSize = fs.SizeSuffix(100)
minFileNameLength = 4
maxFileNameLength = 12
seed = int64(1)
// Globals
randSource *rand.Rand
directoriesToCreate int
totalDirectories int
fileNames = map[string]struct{}{} // keep a note of which file name we've used already
@ -44,6 +46,7 @@ func init() {
flags.FVarP(cmdFlags, &maxFileSize, "max-file-size", "", "Maximum size of files to create")
flags.IntVarP(cmdFlags, &minFileNameLength, "min-name-length", "", minFileNameLength, "Minimum size of file names")
flags.IntVarP(cmdFlags, &maxFileNameLength, "max-name-length", "", maxFileNameLength, "Maximum size of file names")
flags.Int64VarP(cmdFlags, &seed, "seed", "", seed, "Seed for the random number generator (0 for random)")
}
var commandDefinition = &cobra.Command{
@ -51,6 +54,11 @@ var commandDefinition = &cobra.Command{
Short: `Make a random file hierarchy in <dir>`,
Run: func(command *cobra.Command, args []string) {
cmd.CheckArgs(1, 1, command, args)
if seed == 0 {
seed = time.Now().UnixNano()
log.Printf("Using random seed = %d", seed)
}
randSource = rand.New(rand.NewSource(seed))
outputDirectory := args[0]
directoriesToCreate = numberOfFiles / averageFilesPerDirectory
averageSize := (minFileSize + maxFileSize) / 2
@ -61,7 +69,7 @@ var commandDefinition = &cobra.Command{
}
dirs := root.list("", []string{})
for i := 0; i < numberOfFiles; i++ {
dir := dirs[rand.Intn(len(dirs))]
dir := dirs[randSource.Intn(len(dirs))]
writeFile(dir, fileName())
}
log.Printf("Done.")
@ -71,8 +79,8 @@ var commandDefinition = &cobra.Command{
// fileName creates a unique random file or directory name
func fileName() (name string) {
for {
length := rand.Intn(maxFileNameLength-minFileNameLength) + minFileNameLength
name = random.String(length)
length := randSource.Intn(maxFileNameLength-minFileNameLength) + minFileNameLength
name = random.StringFn(length, randSource.Intn)
if _, found := fileNames[name]; !found {
break
}
@ -99,7 +107,7 @@ func (d *dir) createDirectories() {
}
d.children = append(d.children, newDir)
totalDirectories++
switch rand.Intn(4) {
switch randSource.Intn(4) {
case 0:
if d.depth < maxDepth {
newDir.createDirectories()
@ -132,8 +140,8 @@ func writeFile(dir, name string) {
if err != nil {
log.Fatalf("Failed to open file %q: %v", path, err)
}
size := rand.Int63n(int64(maxFileSize-minFileSize)) + int64(minFileSize)
_, err = io.CopyN(fd, cryptrand.Reader, size)
size := randSource.Int63n(int64(maxFileSize-minFileSize)) + int64(minFileSize)
_, err = io.CopyN(fd, randSource, size)
if err != nil {
log.Fatalf("Failed to write %v bytes to file %q: %v", size, path, err)
}

View file

@ -10,10 +10,11 @@ import (
"github.com/pkg/errors"
)
// String create a random string for test purposes.
// StringFn create a random string for test purposes using the random
// number generator function passed in.
//
// Do not use these for passwords.
func String(n int) string {
func StringFn(n int, randIntn func(n int) int) string {
const (
vowel = "aeiou"
consonant = "bcdfghjklmnpqrstvwxyz"
@ -25,11 +26,18 @@ func String(n int) string {
for i := range out {
source := pattern[p]
p = (p + 1) % len(pattern)
out[i] = source[mathrand.Intn(len(source))]
out[i] = source[randIntn(len(source))]
}
return string(out)
}
// String create a random string for test purposes.
//
// Do not use these for passwords.
func String(n int) string {
return StringFn(n, mathrand.Intn)
}
// Password creates a crypto strong password which is just about
// memorable. The password is composed of printable ASCII characters
// from the base64 alphabet.