github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/config/reader_test.go (about)

     1  package config_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"path"
     8  	"testing"
     9  
    10  	"github.com/kyma-project/kyma-environment-broker/internal/broker"
    11  	"github.com/kyma-project/kyma-environment-broker/internal/config"
    12  	"github.com/sirupsen/logrus"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  	"gopkg.in/yaml.v2"
    16  	coreV1 "k8s.io/api/core/v1"
    17  	"k8s.io/apimachinery/pkg/api/meta"
    18  	metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    19  	"k8s.io/apimachinery/pkg/runtime"
    20  	"sigs.k8s.io/controller-runtime/pkg/client"
    21  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    22  )
    23  
    24  const (
    25  	kebConfigYaml             = "keb-config.yaml"
    26  	namespace                 = "kcp-system"
    27  	runtimeVersionLabelPrefix = "runtime-version-"
    28  	kebConfigLabel            = "keb-config"
    29  	kymaVersion               = "2.4.0"
    30  	defaultConfigKey          = "default"
    31  )
    32  
    33  func TestConfigReaderSuccessFlow(t *testing.T) {
    34  	// setup
    35  	ctx := context.TODO()
    36  	cfgMap, err := fixConfigMap()
    37  	require.NoError(t, err)
    38  
    39  	fakeK8sClient := fake.NewClientBuilder().WithRuntimeObjects(cfgMap).Build()
    40  	logger := logrus.New()
    41  	logger.SetFormatter(&logrus.JSONFormatter{})
    42  	cfgReader := config.NewConfigMapReader(ctx, fakeK8sClient, logger, kymaVersion)
    43  
    44  	t.Run("should read default KEB config for Kyma version 2.4.0", func(t *testing.T) {
    45  		// when
    46  		rawCfg, err := cfgReader.Read(kymaVersion, broker.AWSPlanName)
    47  
    48  		// then
    49  		require.NoError(t, err)
    50  		assert.Equal(t, cfgMap.Data[defaultConfigKey], rawCfg)
    51  	})
    52  
    53  	t.Run("should read KEB config for Kyma version 2.4.0 and azure plan", func(t *testing.T) {
    54  		// when
    55  		rawCfg, err := cfgReader.Read(kymaVersion, broker.AzurePlanName)
    56  
    57  		// then
    58  		require.NoError(t, err)
    59  		assert.Equal(t, cfgMap.Data[broker.AzurePlanName], rawCfg)
    60  	})
    61  
    62  	t.Run("should read KEB config for Kyma version 2.4.0 and trial plan", func(t *testing.T) {
    63  		// when
    64  		rawCfg, err := cfgReader.Read(kymaVersion, broker.TrialPlanName)
    65  
    66  		// then
    67  		require.NoError(t, err)
    68  		assert.Equal(t, cfgMap.Data[broker.TrialPlanName], rawCfg)
    69  	})
    70  
    71  	t.Run("should read KEB config for custom Kyma version and azure plan", func(t *testing.T) {
    72  		// when
    73  		customVersion := "PR-1000"
    74  		rawCfg, err := cfgReader.Read(customVersion, broker.AzurePlanName)
    75  
    76  		// then
    77  		require.NoError(t, err)
    78  		assert.Equal(t, cfgMap.Data[broker.AzurePlanName], rawCfg)
    79  	})
    80  
    81  	t.Run("should read KEB config for the latest official Kyma version and azure plan when config for custom main-* version is missing", func(t *testing.T) {
    82  		// when
    83  		customVersion := "main-fffff"
    84  		rawCfg, err := cfgReader.Read(customVersion, broker.AzurePlanName)
    85  
    86  		// then
    87  		require.NoError(t, err)
    88  		assert.Equal(t, cfgMap.Data[broker.AzurePlanName], rawCfg)
    89  	})
    90  
    91  	t.Run("should read KEB config for the latest official Kyma version and azure plan when config for custom PR-* version is missing", func(t *testing.T) {
    92  		// when
    93  		customVersion := "PR-1234"
    94  		rawCfg, err := cfgReader.Read(customVersion, broker.AzurePlanName)
    95  
    96  		// then
    97  		require.NoError(t, err)
    98  		assert.Equal(t, cfgMap.Data[broker.AzurePlanName], rawCfg)
    99  	})
   100  }
   101  
   102  func TestConfigReaderErrors(t *testing.T) {
   103  	// setup
   104  	ctx := context.TODO()
   105  	redundantCfgMap := &coreV1.ConfigMap{
   106  		TypeMeta: metaV1.TypeMeta{
   107  			Kind:       "ConfigMap",
   108  			APIVersion: "v1",
   109  		},
   110  		ObjectMeta: metaV1.ObjectMeta{
   111  			Name:      "redundant-configmap",
   112  			Namespace: namespace,
   113  			Labels: map[string]string{
   114  				fmt.Sprintf("%s%s", runtimeVersionLabelPrefix, kymaVersion): "true",
   115  				kebConfigLabel: "true",
   116  			},
   117  		},
   118  	}
   119  	cfgMap, err := fixConfigMap()
   120  	require.NoError(t, err)
   121  
   122  	k8sClient := failingK8sClient{}
   123  	fakeK8sClient := fake.NewClientBuilder().Build()
   124  	logger := logrus.New()
   125  	logger.SetFormatter(&logrus.JSONFormatter{})
   126  
   127  	t.Run("should return error while fetching configmap on List() of K8s client", func(t *testing.T) {
   128  		// given
   129  		cfgReader := config.NewConfigMapReader(ctx, k8sClient, logger, kymaVersion)
   130  
   131  		// when
   132  		rawCfg, err := cfgReader.Read(kymaVersion, broker.AzurePlanName)
   133  
   134  		// then
   135  		require.Error(t, err)
   136  		logger.Error(err)
   137  		assert.Equal(t, "", rawCfg)
   138  	})
   139  
   140  	t.Run("should return error while verifying configuration configmap existence", func(t *testing.T) {
   141  		// given
   142  		cfgReader := config.NewConfigMapReader(ctx, fakeK8sClient, logger, kymaVersion)
   143  
   144  		// when
   145  		rawCfg, err := cfgReader.Read(kymaVersion, broker.AzurePlanName)
   146  
   147  		// then
   148  		require.Error(t, err)
   149  		logger.Error(err)
   150  		assert.Equal(t, "", rawCfg)
   151  
   152  		// given
   153  		err = fakeK8sClient.Create(ctx, cfgMap)
   154  		require.NoError(t, err)
   155  
   156  		err = fakeK8sClient.Create(ctx, redundantCfgMap)
   157  		require.NoError(t, err)
   158  
   159  		// when
   160  		rawCfg, err = cfgReader.Read(kymaVersion, broker.AzurePlanName)
   161  
   162  		// then
   163  		require.Error(t, err)
   164  		logger.Error(err)
   165  		assert.Equal(t, "", rawCfg)
   166  	})
   167  
   168  	t.Run("should return error while getting config string for a plan", func(t *testing.T) {
   169  		// given
   170  		err = fakeK8sClient.Delete(ctx, cfgMap)
   171  		require.NoError(t, err)
   172  
   173  		cfgReader := config.NewConfigMapReader(ctx, fakeK8sClient, logger, kymaVersion)
   174  
   175  		// when
   176  		rawCfg, err := cfgReader.Read(kymaVersion, broker.AzurePlanName)
   177  
   178  		// then
   179  		require.Error(t, err)
   180  		logger.Error(err)
   181  		assert.Equal(t, "", rawCfg)
   182  	})
   183  }
   184  
   185  func fixConfigMap() (*coreV1.ConfigMap, error) {
   186  	yamlFilePath := path.Join("testdata", kebConfigYaml)
   187  	contents, err := os.ReadFile(yamlFilePath)
   188  	if err != nil {
   189  		return nil, fmt.Errorf("while reading configmap")
   190  	}
   191  
   192  	var tempCfgMap tempConfigMap
   193  	err = yaml.Unmarshal(contents, &tempCfgMap)
   194  	if err != nil {
   195  		return nil, fmt.Errorf("while unmarshalling configmap")
   196  	}
   197  
   198  	return tempCfgMap.toConfigMap(), nil
   199  }
   200  
   201  type tempConfigMap struct {
   202  	APIVersion string            `yaml:"apiVersion,omitempty"`
   203  	Kind       string            `yaml:"kind,omitempty"`
   204  	Metadata   tempMetadata      `yaml:"metadata,omitempty"`
   205  	Data       map[string]string `yaml:"data,omitempty"`
   206  }
   207  
   208  type tempMetadata struct {
   209  	Name      string            `yaml:"name,omitempty"`
   210  	Namespace string            `yaml:"namespace,omitempty"`
   211  	Labels    map[string]string `yaml:"labels,omitempty"`
   212  }
   213  
   214  func (m *tempConfigMap) toConfigMap() *coreV1.ConfigMap {
   215  	return &coreV1.ConfigMap{
   216  		TypeMeta: metaV1.TypeMeta{
   217  			Kind:       m.Kind,
   218  			APIVersion: m.APIVersion,
   219  		},
   220  		ObjectMeta: metaV1.ObjectMeta{
   221  			Name:      m.Metadata.Name,
   222  			Namespace: m.Metadata.Namespace,
   223  			Labels:    m.Metadata.Labels,
   224  		},
   225  		Data: m.Data,
   226  	}
   227  }
   228  
   229  type failingK8sClient struct{}
   230  
   231  func (c failingK8sClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
   232  	return fmt.Errorf("not implemented")
   233  }
   234  
   235  func (c failingK8sClient) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
   236  	return fmt.Errorf("not implemented")
   237  }
   238  
   239  func (c failingK8sClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error {
   240  	return fmt.Errorf("not implemented")
   241  }
   242  
   243  func (c failingK8sClient) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error {
   244  	return fmt.Errorf("not implemented")
   245  }
   246  
   247  func (c failingK8sClient) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error {
   248  	return fmt.Errorf("not implemented")
   249  }
   250  
   251  func (c failingK8sClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error {
   252  	return fmt.Errorf("not implemented")
   253  }
   254  
   255  func (c failingK8sClient) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error {
   256  	return fmt.Errorf("not implemented")
   257  }
   258  
   259  func (c failingK8sClient) Status() client.StatusWriter {
   260  	panic("not implemented")
   261  }
   262  
   263  func (c failingK8sClient) Scheme() *runtime.Scheme {
   264  	panic("not implemented")
   265  }
   266  
   267  func (c failingK8sClient) RESTMapper() meta.RESTMapper {
   268  	panic("not implemented")
   269  }
   270  
   271  func (c failingK8sClient) SubResource(s string) client.SubResourceClient {
   272  	panic("not implemented")
   273  }