Files
crawlab/core/models/common/index_utils_test.go
Marvin Zhang dc59599509 refactor: remove db module and update imports to core/mongo
- Deleted the db module, consolidating database-related functionality into the core/mongo package for better organization and maintainability.
- Updated all import paths across the codebase to replace references to the removed db module with core/mongo.
- Cleaned up unused code and dependencies, enhancing overall project clarity and reducing complexity.
- This refactor improves the structure of the codebase by centralizing database operations and simplifying module management.
2024-12-25 10:28:21 +08:00

166 lines
3.9 KiB
Go

package common
import (
"fmt"
"github.com/crawlab-team/crawlab/core/mongo"
"testing"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/bson"
mongo2 "go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func TestRecreateIndexes(t *testing.T) {
// Setup test collection
testCol := mongo.GetMongoCol("test_collection")
defer func() {
_ = testCol.GetCollection().Drop(testCol.GetContext())
}()
// Test cases
tests := []struct {
name string
desiredIndexes []mongo2.IndexModel
expectedCount int64
}{
{
name: "Create new indexes",
desiredIndexes: []mongo2.IndexModel{
{Keys: bson.D{{Key: "field1", Value: 1}}},
{Keys: bson.D{{Key: "field2", Value: -1}}},
},
expectedCount: 3, // Including _id index
},
{
name: "Update existing indexes",
desiredIndexes: []mongo2.IndexModel{
{Keys: bson.D{{Key: "field1", Value: 1}}},
{Keys: bson.D{{Key: "field3", Value: 1}}},
},
expectedCount: 3,
},
{
name: "Compound indexes",
desiredIndexes: []mongo2.IndexModel{
{Keys: bson.D{
{Key: "field1", Value: 1},
{Key: "field2", Value: -1},
}},
{Keys: bson.D{
{Key: "field3", Value: 1},
{Key: "field4", Value: 1},
}},
},
expectedCount: 3,
},
{
name: "Unique and sparse indexes",
desiredIndexes: []mongo2.IndexModel{
{
Keys: bson.D{{Key: "email", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "optional_field", Value: 1}},
Options: options.Index().SetSparse(true),
},
},
expectedCount: 3,
},
{
name: "Mixed index types",
desiredIndexes: []mongo2.IndexModel{
{Keys: bson.D{
{Key: "field1", Value: 1},
{Key: "field2", Value: -1},
}},
{
Keys: bson.D{{Key: "unique_field", Value: 1}},
Options: options.Index().SetUnique(true),
},
},
expectedCount: 3,
},
{
name: "Complex compound index with options",
desiredIndexes: []mongo2.IndexModel{
{
Keys: bson.D{
{Key: "category", Value: 1},
{Key: "timestamp", Value: -1},
{Key: "status", Value: 1},
},
Options: options.Index().
SetUnique(true).
SetPartialFilterExpression(bson.D{
{Key: "status", Value: "active"},
}),
},
},
expectedCount: 2,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Execute CreateIndexes
CreateIndexes(testCol, tt.desiredIndexes)
// Verify indexes
indexes, err := testCol.ListIndexes()
assert.NoError(t, err)
// Check total number of indexes (including _id)
assert.Equal(t, tt.expectedCount, int64(len(indexes)))
// Verify each desired index exists
for _, desiredIdx := range tt.desiredIndexes {
found := false
// Convert bson.D to normalized string representation
desiredKeyDoc := desiredIdx.Keys.(bson.D)
desiredKeyMap := make(map[string]interface{})
for _, elem := range desiredKeyDoc {
desiredKeyMap[elem.Key] = elem.Value
}
for _, existingIdx := range indexes {
if existingIdx["name"].(string) != "_id_" {
existingKey := existingIdx["key"].(map[string]interface{})
// Compare maps by converting to strings and normalizing
if compareIndexKeys(desiredKeyMap, existingKey) {
found = true
break
}
}
}
assert.True(t, found, "Index not found: %v", desiredIdx.Keys)
}
})
}
}
// compareIndexKeys compares two index key specifications
func compareIndexKeys(desired, existing map[string]interface{}) bool {
if len(desired) != len(existing) {
return false
}
for k, v1 := range desired {
v2, exists := existing[k]
if !exists {
return false
}
// Convert values to strings for comparison
// This handles different numeric types (int, float64, etc.)
str1 := fmt.Sprintf("%v", v1)
str2 := fmt.Sprintf("%v", v2)
if str1 != str2 {
return false
}
}
return true
}