github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/fstest/test_all/config.go (about) 1 // Config handling 2 3 package main 4 5 import ( 6 "io/ioutil" 7 "log" 8 "path" 9 10 "github.com/pkg/errors" 11 "github.com/rclone/rclone/fs" 12 yaml "gopkg.in/yaml.v2" 13 ) 14 15 // Test describes an integration test to run with `go test` 16 type Test struct { 17 Path string // path to the source directory 18 FastList bool // if it is possible to add -fast-list to tests 19 Short bool // if it is possible to run the test with -short 20 AddBackend bool // set if Path needs the current backend appending 21 NoRetries bool // set if no retries should be performed 22 NoBinary bool // set to not build a binary in advance 23 LocalOnly bool // if set only run with the local backend 24 } 25 26 // Backend describes a backend test 27 // 28 // FIXME make bucket based remotes set sub-dir automatically??? 29 type Backend struct { 30 Backend string // name of the backend directory 31 Remote string // name of the test remote 32 FastList bool // set to test with -fast-list 33 Short bool // set to test with -short 34 OneOnly bool // set to run only one backend test at once 35 MaxFile string // file size limit 36 CleanUp bool // when running clean, run cleanup first 37 Ignore []string // test names to ignore the failure of 38 Tests []string // paths of tests to run, blank for all 39 } 40 41 // includeTest returns true if this backend should be included in this 42 // test 43 func (b *Backend) includeTest(t *Test) bool { 44 if len(b.Tests) == 0 { 45 return true 46 } 47 for _, testPath := range b.Tests { 48 if testPath == t.Path { 49 return true 50 } 51 } 52 return false 53 } 54 55 // MakeRuns creates Run objects the Backend and Test 56 // 57 // There can be several created, one for each combination of optionl 58 // flags (eg FastList) 59 func (b *Backend) MakeRuns(t *Test) (runs []*Run) { 60 if !b.includeTest(t) { 61 return runs 62 } 63 maxSize := fs.SizeSuffix(0) 64 if b.MaxFile != "" { 65 if err := maxSize.Set(b.MaxFile); err != nil { 66 log.Printf("Invalid maxfile value %q: %v", b.MaxFile, err) 67 } 68 } 69 fastlists := []bool{false} 70 if b.FastList && t.FastList { 71 fastlists = append(fastlists, true) 72 } 73 ignore := make(map[string]struct{}, len(b.Ignore)) 74 for _, item := range b.Ignore { 75 ignore[item] = struct{}{} 76 } 77 for _, fastlist := range fastlists { 78 if t.LocalOnly && b.Backend != "local" { 79 continue 80 } 81 run := &Run{ 82 Remote: b.Remote, 83 Backend: b.Backend, 84 Path: t.Path, 85 FastList: fastlist, 86 Short: (b.Short && t.Short), 87 NoRetries: t.NoRetries, 88 OneOnly: b.OneOnly, 89 NoBinary: t.NoBinary, 90 SizeLimit: int64(maxSize), 91 Ignore: ignore, 92 } 93 if t.AddBackend { 94 run.Path = path.Join(run.Path, b.Backend) 95 } 96 runs = append(runs, run) 97 } 98 return runs 99 } 100 101 // Config describes the config for this program 102 type Config struct { 103 Tests []Test 104 Backends []Backend 105 } 106 107 // NewConfig reads the config file 108 func NewConfig(configFile string) (*Config, error) { 109 d, err := ioutil.ReadFile(configFile) 110 if err != nil { 111 return nil, errors.Wrap(err, "failed to read config file") 112 } 113 config := &Config{} 114 err = yaml.Unmarshal(d, &config) 115 if err != nil { 116 return nil, errors.Wrap(err, "failed to parse config file") 117 } 118 // d, err = yaml.Marshal(&config) 119 // if err != nil { 120 // log.Fatalf("error: %v", err) 121 // } 122 // fmt.Printf("--- m dump:\n%s\n\n", string(d)) 123 return config, nil 124 } 125 126 // MakeRuns makes Run objects for each combination of Backend and Test 127 // in the config 128 func (c *Config) MakeRuns() (runs Runs) { 129 for _, backend := range c.Backends { 130 for _, test := range c.Tests { 131 runs = append(runs, backend.MakeRuns(&test)...) 132 } 133 } 134 return runs 135 } 136 137 // Filter the Backends with the remotes passed in. 138 // 139 // If no backend is found with a remote is found then synthesize one 140 func (c *Config) filterBackendsByRemotes(remotes []string) { 141 var newBackends []Backend 142 for _, name := range remotes { 143 found := false 144 for i := range c.Backends { 145 if c.Backends[i].Remote == name { 146 newBackends = append(newBackends, c.Backends[i]) 147 found = true 148 } 149 } 150 if !found { 151 log.Printf("Remote %q not found - inserting with default flags", name) 152 // Lookup which backend 153 fsInfo, _, _, _, err := fs.ConfigFs(name) 154 if err != nil { 155 log.Fatalf("couldn't find remote %q: %v", name, err) 156 } 157 newBackends = append(newBackends, Backend{Backend: fsInfo.FileName(), Remote: name}) 158 } 159 } 160 c.Backends = newBackends 161 } 162 163 // Filter the Backends with the backendNames passed in 164 func (c *Config) filterBackendsByBackends(backendNames []string) { 165 var newBackends []Backend 166 for _, name := range backendNames { 167 for i := range c.Backends { 168 if c.Backends[i].Backend == name { 169 newBackends = append(newBackends, c.Backends[i]) 170 } 171 } 172 } 173 c.Backends = newBackends 174 } 175 176 // Filter the incoming tests into the backends selected 177 func (c *Config) filterTests(paths []string) { 178 var newTests []Test 179 for _, path := range paths { 180 for i := range c.Tests { 181 if c.Tests[i].Path == path { 182 newTests = append(newTests, c.Tests[i]) 183 } 184 } 185 } 186 c.Tests = newTests 187 }