Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
87 changes: 79 additions & 8 deletions .evergreen/start-atlas-cloud-cluster.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,61 @@
#!/bin/bash

# This script helps to automatically provision Atlas cluster for running the e2e
# tests against. In CI this will always create a new cluster and delete it when
# the test run is finished. You can also use this script locally to run e2e
# tests against a "logged in" Atlas Cloud experience in compass-web sandbox.
#
# While the provisioning of clusters is automated, you should be aware that it
# requires some extra environmental variables to be available when you are
# running it. If you want to be able to run these e2e tests locally, following
# steps are required:
#
# - Create a test Atlas user on one of the testing environments (-dev / -qa).
# You can only use your work emails with a subaddress to create those (e.g,
# [email protected]).
#
# - Setup a new org and project. Save the org id and project id for later.
#
# - Create new db user with username / password auth and admin role. This user
# will be used to prepopulate dbs with data in tests. Save the credentials.
#
# - Create a new API key (Access Manager > Project Access > Create Application >
# API Key) for the project you created and save the public and private keys.
#
# - (Optional) Deploy a cluster with a required configuration through Atlas
# Cloud UI. If you skip the step, the script will deploy a default cluster for
# you.
#
# - Make sure that you have the following environmental variables provided to
# the script below:
#
# MCLI_OPS_MANAGER_URL API base url matching the environment you used to
# create your user (https://cloud{-dev,-qa}.mongodb.com/)
# MCLI_PUBLIC_API_KEY Public API key
# MCLI_PRIVATE_API_KEY Private API key
# MCLI_ORG_ID Org ID
# MCLI_PROJECT_ID Project ID
#
# COMPASS_E2E_ATLAS_CLOUD_SANDBOX_USERNAME Cloud user you created
# COMPASS_E2E_ATLAS_CLOUD_SANDBOX_PASSWORD Cloud user password
# COMPASS_E2E_ATLAS_CLOUD_SANDBOX_DBUSER_USERNAME Db user for the project
# COMPASS_E2E_ATLAS_CLOUD_SANDBOX_DBUSER_PASSWORD Db user password
#
# - Source the script followed by running the tests to make sure that some
# variables exported from this script are available for the test env:
#
# (ATLAS_CLOUD_TEST_CLUSTER_NAME="TestCluster" source .evergreen/start-atlas-cloud-cluster.sh \
# && npm run -w compass-e2e-tests test web -- --test-atlas-cloud-sandbox --test-filter="atlas-cloud/**/*")

_ATLAS_CLOUD_TEST_CLUSTER_NAME=${ATLAS_CLOUD_TEST_CLUSTER_NAME:-""}

# Atlas limits the naming to something like /^[\w\d-]{,23}$/ (and will auto
# truncate if it's too long) so we're very limited in terms of how unique this
# name can be. Hopefully the epoch + part of git hash is enough for these to not
# overlap when tests are running
ATLAS_CLOUD_TEST_CLUSTER_NAME="e2e-$(date +"%s")-$(git rev-parse HEAD)"
DEFAULT_ATLAS_CLOUD_TEST_CLUSTER_NAME="e2e-$(date +"%s")-$(git rev-parse HEAD)"

ATLAS_CLUSTER_NAME="${_ATLAS_CLOUD_TEST_CLUSTER_NAME:-$DEFAULT_ATLAS_CLOUD_TEST_CLUSTER_NAME}"

