From 5065c422b4885cc95da09b368538627e59fcfe29 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 6 Aug 2019 12:44:08 +0100 Subject: [PATCH] lib/random: unify random string generation into random.String This was factored from fstest as we were including the testing enviroment into the main binary because of it. This was causing opening the browser to fail because of 8243ff8bc8. --- backend/cache/cache_internal_test.go | 5 +++-- backend/googlephotos/googlephotos_test.go | 3 ++- cmd/cmd.go | 2 ++ cmd/info/info.go | 4 ++-- fs/operations/multithread_test.go | 3 ++- fs/operations/operations.go | 15 ++------------- fs/rc/rcserver/rcserver.go | 2 ++ fstest/fstest.go | 23 +++-------------------- fstest/fstests/fstests.go | 13 +++++++------ lib/random/random.go | 22 ++++++++++++++++++++++ lib/random/random_test.go | 13 +++++++++++++ vfs/test_vfs/test_vfs.go | 23 +++-------------------- 12 files changed, 63 insertions(+), 65 deletions(-) create mode 100644 lib/random/random.go create mode 100644 lib/random/random_test.go diff --git a/backend/cache/cache_internal_test.go b/backend/cache/cache_internal_test.go index fc455a24e..d183f2a23 100644 --- a/backend/cache/cache_internal_test.go +++ b/backend/cache/cache_internal_test.go @@ -33,6 +33,7 @@ import ( "github.com/rclone/rclone/fs/object" "github.com/rclone/rclone/fs/rc" "github.com/rclone/rclone/fstest" + "github.com/rclone/rclone/lib/random" "github.com/rclone/rclone/vfs" "github.com/rclone/rclone/vfs/vfsflags" "github.com/stretchr/testify/assert" @@ -355,8 +356,8 @@ func TestInternalCachedUpdatedContentMatches(t *testing.T) { testData2, err = base64.StdEncoding.DecodeString(cryptedText2Base64) require.NoError(t, err) } else { - testData1 = []byte(fstest.RandomString(100)) - testData2 = []byte(fstest.RandomString(200)) + testData1 = []byte(random.String(100)) + testData2 = []byte(random.String(200)) } // write the object diff --git a/backend/googlephotos/googlephotos_test.go b/backend/googlephotos/googlephotos_test.go index 22e1e1878..7fe46781f 100644 --- a/backend/googlephotos/googlephotos_test.go +++ b/backend/googlephotos/googlephotos_test.go @@ -13,6 +13,7 @@ import ( "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fstest" + "github.com/rclone/rclone/lib/random" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -55,7 +56,7 @@ func TestIntegration(t *testing.T) { require.NoError(t, err) t.Run("CreateAlbum", func(t *testing.T) { - albumName := "album/rclone-test-" + fstest.RandomString(24) + albumName := "album/rclone-test-" + random.String(24) err = f.Mkdir(ctx, albumName) require.NoError(t, err) remote := albumName + "/" + fileNameAlbum diff --git a/cmd/cmd.go b/cmd/cmd.go index 815fe6a93..c5d2d388b 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -9,6 +9,7 @@ package cmd import ( "fmt" "log" + "math/rand" "os" "os/exec" "path" @@ -492,6 +493,7 @@ func AddBackendFlags() { // Main runs rclone interpreting flags and commands out of os.Args func Main() { + rand.Seed(time.Now().Unix()) setupRootCommand(Root) AddBackendFlags() if err := Root.Execute(); err != nil { diff --git a/cmd/info/info.go b/cmd/info/info.go index 70b908007..51d1fbfee 100644 --- a/cmd/info/info.go +++ b/cmd/info/info.go @@ -18,7 +18,7 @@ import ( "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/object" - "github.com/rclone/rclone/fstest" + "github.com/rclone/rclone/lib/random" "github.com/spf13/cobra" ) @@ -118,7 +118,7 @@ func (r *results) Print() { // writeFile writes a file with some random contents func (r *results) writeFile(path string) (fs.Object, error) { - contents := fstest.RandomString(50) + contents := random.String(50) src := object.NewStaticObjectInfo(path, time.Now(), int64(len(contents)), true, nil, r.f) return r.f.Put(r.ctx, bytes.NewBufferString(contents), src) } diff --git a/fs/operations/multithread_test.go b/fs/operations/multithread_test.go index 0c263204f..727b1b7f5 100644 --- a/fs/operations/multithread_test.go +++ b/fs/operations/multithread_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/rclone/rclone/fs/accounting" + "github.com/rclone/rclone/lib/random" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fstest" @@ -52,7 +53,7 @@ func TestMultithreadCopy(t *testing.T) { } { t.Run(fmt.Sprintf("%+v", test), func(t *testing.T) { var err error - contents := fstest.RandomString(test.size) + contents := random.String(test.size) t1 := fstest.Time("2001-02-03T04:05:06.499999999Z") file1 := r.WriteObject(context.Background(), "file1", contents, t1) fstest.CheckItems(t, r.Fremote, file1) diff --git a/fs/operations/operations.go b/fs/operations/operations.go index eae809b2f..f5d46ba8e 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -8,7 +8,6 @@ import ( "fmt" "io" "io/ioutil" - "math/rand" "path" "path/filepath" "sort" @@ -28,6 +27,7 @@ import ( "github.com/rclone/rclone/fs/march" "github.com/rclone/rclone/fs/object" "github.com/rclone/rclone/fs/walk" + "github.com/rclone/rclone/lib/random" "github.com/rclone/rclone/lib/readers" "golang.org/x/sync/errgroup" ) @@ -1666,7 +1666,7 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str // to avoid issues with certain remotes and avoid file deletion. if !cp && fdst.Name() == fsrc.Name() && fdst.Features().CaseInsensitive && dstFileName != srcFileName && strings.ToLower(dstFilePath) == strings.ToLower(srcFilePath) { // Create random name to temporarily move file to - tmpObjName := dstFileName + "-rclone-move-" + random(8) + tmpObjName := dstFileName + "-rclone-move-" + random.String(8) _, err := fdst.NewObject(ctx, tmpObjName) if err != fs.ErrorObjectNotFound { if err == nil { @@ -1730,17 +1730,6 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str return err } -// random generates a pseudorandom alphanumeric string -func random(length int) string { - randomOutput := make([]byte, length) - possibleCharacters := "123567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - rand.Seed(time.Now().Unix()) - for i := range randomOutput { - randomOutput[i] = possibleCharacters[rand.Intn(len(possibleCharacters))] - } - return string(randomOutput) -} - // MoveFile moves a single file possibly to a new name func MoveFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName string, srcFileName string) (err error) { return moveOrCopyFile(ctx, fdst, fsrc, dstFileName, srcFileName, false) diff --git a/fs/rc/rcserver/rcserver.go b/fs/rc/rcserver/rcserver.go index 53cec2088..65fc9bc82 100644 --- a/fs/rc/rcserver/rcserver.go +++ b/fs/rc/rcserver/rcserver.go @@ -95,6 +95,8 @@ func (s *Server) Serve() error { // Don't open browser if serving in testing environment. if flag.Lookup("test.v") == nil { _ = open.Start(openURL.String()) + } else { + fs.Errorf(nil, "Not opening browser in testing environment") } } return nil diff --git a/fstest/fstest.go b/fstest/fstest.go index 62fa9755b..c2b2b2672 100644 --- a/fstest/fstest.go +++ b/fstest/fstest.go @@ -27,6 +27,7 @@ import ( "github.com/rclone/rclone/fs/config" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/walk" + "github.com/rclone/rclone/lib/random" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/text/unicode/norm" @@ -357,24 +358,6 @@ func Time(timeString string) time.Time { return t } -// RandomString create a random string for test purposes -func RandomString(n int) string { - const ( - vowel = "aeiou" - consonant = "bcdfghjklmnpqrstvwxyz" - digit = "0123456789" - ) - pattern := []string{consonant, vowel, consonant, vowel, consonant, vowel, consonant, digit} - out := make([]byte, n) - p := 0 - for i := range out { - source := pattern[p] - p = (p + 1) % len(pattern) - out[i] = source[rand.Intn(len(source))] - } - return string(out) -} - // LocalRemote creates a temporary directory name for local remotes func LocalRemote() (path string, err error) { path, err = ioutil.TempDir("", "rclone") @@ -403,7 +386,7 @@ func RandomRemoteName(remoteName string) (string, string, error) { if !strings.HasSuffix(remoteName, ":") { remoteName += "/" } - leafName = "rclone-test-" + RandomString(24) + leafName = "rclone-test-" + random.String(24) if !MatchTestRemote.MatchString(leafName) { log.Fatalf("%q didn't match the test remote name regexp", leafName) } @@ -432,7 +415,7 @@ func RandomRemote(remoteName string, subdir bool) (fs.Fs, string, func(), error) if err != nil { return nil, "", nil, err } - remoteName += "/rclone-test-subdir-" + RandomString(8) + remoteName += "/rclone-test-subdir-" + random.String(8) } remote, err := fs.NewFs(remoteName) diff --git a/fstest/fstests/fstests.go b/fstest/fstests/fstests.go index e34f712e4..8500815cf 100644 --- a/fstest/fstests/fstests.go +++ b/fstest/fstests/fstests.go @@ -31,6 +31,7 @@ import ( "github.com/rclone/rclone/fs/operations" "github.com/rclone/rclone/fs/walk" "github.com/rclone/rclone/fstest" + "github.com/rclone/rclone/lib/random" "github.com/rclone/rclone/lib/readers" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -157,7 +158,7 @@ func testPut(t *testing.T, f fs.Fs, file *fstest.Item) (string, fs.Object) { contents string ) retry(t, "Put", func() error { - contents = fstest.RandomString(100) + contents = random.String(100) buf := bytes.NewBufferString(contents) uploadHash = hash.NewMultiHasher() in := io.TeeReader(buf, uploadHash) @@ -557,7 +558,7 @@ func Run(t *testing.T, opt *Opt) { const N = 5 * 1024 // Read N bytes then produce an error - contents := fstest.RandomString(N) + contents := random.String(N) buf := bytes.NewBufferString(contents) er := &errorReader{errors.New("potato")} in := io.MultiReader(buf, er) @@ -1322,7 +1323,7 @@ func Run(t *testing.T, opt *Opt) { // TestObjectUpdate tests that Update works t.Run("ObjectUpdate", func(t *testing.T) { skipIfNotOk(t) - contents := fstest.RandomString(200) + contents := random.String(200) buf := bytes.NewBufferString(contents) hash := hash.NewMultiHasher() in := io.TeeReader(buf, hash) @@ -1507,7 +1508,7 @@ func Run(t *testing.T, opt *Opt) { contentSize = 100 ) retry(t, "PutStream", func() error { - contents := fstest.RandomString(contentSize) + contents := random.String(contentSize) buf := bytes.NewBufferString(contents) uploadHash = hash.NewMultiHasher() in := io.TeeReader(buf, uploadHash) @@ -1564,7 +1565,7 @@ func Run(t *testing.T, opt *Opt) { assert.Nil(t, recover(), "Fs.Put() should not panic when src.Size() == -1") }() - contents := fstest.RandomString(100) + contents := random.String(100) in := bytes.NewBufferString(contents) obji := object.NewStaticObjectInfo("unknown-size-put.txt", fstest.Time("2002-02-03T04:05:06.499999999Z"), -1, true, nil, nil) @@ -1587,7 +1588,7 @@ func Run(t *testing.T, opt *Opt) { assert.Nil(t, recover(), "Object.Update() should not panic when src.Size() == -1") }() - newContents := fstest.RandomString(200) + newContents := random.String(200) in := bytes.NewBufferString(newContents) obj := findObject(t, remote, unknownSizeUpdateFile.Path) diff --git a/lib/random/random.go b/lib/random/random.go new file mode 100644 index 000000000..fef49bbe2 --- /dev/null +++ b/lib/random/random.go @@ -0,0 +1,22 @@ +// Package random holds a few functions for working with random numbers +package random + +import "math/rand" + +// String create a random string for test purposes +func String(n int) string { + const ( + vowel = "aeiou" + consonant = "bcdfghjklmnpqrstvwxyz" + digit = "0123456789" + ) + pattern := []string{consonant, vowel, consonant, vowel, consonant, vowel, consonant, digit} + out := make([]byte, n) + p := 0 + for i := range out { + source := pattern[p] + p = (p + 1) % len(pattern) + out[i] = source[rand.Intn(len(source))] + } + return string(out) +} diff --git a/lib/random/random_test.go b/lib/random/random_test.go new file mode 100644 index 000000000..f32b991ab --- /dev/null +++ b/lib/random/random_test.go @@ -0,0 +1,13 @@ +package random + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestString(t *testing.T) { + for i := 0; i < 100; i++ { + assert.Equal(t, i, len(String(i))) + } +} diff --git a/vfs/test_vfs/test_vfs.go b/vfs/test_vfs/test_vfs.go index 8474b7620..9d6f3168e 100644 --- a/vfs/test_vfs/test_vfs.go +++ b/vfs/test_vfs/test_vfs.go @@ -18,6 +18,7 @@ import ( "time" "github.com/rclone/rclone/lib/file" + "github.com/rclone/rclone/lib/random" ) var ( @@ -35,24 +36,6 @@ func init() { } -// RandomString create a random string for test purposes -func RandomString(n int) string { - const ( - vowel = "aeiou" - consonant = "bcdfghjklmnpqrstvwxyz" - digit = "0123456789" - ) - pattern := []string{consonant, vowel, consonant, vowel, consonant, vowel, consonant, digit} - out := make([]byte, n) - p := 0 - for i := range out { - source := pattern[p] - p = (p + 1) % len(pattern) - out[i] = source[rand.Intn(len(source))] - } - return string(out) -} - // Test contains stats about the running test which work for files or // directories type Test struct { @@ -71,7 +54,7 @@ type Test struct { func NewTest(Dir string) *Test { t := &Test{ dir: Dir, - name: RandomString(*nameLength), + name: random.String(*nameLength), isDir: rand.Intn(2) == 0, number: atomic.AddInt32(&testNumber, 1), timer: time.NewTimer(*timeout), @@ -168,7 +151,7 @@ func (t *Test) rename() { return } t.logf("rename") - NewName := RandomString(*nameLength) + NewName := random.String(*nameLength) newPath := path.Join(t.dir, NewName) err := os.Rename(t.path(), newPath) if err != nil {