github.com/SAP/jenkins-library@v1.362.0/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  }