Skip to content

Commit

Permalink
add versioned api tests to evergreen
Browse files Browse the repository at this point in the history
  • Loading branch information
emadum committed Feb 12, 2021
1 parent 176a56b commit 8bfc97c
Show file tree
Hide file tree
Showing 42 changed files with 334 additions and 142 deletions.
26 changes: 24 additions & 2 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ functions:
MONGODB_VERSION=${VERSION} TOPOLOGY=${TOPOLOGY} \
AUTH=${AUTH} SSL=${SSL} \
ORCHESTRATION_FILE=${ORCHESTRATION_FILE} \
REQUIRE_API_VERSION=${REQUIRE_API_VERSION} \
bash ${DRIVERS_TOOLS}/.evergreen/run-orchestration.sh
- command: expansions.update
params:
Expand Down Expand Up @@ -126,8 +127,10 @@ functions:
rm -f ./prepare_client_encryption.sh
fi
AUTH=${AUTH} SSL=${SSL} UNIFIED=${UNIFIED} MONGODB_URI="${MONGODB_URI}" \
NODE_VERSION=${NODE_VERSION} SKIP_DEPS=1 NO_EXIT=1 \
MONGODB_URI="${MONGODB_URI}" \
AUTH=${AUTH} SSL=${SSL} UNIFIED=${UNIFIED} \
MONGODB_API_VERSION="${MONGODB_API_VERSION}" \
NODE_VERSION=${NODE_VERSION} SKIP_DEPS=${SKIP_DEPS|1} NO_EXIT=${NO_EXIT|1} \
bash ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh
run checks:
- command: shell.exec
Expand Down Expand Up @@ -777,6 +780,22 @@ tasks:
VERSION: '2.6'
TOPOLOGY: sharded_cluster
- func: run tests
- name: test-latest-server-v1-api
tags:
- latest
- server
- v1-api
commands:
- func: install dependencies
- func: bootstrap mongo-orchestration
vars:
VERSION: latest
TOPOLOGY: server
REQUIRE_API_VERSION: '1'
- func: run tests
vars:
MONGODB_API_VERSION: '1'
NO_EXIT: ''
- name: test-atlas-connectivity
tags:
- atlas-connect
Expand Down Expand Up @@ -1195,6 +1214,7 @@ buildvariants:
- test-2.6-server
- test-2.6-replica_set
- test-2.6-sharded_cluster
- test-latest-server-v1-api
- test-atlas-connectivity
- test-atlas-data-lake
- test-auth-kerberos
Expand Down Expand Up @@ -1261,6 +1281,7 @@ buildvariants:
- test-2.6-server
- test-2.6-replica_set
- test-2.6-sharded_cluster
- test-latest-server-v1-api
- test-atlas-connectivity
- test-atlas-data-lake
- test-auth-kerberos
Expand Down Expand Up @@ -1356,6 +1377,7 @@ buildvariants:
- test-3.2-server
- test-3.2-replica_set
- test-3.2-sharded_cluster
- test-latest-server-v1-api
- test-atlas-connectivity
- test-atlas-data-lake
- test-auth-kerberos
Expand Down
7 changes: 5 additions & 2 deletions .evergreen/config.yml.in
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ functions:
MONGODB_VERSION=${VERSION} TOPOLOGY=${TOPOLOGY} \
AUTH=${AUTH} SSL=${SSL} \
ORCHESTRATION_FILE=${ORCHESTRATION_FILE} \
REQUIRE_API_VERSION=${REQUIRE_API_VERSION} \
bash ${DRIVERS_TOOLS}/.evergreen/run-orchestration.sh
# run-orchestration generates expansion file with the MONGODB_URI for the cluster
- command: expansions.update
Expand Down Expand Up @@ -146,8 +147,10 @@ functions:
rm -f ./prepare_client_encryption.sh
fi

AUTH=${AUTH} SSL=${SSL} UNIFIED=${UNIFIED} MONGODB_URI="${MONGODB_URI}" \
NODE_VERSION=${NODE_VERSION} SKIP_DEPS=1 NO_EXIT=1 \
MONGODB_URI="${MONGODB_URI}" \
AUTH=${AUTH} SSL=${SSL} UNIFIED=${UNIFIED} \
MONGODB_API_VERSION="${MONGODB_API_VERSION}" \
NODE_VERSION=${NODE_VERSION} SKIP_DEPS=${SKIP_DEPS|1} NO_EXIT=${NO_EXIT|1} \
bash ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh

"run checks":
Expand Down
22 changes: 22 additions & 0 deletions .evergreen/generate_evergreen_tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,28 @@ const BASE_TASKS = [];
MONGODB_VERSIONS.forEach(mongoVersion => {
TOPOLOGIES.forEach(topology => BASE_TASKS.push(makeTask({ mongoVersion, topology })));
});
BASE_TASKS.push({
name: `test-latest-server-v1-api`,
tags: ['latest', 'server', 'v1-api'],
commands: [
{ func: 'install dependencies' },
{
func: 'bootstrap mongo-orchestration',
vars: {
VERSION: 'latest',
TOPOLOGY: 'server',
REQUIRE_API_VERSION: '1'
}
},
{
func: 'run tests',
vars: {
MONGODB_API_VERSION: '1',
NO_EXIT: ''
}
}
]
});

