Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 1 | package percona_xtradb_cluster |
| 2 | |
| 3 | import ( |
| 4 | _ "embed" |
| 5 | "fmt" |
| 6 | "io" |
| 7 | "net/http" |
| 8 | "os" |
| 9 | "regexp" |
| 10 | "strings" |
| 11 | "testing" |
| 12 | |
| 13 | "github.com/goccy/go-yaml" |
| 14 | "github.com/stretchr/testify/assert" |
| 15 | "github.com/stretchr/testify/require" |
| 16 | "github.com/vexxhost/atmosphere/roles/defaults" |
| 17 | "gopkg.in/ini.v1" |
| 18 | "helm.sh/helm/v3/pkg/chart/loader" |
| 19 | v1 "k8s.io/api/core/v1" |
| 20 | "k8s.io/apimachinery/pkg/api/resource" |
| 21 | |
| 22 | pxc_v1 "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1" |
| 23 | ) |
| 24 | |
| 25 | var ( |
| 26 | //go:embed vars/main.yml |
Mohammed Naser | 59853d4 | 2023-11-29 20:32:24 -0500 | [diff] [blame] | 27 | varsFile []byte |
| 28 | vars Vars |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 29 | ) |
| 30 | |
| 31 | type Vars struct { |
| 32 | PerconaXtraDBClusterSpec pxc_v1.PerconaXtraDBClusterSpec `yaml:"_percona_xtradb_cluster_spec"` |
| 33 | } |
| 34 | |
| 35 | func TestMain(m *testing.M) { |
| 36 | t := &testing.T{} |
| 37 | |
Mohammed Naser | 59853d4 | 2023-11-29 20:32:24 -0500 | [diff] [blame] | 38 | err := yaml.UnmarshalWithOptions(varsFile, &vars, yaml.Strict(), yaml.UseJSONUnmarshaler()) |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 39 | require.NoError(t, err) |
| 40 | |
| 41 | code := m.Run() |
| 42 | os.Exit(code) |
| 43 | } |
| 44 | |
| 45 | func TestPerconaXtraDBClusterSpec(t *testing.T) { |
| 46 | chart, err := loader.LoadDir("../../charts/pxc-operator") |
| 47 | require.NoError(t, err) |
| 48 | |
| 49 | assert.Equal(t, chart.AppVersion(), vars.PerconaXtraDBClusterSpec.CRVersion) |
| 50 | assert.Equal(t, "percona-xtradb", vars.PerconaXtraDBClusterSpec.SecretsName) |
| 51 | } |
| 52 | |
| 53 | func TestPerconaXtraDBClusterPXCSpec(t *testing.T) { |
| 54 | assert.Equal(t, int32(3), vars.PerconaXtraDBClusterSpec.PXC.Size) |
| 55 | assert.Equal(t, true, *vars.PerconaXtraDBClusterSpec.PXC.AutoRecovery) |
Oleksandr K. | 99651a6 | 2024-10-30 04:41:51 +0100 | [diff] [blame] | 56 | defaults.AssertAtmosphereImage(t, "docker.io/percona/percona-xtradb-cluster:8.0.36-28.1", vars.PerconaXtraDBClusterSpec.PXC.Image) |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 57 | |
| 58 | assert.Equal(t, map[string]string{ |
| 59 | "openstack-control-plane": "enabled", |
| 60 | }, vars.PerconaXtraDBClusterSpec.PXC.NodeSelector) |
| 61 | |
| 62 | assert.Equal(t, &pxc_v1.VolumeSpec{ |
| 63 | PersistentVolumeClaim: &v1.PersistentVolumeClaimSpec{ |
Mohammed Naser | d669de5 | 2024-01-02 08:45:01 -0500 | [diff] [blame] | 64 | Resources: v1.VolumeResourceRequirements{ |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 65 | Requests: v1.ResourceList{ |
| 66 | "storage": resource.MustParse("160Gi"), |
| 67 | }, |
| 68 | }, |
| 69 | }, |
| 70 | }, vars.PerconaXtraDBClusterSpec.PXC.VolumeSpec) |
| 71 | } |
| 72 | |
| 73 | func parsePXCConfiguration(t *testing.T, cfg string) *ini.File { |
| 74 | parsed, err := ini.LoadSources(ini.LoadOptions{ |
| 75 | AllowBooleanKeys: true, |
| 76 | }, []byte(cfg)) |
| 77 | require.NoError(t, err) |
| 78 | |
| 79 | return parsed |
| 80 | } |
| 81 | |
| 82 | func TestPerconaXtraDBClusterPXCConfiguration(t *testing.T) { |
| 83 | cfg := parsePXCConfiguration(t, vars.PerconaXtraDBClusterSpec.PXC.Configuration) |
| 84 | |
| 85 | section := cfg.Section("mysqld") |
| 86 | assert.Equal(t, 8192, section.Key("max_connections").MustInt()) |
| 87 | assert.Equal(t, "4096M", section.Key("innodb_buffer_pool_size").String()) |
| 88 | assert.Equal(t, "16M", section.Key("max_allowed_packet").String()) |
| 89 | assert.Equal(t, true, section.Key("skip-name-resolve").MustBool()) |
| 90 | } |
| 91 | |
| 92 | func TestPerconaXtraDBClusterPXCSidecarSpec(t *testing.T) { |
| 93 | sidecar := vars.PerconaXtraDBClusterSpec.PXC.Sidecars[0] |
| 94 | assert.Equal(t, "exporter", sidecar.Name) |
Oleksandr K. | 99651a6 | 2024-10-30 04:41:51 +0100 | [diff] [blame] | 95 | defaults.AssertAtmosphereImage(t, "quay.io/prometheus/mysqld-exporter:v0.15.1", sidecar.Image) |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 96 | |
| 97 | assert.Equal(t, v1.EnvVar{ |
Oleksandr K. | 99651a6 | 2024-10-30 04:41:51 +0100 | [diff] [blame] | 98 | Name: "MYSQLD_EXPORTER_PASSWORD", |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 99 | ValueFrom: &v1.EnvVarSource{ |
| 100 | SecretKeyRef: &v1.SecretKeySelector{ |
| 101 | LocalObjectReference: v1.LocalObjectReference{ |
| 102 | Name: vars.PerconaXtraDBClusterSpec.SecretsName, |
| 103 | }, |
| 104 | Key: "monitor", |
| 105 | }, |
| 106 | }, |
| 107 | }, sidecar.Env[0]) |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 108 | |
| 109 | assert.Equal(t, v1.ContainerPort{ |
| 110 | Name: "metrics", |
| 111 | ContainerPort: 9104, |
| 112 | }, sidecar.Ports[0]) |
| 113 | } |
| 114 | |
| 115 | func TestPerconaXtraDBClusterHAProxySpec(t *testing.T) { |
| 116 | assert.Equal(t, true, vars.PerconaXtraDBClusterSpec.HAProxy.Enabled) |
| 117 | assert.Equal(t, int32(3), vars.PerconaXtraDBClusterSpec.HAProxy.Size) |
| 118 | |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 119 | defaults.AssertAtmosphereImage(t, |
Oleksandr K. | 99651a6 | 2024-10-30 04:41:51 +0100 | [diff] [blame] | 120 | fmt.Sprintf("docker.io/percona/percona-xtradb-cluster-operator:%s-haproxy", vars.PerconaXtraDBClusterSpec.CRVersion), |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 121 | vars.PerconaXtraDBClusterSpec.HAProxy.Image, |
| 122 | ) |
| 123 | |
| 124 | assert.Equal(t, map[string]string{ |
| 125 | "openstack-control-plane": "enabled", |
| 126 | }, vars.PerconaXtraDBClusterSpec.HAProxy.NodeSelector) |
| 127 | } |
| 128 | |
| 129 | func TestPerconaXtraDBClusterHAProxyConfiguration(t *testing.T) { |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 130 | pxcConfig := parsePXCConfiguration(t, vars.PerconaXtraDBClusterSpec.PXC.Configuration) |
| 131 | maxConnections := pxcConfig.Section("mysqld").Key("max_connections").MustInt() |
| 132 | |
| 133 | // NOTE(mnaser): Since there is no way of overriding specific values, we pull |
| 134 | // the file from the Docker image, replace the maxconn value and |
| 135 | // then compare it. |
| 136 | |
| 137 | // Get the default HAproxy configuration |
Oleksandr K. | 99651a6 | 2024-10-30 04:41:51 +0100 | [diff] [blame] | 138 | configFileUrl := fmt.Sprintf("https://raw.githubusercontent.com/percona/percona-docker/pxc-operator-%s/haproxy/dockerdir/etc/haproxy/haproxy-global.cfg", vars.PerconaXtraDBClusterSpec.CRVersion) |
Mohammed Naser | 3b3507d | 2023-11-28 21:13:39 -0500 | [diff] [blame] | 139 | resp, err := http.Get(configFileUrl) |
| 140 | require.NoError(t, err) |
| 141 | defer resp.Body.Close() |
| 142 | haproxyConfigData, err := io.ReadAll(resp.Body) |
| 143 | require.NoError(t, err) |
| 144 | haproxyConfig := string(haproxyConfigData) |
| 145 | |
| 146 | // Replace the 4 spaces at the start of each line |
| 147 | regex := regexp.MustCompile("(?m)^ ") |
| 148 | haproxyConfig = regex.ReplaceAllString(haproxyConfig, "") |
| 149 | |
| 150 | // Replace the maxconn value |
| 151 | haproxyConfig = strings.Replace(haproxyConfig, "maxconn 2048", fmt.Sprintf("maxconn %d", maxConnections), 1) |
| 152 | assert.Contains(t, haproxyConfig, fmt.Sprintf("maxconn %d", maxConnections)) |
| 153 | |
| 154 | assert.Equal(t, |
| 155 | haproxyConfig, |
| 156 | vars.PerconaXtraDBClusterSpec.HAProxy.Configuration, |
| 157 | ) |
| 158 | } |