diff --git a/analysis.go b/analysis.go index 12dd868..26c1d26 100644 --- a/analysis.go +++ b/analysis.go @@ -3,8 +3,10 @@ package main import ( "encoding/json" "fmt" + "io" "io/ioutil" "path/filepath" + "strings" "github.com/feedhenry/fh-system-dump-tool/openshift/api/types" ) @@ -177,3 +179,28 @@ func CheckDeploymentConfigs(deploymentConfigs types.DeploymentConfigList) CheckR } return result } + +// PrintAnalysisReport writes a summary of problems found in analysisResult to +// out. +func PrintAnalysisReport(analysisResult AnalysisResult, out io.Writer) { + ok := true + // TODO: handle analysisResult.Platform. + for _, projectResult := range analysisResult.Projects { + for _, checkResult := range projectResult.Results { + if !checkResult.Ok { + ok = false + fmt.Fprintf(out, "Potential issue in project %s: %s\n", projectResult.Project, checkResult.CheckName) + fmt.Fprintf(out, " Details:\n") + for _, info := range checkResult.Info { + fmt.Fprintf(out, " %s\n", strings.Replace(strings.TrimSpace(info.Message), "\n", "\n ", -1)) + } + for _, event := range checkResult.Events { + fmt.Fprintf(out, " %s\n", strings.Replace(strings.TrimSpace(event.Message), "\n", "\n ", -1)) + } + } + } + } + if ok { + fmt.Fprintln(out, "No issues found") + } +} diff --git a/analysis_test.go b/analysis_test.go index 05ced9c..08ec694 100644 --- a/analysis_test.go +++ b/analysis_test.go @@ -1,9 +1,11 @@ package main import ( + "bytes" "encoding/json" "fmt" "reflect" + "strings" "testing" "github.com/feedhenry/fh-system-dump-tool/openshift/api/types" @@ -304,3 +306,102 @@ func (l fakeDefinitionLoader) Err() error { } var _ DefinitionLoader = (*fakeDefinitionLoader)(nil) + +func TestPrintAnalysisReport(t *testing.T) { + tests := []struct { + description string + analysisResult AnalysisResult + // set want for exact matches or contains/notContains for + // inexact matches. + want string + contains []string + notContains []string + }{ + { + description: "empty analysis", + analysisResult: AnalysisResult{}, + want: "No issues found\n", + }, + { + description: "no errors", + analysisResult: AnalysisResult{ + Projects: []ProjectResult{ + { + Project: "dev", + Results: []CheckResult{ + { + CheckName: "check event log for errors", + Ok: true, + Message: "this issue was not detected", + }, + { + CheckName: "check number of replicas in deployment configs", + Ok: true, + Message: "this issue was not detected", + }, + { + CheckName: "check pods for containers in waiting state", + Ok: true, + Message: "this issue was not detected", + }, + }, + }, + }, + }, + want: "No issues found\n", + }, + { + description: "errors found", + analysisResult: AnalysisResult{ + Projects: []ProjectResult{ + { + Project: "rhmap-core", + Results: []CheckResult{ + { + CheckName: "check event log for errors", + Ok: false, + Message: "errors detected in event log", + Events: []types.Event{ + { + TypeMeta: types.TypeMeta{Kind: "Event"}, + InvolvedObject: types.ObjectReference{ + Namespace: "rhmap-core", + Name: "fh-ngui", + }, + Reason: "FailedUpdate", + Message: "Cannot update deployment rhmap-core/fh-ngui-3 status to Pending: replicationcontrollers \"fh-ngui-3\" cannot be updated: the object has been modified; please apply your changes to the latest version and try again", + Count: 1, + Type: "Warning", + }, + }, + }, + }, + }, + }, + }, + contains: []string{"rhmap-core", "fh-ngui", "Cannot update deployment"}, + notContains: []string{"No issues found"}, + }, + } + for _, tt := range tests { + var out bytes.Buffer + PrintAnalysisReport(tt.analysisResult, &out) + got := out.String() + if len(tt.contains) > 0 || len(tt.notContains) > 0 { + for _, want := range tt.contains { + if !strings.Contains(got, want) { + t.Errorf("%s: got %q, want to contain %q", tt.description, got, want) + } + } + for _, notWant := range tt.notContains { + if strings.Contains(got, notWant) { + t.Errorf("%s: got %q, want not to contain %q", tt.description, got, notWant) + } + } + } else { + if got != tt.want { + t.Errorf("%s: got %q, want %q", tt.description, got, tt.want) + } + } + } +} diff --git a/main.go b/main.go index 1c5ee7d..d4531ba 100644 --- a/main.go +++ b/main.go @@ -186,5 +186,5 @@ func main() { log.Printf("Finished in %v", delta) } - RunOutputTask(os.Stdout, os.Stderr, analysisResults) + PrintAnalysisReport(analysisResults, os.Stdout) } diff --git a/output_results.go b/output_results.go deleted file mode 100644 index 38e6c02..0000000 --- a/output_results.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "fmt" - "io" - "strings" -) - -// RunOutputTask will read in the analysis.json file and output -// any useful information to o or any errors to e. -func RunOutputTask(o io.Writer, e io.Writer, analysisResult AnalysisResult) { - // TODO: handle analysisResult.Platform. - for _, projectResult := range analysisResult.Projects { - for _, checkResult := range projectResult.Results { - if !checkResult.Ok { - fmt.Fprintf(o, "Potential issue discovered in project %s: %s\n", projectResult.Project, checkResult.CheckName) - fmt.Fprintf(o, " Details:\n") - for _, info := range checkResult.Info { - fmt.Fprintf(o, " %s\n", strings.Replace(strings.TrimSpace(info.Message), "\n", "\n ", -1)) - } - for _, event := range checkResult.Events { - fmt.Fprintf(o, " %s\n", strings.Replace(strings.TrimSpace(event.Message), "\n", "\n ", -1)) - } - } - } - } -} diff --git a/output_results_test.go b/output_results_test.go deleted file mode 100644 index 2560b6a..0000000 --- a/output_results_test.go +++ /dev/null @@ -1,101 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "strings" - "testing" -) - -func mockAnalysisNoErrors(p string, d interface{}) error { - contents := `{ - "projects": [{ - "project": "dev", - "checks": [{ - "checkName": "check event log for errors", - "ok": true, - "message": "this issue was not detected" - }, { - "checkName": "check number of replicas in deployment configs", - "ok": true, - "message": "this issue was not detected" - }, { - "checkName": "check pods for containers in waiting state", - "ok": true, - "message": "this issue was not detected" - }] - }] - }` - - decoder := json.NewDecoder(bytes.NewBuffer([]byte(contents))) - err := decoder.Decode(&d) - if err != nil { - return err - } - return nil -} - -func mockAnalysisErrors(p string, d interface{}) error { - contents := `{ - "projects": [{ - "project": "rhmap-core", - "checks": [{ - "checkName": "check event log for errors", - "ok": false, - "message": "Errors detected in event log", - "events": [{ - "kind": "Event", - "involvedObject": { - "namespace": "rhmap-core", - "name": "fh-ngui" - }, - "reason": "FailedUpdate", - "message": "Cannot update deployment rhmap-core/fh-ngui-3 status to Pending: replicationcontrollers \"fh-ngui-3\" cannot be updated: the object has been modified; please apply your changes to the latest version and try again", - "count": 1, - "type": "Warning" - }] - }] - }] - }` - - decoder := json.NewDecoder(bytes.NewBuffer([]byte(contents))) - err := decoder.Decode(&d) - if err != nil { - return err - } - return nil -} - -func TestRunOutputTaskNoErrors(t *testing.T) { - o := bytes.NewBuffer([]byte{}) - e := bytes.NewBuffer([]byte{}) - var analysisResult AnalysisResult - if err := mockAnalysisNoErrors("", &analysisResult); err != nil { - t.Fatal(err) - } - RunOutputTask(o, e, analysisResult) - - if got := len(o.Bytes()); got > 0 { - t.Fatal("len(o.Bytes()), expected: 0, got:", got) - } - if got := len(e.Bytes()); got > 0 { - t.Fatal("len(e.Bytes()), expected: 0, got:", got) - } -} - -func TestRunOutputTaskFoundErrors(t *testing.T) { - o := bytes.NewBuffer([]byte{}) - e := bytes.NewBuffer([]byte{}) - var analysisResult AnalysisResult - if err := mockAnalysisErrors("", &analysisResult); err != nil { - t.Fatal(err) - } - RunOutputTask(o, e, analysisResult) - - if !strings.Contains(string(o.Bytes()), "rhmap-core") { - t.Fatal("string(o.Bytes()), expected: to contain 'rhmap-core', got:", string(o.Bytes())) - } - if got := len(e.Bytes()); got > 0 { - t.Fatal("len(e.Bytes()), expected: 0, got:", got) - } -}