Skip to content
Snippets Groups Projects
Select Git revision
  • d580684acb7d3c2825e5ebba8d3e45e4356be292
  • master default protected
  • spilo-wale-removal
  • dependabot/go_modules/golang.org/x/oauth2-0.27.0
  • dependabot/go_modules/golang.org/x/net-0.38.0
  • dependabot/pip/ui/requests-2.32.4
  • bug-upgrade
  • gh-pages
  • patroni-4-integration
  • remove-zappr
  • ignore-auto-upgrade
  • arm-pooler
  • update-go-and-deps
  • pluralsh-liveness-probe
  • silenium-dev-master
  • bump-v1.9.1
  • enable-query-logging
  • bump-v1.7.1
  • resize-mixed-mode
  • instance-annotation
  • bump-v1.8.2
  • v1.14.0
  • v1.13.0
  • v1.12.2
  • v1.12.1
  • v1.12.0
  • v1.11.0
  • v1.10.1
  • v1.10.0
  • v1.9.0
  • v1.8.2
  • v1.8.1
  • v1.8.0
  • v1.7.1
  • v1.7.0
  • v1.6.3
  • v1.6.2
  • v1.6.1
  • v1.6.0
  • v1.5.0
  • v1.4.0
41 results

util_test.go

Blame
  • util_test.go 12.85 KiB
    package controller
    
    import (
    	"fmt"
    	"reflect"
    	"testing"
    
    	b64 "encoding/base64"
    
    	"github.com/stretchr/testify/assert"
    	"github.com/zalando/postgres-operator/pkg/spec"
    	"github.com/zalando/postgres-operator/pkg/util/config"
    	"github.com/zalando/postgres-operator/pkg/util/k8sutil"
    	v1 "k8s.io/api/core/v1"
    	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    )
    
    const (
    	testInfrastructureRolesOldSecretName = "infrastructureroles-old-test"
    	testInfrastructureRolesNewSecretName = "infrastructureroles-new-test"
    )
    
    func newUtilTestController() *Controller {
    	controller := NewController(&spec.ControllerConfig{}, "util-test")
    	controller.opConfig.ClusterNameLabel = "cluster-name"
    	controller.opConfig.InfrastructureRolesSecretName =
    		spec.NamespacedName{
    			Namespace: v1.NamespaceDefault,
    			Name:      testInfrastructureRolesOldSecretName,
    		}
    	controller.opConfig.Workers = 4
    	controller.KubeClient = k8sutil.NewMockKubernetesClient()
    	return controller
    }
    
    var utilTestController = newUtilTestController()
    
    func TestPodClusterName(t *testing.T) {
    	var testTable = []struct {
    		in       *v1.Pod
    		expected spec.NamespacedName
    	}{
    		{
    			&v1.Pod{},
    			spec.NamespacedName{},
    		},
    		{
    			&v1.Pod{
    				ObjectMeta: metav1.ObjectMeta{
    					Namespace: v1.NamespaceDefault,
    					Labels: map[string]string{
    						utilTestController.opConfig.ClusterNameLabel: "testcluster",
    					},
    				},
    			},
    			spec.NamespacedName{Namespace: v1.NamespaceDefault, Name: "testcluster"},
    		},
    	}
    	for _, test := range testTable {
    		resp := utilTestController.podClusterName(test.in)
    		if resp != test.expected {
    			t.Errorf("expected response %v does not match the actual %v", test.expected, resp)
    		}
    	}
    }
    
    func TestClusterWorkerID(t *testing.T) {
    	var testTable = []struct {
    		in       spec.NamespacedName
    		expected uint32
    	}{
    		{
    			in:       spec.NamespacedName{Namespace: "foo", Name: "bar"},
    			expected: 0,
    		},
    		{
    			in:       spec.NamespacedName{Namespace: "default", Name: "testcluster"},
    			expected: 1,
    		},
    	}
    	for _, test := range testTable {
    		resp := utilTestController.clusterWorkerID(test.in)
    		if resp != test.expected {
    			t.Errorf("expected response %v does not match the actual %v", test.expected, resp)
    		}
    	}
    }
    
    // Test functionality of getting infrastructure roles from their description in
    // corresponding secrets. Here we test only common stuff (e.g. when a secret do
    // not exist, or empty) and the old format.
    func TestOldInfrastructureRoleFormat(t *testing.T) {
    	var testTable = []struct {
    		secretName    spec.NamespacedName
    		expectedRoles map[string]spec.PgUser
    		expectedError error
    	}{
    		{
    			// empty secret name
    			spec.NamespacedName{},
    			map[string]spec.PgUser{},
    			nil,
    		},
    		{
    			// secret does not exist
    			spec.NamespacedName{Namespace: v1.NamespaceDefault, Name: "null"},
    			map[string]spec.PgUser{},
    			fmt.Errorf(`could not get infrastructure roles secret default/null: NotFound`),
    		},
    		{
    			spec.NamespacedName{
    				Namespace: v1.NamespaceDefault,
    				Name:      testInfrastructureRolesOldSecretName,
    			},
    			map[string]spec.PgUser{
    				"testrole": {
    					Name:     "testrole",
    					Origin:   spec.RoleOriginInfrastructure,
    					Password: "testpassword",
    					MemberOf: []string{"testinrole"},
    				},
    				"foobar": {
    					Name:     "foobar",
    					Origin:   spec.RoleOriginInfrastructure,
    					Password: b64.StdEncoding.EncodeToString([]byte("password")),
    					MemberOf: nil,
    				},
    			},
    			nil,
    		},
    	}
    	for _, test := range testTable {
    		roles, err := utilTestController.getInfrastructureRoles(
    			[]*config.InfrastructureRole{
    				&config.InfrastructureRole{
    					SecretName:  test.secretName,
    					UserKey:     "user",
    					PasswordKey: "password",
    					RoleKey:     "inrole",
    					Template:    true,
    				},
    			})
    
    		if err != nil && err.Error() != test.expectedError.Error() {
    			t.Errorf("expected error '%v' does not match the actual error '%v'",
    				test.expectedError, err)
    		}
    
    		if !reflect.DeepEqual(roles, test.expectedRoles) {
    			t.Errorf("expected roles output %#v does not match the actual %#v",
    				test.expectedRoles, roles)
    		}
    	}
    }
    
    // Test functionality of getting infrastructure roles from their description in
    // corresponding secrets. Here we test the new format.
    func TestNewInfrastructureRoleFormat(t *testing.T) {
    	var testTable = []struct {
    		secrets       []spec.NamespacedName
    		expectedRoles map[string]spec.PgUser
    	}{
    		// one secret with one configmap
    		{
    			[]spec.NamespacedName{
    				spec.NamespacedName{
    					Namespace: v1.NamespaceDefault,
    					Name:      testInfrastructureRolesNewSecretName,
    				},
    			},
    			map[string]spec.PgUser{
    				"new-test-role": {
    					Name:     "new-test-role",
    					Origin:   spec.RoleOriginInfrastructure,
    					Password: "new-test-password",
    					MemberOf: []string{"new-test-inrole"},
    				},
    				"new-foobar": {
    					Name:     "new-foobar",
    					Origin:   spec.RoleOriginInfrastructure,
    					Password: b64.StdEncoding.EncodeToString([]byte("password")),
    					MemberOf: nil,
    					Flags:    []string{"createdb"},
    				},
    			},
    		},
    		// multiple standalone secrets
    		{
    			[]spec.NamespacedName{
    				spec.NamespacedName{
    					Namespace: v1.NamespaceDefault,
    					Name:      "infrastructureroles-new-test1",
    				},
    				spec.NamespacedName{
    					Namespace: v1.NamespaceDefault,
    					Name:      "infrastructureroles-new-test2",
    				},
    			},
    			map[string]spec.PgUser{
    				"new-test-role1": {
    					Name:     "new-test-role1",
    					Origin:   spec.RoleOriginInfrastructure,
    					Password: "new-test-password1",
    					MemberOf: []string{"new-test-inrole1"},
    				},
    				"new-test-role2": {
    					Name:     "new-test-role2",
    					Origin:   spec.RoleOriginInfrastructure,
    					Password: "new-test-password2",
    					MemberOf: []string{"new-test-inrole2"},
    				},
    			},
    		},
    	}
    	for _, test := range testTable {
    		definitions := []*config.InfrastructureRole{}
    		for _, secret := range test.secrets {
    			definitions = append(definitions, &config.InfrastructureRole{
    				SecretName:  secret,
    				UserKey:     "user",
    				PasswordKey: "password",
    				RoleKey:     "inrole",
    				Template:    false,
    			})
    		}
    
    		roles, err := utilTestController.getInfrastructureRoles(definitions)
    		assert.NoError(t, err)
    
    		if !reflect.DeepEqual(roles, test.expectedRoles) {
    			t.Errorf("expected roles output/the actual:\n%#v\n%#v",
    				test.expectedRoles, roles)
    		}
    	}
    }
    
    // Tests for getting correct infrastructure roles definitions from present
    // configuration. E.g. in which secrets for which roles too look. The biggest
    // point here is compatibility of old and new formats of defining
    // infrastructure roles.
    func TestInfrastructureRoleDefinitions(t *testing.T) {
    	var testTable = []struct {
    		rolesDefs      []*config.InfrastructureRole
    		roleSecretName spec.NamespacedName
    		roleSecrets    string
    		expectedDefs   []*config.InfrastructureRole
    	}{
    		// only new CRD format
    		{
    			[]*config.InfrastructureRole{
    				&config.InfrastructureRole{
    					SecretName: spec.NamespacedName{
    						Namespace: v1.NamespaceDefault,
    						Name:      testInfrastructureRolesNewSecretName,
    					},
    					UserKey:     "test-user",
    					PasswordKey: "test-password",
    					RoleKey:     "test-role",
    					Template:    false,
    				},
    			},
    			spec.NamespacedName{},
    			"",
    			[]*config.InfrastructureRole{
    				&config.InfrastructureRole{
    					SecretName: spec.NamespacedName{
    						Namespace: v1.NamespaceDefault,
    						Name:      testInfrastructureRolesNewSecretName,
    					},
    					UserKey:     "test-user",
    					PasswordKey: "test-password",
    					RoleKey:     "test-role",
    					Template:    false,
    				},
    			},
    		},
    		// only new configmap format
    		{
    			[]*config.InfrastructureRole{},
    			spec.NamespacedName{},
    			"secretname: infrastructureroles-new-test, userkey: test-user, passwordkey: test-password, rolekey: test-role",
    			[]*config.InfrastructureRole{
    				&config.InfrastructureRole{
    					SecretName: spec.NamespacedName{
    						Namespace: v1.NamespaceDefault,
    						Name:      testInfrastructureRolesNewSecretName,
    					},
    					UserKey:     "test-user",
    					PasswordKey: "test-password",
    					RoleKey:     "test-role",
    					Template:    false,
    				},
    			},
    		},
    		// new configmap format with defaultRoleValue
    		{
    			[]*config.InfrastructureRole{},
    			spec.NamespacedName{},
    			"secretname: infrastructureroles-new-test, userkey: test-user, passwordkey: test-password, defaultrolevalue: test-role",
    			[]*config.InfrastructureRole{
    				&config.InfrastructureRole{
    					SecretName: spec.NamespacedName{
    						Namespace: v1.NamespaceDefault,
    						Name:      testInfrastructureRolesNewSecretName,
    					},
    					UserKey:          "test-user",
    					PasswordKey:      "test-password",
    					DefaultRoleValue: "test-role",
    					Template:         false,
    				},
    			},
    		},
    		// only old CRD and configmap format
    		{
    			[]*config.InfrastructureRole{},
    			spec.NamespacedName{
    				Namespace: v1.NamespaceDefault,
    				Name:      testInfrastructureRolesOldSecretName,
    			},
    			"",
    			[]*config.InfrastructureRole{
    				&config.InfrastructureRole{
    					SecretName: spec.NamespacedName{
    						Namespace: v1.NamespaceDefault,
    						Name:      testInfrastructureRolesOldSecretName,
    					},
    					UserKey:     "user",
    					PasswordKey: "password",
    					RoleKey:     "inrole",
    					Template:    true,
    				},
    			},
    		},
    		// both formats for CRD
    		{
    			[]*config.InfrastructureRole{
    				&config.InfrastructureRole{
    					SecretName: spec.NamespacedName{
    						Namespace: v1.NamespaceDefault,
    						Name:      testInfrastructureRolesNewSecretName,
    					},
    					UserKey:     "test-user",
    					PasswordKey: "test-password",
    					RoleKey:     "test-role",
    					Template:    false,
    				},
    			},
    			spec.NamespacedName{
    				Namespace: v1.NamespaceDefault,
    				Name:      testInfrastructureRolesOldSecretName,
    			},
    			"",
    			[]*config.InfrastructureRole{
    				&config.InfrastructureRole{
    					SecretName: spec.NamespacedName{
    						Namespace: v1.NamespaceDefault,
    						Name:      testInfrastructureRolesNewSecretName,
    					},
    					UserKey:     "test-user",
    					PasswordKey: "test-password",
    					RoleKey:     "test-role",
    					Template:    false,
    				},
    				&config.InfrastructureRole{
    					SecretName: spec.NamespacedName{
    						Namespace: v1.NamespaceDefault,
    						Name:      testInfrastructureRolesOldSecretName,
    					},
    					UserKey:     "user",
    					PasswordKey: "password",
    					RoleKey:     "inrole",
    					Template:    true,
    				},
    			},
    		},
    		// both formats for configmap
    		{
    			[]*config.InfrastructureRole{},
    			spec.NamespacedName{
    				Namespace: v1.NamespaceDefault,
    				Name:      testInfrastructureRolesOldSecretName,
    			},
    			"secretname: infrastructureroles-new-test, userkey: test-user, passwordkey: test-password, rolekey: test-role",
    			[]*config.InfrastructureRole{
    				&config.InfrastructureRole{
    					SecretName: spec.NamespacedName{
    						Namespace: v1.NamespaceDefault,
    						Name:      testInfrastructureRolesNewSecretName,
    					},
    					UserKey:     "test-user",
    					PasswordKey: "test-password",
    					RoleKey:     "test-role",
    					Template:    false,
    				},
    				&config.InfrastructureRole{
    					SecretName: spec.NamespacedName{
    						Namespace: v1.NamespaceDefault,
    						Name:      testInfrastructureRolesOldSecretName,
    					},
    					UserKey:     "user",
    					PasswordKey: "password",
    					RoleKey:     "inrole",
    					Template:    true,
    				},
    			},
    		},
    		// incorrect configmap format
    		{
    			[]*config.InfrastructureRole{},
    			spec.NamespacedName{},
    			"wrong-format",
    			[]*config.InfrastructureRole{},
    		},
    		// configmap without a secret
    		{
    			[]*config.InfrastructureRole{},
    			spec.NamespacedName{},
    			"userkey: test-user, passwordkey: test-password, rolekey: test-role",
    			[]*config.InfrastructureRole{},
    		},
    	}
    
    	for _, test := range testTable {
    		t.Logf("Test: %+v", test)
    		utilTestController.opConfig.InfrastructureRoles = test.rolesDefs
    		utilTestController.opConfig.InfrastructureRolesSecretName = test.roleSecretName
    		utilTestController.opConfig.InfrastructureRolesDefs = test.roleSecrets
    
    		defs := utilTestController.getInfrastructureRoleDefinitions()
    		if len(defs) != len(test.expectedDefs) {
    			t.Errorf("expected definitions does not match the actual:\n%#v\n%#v",
    				test.expectedDefs, defs)
    
    			// Stop and do not do any further checks
    			return
    		}
    
    		for idx := range defs {
    			def := defs[idx]
    			expectedDef := test.expectedDefs[idx]
    
    			if !reflect.DeepEqual(def, expectedDef) {
    				t.Errorf("expected definition/the actual:\n%#v\n%#v",
    					expectedDef, def)
    			}
    		}
    	}
    }
    
    type SubConfig struct {
    	teammap map[string]string
    }
    
    type SuperConfig struct {
    	sub SubConfig
    }
    
    func TestUnderstandingMapsAndReferences(t *testing.T) {
    	teams := map[string]string{"acid": "Felix"}
    
    	sc := SubConfig{
    		teammap: teams,
    	}
    
    	ssc := SuperConfig{
    		sub: sc,
    	}
    
    	teams["24x7"] = "alex"
    
    	if len(ssc.sub.teammap) != 2 {
    		t.Errorf("Team Map does not contain 2 elements")
    	}
    
    	ssc.sub.teammap["teapot"] = "Mikkel"
    
    	if len(teams) != 3 {
    		t.Errorf("Team Map does not contain 3 elements")
    	}
    
    	teams = make(map[string]string)
    
    	if len(ssc.sub.teammap) != 3 {
    		t.Errorf("Team Map does not contain 0 elements")
    	}
    
    	if &teams == &(ssc.sub.teammap) {
    		t.Errorf("Identical maps")
    	}
    }