Skip to content

Commit 06bb69c

Browse files
fix unit test cases and lint issue
1 parent 1efdf4b commit 06bb69c

File tree

3 files changed

+101
-63
lines changed

3 files changed

+101
-63
lines changed

internal/commands/scan_test.go

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,15 +2972,31 @@ func TestResubmitConfig_ProjectDoesNotExist_ReturnedEmptyConfig(t *testing.T) {
29722972
func TestUploadZip_whenUserProvideZip_shouldReturnEmptyZipFilePathInSuccessCase(t *testing.T) {
29732973
uploadWrapper := mock.UploadsMockWrapper{}
29742974
featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{}
2975-
_, zipPath, err := uploadZip(&uploadWrapper, "test.zip", false, true, featureFlagsWrapper)
2975+
_, zipPath, err := uploadZip(&uploadWrapper, "data/sources.zip", false, true, featureFlagsWrapper)
29762976
assert.NilError(t, err)
29772977
assert.Equal(t, zipPath, "")
29782978
}
29792979

29802980
func TestUploadZip_whenUserProvideZip_shouldReturnEmptyZipFilePathInFailureCase(t *testing.T) {
2981+
// Create a temporary zip file
2982+
dir := t.TempDir()
2983+
zipPathTemp := filepath.Join(dir, "failureCase.zip")
2984+
2985+
// Create the zip file
2986+
zipFile, err := os.Create(zipPathTemp)
2987+
if err != nil {
2988+
t.Fatalf("Failed to create zip file: %v", err)
2989+
}
2990+
defer func(zipFile *os.File) {
2991+
err := zipFile.Close()
2992+
if err != nil {
2993+
t.Fatalf("Failed to close zip file: %v", err)
2994+
}
2995+
}(zipFile)
2996+
29812997
uploadWrapper := mock.UploadsMockWrapper{}
29822998
featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{}
2983-
_, zipPath, err := uploadZip(&uploadWrapper, "failureCase.zip", false, true, featureFlagsWrapper)
2999+
_, zipPath, err := uploadZip(&uploadWrapper, zipPathTemp, false, true, featureFlagsWrapper)
29843000
assert.Assert(t, err != nil)
29853001
assert.Assert(t, strings.Contains(err.Error(), "error from UploadFile"), err.Error())
29863002
assert.Equal(t, zipPath, "")
@@ -2989,18 +3005,33 @@ func TestUploadZip_whenUserProvideZip_shouldReturnEmptyZipFilePathInFailureCase(
29893005
func TestUploadZip_whenUserNotProvideZip_shouldReturnZipFilePathInSuccessCase(t *testing.T) {
29903006
uploadWrapper := mock.UploadsMockWrapper{}
29913007
featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{}
2992-
_, zipPath, err := uploadZip(&uploadWrapper, "test.zip", false, false, featureFlagsWrapper)
3008+
_, zipPath, err := uploadZip(&uploadWrapper, "data/sources.zip", false, false, featureFlagsWrapper)
29933009
assert.NilError(t, err)
2994-
assert.Equal(t, zipPath, "test.zip")
3010+
assert.Equal(t, zipPath, "data/sources.zip")
29953011
}
29963012

29973013
func TestUploadZip_whenUserNotProvideZip_shouldReturnZipFilePathInFailureCase(t *testing.T) {
3014+
// Create a temporary zip file
3015+
dir := t.TempDir()
3016+
zipPathTemp := filepath.Join(dir, "failureCase.zip")
3017+
3018+
// Create the zip file
3019+
zipFile, err := os.Create(zipPathTemp)
3020+
if err != nil {
3021+
t.Fatalf("Failed to create zip file: %v", err)
3022+
}
3023+
defer func(zipFile *os.File) {
3024+
err := zipFile.Close()
3025+
if err != nil {
3026+
t.Fatalf("Failed to close zip file: %v", err)
3027+
}
3028+
}(zipFile)
29983029
uploadWrapper := mock.UploadsMockWrapper{}
29993030
featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{}
3000-
_, zipPath, err := uploadZip(&uploadWrapper, "failureCase.zip", false, false, featureFlagsWrapper)
3031+
_, zipPath, err := uploadZip(&uploadWrapper, zipPathTemp, false, false, featureFlagsWrapper)
30013032
assert.Assert(t, err != nil)
30023033
assert.Assert(t, strings.Contains(err.Error(), "error from UploadFile"), err.Error())
3003-
assert.Equal(t, zipPath, "failureCase.zip")
3034+
assert.Equal(t, zipPath, zipPathTemp)
30043035
}
30053036

30063037
func TestAddSastScan_ScanFlags(t *testing.T) {

internal/wrappers/mock/uploads-mock.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package mock
22

33
import (
44
"fmt"
5+
"strings"
56

67
"github.com/pkg/errors"
78

@@ -11,18 +12,18 @@ import (
1112
type UploadsMockWrapper struct {
1213
}
1314

14-
func (u *UploadsMockWrapper) UploadFileInMultipart(path string, wrapper wrappers.FeatureFlagsWrapper) (*string, error) {
15-
fmt.Println("Called Create in UploadsMockWrapper")
16-
if path == "failureCase.zip" {
15+
func (u *UploadsMockWrapper) UploadFileInMultipart(filePath string, wrapper wrappers.FeatureFlagsWrapper) (*string, error) {
16+
fmt.Println("UploadFileInMultipart called Create in UploadsMockWrapper")
17+
if filePath == "failureCase2.zip" {
1718
return nil, errors.New("error from UploadFileInMultipart")
1819
}
19-
url := "/path/to/nowhere"
20+
url := "/path/to/largeZipFile"
2021
return &url, nil
2122
}
2223

2324
func (u *UploadsMockWrapper) UploadFile(filePath string, featureFlagsWrapper wrappers.FeatureFlagsWrapper) (*string, error) {
2425
fmt.Println("Called Create in UploadsMockWrapper")
25-
if filePath == "failureCase.zip" {
26+
if strings.Contains(filePath, "failureCase.zip") {
2627
return nil, errors.New("error from UploadFile")
2728
}
2829
url := "/path/to/nowhere"

internal/wrappers/uploads-http.go

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type StartMultipartUploadResponse struct {
3333
type StartMultipartUploadRequest struct {
3434
FileSize int64 `json:"fileSize"`
3535
}
36-
type MultipartPresignedURl struct {
36+
type MultipartPresignedURL struct {
3737
ObjectName string `json:"objectName"`
3838
UploadID string `json:"UploadID"`
3939
PartNumber int `json:"partNumber"`
@@ -225,6 +225,9 @@ func (u *UploadsHTTPWrapper) UploadFileInMultipart(sourcesFile string, featureFl
225225
clientTimeout := viper.GetUint(commonParams.ClientTimeoutKey)
226226
path := viper.GetString(commonParams.CompleteMultipartUploadPathEnv)
227227
jsonBytes, err := json.Marshal(completeMultipartUpload)
228+
if err != nil {
229+
return nil, errors.Errorf("Failed to marshal complete multipart upload request body - %s", err.Error())
230+
}
228231
resp, err := SendHTTPRequest(http.MethodPost, path, bytes.NewBuffer(jsonBytes), true, clientTimeout)
229232
if err != nil {
230233
return nil, err
@@ -252,6 +255,9 @@ func startMultipartUpload(startMultipartUploadRequest StartMultipartUploadReques
252255
clientTimeout := viper.GetUint(commonParams.ClientTimeoutKey)
253256
path := viper.GetString(commonParams.StartMultiPartUploadPathEnv)
254257
jsonBytes, err := json.Marshal(startMultipartUploadRequest)
258+
if err != nil {
259+
return StartMultipartUploadResponse{}, errors.Errorf("Failed to marshal start multipart upload request body - %s", err.Error())
260+
}
255261
resp, err := SendHTTPRequest(http.MethodPost, path, bytes.NewBuffer(jsonBytes), true, clientTimeout)
256262
if err != nil {
257263
return StartMultipartUploadResponse{}, err
@@ -286,12 +292,12 @@ func getPresignedURLForMultipartUploading(response StartMultipartUploadResponse,
286292
clientTimeout := viper.GetUint(commonParams.ClientTimeoutKey)
287293
path := viper.GetString(commonParams.MultipartPresignedPathEnv)
288294

289-
multipartPresignedURl := MultipartPresignedURl{
295+
multipartPresignedURL := MultipartPresignedURL{
290296
ObjectName: response.ObjectName,
291297
UploadID: response.UploadID,
292298
PartNumber: partNumber,
293299
}
294-
jsonBytes, err := json.Marshal(multipartPresignedURl)
300+
jsonBytes, err := json.Marshal(multipartPresignedURL)
295301
if err != nil {
296302
return "", errors.Errorf("Failed to marshal multipart upload presigned URL request body - %s", err.Error())
297303
}
@@ -329,7 +335,7 @@ func getPresignedURLForMultipartUploading(response StartMultipartUploadResponse,
329335
}
330336
}
331337

332-
func uploadPart(preSignedURL string, sourcesFile string, featureFlagsWrapper FeatureFlagsWrapper) (string, error) {
338+
func uploadPart(preSignedURL, sourcesFile string, featureFlagsWrapper FeatureFlagsWrapper) (string, error) {
333339
if preSignedURL == "" {
334340
return "", errors.New("preSignedURL is empty or nil")
335341
}
@@ -383,41 +389,16 @@ func uploadPart(preSignedURL string, sourcesFile string, featureFlagsWrapper Fea
383389
}
384390

385391
func SplitZipBySizeGB(zipFilePath string) ([]string, error) {
386-
387-
// Get part size in GB from config if config is not provided, default to 2 GB
388-
partChunkSizeStr := viper.GetString(commonParams.MultipartFileSize)
389-
partChunkSizeFloat, err := strconv.ParseFloat(partChunkSizeStr, 64)
392+
partSizeBytes, err := getPartSizeBytes()
390393
if err != nil {
391-
return nil, fmt.Errorf("invalid part size value: %w", err)
392-
}
393-
// Truncate to integer
394-
truncatedSize := int64(partChunkSizeFloat)
395-
if truncatedSize < 1 || truncatedSize > 5 {
396-
// Enforce part size to be between 1 GB and 5 GB.
397-
// If the configured part size is outside this range, default to 2 GB.
398-
logger.PrintIfVerbose(fmt.Sprintf("Configured part size %d GB is outside the allowed range (1 – 5 GB). Defaulting to 2 GB.", truncatedSize))
399-
truncatedSize = 2 // default to 2 GB if out of range
400-
}
401-
partSizeGB := float64(truncatedSize)
402-
403-
logger.PrintIfVerbose("Splitting zip file into parts of size: " + fmt.Sprintf("%.0f", partSizeGB) + " GB")
404-
405-
if partSizeGB <= 0 {
406-
return nil, fmt.Errorf("part size must be greater than 0 GB")
394+
return nil, err
407395
}
408396

409-
const bytesPerGB = 1024 * 1024 * 1024
410-
partSizeBytes := int64(partSizeGB * float64(bytesPerGB))
411-
412397
f, err := os.Open(zipFilePath)
413398
if err != nil {
414399
return nil, fmt.Errorf("open input - %w", err)
415400
}
416-
defer func() {
417-
if err := f.Close(); err != nil {
418-
logger.PrintfIfVerbose("warning: failed to close input file - %v", err)
419-
}
420-
}()
401+
defer closeFileVerbose(f)
421402

422403
stat, err := f.Stat()
423404
if err != nil {
@@ -427,12 +408,40 @@ func SplitZipBySizeGB(zipFilePath string) ([]string, error) {
427408
return nil, fmt.Errorf("input file is empty")
428409
}
429410

430-
totalSize := stat.Size()
411+
partSizes := calculatePartSizes(stat.Size(), partSizeBytes)
412+
partNames, err := createParts(f, partSizes)
413+
if err != nil {
414+
cleanUpTempParts(partNames)
415+
return nil, err
416+
}
417+
418+
return partNames, nil
419+
}
420+
421+
func getPartSizeBytes() (int64, error) {
422+
// Get part size in GB from config if config is not provided, default to 2 GB
423+
partChunkSizeStr := viper.GetString(commonParams.MultipartFileSize)
424+
partChunkSizeFloat, err := strconv.ParseFloat(partChunkSizeStr, 64)
425+
if err != nil {
426+
return 0, fmt.Errorf("invalid part size value: %w", err)
427+
}
428+
// Truncate to integer
429+
truncatedSize := int64(partChunkSizeFloat)
430+
if truncatedSize < 1 || truncatedSize > 5 {
431+
// Enforce part size to be between 1 GB and 5 GB.
432+
// If the configured part size is outside this range, default to 2 GB.
433+
logger.PrintIfVerbose(fmt.Sprintf("Configured part size %d GB is outside the allowed range (1 – 5 GB). Defaulting to 2 GB.", truncatedSize))
434+
truncatedSize = 2
435+
}
436+
const bytesPerGB = 1024 * 1024 * 1024
437+
return int64(float64(truncatedSize) * float64(bytesPerGB)), nil
438+
}
439+
440+
func calculatePartSizes(totalSize, partSizeBytes int64) []int64 {
431441
numParts := int(totalSize / partSizeBytes)
432442
if totalSize%partSizeBytes != 0 {
433443
numParts++
434444
}
435-
436445
partSizes := make([]int64, numParts)
437446
for i := 0; i < numParts; i++ {
438447
remaining := totalSize - int64(i)*partSizeBytes
@@ -442,21 +451,16 @@ func SplitZipBySizeGB(zipFilePath string) ([]string, error) {
442451
partSizes[i] = remaining
443452
}
444453
}
454+
return partSizes
455+
}
445456

446-
partNames := make([]string, numParts)
447-
for i := 0; i < numParts; i++ {
457+
func createParts(f *os.File, partSizes []int64) ([]string, error) {
458+
partNames := make([]string, len(partSizes))
459+
for i, size := range partSizes {
448460
partFile, err := os.CreateTemp("", fmt.Sprintf("cx-part%d-*", i+1))
449461
if err != nil {
450-
for j := 0; j < i; j++ {
451-
if partNames[j] != "" {
452-
if err := os.Remove(partNames[j]); err != nil && !os.IsNotExist(err) {
453-
logger.PrintfIfVerbose("warning: failed to remove part%d - %v", j+1, err)
454-
}
455-
}
456-
}
457-
return nil, fmt.Errorf("create part%d - %w", i+1, err)
462+
return partNames, fmt.Errorf("create part%d - %w", i+1, err)
458463
}
459-
460464
offset := int64(0)
461465
for j := 0; j < i; j++ {
462466
offset += partSizes[j]
@@ -470,10 +474,9 @@ func SplitZipBySizeGB(zipFilePath string) ([]string, error) {
470474
if err != nil {
471475
return nil, err
472476
}
473-
return nil, fmt.Errorf("seek to part%d - %w", i+1, err)
477+
return partNames, fmt.Errorf("seek to part%d - %w", i+1, err)
474478
}
475-
476-
if _, err := io.CopyN(partFile, f, partSizes[i]); err != nil && err != io.EOF {
479+
if _, err := io.CopyN(partFile, f, size); err != nil && err != io.EOF {
477480
err := partFile.Close()
478481
if err != nil {
479482
return nil, err
@@ -482,22 +485,25 @@ func SplitZipBySizeGB(zipFilePath string) ([]string, error) {
482485
if err != nil {
483486
return nil, err
484487
}
485-
return nil, fmt.Errorf("copy to part%d - %w", i+1, err)
488+
return partNames, fmt.Errorf("copy to part%d - %w", i+1, err)
486489
}
487-
488490
if err := partFile.Sync(); err != nil {
489491
logger.PrintfIfVerbose("warning: failed to sync part%d - %v", i+1, err)
490492
}
491493
if err := partFile.Close(); err != nil {
492494
logger.PrintfIfVerbose("warning: failed to close part%d - %v", i+1, err)
493495
}
494-
495496
partNames[i] = partFile.Name()
496497
}
497-
498498
return partNames, nil
499499
}
500500

501+
func closeFileVerbose(f *os.File) {
502+
if err := f.Close(); err != nil {
503+
logger.PrintfIfVerbose("warning: failed to close input file - %v", err)
504+
}
505+
}
506+
501507
// cleanUpTempParts removes the temporary part files created during multipart upload.
502508
func cleanUpTempParts(partList []string) {
503509
cleanupMaxRetries := 3

0 commit comments

Comments
 (0)