github.com/verrazzano/verrazzano@v1.7.0/pkg/profiles/merge_test.go (about)

     1  // Copyright (c) 2021, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package profiles
     5  
     6  import (
     7  	"os"
     8  	"path/filepath"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	vzyaml "github.com/verrazzano/verrazzano/pkg/yaml"
    13  	"github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1"
    14  	"github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1"
    15  	"sigs.k8s.io/yaml"
    16  )
    17  
    18  const (
    19  	actualSpecFilePath         = "./testdata/actual.yaml"
    20  	certsBaseSpecFilePath      = "./testdata/cert_base.yaml"
    21  	certsOverlaySpecFilePath   = "./testdata/cert_overlay.yaml"
    22  	certsMergedSpecFilePath    = "./testdata/cert_merged.yaml"
    23  	openSearchActualFilePath   = "./testdata/custom_os.yaml"
    24  	openSearchBaseFilePath     = "./testdata/prod_os.yaml"
    25  	openSearchMergedFilePath   = "./testdata/os_merged.yaml"
    26  	consoleSpecFilePath        = "./testdata/console.yaml"
    27  	devProfileSpecFilePath     = "./testdata/dev.yaml"
    28  	keycloakSpecFilePath       = "./testdata/keycloak.yaml"
    29  	managedProfileSpecFilePath = "./testdata/managed.yaml"
    30  	managedMergedSpecFilePath  = "./testdata/managed_merged.yaml"
    31  	mergedSpecFilePath         = "./testdata/merged.yaml"
    32  	profileCustomSpecFilePath  = "./testdata/profile.yaml"
    33  )
    34  
    35  const (
    36  	mergeProfileErrorMsg      = "error merging profiles"
    37  	readProfileErrorMsg       = "error reading profiles"
    38  	incorrectMergedProfileMsg = "merged profile is incorrect"
    39  )
    40  
    41  type mergeProfileTestData struct {
    42  	name     string
    43  	actualCR string
    44  	profiles []string
    45  	mergedCR string
    46  }
    47  
    48  // TestMergeSpec tests the StrategicMergeFiles function for a list of VerrazzanoSpecs
    49  // GIVEN an array of tests, where each tests specifies files to merge
    50  // WHEN StrategicMergeFiles is called, with some contents being a list that should be merged
    51  // THEN ensure that the merged result is correct.
    52  func TestMergeSpec(t *testing.T) {
    53  	tests := []struct {
    54  		name     string
    55  		base     string
    56  		overlay  string
    57  		expected string
    58  	}{
    59  		{
    60  			name:     "1",
    61  			base:     devProfileSpecFilePath,
    62  			overlay:  managedProfileSpecFilePath,
    63  			expected: managedProfileSpecFilePath,
    64  		},
    65  		{
    66  			name:     "3",
    67  			base:     certsBaseSpecFilePath,
    68  			overlay:  certsOverlaySpecFilePath,
    69  			expected: certsMergedSpecFilePath,
    70  		},
    71  	}
    72  	for _, test := range tests {
    73  		t.Run(test.name, func(t *testing.T) {
    74  			merged, err := vzyaml.StrategicMergeFiles(v1alpha1.Verrazzano{}, test.base, test.overlay)
    75  			assert.NoError(t, err, mergeProfileErrorMsg)
    76  			vzMerged := v1alpha1.Verrazzano{}
    77  			err = yaml.Unmarshal([]byte(merged), &vzMerged)
    78  			assert.NoError(t, err, "Error marshalling merged results into VZ struct")
    79  
    80  			expected, err := os.ReadFile(filepath.Join(test.expected))
    81  			assert.NoError(t, err, "error reading mergedCR results file")
    82  			vzExpected := v1alpha1.Verrazzano{}
    83  			err = yaml.Unmarshal(expected, &vzExpected)
    84  			assert.NoError(t, err, "Error marshalling mergedCR results into VZ struct")
    85  
    86  			assert.Equal(t, vzExpected, vzMerged, incorrectMergedProfileMsg)
    87  		})
    88  	}
    89  }
    90  
    91  // TestMergeProfiles tests the MergeProfiles function for a list of profiles
    92  // GIVEN an array of tests, where each tests specifies profiles to merge
    93  // WHEN MergeProfiles is called, with some contents being a list that should be merged
    94  // THEN ensure that the merged result is correct.
    95  func TestMergeProfiles(t *testing.T) {
    96  	for _, test := range getMergeProfileTestData() {
    97  		t.Run(test.name, func(t *testing.T) {
    98  
    99  			// Create VerrazzanoSpec from actualCR profile
   100  			actualCR, err := readProfile(test.actualCR)
   101  			assert.NoError(t, err, readProfileErrorMsg)
   102  
   103  			// Merge the profiles
   104  			mergedCR, err := MergeProfiles(actualCR, test.profiles...)
   105  			assert.NoError(t, err, mergeProfileErrorMsg)
   106  
   107  			// Create VerrazzanoSpec from mergedCR profile
   108  			expectedSpec, err := readProfile(test.mergedCR)
   109  			assert.NoError(t, err, readProfileErrorMsg)
   110  
   111  			assert.Equal(t, expectedSpec, mergedCR, incorrectMergedProfileMsg)
   112  		})
   113  	}
   114  }
   115  
   116  // TestAppendComponentOverrides tests the appendComponentOverrides
   117  // GIVEN  actual and profile CRs
   118  // WHEN appendComponentOverrides is called
   119  // THEN the compoent overrides from the profile CR should be appended to the component overrides of the actual CR.
   120  func TestAppendComponentOverrides(t *testing.T) {
   121  	actual, err := readProfile(actualSpecFilePath)
   122  	assert.NoError(t, err)
   123  	profile, err := readProfile(profileCustomSpecFilePath)
   124  	assert.NoError(t, err)
   125  	AppendComponentOverrides(actual, profile)
   126  	merged, err := readProfile(mergedSpecFilePath)
   127  	assert.NoError(t, err)
   128  	assert.Equal(t, merged, actual)
   129  }
   130  
   131  // TestMergeProfilesForV1beta1 tests the MergeProfiles function for a list of profiles
   132  // GIVEN an array of tests, where each tests specifies profiles to merge
   133  // WHEN MergeProfilesForV1beta1 is called, with some contents being a list that should be merged
   134  // THEN ensure that the merged result is correct.
   135  func TestMergeProfilesForV1beta1(t *testing.T) {
   136  	for _, test := range getMergeProfileTestData() {
   137  		t.Run(test.name, func(t *testing.T) {
   138  
   139  			// Create VerrazzanoSpec from actualCR profile
   140  			actualCR, err := readProfileForV1beta1(test.actualCR)
   141  			assert.NoError(t, err, readProfileErrorMsg)
   142  
   143  			// Merge the profiles
   144  			mergedCR, err := MergeProfilesForV1beta1(actualCR, test.profiles...)
   145  			assert.NoError(t, err, mergeProfileErrorMsg)
   146  
   147  			// Create VerrazzanoSpec from mergedCR profile
   148  			expectedSpec, err := readProfileForV1beta1(test.mergedCR)
   149  			assert.NoError(t, err, readProfileErrorMsg)
   150  
   151  			assert.Equal(t, expectedSpec, mergedCR, incorrectMergedProfileMsg)
   152  		})
   153  	}
   154  }
   155  
   156  // TestAppendComponentOverrides tests the appendComponentOverrides
   157  // GIVEN  actual and profile CRs
   158  // WHEN appendComponentOverrides is called
   159  // THEN the compoent overrides from the profile CR should be appended to the component overrides of the actual CR.
   160  func TestAppendComponentOverridesForV1beta1(t *testing.T) {
   161  	actual, err := readProfileForV1beta1(actualSpecFilePath)
   162  	assert.NoError(t, err)
   163  	profile, err := readProfileForV1beta1(profileCustomSpecFilePath)
   164  	assert.NoError(t, err)
   165  	AppendComponentOverridesV1beta1(actual, profile)
   166  	merged, err := readProfileForV1beta1(mergedSpecFilePath)
   167  	assert.NoError(t, err)
   168  	assert.Equal(t, merged, actual)
   169  }
   170  
   171  // Create VerrazzanoSpec from profile
   172  func readProfile(filename string) (*v1alpha1.Verrazzano, error) {
   173  	specYaml, err := os.ReadFile(filepath.Join(filename))
   174  	if err != nil {
   175  		return nil, err
   176  	}
   177  	var spec v1alpha1.Verrazzano
   178  	err = yaml.Unmarshal(specYaml, &spec)
   179  	if err != nil {
   180  		return nil, err
   181  	}
   182  	return &spec, nil
   183  }
   184  
   185  // Create VerrazzanoSpec from profile
   186  func readProfileForV1beta1(filename string) (*v1beta1.Verrazzano, error) {
   187  	specYaml, err := os.ReadFile(filepath.Join(filename))
   188  	if err != nil {
   189  		return nil, err
   190  	}
   191  	var spec v1beta1.Verrazzano
   192  	err = yaml.Unmarshal(specYaml, &spec)
   193  	if err != nil {
   194  		return nil, err
   195  	}
   196  	return &spec, nil
   197  }
   198  
   199  func getMergeProfileTestData() []mergeProfileTestData {
   200  	return []mergeProfileTestData{
   201  		{
   202  			name:     "1",
   203  			actualCR: devProfileSpecFilePath,
   204  			profiles: []string{
   205  				managedProfileSpecFilePath,
   206  			},
   207  			mergedCR: managedProfileSpecFilePath,
   208  		},
   209  		{
   210  			name:     "2",
   211  			actualCR: managedProfileSpecFilePath,
   212  			profiles: []string{
   213  				consoleSpecFilePath,
   214  				keycloakSpecFilePath,
   215  			},
   216  			mergedCR: managedMergedSpecFilePath,
   217  		},
   218  		{
   219  			name:     "3",
   220  			actualCR: certsBaseSpecFilePath,
   221  			profiles: []string{
   222  				certsOverlaySpecFilePath,
   223  			},
   224  			mergedCR: certsBaseSpecFilePath,
   225  		},
   226  		{
   227  			// This unit test makes sure that replicas in OS NodePool is never nil in the effectiveCR
   228  			// Even it is nil in the actualCR
   229  			name:     "4",
   230  			actualCR: openSearchActualFilePath,
   231  			profiles: []string{
   232  				openSearchBaseFilePath,
   233  			},
   234  			mergedCR: openSearchMergedFilePath,
   235  		},
   236  	}
   237  }