config.go 5.0 KB

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