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