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 }`