github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/step/create/helmfile/create_helmfile_test.go (about)

     1  // +build unit
     2  
     3  package helmfile
     4  
     5  import (
     6  	"fmt"
     7  	"io/ioutil"
     8  	"path"
     9  	"path/filepath"
    10  	"testing"
    11  
    12  	v1 "k8s.io/api/core/v1"
    13  
    14  	mocks "github.com/olli-ai/jx/v2/pkg/cmd/clients/mocks"
    15  	helmfile2 "github.com/olli-ai/jx/v2/pkg/helmfile"
    16  	kube_test "github.com/olli-ai/jx/v2/pkg/kube/mocks"
    17  	. "github.com/petergtz/pegomock"
    18  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    19  	"k8s.io/client-go/kubernetes/fake"
    20  
    21  	"github.com/olli-ai/jx/v2/pkg/cmd/create/options"
    22  	"github.com/olli-ai/jx/v2/pkg/cmd/opts"
    23  	helm_test "github.com/olli-ai/jx/v2/pkg/helm/mocks"
    24  
    25  	"github.com/olli-ai/jx/v2/pkg/util"
    26  	"github.com/pkg/errors"
    27  	"github.com/stretchr/testify/assert"
    28  	"gopkg.in/yaml.v2"
    29  )
    30  
    31  func TestDedupeRepositories(t *testing.T) {
    32  	tempDir, err := ioutil.TempDir("", "test-applications-config")
    33  	assert.NoError(t, err, "should create a temporary config dir")
    34  
    35  	o := &CreateHelmfileOptions{
    36  		outputDir:     tempDir,
    37  		dir:           "test_data",
    38  		CreateOptions: *getCreateOptions(),
    39  	}
    40  	err = o.Run()
    41  	assert.NoError(t, err)
    42  
    43  	h, err := loadHelmfile(path.Join(tempDir, "apps"))
    44  	assert.NoError(t, err)
    45  
    46  	// assert there are 3 repos and not 4 as one of them in the jx-applications.yaml is a duplicate
    47  	assert.Equal(t, 3, len(h.Repositories))
    48  
    49  }
    50  
    51  func TestExtraAppValues(t *testing.T) {
    52  	tempDir, err := ioutil.TempDir("", "test-applications-config")
    53  	assert.NoError(t, err, "should create a temporary config dir")
    54  
    55  	o := &CreateHelmfileOptions{
    56  		outputDir:     tempDir,
    57  		dir:           path.Join("test_data", "extra-values"),
    58  		CreateOptions: *getCreateOptions(),
    59  	}
    60  	err = o.Run()
    61  	assert.NoError(t, err)
    62  
    63  	h, err := loadHelmfile(path.Join(tempDir, "apps"))
    64  	assert.NoError(t, err)
    65  
    66  	// assert we added the local values.yaml for the velero app
    67  	assert.Equal(t, "velero/values.yaml", h.Releases[0].Values[0])
    68  
    69  }
    70  
    71  func TestExtraFlagValues(t *testing.T) {
    72  	tempDir, err := ioutil.TempDir("", "test-applications-config")
    73  	assert.NoError(t, err, "should create a temporary config dir")
    74  
    75  	o := &CreateHelmfileOptions{
    76  		outputDir:     tempDir,
    77  		dir:           path.Join("test_data"),
    78  		valueFiles:    []string{"foo/bar.yaml"},
    79  		CreateOptions: *getCreateOptions(),
    80  	}
    81  	err = o.Run()
    82  	assert.NoError(t, err)
    83  
    84  	h, err := loadHelmfile(path.Join(tempDir, "apps"))
    85  	assert.NoError(t, err)
    86  
    87  	// assert we added the values file passed in as a CLI flag
    88  	assert.Equal(t, "foo/bar.yaml", h.Releases[0].Values[0])
    89  
    90  }
    91  
    92  func TestCreateNamespaceChart(t *testing.T) {
    93  	tempDir, err := ioutil.TempDir("", "test-applications-config")
    94  	assert.NoError(t, err, "should create a temporary config dir")
    95  
    96  	o := &CreateHelmfileOptions{
    97  		outputDir:     tempDir,
    98  		dir:           path.Join("test_data", "create-namespace-chart"),
    99  		valueFiles:    []string{"foo/bar.yaml"},
   100  		CreateOptions: *getCreateOptions(),
   101  	}
   102  	err = o.Run()
   103  	assert.NoError(t, err)
   104  
   105  	h, err := loadHelmfile(path.Join(tempDir, "apps"))
   106  	assert.NoError(t, err)
   107  
   108  	exists, err := util.FileExists(path.Join(tempDir, "apps", "generated", "foo", "values.yaml"))
   109  	assert.True(t, exists, "generated namespace values file not found")
   110  
   111  	// assert we added the values file passed in as a CLI flag
   112  	assert.Equal(t, 2, len(h.Releases), "should have two charts, one for the app and a second added to create the missing namespace")
   113  
   114  	for _, release := range h.Releases {
   115  		if release.Name == "velero" {
   116  			assert.Equal(t, "foo/bar.yaml", release.Values[0])
   117  		} else {
   118  			assert.Equal(t, "namespace-foo", release.Name)
   119  			assert.Equal(t, path.Join("generated", "foo", "values.yaml"), release.Values[0])
   120  		}
   121  	}
   122  
   123  }
   124  
   125  func TestSystem(t *testing.T) {
   126  	tempDir, err := ioutil.TempDir("", "test-applications-config")
   127  	assert.NoError(t, err, "should create a temporary config dir")
   128  
   129  	o := &CreateHelmfileOptions{
   130  		outputDir:     tempDir,
   131  		dir:           path.Join("test_data", "system"),
   132  		CreateOptions: *getCreateOptions(),
   133  	}
   134  	err = o.Run()
   135  	assert.NoError(t, err)
   136  
   137  	appHelmfile, err := loadHelmfile(path.Join(tempDir, "apps"))
   138  	assert.NoError(t, err)
   139  
   140  	systemHelmfile, err := loadHelmfile(path.Join(tempDir, "system"))
   141  	assert.NoError(t, err)
   142  
   143  	// assert we added the local values.yaml for the velero app
   144  	assert.Equal(t, "velero", appHelmfile.Releases[0].Name)
   145  	assert.Equal(t, "cert-manager", systemHelmfile.Releases[0].Name)
   146  }
   147  
   148  func loadHelmfile(dir string) (*helmfile2.HelmState, error) {
   149  
   150  	fileName := helmfile
   151  	if dir != "" {
   152  		fileName = filepath.Join(dir, helmfile)
   153  	}
   154  
   155  	exists, err := util.FileExists(fileName)
   156  	if err != nil || !exists {
   157  		return nil, errors.Errorf("no %s found in directory %s", fileName, dir)
   158  	}
   159  
   160  	config := &helmfile2.HelmState{}
   161  
   162  	data, err := ioutil.ReadFile(fileName)
   163  	if err != nil {
   164  		return config, fmt.Errorf("failed to load file %s due to %s", fileName, err)
   165  	}
   166  
   167  	err = yaml.Unmarshal(data, config)
   168  	if err != nil {
   169  		return config, fmt.Errorf("failed to unmarshal YAML file %s due to %s", fileName, err)
   170  	}
   171  
   172  	return config, err
   173  }
   174  
   175  func getCreateOptions() *options.CreateOptions {
   176  	// default jx namespace
   177  	ns := &v1.Namespace{
   178  		ObjectMeta: metav1.ObjectMeta{
   179  			Name: "jx",
   180  		},
   181  	}
   182  	// mock factory
   183  	factory := mocks.NewMockFactory()
   184  	// mock Kubernetes interface
   185  	kubeInterface := fake.NewSimpleClientset(ns)
   186  
   187  	// Override CreateKubeClient to return mock Kubernetes interface
   188  	When(factory.CreateKubeClient()).ThenReturn(kubeInterface, "jx", nil)
   189  	commonOpts := opts.NewCommonOptionsWithFactory(factory)
   190  
   191  	helmer := helm_test.NewMockHelmer()
   192  	kuber := kube_test.NewMockKuber()
   193  
   194  	commonOpts.SetHelm(helmer)
   195  	commonOpts.SetKube(kuber)
   196  
   197  	return &options.CreateOptions{
   198  		CommonOptions: &commonOpts,
   199  	}
   200  }