github.com/xhghs/rclone@v1.51.1-0.20200430155106-e186a28cced8/fstest/test_all/test_all.go (about) 1 // +build go1.11 2 3 // Run tests for all the remotes. Run this with package names which 4 // need integration testing. 5 // 6 // See the `test` target in the Makefile. 7 // 8 package main 9 10 /* FIXME 11 12 Make TesTrun have a []string of flags to try - that then makes it generic 13 14 */ 15 16 import ( 17 "flag" 18 "log" 19 "math/rand" 20 "os" 21 "path" 22 "regexp" 23 "strings" 24 "time" 25 26 _ "github.com/rclone/rclone/backend/all" // import all fs 27 "github.com/rclone/rclone/lib/pacer" 28 ) 29 30 var ( 31 // Flags 32 maxTries = flag.Int("maxtries", 5, "Number of times to try each test") 33 maxN = flag.Int("n", 20, "Maximum number of tests to run at once") 34 testRemotes = flag.String("remotes", "", "Comma separated list of remotes to test, eg 'TestSwift:,TestS3'") 35 testBackends = flag.String("backends", "", "Comma separated list of backends to test, eg 's3,googlecloudstorage") 36 testTests = flag.String("tests", "", "Comma separated list of tests to test, eg 'fs/sync,fs/operations'") 37 clean = flag.Bool("clean", false, "Instead of testing, clean all left over test directories") 38 runOnly = flag.String("run", "", "Run only those tests matching the regexp supplied") 39 timeout = flag.Duration("timeout", 30*time.Minute, "Maximum time to run each test for before giving up") 40 configFile = flag.String("config", "fstest/test_all/config.yaml", "Path to config file") 41 outputDir = flag.String("output", path.Join(os.TempDir(), "rclone-integration-tests"), "Place to store results") 42 emailReport = flag.String("email", "", "Set to email the report to the address supplied") 43 dryRun = flag.Bool("dry-run", false, "Print commands which would be executed only") 44 urlBase = flag.String("url-base", "https://pub.rclone.org/integration-tests/", "Base for the online version") 45 uploadPath = flag.String("upload", "", "Set this to an rclone path to upload the results here") 46 verbose = flag.Bool("verbose", false, "Set to enable verbose logging in the tests") 47 ) 48 49 // if matches then is definitely OK in the shell 50 var shellOK = regexp.MustCompile("^[A-Za-z0-9./_:-]+$") 51 52 // converts a argv style input into a shell command 53 func toShell(args []string) (result string) { 54 for _, arg := range args { 55 if result != "" { 56 result += " " 57 } 58 if shellOK.MatchString(arg) { 59 result += arg 60 } else { 61 result += "'" + arg + "'" 62 } 63 } 64 return result 65 } 66 67 func main() { 68 flag.Parse() 69 conf, err := NewConfig(*configFile) 70 if err != nil { 71 log.Println("test_all should be run from the root of the rclone source code") 72 log.Fatal(err) 73 } 74 75 // Seed the random number generator 76 rand.Seed(time.Now().UTC().UnixNano()) 77 78 // Filter selection 79 if *testRemotes != "" { 80 conf.filterBackendsByRemotes(strings.Split(*testRemotes, ",")) 81 } 82 if *testBackends != "" { 83 conf.filterBackendsByBackends(strings.Split(*testBackends, ",")) 84 } 85 if *testTests != "" { 86 conf.filterTests(strings.Split(*testTests, ",")) 87 } 88 89 // Just clean the directories if required 90 if *clean { 91 err := cleanRemotes(conf.Remotes()) 92 if err != nil { 93 log.Fatalf("Failed to clean: %v", err) 94 } 95 return 96 } 97 98 var names []string 99 for _, remote := range conf.Backends { 100 names = append(names, remote.Remote) 101 } 102 log.Printf("Testing remotes: %s", strings.Join(names, ", ")) 103 104 // Runs we will do for this test in random order 105 runs := conf.MakeRuns() 106 rand.Shuffle(len(runs), runs.Swap) 107 108 // Create Report 109 report := NewReport() 110 111 // Make the test binaries, one per Path found in the tests 112 done := map[string]struct{}{} 113 for _, run := range runs { 114 if _, found := done[run.Path]; !found { 115 done[run.Path] = struct{}{} 116 if !run.NoBinary { 117 run.MakeTestBinary() 118 defer run.RemoveTestBinary() 119 } 120 } 121 } 122 123 // workaround for cache backend as we run simultaneous tests 124 _ = os.Setenv("RCLONE_CACHE_DB_WAIT_TIME", "30m") 125 126 // start the tests 127 results := make(chan *Run, len(runs)) 128 awaiting := 0 129 tokens := pacer.NewTokenDispenser(*maxN) 130 for _, run := range runs { 131 tokens.Get() 132 go func(run *Run) { 133 defer tokens.Put() 134 run.Run(report.LogDir, results) 135 }(run) 136 awaiting++ 137 } 138 139 // Wait for the tests to finish 140 for ; awaiting > 0; awaiting-- { 141 t := <-results 142 report.RecordResult(t) 143 } 144 145 // Log and exit 146 report.End() 147 report.LogSummary() 148 report.LogJSON() 149 report.LogHTML() 150 report.EmailHTML() 151 report.Upload() 152 if !report.AllPassed() { 153 os.Exit(1) 154 } 155 }