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