From 203a3cfdd1d8827b5be5b64d8428385ea0409dc8 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Fri, 23 Oct 2015 13:02:00 +0000 Subject: [PATCH] Remove test runner; it now live in build-tools.git --- Makefile | 10 +- test/run_all.sh | 2 +- testing/runner/runner.go | 273 --------------------------------------- tools | 2 +- 4 files changed, 8 insertions(+), 279 deletions(-) delete mode 100644 testing/runner/runner.go diff --git a/Makefile b/Makefile index e1ff2156..2335594b 100644 --- a/Makefile +++ b/Makefile @@ -15,9 +15,9 @@ SIGPROXY_EXE=prog/sigproxy/sigproxy WEAVEWAIT_EXE=prog/weavewait/weavewait NETCHECK_EXE=prog/netcheck/netcheck DOCKERTLSARGS_EXE=prog/docker_tls_args/docker_tls_args -RUNNER_EXE=testing/runner/runner +RUNNER_EXE=tools/runner/runner -EXES=$(WEAVER_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE) $(RUNNER_EXE) +EXES=$(WEAVER_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE) WEAVER_UPTODATE=.weaver.uptodate WEAVEEXEC_UPTODATE=.weaveexec.uptodate @@ -77,10 +77,9 @@ $(NETCHECK_EXE): prog/netcheck/netcheck.go # the main build stanza due to not importing net package $(SIGPROXY_EXE): prog/sigproxy/main.go $(WEAVEWAIT_EXE): prog/weavewait/main.go net/*.go -$(RUNNER_EXE): testing/runner/runner.go $(DOCKERTLSARGS_EXE): prog/docker_tls_args/*.go -$(WEAVEWAIT_EXE) $(SIGPROXY_EXE) $(RUNNER_EXE) $(DOCKERTLSARGS_EXE): +$(WEAVEWAIT_EXE) $(SIGPROXY_EXE) $(DOCKERTLSARGS_EXE): go get -tags netgo ./$(@D) go build $(BUILD_FLAGS) -o $@ ./$(@D) @@ -114,6 +113,9 @@ lint: tools/.git tools/.git: git submodule update --init +$(RUNNER_EXE): + make -C tools/runner + $(PUBLISH): publish_%: $(IMAGES_UPTODATE) $(SUDO) docker tag -f $(DOCKERHUB_USER)/$* $(DOCKERHUB_USER)/$*:$(WEAVE_VERSION) $(SUDO) docker push $(DOCKERHUB_USER)/$*:$(WEAVE_VERSION) diff --git a/test/run_all.sh b/test/run_all.sh index d73c5b1c..78cc7f74 100755 --- a/test/run_all.sh +++ b/test/run_all.sh @@ -23,4 +23,4 @@ if [ -n "$CIRCLECI" -o -n "$PARALLEL" ]; then RUNNER_ARGS="$RUNNER_ARGS -parallel" fi -HOSTS="$HOSTS" "${DIR}/../testing/runner/runner" $RUNNER_ARGS $TESTS +HOSTS="$HOSTS" "${DIR}/../tools/runner/runner" $RUNNER_ARGS $TESTS diff --git a/testing/runner/runner.go b/testing/runner/runner.go deleted file mode 100644 index fe4f7efe..00000000 --- a/testing/runner/runner.go +++ /dev/null @@ -1,273 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "net/http" - "net/url" - "os" - "os/exec" - "sort" - "strconv" - "strings" - "sync" - "time" - - "github.com/docker/docker/pkg/mflag" - "github.com/mgutz/ansi" -) - -const ( - schedulerHost = "positive-cocoa-90213.appspot.com" - JSON = "application/json" -) - -var ( - start = ansi.ColorCode("black+ub") - fail = ansi.ColorCode("red+b") - succ = ansi.ColorCode("green+b") - reset = ansi.ColorCode("reset") - - useScheduler = false - runParallel = false - verbose = false - - consoleLock = sync.Mutex{} -) - -type test struct { - name string - hosts int -} - -type schedule struct { - Tests []string `json:"tests"` -} - -type result struct { - test - errored bool - hosts []string -} - -type tests []test - -func (ts tests) Len() int { return len(ts) } -func (ts tests) Swap(i, j int) { ts[i], ts[j] = ts[j], ts[i] } -func (ts tests) Less(i, j int) bool { - if ts[i].hosts != ts[j].hosts { - return ts[i].hosts < ts[j].hosts - } - return ts[i].name < ts[j].name -} - -func (ts *tests) pick(availible int) (test, bool) { - // pick the first test that fits in the availible hosts - for i, test := range *ts { - if test.hosts <= availible { - *ts = append((*ts)[:i], (*ts)[i+1:]...) - return test, true - } - } - - return test{}, false -} - -func (t test) run(hosts []string) bool { - consoleLock.Lock() - fmt.Printf("%s>>> Running %s on %s%s\n", start, t.name, hosts, reset) - consoleLock.Unlock() - - var out bytes.Buffer - - cmd := exec.Command(t.name) - cmd.Env = os.Environ() - cmd.Stdout = &out - cmd.Stderr = &out - - // replace HOSTS in env - for i, env := range cmd.Env { - if strings.HasPrefix(env, "HOSTS") { - cmd.Env[i] = fmt.Sprintf("HOSTS=%s", strings.Join(hosts, " ")) - break - } - } - - start := time.Now() - err := cmd.Run() - duration := float64(time.Now().Sub(start)) / float64(time.Second) - - consoleLock.Lock() - if err != nil { - fmt.Printf("%s>>> Test %s finished after %0.1f secs with error: %v%s\n", fail, t.name, duration, err, reset) - } else { - fmt.Printf("%s>>> Test %s finished with success after %0.1f secs%s\n", succ, t.name, duration, reset) - } - if err != nil || verbose { - fmt.Print(out.String()) - fmt.Println() - } - consoleLock.Unlock() - - if err != nil && useScheduler { - updateScheduler(t.name, duration) - } - - return err != nil -} - -func updateScheduler(test string, duration float64) { - req := &http.Request{ - Method: "POST", - Host: schedulerHost, - URL: &url.URL{ - Opaque: fmt.Sprintf("/record/%s/%0.2f", url.QueryEscape(test), duration), - Scheme: "http", - Host: schedulerHost, - }, - Close: true, - } - if resp, err := http.DefaultClient.Do(req); err != nil { - fmt.Printf("Error updating scheduler: %v\n", err) - } else { - resp.Body.Close() - } -} - -func getSchedule(tests []string) ([]string, error) { - var ( - testRun = "integration-" + os.Getenv("CIRCLE_BUILD_NUM") - shardCount = os.Getenv("CIRCLE_NODE_TOTAL") - shardID = os.Getenv("CIRCLE_NODE_INDEX") - requestBody = &bytes.Buffer{} - ) - if err := json.NewEncoder(requestBody).Encode(schedule{tests}); err != nil { - return []string{}, err - } - url := fmt.Sprintf("http://%s/schedule/%s/%s/%s", schedulerHost, testRun, shardCount, shardID) - resp, err := http.Post(url, JSON, requestBody) - if err != nil { - return []string{}, err - } - var sched schedule - if err := json.NewDecoder(resp.Body).Decode(&sched); err != nil { - return []string{}, err - } - return sched.Tests, nil -} - -func getTests(testNames []string) (tests, error) { - var err error - if useScheduler { - testNames, err = getSchedule(testNames) - if err != nil { - return tests{}, err - } - } - tests := tests{} - for _, name := range testNames { - parts := strings.Split(strings.TrimSuffix(name, "_test.sh"), "_") - numHosts, err := strconv.Atoi(parts[len(parts)-1]) - if err != nil { - numHosts = 1 - } - tests = append(tests, test{name, numHosts}) - fmt.Printf("Test %s needs %d hosts\n", name, numHosts) - } - return tests, nil -} - -func summary(tests, failed tests) { - if len(failed) > 0 { - fmt.Printf("%s>>> Ran %d tests, %d failed%s\n", fail, len(tests), len(failed), reset) - for _, test := range failed { - fmt.Printf("%s>>> Fail %s%s\n", fail, test.name, reset) - } - } else { - fmt.Printf("%s>>> Ran %d tests, all succeeded%s\n", succ, len(tests), reset) - } -} - -func parallel(ts tests, hosts []string) bool { - testsCopy := ts - sort.Sort(sort.Reverse(ts)) - resultsChan := make(chan result) - outstanding := 0 - failed := tests{} - for len(ts) > 0 || outstanding > 0 { - // While we have some free hosts, try and schedule - // a test on them - for len(hosts) > 0 { - test, ok := ts.pick(len(hosts)) - if !ok { - break - } - testHosts := hosts[:test.hosts] - hosts = hosts[test.hosts:] - - go func() { - errored := test.run(testHosts) - resultsChan <- result{test, errored, testHosts} - }() - outstanding++ - } - - // Otherwise, wait for the test to finish and return - // the hosts to the pool - result := <-resultsChan - hosts = append(hosts, result.hosts...) - outstanding-- - if result.errored { - failed = append(failed, result.test) - } - } - summary(testsCopy, failed) - return len(failed) > 0 -} - -func sequential(ts tests, hosts []string) bool { - failed := tests{} - for _, test := range ts { - if test.run(hosts) { - failed = append(failed, test) - } - } - summary(ts, failed) - return len(failed) > 0 -} - -func main() { - mflag.BoolVar(&useScheduler, []string{"scheduler"}, false, "Use scheduler to distribute tests across shards") - mflag.BoolVar(&runParallel, []string{"parallel"}, false, "Run tests in parallel on hosts where possible") - mflag.BoolVar(&verbose, []string{"v"}, false, "Print output from all tests (Also enabled via DEBUG=1)") - mflag.Parse() - - if len(os.Getenv("DEBUG")) > 0 { - verbose = true - } - - tests, err := getTests(mflag.Args()) - if err != nil { - fmt.Printf("Error parsing tests: %v\n", err) - os.Exit(1) - } - - hosts := strings.Fields(os.Getenv("HOSTS")) - maxHosts := len(hosts) - if maxHosts == 0 { - fmt.Print("No HOSTS specified.\n") - os.Exit(1) - } - - var errored bool - if runParallel { - errored = parallel(tests, hosts) - } else { - errored = sequential(tests, hosts) - } - - if errored { - os.Exit(1) - } -} diff --git a/tools b/tools index a286ddad..58c9a390 160000 --- a/tools +++ b/tools @@ -1 +1 @@ -Subproject commit a286ddade02b98e429a8f65d52a825405a9efcf3 +Subproject commit 58c9a390c54860547254fa3a66e0acd8916f889c