diff --git a/runtime/http.go b/runtime/http.go index 2af1a7d..8289a9e 100644 --- a/runtime/http.go +++ b/runtime/http.go @@ -72,6 +72,13 @@ func (*httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { lines[i] = fps[i] + "=" + s } w.Write([]byte(strings.Join(lines, "\n") + "\n")) + } else if strings.HasSuffix(key, "/count") { + fp := key[:len(key)-6] + count, err := StatusCount(fp) + if err != nil { + http.Error(w, "failed to GET: "+err.Error(), http.StatusNotFound) + } + w.Write([]byte(count)) } else { status, err := Status(key) if err != nil { diff --git a/runtime/runtime.go b/runtime/runtime.go index b20293b..954beb5 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -114,6 +114,25 @@ func Status(failpath string) (string, error) { return t.desc, nil } +// StatusCount gives the number of sleeps executed on the current terms +func StatusCount(failpath string) (string, error) { + failpointsMu.RLock() + fp := failpoints[failpath] + failpointsMu.RUnlock() + if fp == nil { + return "", ErrNoExist + } + fp.mu.RLock() + t := fp.t + fp.mu.RUnlock() + if t == nil { + return "", ErrDisabled + } + count := fp.t.counter + return fmt.Sprint(count), nil + +} + func List() []string { failpointsMu.RLock() ret := make([]string, 0, len(failpoints)) diff --git a/runtime/terms.go b/runtime/terms.go index d81477d..91cfd82 100644 --- a/runtime/terms.go +++ b/runtime/terms.go @@ -41,6 +41,8 @@ type terms struct { // mu protects the state of the terms chain mu sync.Mutex + // counts amount of sleep executions + counter int } // term is an executable unit of the failpoint terms chain @@ -310,6 +312,9 @@ func actSleep(t *term) interface{} { return nil } time.Sleep(dur) + t.parent.mu.Lock() + t.parent.counter++ + t.parent.mu.Unlock() return nil }