// manually added tasks
Array.prototype.push.apply(TASKS, [
Expand Down
2 changes: 1 addition & 1 deletion .evergreen/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ else
npm install mongodb-client-encryption
fi

MONGODB_UNIFIED_TOPOLOGY=${UNIFIED} MONGODB_URI=${MONGODB_URI} npm run ${TEST_NPM_SCRIPT}
MONGODB_API_VERSION=${MONGODB_API_VERSION} MONGODB_UNIFIED_TOPOLOGY=${UNIFIED} MONGODB_URI=${MONGODB_URI} npm run ${TEST_NPM_SCRIPT}
11 changes: 10 additions & 1 deletion src/cmap/auth/scram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as crypto from 'crypto';
import { Binary, Document } from '../../bson';
import { MongoError, AnyError } from '../../error';
import { AuthProvider, AuthContext } from './auth_provider';
import { Callback, ns } from '../../utils';
import { Callback, ns, applyServerApiVersion } from '../../utils';
import type { MongoCredentials } from './mongo_credentials';
import type { HandshakeDocument } from '../connect';

Expand Down Expand Up @@ -112,6 +112,9 @@ function executeScram(cryptoMethod: CryptoMethod, authContext: AuthContext, call
const db = credentials.source;

const saslStartCmd = makeFirstMessage(cryptoMethod, credentials, nonce);
if (connection.serverApi) {
applyServerApiVersion(saslStartCmd, connection.serverApi);
}
connection.command(ns(`${db}.$cmd`), saslStartCmd, undefined, (_err, result) => {
const err = resolveError(_err, result);
if (err) {
Expand Down Expand Up @@ -197,6 +200,9 @@ function continueScramConversation(
conversationId: response.conversationId,
payload: new Binary(Buffer.from(clientFinal))
};
if (connection.serverApi) {
applyServerApiVersion(saslContinueCmd, connection.serverApi);
}

connection.command(ns(`${db}.$cmd`), saslContinueCmd, undefined, (_err, r) => {
const err = resolveError(_err, r);
Expand All @@ -219,6 +225,9 @@ function continueScramConversation(
conversationId: r.conversationId,
payload: Buffer.alloc(0)
};
if (connection.serverApi) {
applyServerApiVersion(retrySaslContinueCmd, connection.serverApi);
}

connection.command(ns(`${db}.$cmd`), retrySaslContinueCmd, undefined, callback);
});
Expand Down
13 changes: 12 additions & 1 deletion src/cmap/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import { Connection, ConnectionOptions, CryptoConnection } from './connection';
import { MongoError, MongoNetworkError, MongoNetworkTimeoutError, AnyError } from '../error';
import { AUTH_PROVIDERS, AuthMechanism } from './auth/defaultAuthProviders';
import { AuthContext } from './auth/auth_provider';
import { makeClientMetadata, ClientMetadata, Callback, CallbackWithType, ns } from '../utils';
import {
makeClientMetadata,
ClientMetadata,
Callback,
CallbackWithType,
ns,
applyServerApiVersion
} from '../utils';
import {
MAX_SUPPORTED_WIRE_VERSION,
MAX_SUPPORTED_SERVER_VERSION,
Expand Down Expand Up @@ -96,6 +103,10 @@ function performInitialHandshake(
handshakeOptions.socketTimeout = options.connectTimeoutMS;
}

if (conn.serverApi) {
applyServerApiVersion(handshakeDoc, conn.serverApi);
}

const start = new Date().getTime();
conn.command(ns('admin.$cmd'), handshakeDoc, handshakeOptions, (err, response) => {
if (err) {
Expand Down
7 changes: 1 addition & 6 deletions src/cmap/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import {
Callback,
MongoDBNamespace,
maxWireVersion,
HostAddress,
applyServerApiVersion
HostAddress
} from '../utils';
import {
AnyError,
Expand Down Expand Up @@ -367,10 +366,6 @@ export class Connection extends EventEmitter {

const inTransaction = session && (session.inTransaction() || isTransactionCommand(finalCmd));

if (!inTransaction && !finalCmd.getMore && this.serverApi) {
applyServerApiVersion(finalCmd, this.serverApi);
}

const commandResponseHandler = inTransaction
? (err?: AnyError, ...args: Document[]) => {
// We need to add a TransientTransactionError errorLabel, as stated in the transaction spec.
Expand Down
12 changes: 11 additions & 1 deletion src/connection_string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import {
MongoClient,
MongoClientOptions,
MongoOptions,
PkFactory
PkFactory,
ServerApi
} from './mongo_client';
import { MongoCredentials } from './cmap/auth/mongo_credentials';
import type { TagSet } from './sdam/server_description';
Expand Down Expand Up @@ -572,6 +573,15 @@ export const OPTIONS = {
autoEncryption: {
type: 'record'
},
serverApi: {
target: 'serverApi',
transform({ values: [version] }): ServerApi {
if (typeof version === 'string') {
return { version };
}
return version as ServerApi;
}
},
checkKeys: {
type: 'boolean'
},
Expand Down
19 changes: 8 additions & 11 deletions src/mongo_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ export interface MongoClientOptions extends BSONSerializeOptions, SupportedNodeC
logger?: Logger;
/** Enable command monitoring for this client */
monitorCommands?: boolean;
/** Server API version */
serverApi?: ServerApiVersion | ServerApi;
/** Optionally enable client side auto encryption */
autoEncryption?: AutoEncryptionOptions;
/** Allows a wrapping driver to amend the client metadata generated by the driver to include information about the wrapping driver */
Expand All @@ -243,13 +245,13 @@ export interface MongoClientPrivate {
readConcern?: ReadConcern;
writeConcern?: WriteConcern;
readPreference: ReadPreference;
serverApi: ServerApi;
bsonOptions: BSONSerializeOptions;
namespace: MongoDBNamespace;
logger: Logger;
}

const kOptions = Symbol('options');
const kServerApi = Symbol('serverApi');

/**
* The **MongoClient** class is a class that allows for making Connections to MongoDB.
Expand Down Expand Up @@ -302,24 +304,17 @@ export class MongoClient extends EventEmitter {
*/
[kOptions]: MongoOptions;

/**
* The MongoDB Server API version
* @internal
* */
[kServerApi]: ServerApi;

// debugging
originalUri;
originalOptions;

constructor(url: string, options?: MongoClientOptions, serverApi?: ServerApi) {
constructor(url: string, options?: MongoClientOptions) {
super();

this.originalUri = url;
this.originalOptions = options;

this[kOptions] = parseOptions(url, this, options);
this[kServerApi] = Object.freeze({ version: ServerApiVersion.v1, ...serverApi });

// The internal state
this.s = {
Expand All @@ -329,6 +324,7 @@ export class MongoClient extends EventEmitter {
readConcern: this[kOptions].readConcern,
writeConcern: this[kOptions].writeConcern,
readPreference: this[kOptions].readPreference,
serverApi: this[kOptions].serverApi,
bsonOptions: resolveBSONOptions(this[kOptions]),
namespace: ns('admin'),
logger: this[kOptions].logger
Expand All @@ -339,8 +335,8 @@ export class MongoClient extends EventEmitter {
return Object.freeze({ ...this[kOptions] });
}

get serverApi(): Readonly<ServerApi> {
return this[kServerApi];
get serverApi(): Readonly<ServerApi | undefined> {
return this[kOptions].serverApi && Object.freeze({ ...this[kOptions].serverApi });
}

get autoEncrypter(): AutoEncrypter | undefined {
Expand Down Expand Up @@ -652,6 +648,7 @@ export interface MongoOptions
credentials?: MongoCredentials;
readPreference: ReadPreference;
readConcern: ReadConcern;
serverApi: ServerApi;
writeConcern: WriteConcern;
dbName: string;
metadata: ClientMetadata;
Expand Down
20 changes: 19 additions & 1 deletion src/operations/command.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { Aspect, AbstractOperation, OperationOptions } from './operation';
import { ReadConcern } from '../read_concern';
import { WriteConcern, WriteConcernOptions } from '../write_concern';
import { maxWireVersion, MongoDBNamespace, Callback, decorateWithExplain } from '../utils';
import {
applyServerApiVersion,
maxWireVersion,
MongoDBNamespace,
Callback,
decorateWithExplain
} from '../utils';
import type { ReadPreference } from '../read_preference';
import { ClientSession, commandSupportsReadConcern } from '../sessions';
import { MongoError } from '../error';
Expand Down Expand Up @@ -173,6 +179,18 @@ export abstract class CommandOperation<T> extends AbstractOperation<T> {
}
}

// if an API version was declared, add the apiVersion option to every command, except:
// a. only in the initial command of a transaction
// b. only in a Cursor's initiating command, not subsequent getMore commands
if (
server.serverApi &&
(!inTransaction || this.session.transaction.isStarting) &&
!cmd.commitTransaction &&
!cmd.getMore
) {
applyServerApiVersion(cmd, server.serverApi);
}

server.command(this.ns, cmd, { fullResult: !!this.fullResponse, ...options }, callback);
}
}
6 changes: 5 additions & 1 deletion src/operations/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
MongoDBNamespace,
Callback,
normalizeHintField,
decorateWithExplain
decorateWithExplain,
applyServerApiVersion
} from '../utils';
import { MongoError } from '../error';
import type { Document } from '../bson';
Expand Down Expand Up @@ -153,6 +154,9 @@ export class FindOperation extends CommandOperation<Document> {
if (this.explain) {
findCommand = decorateWithExplain(findCommand, this.explain);
}
if (server.serverApi) {
applyServerApiVersion(findCommand, server.serverApi);
}

server.command(
this.ns,
Expand Down
2 changes: 1 addition & 1 deletion src/operations/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ export function makeUpdateStatement(
op.upsert = options.upsert;
}

if (typeof options.multi === 'boolean') {
if (options.multi) {
op.multi = options.multi;
}

Expand Down
Loading

0 comments on commit 8bfc97c

Please sign in to comment.