Spaces:
Running
Running
// _ _ | |
// __ _____ __ ___ ___ __ _| |_ ___ | |
// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ | |
// \ V V / __/ (_| |\ V /| | (_| | || __/ | |
// \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| | |
// | |
// Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. | |
// | |
// CONTACT: [email protected] | |
// | |
package replica | |
import ( | |
"fmt" | |
"testing" | |
"github.com/stretchr/testify/assert" | |
"github.com/stretchr/testify/require" | |
"github.com/weaviate/weaviate/entities/models" | |
"github.com/weaviate/weaviate/entities/replication" | |
) | |
func Test_ValidateConfig(t *testing.T) { | |
tests := []struct { | |
name string | |
initialconfig *models.ReplicationConfig | |
resultConfig *models.ReplicationConfig | |
globalConfig replication.GlobalConfig | |
expectedErr error | |
}{ | |
{ | |
name: "config not provided", | |
initialconfig: nil, | |
resultConfig: &models.ReplicationConfig{Factor: 1}, | |
globalConfig: replication.GlobalConfig{MinimumFactor: 1}, | |
}, | |
{ | |
name: "config not provided - global minimum is 2", | |
initialconfig: nil, | |
resultConfig: &models.ReplicationConfig{Factor: 2}, | |
globalConfig: replication.GlobalConfig{MinimumFactor: 2}, | |
}, | |
{ | |
name: "config provided, factor not provided", | |
initialconfig: &models.ReplicationConfig{}, | |
resultConfig: &models.ReplicationConfig{Factor: 1}, | |
globalConfig: replication.GlobalConfig{MinimumFactor: 1}, | |
}, | |
{ | |
name: "config provided, factor < 0", | |
initialconfig: &models.ReplicationConfig{Factor: -1}, | |
resultConfig: &models.ReplicationConfig{Factor: 1}, | |
globalConfig: replication.GlobalConfig{MinimumFactor: 1}, | |
}, | |
{ | |
name: "config provided, valid factor", | |
initialconfig: &models.ReplicationConfig{Factor: 7}, | |
resultConfig: &models.ReplicationConfig{Factor: 7}, | |
}, | |
{ | |
name: "explicitly trying to bypass the minimum leads to error", | |
initialconfig: &models.ReplicationConfig{Factor: 1}, | |
resultConfig: &models.ReplicationConfig{Factor: 1}, | |
globalConfig: replication.GlobalConfig{MinimumFactor: 2}, | |
expectedErr: fmt.Errorf("invalid replication factor: setup requires a minimum replication factor of 2: got 1"), | |
}, | |
} | |
for _, test := range tests { | |
t.Run(test.name, func(t *testing.T) { | |
class := &models.Class{ | |
ReplicationConfig: test.initialconfig, | |
} | |
err := ValidateConfig(class, test.globalConfig) | |
if test.expectedErr != nil { | |
assert.EqualError(t, test.expectedErr, err.Error()) | |
} else { | |
assert.Nil(t, err) | |
assert.EqualValues(t, test.resultConfig, class.ReplicationConfig) | |
} | |
}) | |
} | |
} | |
func Test_ValidateConfigUpdate(t *testing.T) { | |
tests := []struct { | |
name string | |
initial *models.ReplicationConfig | |
update *models.ReplicationConfig | |
expectedError error | |
}{ | |
{ | |
name: "attempting to increase replicas beyond cluster size", | |
initial: &models.ReplicationConfig{Factor: 3}, | |
update: &models.ReplicationConfig{Factor: 4}, | |
expectedError: fmt.Errorf( | |
"cannot scale to 4 replicas, cluster has only 3 nodes"), | |
}, | |
} | |
for _, test := range tests { | |
t.Run(test.name, func(t *testing.T) { | |
err := ValidateConfigUpdate( | |
&models.Class{ReplicationConfig: test.initial}, | |
&models.Class{ReplicationConfig: test.update}, | |
&fakeNodeCounter{3}) | |
if test.expectedError == nil { | |
assert.Nil(t, err) | |
} else { | |
require.NotNil(t, err, "update validation must error") | |
assert.Equal(t, test.expectedError.Error(), err.Error()) | |
} | |
}) | |
} | |
} | |
type fakeNodeCounter struct{ count int } | |
func (f *fakeNodeCounter) NodeCount() int { | |
return f.count | |
} | |