github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/cmd/malwareExecuteScan_test.go (about) 1 //go:build unit 2 // +build unit 3 4 package cmd 5 6 import ( 7 "io" 8 "os" 9 "testing" 10 11 v1 "github.com/google/go-containerregistry/pkg/v1" 12 "github.com/google/go-containerregistry/pkg/v1/fake" 13 14 piperDocker "github.com/SAP/jenkins-library/pkg/docker" 15 "github.com/SAP/jenkins-library/pkg/malwarescan" 16 "github.com/SAP/jenkins-library/pkg/mock" 17 "github.com/stretchr/testify/assert" 18 ) 19 20 var malwareScanConfig = malwareExecuteScanOptions{ 21 Host: "https://example.org/malwarescanner", 22 Username: "me", 23 Password: "********", 24 ScanFile: "target/myFile", 25 Timeout: "60", 26 } 27 28 type malwareScanUtilsMockBundle struct { 29 *mock.FilesMock 30 31 returnScanResult *malwarescan.ScanResult 32 returnSHA256 string 33 } 34 35 func (utils *malwareScanUtilsMockBundle) SHA256(filePath string) (string, error) { 36 if utils.returnSHA256 == "" { 37 return utils.returnScanResult.SHA256, nil 38 } 39 40 return utils.returnSHA256, nil 41 } 42 43 func (utils *malwareScanUtilsMockBundle) OpenFile(path string, flag int, perm os.FileMode) (io.ReadCloser, error) { 44 return utils.FilesMock.OpenFile(path, flag, perm) 45 } 46 47 func (utils *malwareScanUtilsMockBundle) FileWrite(path string, content []byte, perm os.FileMode) error { 48 return utils.FilesMock.FileWrite(path, content, perm) 49 } 50 51 func (utils *malwareScanUtilsMockBundle) Info() (*malwarescan.Info, error) { 52 return &malwarescan.Info{EngineVersion: "Mock Malware Scanner", SignatureTimestamp: "n/a"}, nil 53 } 54 55 func (utils *malwareScanUtilsMockBundle) Scan(candidate io.Reader) (*malwarescan.ScanResult, error) { 56 return utils.returnScanResult, nil 57 } 58 59 func (utils *malwareScanUtilsMockBundle) newDockerClient(options piperDocker.ClientOptions) piperDocker.Download { 60 return &dockerClientMock{imageName: options.ImageName, registryURL: options.RegistryURL, localPath: options.LocalPath} 61 } 62 63 func TestMalwareScanWithNoBuildtool(t *testing.T) { 64 files := &mock.FilesMock{} 65 files.AddFile("target/myFile", []byte(`HELLO`)) 66 67 utils := malwareScanUtilsMockBundle{ 68 FilesMock: files, 69 } 70 71 t.Run("No malware, no encrypted content in file", func(t *testing.T) { 72 utils.returnScanResult = &malwarescan.ScanResult{ 73 MalwareDetected: false, 74 EncryptedContentDetected: false, 75 ScanSize: 298782, 76 MimeType: "application/octet-stream", 77 SHA256: "96ca802fbd54d31903f1115a1d95590c685160637d9262bd340ab30d0f817e85", 78 } 79 80 error := runMalwareScan(&malwareScanConfig, nil, &utils) 81 82 assert.NoError(t, error) 83 }) 84 85 t.Run("Malware detected in file", func(t *testing.T) { 86 utils.returnScanResult = &malwarescan.ScanResult{ 87 MalwareDetected: true, 88 EncryptedContentDetected: false, 89 ScanSize: 298782, 90 MimeType: "application/octet-stream", 91 SHA256: "96ca802fbd54d31903f1115a1d95590c685160637d9262bd340ab30d0f817e85", 92 Finding: "Win.Test.EICAR_HDB-1", 93 } 94 95 error := runMalwareScan(&malwareScanConfig, nil, &utils) 96 assert.EqualError(t, error, "Malware scan failed for file 'target/myFile'. Malware detected: true, encrypted content detected: false, finding: Win.Test.EICAR_HDB-1") 97 }) 98 99 t.Run("Encrypted content detected in file", func(t *testing.T) { 100 utils.returnScanResult = &malwarescan.ScanResult{ 101 MalwareDetected: false, 102 EncryptedContentDetected: true, 103 ScanSize: 298782, 104 MimeType: "application/octet-stream", 105 SHA256: "96ca802fbd54d31903f1115a1d95590c685160637d9262bd340ab30d0f817e85", 106 } 107 108 error := runMalwareScan(&malwareScanConfig, nil, &utils) 109 assert.EqualError(t, error, "Malware scan failed for file 'target/myFile'. Malware detected: false, encrypted content detected: true, finding: ") 110 }) 111 112 t.Run("Malware and encrypted content detected in file", func(t *testing.T) { 113 utils.returnScanResult = &malwarescan.ScanResult{ 114 MalwareDetected: true, 115 EncryptedContentDetected: true, 116 ScanSize: 298782, 117 MimeType: "application/octet-stream", 118 SHA256: "96ca802fbd54d31903f1115a1d95590c685160637d9262bd340ab30d0f817e85", 119 Finding: "Win.Test.EICAR_HDB-1", 120 } 121 122 error := runMalwareScan(&malwareScanConfig, nil, &utils) 123 assert.EqualError(t, error, "Malware scan failed for file 'target/myFile'. Malware detected: true, encrypted content detected: true, finding: Win.Test.EICAR_HDB-1") 124 }) 125 126 t.Run("No file and no buildtool specified", func(t *testing.T) { 127 malwareScanConfig := malwareExecuteScanOptions{ 128 Host: "https://example.org/malwarescanner", 129 Username: "me", 130 Password: "********", 131 Timeout: "60", 132 } 133 134 error := runMalwareScan(&malwareScanConfig, nil, nil) 135 assert.EqualError(t, error, "Please specify a file to be scanned") 136 }) 137 138 t.Run("File to be scanned, can't be found", func(t *testing.T) { 139 utils.returnScanResult = nil 140 141 malwareScanConfig := malwareExecuteScanOptions{ 142 Host: "https://example.org/malwarescanner", 143 Username: "me", 144 Password: "********", 145 Timeout: "60", 146 ScanFile: "target/fileWhichDoesntExist", 147 } 148 149 error := runMalwareScan(&malwareScanConfig, nil, &utils) 150 assert.EqualError(t, error, "the file 'target/fileWhichDoesntExist' does not exist: file does not exist") 151 }) 152 } 153 154 func TestMalwareScanWithDockerAsBuildtoolTests(t *testing.T) { 155 files := &mock.FilesMock{} 156 files.AddFile("dockerimagename_latest.tar", []byte(``)) 157 158 utils := malwareScanUtilsMockBundle{ 159 FilesMock: files, 160 } 161 162 t.Run("No malware detected in docker image", func(t *testing.T) { 163 utils.returnScanResult = &malwarescan.ScanResult{ 164 MalwareDetected: false, 165 EncryptedContentDetected: false, 166 ScanSize: 298782, 167 MimeType: "application/octet-stream", 168 SHA256: "96ca802fbd54d31903f1115a1d95590c685160637d9262bd340ab30d0f817e85", 169 } 170 171 malwareScanConfig := malwareExecuteScanOptions{ 172 Host: "https://example.org/malwarescanner", 173 Username: "me", 174 Password: "********", 175 Timeout: "60", 176 BuildTool: "docker", 177 ScanImage: "dockerimagename:latest", 178 } 179 180 error := runMalwareScan(&malwareScanConfig, nil, &utils) 181 182 assert.NoError(t, error) 183 }) 184 185 t.Run("No file and no buildtool specified", func(t *testing.T) { 186 malwareScanConfig := malwareExecuteScanOptions{ 187 Host: "https://example.org/malwarescanner", 188 Username: "me", 189 Password: "********", 190 Timeout: "60", 191 } 192 193 error := runMalwareScan(&malwareScanConfig, nil, &utils) 194 assert.EqualError(t, error, "Please specify a file to be scanned") 195 }) 196 } 197 198 func TestMalwareScanWithOtherBuildtoolTests(t *testing.T) { 199 files := &mock.FilesMock{} 200 files.AddFile("dockerimagename_latest.tar", []byte(``)) 201 202 utils := malwareScanUtilsMockBundle{ 203 FilesMock: files, 204 } 205 206 t.Run("No malware detected in docker image", func(t *testing.T) { 207 utils.returnScanResult = &malwarescan.ScanResult{ 208 MalwareDetected: false, 209 EncryptedContentDetected: false, 210 ScanSize: 298782, 211 MimeType: "application/octet-stream", 212 SHA256: "96ca802fbd54d31903f1115a1d95590c685160637d9262bd340ab30d0f817e85", 213 } 214 215 malwareScanConfig := malwareExecuteScanOptions{ 216 Host: "https://example.org/malwarescanner", 217 Username: "me", 218 Password: "********", 219 Timeout: "60", 220 BuildTool: "golang", 221 ScanImage: "dockerimagename:latest", 222 } 223 224 error := runMalwareScan(&malwareScanConfig, nil, &utils) 225 226 assert.NoError(t, error) 227 }) 228 } 229 230 type dockerClientMock struct { 231 imageName string 232 registryURL string 233 localPath string 234 } 235 236 // DownloadImage download the image to the specified path 237 func (c *dockerClientMock) DownloadImage(imageSource, filePath string) (v1.Image, error) { 238 return &fake.FakeImage{}, nil // fmt.Errorf("%s", filePath) 239 } 240 241 // DownloadImage download the image to the specified path 242 func (c *dockerClientMock) DownloadImageContent(imageSource, filePath string) (v1.Image, error) { 243 return &fake.FakeImage{}, nil // fmt.Errorf("%s", filePath) 244 } 245 246 // GetRemoteImageInfo return remote image information 247 func (c *dockerClientMock) GetRemoteImageInfo(imageSoure string) (v1.Image, error) { 248 return &fake.FakeImage{}, nil 249 }