Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ functions:
params:
binary: "bash"
env:
TEST_SEARCH_INDEX: "${MONGODB_URI}"
SEARCH_INDEX_URI: "${SEARCH_INDEX_URI}"
args: [*task-runner, evg-test-search-index]
add-aws-auth-variables-to-file:
- command: ec2.assume_role
Expand Down Expand Up @@ -1916,7 +1916,7 @@ task_groups:
params:
working_dir: src/go.mongodb.org/mongo-driver
binary: bash
include_expansions_in_env: [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN]
include_expansions_in_env: [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, MONGODB_URI]
env:
MONGODB_VERSION: ${VERSION}
LAMBDA_STACK_NAME: dbx-go-lambda
Expand All @@ -1925,6 +1925,15 @@ task_groups:
- command: expansions.update
params:
file: src/go.mongodb.org/mongo-driver/atlas-expansion.yml
- command: shell.exec
params:
working_dir: src/go.mongodb.org/mongo-driver
shell: bash
script: |-
echo "SEARCH_INDEX_URI: ${MONGODB_URI}" > atlas-expansion.yml
- command: expansions.update
params:
file: src/go.mongodb.org/mongo-driver/atlas-expansion.yml
teardown_group:
- command: subprocess.exec
params:
Expand Down
135 changes: 104 additions & 31 deletions internal/integration/search_index_prose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestSearchIndexProse(t *testing.T) {

const timeout = 5 * time.Minute

uri := os.Getenv("TEST_INDEX_URI")
uri := os.Getenv("SEARCH_INDEX_URI")
if uri == "" {
t.Skip("skipping")
}
Expand All @@ -57,20 +57,23 @@ func TestSearchIndexProse(t *testing.T) {
require.NoError(mt, err, "failed to create index")
require.Equal(mt, searchName, index, "unmatched name")

awaitCtx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()

var doc bson.Raw
for doc == nil {
cursor, err := view.List(ctx, opts)
cursor, err := view.List(awaitCtx, opts)
require.NoError(mt, err, "failed to list")

if !cursor.Next(ctx) {
if !cursor.Next(awaitCtx) {
break
}
name := cursor.Current.Lookup("name").StringValue()
queryable := cursor.Current.Lookup("queryable").Boolean()
if name == searchName && queryable {
doc = cursor.Current
} else {
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
}
Expand Down Expand Up @@ -110,7 +113,7 @@ func TestSearchIndexProse(t *testing.T) {
require.Contains(mt, indexes, *args.Name)
}

getDocument := func(opts *options.SearchIndexesOptionsBuilder) bson.Raw {
getDocument := func(ctx context.Context, opts *options.SearchIndexesOptionsBuilder) bson.Raw {
for {
cursor, err := view.List(ctx, opts)
require.NoError(mt, err, "failed to list")
Expand All @@ -127,7 +130,7 @@ func TestSearchIndexProse(t *testing.T) {
if name == *args.Name && queryable {
return cursor.Current
}
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
}
Expand All @@ -138,7 +141,10 @@ func TestSearchIndexProse(t *testing.T) {
go func(opts *options.SearchIndexesOptionsBuilder) {
defer wg.Done()

doc := getDocument(opts)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()

doc := getDocument(ctx, opts)
require.NotNil(mt, doc, "got empty document")

args, err := mongoutil.NewOptions[options.SearchIndexesOptions](opts)
Expand Down Expand Up @@ -173,35 +179,39 @@ func TestSearchIndexProse(t *testing.T) {
require.NoError(mt, err, "failed to create index")
require.Equal(mt, searchName, index, "unmatched name")

createOneCtx, createOneCancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer createOneCancel()
var doc bson.Raw
for doc == nil {
cursor, err := view.List(ctx, opts)
cursor, err := view.List(createOneCtx, opts)
require.NoError(mt, err, "failed to list")

if !cursor.Next(ctx) {
if !cursor.Next(createOneCtx) {
break
}
name := cursor.Current.Lookup("name").StringValue()
queryable := cursor.Current.Lookup("queryable").Boolean()
if name == searchName && queryable {
doc = cursor.Current
} else {
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
}
require.NotNil(mt, doc, "got empty document")

err = view.DropOne(ctx, searchName)
require.NoError(mt, err, "failed to drop index")
dropOneCtx, dropOneCancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer dropOneCancel()
for {
cursor, err := view.List(ctx, opts)
cursor, err := view.List(dropOneCtx, opts)
require.NoError(mt, err, "failed to list")

if !cursor.Next(ctx) {
if !cursor.Next(dropOneCtx) {
break
}
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
})
Expand All @@ -224,20 +234,22 @@ func TestSearchIndexProse(t *testing.T) {
require.NoError(mt, err, "failed to create index")
require.Equal(mt, searchName, index, "unmatched name")

createOneCtx, createOneCancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer createOneCancel()
var doc bson.Raw
for doc == nil {
cursor, err := view.List(ctx, opts)
cursor, err := view.List(createOneCtx, opts)
require.NoError(mt, err, "failed to list")

if !cursor.Next(ctx) {
if !cursor.Next(createOneCtx) {
break
}
name := cursor.Current.Lookup("name").StringValue()
queryable := cursor.Current.Lookup("queryable").Boolean()
if name == searchName && queryable {
doc = cursor.Current
} else {
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
}
Expand All @@ -248,11 +260,13 @@ func TestSearchIndexProse(t *testing.T) {
require.NoError(mt, err, "failed to marshal definition")
err = view.UpdateOne(ctx, searchName, definition)
require.NoError(mt, err, "failed to update index")
updateOneCtx, updateOneCancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer updateOneCancel()
for doc == nil {
cursor, err := view.List(ctx, opts)
cursor, err := view.List(updateOneCtx, opts)
require.NoError(mt, err, "failed to list")

if !cursor.Next(ctx) {
if !cursor.Next(updateOneCtx) {
break
}
name := cursor.Current.Lookup("name").StringValue()
Expand All @@ -262,7 +276,7 @@ func TestSearchIndexProse(t *testing.T) {
if name == searchName && queryable && status == "READY" && bytes.Equal(latestDefinition, expected) {
doc = cursor.Current
} else {
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
}
Expand Down Expand Up @@ -302,20 +316,22 @@ func TestSearchIndexProse(t *testing.T) {
})
require.NoError(mt, err, "failed to create index")
require.Equal(mt, searchName, index, "unmatched name")
awaitCtx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
var doc bson.Raw
for doc == nil {
cursor, err := view.List(ctx, opts)
cursor, err := view.List(awaitCtx, opts)
require.NoError(mt, err, "failed to list")

if !cursor.Next(ctx) {
if !cursor.Next(awaitCtx) {
break
}
name := cursor.Current.Lookup("name").StringValue()
queryable := cursor.Current.Lookup("queryable").Boolean()
if name == searchName && queryable {
doc = cursor.Current
} else {
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
}
Expand Down Expand Up @@ -348,12 +364,14 @@ func TestSearchIndexProse(t *testing.T) {
})
require.NoError(mt, err, "failed to create index")
require.Equal(mt, indexName, index, "unmatched name")
implicitCtx, implicitCancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer implicitCancel()
var doc bson.Raw
for doc == nil {
cursor, err := view.List(ctx, opts)
cursor, err := view.List(implicitCtx, opts)
require.NoError(mt, err, "failed to list")

if !cursor.Next(ctx) {
if !cursor.Next(implicitCtx) {
break
}
name := cursor.Current.Lookup("name").StringValue()
Expand All @@ -363,7 +381,7 @@ func TestSearchIndexProse(t *testing.T) {
doc = cursor.Current
assert.Equal(mt, indexType, "search")
} else {
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
}
Expand All @@ -376,12 +394,14 @@ func TestSearchIndexProse(t *testing.T) {
})
require.NoError(mt, err, "failed to create index")
require.Equal(mt, indexName, index, "unmatched name")
explicitCtx, explicitCancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer explicitCancel()
doc = nil
for doc == nil {
cursor, err := view.List(ctx, opts)
cursor, err := view.List(explicitCtx, opts)
require.NoError(mt, err, "failed to list")

if !cursor.Next(ctx) {
if !cursor.Next(explicitCtx) {
break
}
name := cursor.Current.Lookup("name").StringValue()
Expand All @@ -391,7 +411,7 @@ func TestSearchIndexProse(t *testing.T) {
doc = cursor.Current
assert.Equal(mt, indexType, "search")
} else {
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
}
Expand All @@ -417,12 +437,14 @@ func TestSearchIndexProse(t *testing.T) {
})
require.NoError(mt, err, "failed to create index")
require.Equal(mt, indexName, index, "unmatched name")
vectorCtx, vectorCancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer vectorCancel()
doc = nil
for doc == nil {
cursor, err := view.List(ctx, opts)
cursor, err := view.List(vectorCtx, opts)
require.NoError(mt, err, "failed to list")

if !cursor.Next(ctx) {
if !cursor.Next(vectorCtx) {
break
}
name := cursor.Current.Lookup("name").StringValue()
Expand All @@ -432,7 +454,7 @@ func TestSearchIndexProse(t *testing.T) {
doc = cursor.Current
assert.Equal(mt, indexType, "vectorSearch")
} else {
t.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
}
Expand Down Expand Up @@ -472,4 +494,55 @@ func TestSearchIndexProse(t *testing.T) {
})
assert.ErrorContains(mt, err, "Attribute mappings missing")
})

mt.Run("case 9: Drivers use server default for unspecified name (`default`) and type (`search`)", func(mt *mtest.T) {
cases := []struct {
name string
opts *options.SearchIndexesOptionsBuilder
}{
{name: "empty options", opts: options.SearchIndexes()},
{name: "nil options", opts: nil},
}

for _, tc := range cases {
mt.Run(tc.name, func(mt *mtest.T) {
view := mt.Coll.SearchIndexes()
definition := bson.D{
{"mappings", bson.D{
{"dynamic", true},
}},
}

indexName, err := view.CreateOne(context.Background(), mongo.SearchIndexModel{
Definition: definition,
Options: tc.opts,
})
require.NoError(mt, err, "failed to create index")
require.Equal(mt, "default", indexName)

ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()

var doc bson.Raw
for doc == nil {
cursor, err := view.List(ctx, tc.opts)
require.NoError(mt, err, "failed to list")

if !cursor.Next(ctx) {
break
}
name := cursor.Current.Lookup("name").StringValue()
queryable := cursor.Current.Lookup("queryable").Boolean()
indexType := cursor.Current.Lookup("type").StringValue()
if name == indexName && queryable {
doc = cursor.Current
require.Equal(mt, indexType, "search")
} else {
mt.Logf("cursor: %s, sleep 5 seconds...", cursor.Current.String())
time.Sleep(5 * time.Second)
}
}
})
}
})
}
2 changes: 1 addition & 1 deletion mongo/search_index_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,13 @@ func (siv SearchIndexView) CreateMany(
}

var iidx int32
iidx, indexes = bsoncore.AppendDocumentElementStart(indexes, strconv.Itoa(i))
if model.Options != nil {
searchIndexArgs, err := mongoutil.NewOptions[options.SearchIndexesOptions](model.Options)
if err != nil {
return nil, fmt.Errorf("failed to construct options from builder: %w", err)
}

iidx, indexes = bsoncore.AppendDocumentElementStart(indexes, strconv.Itoa(i))
if searchIndexArgs.Name != nil {
indexes = bsoncore.AppendStringElement(indexes, "name", *searchIndexArgs.Name)
}
Expand Down
Loading