Skip to content

Commit bb89755

Browse files
authored
CSHARP-5840: Proper XUnit shared test fixture for Atlas tests (#2007)
* Self-seed Atlas Search test data via shared XUnit fixture Replaces the suite's dependence on pre-configured Atlas sample databases and search indexes. The new AtlasSearchFixture (collection-scoped) owns a single client, an EventCapturer, and a fixture-managed atlas_search_<guid> database. Lazy seeders populate historical_documents, movies, embedded_movies, airbnb_listings, test_classes, binary_vector_items, auto_embed_movies, two synonym source collections, and the existing return-scope directors collection, and create the ten search/vector indexes required by the tests (waiting for READY). Dispose drops the whole database. The seed data is baked in as C# literals in AtlasSearchFixtureSeedData.cs (generated by tests/Tools/AtlasSeedExtractor from Atlas Local sample data once) so the test suite has zero runtime dependency on sample databases — only on an Atlas-search-capable cluster being reachable at ATLAS_SEARCH_URI. Embeddings are preserved as real Voyage-AI float32 vectors via BinaryVectorFloat32. AtlasSearchTests, VectorSearchTests, AutoEmbedVectorSearchTests, and AtlasSearchIndexManagementTests join via [Collection(AtlasSearchCollection.Name)] and pull their client / collections through the fixture. AtlasSearchTests loses its static __indexesCreated / __databaseUniquifier / __returnScopeTestCount machinery and the inline return-scope seed. AtlasSearchTestsUtils is obsoleted. AutoEmbedVectorSearchTests now run for real (the previous CSHARP-5840 skip is gone): the auto-embed collection and index live in the fixture so the Voyage AI embedding work happens once per test session instead of three times, the corpus is reduced to 4 movies (2 pass the runtime+year filter, 2 don't), and the ctor's unbounded wait loop is replaced with a 15-minute deadline that surfaces a clear error mentioning VOYAGE_API_KEY. Gated on a new AUTO_EMBEDDING_TESTS_ENABLED env var so contributors without a Voyage AI key can still run the rest of the Atlas Search suite. When enabled, the Atlas Local container must have VOYAGE_API_KEY provisioned via the Atlas UI's Model API Keys page (the key must authenticate against ai.mongodb.com, not api.voyageai.com). docker-compose.atlas-local.yml is included as a convenience launcher. Count- and ranking-dependent assertions are recalibrated for the lean corpus: phrase-match counts drop from 108 to 1, geo-result counts from 25 to membership checks, and vector-search top-K assertions switch from order-sensitive ShouldBeEquivalentTo to order-insensitive BeEquivalentTo. The Pinocchio→Oz swap in VectorSearch top-5 is documented in the test where it lives. The Rerank test guards on AtlasSearchFixture.IsRerankSupported, which probes the deployment on first use. Validated against Atlas Local: 77/77 AtlasSearch* tests pass, 36/36 AtlasSearchIndexManagement tests pass, 3/3 AutoEmbedVectorSearchTests pass (with a valid VOYAGE_API_KEY), 74 tests skip cleanly when env vars are unset, and no atlas_search_* databases remain after the suite exits. [review-iter 1] Address review findings [review-iter 2] Address review findings * Copilot feedback * Review feedback * Remove atlas-search-index-helpers-test * Remove AtlasSeedExtractor tool and simplify fixture init locking The AtlasSeedExtractor project was a one-shot generator that produced the baked-in literals in AtlasSearchFixtureSeedData.cs. That seed data is now static and checked in, so the tool is no longer needed: delete the project and drop the generator references from the seed-data file header. Also collapse the eight near-identical double-checked-locking blocks in AtlasSearchFixture into a single EnsureInitialized(isInitialized, initialize) helper, and mark the per-collection init guards volatile so the lock-free fast-path read is correctly published. Behavior is unchanged: the shared _initLock still serializes seeding, and a throwing seeder still leaves its guard unset so the next access retries (unlike Lazy<T>, which would cache and re-throw the failure).
1 parent ddffda4 commit bb89755

12 files changed

Lines changed: 7582 additions & 701 deletions

AGENTS.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ The C# driver for MongoDB.
3434
| Feature area | Required environment variables |
3535
|---|---|
3636
| Atlas Search | `ATLAS_SEARCH_TESTS_ENABLED`, `ATLAS_SEARCH_URI` |
37-
| Atlas Search index helpers | `ATLAS_SEARCH_INDEX_HELPERS_TESTS_ENABLED`, `ATLAS_SEARCH_URI` |
3837
| CSFLE / auto-encryption | `CRYPT_SHARED_LIB_PATH` |
3938
| CSFLE with KMS mock servers | `KMS_MOCK_SERVERS_ENABLED` |
4039
| CSFLE with AWS KMS | `CSFLE_AWS_TEMPORARY_CREDS_ENABLED` |

