diff --git a/pkg/reconciler/topology/partitionset/partitioning_test.go b/pkg/reconciler/topology/partitionset/partitioning_test.go index 6f0335e7630..40231603302 100644 --- a/pkg/reconciler/topology/partitionset/partitioning_test.go +++ b/pkg/reconciler/topology/partitionset/partitioning_test.go @@ -135,6 +135,12 @@ func TestPartition(t *testing.T) { for _, v := range matchLabelsMap { require.Equal(t, "prod", v["environment"], "Expected that all partitions have a label selector for environment = prod") } + + matchLabelsMap = partition(shards, []string{"region", "environment"}, map[string]string{"environment": "prod"}) + require.Equal(t, map[string]map[string]string{ + "+environment=prod+region=Asia": {"environment": "prod", "region": "Asia"}, + "+environment=prod+region=Europe": {"environment": "prod", "region": "Europe"}, + }, matchLabelsMap, "Labels being both a dimension and in the shard selector should only be considered once") } func TestGeneratePartitionName(t *testing.T) { diff --git a/pkg/reconciler/topology/partitionset/partitionset_controller_test.go b/pkg/reconciler/topology/partitionset/partitionset_controller_test.go index 2efb014228c..ff65e748198 100644 --- a/pkg/reconciler/topology/partitionset/partitionset_controller_test.go +++ b/pkg/reconciler/topology/partitionset/partitionset_controller_test.go @@ -92,6 +92,13 @@ func TestReconcile(t *testing.T) { wantPartitionCount: 2, wantCountCreated: 2, }, + "Existing partition kept with selector and dimension overlapping": { + withMatchLabelOverlap: true, + existingValidPartition: true, + wantPartitionsReady: true, + wantPartitionCount: 2, + wantCountCreated: 1, + }, } for name, tc := range tests { diff --git a/pkg/reconciler/topology/partitionset/partitionset_reconcile.go b/pkg/reconciler/topology/partitionset/partitionset_reconcile.go index 1e9b89c5326..3dd1fd52e72 100644 --- a/pkg/reconciler/topology/partitionset/partitionset_reconcile.go +++ b/pkg/reconciler/topology/partitionset/partitionset_reconcile.go @@ -196,12 +196,11 @@ func (c *controller) reconcile(ctx context.Context, partitionSet *topologyv1alph // so that Partitions not referring to any Shard would not get created. func partition(shards []*corev1alpha1.Shard, dimensions []string, shardSelectorLabels map[string]string) (matchLabelsMap map[string]map[string]string) { matchLabelsMap = make(map[string]map[string]string) - l := make([]string, len(dimensions), len(dimensions)+len(shardSelectorLabels)) - copy(l, dimensions) - for label := range shardSelectorLabels { - l = append(l, label) - } - sort.Strings(l) // Sorting for consistent comparison. + // A label can be both a dimension and part of the shard selector matchLabels. + // It must only be considered once, otherwise the generated key would not + // match the one computed from the matchLabels of existing Partitions. + // sets.List returns the labels sorted for consistent comparison. + l := sets.List(sets.KeySet(shardSelectorLabels).Insert(dimensions...)) for _, shard := range shards { key := "" selector := make(map[string]string)