diff --git a/outputs/documentation_test.go b/outputs/documentation_test.go index c5998c7..d1e7209 100644 --- a/outputs/documentation_test.go +++ b/outputs/documentation_test.go @@ -1,45 +1,70 @@ package outputs import ( - "bytes" - "github.com/SimonBaeumer/goss/resource" - "github.com/SimonBaeumer/goss/util" "github.com/stretchr/testify/assert" - "sync" "testing" "time" ) func TestDocumentation_Name(t *testing.T) { - j := Documentation{} - assert.Equal(t, "documentation", j.Name()) + d := Documentation{} + assert.Equal(t, "documentation", d.Name()) } -func TestDocumentation_Output(t *testing.T) { - var wg sync.WaitGroup - b := &bytes.Buffer{} - d, _ := time.ParseDuration("2s") - j := Documentation{FakeDuration: d} - out := make(chan []resource.TestResult) - r := 1 - - go func() { - defer wg.Done() - wg.Add(1) - r = j.Output(b, out, time.Now(), util.OutputConfig{}) - }() - - out <- GetExampleTestResult() - - close(out) - wg.Wait() - expectedJson := `Title: my title +func TestDocumentation_Output_Success(t *testing.T) { + duration, _ := time.ParseDuration("2s") + d := Documentation{FakeDuration: duration} + result, exitCode := runOutput(d, getSuccessTestResult()) + + expected := `Title: my title resource type: my resource id: a property: matches expectation: [expected] Total Duration: 2.000s Count: 1, Failed: 0, Skipped: 0 ` - assert.Equal(t, expectedJson, b.String()) - assert.Equal(t, 0, r) + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) +} + +func TestDocumentation_Output_Fail(t *testing.T) { + duration, _ := time.ParseDuration("2s") + d := Documentation{FakeDuration: duration} + result, exitCode := runOutput(d, getFailTestResult()) + + expected := `Title: failure +resource type: my resource id: a property: doesn't match, expect: [expected] found: [] + + +Failures/Skipped: + +Title: failure +resource type: my resource id: a property: doesn't match, expect: [expected] found: [] + +Total Duration: 2.000s +Count: 1, Failed: 1, Skipped: 0 +` + assert.Equal(t, expected, result) + assert.Equal(t, 1, exitCode) +} + +func TestDocumentation_Output_Skip(t *testing.T) { + duration, _ := time.ParseDuration("2s") + d := Documentation{FakeDuration: duration} + result, exitCode := runOutput(d, getSkipTestResult()) + + expected := `Title: failure +resource type: my resource id: a property: skipped + + +Failures/Skipped: + +Title: failure +resource type: my resource id: a property: skipped + +Total Duration: 2.000s +Count: 1, Failed: 0, Skipped: 1 +` + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) } diff --git a/outputs/json_oneline.go b/outputs/json_oneline.go index 65a355f..b0a4dd7 100644 --- a/outputs/json_oneline.go +++ b/outputs/json_oneline.go @@ -12,7 +12,9 @@ import ( ) // JsonOneline represents the JsonOneline output type -type JsonOneline struct{} +type JsonOneline struct { + duration time.Duration +} // Name returns the name func (r JsonOneline) Name() string { return "json_oneline" } @@ -40,6 +42,10 @@ func (r JsonOneline) Output(w io.Writer, results <-chan []resource.TestResult, summary := make(map[string]interface{}) duration := time.Since(startTime) + //testing purposes + if r.duration != 0 { + duration = r.duration + } summary["test-count"] = testCount summary["failed-count"] = failed summary["total-duration"] = duration diff --git a/outputs/json_oneline_test.go b/outputs/json_oneline_test.go new file mode 100644 index 0000000..a45c721 --- /dev/null +++ b/outputs/json_oneline_test.go @@ -0,0 +1,42 @@ +package outputs + +import ( + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func TestJsonOneline_Name(t *testing.T) { + j := JsonOneline{} + assert.Equal(t, "json_oneline", j.Name()) +} + +func TestJsonOneline_Output_FAIL(t *testing.T) { + duration, _ := time.ParseDuration("2s") + result, exitCode := runOutput(JsonOneline{duration: duration}, getFailTestResult()) + + expected := `{"results":[{"duration":500,"err":null,"expected":["expected"],"found":null,"human":"","meta":null,"property":"a property","resource-id":"my resource id","resource-type":"resource type","result":1,"successful":false,"summary-line":"resource type: my resource id: a property: doesn't match, expect: [expected] found: []","test-type":0,"title":"failure"}],"summary":{"failed-count":1,"summary-line":"Count: 1, Failed: 1, Duration: 2.000s","test-count":1,"total-duration":2000000000}} +` + assert.Equal(t, expected, result) + assert.Equal(t, 1, exitCode) +} + +func TestJsonOneline_Output_Success(t *testing.T) { + duration, _ := time.ParseDuration("2s") + result, exitCode := runOutput(JsonOneline{duration: duration}, getSuccessTestResult()) + + expected := `{"results":[{"duration":500,"err":null,"expected":["expected"],"found":null,"human":"","meta":null,"property":"a property","resource-id":"my resource id","resource-type":"resource type","result":0,"successful":true,"summary-line":"resource type: my resource id: a property: matches expectation: [expected]","test-type":0,"title":"my title"}],"summary":{"failed-count":0,"summary-line":"Count: 1, Failed: 0, Duration: 2.000s","test-count":1,"total-duration":2000000000}} +` + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) +} + +func TestJsonOneline_Output_Skip(t *testing.T) { + duration, _ := time.ParseDuration("2s") + result, exitCode := runOutput(JsonOneline{duration: duration}, getSkipTestResult()) + + expected := `{"results":[{"duration":500,"err":null,"expected":["expected"],"found":null,"human":"","meta":null,"property":"a property","resource-id":"my resource id","resource-type":"resource type","result":2,"successful":true,"summary-line":"resource type: my resource id: a property: skipped","test-type":0,"title":"failure"}],"summary":{"failed-count":0,"summary-line":"Count: 1, Failed: 0, Duration: 2.000s","test-count":1,"total-duration":2000000000}} +` + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) +} diff --git a/outputs/json_test.go b/outputs/json_test.go index b571dd2..7725165 100644 --- a/outputs/json_test.go +++ b/outputs/json_test.go @@ -1,13 +1,8 @@ package outputs import ( - "bytes" - "github.com/SimonBaeumer/goss/resource" - "github.com/SimonBaeumer/goss/util" "github.com/stretchr/testify/assert" - "sync" "testing" - "time" ) func TestJson_Name(t *testing.T) { @@ -16,22 +11,11 @@ func TestJson_Name(t *testing.T) { } func TestJson_Output(t *testing.T) { - var wg sync.WaitGroup - b := &bytes.Buffer{} - j := Json{FakeDuration: 1000} - out := make(chan []resource.TestResult) - r := 1 + result, exitCode := runOutput( + Json{FakeDuration: 1000}, + getSuccessTestResult(), + ) - go func() { - defer wg.Done() - wg.Add(1) - r = j.Output(b, out, time.Now(), util.OutputConfig{}) - }() - - out <- GetExampleTestResult() - - close(out) - wg.Wait() expectedJson := `{ "results": [ { @@ -61,6 +45,45 @@ func TestJson_Output(t *testing.T) { } } ` - assert.Equal(t, expectedJson, b.String()) - assert.Equal(t, 0, r) + assert.Equal(t, expectedJson, result) + assert.Equal(t, 0, exitCode) +} + +func TestJson_Output_FAIL(t *testing.T) { + result, exitCode := runOutput( + Json{FakeDuration: 1000}, + getFailTestResult(), + ) + + expected := `{ + "results": [ + { + "duration": 500, + "err": null, + "expected": [ + "expected" + ], + "found": null, + "human": "", + "meta": null, + "property": "a property", + "resource-id": "my resource id", + "resource-type": "resource type", + "result": 1, + "successful": false, + "summary-line": "resource type: my resource id: a property: doesn't match, expect: [expected] found: []", + "test-type": 0, + "title": "failure" + } + ], + "summary": { + "failed-count": 1, + "summary-line": "Count: 1, Failed: 1, Duration: 0.000s", + "test-count": 1, + "total-duration": 1000 + } +} +` + assert.Equal(t, expected, result) + assert.Equal(t, 1, exitCode) } diff --git a/outputs/junit.go b/outputs/junit.go index 12c5b2b..36a6ed5 100644 --- a/outputs/junit.go +++ b/outputs/junit.go @@ -14,7 +14,9 @@ import ( ) // JUnit represents the junit output type -type JUnit struct{} +type JUnit struct { + testingTimestamp string +} // Name returns the name func (r JUnit) Name() string { return "junit" } @@ -28,6 +30,10 @@ func (r JUnit) Output(w io.Writer, results <-chan []resource.TestResult, // ISO8601 timeformat timestamp := time.Now().Format(time.RFC3339) + // Testing purposes to set the timestamp directly + if r.testingTimestamp != "" { + timestamp = r.testingTimestamp + } var summary map[int]string summary = make(map[int]string) @@ -66,7 +72,7 @@ func (r JUnit) Output(w io.Writer, results <-chan []resource.TestResult, duration := time.Since(startTime) fmt.Fprintln(w, "") fmt.Fprintf(w, "\n", + "failures=\"%d\" skipped=\"%d\" time=\"%.3f\" testingTimestamp=\"%s\">\n", testCount, failed, skipped, duration.Seconds(), timestamp) for i := 0; i < testCount; i++ { diff --git a/outputs/junit_test.go b/outputs/junit_test.go new file mode 100644 index 0000000..de2ca99 --- /dev/null +++ b/outputs/junit_test.go @@ -0,0 +1,60 @@ +package outputs + +import ( + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func TestJunit_Name(t *testing.T) { + j := JUnit{} + assert.Equal(t, "junit", j.Name()) +} + +func getDate() string { + return time.Date( + 2019, 01, 01, 10, 30, 30, 3000, time.UTC).Format(time.RFC3339) +} + +func TestJunit_Output_Fail(t *testing.T) { + result, exitCode := runOutput(JUnit{testingTimestamp: getDate()}, getFailTestResult()) + + expected := ` + + +resource type: my resource id: a property: doesn't match, expect: [expected] found: [] +resource type: my resource id: a property: doesn't match, expect: [expected] found: [] + + +` + assert.Equal(t, expected, result) + assert.Equal(t, 1, exitCode) +} + +func TestJunit_Output_Success(t *testing.T) { + result, exitCode := runOutput(JUnit{testingTimestamp: getDate()}, getSuccessTestResult()) + + expected := ` + + +resource type: my resource id: a property: matches expectation: [expected] + + +` + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) +} + +func TestJunit_Output_Skip(t *testing.T) { + result, exitCode := runOutput(JUnit{testingTimestamp: getDate()}, getSkipTestResult()) + + expected := ` + + +resource type: my resource id: a property: skipped + + +` + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) +} diff --git a/outputs/nagios_test.go b/outputs/nagios_test.go new file mode 100644 index 0000000..c6a529c --- /dev/null +++ b/outputs/nagios_test.go @@ -0,0 +1,38 @@ +package outputs + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestNagios_Name(t *testing.T) { + j := Nagios{} + assert.Equal(t, "nagios", j.Name()) +} + +func TestNagiosOuput_Success(t *testing.T) { + result, exitCode := runOutput(Nagios{}, getSuccessTestResult()) + + expected := `GOSS OK - Count: 1, Failed: 0, Skipped: 0, Duration: 0.000s +` + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) +} + +func TestNagiosOuput_Fail(t *testing.T) { + result, exitCode := runOutput(Nagios{}, getFailTestResult()) + + expected := `GOSS CRITICAL - Count: 1, Failed: 1, Skipped: 0, Duration: 0.000s +` + assert.Equal(t, expected, result) + assert.Equal(t, 2, exitCode) +} + +func TestNagiosOuput_Skip(t *testing.T) { + result, exitCode := runOutput(Nagios{}, getSkipTestResult()) + + expected := `GOSS OK - Count: 1, Failed: 0, Skipped: 1, Duration: 0.000s +` + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) +} diff --git a/outputs/outputs_test.go b/outputs/outputs_test.go new file mode 100644 index 0000000..bc0ee61 --- /dev/null +++ b/outputs/outputs_test.go @@ -0,0 +1,23 @@ +package outputs + +import ( + "github.com/magiconair/properties/assert" + "testing" +) + +func Test_Outputers(t *testing.T) { + outputer := GetOutputer("json") + assert.Equal(t, "json", outputer.Name()) + + registeredOutputers := []string{ + "documentation", + "json", + "json_oneline", + "junit", + "nagios", + "rspecish", + "silent", + "tap", + } + assert.Equal(t, registeredOutputers, Outputers()) +} diff --git a/outputs/rspecish_test.go b/outputs/rspecish_test.go index 7c3e6b2..b5ff82b 100644 --- a/outputs/rspecish_test.go +++ b/outputs/rspecish_test.go @@ -1,11 +1,7 @@ package outputs import ( - "bytes" - "github.com/SimonBaeumer/goss/resource" - "github.com/SimonBaeumer/goss/util" "github.com/stretchr/testify/assert" - "sync" "testing" "time" ) @@ -15,29 +11,54 @@ func TestRspecish_Name(t *testing.T) { assert.Equal(t, "rspecish", j.Name()) } -func TestRspecish_Output(t *testing.T) { - var wg sync.WaitGroup - b := &bytes.Buffer{} +func TestRspecish_Output_Success(t *testing.T) { d, _ := time.ParseDuration("2s") - j := Rspecish{FakeDuration: d} - out := make(chan []resource.TestResult) - r := 1 - go func() { - defer wg.Done() - wg.Add(1) - r = j.Output(b, out, time.Now(), util.OutputConfig{}) - }() + result, exitCode := runOutput(Rspecish{FakeDuration: d}, getSuccessTestResult()) - out <- GetExampleTestResult() - - close(out) - wg.Wait() - expectedJson := `. + expected := `. Total Duration: 2.000s Count: 1, Failed: 0, Skipped: 0 ` - assert.Equal(t, expectedJson, b.String()) - assert.Equal(t, 0, r) + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) +} + +func TestRspecish_Output_Fail(t *testing.T) { + d, _ := time.ParseDuration("2s") + + result, exitCode := runOutput(Rspecish{FakeDuration: d}, getFailTestResult()) + + expected := `F + +Failures/Skipped: + +Title: failure +resource type: my resource id: a property: doesn't match, expect: [expected] found: [] + +Total Duration: 2.000s +Count: 1, Failed: 1, Skipped: 0 +` + assert.Equal(t, expected, result) + assert.Equal(t, 1, exitCode) +} + +func TestRspecish_Output_Skip(t *testing.T) { + d, _ := time.ParseDuration("2s") + + result, exitCode := runOutput(Rspecish{FakeDuration: d}, getSkipTestResult()) + + expected := `S + +Failures/Skipped: + +Title: failure +resource type: my resource id: a property: skipped + +Total Duration: 2.000s +Count: 1, Failed: 0, Skipped: 1 +` + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) } diff --git a/outputs/silent_test.go b/outputs/silent_test.go new file mode 100644 index 0000000..38d77a8 --- /dev/null +++ b/outputs/silent_test.go @@ -0,0 +1,32 @@ +package outputs + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestSilentDocumentation_Name(t *testing.T) { + j := Silent{} + assert.Equal(t, "silent", j.Name()) +} + +func TestSilent_Output_Success(t *testing.T) { + result, exitCode := runOutput(Silent{}, getSuccessTestResult()) + + assert.Equal(t, "", result) + assert.Equal(t, 0, exitCode) +} + +func TestSilent_Output_Fail(t *testing.T) { + result, exitCode := runOutput(Silent{}, getFailTestResult()) + + assert.Equal(t, "", result) + assert.Equal(t, 1, exitCode) +} + +func TestSilent_Output_Skip(t *testing.T) { + result, exitCode := runOutput(Silent{}, getSkipTestResult()) + + assert.Equal(t, "", result) + assert.Equal(t, 0, exitCode) +} diff --git a/outputs/tap_test.go b/outputs/tap_test.go new file mode 100644 index 0000000..2035bf7 --- /dev/null +++ b/outputs/tap_test.go @@ -0,0 +1,52 @@ +package outputs + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestTapDocumentation_Name(t *testing.T) { + j := Tap{} + assert.Equal(t, "tap", j.Name()) +} + +func TestTap_Output_Success(t *testing.T) { + result, exitCode := runOutput( + Tap{}, + getSuccessTestResult(), + getSuccessTestResult(), + ) + + expected := `1..2 +ok 1 - resource type: my resource id: a property: matches expectation: [expected] +ok 2 - resource type: my resource id: a property: matches expectation: [expected] +` + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) +} + +func TestTap_Output_Fail(t *testing.T) { + result, exitCode := runOutput( + Tap{}, + getFailTestResult(), + ) + + expected := `1..1 +not ok 1 - resource type: my resource id: a property: doesn't match, expect: [expected] found: [] +` + assert.Equal(t, expected, result) + assert.Equal(t, 1, exitCode) +} + +func TestTap_Output_Skip(t *testing.T) { + result, exitCode := runOutput( + Tap{}, + getSkipTestResult(), + ) + + expected := `1..1 +ok 1 - # SKIP resource type: my resource id: a property: skipped +` + assert.Equal(t, expected, result) + assert.Equal(t, 0, exitCode) +} diff --git a/outputs/test_helper.go b/outputs/test_helper.go index 3e4ccb2..7f87cce 100644 --- a/outputs/test_helper.go +++ b/outputs/test_helper.go @@ -1,20 +1,75 @@ package outputs import ( + "bytes" "github.com/SimonBaeumer/goss/resource" + "github.com/SimonBaeumer/goss/util" + "sync" "time" ) -func GetExampleTestResult() []resource.TestResult { - return []resource.TestResult{ - { - Title: "my title", - Duration: time.Duration(500), - Successful: true, - ResourceType: "resource type", - ResourceId: "my resource id", - Property: "a property", - Expected: []string{"expected"}, - }, +// runOutput runs the output on the given outputer +func runOutput(outputer Outputer, results ...resource.TestResult) (string, int) { + var wg sync.WaitGroup + buffer := &bytes.Buffer{} + //d, _ := time.ParseDuration("2s") + out := make(chan []resource.TestResult) + codeChan := make(chan int) + + go func(o Outputer, b *bytes.Buffer, e chan int) { + defer wg.Done() + wg.Add(1) + exit := o.Output(b, out, time.Now(), util.OutputConfig{}) + codeChan <- exit + }(outputer, buffer, codeChan) + + //Write results to channel + out <- results + close(out) + + exitCode := <-codeChan + close(codeChan) + wg.Wait() + + return buffer.String(), exitCode +} + +//getSuccessTestResult returns an example test result +func getSuccessTestResult() resource.TestResult { + return resource.TestResult{ + Title: "my title", + Duration: time.Duration(500), + Successful: true, + Result: resource.SUCCESS, + ResourceType: "resource type", + ResourceId: "my resource id", + Property: "a property", + Expected: []string{"expected"}, + } +} + +func getFailTestResult() resource.TestResult { + return resource.TestResult{ + Title: "failure", + Duration: time.Duration(500), + Successful: false, + Result: resource.FAIL, + ResourceType: "resource type", + ResourceId: "my resource id", + Property: "a property", + Expected: []string{"expected"}, + } +} + +func getSkipTestResult() resource.TestResult { + return resource.TestResult{ + Title: "failure", + Duration: time.Duration(500), + Successful: true, + Result: resource.SKIP, + ResourceType: "resource type", + ResourceId: "my resource id", + Property: "a property", + Expected: []string{"expected"}, } }