docker-compose.atlas-local.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Atlas Local with Voyage AI auto-embedding enabled.
2+
#
3+
# The VOYAGE_API_KEY value is pulled from your shell environment at compose time.
4+
#
5+
# export VOYAGE_API_KEY=...
6+
# docker compose -f docker-compose.atlas-local.yml up -d
7+
#
8+
# To tear down (keeps the named volume so sample data + indexes survive):
9+
# docker compose -f docker-compose.atlas-local.yml down
10+
#
11+
# To wipe everything including the data volume:
12+
# docker compose -f docker-compose.atlas-local.yml down -v
13+
14+
name: atlas-local-preview
15+
16+
services:
17+
mongodb:
18+
image: mongodb/mongodb-atlas-local:preview
19+
hostname: mongodb
20+
container_name: local8g
21+
environment:
22+
- VOYAGE_API_KEY=${VOYAGE_API_KEY}
23+
ports:
24+
- 56661:27017
25+
volumes:
26+
- ./init:/docker-entrypoint-initdb.d
27+
- db:/data/db
28+
- configdb:/data/configdb
29+
- mongot:/data/mongot
30+
volumes:
31+
db:
32+
configdb:
33+
mongot:

evergreen/evergreen.yml

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -672,17 +672,6 @@ functions:
672672
. ${DRIVERS_TOOLS}/.evergreen/secrets_handling/setup-secrets.sh drivers/atlas-qa
673673
evergreen/run-atlas-search-test.sh
674674
675-
run-atlas-search-index-helpers-test:
676-
- command: shell.exec
677-
type: test
678-
params:
679-
working_dir: mongo-csharp-driver
680-
include_expansions_in_env:
681-
- "FRAMEWORK"
682-
script: |
683-
${PREPARE_SHELL}
684-
MONGODB_URI="${MONGODB_URI}" evergreen/run-atlas-search-index-helpers-test.sh
685-
686675
run-ocsp-test:
687676
- command: shell.exec
688677
type: test
@@ -1383,13 +1372,6 @@ tasks:
13831372
FRAMEWORK: net6.0
13841373
- func: run-atlas-search-test
13851374

1386-
- name: atlas-search-index-helpers-test
1387-
commands:
1388-
- func: configure-framework
1389-
vars:
1390-
FRAMEWORK: net6.0
1391-
- func: run-atlas-search-index-helpers-test
1392-
13931375
- name: test-oidc-auth
13941376
commands:
13951377
- func: configure-framework
@@ -2187,41 +2169,6 @@ task_groups:
21872169
tasks:
21882170
- test-csfle-with-gcp-kms
21892171

2190-
- name: atlas-search-index-helpers-task-group
2191-
setup_group_can_fail_task: true
2192-
setup_group_timeout_secs: 1800 # 30 minutes
2193-
setup_group:
2194-
- func: fetch-source
2195-
- func: prepare-resources
2196-
- func: fix-absolute-paths
2197-
- func: init-test-results
2198-
- func: make-files-executable
2199-
- func: assume-aws-test-secrets-role
2200-
- command: subprocess.exec
2201-
params:
2202-
binary: bash
2203-
include_expansions_in_env:
2204-
- "AWS_ACCESS_KEY_ID"
2205-
- "AWS_SECRET_ACCESS_KEY"
2206-
- "AWS_SESSION_TOKEN"
2207-
env:
2208-
CLUSTER_PREFIX: dbx-csharp-index
2209-
MONGODB_VERSION: "8.0"
2210-
args:
2211-
- ${DRIVERS_TOOLS}/.evergreen/atlas/setup-atlas-cluster.sh
2212-
- command: expansions.update
2213-
params:
2214-
file: atlas-expansion.yml
2215-
teardown_group:
2216-
- func: upload-test-results
2217-
- command: subprocess.exec
2218-
params:
2219-
binary: bash
2220-
args:
2221-
- ${DRIVERS_TOOLS}/.evergreen/atlas/teardown-atlas-cluster.sh
2222-
tasks:
2223-
- atlas-search-index-helpers-test
2224-
22252172
- name: test-aws-lambda-task-group
22262173
setup_group_can_fail_task: true
22272174
setup_group_timeout_secs: 1800 # 30 minutes
@@ -2748,13 +2695,6 @@ buildvariants:
27482695
tasks:
27492696
- name: atlas-search-test
27502697

2751-
- name: atlas-search-index-helpers-test
2752-
display_name: "Atlas Search Index Helpers Tests"
2753-
run_on:
2754-
- ubuntu2004-test
2755-
tasks:
2756-
- name: atlas-search-index-helpers-task-group
2757-
27582698
# Socks5 Proxy tests
27592699
- matrix_name: "socks5-proxy-tests-linux"
27602700
matrix_spec: { os: "ubuntu-2004", ssl: ["nossl", "ssl"], version: ["latest"], topology: ["replicaset"] }

evergreen/run-atlas-search-index-helpers-test.sh

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using Xunit;
17+
18+
namespace MongoDB.Driver.Tests.Search
19+
{
20+
[CollectionDefinition(Name)]
21+
public sealed class AtlasSearchCollection : ICollectionFixture<AtlasSearchFixture>
22+
{
23+
public const string Name = "AtlasSearch";
24+
}
25+
}

0 commit comments

Comments
 (0)