Skip to content

Commit b1af047

Browse files
authored
chore(ci): add FIPS e2e and smoke tests MONGOSH-1222 (#1298)
1 parent b160fde commit b1af047

26 files changed

+703
-146
lines changed

.evergreen.yml

Lines changed: 401 additions & 0 deletions
Large diffs are not rendered by default.

.evergreen/evergreen.yml.in

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -798,8 +798,9 @@ tasks:
798798
###
799799
<% for (const { executableOsId, compileBuildVariant } of EXECUTABLE_PKG_INFO) {
800800
for (const mVersion of ['stable', 'unstable']) {
801+
for (const fipsVariant of ['fips', 'nofips']) {
801802
%>
802-
- name: e2e_tests_<% out(executableOsId.replace(/-/g, '_')) %><% out(mVersion === 'stable' ? '' : '_unstable') %>
803+
- name: e2e_tests_<% out(executableOsId.replace(/-/g, '_')) %><% out(mVersion === 'stable' ? '' : '_unstable') %><% out(fipsVariant === 'fips' ? '_fips' : '') %>
803804
tags: ["e2e-test"]
804805
depends_on:
805806
- name: compile_artifact
@@ -817,7 +818,8 @@ tasks:
817818
vars:
818819
node_js_version: "<% out(NODE_JS_VERSION_16) %>"
819820
mongosh_server_test_version: "<% out(mVersion) %>"
820-
<% } } %>
821+
mongosh_test_e2e_force_fips: "<% out(fipsVariant === 'fips' ? '1' : '') %>"
822+
<% } } } %>
821823

822824
###
823825
# PACKAGING
@@ -1084,6 +1086,7 @@ buildvariants:
10841086
tasks:
10851087
- name: e2e_tests_linux_x64
10861088
- name: e2e_tests_linux_x64_openssl11
1089+
- name: e2e_tests_linux_x64_openssl11_fips
10871090
- name: e2e_ubuntu1804_x64
10881091
display_name: "Ubuntu 18.04 x64 (E2E Tests)"
10891092
run_on: ubuntu1804-small

packages/cli-repl/src/smoke-tests.ts

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
/* eslint-disable no-console */
1+
/* eslint-disable no-console, @typescript-eslint/no-non-null-assertion, chai-friendly/no-unused-expressions */
22
import { spawn } from 'child_process';
33
import assert from 'assert';
44
import { once } from 'events';
55
import { redactURICredentials } from '@mongosh/history';
66
import fleSmokeTestScript from './smoke-tests-fle';
7+
import { buildInfo } from './build-info';
78

