diff --git a/.evergreen/ci_matrix_constants.js b/.evergreen/ci_matrix_constants.js index 25424b3be1..3a349d5849 100644 --- a/.evergreen/ci_matrix_constants.js +++ b/.evergreen/ci_matrix_constants.js @@ -10,9 +10,8 @@ const LATEST_LTS = NODE_VERSIONS[NODE_VERSIONS.length - 1]; const TOPOLOGIES = ['server', 'replica_set', 'sharded_cluster']; const AWS_AUTH_VERSIONS = ['latest']; -const TLS_VERSIONS = ['latest', '8.0', '7.0', '6.0', '5.0', '4.4', '4.2']; -const LB_VERSIONS = MONGODB_VERSIONS.slice(0, MONGODB_VERSIONS.indexOf('5.0') + 1); -LB_VERSIONS.reverse(); +const TLS_VERSIONS = MONGODB_VERSIONS.filter(value => value !== 'rapid'); +const LB_VERSIONS = MONGODB_VERSIONS.slice(0, MONGODB_VERSIONS.indexOf('5.0') + 1).toReversed(); const DEFAULT_OS = 'rhel80-large'; const WINDOWS_OS = 'windows-2022-latest-large'; diff --git a/.evergreen/config.yml b/.evergreen/config.yml index e5f5c0962e..399010513e 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -893,6 +893,7 @@ tasks: updates: - {key: VERSION, value: latest} - {key: TOPOLOGY, value: server} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -908,6 +909,7 @@ tasks: updates: - {key: VERSION, value: latest} - {key: TOPOLOGY, value: replica_set} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -923,6 +925,7 @@ tasks: updates: - {key: VERSION, value: latest} - {key: TOPOLOGY, value: sharded_cluster} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -938,6 +941,7 @@ tasks: updates: - {key: VERSION, value: rapid} - {key: TOPOLOGY, value: server} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -953,6 +957,7 @@ tasks: updates: - {key: VERSION, value: rapid} - {key: TOPOLOGY, value: replica_set} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -968,6 +973,7 @@ tasks: updates: - {key: VERSION, value: rapid} - {key: TOPOLOGY, value: sharded_cluster} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -983,6 +989,7 @@ tasks: updates: - {key: VERSION, value: '8.0'} - {key: TOPOLOGY, value: server} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -998,6 +1005,7 @@ tasks: updates: - {key: VERSION, value: '8.0'} - {key: TOPOLOGY, value: replica_set} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1013,6 +1021,7 @@ tasks: updates: - {key: VERSION, value: '8.0'} - {key: TOPOLOGY, value: sharded_cluster} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1028,6 +1037,7 @@ tasks: updates: - {key: VERSION, value: '7.0'} - {key: TOPOLOGY, value: server} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1043,6 +1053,7 @@ tasks: updates: - {key: VERSION, value: '7.0'} - {key: TOPOLOGY, value: replica_set} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1058,6 +1069,7 @@ tasks: updates: - {key: VERSION, value: '7.0'} - {key: TOPOLOGY, value: sharded_cluster} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1073,6 +1085,7 @@ tasks: updates: - {key: VERSION, value: '6.0'} - {key: TOPOLOGY, value: server} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1088,6 +1101,7 @@ tasks: updates: - {key: VERSION, value: '6.0'} - {key: TOPOLOGY, value: replica_set} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1103,6 +1117,7 @@ tasks: updates: - {key: VERSION, value: '6.0'} - {key: TOPOLOGY, value: sharded_cluster} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1118,6 +1133,7 @@ tasks: updates: - {key: VERSION, value: '5.0'} - {key: TOPOLOGY, value: server} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1133,6 +1149,7 @@ tasks: updates: - {key: VERSION, value: '5.0'} - {key: TOPOLOGY, value: replica_set} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1148,6 +1165,7 @@ tasks: updates: - {key: VERSION, value: '5.0'} - {key: TOPOLOGY, value: sharded_cluster} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1163,6 +1181,7 @@ tasks: updates: - {key: VERSION, value: '4.4'} - {key: TOPOLOGY, value: server} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1178,6 +1197,7 @@ tasks: updates: - {key: VERSION, value: '4.4'} - {key: TOPOLOGY, value: replica_set} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1193,6 +1213,7 @@ tasks: updates: - {key: VERSION, value: '4.4'} - {key: TOPOLOGY, value: sharded_cluster} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1208,6 +1229,7 @@ tasks: updates: - {key: VERSION, value: '4.2'} - {key: TOPOLOGY, value: server} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1223,6 +1245,7 @@ tasks: updates: - {key: VERSION, value: '4.2'} - {key: TOPOLOGY, value: replica_set} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -1238,6 +1261,7 @@ tasks: updates: - {key: VERSION, value: '4.2'} - {key: TOPOLOGY, value: sharded_cluster} + - {key: SSL, value: nossl} - {key: AUTH, value: auth} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2034,6 +2058,7 @@ tasks: - {key: VERSION, value: latest} - {key: TOPOLOGY, value: server} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2051,6 +2076,7 @@ tasks: - {key: VERSION, value: latest} - {key: TOPOLOGY, value: replica_set} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2068,6 +2094,7 @@ tasks: - {key: VERSION, value: latest} - {key: TOPOLOGY, value: sharded_cluster} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2085,6 +2112,7 @@ tasks: - {key: VERSION, value: rapid} - {key: TOPOLOGY, value: server} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2102,6 +2130,7 @@ tasks: - {key: VERSION, value: rapid} - {key: TOPOLOGY, value: replica_set} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2119,6 +2148,7 @@ tasks: - {key: VERSION, value: rapid} - {key: TOPOLOGY, value: sharded_cluster} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2136,6 +2166,7 @@ tasks: - {key: VERSION, value: '8.0'} - {key: TOPOLOGY, value: server} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2153,6 +2184,7 @@ tasks: - {key: VERSION, value: '8.0'} - {key: TOPOLOGY, value: replica_set} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2170,6 +2202,7 @@ tasks: - {key: VERSION, value: '8.0'} - {key: TOPOLOGY, value: sharded_cluster} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2187,6 +2220,7 @@ tasks: - {key: VERSION, value: '7.0'} - {key: TOPOLOGY, value: server} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2204,6 +2238,7 @@ tasks: - {key: VERSION, value: '7.0'} - {key: TOPOLOGY, value: replica_set} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2221,6 +2256,7 @@ tasks: - {key: VERSION, value: '7.0'} - {key: TOPOLOGY, value: sharded_cluster} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2238,6 +2274,7 @@ tasks: - {key: VERSION, value: '6.0'} - {key: TOPOLOGY, value: server} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2255,6 +2292,7 @@ tasks: - {key: VERSION, value: '6.0'} - {key: TOPOLOGY, value: replica_set} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2272,6 +2310,7 @@ tasks: - {key: VERSION, value: '6.0'} - {key: TOPOLOGY, value: sharded_cluster} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2289,6 +2328,7 @@ tasks: - {key: VERSION, value: '5.0'} - {key: TOPOLOGY, value: server} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2306,6 +2346,7 @@ tasks: - {key: VERSION, value: '5.0'} - {key: TOPOLOGY, value: replica_set} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2323,6 +2364,7 @@ tasks: - {key: VERSION, value: '5.0'} - {key: TOPOLOGY, value: sharded_cluster} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2340,6 +2382,7 @@ tasks: - {key: VERSION, value: '4.4'} - {key: TOPOLOGY, value: server} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2357,6 +2400,7 @@ tasks: - {key: VERSION, value: '4.4'} - {key: TOPOLOGY, value: replica_set} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2374,6 +2418,7 @@ tasks: - {key: VERSION, value: '4.4'} - {key: TOPOLOGY, value: sharded_cluster} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2391,6 +2436,7 @@ tasks: - {key: VERSION, value: '4.2'} - {key: TOPOLOGY, value: server} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2408,6 +2454,7 @@ tasks: - {key: VERSION, value: '4.2'} - {key: TOPOLOGY, value: replica_set} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2425,6 +2472,7 @@ tasks: - {key: VERSION, value: '4.2'} - {key: TOPOLOGY, value: sharded_cluster} - {key: AUTH, value: noauth} + - {key: SSL, value: nossl} - {key: NODE_LTS_VERSION, value: 20.19.0} - func: install dependencies - func: bootstrap mongo-orchestration @@ -2590,6 +2638,486 @@ tasks: - func: install dependencies - func: bootstrap mongo-orchestration - func: run tests + - name: test-latest-server-ssl + tags: + - latest + - server + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: latest} + - {key: TOPOLOGY, value: server} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-latest-replica_set-ssl + tags: + - latest + - replica_set + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: latest} + - {key: TOPOLOGY, value: replica_set} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-latest-sharded_cluster-ssl + tags: + - latest + - sharded_cluster + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: latest} + - {key: TOPOLOGY, value: sharded_cluster} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-rapid-server-ssl + tags: + - rapid + - server + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: rapid} + - {key: TOPOLOGY, value: server} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-rapid-replica_set-ssl + tags: + - rapid + - replica_set + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: rapid} + - {key: TOPOLOGY, value: replica_set} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-rapid-sharded_cluster-ssl + tags: + - rapid + - sharded_cluster + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: rapid} + - {key: TOPOLOGY, value: sharded_cluster} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-8.0-server-ssl + tags: + - '8.0' + - server + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '8.0'} + - {key: TOPOLOGY, value: server} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-8.0-replica_set-ssl + tags: + - '8.0' + - replica_set + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '8.0'} + - {key: TOPOLOGY, value: replica_set} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-8.0-sharded_cluster-ssl + tags: + - '8.0' + - sharded_cluster + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '8.0'} + - {key: TOPOLOGY, value: sharded_cluster} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-7.0-server-ssl + tags: + - '7.0' + - server + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '7.0'} + - {key: TOPOLOGY, value: server} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-7.0-replica_set-ssl + tags: + - '7.0' + - replica_set + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '7.0'} + - {key: TOPOLOGY, value: replica_set} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-7.0-sharded_cluster-ssl + tags: + - '7.0' + - sharded_cluster + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '7.0'} + - {key: TOPOLOGY, value: sharded_cluster} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-6.0-server-ssl + tags: + - '6.0' + - server + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '6.0'} + - {key: TOPOLOGY, value: server} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-6.0-replica_set-ssl + tags: + - '6.0' + - replica_set + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '6.0'} + - {key: TOPOLOGY, value: replica_set} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-6.0-sharded_cluster-ssl + tags: + - '6.0' + - sharded_cluster + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '6.0'} + - {key: TOPOLOGY, value: sharded_cluster} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-5.0-server-ssl + tags: + - '5.0' + - server + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '5.0'} + - {key: TOPOLOGY, value: server} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-5.0-replica_set-ssl + tags: + - '5.0' + - replica_set + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '5.0'} + - {key: TOPOLOGY, value: replica_set} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-5.0-sharded_cluster-ssl + tags: + - '5.0' + - sharded_cluster + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '5.0'} + - {key: TOPOLOGY, value: sharded_cluster} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-4.4-server-ssl + tags: + - '4.4' + - server + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '4.4'} + - {key: TOPOLOGY, value: server} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-4.4-replica_set-ssl + tags: + - '4.4' + - replica_set + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '4.4'} + - {key: TOPOLOGY, value: replica_set} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-4.4-sharded_cluster-ssl + tags: + - '4.4' + - sharded_cluster + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '4.4'} + - {key: TOPOLOGY, value: sharded_cluster} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-4.2-server-ssl + tags: + - '4.2' + - server + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '4.2'} + - {key: TOPOLOGY, value: server} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-4.2-replica_set-ssl + tags: + - '4.2' + - replica_set + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '4.2'} + - {key: TOPOLOGY, value: replica_set} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests + - name: test-4.2-sharded_cluster-ssl + tags: + - '4.2' + - sharded_cluster + - ssl + commands: + - command: expansions.update + type: setup + params: + updates: + - {key: VERSION, value: '4.2'} + - {key: TOPOLOGY, value: sharded_cluster} + - {key: AUTH, value: auth} + - {key: SSL, value: ssl} + - {key: NODE_LTS_VERSION, value: '24'} + - {key: CLIENT_ENCRYPTION, value: 'true'} + - {key: TEST_CSFLE, value: 'true'} + - func: install dependencies + - func: bootstrap mongo-orchestration + - func: run tests task_groups: - name: test_gcpkms_task_group setup_group_can_fail_task: true @@ -3370,3 +3898,8 @@ buildvariants: run_on: rhel80-large tasks: - .resource-management + - name: TLS tests + display_name: TLS smoke tests + run_on: rhel80-large + tasks: + - .ssl diff --git a/.evergreen/generate_evergreen_tasks.js b/.evergreen/generate_evergreen_tasks.js index ff977cdede..e5f0b691af 100644 --- a/.evergreen/generate_evergreen_tasks.js +++ b/.evergreen/generate_evergreen_tasks.js @@ -64,20 +64,37 @@ function updateExpansions(expansions) { }; } -function makeTask({ mongoVersion, topology, tags = [], auth = 'auth', nodeLtsVersion }) { - const expansions = nodeLtsVersion - ? updateExpansions({ +function makeTask({ + mongoVersion, + topology, + tags = [], + auth = 'auth', + ssl = 'nossl', + testCsfle, + nodeLtsVersion +}) { + const baseExpansions = nodeLtsVersion + ? { VERSION: mongoVersion, TOPOLOGY: topology, AUTH: auth, + SSL: ssl, NODE_LTS_VERSION: nodeLtsVersion - }) - : updateExpansions({ VERSION: mongoVersion, TOPOLOGY: topology, AUTH: auth }); + } + : { VERSION: mongoVersion, TOPOLOGY: topology, SSL: ssl, AUTH: auth }; + + if (testCsfle) { + baseExpansions.CLIENT_ENCRYPTION = true; + baseExpansions.TEST_CSFLE = true; + } + + const name = `test-${mongoVersion}-${topology}${auth === 'noauth' ? '-noauth' : ''}${ssl === 'ssl' ? '-ssl' : ''}`; + return { - name: `test-${mongoVersion}-${topology}${auth === 'noauth' ? '-noauth' : ''}`, + name, tags: [mongoVersion, topology, ...tags], commands: [ - expansions, + updateExpansions(baseExpansions), { func: 'install dependencies' }, { func: 'bootstrap mongo-orchestration' }, { func: 'run tests' } @@ -469,6 +486,17 @@ const unitTestTasks = Array.from( })() ); +const tlsTests = generateVersionTopologyMatrix().map(({ mongoVersion, topology }) => + makeTask({ + mongoVersion, + topology, + ssl: 'ssl', + tags: ['ssl'], + nodeLtsVersion: LATEST_LTS, + testCsfle: true + }) +); + // singleton build variant for linting SINGLETON_TASKS.push( ...[ @@ -776,6 +804,13 @@ BUILD_VARIANTS.push({ tasks: ['.resource-management'] }); +BUILD_VARIANTS.push({ + name: 'TLS tests', + display_name: 'TLS smoke tests', + run_on: DEFAULT_OS, + tasks: ['.ssl'] +}); + // TODO(NODE-4897): Debug socks5 tests on node latest for (const variant of BUILD_VARIANTS.filter( variant => variant.expansions && ['latest'].includes(variant.expansions.NODE_LTS_VERSION) @@ -791,7 +826,8 @@ fileData.tasks = [ ...SINGLETON_TASKS, ...AUTH_DISABLED_TASKS, ...AWS_LAMBDA_HANDLER_TASKS, - ...MONGOCRYPTD_CSFLE_TASKS + ...MONGOCRYPTD_CSFLE_TASKS, + ...tlsTests ]; fileData.buildvariants = [...(fileData.buildvariants ?? []), ...BUILD_VARIANTS]; diff --git a/.evergreen/run-tests.sh b/.evergreen/run-tests.sh index 87ad6f4da7..667f5cfc46 100755 --- a/.evergreen/run-tests.sh +++ b/.evergreen/run-tests.sh @@ -26,8 +26,8 @@ fi # ssl setup SSL=${SSL:-nossl} if [ "$SSL" != "nossl" ]; then - export SSL_KEY_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/client.pem" - export SSL_CA_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/ca.pem" + export TLS_KEY_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/client.pem" + export TLS_CA_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/ca.pem" fi # run tests diff --git a/global.d.ts b/global.d.ts index 13cd171c47..968e5b03c0 100644 --- a/global.d.ts +++ b/global.d.ts @@ -20,8 +20,10 @@ declare global { idmsMockServer?: true; nodejs?: string; predicate?: (test?: Mocha.Test) => true | string; - crypt_shared?: 'enabled' | 'disabled', + crypt_shared?: 'enabled' | 'disabled'; libmongocrypt?: string; + + tls?: 'enabled' | 'disabled'; }; sessions?: { diff --git a/test/integration/auth/auth.prose.test.ts b/test/integration/auth/auth.prose.test.ts index dfc0b8b1fe..5abdd398ca 100644 --- a/test/integration/auth/auth.prose.test.ts +++ b/test/integration/auth/auth.prose.test.ts @@ -15,7 +15,8 @@ function makeConnectionString(config, username, password) { const metadata: MongoDBMetadataUI = { requires: { predicate: () => - process.env.LOAD_BALANCER ? 'TODO(NODE-5631): fix tests to run in load balancer mode.' : true + process.env.LOAD_BALANCER ? 'TODO(NODE-5631): fix tests to run in load balancer mode.' : true, + tls: 'disabled' } }; diff --git a/test/integration/change-streams/change_stream.test.ts b/test/integration/change-streams/change_stream.test.ts index a7b8dec85c..c3011a4168 100644 --- a/test/integration/change-streams/change_stream.test.ts +++ b/test/integration/change-streams/change_stream.test.ts @@ -251,6 +251,7 @@ describe('Change Streams', function () { beforeEach(async function () { client = this.configuration.newClient(); + await client.connect(); }); afterEach(async function () { @@ -1267,46 +1268,54 @@ describe('Change Streams', function () { await mock.cleanup(); }); - it('changeStream should close if cursor id for initial aggregate is Long.ZERO', async function () { - mockServer.setMessageHandler(req => { - const doc = req.document; - if (isHello(doc)) { - return req.reply(mock.HELLO); - } - if (doc.aggregate) { - return req.reply({ - ok: 1, - cursor: { - id: Long.ZERO, - firstBatch: [] - } - }); - } - if (doc.getMore) { - return req.reply({ - ok: 1, - cursor: { - id: new Long(1407, 1407), - nextBatch: [] - } - }); + it( + 'changeStream should close if cursor id for initial aggregate is Long.ZERO', + { + requires: { + tls: 'disabled' } - req.reply({ ok: 1 }); - }); - const client = this.configuration.newClient(`mongodb://${mockServer.uri()}/`, { - serverApi: null // TODO(NODE-3807): remove resetting serverApi when the usage of mongodb mock server is removed - }); - await client.connect(); - const collection = client.db('cs').collection('test'); - const changeStream = collection.watch(); + }, + async function () { + mockServer.setMessageHandler(req => { + const doc = req.document; + if (isHello(doc)) { + return req.reply(mock.HELLO); + } + if (doc.aggregate) { + return req.reply({ + ok: 1, + cursor: { + id: Long.ZERO, + firstBatch: [] + } + }); + } + if (doc.getMore) { + return req.reply({ + ok: 1, + cursor: { + id: new Long(1407, 1407), + nextBatch: [] + } + }); + } + req.reply({ ok: 1 }); + }); + const client = this.configuration.newClient(`mongodb://${mockServer.uri()}/`, { + serverApi: null // TODO(NODE-3807): remove resetting serverApi when the usage of mongodb mock server is removed + }); + await client.connect(); + const collection = client.db('cs').collection('test'); + const changeStream = collection.watch(); - const err = await changeStream.next().catch(e => e); - expect(err).to.exist; - expect(err?.message).to.equal('ChangeStream is closed'); + const err = await changeStream.next().catch(e => e); + expect(err).to.exist; + expect(err?.message).to.equal('ChangeStream is closed'); - await changeStream.close(); - await client.close(); - }); + await changeStream.close(); + await client.close(); + } + ); }); }); diff --git a/test/integration/change-streams/change_streams.prose.test.ts b/test/integration/change-streams/change_streams.prose.test.ts index 7a876c0d88..e39a4e652f 100644 --- a/test/integration/change-streams/change_streams.prose.test.ts +++ b/test/integration/change-streams/change_streams.prose.test.ts @@ -328,48 +328,52 @@ describe('Change Stream prose tests', function () { // Expected result: // getResumeToken must return the postBatchResumeToken from the current command response. describe('for emptied batch on server', function () { - it('must return the postBatchResumeToken from the current command response', function () { - const manager = new MockServerManager(this.configuration, { - aggregate: (function* () { - yield { numDocuments: 0, postBatchResumeToken: true, cursor: { firstBatch: [] } }; - })(), - getMore: (function* () { - yield { numDocuments: 1, postBatchResumeToken: true, cursor: { nextBatch: [{}] } }; - })() - }); + it( + 'must return the postBatchResumeToken from the current command response', + { requires: { tls: 'disabled' } }, + function () { + const manager = new MockServerManager(this.configuration, { + aggregate: (function* () { + yield { numDocuments: 0, postBatchResumeToken: true, cursor: { firstBatch: [] } }; + })(), + getMore: (function* () { + yield { numDocuments: 1, postBatchResumeToken: true, cursor: { nextBatch: [{}] } }; + })() + }); - return manager - .ready() - .then(() => { - return manager.makeChangeStream().next(); - }) - .then( - () => manager.teardown(), - err => manager.teardown(err) - ) - .then(() => { - const tokens = manager.resumeTokenChangedEvents.map(e => e.resumeToken); - const successes = manager.apm.succeeded.map(e => { - try { - // @ts-expect-error: e.reply is unknown - return e.reply.cursor; - } catch { - return {}; - } - }); + return manager + .ready() + .then(() => { + return manager.makeChangeStream().next(); + }) + .then( + () => manager.teardown(), + err => manager.teardown(err) + ) + .then(() => { + const tokens = manager.resumeTokenChangedEvents.map(e => e.resumeToken); + const successes = manager.apm.succeeded.map(e => { + try { + // @ts-expect-error: e.reply is unknown + return e.reply.cursor; + } catch { + return {}; + } + }); - expect(successes).to.have.a.lengthOf(2); - expect(successes[0]).to.have.a.property('postBatchResumeToken'); - expect(successes[1]).to.have.a.property('postBatchResumeToken'); - expect(successes[1]).to.have.a.nested.property('nextBatch[0]._id'); + expect(successes).to.have.a.lengthOf(2); + expect(successes[0]).to.have.a.property('postBatchResumeToken'); + expect(successes[1]).to.have.a.property('postBatchResumeToken'); + expect(successes[1]).to.have.a.nested.property('nextBatch[0]._id'); - expect(tokens).to.have.a.lengthOf(2); - expect(tokens[0]).to.deep.equal(successes[0].postBatchResumeToken); - expect(tokens[1]) - .to.deep.equal(successes[1].postBatchResumeToken) - .and.to.not.deep.equal(successes[1].nextBatch[0]._id); - }); - }); + expect(tokens).to.have.a.lengthOf(2); + expect(tokens[0]).to.deep.equal(successes[0].postBatchResumeToken); + expect(tokens[1]) + .to.deep.equal(successes[1].postBatchResumeToken) + .and.to.not.deep.equal(successes[1].nextBatch[0]._id); + }); + } + ); }); // 13. For a ChangeStream under these conditions: @@ -378,46 +382,50 @@ describe('Change Stream prose tests', function () { // Expected result: // getResumeToken must return the _id of the previous document returned. describe('for non-empty batch iterated up to but not including the last element', function () { - it('must return the _id of the previous document returned', function () { - const manager = new MockServerManager(this.configuration, { - aggregate: (function* () { - yield { numDocuments: 2, postBatchResumeToken: true }; - })(), - getMore: (function* () { - // fake getMore - })() - }); + it( + 'must return the _id of the previous document returned', + { requires: { tls: 'disabled' } }, + function () { + const manager = new MockServerManager(this.configuration, { + aggregate: (function* () { + yield { numDocuments: 2, postBatchResumeToken: true }; + })(), + getMore: (function* () { + // fake getMore + })() + }); - return manager - .ready() - .then(() => { - return manager.makeChangeStream().next(); - }) - .then( - () => manager.teardown(), - err => manager.teardown(err) - ) - .then(() => { - const tokens = manager.resumeTokenChangedEvents.map(e => e.resumeToken); - const successes = manager.apm.succeeded.map(e => { - try { - // @ts-expect-error: e.reply is unknown - return e.reply.cursor; - } catch { - return {}; - } - }); + return manager + .ready() + .then(() => { + return manager.makeChangeStream().next(); + }) + .then( + () => manager.teardown(), + err => manager.teardown(err) + ) + .then(() => { + const tokens = manager.resumeTokenChangedEvents.map(e => e.resumeToken); + const successes = manager.apm.succeeded.map(e => { + try { + // @ts-expect-error: e.reply is unknown + return e.reply.cursor; + } catch { + return {}; + } + }); - expect(successes).to.have.a.lengthOf(1); - expect(successes[0]).to.have.a.nested.property('firstBatch[0]._id'); - expect(successes[0]).to.have.a.property('postBatchResumeToken'); + expect(successes).to.have.a.lengthOf(1); + expect(successes[0]).to.have.a.nested.property('firstBatch[0]._id'); + expect(successes[0]).to.have.a.property('postBatchResumeToken'); - expect(tokens).to.have.a.lengthOf(1); - expect(tokens[0]) - .to.deep.equal(successes[0].firstBatch[0]._id) - .and.to.not.deep.equal(successes[0].postBatchResumeToken); - }); - }); + expect(tokens).to.have.a.lengthOf(1); + expect(tokens[0]) + .to.deep.equal(successes[0].firstBatch[0]._id) + .and.to.not.deep.equal(successes[0].postBatchResumeToken); + }); + } + ); }); // 14. For a ChangeStream under these conditions: @@ -429,113 +437,125 @@ describe('Change Stream prose tests', function () { // getResumeToken must return resumeAfter from the initial aggregate if the option was specified. // If neither the startAfter nor resumeAfter options were specified, the getResumeToken result must be empty. describe('for non-empty non-iterated batch where only the initial aggregate command has been executed', function () { - it('must return startAfter from the initial aggregate if the option was specified', function () { - const manager = new MockServerManager(this.configuration, { - aggregate: (function* () { - yield { numDocuments: 0, postBatchResumeToken: false }; - })(), - getMore: (function* () { - yield { numDocuments: 0, postBatchResumeToken: false }; - })() - }); - let token; - const startAfter = manager.resumeToken(); - const resumeAfter = manager.resumeToken(); - - return manager - .ready() - .then(() => { - return new Promise(resolve => { - const changeStream = manager.makeChangeStream({ startAfter, resumeAfter }); - changeStream.cursor.once('response', () => { - token = changeStream.resumeToken; - resolve(); - }); - - changeStream.next().catch(() => { - // Note: this is expected to fail + it( + 'must return startAfter from the initial aggregate if the option was specified', + { requires: { tls: 'disabled' } }, + function () { + const manager = new MockServerManager(this.configuration, { + aggregate: (function* () { + yield { numDocuments: 0, postBatchResumeToken: false }; + })(), + getMore: (function* () { + yield { numDocuments: 0, postBatchResumeToken: false }; + })() + }); + let token; + const startAfter = manager.resumeToken(); + const resumeAfter = manager.resumeToken(); + + return manager + .ready() + .then(() => { + return new Promise(resolve => { + const changeStream = manager.makeChangeStream({ startAfter, resumeAfter }); + changeStream.cursor.once('response', () => { + token = changeStream.resumeToken; + resolve(); + }); + + changeStream.next().catch(() => { + // Note: this is expected to fail + }); }); + }) + .then( + () => manager.teardown(), + err => manager.teardown(err) + ) + .then(() => { + expect(token).to.deep.equal(startAfter).and.to.not.deep.equal(resumeAfter); }); - }) - .then( - () => manager.teardown(), - err => manager.teardown(err) - ) - .then(() => { - expect(token).to.deep.equal(startAfter).and.to.not.deep.equal(resumeAfter); + } + ); + + it( + 'must return resumeAfter from the initial aggregate if the option was specified', + { requires: { tls: 'disabled' } }, + function () { + const manager = new MockServerManager(this.configuration, { + aggregate: (function* () { + yield { numDocuments: 0, postBatchResumeToken: false }; + })(), + getMore: (function* () { + yield { numDocuments: 0, postBatchResumeToken: false }; + })() }); - }); - - it('must return resumeAfter from the initial aggregate if the option was specified', function () { - const manager = new MockServerManager(this.configuration, { - aggregate: (function* () { - yield { numDocuments: 0, postBatchResumeToken: false }; - })(), - getMore: (function* () { - yield { numDocuments: 0, postBatchResumeToken: false }; - })() - }); - let token; - const resumeAfter = manager.resumeToken(); - - return manager - .ready() - .then(() => { - return new Promise(resolve => { - const changeStream = manager.makeChangeStream({ resumeAfter }); - changeStream.cursor.once('response', () => { - token = changeStream.resumeToken; - resolve(); - }); - - changeStream.next().catch(() => { - // Note: this is expected to fail + let token; + const resumeAfter = manager.resumeToken(); + + return manager + .ready() + .then(() => { + return new Promise(resolve => { + const changeStream = manager.makeChangeStream({ resumeAfter }); + changeStream.cursor.once('response', () => { + token = changeStream.resumeToken; + resolve(); + }); + + changeStream.next().catch(() => { + // Note: this is expected to fail + }); }); + }) + .then( + () => manager.teardown(), + err => manager.teardown(err) + ) + .then(() => { + expect(token).to.deep.equal(resumeAfter); }); - }) - .then( - () => manager.teardown(), - err => manager.teardown(err) - ) - .then(() => { - expect(token).to.deep.equal(resumeAfter); + } + ); + + it( + 'must be empty if neither the startAfter nor resumeAfter options were specified', + { requires: { tls: 'disabled' } }, + function () { + const manager = new MockServerManager(this.configuration, { + aggregate: (function* () { + yield { numDocuments: 0, postBatchResumeToken: false }; + })(), + getMore: (function* () { + yield { numDocuments: 0, postBatchResumeToken: false }; + })() }); - }); - - it('must be empty if neither the startAfter nor resumeAfter options were specified', function () { - const manager = new MockServerManager(this.configuration, { - aggregate: (function* () { - yield { numDocuments: 0, postBatchResumeToken: false }; - })(), - getMore: (function* () { - yield { numDocuments: 0, postBatchResumeToken: false }; - })() - }); - let token; - - return manager - .ready() - .then(() => { - return new Promise(resolve => { - const changeStream = manager.makeChangeStream(); - changeStream.cursor.once('response', () => { - token = changeStream.resumeToken; - resolve(); - }); - - changeStream.next().catch(() => { - // Note: this is expected to fail + let token; + + return manager + .ready() + .then(() => { + return new Promise(resolve => { + const changeStream = manager.makeChangeStream(); + changeStream.cursor.once('response', () => { + token = changeStream.resumeToken; + resolve(); + }); + + changeStream.next().catch(() => { + // Note: this is expected to fail + }); }); + }) + .then( + () => manager.teardown(), + err => manager.teardown(err) + ) + .then(() => { + expect(token).to.not.exist; }); - }) - .then( - () => manager.teardown(), - err => manager.teardown(err) - ) - .then(() => { - expect(token).to.not.exist; - }); - }); + } + ); }); }); diff --git a/test/integration/client-side-operations-timeout/client_side_operations_timeout.prose.test.ts b/test/integration/client-side-operations-timeout/client_side_operations_timeout.prose.test.ts index 6a56563091..d785e61e2c 100644 --- a/test/integration/client-side-operations-timeout/client_side_operations_timeout.prose.test.ts +++ b/test/integration/client-side-operations-timeout/client_side_operations_timeout.prose.test.ts @@ -639,6 +639,8 @@ describe('CSOT spec prose tests', function () { this.configuration.url({ useMultipleMongoses: false }), { timeoutMS: 150 } ); + + await client.connect(); }); afterEach(async function () { diff --git a/test/integration/collection-management/collection.test.ts b/test/integration/collection-management/collection.test.ts index 7adaf2b13c..cf1e71ac26 100644 --- a/test/integration/collection-management/collection.test.ts +++ b/test/integration/collection-management/collection.test.ts @@ -17,10 +17,15 @@ describe('Collection', function () { let client: MongoClient; let db: Db; - beforeEach(function () { - client = configuration.newClient(configuration.writeConcernMax(), { - maxPoolSize: 1 - }); + beforeEach(async function () { + client = configuration.newClient( + {}, + { + ...this.configuration.writeConcernMax(), + maxPoolSize: 1 + } + ); + await client.connect(); db = client.db(configuration.db); }); @@ -79,9 +84,9 @@ describe('Collection', function () { expect(found2).to.be.true; }); - it('should permit insert of dot and dollar keys if requested', function () { + it('should permit insert of dot and dollar keys if requested', async function () { const collection = db.collection('test_invalid_key_names'); - return Promise.all([ + await Promise.all([ collection.insertOne({ hel$lo: 0 }, { checkKeys: false }), collection.insertOne({ hello: { $hello: 0 } }, { checkKeys: false }), // embedded document can have a leading dollar collection.insertOne({ 'hel.lo': 0 }, { checkKeys: false }), diff --git a/test/integration/command-logging-and-monitoring/command_monitoring.test.ts b/test/integration/command-logging-and-monitoring/command_monitoring.test.ts index 01c596c07f..e68daa3f42 100644 --- a/test/integration/command-logging-and-monitoring/command_monitoring.test.ts +++ b/test/integration/command-logging-and-monitoring/command_monitoring.test.ts @@ -557,7 +557,7 @@ describe('Command Monitoring', function () { it('should correctly decorate the apm result for listCollections with cursorId', { metadata: { requires: { topology: ['single', 'replicaset'], mongodb: '>=3.0.0' } }, - test: function () { + test: async function () { const started = []; const succeeded = []; const client = this.configuration.newClient( @@ -565,6 +565,7 @@ describe('Command Monitoring', function () { { maxPoolSize: 1, monitorCommands: true } ); + await client.connect(); const desiredEvents = ['listCollections']; client.on('commandStarted', filterForCommands(desiredEvents, started)); client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded)); diff --git a/test/integration/connection-monitoring-and-pooling/connection.test.ts b/test/integration/connection-monitoring-and-pooling/connection.test.ts index 0e6ccff28a..a20f36c7b6 100644 --- a/test/integration/connection-monitoring-and-pooling/connection.test.ts +++ b/test/integration/connection-monitoring-and-pooling/connection.test.ts @@ -43,7 +43,7 @@ describe('Connection', function () { describe('Connection.command', function () { it('should execute a command against a server', { - metadata: { requires: { apiVersion: false, topology: '!load-balanced' } }, + metadata: { requires: { apiVersion: false, topology: '!load-balanced', tls: 'disabled' } }, test: async function () { const connectOptions: ConnectionOptions = { ...commonConnectOptions, @@ -64,7 +64,7 @@ describe('Connection', function () { }); it('should emit command monitoring events', { - metadata: { requires: { apiVersion: false, topology: '!load-balanced' } }, + metadata: { requires: { apiVersion: false, topology: '!load-balanced', tls: 'disabled' } }, test: async function () { const connectOptions: ConnectionOptions = { ...commonConnectOptions, @@ -95,7 +95,7 @@ describe('Connection', function () { afterEach(() => sinon.restore()); it('command monitoring event do not deserialize more than once', { - metadata: { requires: { apiVersion: false, topology: '!load-balanced' } }, + metadata: { requires: { apiVersion: false, topology: '!load-balanced', tls: 'disabled' } }, test: async function () { const connectOptions: ConnectionOptions = { ...commonConnectOptions, diff --git a/test/integration/crud/aggregation.test.ts b/test/integration/crud/aggregation.test.ts index 92602f7b87..6e2ace06f0 100644 --- a/test/integration/crud/aggregation.test.ts +++ b/test/integration/crud/aggregation.test.ts @@ -832,6 +832,8 @@ describe('Aggregation', function () { const coll1 = client.db(databaseName).collection('coll1'); const coll2 = client.db(databaseName).collection('coll2'); + await client.connect(); + await Promise.all([coll1.deleteMany({}), coll2.deleteMany({})]) .then(() => { const docs = Array.from({ length: 10 }).map(() => ({ a: 1 })); diff --git a/test/integration/initial-dns-seedlist-discovery/dns_seedlist.test.ts b/test/integration/initial-dns-seedlist-discovery/dns_seedlist.test.ts index 0618c376c0..15ad016cc3 100644 --- a/test/integration/initial-dns-seedlist-discovery/dns_seedlist.test.ts +++ b/test/integration/initial-dns-seedlist-discovery/dns_seedlist.test.ts @@ -4,7 +4,7 @@ import * as sinon from 'sinon'; import { MongoClient } from '../../../src'; -const metadata: MongoDBMetadataUI = { requires: { topology: '!single' } }; +const metadata: MongoDBMetadataUI = { requires: { topology: '!single', tls: 'disabled' } }; // This serves as a placeholder for _whatever_ node.js may throw. We only rely upon `.code` class DNSTimeoutError extends Error { diff --git a/test/integration/max-staleness/max_staleness.test.js b/test/integration/max-staleness/max_staleness.test.js index 2bb712cd70..867bdc92fe 100644 --- a/test/integration/max-staleness/max_staleness.test.js +++ b/test/integration/max-staleness/max_staleness.test.js @@ -46,7 +46,7 @@ describe('Max Staleness', function () { it('should correctly set maxStalenessSeconds on Mongos query on connect', { metadata: { requires: { - generators: true, + tls: 'disabled', topology: 'replicaset' } }, @@ -72,7 +72,7 @@ describe('Max Staleness', function () { it('should correctly set maxStalenessSeconds on Mongos query using db level readPreference', { metadata: { requires: { - generators: true, + tls: 'disabled', topology: 'replicaset' } }, @@ -102,7 +102,7 @@ describe('Max Staleness', function () { { metadata: { requires: { - generators: true, + tls: 'disabled', topology: 'replicaset' } }, @@ -135,7 +135,7 @@ describe('Max Staleness', function () { it('should correctly set maxStalenessSeconds on Mongos query using cursor level readPreference', { metadata: { requires: { - generators: true, + tls: 'disabled', topology: 'replicaset' } }, diff --git a/test/integration/mongodb-handshake/mongodb-handshake.prose.test.ts b/test/integration/mongodb-handshake/mongodb-handshake.prose.test.ts index 6e53e84699..219ef6f70e 100644 --- a/test/integration/mongodb-handshake/mongodb-handshake.prose.test.ts +++ b/test/integration/mongodb-handshake/mongodb-handshake.prose.test.ts @@ -2,7 +2,7 @@ import { expect } from 'chai'; import * as process from 'process'; import * as sinon from 'sinon'; -import { type ClientMetadata, type DriverInfo, Int32, MongoClient } from '../../../src'; +import { type ClientMetadata, type DriverInfo, Int32, type MongoClient } from '../../../src'; import { Connection } from '../../../src/cmap/connection'; import { getFAASEnv, isDriverInfoEqual } from '../../../src/cmap/handshake/client_metadata'; import { LEGACY_HELLO_COMMAND } from '../../../src/constants'; @@ -397,7 +397,7 @@ describe('Client Metadata Update Prose Tests', function () { // 4. Save intercepted `client` document as `updatedClientMetadata`. // 5. Wait 5ms for the connection to become idle. beforeEach(async function () { - client = new MongoClient(this.configuration.url(), { + client = this.configuration.newClient(this.configuration.url(), { maxIdleTimeMS: 1, serverApi: this.configuration.serverApi }); @@ -488,10 +488,13 @@ describe('Client Metadata Update Prose Tests', function () { // 1. Create a `MongoClient` instance with: // - `maxIdleTimeMS` set to `1ms` - client = new MongoClient(this.configuration.url(), { - maxIdleTimeMS: 1, - serverApi: this.configuration.serverApi - }); + client = this.configuration.newClient( + {}, + { + maxIdleTimeMS: 1, + serverApi: this.configuration.serverApi + } + ); // 2. Append the following `DriverInfoOptions` to the `MongoClient` metadata: // | Field | Value | // | -------- | ---------------- | @@ -592,7 +595,7 @@ describe('Client Metadata Update Prose Tests', function () { // | name | library | // | version | 1.2 | // | platform | Library Platform | - client = new MongoClient(this.configuration.url(), { + client = this.configuration.newClient(this.configuration.url(), { maxIdleTimeMS: 1, serverApi: this.configuration.serverApi, driverInfo: { name: 'library', version: '1.2', platform: 'Library Platform' } @@ -663,7 +666,7 @@ describe('Client Metadata Update Prose Tests', function () { // | version | 1.2 | // | platform | Library Platform | - client = new MongoClient(this.configuration.url(), { + client = this.configuration.newClient(this.configuration.url(), { maxIdleTimeMS: 1, driverInfo: { name: 'library', @@ -793,7 +796,7 @@ describe('Client Metadata Update Prose Tests', function () { it('does not appended duplicate metadata', async function () { // 1. Create a `MongoClient` instance with: // - `maxIdleTimeMS` set to `1ms` - client = new MongoClient(this.configuration.url(), { + client = this.configuration.newClient(this.configuration.url(), { maxIdleTimeMS: 1, serverApi: this.configuration.serverApi }); @@ -897,7 +900,7 @@ describe('Client Metadata Update Prose Tests', function () { // 1. Create a `MongoClient` instance with: // - `maxIdleTimeMS` set to `1ms` // - `driverInfo` set to the `DriverInfoOptions` from the selected test case from the initial metadata section. - client = new MongoClient(this.configuration.url(), { + client = this.configuration.newClient(this.configuration.url(), { maxIdleTimeMS: 1, serverApi: this.configuration.serverApi, driverInfo: metadata.initial diff --git a/test/integration/node-specific/client_close.test.ts b/test/integration/node-specific/client_close.test.ts index 1e9188b1cf..74f380e938 100644 --- a/test/integration/node-specific/client_close.test.ts +++ b/test/integration/node-specific/client_close.test.ts @@ -536,7 +536,7 @@ describe('MongoClient.close() Integration', () => { expect(client.s.sessionPool.sessions).to.have.length.greaterThan(0); }); - it('does not execute endSessions', async function () { + it('does not execute endSessions', { requires: { tls: 'disabled' } }, async function () { await client.close(); expect(commands).to.deep.equal([]); diff --git a/test/integration/node-specific/mongo_client.test.ts b/test/integration/node-specific/mongo_client.test.ts index 725c42e7b0..001c33a919 100644 --- a/test/integration/node-specific/mongo_client.test.ts +++ b/test/integration/node-specific/mongo_client.test.ts @@ -126,8 +126,7 @@ describe('class MongoClient', function () { beforeEach(async function () { spy = sinon.spy(net, 'createConnection'); - const uri = this.configuration.url(); - client = new MongoClient(uri, options); + client = this.configuration.newClient({}, options); await client.connect(); }); @@ -137,7 +136,7 @@ describe('class MongoClient', function () { }); it('passes through the option', { - metadata: { requires: { apiVersion: false } }, + metadata: { requires: { apiVersion: false, tls: 'disabled' } }, test: function () { expect(spy).to.have.been.calledWith( sinon.match({ @@ -156,8 +155,7 @@ describe('class MongoClient', function () { beforeEach(async function () { spy = sinon.spy(net, 'createConnection'); - const uri = this.configuration.url(); - client = new MongoClient(uri, options); + client = this.configuration.newClient({}, options); await client.connect(); }); @@ -167,7 +165,7 @@ describe('class MongoClient', function () { }); it('passes through the option', { - metadata: { requires: { apiVersion: false } }, + metadata: { requires: { apiVersion: false, tls: 'disabled' } }, test: function () { expect(spy).to.have.been.calledWith( sinon.match({ @@ -186,8 +184,7 @@ describe('class MongoClient', function () { beforeEach(async function () { spy = sinon.spy(net, 'createConnection'); - const uri = this.configuration.url(); - client = new MongoClient(uri, options); + client = this.configuration.newClient({}, options); await client.connect(); }); @@ -197,7 +194,7 @@ describe('class MongoClient', function () { }); it('the Node.js runtime sets the option to 0', { - metadata: { requires: { apiVersion: false } }, + metadata: { requires: { apiVersion: false, tls: 'disabled' } }, test: function () { expect(spy).to.have.been.calledWith( sinon.match({ @@ -228,7 +225,7 @@ describe('class MongoClient', function () { }); it('throws an error', { - metadata: { requires: { apiVersion: false } }, + metadata: { requires: { apiVersion: false, tls: 'disabled' } }, test: async function () { const error = await client.connect().catch(error => error); expect(error.message).to.include( @@ -254,7 +251,7 @@ describe('class MongoClient', function () { spy.restore(); }); - it('sets keepalive to 120000', function () { + it('sets keepalive to 120000', { requires: { tls: 'disabled' } }, function () { expect(spy).to.have.been.calledWith( sinon.match({ keepAlive: true, @@ -279,13 +276,19 @@ describe('class MongoClient', function () { spy.restore(); }); - it('sets noDelay to true', function () { - expect(spy).to.have.been.calledWith( - sinon.match({ - noDelay: true - }) - ); - }); + it( + 'sets noDelay to true', + { + requires: { tls: 'disabled' } + }, + function () { + expect(spy).to.have.been.calledWith( + sinon.match({ + noDelay: true + }) + ); + } + ); }); context('when noDelay is provided', function () { @@ -295,8 +298,7 @@ describe('class MongoClient', function () { beforeEach(async function () { const options = { noDelay: false }; spy = sinon.spy(net, 'createConnection'); - const uri = this.configuration.url(); - client = new MongoClient(uri, options); + client = this.configuration.newClient({}, options); await client.connect(); }); @@ -306,7 +308,7 @@ describe('class MongoClient', function () { }); it('sets noDelay', { - metadata: { requires: { apiVersion: false } }, + metadata: { requires: { apiVersion: false, tls: 'disabled' } }, test: function () { expect(spy).to.have.been.calledWith( sinon.match({ @@ -463,26 +465,32 @@ describe('class MongoClient', function () { it('must respect a finite connectTimeoutMS for the streaming protocol', { metadata: { requires: { topology: 'replicaset', mongodb: '>= 4.4' } }, test: async function () { - client = this.configuration.newClient({ - connectTimeoutMS: 10, - heartbeatFrequencyMS: 500 - }); + client = this.configuration.newClient( + {}, + { + connectTimeoutMS: 2000, + heartbeatFrequencyMS: 500 + } + ); const spy = sinon.spy(Connection.prototype, 'command'); await client.connect(); const options = spy.getCall(0).args[2]; - expect(options).property('socketTimeoutMS').to.equal(10); + expect(options).property('socketTimeoutMS').to.equal(2000); } }); context('explict #connect()', () => { let client: MongoClient; beforeEach(function () { - client = this.configuration.newClient(this.configuration.url(), { - monitorCommands: true - }); + client = this.configuration.newClient( + {}, + { + monitorCommands: true + } + ); }); afterEach(async function () { @@ -519,9 +527,12 @@ describe('class MongoClient', function () { context('implicit #connect()', () => { let client: MongoClient; beforeEach(function () { - client = this.configuration.newClient(this.configuration.url(), { - monitorCommands: true - }); + client = this.configuration.newClient( + {}, + { + monitorCommands: true + } + ); }); afterEach(async function () { @@ -1034,7 +1045,7 @@ describe('class MongoClient', function () { }); it('sets the provided options', { - metadata: { requires: { topology: ['single'] } }, + metadata: { requires: { topology: ['single'], tls: 'disabled' } }, test: async function () { await client.connect(); expect(netSpy).to.have.been.calledWith( @@ -1053,7 +1064,7 @@ describe('class MongoClient', function () { }); it('sets the default options', { - metadata: { requires: { topology: ['single'] } }, + metadata: { requires: { topology: ['single'], tls: 'disabled' } }, test: async function () { await client.connect(); expect(netSpy).to.have.been.calledWith( diff --git a/test/integration/node-specific/resource_clean_up.test.ts b/test/integration/node-specific/resource_clean_up.test.ts index edcb7e48fc..db74ced8b0 100644 --- a/test/integration/node-specific/resource_clean_up.test.ts +++ b/test/integration/node-specific/resource_clean_up.test.ts @@ -2,6 +2,7 @@ import * as v8 from 'node:v8'; import { expect } from 'chai'; +import { isTLSEnabled } from '../../tools/runner/filters/tls_filter'; import { sleep } from '../../tools/utils'; import { runScriptAndReturnHeapInfo } from './resource_tracking_script_builder'; @@ -34,7 +35,11 @@ describe('Driver Resources', () => { context('on MongoClient.close()', () => { before('create leak reproduction script', async function () { - if (globalThis.AbortController == null || typeof this.configuration.serverApi === 'string') { + if ( + globalThis.AbortController == null || + typeof this.configuration.serverApi === 'string' || + isTLSEnabled + ) { return; } const res = await runScriptAndReturnHeapInfo( @@ -56,21 +61,25 @@ describe('Driver Resources', () => { }); describe('ending memory usage', () => { - it(`is within ${MB_PERMITTED_OFFSET}MB of starting amount`, async () => { - // Why check the lower bound? No reason, but it would be very surprising if we managed to free MB_PERMITTED_OFFSET MB of memory - // I expect us to **never** be below the lower bound, but I'd want to know if it happened - expect( - endingMemoryUsed, - `script started with ${startingMemoryUsed}MB heap but ended with ${endingMemoryUsed}MB heap used` - ).to.be.within( - startingMemoryUsed - MB_PERMITTED_OFFSET, - startingMemoryUsed + MB_PERMITTED_OFFSET - ); - }); + it( + `is within ${MB_PERMITTED_OFFSET}MB of starting amount`, + { requires: { tls: 'disabled' } }, + async () => { + // Why check the lower bound? No reason, but it would be very surprising if we managed to free MB_PERMITTED_OFFSET MB of memory + // I expect us to **never** be below the lower bound, but I'd want to know if it happened + expect( + endingMemoryUsed, + `script started with ${startingMemoryUsed}MB heap but ended with ${endingMemoryUsed}MB heap used` + ).to.be.within( + startingMemoryUsed - MB_PERMITTED_OFFSET, + startingMemoryUsed + MB_PERMITTED_OFFSET + ); + } + ); }); describe('ending heap snapshot', () => { - it('has 0 MongoClients in memory', async () => { + it('has 0 MongoClients in memory', { requires: { tls: 'disabled' } }, async () => { // lengthOf crashes chai b/c it tries to print out a gigantic diff expect( clientsInMemory, diff --git a/test/integration/node-specific/topology.test.ts b/test/integration/node-specific/topology.test.ts index cc35303c0f..b4ab8fd9fb 100644 --- a/test/integration/node-specific/topology.test.ts +++ b/test/integration/node-specific/topology.test.ts @@ -4,7 +4,7 @@ import { MongoClient, type MongoClientOptions, type Topology } from '../../../sr describe('Topology', function () { it('should correctly track states of a topology', { - metadata: { requires: { apiVersion: false, topology: '!load-balanced' } }, // apiVersion not supported by newTopology() + metadata: { requires: { apiVersion: false, topology: '!load-balanced', tls: 'disabled' } }, // apiVersion not supported by newTopology() test: async function () { class WrappedClient extends MongoClient { _topology: Topology | undefined = undefined; diff --git a/test/integration/retryable-reads/retryable_reads.spec.test.ts b/test/integration/retryable-reads/retryable_reads.spec.test.ts index 19657f01e6..70c503ea83 100644 --- a/test/integration/retryable-reads/retryable_reads.spec.test.ts +++ b/test/integration/retryable-reads/retryable_reads.spec.test.ts @@ -1,6 +1,7 @@ import * as path from 'path'; import { loadSpecTests } from '../../spec'; +import { isTLSEnabled } from '../../tools/runner/filters/tls_filter'; import { runUnifiedSuite } from '../../tools/unified-spec-runner/runner'; const UNIMPLEMENTED_APIS = [ @@ -25,6 +26,9 @@ describe('Retryable Reads (unified)', function () { return `TODO(NODE-6832): fix flaky retryable reads tests`; } } + + if (isTLSEnabled) return 'TODO(NODE-7408): fix these tests when TLS is enabled'; + return false; }); }); diff --git a/test/integration/retryable-writes/retryable_writes.spec.test.ts b/test/integration/retryable-writes/retryable_writes.spec.test.ts index 87e8c1edc9..c050f5b8c1 100644 --- a/test/integration/retryable-writes/retryable_writes.spec.test.ts +++ b/test/integration/retryable-writes/retryable_writes.spec.test.ts @@ -1,8 +1,11 @@ import * as path from 'path'; import { loadSpecTests } from '../../spec'; +import { isTLSEnabled } from '../../tools/runner/filters/tls_filter'; import { runUnifiedSuite } from '../../tools/unified-spec-runner/runner'; +const filter = () => + isTLSEnabled ? 'TODO(NODE-7408): fix these tests when TLS is enabled' : false; describe('Retryable Writes (unified)', function () { - runUnifiedSuite(loadSpecTests(path.join('retryable-writes', 'unified'))); + runUnifiedSuite(loadSpecTests(path.join('retryable-writes', 'unified')), filter); }); diff --git a/test/readme.md b/test/readme.md index f9c38ac636..8dcc19fff9 100644 --- a/test/readme.md +++ b/test/readme.md @@ -679,10 +679,37 @@ needs to be tested. 3. For additional Node.js options (like HTTP debug), add them to `K8S_TEST_CMD` in `.evergreen/run-oidc-tests-k8s.sh` 4. Create an evergreen patch and schedule only the `oidc-auth-test-k8s-latest-aks` variant. +### Running tests with TLS + +We tests TLS in two suites in CI: + +- For each node version and platform, we run a small test suite that confirms TLS works. +- We run the full test suite on Linux, on latest Nodejs and on all topologies, to confirm that our full test suite works with TLS enabled. + +Setting up a local environment is the same for both suites. + +First, configure a server with TLS enabled by following the steps in [Runing the Tests Locally](#Running-the-Tests-Locally) with the environment +variable `SSL=SSL` set. + +Then, in addition to setting the `MONGODB_URI` environment varialbe, set the following environment variables: + +```bash +export SSL='ssl' # enable TLS + +# TLS certificates +export TLS_KEY_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/client.pem" +export TLS_CA_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/ca.pem" +export TLS_CRL_FILE="$DRIVERS_TOOLS/.evergreen/x509gen/crl.pem" +``` + +Then run the TLS tests: + +- If running the integration test suite, run `npm run check:test` +- If running the manual TLS tests, run `npm run check:tls` + ### TODO Special Env Sections -- TLS - LDAP - Snappy (maybe in general, how to test optional dependencies) - Atlas connectivity diff --git a/test/tools/cmap_spec_runner.ts b/test/tools/cmap_spec_runner.ts index b29efcefd3..38759f582e 100644 --- a/test/tools/cmap_spec_runner.ts +++ b/test/tools/cmap_spec_runner.ts @@ -9,6 +9,7 @@ import { type ConnectionPoolOptions, type HostAddress, type MongoClient, + type MongoClientOptions, type Server } from '../../src'; import { ConnectionPool } from '../../src/cmap/connection_pool'; @@ -509,7 +510,7 @@ export function runCmapTestSuite( const selectedHostUri = hosts[0]; hostAddress = serverDescriptionMap.get(selectedHostUri).hostAddress; - const clientOptions: { appName?: string } = {}; + const clientOptions: Pick = {}; if (test.poolOptions?.appName) { clientOptions.appName = test.poolOptions.appName; } @@ -520,6 +521,7 @@ export function runCmapTestSuite( clientOptions ); await client.connect(); + if (test.failPoint) { await client.db('admin').command(test.failPoint); } @@ -530,12 +532,11 @@ export function runCmapTestSuite( throw new Error('Failed to retrieve server for test'); } - threadContext = new ThreadContext( - server, - hostAddress, - this.configuration.isLoadBalanced ? { loadBalanced: true } : {}, - { injectPoolStats: !!options?.injectPoolStats } - ); + const poolOptions = this.configuration.isLoadBalanced ? { loadBalanced: true } : {}; + + threadContext = new ThreadContext(server, hostAddress, poolOptions, { + injectPoolStats: !!options?.injectPoolStats + }); } finally { await utilClient.close(); } @@ -554,9 +555,18 @@ export function runCmapTestSuite( await client.close(); }); - it(test.description, async function () { - await runCmapTest(test, threadContext); - }); + it( + test.description, + { + requires: { + // TODO(NODE-7408): fix these tests when TLS is enabled + tls: 'disabled' + } + }, + async function () { + await runCmapTest(test, threadContext); + } + ); }); } } diff --git a/test/tools/runner/config.ts b/test/tools/runner/config.ts index f7f087b2ac..adcb31674a 100644 --- a/test/tools/runner/config.ts +++ b/test/tools/runner/config.ts @@ -235,14 +235,14 @@ export class TestConfiguration { // Support MongoClient constructor form (url, options) for `newClient`. if (typeof urlOrQueryOptions === 'string') { - if (Reflect.has(serverOptions, 'host') || Reflect.has(serverOptions, 'port')) { + if ('host' in serverOptions || 'port' in serverOptions) { throw new Error(`Cannot use options to specify host/port, must be in ${urlOrQueryOptions}`); } return new MongoClient(urlOrQueryOptions, serverOptions); } - const queryOptions = urlOrQueryOptions || {}; + const queryOptions = urlOrQueryOptions ?? {}; // Fall back. let dbHost = queryOptions.host || this.options.host; diff --git a/test/tools/runner/filters/tls_filter.ts b/test/tools/runner/filters/tls_filter.ts new file mode 100644 index 0000000000..aa51c88f7c --- /dev/null +++ b/test/tools/runner/filters/tls_filter.ts @@ -0,0 +1,41 @@ +import * as process from 'process'; + +import { type MongoClient } from '../../../../src'; +import { Filter } from './filter'; + +export const isTLSEnabled = process.env.SSL === 'ssl'; + +/** + * Filter for the MongoDB API Version required for the test + * + * @example + * ```js + * metadata: { + * requires: { + * tls: 'enabled' | 'disabled' + * } + * } + * ``` + */ +export class TLSFilter extends Filter { + tls: 'enabled' | 'disabled'; + constructor() { + super(); + // Get environmental variables that are known + this.tls = isTLSEnabled ? 'enabled' : 'disabled'; + } + + override async initializeFilter( + _client: MongoClient, + context: Record + ): Promise { + context.tls = this.tls; + } + + filter(test: { metadata?: MongoDBMetadataUI }) { + const tls = test.metadata?.requires?.tls; + if (!tls) return true; + + return tls === this.tls; + } +} diff --git a/test/tools/runner/hooks/configuration.ts b/test/tools/runner/hooks/configuration.ts index 87cd1c2e1e..87f7502825 100644 --- a/test/tools/runner/hooks/configuration.ts +++ b/test/tools/runner/hooks/configuration.ts @@ -28,6 +28,7 @@ import { type Context } from 'mocha'; import { flakyTests } from '../flaky'; import { CryptSharedFilter } from '../filters/crypt_shared_filter'; import { LibmongocryptVersionFilter } from '../filters/libmongocrypt_version_filter'; +import { TLSFilter } from '../filters/tls_filter'; // Default our tests to have auth enabled // A better solution will be tackled in NODE-3714 @@ -68,7 +69,8 @@ async function initializeFilters(client): Promise> { new MongoDBTopologyFilter(), new MongoDBVersionFilter(), new NodeVersionFilter(), - new OSFilter() + new OSFilter(), + new TLSFilter() ] }; @@ -119,10 +121,9 @@ const testConfigBeforeHook = async function () { return; } - const client = new MongoClient( - loadBalanced ? SINGLE_MONGOS_LB_URI : MONGODB_URI, - getEnvironmentalOptions() - ); + const options = getEnvironmentalOptions(); + + const client = new MongoClient(loadBalanced ? SINGLE_MONGOS_LB_URI : MONGODB_URI, options); await client.db('test').command({ ping: 1 }); diff --git a/test/tools/utils.ts b/test/tools/utils.ts index b60040b232..5a23fdd970 100644 --- a/test/tools/utils.ts +++ b/test/tools/utils.ts @@ -18,12 +18,14 @@ import { type HostAddress, MongoClient, type MongoClientOptions, + type ServerApiVersion, type TopologyOptions } from '../../src'; import { OP_MSG } from '../../src/cmap/wire_protocol/constants'; import { Topology } from '../../src/sdam/topology'; import { processTimeMS } from '../../src/utils'; import { type TestConfiguration } from './runner/config'; +import { isTLSEnabled } from './runner/filters/tls_filter'; export function ensureCalledWith(stub: any, args: any[]) { args.forEach((m: any) => expect(stub).to.have.been.calledWith(m)); @@ -111,14 +113,41 @@ export function getEncryptExtraOptions(): MongoClientOptions['autoEncryption'][' return {}; } -export function getEnvironmentalOptions() { - const options = {}; +export function getTLSOptions(): Pick< + MongoClientOptions, + 'tls' | 'tlsCertificateKeyFile' | 'tlsCAFile' +> { + if (!isTLSEnabled) return {}; + + const requiredTLSEnv = ['TLS_KEY_FILE', 'TLS_CA_FILE']; + const missingVariables = requiredTLSEnv.filter(key => process.env[key] == null); + + if (missingVariables.length) + throw new Error( + `TLS requires the following additional environment variables: ${missingVariables.join(',')}` + ); + + const { TLS_KEY_FILE: tlsCertificateKeyFile, TLS_CA_FILE: tlsCAFile } = process.env; + + return { + tlsCertificateKeyFile, + tlsCAFile, + tls: true + }; +} + +export function getEnvironmentalOptions(): ReturnType & + Pick { + const options: ReturnType = {}; + if (process.env.MONGODB_API_VERSION) { - Object.assign(options, { - serverApi: { version: process.env.MONGODB_API_VERSION } - }); + options.serverApi = { version: process.env.MONGODB_API_VERSION as ServerApiVersion }; } - return options; + + return { + ...options, + ...getTLSOptions() + }; } /**