github.com/aquasecurity/trivy-iac@v0.8.1-0.20240127024015-3d8e412cf0ab/pkg/scanners/helm/test/parser_test.go (about)

     1  package test
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/aquasecurity/trivy-iac/pkg/detection"
    11  	"github.com/aquasecurity/trivy-iac/pkg/scanners/helm/parser"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func Test_helm_parser(t *testing.T) {
    17  
    18  	tests := []struct {
    19  		testName  string
    20  		chartName string
    21  	}{
    22  		{
    23  			testName:  "Parsing directory 'testchart'",
    24  			chartName: "testchart",
    25  		},
    26  		{
    27  			testName:  "Parsing directory with tarred dependency",
    28  			chartName: "with-tarred-dep",
    29  		},
    30  	}
    31  
    32  	for _, test := range tests {
    33  		t.Run(test.testName, func(t *testing.T) {
    34  			chartName := test.chartName
    35  
    36  			t.Logf("Running test: %s", test.testName)
    37  
    38  			helmParser := parser.New(chartName)
    39  			err := helmParser.ParseFS(context.TODO(), os.DirFS(filepath.Join("testdata", chartName)), ".")
    40  			require.NoError(t, err)
    41  			manifests, err := helmParser.RenderedChartFiles()
    42  			require.NoError(t, err)
    43  
    44  			assert.Len(t, manifests, 3)
    45  
    46  			for _, manifest := range manifests {
    47  				expectedPath := filepath.Join("testdata", "expected", chartName, manifest.TemplateFilePath)
    48  
    49  				expectedContent, err := os.ReadFile(expectedPath)
    50  				require.NoError(t, err)
    51  
    52  				got := strings.ReplaceAll(manifest.ManifestContent, "\r\n", "\n")
    53  				assert.Equal(t, strings.ReplaceAll(string(expectedContent), "\r\n", "\n"), got)
    54  			}
    55  		})
    56  	}
    57  }
    58  
    59  func Test_helm_parser_where_name_non_string(t *testing.T) {
    60  
    61  	tests := []struct {
    62  		testName  string
    63  		chartName string
    64  	}{
    65  		{
    66  			testName:  "Scanning chart with integer for name",
    67  			chartName: "numberName",
    68  		},
    69  	}
    70  
    71  	for _, test := range tests {
    72  		chartName := test.chartName
    73  
    74  		t.Logf("Running test: %s", test.testName)
    75  
    76  		helmParser := parser.New(chartName)
    77  		err := helmParser.ParseFS(context.TODO(), os.DirFS(filepath.Join("testdata", chartName)), ".")
    78  		require.NoError(t, err)
    79  	}
    80  }
    81  
    82  func Test_tar_is_chart(t *testing.T) {
    83  
    84  	tests := []struct {
    85  		testName    string
    86  		archiveFile string
    87  		isHelmChart bool
    88  	}{
    89  		{
    90  			testName:    "standard tarball",
    91  			archiveFile: "mysql-8.8.26.tar",
    92  			isHelmChart: true,
    93  		},
    94  		{
    95  			testName:    "gzip tarball with tar.gz extension",
    96  			archiveFile: "mysql-8.8.26.tar.gz",
    97  			isHelmChart: true,
    98  		},
    99  		{
   100  			testName:    "broken gzip tarball with tar.gz extension",
   101  			archiveFile: "aws-cluster-autoscaler-bad.tar.gz",
   102  			isHelmChart: true,
   103  		},
   104  		{
   105  			testName:    "gzip tarball with tgz extension",
   106  			archiveFile: "mysql-8.8.26.tgz",
   107  			isHelmChart: true,
   108  		},
   109  		{
   110  			testName:    "gzip tarball that has nothing of interest in it",
   111  			archiveFile: "nope.tgz",
   112  			isHelmChart: false,
   113  		},
   114  	}
   115  
   116  	for _, test := range tests {
   117  
   118  		t.Logf("Running test: %s", test.testName)
   119  		testPath := filepath.Join("testdata", test.archiveFile)
   120  		file, err := os.Open(testPath)
   121  		defer func() { _ = file.Close() }()
   122  		require.NoError(t, err)
   123  
   124  		assert.Equal(t, test.isHelmChart, detection.IsHelmChartArchive(test.archiveFile, file))
   125  
   126  		_ = file.Close()
   127  	}
   128  }
   129  
   130  func Test_helm_tarball_parser(t *testing.T) {
   131  
   132  	tests := []struct {
   133  		testName    string
   134  		chartName   string
   135  		archiveFile string
   136  	}{
   137  		{
   138  			testName:    "standard tarball",
   139  			chartName:   "mysql",
   140  			archiveFile: "mysql-8.8.26.tar",
   141  		},
   142  		{
   143  			testName:    "gzip tarball with tar.gz extension",
   144  			chartName:   "mysql",
   145  			archiveFile: "mysql-8.8.26.tar.gz",
   146  		},
   147  		{
   148  			testName:    "gzip tarball with tgz extension",
   149  			chartName:   "mysql",
   150  			archiveFile: "mysql-8.8.26.tgz",
   151  		},
   152  	}
   153  
   154  	for _, test := range tests {
   155  
   156  		t.Logf("Running test: %s", test.testName)
   157  
   158  		testPath := filepath.Join("testdata", test.archiveFile)
   159  
   160  		testTemp := t.TempDir()
   161  		testFileName := filepath.Join(testTemp, test.archiveFile)
   162  		require.NoError(t, copyArchive(testPath, testFileName))
   163  
   164  		testFs := os.DirFS(testTemp)
   165  
   166  		helmParser := parser.New(test.archiveFile)
   167  		err := helmParser.ParseFS(context.TODO(), testFs, ".")
   168  		require.NoError(t, err)
   169  
   170  		manifests, err := helmParser.RenderedChartFiles()
   171  		require.NoError(t, err)
   172  
   173  		assert.Len(t, manifests, 6)
   174  
   175  		oneOf := []string{
   176  			"configmap.yaml",
   177  			"statefulset.yaml",
   178  			"svc-headless.yaml",
   179  			"svc.yaml",
   180  			"secrets.yaml",
   181  			"serviceaccount.yaml",
   182  		}
   183  
   184  		for _, manifest := range manifests {
   185  			filename := filepath.Base(manifest.TemplateFilePath)
   186  			assert.Contains(t, oneOf, filename)
   187  
   188  			if strings.HasSuffix(manifest.TemplateFilePath, "secrets.yaml") {
   189  				continue
   190  			}
   191  			expectedPath := filepath.Join("testdata", "expected", test.chartName, manifest.TemplateFilePath)
   192  
   193  			expectedContent, err := os.ReadFile(expectedPath)
   194  			require.NoError(t, err)
   195  
   196  			assert.Equal(t, strings.ReplaceAll(string(expectedContent), "\r\n", "\n"), strings.ReplaceAll(manifest.ManifestContent, "\r\n", "\n"))
   197  		}
   198  	}
   199  }