github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/sonar/taskService_test.go (about)

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