Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more test cases for index validation #2752

Merged
merged 17 commits into from
Jun 13, 2023
Merged
64 changes: 52 additions & 12 deletions integration/indexes_compat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
"github.com/FerretDB/FerretDB/integration/shareddata"
)

func TestIndexesCompatList(t *testing.T) {
func TestListIndexesCompat(t *testing.T) {
t.Parallel()

s := setup.SetupCompatWithOpts(t, &setup.SetupCompatOpts{
Expand Down Expand Up @@ -67,7 +67,7 @@ func TestIndexesCompatList(t *testing.T) {
}
}

func TestIndexesCompatCreate(t *testing.T) {
func TestCreateIndexesCompat(t *testing.T) {
setup.SkipForTigrisWithReason(t, "Indexes creation is not supported for Tigris")

t.Parallel()
Expand Down Expand Up @@ -304,55 +304,62 @@ func TestCreateIndexesCommandCompat(t *testing.T) {
resultType compatTestCaseResultType // defaults to nonEmptyResult
skip string // optional, skip test with a specified reason
}{
"invalid-collection-name": {
"InvalidCollectionName": {
collectionName: 42,
key: bson.D{{"v", -1}},
indexName: "custom-name",
resultType: emptyResult,
},
"nil-collection-name": {
"NilCollectionName": {
collectionName: nil,
key: bson.D{{"v", -1}},
indexName: "custom-name",
resultType: emptyResult,
},
"index-name-not-set": {
"EmptyCollectionName": {
collectionName: "",
key: bson.D{{"v", -1}},
indexName: "custom-name",
resultType: emptyResult,
skip: "https://github.com/FerretDB/FerretDB/issues/2311",
},
"IndexNameNotSet": {
collectionName: "test",
key: bson.D{{"v", -1}},
indexName: nil,
resultType: emptyResult,
skip: "https://github.com/FerretDB/FerretDB/issues/2311",
},
"empty-index-name": {
"EmptyIndexName": {
collectionName: "test",
key: bson.D{{"v", -1}},
indexName: "",
resultType: emptyResult,
skip: "https://github.com/FerretDB/FerretDB/issues/2311",
},
"non-string-index-name": {
"NonStringIndexName": {
collectionName: "test",
key: bson.D{{"v", -1}},
indexName: 42,
resultType: emptyResult,
},
"existing-name-different-key-length": {
"ExistingNameDifferentKeyLength": {
collectionName: "test",
key: bson.D{{"_id", 1}, {"v", 1}},
indexName: "_id_", // the same name as the default index
skip: "https://github.com/FerretDB/FerretDB/issues/2311",
},
"invalid-key": {
"InvalidKey": {
collectionName: "test",
key: 42,
resultType: emptyResult,
},
"empty-key": {
"EmptyKey": {
collectionName: "test",
key: bson.D{},
resultType: emptyResult,
},
"key-not-set": {
"KeyNotSet": {
collectionName: "test",
resultType: emptyResult,
skip: "https://github.com/FerretDB/FerretDB/issues/2311",
Expand Down Expand Up @@ -436,7 +443,7 @@ func TestCreateIndexesCommandCompat(t *testing.T) {
}
}

func TestIndexesCompatDrop(t *testing.T) {
func TestDropIndexesCompat(t *testing.T) {
setup.SkipForTigrisWithReason(t, "Indexes are not supported for Tigris")

t.Parallel()
Expand Down Expand Up @@ -483,6 +490,10 @@ func TestIndexesCompatDrop(t *testing.T) {
dropIndexName: "nonexistent_1",
resultType: emptyResult,
},
"Empty": {
dropIndexName: "",
resultType: emptyResult,
},
} {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
Expand Down Expand Up @@ -579,6 +590,22 @@ func TestDropIndexesCommandCompat(t *testing.T) {
},
toDrop: bson.A{"v_-1", "v_1_foo_1"},
},
"MultipleIndexesByKey": {
toCreate: []mongo.IndexModel{
{Keys: bson.D{{"v", -1}}},
{Keys: bson.D{{"v.foo", -1}}},
},
toDrop: bson.A{bson.D{{"v", -1}}, bson.D{{"v.foo", -1}}},
resultType: emptyResult,
},
"NonExistentMultipleIndexes": {
toDrop: bson.A{"non-existent", "invalid"},
resultType: emptyResult,
},
"InvalidMultipleIndexType": {
toDrop: bson.A{1},
resultType: emptyResult,
},
"DocumentIndex": {
toCreate: []mongo.IndexModel{
{Keys: bson.D{{"v", -1}}},
Expand All @@ -593,6 +620,19 @@ func TestDropIndexesCommandCompat(t *testing.T) {
},
toDrop: "*",
},
"WrongExpression": {
toCreate: []mongo.IndexModel{
{Keys: bson.D{{"v", -1}}},
{Keys: bson.D{{"foo.bar", 1}}},
{Keys: bson.D{{"foo", 1}, {"bar", 1}}},
},
toDrop: "***",
resultType: emptyResult,
},
"NonExistentDescendingID": {
toDrop: bson.D{{"_id", -1}},
resultType: emptyResult,
},
"MultipleKeyIndex": {
toCreate: []mongo.IndexModel{
{Keys: bson.D{{"_id", -1}, {"v", 1}}},
Expand Down
140 changes: 140 additions & 0 deletions integration/indexes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,143 @@ func TestIndexesDropCommandErrors(t *testing.T) {
})
}
}

func TestCreateIndexesInvalidSpec(t *testing.T) {
setup.SkipForTigrisWithReason(t, "Indexes are not supported for Tigris")

t.Parallel()

for name, tc := range map[string]struct {
indexes any
err *mongo.CommandError
altMessage string
skip string
}{
"EmptyIndexes": {
indexes: bson.A{},
err: &mongo.CommandError{
Code: 2,
Name: "BadValue",
Message: "Must specify at least one index to create",
},
},
"NilIndexes": {
indexes: nil,
err: &mongo.CommandError{
Code: 10065,
Name: "Location10065",
Message: "invalid parameter: expected an object (indexes)",
},
skip: "https://github.com/FerretDB/FerretDB/issues/2311",
},
"InvalidType": {
indexes: 42,
err: &mongo.CommandError{
Code: 14,
Name: "TypeMismatch",
Message: "BSON field 'createIndexes.indexes' is the wrong type 'int', expected type 'array'",
},
skip: "https://github.com/FerretDB/FerretDB/issues/2311",
},
} {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
if tc.skip != "" {
t.Skip(tc.skip)
}

t.Parallel()

provider := shareddata.ArrayDocuments // one provider is enough to check for errors
ctx, collection := setup.Setup(t, provider)

command := bson.D{
{"createIndexes", collection.Name()},
{"indexes", tc.indexes},
}

var res bson.D
err := collection.Database().RunCommand(ctx, command).Decode(&res)

require.Nil(t, res)
AssertEqualAltCommandError(t, *tc.err, tc.altMessage, err)
})
}
}

func TestDropIndexesInvalidCollection(t *testing.T) {
setup.SkipForTigrisWithReason(t, "Indexes are not supported for Tigris")

t.Parallel()

for name, tc := range map[string]struct {
collectionName any
indexName any
err *mongo.CommandError
altMessage string
skip string
}{
"NonExistentCollection": {
collectionName: "non-existent",
indexName: "index",
err: &mongo.CommandError{
Code: 26,
Name: "NamespaceNotFound",
Message: "ns not found TestDropIndexesInvalidCollection-NonExistentCollection.non-existent",
},
},
"InvalidTypeCollection": {
collectionName: 42,
indexName: "index",
err: &mongo.CommandError{
Code: 2,
Name: "BadValue",
Message: "collection name has invalid type int",
},
skip: "https://github.com/FerretDB/FerretDB/issues/2311",
},
"NilCollection": {
collectionName: nil,
indexName: "index",
err: &mongo.CommandError{
Code: 2,
Name: "BadValue",
Message: "collection name has invalid type null",
},
skip: "https://github.com/FerretDB/FerretDB/issues/2311",
},
"EmptyCollection": {
collectionName: "",
indexName: "index",
err: &mongo.CommandError{
Code: 73,
Name: "InvalidNamespace",
Message: "Invalid namespace specified 'TestIndexesDropInvalidCollection-EmptyCollection.'",
},
skip: "https://github.com/FerretDB/FerretDB/issues/2311",
},
} {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
if tc.skip != "" {
t.Skip(tc.skip)
}

t.Parallel()

provider := shareddata.ArrayDocuments // one provider is enough to check for errors
ctx, collection := setup.Setup(t, provider)

command := bson.D{
{"dropIndexes", tc.collectionName},
{"index", tc.indexName},
}

var res bson.D
err := collection.Database().RunCommand(ctx, command).Decode(&res)

require.Nil(t, res)
AssertEqualAltCommandError(t, *tc.err, tc.altMessage, err)
})
}
}
2 changes: 0 additions & 2 deletions internal/handlers/pg/msg_createindexes.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ func processIndexKey(keyDoc *types.Document) (pgdb.IndexKey, error) {
var orderParam int64

if orderParam, err = commonparams.GetWholeNumberParam(order); err != nil {
// TODO Add better validation and return proper error: https://github.com/FerretDB/FerretDB/issues/2311
chilagrow marked this conversation as resolved.
Show resolved Hide resolved
return nil, commonerrors.NewCommandErrorMsgWithArgument(
commonerrors.ErrNotImplemented,
fmt.Sprintf("Index key value %q is not implemented yet", order),
Expand All @@ -289,7 +288,6 @@ func processIndexKey(keyDoc *types.Document) (pgdb.IndexKey, error) {
case -1:
indexOrder = types.Descending
default:
// TODO Add better validation: https://github.com/FerretDB/FerretDB/issues/2311
return nil, commonerrors.NewCommandErrorMsgWithArgument(
commonerrors.ErrNotImplemented,
fmt.Sprintf("Index key value %q is not implemented yet", orderParam),
Expand Down