@@ -4050,3 +4050,170 @@ func Test_CreateScanWithExistingProjectAssign_to_Application_FF_DirectAssociatio
40504050 }
40514051 assert .Equal (t , strings .Contains (stdoutString , "Successfully updated the application" ), true , "Expected output: %s" , "Successfully updated the application" )
40524052}
4053+
4054+ // TestIsTarFileReference tests the tar file detection logic.
4055+ // Container-security scan-type related test function.
4056+ func TestIsTarFileReference (t * testing.T ) {
4057+ testCases := []struct {
4058+ name string
4059+ imageRef string
4060+ expected bool
4061+ }{
4062+ // Tar files (various formats)
4063+ {"Simple tar" , "alpine.tar" , true },
4064+ {"Tar with path" , "/path/to/image.tar" , true },
4065+ {"Tar case insensitive" , "image.TAR" , true },
4066+ {"Tar with quotes" , "'alpine.tar'" , true },
4067+ {"Tar multiple dots" , "alpine.3.18.0.tar" , true },
4068+
4069+ // Prefixed tar files
4070+ {"docker-archive tar" , "docker-archive:alpine.tar" , true },
4071+ {"oci-archive tar" , "oci-archive:image.tar" , true },
4072+ {"file prefix tar" , "file:myimage.tar" , true },
4073+ {"oci-dir tar" , "oci-dir:image.tar" , true },
4074+
4075+ // Non-tar images
4076+ {"Image with tag" , "nginx:latest" , false },
4077+ {"Image with registry" , "registry.io/namespace/image:v1.0" , false },
4078+ {"Compressed tar.gz" , "image.tar.gz" , false },
4079+
4080+ // Prefixed non-tar images
4081+ {"docker-archive image" , "docker-archive:nginx:latest" , false },
4082+ {"docker daemon image" , "docker:nginx:latest" , false },
4083+ {"registry image" , "registry:ubuntu:20.04" , false },
4084+ {"oci-dir with directory:tag" , "oci-dir:/path/to/dir:latest" , false },
4085+
4086+ // Invalid: tar file cannot have tag
4087+ {"Invalid tar with tag" , "oci-dir:image.tar:latest" , false },
4088+ }
4089+
4090+ for _ , tc := range testCases {
4091+ t .Run (tc .name , func (t * testing.T ) {
4092+ if result := isTarFileReference (tc .imageRef ); result != tc .expected {
4093+ t .Errorf ("Expected %v for '%s', got %v" , tc .expected , tc .imageRef , result )
4094+ }
4095+ })
4096+ }
4097+ }
4098+
4099+ // TestEnforceLocalResolutionForTarFiles tests the automatic enforcement of local resolution when tar files are detected.
4100+ // Container-security scan-type related test function.
4101+ func TestEnforceLocalResolutionForTarFiles (t * testing.T ) {
4102+ testCases := []struct {
4103+ name string
4104+ containerImages string
4105+ initialLocalResolution bool
4106+ expectedLocalResolution bool
4107+ expectWarning bool
4108+ }{
4109+ // No action needed
4110+ {"Empty images" , "" , false , false , false },
4111+ {"Already enabled" , "alpine.tar" , true , true , false },
4112+ {"Only image:tag" , "nginx:latest,alpine:3.18" , false , false , false },
4113+ {"Non-tar prefixes" , "docker:nginx:latest,registry:ubuntu:22.04" , false , false , false },
4114+ {"Invalid tar:tag format" , "oci-dir:file.tar:latest" , false , false , false },
4115+
4116+ // Should enable local resolution
4117+ {"Single tar" , "alpine.tar" , false , true , true },
4118+ {"Mixed tar+image" , "nginx:latest,alpine.tar" , false , true , true },
4119+ {"Tar with spaces/quotes" , " 'alpine.tar' ,nginx:latest" , false , true , true },
4120+ {"Prefixed tar" , "docker-archive:alpine.tar" , false , true , true },
4121+ {"oci-dir tar" , "oci-dir:image.tar" , false , true , true },
4122+ {"Tar at end" , "nginx:latest,ubuntu.tar" , false , true , true },
4123+ }
4124+
4125+ for _ , tc := range testCases {
4126+ tc := tc
4127+ t .Run (tc .name , func (t * testing.T ) {
4128+ // Create a mock command
4129+ cmd := & cobra.Command {}
4130+ cmd .Flags ().String (commonParams .ContainerImagesFlag , "" , "" )
4131+ cmd .Flags ().Bool (commonParams .ContainerResolveLocallyFlag , false , "" )
4132+
4133+ // Set the initial flag values
4134+ _ = cmd .Flags ().Set (commonParams .ContainerImagesFlag , tc .containerImages )
4135+ _ = cmd .Flags ().Set (commonParams .ContainerResolveLocallyFlag , fmt .Sprintf ("%v" , tc .initialLocalResolution ))
4136+
4137+ // Capture output to check for warning message
4138+ oldStdout := os .Stdout
4139+ r , w , _ := os .Pipe ()
4140+ os .Stdout = w
4141+
4142+ // Run the function
4143+ err := enforceLocalResolutionForTarFiles (cmd )
4144+
4145+ // Restore stdout
4146+ w .Close ()
4147+ os .Stdout = oldStdout
4148+ var buf bytes.Buffer
4149+ _ , _ = io .Copy (& buf , r )
4150+ output := buf .String ()
4151+
4152+ // Validate results
4153+ if err != nil {
4154+ t .Errorf ("Unexpected error: %v" , err )
4155+ }
4156+
4157+ actualLocalResolution , _ := cmd .Flags ().GetBool (commonParams .ContainerResolveLocallyFlag )
4158+ if actualLocalResolution != tc .expectedLocalResolution {
4159+ t .Errorf ("Expected local resolution=%v, got=%v" , tc .expectedLocalResolution , actualLocalResolution )
4160+ }
4161+
4162+ hasWarning := strings .Contains (output , "Warning:" ) && strings .Contains (output , "Tar file" )
4163+ if tc .expectWarning && ! hasWarning {
4164+ t .Errorf ("Expected warning but got: %s" , output )
4165+ } else if ! tc .expectWarning && hasWarning {
4166+ t .Errorf ("Unexpected warning: %s" , output )
4167+ }
4168+ })
4169+ }
4170+ }
4171+
4172+ // TestEnforceLocalResolutionForTarFiles_Integration tests the integration with scan create command.
4173+ // Container-security scan-type related test function.
4174+ func TestEnforceLocalResolutionForTarFiles_Integration (t * testing.T ) {
4175+ tempDir := t .TempDir ()
4176+ tarFile := filepath .Join (tempDir , "test.tar" )
4177+ if file , err := os .Create (tarFile ); err != nil {
4178+ t .Fatalf ("Failed to create test tar: %v" , err )
4179+ } else {
4180+ file .Close ()
4181+ }
4182+
4183+ testCases := []struct {
4184+ name string
4185+ images string
4186+ addFlag bool
4187+ expectWarn bool
4188+ }{
4189+ {"Tar without flag" , tarFile , false , true },
4190+ {"Tar with flag" , tarFile , true , false },
4191+ {"Image without flag" , "nginx:latest" , false , false },
4192+ {"Mixed without flag" , tarFile + ",nginx:latest" , false , true },
4193+ }
4194+
4195+ for _ , tc := range testCases {
4196+ t .Run (tc .name , func (t * testing.T ) {
4197+ args := []string {"scan" , "create" , "--project-name" , "MOCK" , "-s" , "." ,
4198+ "-b" , "test-branch" , "--scan-types" , "containers" , "--container-images" , tc .images }
4199+ if tc .addFlag {
4200+ args = append (args , "--containers-local-resolution" )
4201+ }
4202+
4203+ oldStdout := os .Stdout
4204+ r , w , _ := os .Pipe ()
4205+ os .Stdout = w
4206+ execCmdNilAssertion (t , args ... )
4207+ w .Close ()
4208+ os .Stdout = oldStdout
4209+
4210+ var buf bytes.Buffer
4211+ _ , _ = io .Copy (& buf , r )
4212+ hasWarning := strings .Contains (buf .String (), "Warning:" ) && strings .Contains (buf .String (), "Tar file" )
4213+
4214+ if tc .expectWarn != hasWarning {
4215+ t .Errorf ("Expected warning=%v, got=%v" , tc .expectWarn , hasWarning )
4216+ }
4217+ })
4218+ }
4219+ }
0 commit comments