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  }