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