89
/**
910
* Run smoke tests on an executable, e.g.
@@ -20,11 +21,23 @@ export async function runSmokeTests(smokeTestServer: string | undefined, executa
2021
assert(!!smokeTestServer, 'Make sure MONGOSH_SMOKE_TEST_SERVER is set in CI');
2122
}
2223

23-
for (const { input, output, testArgs } of [{
24+
const skipFipsWithOpenSSL3 = process.env.MONGOSH_SMOKE_TEST_OS_SKIP_FIPS_WITH_OPENSSL3 && buildInfo().opensslVersion.startsWith('3.');
25+
const expectFipsSupport = !!process.env.MONGOSH_SMOKE_TEST_OS_HAS_FIPS_SUPPORT && buildInfo().sharedOpenssl;
26+
console.log('FIPS support required to pass?', { skipFipsWithOpenSSL3, expectFipsSupport });
27+
28+
for (const { input, output, testArgs, includeStderr } of [{
2429
input: 'print("He" + "llo" + " Wor" + "ld!")',
2530
output: /Hello World!/,
31+
includeStderr: false,
2632
testArgs: ['--nodb'],
27-
}].concat(smokeTestServer ? [{
33+
}].concat(skipFipsWithOpenSSL3 ? [] : [{
34+
input: 'crypto.createHash("md5").update("hello").digest("hex")',
35+
output: expectFipsSupport ?
36+
/disabled for FIPS/i :
37+
/disabled for FIPS|Could not enable FIPS mode/i,
38+
includeStderr: true,
39+
testArgs: ['--tlsFIPSMode', '--nodb']
40+
}]).concat(smokeTestServer ? [{
2841
input: `
2942
const dbname = "testdb_simplesmoke" + new Date().getTime();
3043
use(dbname);
@@ -34,13 +47,15 @@ export async function runSmokeTests(smokeTestServer: string | undefined, executa
3447
}
3548
db.dropDatabase();`,
3649
output: /Test succeeded/,
50+
includeStderr: false,
3751
testArgs: [smokeTestServer as string]
3852
}, {
3953
input: fleSmokeTestScript,
4054
output: /Test succeeded|Test skipped/,
55+
includeStderr: false,
4156
testArgs: [smokeTestServer as string]
4257
}] : [])) {
43-
await runSmokeTest(executable, [...args, ...testArgs], input, output);
58+
await runSmokeTest(executable, [...args, ...testArgs], input, output, includeStderr);
4459
}
4560
console.log('all tests passed');
4661
}
@@ -53,16 +68,18 @@ export async function runSmokeTests(smokeTestServer: string | undefined, executa
5368
* @param input stdin contents of the executable
5469
* @param output Expected contents of stdout
5570
*/
56-
async function runSmokeTest(executable: string, args: string[], input: string, output: RegExp): Promise<void> {
71+
async function runSmokeTest(executable: string, args: string[], input: string, output: RegExp, includeStderr?: boolean): Promise<void> {
5772
const proc = spawn(executable, [...args], {
58-
stdio: ['pipe', 'pipe', 'inherit']
73+
stdio: ['pipe', 'pipe', includeStderr ? 'pipe' : 'inherit']
5974
});
6075
let stdout = '';
61-
proc.stdout.setEncoding('utf8').on('data', (chunk) => { stdout += chunk; });
62-
proc.stdin.end(input);
63-
await once(proc.stdout, 'end');
76+
let stderr = '';
77+
proc.stdout!.setEncoding('utf8').on('data', (chunk) => { stdout += chunk; });
78+
proc.stderr?.setEncoding('utf8').on('data', (chunk) => { stderr += chunk; });
79+
proc.stdin!.end(input);
80+
await once(proc.stdout!, 'end');
6481
try {
65-
assert.match(stdout, output);
82+
assert.match(includeStderr ? `${stdout}\n${stderr}` : stdout, output);
6683
console.error({ status: 'success', input, output, stdout, executable, args: args.map(arg => redactURICredentials(arg)) });
6784
} catch (err: any) {
6885
console.error({ status: 'failure', input, output, stdout, executable, args: args.map(arg => redactURICredentials(arg)) });

packages/cli-repl/test/e2e-auth.spec.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,6 @@ describe('Auth e2e', function() {
111111

112112
describe('user management', () => {
113113
describe('createUser', () => {
114-
afterEach(async() => {
115-
await assertUserAuth();
116-
});
117114
it('all arguments', async() => {
118115
await shell.executeLine(`use ${dbName}`);
119116
expect(await shell.executeLine(
@@ -125,6 +122,7 @@ describe('Auth e2e', function() {
125122
mechanisms: ['SCRAM-SHA-256']
126123
});
127124
shell.assertNoErrors();
125+
await assertUserAuth();
128126
});
129127
it('default arguments', async() => {
130128
await shell.executeLine(`use ${dbName}`);
@@ -136,8 +134,12 @@ describe('Auth e2e', function() {
136134
mechanisms: ['SCRAM-SHA-1', 'SCRAM-SHA-256']
137135
});
138136
shell.assertNoErrors();
137+
await assertUserAuth();
139138
});
140-
it('digestPassword', async() => {
139+
it('digestPassword', async function() {
140+
if (process.env.MONGOSH_TEST_E2E_FORCE_FIPS) {
141+
return this.skip(); // No SCRAM-SHA-1 in FIPS mode
142+
}
141143
await shell.executeLine(`use ${dbName}`);
142144
expect(await shell.executeLine(
143145
'db.createUser({ user: "anna", pwd: "pwd", roles: [], mechanisms: ["SCRAM-SHA-1"], passwordDigestor: "client"})'
@@ -147,6 +149,7 @@ describe('Auth e2e', function() {
147149
mechanisms: ['SCRAM-SHA-1']
148150
});
149151
shell.assertNoErrors();
152+
await assertUserAuth();
150153
});
151154
});
152155
describe('updateUser', () => {
@@ -190,7 +193,10 @@ describe('Auth e2e', function() {
190193
});
191194
shell.assertNoErrors();
192195
});
193-
it('digestPassword', async() => {
196+
it('digestPassword', async function() {
197+
if (process.env.MONGOSH_TEST_E2E_FORCE_FIPS) {
198+
return this.skip(); // No SCRAM-SHA-1 in FIPS mode
199+
}
194200
await shell.executeLine(`use ${dbName}`);
195201
expect(await shell.executeLine(
196202
'db.updateUser("anna", { pwd: "pwd3", passwordDigestor: "client", mechanisms: ["SCRAM-SHA-1"]})'
@@ -825,7 +831,10 @@ describe('Auth e2e', function() {
825831
shell.assertNoErrors();
826832
});
827833
context('with specific auth mechanisms', () => {
828-
it('can auth with SCRAM-SHA-1', async() => {
834+
it('can auth with SCRAM-SHA-1', async function() {
835+
if (process.env.MONGOSH_TEST_E2E_FORCE_FIPS) {
836+
return this.skip(); // No SCRAM-SHA-1 in FIPS mode
837+
}
829838
const connectionString = await testServer.connectionString();
830839
shell = TestShell.start({ args: [
831840
connectionString,

packages/cli-repl/test/e2e-tls.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,10 @@ describe('e2e TLS', () => {
424424
shell.assertContainsOutput('MongoServerSelectionError');
425425
});
426426

427-
it('works with valid cert (with tlsCertificateSelector)', async() => {
427+
it('works with valid cert (with tlsCertificateSelector)', async function() {
428+
if (process.env.MONGOSH_TEST_E2E_FORCE_FIPS) {
429+
return this.skip(); // No tlsCertificateSelector support in FIPS mode
430+
}
428431
const fakeOsCaModule = path.resolve(tmpdir.path, 'fake-ca.js');
429432
await fs.writeFile(fakeOsCaModule, `
430433
const fs = require('fs');

packages/cli-repl/test/test-shell.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,13 @@ export class TestShell {
3535
env = { ...env, MONGOSH_FORCE_TERMINAL: '1' };
3636
}
3737

38+
const args = [...options.args];
39+
if (process.env.MONGOSH_TEST_E2E_FORCE_FIPS) {
40+
args.push('--tlsFIPSMode');
41+
}
42+
3843
if (process.env.MONGOSH_TEST_EXECUTABLE_PATH) {
39-
shellProcess = spawn(process.env.MONGOSH_TEST_EXECUTABLE_PATH, [...options.args], {
44+
shellProcess = spawn(process.env.MONGOSH_TEST_EXECUTABLE_PATH, args, {
4045
stdio: [ 'pipe', 'pipe', 'pipe' ],
4146
env: env,
4247
cwd: options.cwd
@@ -52,7 +57,7 @@ export class TestShell {
5257
env = { ...env, CLEAR_SIGINT_LISTENERS: '1' };
5358
}
5459

55-
shellProcess = spawn('node', [path.resolve(__dirname, '..', 'bin', 'mongosh.js'), ...options.args], {
60+
shellProcess = spawn('node', [path.resolve(__dirname, '..', 'bin', 'mongosh.js'), ...args], {
5661
stdio: [ 'pipe', 'pipe', 'pipe' ],
5762
env: env,
5863
cwd: options.cwd

scripts/docker/amazonlinux1-rpm.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ ADD ${artifact_url} /tmp
55
ADD node_modules /usr/share/mongodb-crypt-library-version/node_modules
66
RUN yum repolist
77
RUN yum install -y /tmp/*mongosh*.rpm
8-
RUN /usr/bin/mongosh --version
8+
RUN /usr/bin/mongosh --build-info
99
RUN env MONGOSH_RUN_NODE_SCRIPT=1 mongosh /usr/share/mongodb-crypt-library-version/node_modules/.bin/mongodb-crypt-library-version /usr/lib64/mongosh_crypt_v1.so | grep -Eq '^mongo_(crypt|csfle)_v1-'
1010
ENTRYPOINT [ "mongosh" ]

scripts/docker/amazonlinux2-rpm.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ ADD ${artifact_url} /tmp
55
ADD node_modules /usr/share/mongodb-crypt-library-version/node_modules
66
RUN yum repolist
77
RUN yum install -y /tmp/*mongosh*.rpm
8-
RUN /usr/bin/mongosh --version
8+
RUN /usr/bin/mongosh --build-info
99
RUN env MONGOSH_RUN_NODE_SCRIPT=1 mongosh /usr/share/mongodb-crypt-library-version/node_modules/.bin/mongodb-crypt-library-version /usr/lib64/mongosh_crypt_v1.so | grep -Eq '^mongo_(crypt|csfle)_v1-'
1010
ENTRYPOINT [ "mongosh" ]

scripts/docker/centos7-epel-rpm.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ RUN yum repolist
88
RUN yum install -y epel-release
99
RUN yum repolist
1010
RUN yum install -y /tmp/*mongosh*.rpm
11-
RUN /usr/bin/mongosh --version
11+
RUN /usr/bin/mongosh --build-info
1212
RUN env MONGOSH_RUN_NODE_SCRIPT=1 mongosh /usr/share/mongodb-crypt-library-version/node_modules/.bin/mongodb-crypt-library-version /usr/lib64/mongosh_crypt_v1.so | grep -Eq '^mongo_(crypt|csfle)_v1-'
1313
ENTRYPOINT [ "mongosh" ]

scripts/docker/centos7-rpm.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ ADD ${artifact_url} /tmp
55
ADD node_modules /usr/share/mongodb-crypt-library-version/node_modules
66
RUN yum repolist
77
RUN yum install -y /tmp/*mongosh*.rpm
8-
RUN /usr/bin/mongosh --version
8+
RUN /usr/bin/mongosh --build-info
99
RUN env MONGOSH_RUN_NODE_SCRIPT=1 mongosh /usr/share/mongodb-crypt-library-version/node_modules/.bin/mongodb-crypt-library-version /usr/lib64/mongosh_crypt_v1.so | grep -Eq '^mongo_(crypt|csfle)_v1-'
1010
ENTRYPOINT [ "mongosh" ]

0 commit comments

Comments
 (0)