function atlascli() {
docker run \
Expand All @@ -17,23 +68,43 @@ function atlascli() {
}

cleanup() {
echo "Scheduling Atlas deployment \`$ATLAS_CLOUD_TEST_CLUSTER_NAME\` for deletion..."
atlascli clusters delete $ATLAS_CLOUD_TEST_CLUSTER_NAME --force
# Assuming that we want to preserve the cluster if the name was provided
# outside of script. Helpful when trying to run the tests locally, you can
# automatically create a cluster with a custom name for the first time, but
# then re-use it when running the tests again. Don't forget to clean it up
# after you're done!
if [ -z "$_ATLAS_CLOUD_TEST_CLUSTER_NAME" ]; then
echo "Scheduling Atlas deployment \`$ATLAS_CLUSTER_NAME\` for deletion..."
atlascli clusters delete $ATLAS_CLUSTER_NAME --force
else
echo "Custom cluster name provided ($_ATLAS_CLOUD_TEST_CLUSTER_NAME), skipping cluster cleanup"
fi
}

trap cleanup EXIT

echo "Creating Atlas deployment \`$ATLAS_CLOUD_TEST_CLUSTER_NAME\` to test against..."
atlascli clusters create $ATLAS_CLOUD_TEST_CLUSTER_NAME \
echo "Creating Atlas deployment \`$ATLAS_CLUSTER_NAME\` to test against..."
atlascli clusters create $ATLAS_CLUSTER_NAME \
--provider AWS \
--region US_EAST_1 \
--tier M10

echo "Waiting for the deployment to be provisioned..."
atlascli clusters watch "$ATLAS_CLOUD_TEST_CLUSTER_NAME"
atlascli clusters watch $ATLAS_CLUSTER_NAME

echo "Getting connection string for provisioned cluster..."
ATLAS_CLOUD_TEST_CLUSTER_CONNECTION_STRING_JSON="$(atlascli clusters connectionStrings describe $ATLAS_CLOUD_TEST_CLUSTER_NAME -o json)"
CONNECTION_STRINGS_JSON="$(atlascli clusters connectionStrings describe $ATLAS_CLUSTER_NAME -o json)"

export COMPASS_E2e_ATLAS_CLOUD_SANDBOX_CLOUD_CONFIG=$(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export COMPASS_E2e_ATLAS_CLOUD_SANDBOX_CLOUD_CONFIG=$(
export COMPASS_E2E_ATLAS_CLOUD_SANDBOX_CLOUD_CONFIG=$(

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we are passing this to test-web-sandbox-atlas-cloud evergreen function (as qa), should we check if that's set?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe remove it from there as we are now using MCLI_OPS_MANAGER_URL to determine this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, can drop it from evergreen config, forgot about that, makes sense 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in e284976 with the typo fix, thanks for spotting!

if [[ "$MCLI_OPS_MANAGER_URL" =~ "-dev" ]]; then
echo "dev"
elif [[ "$MCLI_OPS_MANAGER_URL" =~ "-qa" ]]; then
echo "qa"
else
echo "prod"
fi
)
echo "Cloud config: $COMPASS_E2e_ATLAS_CLOUD_SANDBOX_CLOUD_CONFIG"

export COMPASS_E2E_ATLAS_CLOUD_SANDBOX_DEFAULT_CONNECTIONS="{\"$ATLAS_CLOUD_TEST_CLUSTER_NAME\": $ATLAS_CLOUD_TEST_CLUSTER_CONNECTION_STRING_JSON}"
export COMPASS_E2E_ATLAS_CLOUD_SANDBOX_DEFAULT_CONNECTIONS="{\"$ATLAS_CLUSTER_NAME\": $CONNECTION_STRINGS_JSON}"
echo "Cluster connections: $COMPASS_E2E_ATLAS_CLOUD_SANDBOX_DEFAULT_CONNECTIONS"
57 changes: 18 additions & 39 deletions packages/compass-e2e-tests/helpers/test-runner-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
} from '@mongodb-js/connection-info';
import type { MongoClusterOptions } from 'mongodb-runner';
import yargs from 'yargs';
import type { Argv } from 'yargs';
import type { Argv, CamelCase } from 'yargs';
import { hideBin } from 'yargs/helpers';
import Debug from 'debug';
import fs from 'fs';
Expand Down Expand Up @@ -106,15 +106,17 @@ function buildDesktopArgs(yargs: Argv) {
* make sure that the tests in mms are also updated to account for that
*/
const atlasCloudExternalArgs = [
'test-atlas-cloud-external',
'atlas-cloud-external-url',
'atlas-cloud-external-project-id',
'atlas-cloud-external-cookies-file',
'atlas-cloud-external-default-connections-file',
] as const;

type AtlasCloudExternalArgs =
| typeof atlasCloudExternalArgs[number]
| CamelCase<typeof atlasCloudExternalArgs[number]>;

const atlasCloudSandboxArgs = [
'test-atlas-cloud-sandbox',
'atlas-cloud-sandbox-cloud-config',
'atlas-cloud-sandbox-username',
'atlas-cloud-sandbox-password',
Expand All @@ -123,6 +125,10 @@ const atlasCloudSandboxArgs = [
'atlas-cloud-sandbox-default-connections',
] as const;

type AtlasCloudSandboxArgs =
| typeof atlasCloudSandboxArgs[number]
| CamelCase<typeof atlasCloudSandboxArgs[number]>;

let testEnv: 'desktop' | 'web' | undefined;

function buildWebArgs(yargs: Argv) {
Expand Down Expand Up @@ -191,13 +197,9 @@ function buildWebArgs(yargs: Argv) {
description:
'Stringified JSON with connections that are expected to be available in the Atlas project',
})
.implies(
Object.fromEntries(
atlasCloudSandboxArgs.map((arg) => {
return [arg, atlasCloudSandboxArgs];
})
)
)
.implies({
'test-atlas-cloud-sandbox': atlasCloudSandboxArgs,
})
.option('test-atlas-cloud-external', {
type: 'boolean',
description:
Expand All @@ -221,13 +223,9 @@ function buildWebArgs(yargs: Argv) {
description:
'File with JSON array of connections (following ConnectionInfo schema) that are expected to be available in the Atlas project',
})
.implies(
Object.fromEntries(
atlasCloudExternalArgs.map((arg) => {
return [arg, atlasCloudExternalArgs];
})
)
)
.implies({
'test-atlas-cloud-external': atlasCloudExternalArgs,
})
.conflicts({
'test-atlas-cloud-external': 'test-atlas-cloud-sandbox',
'test-atlas-cloud-sandbox': 'test-atlas-cloud-external',
Expand Down Expand Up @@ -310,42 +308,23 @@ export function assertTestingWeb(ctx = context): asserts ctx is WebParsedArgs {
export function isTestingAtlasCloudExternal(
ctx = context
): ctx is WebParsedArgs & {
[K in
| 'testAtlasCloudExternal'
| 'atlasCloudExternalUrl'
| 'atlasCloudExternalProjectId'
| 'atlasCloudExternalCookiesFile'
| 'atlasCloudExternalDefaultConnectionsFile']: NonNullable<
WebParsedArgs[K]
>;
[K in AtlasCloudExternalArgs]: NonNullable<WebParsedArgs[K]>;
} {
return isTestingWeb(ctx) && !!ctx.testAtlasCloudExternal;
}

export function isTestingAtlasCloudSandbox(
ctx = context
): ctx is WebParsedArgs & {
[K in
| 'testAtlasCloudSandbox'
| 'atlasCloudSandboxUsername'
| 'atlasCloudSandboxPassword'
| 'atlasCloudSandboxDbuserUsername'
| 'atlasCloudSandboxDbuserPassword'
| 'atlasCloudSandboxDefaultConnections']: NonNullable<WebParsedArgs[K]>;
[K in AtlasCloudSandboxArgs]: NonNullable<WebParsedArgs[K]>;
} {
return isTestingWeb(ctx) && !!ctx.testAtlasCloudSandbox;
}

export function assertTestingAtlasCloudSandbox(
ctx = context
): asserts ctx is WebParsedArgs & {
[K in
| 'testAtlasCloudSandbox'
| 'atlasCloudSandboxUsername'
| 'atlasCloudSandboxPassword'
| 'atlasCloudSandboxDbuserUsername'
| 'atlasCloudSandboxDbuserPassword'
| 'atlasCloudSandboxDefaultConnections']: NonNullable<WebParsedArgs[K]>;
[K in AtlasCloudSandboxArgs]: NonNullable<WebParsedArgs[K]>;
} {
if (!isTestingAtlasCloudSandbox(ctx)) {
throw new Error(`Expected tested runtime to be web w/ Atlas Cloud account`);
Expand Down
Loading