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 }