Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions internal/services/sast-metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package services

import (
"context"
"errors"
"strings"
"sync"

Expand All @@ -11,7 +12,8 @@ import (
)

const (
BatchSize = 200
// BatchSize must not exceed the sast-metadata backend's per-request scan-ids cap (currently 50).
BatchSize = 50
)

func GetSastMetadataByIDs(sastMetaDataWrapper wrappers.SastMetadataWrapper, scanIDs []string) (*wrappers.SastMetadataModel, error) {
Expand All @@ -21,7 +23,7 @@ func GetSastMetadataByIDs(sastMetaDataWrapper wrappers.SastMetadataWrapper, scan

var wg sync.WaitGroup
results := make(chan wrappers.SastMetadataModel, totalBatches)
errors := make(chan error, totalBatches)
errCh := make(chan error, totalBatches)
ctx := context.Background()

for i := 0; i < totalBatches; i++ {
Expand All @@ -46,21 +48,23 @@ func GetSastMetadataByIDs(sastMetaDataWrapper wrappers.SastMetadataWrapper, scan

result, err := sastMetaDataWrapper.GetSastMetadataByIDs(batchParams)
if err != nil {
errors <- err
errCh <- err
return
}
results <- *result
}()
}

go func() {
wg.Wait()
close(results)
close(errors)
}()
wg.Wait()
close(results)
close(errCh)

if len(errors) > 0 {
return nil, <-errors
if len(errCh) > 0 {
var batchErrs []error
for batchErr := range errCh {
batchErrs = append(batchErrs, batchErr)
}
return nil, errors.Join(batchErrs...)
Comment thread
cx-harshjeet-patil marked this conversation as resolved.
}

var models []wrappers.SastMetadataModel
Expand Down
22 changes: 22 additions & 0 deletions internal/services/sast-metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,28 @@ func TestGetSastMetadataByIDs(t *testing.T) {
}
}

func TestGetSastMetadataByIDs_BatchFailureIsSurfacedNotPanicked(t *testing.T) {
// A failing batch must be reliably surfaced as an error, not raced past or dereferenced as nil.
scanIDs := append(createScanIDs(BatchSize), createErrorScanIDs(BatchSize)...)
scanIDs = append(scanIDs, createScanIDs(BatchSize)...)

wrapper := &mock.SastMetadataMockWrapper{}
actual, err := GetSastMetadataByIDs(wrapper, scanIDs)

assert.Nil(t, actual)
if assert.Error(t, err) {
assert.Contains(t, err.Error(), "Too many ids in url")
}
}

func createErrorScanIDs(count int) []string {
scanIDs := make([]string, count)
for i := 0; i < count; i++ {
scanIDs[i] = fmt.Sprintf("TriggerError%d", i)
}
return scanIDs
}

func createScanIDs(count int) []string {
scanIDs := make([]string, count)
for i := 0; i < count; i++ {
Expand Down
11 changes: 9 additions & 2 deletions internal/wrappers/mock/sast-metadata-mock.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mock

import (
"fmt"
"strings"

"github.com/checkmarx/ast-cli/internal/wrappers"
Expand All @@ -10,8 +11,11 @@ import (
type SastMetadataMockWrapper struct{}

const (
scanIDParam = "scan-ids"
concurrent = "ConcurrentTest"
scanIDParam = "scan-ids"
concurrent = "ConcurrentTest"
errorTrigger = "TriggerError"
tooManyIDsErrorCode = 3102
tooManyIDsMessage = "Too many ids in url"
// FakeMetadataErrorID is used to trigger error responses in mock SAST metadata calls.
FakeMetadataErrorID = "fake-sast-metadata-error-id"
// FakeMetadataEmptyID is used to trigger empty responses in mock SAST metadata calls.
Expand All @@ -22,6 +26,9 @@ func (s SastMetadataMockWrapper) GetSastMetadataByIDs(params map[string]string)
*wrappers.SastMetadataModel,
error,
) {
if strings.Contains(params[scanIDParam], errorTrigger) {
return nil, fmt.Errorf("%d - %s", tooManyIDsErrorCode, tooManyIDsMessage)
}
if strings.Contains(params[scanIDParam], FakeMetadataErrorID) {
return nil, errors.New("fake sast metadata fetch error")
}
Expand Down
9 changes: 3 additions & 6 deletions internal/wrappers/sast-metadata-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,10 @@ func (s *SastIncrementalHTTPWrapper) GetSastMetadataByIDs(params map[string]stri
if err != nil {
return nil, err
}
decoder := json.NewDecoder(resp.Body)

defer func() {
if err == nil {
_ = resp.Body.Close()
}
_ = resp.Body.Close()
}()
decoder := json.NewDecoder(resp.Body)

switch resp.StatusCode {
case http.StatusBadRequest, http.StatusInternalServerError:
Expand All @@ -42,7 +39,7 @@ func (s *SastIncrementalHTTPWrapper) GetSastMetadataByIDs(params map[string]stri
if err != nil {
return nil, fmt.Errorf("%v %s", err, failedToParseGetAll)
}
return nil, err
return nil, fmt.Errorf("%d - %s", errorModel.Code, errorModel.Message)
Comment thread
cx-harshjeet-patil marked this conversation as resolved.
case http.StatusOK:
model := SastMetadataModel{}
err = decoder.Decode(&model)
Expand Down
Loading