github.com/jaylevin/jenkins-library@v1.230.4/pkg/sonar/taskService_test.go (about)

     1  package sonar
     2  
     3  import (
     4  	"errors"
     5  	"net/http"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/jarcoal/httpmock"
    10  	sonargo "github.com/magicsong/sonargo/sonar"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/mock"
    13  
    14  	piperhttp "github.com/SAP/jenkins-library/pkg/http"
    15  )
    16  
    17  func TestGetTask(t *testing.T) {
    18  	testURL := "https://example.org"
    19  	t.Run("success", func(t *testing.T) {
    20  		httpmock.Activate()
    21  		defer httpmock.DeactivateAndReset()
    22  
    23  		sender := &piperhttp.Client{}
    24  		sender.SetOptions(piperhttp.ClientOptions{MaxRetries: -1, UseDefaultTransport: true})
    25  		// add response handler
    26  		httpmock.RegisterResponder(http.MethodGet, testURL+"/api/"+EndpointCeTask+"", httpmock.NewStringResponder(http.StatusOK, responseCeTaskSuccess))
    27  		// create service instance
    28  		serviceUnderTest := NewTaskService(testURL, mock.Anything, mock.Anything, sender)
    29  		// test
    30  		result, response, err := serviceUnderTest.GetTask(&sonargo.CeTaskOption{Id: mock.Anything})
    31  		// assert
    32  		assert.NoError(t, err)
    33  		assert.NotEmpty(t, result)
    34  		assert.NotEmpty(t, response)
    35  		assert.Equal(t, 1, httpmock.GetTotalCallCount(), "unexpected number of requests")
    36  	})
    37  	t.Run("request error", func(t *testing.T) {
    38  		httpmock.Activate()
    39  		defer httpmock.DeactivateAndReset()
    40  
    41  		sender := &piperhttp.Client{}
    42  		sender.SetOptions(piperhttp.ClientOptions{MaxRetries: -1, UseDefaultTransport: true})
    43  		// add response handler
    44  		httpmock.RegisterResponder(http.MethodGet, testURL+"/api/"+EndpointCeTask+"", httpmock.NewErrorResponder(errors.New("internal server error")))
    45  		// create service instance
    46  		serviceUnderTest := NewTaskService(testURL, mock.Anything, mock.Anything, sender)
    47  		// test
    48  		result, response, err := serviceUnderTest.GetTask(&sonargo.CeTaskOption{Id: mock.Anything})
    49  		// assert
    50  		assert.Error(t, err)
    51  		assert.Contains(t, err.Error(), "internal server error")
    52  		assert.Empty(t, result)
    53  		assert.Empty(t, response)
    54  		assert.Equal(t, 1, httpmock.GetTotalCallCount(), "unexpected number of requests")
    55  	})
    56  	t.Run("server error", func(t *testing.T) {
    57  		httpmock.Activate()
    58  		defer httpmock.DeactivateAndReset()
    59  
    60  		sender := &piperhttp.Client{}
    61  		sender.SetOptions(piperhttp.ClientOptions{MaxRetries: -1, UseDefaultTransport: true})
    62  		// add response handler
    63  		httpmock.RegisterResponder(http.MethodGet, testURL+"/api/"+EndpointCeTask+"", httpmock.NewStringResponder(http.StatusNotFound, responseCeTaskError))
    64  		// create service instance
    65  		serviceUnderTest := NewTaskService(testURL, mock.Anything, mock.Anything, sender)
    66  		// test
    67  		result, response, err := serviceUnderTest.GetTask(&sonargo.CeTaskOption{Id: mock.Anything})
    68  		// assert
    69  		assert.Error(t, err)
    70  		assert.Contains(t, err.Error(), "No activity found for task ")
    71  		assert.Empty(t, result)
    72  		assert.NotEmpty(t, response)
    73  		assert.Equal(t, 1, httpmock.GetTotalCallCount(), "unexpected number of requests")
    74  	})
    75  }
    76  
    77  func TestWaitForTask(t *testing.T) {
    78  	testURL := "https://example.org"
    79  	t.Run("success", func(t *testing.T) {
    80  		httpmock.Activate()
    81  		defer httpmock.DeactivateAndReset()
    82  
    83  		sender := &piperhttp.Client{}
    84  		sender.SetOptions(piperhttp.ClientOptions{MaxRetries: -1, UseDefaultTransport: true})
    85  		// add response handler
    86  
    87  		httpmock.RegisterResponder(http.MethodGet, testURL+"/api/"+EndpointCeTask+"", httpmock.ResponderFromMultipleResponses(
    88  			[]*http.Response{
    89  				httpmock.NewStringResponse(http.StatusOK, responseCeTaskPending),
    90  				httpmock.NewStringResponse(http.StatusOK, responseCeTaskProcessing),
    91  				httpmock.NewStringResponse(http.StatusOK, responseCeTaskSuccess),
    92  			},
    93  		))
    94  		// create service instance
    95  		serviceUnderTest := NewTaskService(testURL, mock.Anything, mock.Anything, sender)
    96  		serviceUnderTest.PollInterval = time.Millisecond
    97  		// test
    98  		err := serviceUnderTest.WaitForTask()
    99  		// assert
   100  		assert.NoError(t, err)
   101  		assert.Equal(t, 3, httpmock.GetTotalCallCount(), "unexpected number of requests")
   102  	})
   103  	t.Run("failure", func(t *testing.T) {
   104  		httpmock.Activate()
   105  		defer httpmock.DeactivateAndReset()
   106  
   107  		sender := &piperhttp.Client{}
   108  		sender.SetOptions(piperhttp.ClientOptions{MaxRetries: -1, UseDefaultTransport: true})
   109  		// add response handler
   110  
   111  		httpmock.RegisterResponder(http.MethodGet, testURL+"/api/"+EndpointCeTask+"", httpmock.ResponderFromMultipleResponses(
   112  			[]*http.Response{
   113  				httpmock.NewStringResponse(http.StatusOK, responseCeTaskPending),
   114  				httpmock.NewStringResponse(http.StatusOK, responseCeTaskProcessing),
   115  				httpmock.NewStringResponse(http.StatusNotFound, responseCeTaskFailure),
   116  			},
   117  		))
   118  		// create service instance
   119  		serviceUnderTest := NewTaskService(testURL, mock.Anything, mock.Anything, sender)
   120  		serviceUnderTest.PollInterval = time.Millisecond
   121  		// test
   122  		err := serviceUnderTest.WaitForTask()
   123  		// assert
   124  		assert.Error(t, err)
   125  		assert.Contains(t, err.Error(), "status: FAILED")
   126  		assert.Equal(t, 3, httpmock.GetTotalCallCount(), "unexpected number of requests")
   127  	})
   128  }
   129  
   130  const responseCeTaskError = `{
   131      "errors": [
   132          {
   133              "msg": "No activity found for task 'AXDj5ZWQ_ZJrW2xGuBWl'"
   134          }
   135      ]
   136  }`
   137  
   138  const responseCeTaskPending = `{
   139      "task": {
   140          "id": "AXe5y_ZMPMpzvP5DRxw_",
   141          "type": "REPORT",
   142          "componentId": "AW8jANn5v4pDRYwyZIiM",
   143          "componentKey": "Piper-Validation/Golang",
   144          "componentName": "Piper-Validation: Golang",
   145          "componentQualifier": "TRK",
   146          "analysisId": "AXe5y_mgcqEbAZBpFc0V",
   147          "status": "PENDING",
   148          "submittedAt": "2021-02-19T10:18:07+0000",
   149          "submitterLogin": "CCFenner",
   150          "startedAt": "2021-02-19T10:18:08+0000",
   151          "executedAt": "2021-02-19T10:18:09+0000",
   152          "executionTimeMs": 551,
   153          "logs": false,
   154          "hasScannerContext": true,
   155          "organization": "default-organization",
   156          "warningCount": 1,
   157          "warnings": []
   158      }
   159  }`
   160  
   161  const responseCeTaskProcessing = `{
   162      "task": {
   163          "id": "AXe5y_ZMPMpzvP5DRxw_",
   164          "type": "REPORT",
   165          "componentId": "AW8jANn5v4pDRYwyZIiM",
   166          "componentKey": "Piper-Validation/Golang",
   167          "componentName": "Piper-Validation: Golang",
   168          "componentQualifier": "TRK",
   169          "analysisId": "AXe5y_mgcqEbAZBpFc0V",
   170          "status": "IN_PROGRESS",
   171          "submittedAt": "2021-02-19T10:18:07+0000",
   172          "submitterLogin": "CCFenner",
   173          "startedAt": "2021-02-19T10:18:08+0000",
   174          "executedAt": "2021-02-19T10:18:09+0000",
   175          "executionTimeMs": 551,
   176          "logs": false,
   177          "hasScannerContext": true,
   178          "organization": "default-organization",
   179          "warningCount": 1,
   180          "warnings": []
   181      }
   182  }`
   183  
   184  const responseCeTaskSuccess = `{
   185      "task": {
   186          "id": "AXe5y_ZMPMpzvP5DRxw_",
   187          "type": "REPORT",
   188          "componentId": "AW8jANn5v4pDRYwyZIiM",
   189          "componentKey": "Piper-Validation/Golang",
   190          "componentName": "Piper-Validation: Golang",
   191          "componentQualifier": "TRK",
   192          "analysisId": "AXe5y_mgcqEbAZBpFc0V",
   193          "status": "SUCCESS",
   194          "submittedAt": "2021-02-19T10:18:07+0000",
   195          "submitterLogin": "CCFenner",
   196          "startedAt": "2021-02-19T10:18:08+0000",
   197          "executedAt": "2021-02-19T10:18:09+0000",
   198          "executionTimeMs": 551,
   199          "logs": false,
   200          "hasScannerContext": true,
   201          "organization": "default-organization",
   202          "warningCount": 1,
   203          "warnings": [
   204              "The project key ‘Piper-Validation/Golang’ contains invalid characters. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit. You should update the project key with the expected format."
   205          ]
   206      }
   207  }`
   208  
   209  const responseCeTaskFailure = `{
   210      "task": {
   211          "organization": "my-org-1",
   212          "id": "AVAn5RKqYwETbXvgas-I",
   213          "type": "REPORT",
   214          "componentId": "AVAn5RJmYwETbXvgas-H",
   215          "componentKey": "project_1",
   216          "componentName": "Project One",
   217          "componentQualifier": "TRK",
   218          "analysisId": "123456",
   219          "status": "FAILED",
   220          "submittedAt": "2015-10-02T11:32:15+0200",
   221          "startedAt": "2015-10-02T11:32:16+0200",
   222          "executedAt": "2015-10-02T11:32:22+0200",
   223          "executionTimeMs": 5286,
   224          "errorMessage": "Fail to extract report AVaXuGAi_te3Ldc_YItm from database",
   225          "logs": false,
   226          "hasErrorStacktrace": true,
   227          "errorStacktrace": "java.lang.IllegalStateException: Fail to extract report AVaXuGAi_te3Ldc_YItm from database\n\tat org.sonar.server.computation.task.projectanalysis.step.ExtractReportStep.execute(ExtractReportStep.java:50)",
   228          "scannerContext": "SonarQube plugins:\n\t- Git 1.0 (scmgit)\n\t- Java 3.13.1 (java)",
   229          "hasScannerContext": true
   230      }
   231  }`