github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/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/ncw/rclone/fs" 13 "github.com/pkg/errors" 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 SubDir bool // if it is possible to add -sub-dir to tests 21 FastList bool // if it is possible to add -fast-list to tests 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 SubDir bool // set to test with -sub-dir 35 FastList bool // set to test with -fast-list 36 OneOnly bool // set to run only one backend test at once 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 SubDir 58 // and FastList 59 func (b *Backend) MakeRuns(t *Test) (runs []*Run) { 60 if !b.includeTest(t) { 61 return runs 62 } 63 subdirs := []bool{false} 64 if b.SubDir && t.SubDir { 65 subdirs = append(subdirs, true) 66 } 67 fastlists := []bool{false} 68 if b.FastList && t.FastList { 69 fastlists = append(fastlists, true) 70 } 71 ignore := make(map[string]struct{}, len(b.Ignore)) 72 for _, item := range b.Ignore { 73 ignore[item] = struct{}{} 74 } 75 for _, subdir := range subdirs { 76 for _, fastlist := range fastlists { 77 if t.LocalOnly && b.Backend != "local" { 78 continue 79 } 80 run := &Run{ 81 Remote: b.Remote, 82 Backend: b.Backend, 83 Path: t.Path, 84 SubDir: subdir, 85 FastList: fastlist, 86 NoRetries: t.NoRetries, 87 OneOnly: b.OneOnly, 88 NoBinary: t.NoBinary, 89 Ignore: ignore, 90 } 91 if t.AddBackend { 92 run.Path = path.Join(run.Path, b.Backend) 93 } 94 runs = append(runs, run) 95 } 96 } 97 return runs 98 } 99 100 // Config describes the config for this program 101 type Config struct { 102 Tests []Test 103 Backends []Backend 104 } 105 106 // NewConfig reads the config file 107 func NewConfig(configFile string) (*Config, error) { 108 d, err := ioutil.ReadFile(configFile) 109 if err != nil { 110 return nil, errors.Wrap(err, "failed to read config file") 111 } 112 config := &Config{} 113 err = yaml.Unmarshal(d, &config) 114 if err != nil { 115 return nil, errors.Wrap(err, "failed to parse config file") 116 } 117 // d, err = yaml.Marshal(&config) 118 // if err != nil { 119 // log.Fatalf("error: %v", err) 120 // } 121 // fmt.Printf("--- m dump:\n%s\n\n", string(d)) 122 return config, nil 123 } 124 125 // MakeRuns makes Run objects for each combination of Backend and Test 126 // in the config 127 func (c *Config) MakeRuns() (runs Runs) { 128 for _, backend := range c.Backends { 129 for _, test := range c.Tests { 130 runs = append(runs, backend.MakeRuns(&test)...) 131 } 132 } 133 return runs 134 } 135 136 // Filter the Backends with the remotes passed in. 137 // 138 // If no backend is found with a remote is found then synthesize one 139 func (c *Config) filterBackendsByRemotes(remotes []string) { 140 var newBackends []Backend 141 for _, name := range remotes { 142 found := false 143 for i := range c.Backends { 144 if c.Backends[i].Remote == name { 145 newBackends = append(newBackends, c.Backends[i]) 146 found = true 147 } 148 } 149 if !found { 150 log.Printf("Remote %q not found - inserting with default flags", name) 151 // Lookup which backend 152 fsInfo, _, _, _, err := fs.ConfigFs(name) 153 if err != nil { 154 log.Fatalf("couldn't find remote %q: %v", name, err) 155 } 156 newBackends = append(newBackends, Backend{Backend: fsInfo.FileName(), Remote: name}) 157 } 158 } 159 c.Backends = newBackends 160 } 161 162 // Filter the Backends with the backendNames passed in 163 func (c *Config) filterBackendsByBackends(backendNames []string) { 164 var newBackends []Backend 165 for _, name := range backendNames { 166 for i := range c.Backends { 167 if c.Backends[i].Backend == name { 168 newBackends = append(newBackends, c.Backends[i]) 169 } 170 } 171 } 172 c.Backends = newBackends 173 } 174 175 // Filter the incoming tests into the backends selected 176 func (c *Config) filterTests(paths []string) { 177 var newTests []Test 178 for _, path := range paths { 179 for i := range c.Tests { 180 if c.Tests[i].Path == path { 181 newTests = append(newTests, c.Tests[i]) 182 } 183 } 184 } 185 c.Tests = newTests 186 } 187 188 // Remotes returns the unique remotes 189 func (c *Config) Remotes() (remotes []string) { 190 found := map[string]struct{}{} 191 for _, backend := range c.Backends { 192 if _, ok := found[backend.Remote]; ok { 193 continue 194 } 195 remotes = append(remotes, backend.Remote) 196 found[backend.Remote] = struct{}{} 197 } 198 return remotes 199 }