//go:build unit
// +build unit
package cmd
import (
"bytes"
"encoding/xml"
"io"
"io/ioutil"
"net/http"
"testing"
piperhttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestDiscoverServerSuccess(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Scope: "localChangedObjects",
Commit: "0123456789abcdefghijkl",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("discover server successful", func(t *testing.T) {
httpClient := httpMockGcts{
StatusCode: 200,
Header: map[string][]string{"x-csrf-token": {"ZegUEgfa50R7ZfGGxOtx2A=="}},
ResponseBody: `
`}
header, err := discoverServer(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/adt/core/discovery?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check header", func(t *testing.T) {
assert.Equal(t, http.Header{"x-csrf-token": []string{"ZegUEgfa50R7ZfGGxOtx2A=="}}, *header)
})
}
})
}
func TestDiscoverServerFailure(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost3.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Scope: "localChangedObjects",
Commit: "0123456789abcdefghijkl",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("a http error occurred", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 403, ResponseBody: `
Service cannot be reached
`}
header, err := discoverServer(&config, &httpClient)
t.Run("check error", func(t *testing.T) {
assert.EqualError(t, err, "discovery of the ABAP server failed: a http error occurred")
})
t.Run("check header", func(t *testing.T) {
assert.Equal(t, (*http.Header)(nil), header)
})
})
t.Run("discovery response is nil", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200, ResponseBody: ``}
header, err := discoverServer(&config, &httpClient)
t.Run("check error", func(t *testing.T) {
assert.EqualError(t, err, "discovery of the ABAP server failed: did not retrieve a HTTP response")
})
t.Run("check header", func(t *testing.T) {
assert.Equal(t, (*http.Header)(nil), header)
})
})
t.Run("discovery header is nil", func(t *testing.T) {
httpClient := httpMockGctsT{
StatusCode: 200,
Header: nil,
ResponseBody: `
`}
header, err := discoverServer(&config, &httpClient)
t.Run("check error", func(t *testing.T) {
assert.EqualError(t, err, "discovery of the ABAP server failed: did not retrieve a HTTP response")
})
t.Run("check header", func(t *testing.T) {
assert.Equal(t, (*http.Header)(nil), header)
})
})
}
func TestGetLocalObjectsSuccess(t *testing.T) {
t.Run("return multiple objects successfully", func(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "localChangedObjects",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
httpClient := httpMockGctsT{StatusCode: 200}
object1 := repoObject{
Object: "ZCL_GCTS",
Type: "CLAS",
}
object2 := repoObject{
Object: "ZP_GCTS",
Type: "DEVC",
}
object3 := repoObject{
Object: "ZIF_GCTS_API",
Type: "INTF",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object1)
repoObjects = append(repoObjects, object2)
repoObjects = append(repoObjects, object3)
objects, err := getLocalObjects(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo/compareCommits?fromCommit=xyz987654321&toCommit=0123456789abcdefghijkl&sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
t.Run("no objects returned by http call", func(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo2",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "localChangedObjects",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
var repoObjects []repoObject
httpClient := httpMockGctsT{StatusCode: 200, ResponseBody: `{}`}
objects, err := getLocalObjects(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo2/compareCommits?fromCommit=xyz987654321&toCommit=0123456789abcdefghijkl&sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
}
func TestGetLocalObjectsFailure(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "localChangedObjects",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("http error occurred", func(t *testing.T) {
httpClient := httpMockGcts{StatusCode: 500, ResponseBody: `
{
"exception": "No relation between system and repository"
}
`}
_, err := getLocalObjects(&config, &httpClient)
assert.EqualError(t, err, "get local changed objects failed: get history failed: a http error occurred")
})
}
func TestGetRemoteObjectsSuccess(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "remoteChangedObjects",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("return multiple objects successfully", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
object1 := repoObject{
Object: "ZCL_GCTS",
Type: "CLAS",
}
object2 := repoObject{
Object: "ZP_GCTS",
Type: "DEVC",
}
object3 := repoObject{
Object: "ZIF_GCTS_API",
Type: "INTF",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object1)
repoObjects = append(repoObjects, object2)
repoObjects = append(repoObjects, object3)
objects, err := getRemoteObjects(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo/compareCommits?fromCommit=7845abaujztrw785&toCommit=0123456789abcdefghijkl&sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
t.Run("no objects returned by http call", func(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo2",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "remoteChangedObjects",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
httpClient := httpMockGctsT{StatusCode: 200, ResponseBody: `{}`}
var repoObjects []repoObject
objects, err := getRemoteObjects(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo2/compareCommits?fromCommit=7845abaujztrw785&toCommit=0123456789abcdefghijkl&sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
}
func TestGetRemoteObjectsFailure(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "remoteChangedObjects",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("http error occurred", func(t *testing.T) {
httpClient := httpMockGcts{StatusCode: 500, ResponseBody: `
{
"exception": "No relation between system and repository"
}
`}
_, err := getRemoteObjects(&config, &httpClient)
assert.EqualError(t, err, "get remote changed objects failed: get repository history failed: a http error occurred")
})
}
func TestGetLocalPackagesSuccess(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "localChangedPackages",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("return multiple objects successfully", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
object1 := repoObject{
Object: "SGCTS",
Type: "DEVC",
}
object2 := repoObject{
Object: "SGCTS_2",
Type: "DEVC",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object1)
repoObjects = append(repoObjects, object2)
objects, err := getLocalPackages(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/objects/INTF/ZIF_GCTS_API?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
t.Run("no objects returned by http call", func(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo2",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "localChangedObjects",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
httpClient := httpMockGctsT{StatusCode: 200, ResponseBody: `{}`}
var repoObjects []repoObject
objects, err := getLocalPackages(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo2/compareCommits?fromCommit=xyz987654321&toCommit=0123456789abcdefghijkl&sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
}
func TestGetLocalPackagesFailure(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "localChangedPackages",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("http error occurred", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 500, ResponseBody: `
{
"exception": "No relation between system and repository"
}
`}
_, err := getLocalPackages(&config, &httpClient)
assert.EqualError(t, err, "get local changed objects failed: get history failed: a http error occurred")
})
}
func TestGetRemotePackagesSuccess(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "remoteChangedPackages",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("return multiple objects successfully", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
object1 := repoObject{
Object: "SGCTS",
Type: "DEVC",
}
object2 := repoObject{
Object: "SGCTS_2",
Type: "DEVC",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object1)
repoObjects = append(repoObjects, object2)
objects, err := getRemotePackages(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/objects/INTF/ZIF_GCTS_API?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
t.Run("no objects returned by http call", func(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo2",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "remoteChangedPackages",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
httpClient := httpMockGctsT{StatusCode: 200, ResponseBody: `{}`}
var repoObjects []repoObject
objects, err := getRemoteObjects(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo2/compareCommits?fromCommit=7845abaujztrw785&toCommit=0123456789abcdefghijkl&sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
}
func TestGetRemotePackagesFailure(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "remoteChangedPackages",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("http error occurred", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 500, ResponseBody: `
{
"exception": "No relation between system and repository"
}
`}
_, err := getRemotePackages(&config, &httpClient)
assert.EqualError(t, err, "get remote changed packages failed: get repository history failed: a http error occurred")
})
}
func TestGetPackagesSuccess(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "packages",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("return multiple objects successfully", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
object1 := repoObject{
Pgmid: "R3TR",
Object: "ZP_GCTS",
Type: "DEVC",
Description: "Package(ABAP Objects)",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object1)
objects, err := getPackages(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo/objects?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
t.Run("no objects returned by http call", func(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo2",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "packages",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
httpClient := httpMockGcts{StatusCode: 200, ResponseBody: `{}`}
var repoObjects []repoObject
objects, err := getPackages(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo2/objects?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
}
func TestGetPackagesFailure(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo2",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "packages",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("http error occurred", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 500, ResponseBody: `
{
"exception": "No relation between system and repository"
}
`}
_, err := getPackages(&config, &httpClient)
assert.EqualError(t, err, "get packages failed: could not get repository objects: a http error occurred")
})
}
func TestGetRepositoryObjectsSuccess(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("return multiple objects successfully", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
object1 := repoObject{
Pgmid: "R3TR",
Object: "ZCL_GCTS",
Type: "CLAS",
Description: "Class (ABAP Objects)",
}
object3 := repoObject{
Pgmid: "R3TR",
Object: "ZIF_GCTS_API",
Type: "INTF",
Description: "Interface (ABAP Objects)",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object1)
repoObjects = append(repoObjects, object3)
objects, err := getRepositoryObjects(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo/objects?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
t.Run("no objects returned by http call", func(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo2",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
httpClient := httpMockGctsT{StatusCode: 200, ResponseBody: `{}`}
var repoObjects []repoObject
objects, err := getRepositoryObjects(&config, &httpClient)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo2/objects?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check package objects", func(t *testing.T) {
assert.Equal(t, repoObjects, objects)
})
}
})
}
func TestGetRepositoryObjectsFailure(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
}
t.Run("http error occurred", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 500, ResponseBody: `
{
"exception": "No relation between system and repository"
}
`}
_, err := getRepositoryObjects(&config, &httpClient)
assert.EqualError(t, err, "could not get repository objects: a http error occurred")
})
}
func TestExecuteAUnitTestSuccess(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
AtcResultsFileName: "ATCResults.xml",
AUnitResultsFileName: "AUnitResults.xml",
}
t.Run("all unit tests were successful", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
object := repoObject{
Pgmid: "R3TR",
Object: "ZCL_GCTS",
Type: "CLAS",
Description: "Clas Object",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object)
err := executeAUnitTest(&config, &httpClient, repoObjects)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
}
})
t.Run("no unit tests found", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200, ResponseBody: `
The task definition does not refer to any test
`}
object := repoObject{
Pgmid: "R3TR",
Object: "ZP_NON_EXISTANT",
Type: "CLAS",
Description: "Clas Object",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object)
err := executeAUnitTest(&config, &httpClient, repoObjects)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
}
})
}
func TestExecuteAUnitTestFailure(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
AtcResultsFileName: "ATCResults.xml",
AUnitResultsFileName: "AUnitResults.xml",
}
var repoObjects []repoObject
t.Run("a http error occurred", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 403, ResponseBody: `
CSRF token validation failed
`}
header := make(http.Header)
header.Add("Accept", "application/atomsvc+xml")
header.Add("x-csrf-token", "ZegUEgfa50R7ZfGGxOtx2A==")
header.Add("saml2", "disabled")
err := executeAUnitTest(&config, &httpClient, repoObjects)
assert.EqualError(t, err, "execute of Aunit test has failed: run of unit tests failed: discovery of the ABAP server failed: a http error occurred")
})
}
func TestExecuteATCCheckSuccess(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
AtcVariant: "DEFAULT_REMOTE_REF",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
AtcResultsFileName: "ATCResults.xml",
}
header := make(http.Header)
header.Add("Accept", "application/atomsvc+xml")
header.Add("x-csrf-token", "ZegUEgfa50R7ZfGGxOtx2A==")
header.Add("saml2", "disabled")
t.Run("atc checks were found", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
object := repoObject{
Pgmid: "R3TR",
Object: "ZCL_GCTS",
Type: "CLAS",
Description: "Clas Object",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object)
err := executeATCCheck(&config, &httpClient, repoObjects)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
}
})
t.Run("no ATC Checks were found", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
AtcVariant: "CUSTOM_REMOTE_REF",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
AtcResultsFileName: "ATCResults.xml",
}
object := repoObject{
Pgmid: "R3TR",
Object: "ZP_NON_EXISTANT",
Type: "CLAS",
Description: "Clas Object",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object)
err := executeATCCheck(&config, &httpClient, repoObjects)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/adt/atc/worklists/3E3D0764F95Z01ABCDHEF9C9F6B5C14P?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
}
})
}
func TestExecuteATCCheckFailure(t *testing.T) {
object := repoObject{
Pgmid: "R3TR",
Object: "ZP_PIPER",
Type: "CLAS",
Description: "Clas Object",
}
var repoObjects []repoObject
repoObjects = append(repoObjects, object)
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
AtcResultsFileName: "ATCResults.xml",
}
t.Run("a http error occurred", func(t *testing.T) {
httpClient := httpMockGcts{StatusCode: 403, ResponseBody: `
CSRF token validation failed
`}
header := make(http.Header)
header.Add("Accept", "application/atomsvc+xml")
header.Add("x-csrf-token", "ZegUEgfa50R7ZfGGxOtx2A==")
header.Add("saml2", "disabled")
err := executeATCCheck(&config, &httpClient, repoObjects)
assert.EqualError(t, err, "execution of ATC Checks failed: get worklist failed: discovery of the ABAP server failed: a http error occurred")
})
}
func TestParseAUnitResultSuccess(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
AUnitResultsFileName: "AUnitResults.xml",
}
t.Run("unit test is successful", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
var xmlBody = []byte(`
`)
var resp *runResult
xml.Unmarshal(xmlBody, &resp)
parsedRes, err := parseUnitResult(&config, &httpClient, resp)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check file name", func(t *testing.T) {
assert.Equal(t, "/var/jenkins_home/workspace/myFirstPipeline//objects/CLAS/ZCL_GCTS/CINC ZCL_GCTS======================CCAU.abap", parsedRes.File[0].Name)
})
}
})
t.Run("unit test failed", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
var xmlBody = []byte(`
Critical Assertion Error: 'Check: ASSERT_EQUALS'
`)
var resp *runResult
xml.Unmarshal(xmlBody, &resp)
parsedRes, err := parseUnitResult(&config, &httpClient, resp)
if assert.NoError(t, err) {
t.Run("check url", func(t *testing.T) {
assert.Equal(t, "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo?sap-client=000", httpClient.URL)
})
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "GET", httpClient.Method)
})
t.Run("check file name", func(t *testing.T) {
assert.Equal(t, "/var/jenkins_home/workspace/myFirstPipeline//objects/CLAS/ZCL_GCTS_PIPER_DEMO/CINC ZCL_GCTS_PIPER_DEMO===========CCAU.abap", parsedRes.File[0].Name)
})
t.Run("check line number", func(t *testing.T) {
assert.Equal(t, "21", parsedRes.File[0].Error[0].Line)
})
t.Run("check severity", func(t *testing.T) {
assert.Equal(t, "error", parsedRes.File[0].Error[0].Severity)
})
t.Run("check source", func(t *testing.T) {
assert.Equal(t, "LTCL_MASTER/CHECK", parsedRes.File[0].Error[0].Source)
})
t.Run("check message", func(t *testing.T) {
assert.Equal(t, " Different Values: Expected [Hello] Actual [Hello2] Test 'LTCL_MASTER->CHECK' in Main Program 'ZCL_GCTS_PIPER_DEMO===========CP'.", parsedRes.File[0].Error[0].Message)
})
}
})
}
func TestParseAUnitResultFailure(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
AtcVariant: "DEFAULT_REMOTE_REF",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
AUnitResultsFileName: "AUnitResults.xml",
}
t.Run("parser fails", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 403}
var xmlBody = []byte(`
Critical Assertion Error: 'Check: ASSERT_EQUALS'
`)
var resp *runResult
xml.Unmarshal(xmlBody, &resp)
parsedRes, err := parseUnitResult(&config, &httpClient, resp)
if assert.Error(t, err) {
t.Run("check method", func(t *testing.T) {
assert.Equal(t, "parse AUnit Result failed: get file name has failed: could not check readable source format: could not get repository layout: a http error occurred", err.Error())
})
assert.NotEmpty(t, parsedRes, "results are not empty")
}
})
}
func TestParseATCCheckResultSuccess(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
AtcVariant: "DEFAULT_REMOTE_REF",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
AtcResultsFileName: "ATCResults.xml",
}
t.Run("atc found", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 200}
var xmlBody = []byte(`
`)
var resp *worklist
xml.Unmarshal(xmlBody, &resp)
parsedRes, err := parseATCCheckResult(&config, &httpClient, resp)
if assert.NoError(t, err) {
t.Run("check file name", func(t *testing.T) {
assert.Equal(t, "/var/jenkins_home/workspace/myFirstPipeline//objects/CLAS/ZCL_GCTS/CPRI ZCL_GCTS.abap", parsedRes.File[0].Name)
})
t.Run("check line number", func(t *testing.T) {
assert.Equal(t, "20", parsedRes.File[0].Error[0].Line)
})
t.Run("check severity", func(t *testing.T) {
assert.Equal(t, "error", parsedRes.File[0].Error[0].Severity)
})
t.Run("check source", func(t *testing.T) {
assert.Equal(t, "ZCL_GCTS", parsedRes.File[0].Error[0].Source)
})
t.Run("check message", func(t *testing.T) {
assert.Equal(t, "Package Check (Remote-enabled) Package Violation - Error", parsedRes.File[0].Error[0].Message)
})
assert.NotEmpty(t, parsedRes, "results are not empty")
}
})
t.Run("no ATC Checks were found", func(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
AtcVariant: "DEFAULT_REMOTE_REF",
Scope: "repository",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
AtcResultsFileName: "ATCResults.xml",
}
httpClient := httpMockGctsT{StatusCode: 200}
var xmlBody = []byte(`
`)
var resp *worklist
xml.Unmarshal(xmlBody, &resp)
parsedRes, err := parseATCCheckResult(&config, &httpClient, resp)
if assert.NoError(t, err) {
assert.Equal(t, parsedRes.Version, "1.0")
}
})
}
func TestParseATCCheckResultFailure(t *testing.T) {
config := gctsExecuteABAPQualityChecksOptions{
Host: "http://testHost.com:50000",
Client: "000",
Repository: "testRepo",
Username: "testUser",
Password: "testPassword",
Commit: "0123456789abcdefghijkl",
AtcVariant: "DEFAULT_REMOTE_REF",
Scope: "repsoitory",
Workspace: "/var/jenkins_home/workspace/myFirstPipeline",
AtcResultsFileName: "ATCResults.xml",
}
t.Run("a http error occurred", func(t *testing.T) {
httpClient := httpMockGctsT{StatusCode: 403}
var xmlBody = []byte(`
`)
var resp *worklist
xml.Unmarshal(xmlBody, &resp)
parsedRes, err := parseATCCheckResult(&config, &httpClient, resp)
assert.EqualError(t, err, "conversion of ATC check results to CheckStyle has failed: get file name has failed: could not check readable source format: could not get repository layout: a http error occurred")
assert.NotEmpty(t, parsedRes)
})
}
type httpMockGctsT struct {
Method string // is set during test execution
URL string // is set before test execution
Header map[string][]string // is set before test execution
ResponseBody string // is set before test execution
Options piperhttp.ClientOptions // is set during test
StatusCode int // is set during test
}
func (c *httpMockGctsT) SetOptions(options piperhttp.ClientOptions) {
c.Options = options
}
func (c *httpMockGctsT) SendRequest(method string, url string, r io.Reader, header http.Header, cookies []*http.Cookie) (*http.Response, error) {
c.Method = method
c.URL = url
switch url {
case "http://testHost.com:50000/sap/bc/adt/core/discovery?sap-client=000":
c.Header = map[string][]string{"X-Csrf-Token": {"ZegUEgfa50R7ZfGGxOtx2A=="}}
c.ResponseBody = `
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo?sap-client=000":
c.ResponseBody = `
{
"result": {
"rid": "testRepo",
"name": "testRepo",
"role": "PROVIDED",
"type": "GIT",
"vsid": "vSID",
"privateFlag": "false",
"url": "http://github.com/testRepo",
"createdBy": "testUser",
"createdDate": "02/02/2022",
"objects": 3,
"currentCommit": "xyz987654321"
}
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo2?sap-client=000":
c.ResponseBody = `
{
"result": {
"rid": "testRepo2",
"name": "testRepo2",
"role": "PROVIDED",
"type": "GIT",
"vsid": "vSID",
"privateFlag": "false",
"url": "http://github.com/testRepo2",
"createdBy": "testUser",
"createdDate": "02/02/2022",
"objects": 3,
"currentCommit": "xyz987654321"
}
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo/getCommit?sap-client=000":
c.ResponseBody = `
{
"commits": [
{
"id": "0123456789abcdefghijkl"
},
{
"id": "7845abaujztrw785"
},
{
"id": "45poiztr785423"
}
]
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo2/getCommit?sap-client=000":
c.ResponseBody = `
{
"commits": [
{
"id": "0123456789abcdefghijkl"
},
{
"id": "7845abaujztrw785"
},
{
"id": "45poiztr785423"
}
]
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo/getHistory?sap-client=000":
c.ResponseBody = `
{
"result": [
{
"rid": "testRepo",
"checkoutTime": 20220216233655,
"fromCommit": "xyz987654321",
"toCommit": "0123456789abcdefghijkl",
"caller": "USER",
"type": "PULL"
},
{
"rid": "testRepo",
"checkoutTime": 20220216233788,
"fromCommit": "ghi98765432",
"toCommit": "xyz987654321",
"caller": "USER",
"type": "PULL"
}
]
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo2/getHistory?sap-client=000":
c.ResponseBody = `
{
"result": [
{
"rid": "testRepo",
"checkoutTime": 20220216233655,
"fromCommit": "xyz987654321",
"toCommit": "0123456789abcdefghijkl",
"caller": "USER",
"type": "PULL"
},
{
"rid": "testRepo",
"checkoutTime": 20220216233788,
"fromCommit": "ghi98765432",
"toCommit": "xyz987654321",
"caller": "USER",
"type": "PULL"
}
]
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo/compareCommits?fromCommit=xyz987654321&toCommit=0123456789abcdefghijkl&sap-client=000":
c.ResponseBody = `
{
"objects": [
{
"name": "ZCL_GCTS",
"type": "CLAS",
"action": "Class (ABAP Objects)"
},
{
"name": "ZP_GCTS",
"type": "DEVC",
"action": "Package(ABAP Objects)"
},
{
"name": "ZIF_GCTS_API",
"type": "INTF",
"action": "Interface (ABAP Objects)"
}
]
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo/compareCommits?fromCommit=7845abaujztrw785&toCommit=0123456789abcdefghijkl&sap-client=000":
c.ResponseBody = `
{
"objects": [
{
"name": "ZCL_GCTS",
"type": "CLAS",
"action": "Class (ABAP Objects)"
},
{
"name": "ZP_GCTS",
"type": "DEVC",
"action": "Package(ABAP Objects)"
},
{
"name": "ZIF_GCTS_API",
"type": "INTF",
"action": "Interface (ABAP Objects)"
}
]
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/objects/CLAS/ZCL_GCTS?sap-client=000":
c.ResponseBody = `
{
"pgmid": "R3TR",
"object": "CLAS",
"objName": "ZCL_GCTS",
"srcsystem": "src",
"author": "HUGO",
"devclass": "SGCTS"
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/objects/INTF/ZIF_GCTS_API?sap-client=000":
c.ResponseBody = `
{
"pgmid": "R3TR",
"object": "INTF",
"objName": "ZIF_GCTS_API",
"srcsystem": "src",
"author": "HUGO",
"devclass": "SGCTS_2"
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/objects/DEVC/ZP_GCTS?sap-client=000":
c.ResponseBody = `
{
"pgmid": "R3TR",
"object": "DEVC",
"objName": "ZP_GCTS",
"srcsystem": "src",
"author": "HUGO",
"devclass": "SGCTS"
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo/layout?sap-client=000":
c.ResponseBody =
`{
"layout": {
"formatVersion": 5,
"format": "json",
"objectStorage": "plain",
"metaInformation": ".gctsmetadata/",
"tableContent": "true",
"subdirectory": "src/",
"readableSource": "false"
}
}
`
case "http://testHost.com:50000/sap/bc/cts_abapvcs/repository/testRepo/objects?sap-client=000":
c.ResponseBody = `
{
"objects": [
{
"pgmid": "R3TR",
"object": "ZCL_GCTS",
"type": "CLAS",
"description": "Class (ABAP Objects)"
},
{
"pgmid": "R3TR",
"object": "ZP_GCTS",
"type": "DEVC",
"description": "Package(ABAP Objects)"
},
{
"pgmid": "R3TR",
"object": "ZIF_GCTS_API",
"type": "INTF",
"description": "Interface (ABAP Objects)"
}
]
}
`
case "http://testHost.com:50000/sap/bc/adt/abapunit/testruns?sap-client=000":
c.Header = map[string][]string{"Accept": {"application/xml"}}
c.Header = map[string][]string{"x-csrf-token": {"ZegUEgfa50R7ZfGGxOtx2A=="}}
c.Header = map[string][]string{"Content-Type": {"application/vnd.sap.adt.abapunit.testruns.result.v1+xml"}}
c.ResponseBody = `
`
case "http://testHost.com:50000/sap/bc/adt/atc/worklists?checkVariant=DEFAULT_REMOTE_REF&sap-client=000":
c.Header = map[string][]string{"Location": {"/atc/worklists/worklistId/123Z076495C01ABCDEF9C9F6B257OD70"}}
case "http://testHost.com:50000/sap/bc/adt/atc/worklists?checkVariant=CUSTOM_REMOTE_REF&sap-client=000":
c.Header = map[string][]string{"Location": {"/atc/worklists/worklistId/3E3D0764F95Z01ABCDHEF9C9F6B5C14P"}}
case "http://testHost.com:50000/sap/bc/adt/atc/runs?worklistId=123Z076495C01ABCDEF9C9F6B257OD70?sap-client=000":
c.ResponseBody =
`
123Z076495C01ABCDEF9C9F6B257OD70
2021-11-29T14:46:46Z
FINDING_STATS
0,0,1
`
case "http://testHost.com:50000/sap/bc/adt/atc/worklists/3E3D0764F95Z01ABCDHEF9C9F6B5C14P?sap-client=000":
c.ResponseBody =
`
`
case "http://testHost.com:50000/sap/bc/adt/atc/worklists/123Z076495C01ABCDEF9C9F6B257OD70?sap-client=000":
c.ResponseBody =
`
`
}
if r != nil {
_, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
}
res := http.Response{
StatusCode: c.StatusCode,
Header: c.Header,
Body: ioutil.NopCloser(bytes.NewReader([]byte(c.ResponseBody))),
}
if c.StatusCode >= 400 {
return &res, errors.New("a http error occurred")
}
return &res, nil
}