package planr import ( "log" "os" "path" ) type Runner struct { adapters map[string] Adapter dirs DirConfig } func (r Runner) adapterCfgs() []AdapterConfig { cgs := make([]AdapterConfig, len(r.adapters)) for _, adapter := range r.adapters { cgs = append(cgs, adapter.Config()) } return cgs } // TODO: Move into configuration parsing func (r Runner) checkConfig(tcs []TestCase) { for _, tc := range tcs { tc.Config.ensureSatisfied(tc.Path) } } func (r Runner) setupEnv(adapter Adapter) { nm := adapter.Config().Name wd := path.Join(r.dirs.Build(), nm) if !directoryExists(wd) { if err := os.Mkdir(wd, 0755); err != nil { log.Fatalf("Could not create adapter config %s %v\n", wd, err) } } safeCd(wd) } type adapterTestSet struct { adapter Adapter tcs []TestCase } func (r Runner) groupByAdapter(tcs []TestCase) []adapterTestSet { r.checkConfig(tcs) pairs := make(map[string] adapterTestSet, 0) for _, tc := range tcs { // TODO: Make non-pointer adptNm := *tc.Config.Adapter // See if adapter if contained in map adapter, contained := r.adapters[adptNm] if !contained { log.Fatalf("Cannot find adapter \"%s\" for testcase \"%s\"", adptNm, tc.Cname) } pair, exists := pairs[adptNm] if !exists { pair.adapter = adapter } pair.tcs = append(pair.tcs, tc) pairs[adptNm] = pair } // Convert to slice set := make([]adapterTestSet, 0) for _, pair := range pairs { set = append(set, pair) } return set } func (r Runner) CollectCases() []TestCase { return collectUnits(r.dirs.Rubric(), r.adapterCfgs()) } func (r Runner) Build(tcs []TestCase) { if !directoryExists(r.dirs.Build()) { r.dirs.MkBuild() } testSets := r.groupByAdapter(tcs) for _, pair := range testSets { adapter := pair.adapter cases := pair.tcs r.setupEnv(adapter) adapter.Build(cases) } safeCd(r.dirs.Config()) } func (r Runner) Evaluate(tcs []TestCase) []TestCase { testSets := r.groupByAdapter(tcs) results := make([]TestCase, 0) for _, pair := range testSets { adapter := pair.adapter cases := pair.tcs r.setupEnv(adapter) resultSet := adapter.Evaluate(cases) results = append(results, resultSet...) } safeCd(r.dirs.Config()) return results } func (r Runner) Clean() { r.dirs.CleanBuild() } func (r Runner) BuildDir() string { return r.dirs.Build(); } func (r Runner) ConfigDir() string { return r.dirs.Config() } func (r Runner) SrcDir() string { return r.dirs.Src() } func NewRunner(adapters map[string]Adapter, dirs DirConfig) Runner { r := Runner{adapters, dirs} for _, adapter := range r.adapters { adapter.Init(dirs) } return r }