Browse Source

Merge pull request #2494 from xiang90/ft

tools/functional-tester: add http status reporter
Xiang Li 10 years ago
parent
commit
d537ef3de9

+ 19 - 0
tools/functional-tester/etcd-tester/http.go

@@ -0,0 +1,19 @@
+package main
+
+import (
+	"encoding/json"
+	"net/http"
+)
+
+type statusHandler struct {
+	status *Status
+}
+
+func (sh statusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	w.Header().Set("Content-Type", "application/json")
+	en := json.NewEncoder(w)
+	err := en.Encode(sh.status.get())
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+	}
+}

+ 6 - 0
tools/functional-tester/etcd-tester/main.go

@@ -17,6 +17,7 @@ package main
 import (
 	"flag"
 	"log"
+	"net/http"
 	"strings"
 )
 
@@ -43,5 +44,10 @@ func main() {
 		cluster: c,
 		limit:   *limit,
 	}
+
+	sh := statusHandler{status: &t.status}
+	http.Handle("/status", sh)
+	go func() { log.Fatal(http.ListenAndServe(":9028", nil)) }()
+
 	t.runLoop()
 }

+ 46 - 1
tools/functional-tester/etcd-tester/tester.go

@@ -14,17 +14,32 @@
 
 package main
 
-import "log"
+import (
+	"log"
+	"sync"
+	"time"
+)
 
 type tester struct {
 	failures []failure
 	cluster  *cluster
 	limit    int
+
+	status Status
 }
 
 func (tt *tester) runLoop() {
+	tt.status.Since = time.Now()
+	tt.status.RoundLimit = tt.limit
+	for _, f := range tt.failures {
+		tt.status.Failures = append(tt.status.Failures, f.Desc())
+	}
 	for i := 0; i < tt.limit; i++ {
+		tt.status.setRound(i)
+
 		for j, f := range tt.failures {
+			tt.status.setCase(j)
+
 			if err := tt.cluster.WaitHealth(); err != nil {
 				log.Printf("etcd-tester: [round#%d case#%d] wait full health error: %v", i, j, err)
 				if err := tt.cleanup(i, j); err != nil {
@@ -64,3 +79,33 @@ func (tt *tester) cleanup(i, j int) error {
 	}
 	return tt.cluster.Bootstrap()
 }
+
+type Status struct {
+	Since      time.Time
+	Failures   []string
+	RoundLimit int
+
+	mu sync.Mutex // guards Round and Case
+	// TODO: add agent status
+	Round int
+	Case  int
+}
+
+// get gets a copy of status
+func (s *Status) get() Status {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	return *s
+}
+
+func (s *Status) setRound(r int) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	s.Round = r
+}
+
+func (s *Status) setCase(c int) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	s.Case = c
+}