func TestFakeServiceHealth(t *testing.T) { fake := FakePodStore{} targetService := "paladin" targetHost := types.NodeName("aaa2.dfw.square") targetStatus := "healthy" fake.healthResults = map[string]kp.WatchResult{ kp.HealthPath("shrimpy", "aaa1.dfw.square"): kp.WatchResult{ Service: "shrimpy", Status: "critical", }, kp.HealthPath(targetService, targetHost): kp.WatchResult{ Service: targetService, Status: targetStatus, }, } serviceRes, err := fake.GetServiceHealth(targetService) if err != nil { t.Fatal(err) } if len(serviceRes) != 1 { t.Fatalf("Expected %v to have a single health entry, found %v", targetService, len(serviceRes)) } watchResult, ok := serviceRes[kp.HealthPath(targetService, targetHost)] if !ok { t.Fatalf("Expected to find a result for %v", targetHost) } if watchResult.Status != targetStatus { t.Fatalf("Status didn't match expected: %v", watchResult.Status) } }
func (c consulHealthChecker) WatchService( serviceID string, resultCh chan<- map[string]health.Result, errCh chan<- error, quitCh <-chan struct{}, ) { defer close(resultCh) var curIndex uint64 = 0 for { select { case <-quitCh: return case <-time.After(1 * time.Second): results, _, err := c.client.KV().List(kp.HealthPath(serviceID, ""), &api.QueryOptions{ WaitIndex: curIndex, }) if err != nil { errCh <- consulutil.NewKVError("list", kp.HealthPath(serviceID, ""), err) } else { out := make(map[string]health.Result) for _, result := range results { var next kp.WatchResult err = json.Unmarshal(result.Value, &next) if err != nil { errCh <- err } else { out[next.Node] = consulWatchToResult(next) } } resultCh <- out } } } }
func (f *FakePodStore) GetServiceHealth(service string) (map[string]kp.WatchResult, error) { // Is this the best way to emulate recursive Consul queries? ret := map[string]kp.WatchResult{} prefix := kp.HealthPath(service, "") for key, v := range f.healthResults { if strings.HasPrefix(key, prefix) { ret[key] = v } } return ret, nil }
func verifyHealthChecks(config *preparer.PreparerConfig, services []string) error { client, err := config.GetConsulClient() if err != nil { return err } store := kp.NewConsulStore(client) time.Sleep(30 * time.Second) // check consul for health information for each app name, err := os.Hostname() if err != nil { return err } node := types.NodeName(name) for _, sv := range services { res, err := store.GetHealth(sv, node) if err != nil { return err } else if (res == kp.WatchResult{}) { return fmt.Errorf("No results for %s: \n\n %s", sv, targetLogs()) } else if res.Status != string(health.Passing) { return fmt.Errorf("%s did not pass health check: \n\n %s", sv, targetLogs()) } else { fmt.Println(res) } } for _, sv := range services { res, err := store.GetServiceHealth(sv) getres, _ := store.GetHealth(sv, node) if err != nil { return err } val := res[kp.HealthPath(sv, node)] if getres.Id != val.Id || getres.Service != val.Service || getres.Status != val.Status { return fmt.Errorf("GetServiceHealth failed %+v: \n\n%s", res, targetLogs()) } } // if it reaches here it means health checks // are being written to the KV store properly return nil }
func (f *FakePodStore) GetHealth(service string, node types.NodeName) (kp.WatchResult, error) { return f.healthResults[kp.HealthPath(service, node)], nil }