package cmd import ( "bytes" "encoding/xml" "errors" "fmt" "io/ioutil" "os" "testing" "github.com/SAP/jenkins-library/pkg/abaputils" "github.com/SAP/jenkins-library/pkg/mock" "github.com/stretchr/testify/assert" ) type abapEnvironmentRunAUnitTestMockUtils struct { *mock.ExecMockRunner *mock.FilesMock } func newAbapEnvironmentRunAUnitTestTestsUtils() abapEnvironmentRunAUnitTestMockUtils { utils := abapEnvironmentRunAUnitTestMockUtils{ ExecMockRunner: &mock.ExecMockRunner{}, FilesMock: &mock.FilesMock{}, } return utils } func TestBuildAUnitTestBody(t *testing.T) { t.Parallel() t.Run("Test AUnit test run body with no data", func(t *testing.T) { t.Parallel() expectedmetadataString := "" expectedoptionsString := "" expectedobjectSetString := "" var err error var config AUnitConfig var metadataString, optionsString, objectSetString string metadataString, optionsString, objectSetString, err = buildAUnitTestBody(config) assert.Equal(t, expectedmetadataString, metadataString) assert.Equal(t, expectedoptionsString, optionsString) assert.Equal(t, expectedobjectSetString, objectSetString) assert.EqualError(t, err, "Error while parsing AUnit test run config. No title for the AUnit run has been provided. Please configure an appropriate title for the respective test run") }) t.Run("Test AUnit test run body with example yaml config", func(t *testing.T) { t.Parallel() expectedmetadataString := `` expectedoptionsString := `` expectedobjectSetString := `` var err error var config AUnitConfig config = AUnitConfig{ Title: "Test Title", Context: "Test Context", Options: AUnitOptions{ Measurements: "none", Scope: Scope{ OwnTests: new(bool), ForeignTests: new(bool), }, RiskLevel: RiskLevel{ Harmless: new(bool), Dangerous: new(bool), Critical: new(bool), }, Duration: Duration{ Short: new(bool), Medium: new(bool), Long: new(bool), }, }, ObjectSet: []ObjectSet{{ Type: "testSet", Set: []Set{{ Type: "testSet", PackageSet: []AUnitPackage{{ Name: "TestPackage", IncludeSubpackages: new(bool), }}, FlatObjectSet: []AUnitObject{{ Name: "TestObject", Type: "CLAS", }}, }}, }}, } var metadataString, optionsString, objectSetString string metadataString, optionsString, objectSetString, err = buildAUnitTestBody(config) assert.Equal(t, expectedmetadataString, metadataString) assert.Equal(t, expectedoptionsString, optionsString) assert.Equal(t, expectedobjectSetString, objectSetString) assert.Equal(t, nil, err) //assert.EqualError(t, err, "Error while parsing AUnit test run config. No title for the AUnit run has been provided. Please configure an appropriate title for the respective test run") }) t.Run("Test AUnit test run body with example yaml config fail: no Title", func(t *testing.T) { t.Parallel() expectedmetadataString := "" expectedoptionsString := "" expectedobjectSetString := "" var err error var config AUnitConfig config = AUnitConfig{} var metadataString, optionsString, objectSetString string metadataString, optionsString, objectSetString, err = buildAUnitTestBody(config) assert.Equal(t, expectedmetadataString, metadataString) assert.Equal(t, expectedoptionsString, optionsString) assert.Equal(t, expectedobjectSetString, objectSetString) assert.EqualError(t, err, "Error while parsing AUnit test run config. No title for the AUnit run has been provided. Please configure an appropriate title for the respective test run") }) t.Run("Test AUnit test run body with example yaml config fail: no Context", func(t *testing.T) { t.Parallel() expectedmetadataString := "" expectedoptionsString := "" expectedobjectSetString := "" var err error var config AUnitConfig config = AUnitConfig{Title: "Test"} var metadataString, optionsString, objectSetString string metadataString, optionsString, objectSetString, err = buildAUnitTestBody(config) assert.Equal(t, expectedmetadataString, metadataString) assert.Equal(t, expectedoptionsString, optionsString) assert.Equal(t, expectedobjectSetString, objectSetString) assert.EqualError(t, err, "Error while parsing AUnit test run config. No context for the AUnit run has been provided. Please configure an appropriate context for the respective test run") }) t.Run("Test AUnit test run body with example yaml config fail: no Options", func(t *testing.T) { t.Parallel() expectedmetadataString := "" expectedoptionsString := "" expectedobjectSetString := "" var err error var config AUnitConfig config = AUnitConfig{Title: "Test", Context: "Test"} var metadataString, optionsString, objectSetString string metadataString, optionsString, objectSetString, err = buildAUnitTestBody(config) assert.Equal(t, expectedmetadataString, metadataString) assert.Equal(t, expectedoptionsString, optionsString) assert.Equal(t, expectedobjectSetString, objectSetString) assert.EqualError(t, err, "Error while parsing AUnit test run config. No options have been provided. Please configure the options for the respective test run") }) t.Run("Test AUnit test run body with example yaml config fail: no ObjectSet", func(t *testing.T) { t.Parallel() expectedmetadataString := "" expectedoptionsString := "" expectedobjectSetString := "" var err error var config AUnitConfig config = AUnitConfig{Title: "Test", Context: "Test", Options: AUnitOptions{Measurements: "Test"}} var metadataString, optionsString, objectSetString string metadataString, optionsString, objectSetString, err = buildAUnitTestBody(config) assert.Equal(t, expectedmetadataString, metadataString) assert.Equal(t, expectedoptionsString, optionsString) assert.Equal(t, expectedobjectSetString, objectSetString) assert.EqualError(t, err, "Error while parsing AUnit test run object set config. No object set has been provided. Please configure the set of objects you want to be checked for the respective test run") }) } func TestParseAUnitResult(t *testing.T) { t.Parallel() t.Run("succes case: test parsing example XML result", func(t *testing.T) { t.Parallel() dir, err := ioutil.TempDir("", "test get result AUnit test run") if err != nil { t.Fatal("Failed to create temporary directory") } oldCWD, _ := os.Getwd() _ = os.Chdir(dir) // clean up tmp dir defer func() { _ = os.Chdir(oldCWD) _ = os.RemoveAll(dir) }() bodyString := `Test1Test2` body := []byte(bodyString) err = parseAUnitResult(body, "AUnitResults.xml", false) assert.Equal(t, nil, err) }) t.Run("succes case: test parsing empty AUnit run XML result", func(t *testing.T) { t.Parallel() dir, err := ioutil.TempDir("", "test get result AUnit test run") if err != nil { t.Fatal("Failed to create temporary directory") } oldCWD, _ := os.Getwd() _ = os.Chdir(dir) // clean up tmp dir defer func() { _ = os.Chdir(oldCWD) _ = os.RemoveAll(dir) }() bodyString := `` body := []byte(bodyString) err = parseAUnitResult(body, "AUnitResults.xml", false) assert.Equal(t, nil, err) }) t.Run("failure case: parsing empty xml", func(t *testing.T) { t.Parallel() var bodyString string body := []byte(bodyString) err := parseAUnitResult(body, "AUnitResults.xml", false) assert.EqualError(t, err, "Parsing AUnit result failed: Body is empty, can't parse empty body") }) } func TestGetResultAUnitRun(t *testing.T) { t.Parallel() t.Run("Get HTTP Response from AUnit test run Test", func(t *testing.T) { t.Parallel() client := &abaputils.ClientMock{ Body: `AUnit test result body`, } con := abaputils.ConnectionDetailsHTTP{ User: "Test", Password: "Test", URL: "https://api.endpoint.com/Entity/", } resp, err := getResultAUnitRun("GET", con, []byte(client.Body), client) defer resp.Body.Close() if assert.Equal(t, nil, err) { buf := new(bytes.Buffer) buf.ReadFrom(resp.Body) newStr := buf.String() assert.Equal(t, "AUnit test result body", newStr) assert.Equal(t, int64(0), resp.ContentLength) assert.Equal(t, []string([]string(nil)), resp.Header["X-Crsf-Token"]) } }) t.Run("Get HTTP Response from AUnit test run Test Failure", func(t *testing.T) { t.Parallel() client := &abaputils.ClientMock{ Body: `AUnit test result body`, BodyList: []string{}, StatusCode: 400, Error: fmt.Errorf("%w", errors.New("Test fail")), } con := abaputils.ConnectionDetailsHTTP{ User: "Test", Password: "Test", URL: "https://api.endpoint.com/Entity/", } resp, err := getResultAUnitRun("GET", con, []byte(client.Body), client) defer resp.Body.Close() if assert.EqualError(t, err, "Getting AUnit run results failed: Test fail") { buf := new(bytes.Buffer) buf.ReadFrom(resp.Body) newStr := buf.String() assert.Equal(t, "AUnit test result body", newStr) assert.Equal(t, int64(0), resp.ContentLength) assert.Equal(t, 400, resp.StatusCode) assert.Equal(t, []string([]string(nil)), resp.Header["X-Crsf-Token"]) } }) } func TestRunAbapEnvironmentRunAUnitTest(t *testing.T) { t.Parallel() t.Run("FetchXcsrfToken Test", func(t *testing.T) { t.Parallel() tokenExpected := "myToken" client := &abaputils.ClientMock{ Body: `Xcsrf Token test`, Token: tokenExpected, } con := abaputils.ConnectionDetailsHTTP{ User: "Test", Password: "Test", URL: "https://api.endpoint.com/Entity/", } token, error := fetchAUnitXcsrfToken("GET", con, []byte(client.Body), client) if assert.Equal(t, nil, error) { assert.Equal(t, tokenExpected, token) } }) t.Run("failure case: fetch token", func(t *testing.T) { t.Parallel() tokenExpected := "" client := &abaputils.ClientMock{ Body: `Xcsrf Token test`, Token: "", } con := abaputils.ConnectionDetailsHTTP{ User: "Test", Password: "Test", URL: "https://api.endpoint.com/Entity/", } token, error := fetchAUnitXcsrfToken("GET", con, []byte(client.Body), client) if assert.Equal(t, nil, error) { assert.Equal(t, tokenExpected, token) } }) t.Run("AUnit test run Poll Test", func(t *testing.T) { t.Parallel() tokenExpected := "myToken" client := &abaputils.ClientMock{ Body: ``, Token: tokenExpected, } con := abaputils.ConnectionDetailsHTTP{ User: "Test", Password: "Test", URL: "https://api.endpoint.com/Entity/", } resp, err := pollAUnitRun(con, []byte(client.Body), client) if assert.Equal(t, nil, err) { assert.Equal(t, "/sap/bc/adt/api/abapunit/results/test", resp) } }) t.Run("AUnit test run Poll Test Fail", func(t *testing.T) { t.Parallel() tokenExpected := "myToken" client := &abaputils.ClientMock{ Body: ``, Token: tokenExpected, } con := abaputils.ConnectionDetailsHTTP{ User: "Test", Password: "Test", URL: "https://api.endpoint.com/Entity/", } resp, err := pollAUnitRun(con, []byte(client.Body), client) if assert.Equal(t, nil, err) { assert.Equal(t, "", resp) } }) t.Run("Get HTTP Response from AUnit test run Test", func(t *testing.T) { t.Parallel() client := &abaputils.ClientMock{ Body: `HTTP response test`, } con := abaputils.ConnectionDetailsHTTP{ User: "Test", Password: "Test", URL: "https://api.endpoint.com/Entity/", } fmt.Println("Body:" + string([]byte(client.Body))) resp, err := getHTTPResponseAUnitRun("GET", con, []byte(client.Body), client) defer resp.Body.Close() if assert.Equal(t, nil, err) { buf := new(bytes.Buffer) buf.ReadFrom(resp.Body) newStr := buf.String() assert.Equal(t, "HTTP response test", newStr) assert.Equal(t, int64(0), resp.ContentLength) assert.Equal(t, []string([]string(nil)), resp.Header["X-Crsf-Token"]) } }) } func TestGenerateHTMLDocumentAUnit(t *testing.T) { t.Parallel() t.Run("Test empty XML Result", func(t *testing.T) { t.Parallel() expectedString := `AUnit Results

AUnit Results

Run titleSystemClientExecutedByDurationsTimestamp
FailuresErrorsSkippedAssertsTests

SeverityFileMessageTypeText
There are no AUnit findings to be displayed
` result := AUnitResult{} resultString := generateHTMLDocumentAUnit(&result) assert.Equal(t, expectedString, resultString) }) t.Run("Test AUnit XML Result", func(t *testing.T) { t.Parallel() expectedString := `AUnit Results

AUnit Results

Run titleTest titleSystemTest systemClient000ExecutedByCC00000Duration0.15sTimestamp2021-00-00T00:00:00Z
Failures4Errors4Skipped4Asserts12Tests12

SeverityFileMessageTypeText
Testcase: my_test for class ZCL_my_test
FailureZCL_my_testtestMessageAssert ErrortestError
FailureZCL_my_testtestMessage2Assert Error2testError2
FailureZCL_my_testtestMessageAssert FailuretestFailure
FailureZCL_my_testtestMessage2Assert Failure2testFailure2
FailureZCL_my_testtestSkipped-testSkipped
FailureZCL_my_testtestSkipped2-testSkipped2
Testcase: my_test2 for class ZCL_my_test2
FailureZCL_my_test2testMessage3Assert Error3testError3
FailureZCL_my_test2testMessage4Assert Error4testError4
FailureZCL_my_test2testMessage5Assert Failure5testFailure5
FailureZCL_my_test2testMessage6Assert Failure6testFailure6
FailureZCL_my_test2testSkipped7-testSkipped7
FailureZCL_my_test2testSkipped8-testSkipped8
` result := AUnitResult{ XMLName: xml.Name{Space: "testSpace", Local: "testLocal"}, Title: "Test title", System: "Test system", Client: "000", ExecutedBy: "CC00000", Time: "0.15", Timestamp: "2021-00-00T00:00:00Z", Failures: "4", Errors: "4", Skipped: "4", Asserts: "12", Tests: "12", Testsuite: struct { Tests string `xml:"tests,attr"` Asserts string `xml:"asserts,attr"` Skipped string `xml:"skipped,attr"` Errors string `xml:"errors,attr"` Failures string `xml:"failures,attr"` Timestamp string `xml:"timestamp,attr"` Time string `xml:"time,attr"` Hostname string `xml:"hostname,attr"` Package string `xml:"package,attr"` Name string `xml:"name,attr"` Testcase []struct { Asserts string `xml:"asserts,attr"` Time string `xml:"time,attr"` Name string `xml:"name,attr"` Classname string `xml:"classname,attr"` Error []struct { Text string `xml:",chardata"` Type string `xml:"type,attr"` Message string `xml:"message,attr"` } `xml:"error"` Failure []struct { Text string `xml:",chardata"` Type string `xml:"type,attr"` Message string `xml:"message,attr"` } `xml:"failure"` Skipped []struct { Text string `xml:",chardata"` Message string `xml:"message,attr"` } `xml:"skipped"` } `xml:"testcase"` }{ Tests: "6", Asserts: "4", Skipped: "2", Errors: "2", Failures: "2", Timestamp: "2021-00-00T00:00:00Z", Time: "0.15", Hostname: "0xb", Package: "testPackage", Name: "ZCL_testPackage", Testcase: []struct { Asserts string "xml:\"asserts,attr\"" Time string "xml:\"time,attr\"" Name string "xml:\"name,attr\"" Classname string "xml:\"classname,attr\"" Error []struct { Text string "xml:\",chardata\"" Type string "xml:\"type,attr\"" Message string "xml:\"message,attr\"" } "xml:\"error\"" Failure []struct { Text string "xml:\",chardata\"" Type string "xml:\"type,attr\"" Message string "xml:\"message,attr\"" } "xml:\"failure\"" Skipped []struct { Text string "xml:\",chardata\"" Message string "xml:\"message,attr\"" } "xml:\"skipped\"" }{{ Asserts: "4", Time: "0.15", Name: "my_test", Classname: "ZCL_my_test", Error: []struct { Text string "xml:\",chardata\"" Type string "xml:\"type,attr\"" Message string "xml:\"message,attr\"" }{{ Text: "testError", Type: "Assert Error", Message: "testMessage", }, { Text: "testError2", Type: "Assert Error2", Message: "testMessage2", }}, Failure: []struct { Text string "xml:\",chardata\"" Type string "xml:\"type,attr\"" Message string "xml:\"message,attr\"" }{{ Text: "testFailure", Type: "Assert Failure", Message: "testMessage", }, { Text: "testFailure2", Type: "Assert Failure2", Message: "testMessage2", }}, Skipped: []struct { Text string "xml:\",chardata\"" Message string "xml:\"message,attr\"" }{{ Text: "testSkipped", Message: "testSkipped", }, { Text: "testSkipped2", Message: "testSkipped2", }}, }, { Asserts: "4", Time: "0.15", Name: "my_test2", Classname: "ZCL_my_test2", Error: []struct { Text string "xml:\",chardata\"" Type string "xml:\"type,attr\"" Message string "xml:\"message,attr\"" }{{ Text: "testError3", Type: "Assert Error3", Message: "testMessage3", }, { Text: "testError4", Type: "Assert Error4", Message: "testMessage4", }}, Failure: []struct { Text string "xml:\",chardata\"" Type string "xml:\"type,attr\"" Message string "xml:\"message,attr\"" }{{ Text: "testFailure5", Type: "Assert Failure5", Message: "testMessage5", }, { Text: "testFailure6", Type: "Assert Failure6", Message: "testMessage6", }}, Skipped: []struct { Text string "xml:\",chardata\"" Message string "xml:\"message,attr\"" }{{ Text: "testSkipped7", Message: "testSkipped7", }, { Text: "testSkipped8", Message: "testSkipped8", }}, }}, }, } resultString := generateHTMLDocumentAUnit(&result) fmt.Println(resultString) assert.Equal(t, expectedString, resultString) }) }