fix unit test for new subPathExpr feature (#2638)

* fix unit test for new subPathExpr feature
* add subPathExpr flag to CRD and re-sort
This commit is contained in:
Felix Kunde 2024-05-24 15:07:17 +02:00 committed by GitHub
parent 7bcb73a402
commit b550f8ae39
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 78 additions and 52 deletions

View File

@ -87,10 +87,14 @@ spec:
- mountPath - mountPath
- volumeSource - volumeSource
properties: properties:
isSubPathExpr:
type: boolean
name: name:
type: string type: string
mountPath: mountPath:
type: string type: string
subPath:
type: string
targetContainers: targetContainers:
type: array type: array
nullable: true nullable: true
@ -99,10 +103,6 @@ spec:
volumeSource: volumeSource:
type: object type: object
x-kubernetes-preserve-unknown-fields: true x-kubernetes-preserve-unknown-fields: true
subPath:
type: string
isSubPathExpr:
type: boolean
allowedSourceRanges: allowedSourceRanges:
type: array type: array
nullable: true nullable: true
@ -636,6 +636,8 @@ spec:
required: required:
- size - size
properties: properties:
isSubPathExpr:
type: boolean
iops: iops:
type: integer type: integer
selector: selector:

View File

@ -485,6 +485,9 @@ properties of the persistent storage that stores Postgres data.
* **subPath** * **subPath**
Subpath to use when mounting volume into Spilo container. Optional. Subpath to use when mounting volume into Spilo container. Optional.
* **isSubPathExpr**
Set it to true if the specified subPath is an expression. Optional.
* **iops** * **iops**
When running the operator on AWS the latest generation of EBS volumes (`gp3`) When running the operator on AWS the latest generation of EBS volumes (`gp3`)
allows for configuring the number of IOPS. Maximum is 16000. Optional. allows for configuring the number of IOPS. Maximum is 16000. Optional.

View File

@ -68,6 +68,8 @@ spec:
# matchLabels: # matchLabels:
# environment: dev # environment: dev
# service: postgres # service: postgres
# subPath: $(NODE_NAME)/$(POD_NAME)
# isSubPathExpr: true
additionalVolumes: additionalVolumes:
- name: empty - name: empty
mountPath: /opt/empty mountPath: /opt/empty

View File

@ -85,10 +85,14 @@ spec:
- mountPath - mountPath
- volumeSource - volumeSource
properties: properties:
isSubPathExpr:
type: boolean
name: name:
type: string type: string
mountPath: mountPath:
type: string type: string
subPath:
type: string
targetContainers: targetContainers:
type: array type: array
nullable: true nullable: true
@ -97,10 +101,6 @@ spec:
volumeSource: volumeSource:
type: object type: object
x-kubernetes-preserve-unknown-fields: true x-kubernetes-preserve-unknown-fields: true
subPath:
type: string
isSubPathExpr:
type: boolean
allowedSourceRanges: allowedSourceRanges:
type: array type: array
nullable: true nullable: true
@ -634,6 +634,8 @@ spec:
required: required:
- size - size
properties: properties:
isSubPathExpr:
type: boolean
iops: iops:
type: integer type: integer
selector: selector:

View File

@ -146,12 +146,18 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
Type: "object", Type: "object",
Required: []string{"name", "mountPath", "volumeSource"}, Required: []string{"name", "mountPath", "volumeSource"},
Properties: map[string]apiextv1.JSONSchemaProps{ Properties: map[string]apiextv1.JSONSchemaProps{
"isSubPathExpr": {
Type: "boolean",
},
"name": { "name": {
Type: "string", Type: "string",
}, },
"mountPath": { "mountPath": {
Type: "string", Type: "string",
}, },
"subPath": {
Type: "string",
},
"targetContainers": { "targetContainers": {
Type: "array", Type: "array",
Nullable: true, Nullable: true,
@ -165,12 +171,6 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
Type: "object", Type: "object",
XPreserveUnknownFields: util.True(), XPreserveUnknownFields: util.True(),
}, },
"subPath": {
Type: "string",
},
"isSubPathExpr": {
Type: "boolean",
},
}, },
}, },
}, },
@ -1033,6 +1033,9 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
Type: "object", Type: "object",
Required: []string{"size"}, Required: []string{"size"},
Properties: map[string]apiextv1.JSONSchemaProps{ Properties: map[string]apiextv1.JSONSchemaProps{
"isSubPathExpr": {
Type: "boolean",
},
"iops": { "iops": {
Type: "integer", Type: "integer",
}, },

View File

@ -129,13 +129,14 @@ type MaintenanceWindow struct {
// Volume describes a single volume in the manifest. // Volume describes a single volume in the manifest.
type Volume struct { type Volume struct {
Selector *metav1.LabelSelector `json:"selector,omitempty"` Selector *metav1.LabelSelector `json:"selector,omitempty"`
Size string `json:"size"` Size string `json:"size"`
StorageClass string `json:"storageClass,omitempty"` StorageClass string `json:"storageClass,omitempty"`
SubPath string `json:"subPath,omitempty"` SubPath string `json:"subPath,omitempty"`
Iops *int64 `json:"iops,omitempty"` IsSubPathExpr *bool `json:"isSubPathExpr,omitemtpy"`
Throughput *int64 `json:"throughput,omitempty"` Iops *int64 `json:"iops,omitempty"`
VolumeType string `json:"type,omitempty"` Throughput *int64 `json:"throughput,omitempty"`
VolumeType string `json:"type,omitempty"`
} }
// AdditionalVolume specs additional optional volumes for statefulset // AdditionalVolume specs additional optional volumes for statefulset
@ -143,7 +144,7 @@ type AdditionalVolume struct {
Name string `json:"name"` Name string `json:"name"`
MountPath string `json:"mountPath"` MountPath string `json:"mountPath"`
SubPath string `json:"subPath,omitempty"` SubPath string `json:"subPath,omitempty"`
IsSubPathExpr bool `json:"isSubPathExpr,omitemtpy"` IsSubPathExpr *bool `json:"isSubPathExpr,omitemtpy"`
TargetContainers []string `json:"targetContainers"` TargetContainers []string `json:"targetContainers"`
VolumeSource v1.VolumeSource `json:"volumeSource"` VolumeSource v1.VolumeSource `json:"volumeSource"`
} }

View File

@ -53,6 +53,11 @@ func (in *AWSGCPConfiguration) DeepCopy() *AWSGCPConfiguration {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AdditionalVolume) DeepCopyInto(out *AdditionalVolume) { func (in *AdditionalVolume) DeepCopyInto(out *AdditionalVolume) {
*out = *in *out = *in
if in.IsSubPathExpr != nil {
in, out := &in.IsSubPathExpr, &out.IsSubPathExpr
*out = new(bool)
**out = **in
}
if in.TargetContainers != nil { if in.TargetContainers != nil {
in, out := &in.TargetContainers, &out.TargetContainers in, out := &in.TargetContainers, &out.TargetContainers
*out = make([]string, len(*in)) *out = make([]string, len(*in))
@ -1447,6 +1452,11 @@ func (in *Volume) DeepCopyInto(out *Volume) {
*out = new(metav1.LabelSelector) *out = new(metav1.LabelSelector)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
if in.IsSubPathExpr != nil {
in, out := &in.IsSubPathExpr, &out.IsSubPathExpr
*out = new(bool)
**out = **in
}
if in.Iops != nil { if in.Iops != nil {
in, out := &in.Iops, &out.Iops in, out := &in.Iops, &out.Iops
*out = new(int64) *out = new(int64)

View File

@ -668,13 +668,19 @@ func isBootstrapOnlyParameter(param string) bool {
} }
func generateVolumeMounts(volume acidv1.Volume) []v1.VolumeMount { func generateVolumeMounts(volume acidv1.Volume) []v1.VolumeMount {
return []v1.VolumeMount{ volumeMount := []v1.VolumeMount{
{ {
Name: constants.DataVolumeName, Name: constants.DataVolumeName,
MountPath: constants.PostgresDataMount, //TODO: fetch from manifest MountPath: constants.PostgresDataMount, //TODO: fetch from manifest
SubPath: volume.SubPath,
}, },
} }
if volume.IsSubPathExpr != nil && *volume.IsSubPathExpr {
volumeMount[0].SubPathExpr = volume.SubPath
} else {
volumeMount[0].SubPath = volume.SubPath
}
return volumeMount
} }
func generateContainer( func generateContainer(
@ -1825,7 +1831,7 @@ func (c *Cluster) addAdditionalVolumes(podSpec *v1.PodSpec,
MountPath: additionalVolume.MountPath, MountPath: additionalVolume.MountPath,
} }
if additionalVolume.IsSubPathExpr { if additionalVolume.IsSubPathExpr != nil && *additionalVolume.IsSubPathExpr {
v.SubPathExpr = additionalVolume.SubPath v.SubPathExpr = additionalVolume.SubPath
} else { } else {
v.SubPath = additionalVolume.SubPath v.SubPath = additionalVolume.SubPath

View File

@ -1902,7 +1902,7 @@ func TestAdditionalVolume(t *testing.T) {
Name: "test6", Name: "test6",
MountPath: "/test6", MountPath: "/test6",
SubPath: "$(POD_NAME)", SubPath: "$(POD_NAME)",
IsSubPathExpr: true, IsSubPathExpr: util.True(),
TargetContainers: nil, // should mount only to postgres TargetContainers: nil, // should mount only to postgres
VolumeSource: v1.VolumeSource{ VolumeSource: v1.VolumeSource{
EmptyDir: &v1.EmptyDirVolumeSource{}, EmptyDir: &v1.EmptyDirVolumeSource{},
@ -1922,7 +1922,9 @@ func TestAdditionalVolume(t *testing.T) {
ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: acidv1.Volume{ Volume: acidv1.Volume{
Size: "1G", Size: "1G",
SubPath: "$(POD_NAME)",
IsSubPathExpr: util.True(),
}, },
AdditionalVolumes: additionalVolumes, AdditionalVolumes: additionalVolumes,
Sidecars: []acidv1.Sidecar{ Sidecars: []acidv1.Sidecar{
@ -1954,31 +1956,25 @@ func TestAdditionalVolume(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
tests := []struct { tests := []struct {
subTest string subTest string
container string container string
expectedMounts []string expectedMounts []string
expectedSubPath []string expectedSubPaths []string
expectedSubPathExprs []string
}{ }{
{ {
subTest: "checking volume mounts of postgres container", subTest: "checking volume mounts of postgres container",
container: constants.PostgresContainerName, container: constants.PostgresContainerName,
expectedMounts: []string{"pgdata", "test1", "test3", "test4"}, expectedMounts: []string{"pgdata", "test1", "test3", "test4", "test5", "test6"},
expectedSubPaths: []string{"", "", "", "", "subpath", ""},
expectedSubPathExprs: []string{"$(POD_NAME)", "", "", "", "", "$(POD_NAME)"},
}, },
{ {
subTest: "checking volume mounts of sidecar container", subTest: "checking volume mounts of sidecar container",
container: "sidecar", container: "sidecar",
expectedMounts: []string{"pgdata", "test1", "test2"}, expectedMounts: []string{"pgdata", "test1", "test2"},
}, expectedSubPaths: []string{"", "", ""},
{ expectedSubPathExprs: []string{"$(POD_NAME)", "", ""},
subTest: "checking volume mounts with subPath",
container: constants.PostgresContainerName,
expectedMounts: []string{"test5"},
expectedSubPath: []string{"subpath"},
},
{
subTest: "checking volume mounts with subPathExpr",
container: constants.PostgresContainerName,
expectedMounts: []string{"test6"},
}, },
} }
@ -1990,6 +1986,7 @@ func TestAdditionalVolume(t *testing.T) {
mounts := []string{} mounts := []string{}
subPaths := []string{} subPaths := []string{}
subPathExprs := []string{} subPathExprs := []string{}
for _, volumeMounts := range container.VolumeMounts { for _, volumeMounts := range container.VolumeMounts {
mounts = append(mounts, volumeMounts.Name) mounts = append(mounts, volumeMounts.Name)
subPaths = append(subPaths, volumeMounts.SubPath) subPaths = append(subPaths, volumeMounts.SubPath)
@ -2001,14 +1998,14 @@ func TestAdditionalVolume(t *testing.T) {
t.Name(), tt.subTest, mounts, tt.expectedMounts) t.Name(), tt.subTest, mounts, tt.expectedMounts)
} }
if !util.IsEqualIgnoreOrder(subPaths, tt.expectedSubPath) { if !util.IsEqualIgnoreOrder(subPaths, tt.expectedSubPaths) {
t.Errorf("%s %s: different volume subPaths: got %v, expected %v", t.Errorf("%s %s: different volume subPaths: got %v, expected %v",
t.Name(), tt.subTest, mounts, tt.expectedSubPath) t.Name(), tt.subTest, subPaths, tt.expectedSubPaths)
} }
if !util.IsEqualIgnoreOrder(subPathExprs, []string{container.Name}) { if !util.IsEqualIgnoreOrder(subPathExprs, tt.expectedSubPathExprs) {
t.Errorf("%s %s: different volume subPathExprs: got %v, expected %v", t.Errorf("%s %s: different volume subPathExprs: got %v, expected %v",
t.Name(), tt.subTest, mounts, tt.expectedMounts) t.Name(), tt.subTest, subPathExprs, tt.expectedSubPathExprs)
} }
} }
} }