github.com/jenkins-x/jx/v2@v2.1.155/pkg/helm/helm_template_test.go (about)

     1  // +build unit
     2  
     3  package helm
     4  
     5  import (
     6  	"io/ioutil"
     7  	"os"
     8  	"path"
     9  	"path/filepath"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/stretchr/testify/require"
    14  
    15  	"k8s.io/helm/pkg/proto/hapi/chart"
    16  
    17  	"github.com/ghodss/yaml"
    18  	"github.com/jenkins-x/jx/v2/pkg/util"
    19  	"github.com/stretchr/testify/assert"
    20  	corev1 "k8s.io/api/core/v1"
    21  )
    22  
    23  func TestAddYamlLabels(t *testing.T) {
    24  	t.Parallel()
    25  
    26  	baseDir, err := ioutil.TempDir("", "test-add-yaml-labels")
    27  	assert.NoError(t, err)
    28  
    29  	testData := path.Join("test_data", "set_labels")
    30  	_, err = os.Stat(testData)
    31  	assert.NoError(t, err)
    32  
    33  	outDir := path.Join(baseDir, "output")
    34  	err = util.CopyDir(testData, outDir, true)
    35  	assert.NoError(t, err)
    36  
    37  	expectedChartName := "mychart"
    38  	expectedChartRelease := "cheese"
    39  	expectedChartVersion := "1.2.3"
    40  	expectedNamespace := "jx"
    41  
    42  	chartMetadata := &chart.Metadata{
    43  		Name:    expectedChartName,
    44  		Version: expectedChartVersion,
    45  	}
    46  
    47  	namespacesDir := filepath.Join(outDir, "namespaces", "jx")
    48  	hooksDir := path.Join(baseDir, "hooks", "namespaces", "jx")
    49  
    50  	helmHooks, err := addLabelsToChartYaml(outDir, hooksDir, expectedChartName, expectedChartRelease, expectedChartVersion, chartMetadata, expectedNamespace)
    51  	assert.NoError(t, err, "Failed to add labels to YAML")
    52  
    53  	err = filepath.Walk(namespacesDir, func(path string, f os.FileInfo, err error) error {
    54  		ext := filepath.Ext(path)
    55  		if ext == ".yaml" {
    56  			file := path
    57  			svc := &corev1.Service{}
    58  			data, err := ioutil.ReadFile(file)
    59  			assert.NoError(t, err, "Failed to load YAML %s", path)
    60  			if err == nil {
    61  				err = yaml.Unmarshal(data, &svc)
    62  				assert.NoError(t, err, "Failed to parse YAML %s", path)
    63  				if err == nil {
    64  					labels := svc.Labels
    65  					assert.NotNil(t, labels, "No labels on path %s", path)
    66  					if labels != nil {
    67  						assertLabelValue(t, expectedChartRelease, labels, LabelReleaseName, path)
    68  						assertLabelValue(t, expectedChartVersion, labels, LabelReleaseChartVersion, path)
    69  
    70  						if !strings.HasSuffix(file, "clusterrole.yaml") {
    71  							assertLabelValue(t, expectedNamespace, labels, LabelNamespace, path)
    72  						} else {
    73  							assertNoLabelValue(t, labels, LabelNamespace, path)
    74  						}
    75  					}
    76  				}
    77  			}
    78  		}
    79  		return nil
    80  	})
    81  
    82  	assert.FileExists(t, filepath.Join(hooksDir, "part0-post-install-job.yaml"), "Should have moved this YAML into the hooks dir!")
    83  
    84  	if assert.Equal(t, 1, len(helmHooks), "number of helm hooks") {
    85  		hook := helmHooks[0]
    86  		if assert.NotNil(t, hook, "helm hook") {
    87  			assert.Equal(t, []string{"post-install", "post-upgrade"}, hook.Hooks, "hooks")
    88  			assert.Equal(t, []string{"hook-succeeded"}, hook.HookDeletePolicies, "hook delete policies")
    89  			assert.FileExists(t, hook.File, "should have a helm hook template file")
    90  		}
    91  	}
    92  	assert.NoError(t, err, "Failed to walk folders")
    93  }
    94  
    95  func assertLabelValue(t *testing.T, expectedValue string, labels map[string]string, key string, path string) bool {
    96  	require.NotNil(t, labels, "labels were nil for path %s", path)
    97  	actual := labels[key]
    98  	return assert.Equal(t, expectedValue, actual, "Failed to find label %s on AML %s", key, path)
    99  }
   100  
   101  func assertNoLabelValue(t *testing.T, labels map[string]string, key string, path string) bool {
   102  	if labels != nil {
   103  		actual := labels[key]
   104  		return assert.Equal(t, "", actual, "Should not have label %s on YAML %s", key, path)
   105  	}
   106  	return true
   107  }
   108  
   109  func TestSplitObjectsInFiles(t *testing.T) {
   110  	t.Parallel()
   111  
   112  	dataDir := filepath.Join("test_data", "multi_objects")
   113  	testDir, err := ioutil.TempDir("", "test_multi_objects")
   114  	assert.NoError(t, err, "should create a temp dir for tests")
   115  	err = util.CopyDir(dataDir, testDir, true)
   116  	assert.NoError(t, err, "should copy the test data into a temporary folder")
   117  	defer os.RemoveAll(testDir)
   118  
   119  	tests := map[string]struct {
   120  		file    string
   121  		want    int
   122  		wantErr bool
   123  	}{
   124  		"single object": {
   125  			file:    "single_object.yaml",
   126  			want:    1,
   127  			wantErr: false,
   128  		},
   129  		"single object with separator": {
   130  			file:    "single_object_separator.yaml",
   131  			want:    1,
   132  			wantErr: false,
   133  		},
   134  		"single object with separator and comment": {
   135  			file:    "single_object_comment.yaml",
   136  			want:    1,
   137  			wantErr: false,
   138  		},
   139  		"single object with separator and whitespace": {
   140  			file:    "single_object_newlines.yaml",
   141  			want:    1,
   142  			wantErr: false,
   143  		},
   144  		"multiple objects": {
   145  			file:    "objects.yaml",
   146  			want:    2,
   147  			wantErr: false,
   148  		},
   149  		"multiple objects with separator": {
   150  			file:    "objects_separator.yaml",
   151  			want:    2,
   152  			wantErr: false,
   153  		},
   154  		"multiple objects with separator and different namespaces": {
   155  			file:    "objects_separator_namespace.yaml",
   156  			want:    2,
   157  			wantErr: false,
   158  		},
   159  	}
   160  
   161  	for name, tc := range tests {
   162  		t.Run(name, func(t *testing.T) {
   163  			// baseDir string, relativePath, defaultNamespace string
   164  			parts, err := splitObjectsInFiles(filepath.Join(testDir, tc.file), testDir, tc.file, "jx")
   165  			if tc.wantErr {
   166  				assert.Error(t, err, "should fail")
   167  			} else {
   168  				assert.NoError(t, err, "should not fail")
   169  			}
   170  			assert.Equal(t, tc.want, len(parts))
   171  		})
   172  	}
   173  }
   174  
   175  func TestSplitObjectsInFilesWithHooks(t *testing.T) {
   176  	t.Parallel()
   177  
   178  	dataDir := filepath.Join("test_data", "helm_hooks")
   179  	testDir, err := ioutil.TempDir("", "test_helm_hooks")
   180  	assert.NoError(t, err, "should create a temp dir for tests")
   181  	err = util.CopyDir(dataDir, testDir, true)
   182  	assert.NoError(t, err, "should copy the test data into a temporary folder")
   183  	defer os.RemoveAll(testDir)
   184  
   185  	tests := map[string]struct {
   186  		file    string
   187  		want    int
   188  		wantErr bool
   189  	}{
   190  		"multiple_crds_with_hooks": {
   191  			file:    "crds.yaml",
   192  			want:    3,
   193  			wantErr: false,
   194  		},
   195  	}
   196  
   197  	for name, tc := range tests {
   198  		t.Run(name, func(t *testing.T) {
   199  			// baseDir string, relativePath, defaultNamespace string
   200  			parts, err := splitObjectsInFiles(filepath.Join(testDir, tc.file), testDir, tc.file, "jx")
   201  			if tc.wantErr {
   202  				assert.Error(t, err, "should fail")
   203  			} else {
   204  				assert.NoError(t, err, "should not fail")
   205  			}
   206  			assert.Equal(t, tc.want, len(parts))
   207  		})
   208  	}
   209  }