Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(NODE-3528): add support for snappy v7 #2947

Merged
merged 4 commits into from
Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
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
40 changes: 35 additions & 5 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,17 @@ functions:
rm -f ./prepare_client_encryption.sh

UNIFIED=${UNIFIED} MONGODB_URI="${MONGODB_URI}" bash ${PROJECT_DIRECTORY}/.evergreen/run-custom-csfle-tests.sh
run custom snappy tests:
- command: subprocess.exec
params:
working_dir: src
timeout_secs: 60
env:
MONGODB_URI: '${MONGODB_URI}'
PROJECT_DIRECTORY: '${PROJECT_DIRECTORY}'
binary: bash
args:
- '${PROJECT_DIRECTORY}/.evergreen/run-snappy-version-test.sh'
upload test results:
- command: attach.xunit_results
params:
Expand Down Expand Up @@ -1545,16 +1556,34 @@ tasks:
- func: run checks
- name: run-custom-csfle-tests
tags:
- run-custom-csfle-tests
- run-custom-dependency-tests
commands:
- func: install dependencies
vars:
NODE_LTS_NAME: erbium
- func: bootstrap mongo-orchestration
vars:
VERSION: '4.4'
VERSION: '5.0'
TOPOLOGY: server
- func: run custom csfle tests
vars:
UNIFIED: 1
NODE_LTS_NAME: erbium
- name: run-custom-snappy-tests
tags:
- run-custom-dependency-tests
commands:
- func: install dependencies
vars:
NODE_LTS_NAME: erbium
- func: bootstrap mongo-orchestration
vars:
VERSION: '5.0'
TOPOLOGY: server
- func: run custom snappy tests
vars:
UNIFIED: 1
NODE_LTS_NAME: erbium
buildvariants:
- name: macos-1014-fermium
display_name: macOS 10.14 Node Fermium
Expand Down Expand Up @@ -2109,11 +2138,12 @@ buildvariants:
run_on: rhel70
tasks:
- run-checks
- name: ubuntu1804-custom-csfle-tests
display_name: Custom FLE Version Test
run_on: ubuntu1804-test
- name: ubuntu1804-custom-dependency-tests
display_name: Custom Dependency Version Test
run_on: ubuntu1804-large
tasks:
- run-custom-csfle-tests
- run-custom-snappy-tests
- name: ubuntu1804-test-mongodb-aws
display_name: MONGODB-AWS Auth test
run_on: ubuntu1804-test
Expand Down
12 changes: 12 additions & 0 deletions .evergreen/config.yml.in
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,18 @@ functions:

UNIFIED=${UNIFIED} MONGODB_URI="${MONGODB_URI}" bash ${PROJECT_DIRECTORY}/.evergreen/run-custom-csfle-tests.sh

"run custom snappy tests":
- command: subprocess.exec
params:
working_dir: "src"
timeout_secs: 60
env:
MONGODB_URI: ${MONGODB_URI}
PROJECT_DIRECTORY: ${PROJECT_DIRECTORY}
binary: bash
args:
- "${PROJECT_DIRECTORY}/.evergreen/run-snappy-version-test.sh"

"upload test results":
- command: attach.xunit_results
params:
Expand Down
116 changes: 64 additions & 52 deletions .evergreen/generate_evergreen_tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,7 @@ const OPERATING_SYSTEMS = [
)
);

const WINDOWS_SKIP_TAGS = new Set([
'atlas-connect',
'auth'
]);
const WINDOWS_SKIP_TAGS = new Set(['atlas-connect', 'auth']);

const BASE_TASKS = [];
const TASKS = [];
Expand Down Expand Up @@ -109,9 +106,7 @@ function makeTask({ mongoVersion, topology }) {
}

MONGODB_VERSIONS.forEach(mongoVersion => {
TOPOLOGIES.forEach(topology =>
BASE_TASKS.push(makeTask({ mongoVersion, topology }))
);
TOPOLOGIES.forEach(topology => BASE_TASKS.push(makeTask({ mongoVersion, topology })));
});

TASKS.push(
Expand All @@ -125,7 +120,8 @@ TASKS.push(
tags: ['auth', 'kerberos', 'legacy'],
commands: [
{ func: 'install dependencies' },
{ func: 'run kerberos tests',
{
func: 'run kerberos tests',
vars: {
UNIFIED: 0
}
Expand All @@ -137,7 +133,8 @@ TASKS.push(
tags: ['auth', 'kerberos', 'unified'],
commands: [
{ func: 'install dependencies' },
{ func: 'run kerberos tests',
{
func: 'run kerberos tests',
vars: {
UNIFIED: 1
}
Expand Down Expand Up @@ -296,7 +293,7 @@ OCSP_VERSIONS.forEach(VERSION => {
const AWS_AUTH_TASKS = [];

AWS_AUTH_VERSIONS.forEach(VERSION => {
const name = (ex) => `aws-${VERSION}-auth-test-${ex.split(' ').join('-')}`;
const name = ex => `aws-${VERSION}-auth-test-${ex.split(' ').join('-')}`;
// AWS_AUTH_TASKS.push(name);

const aws_funcs = [
Expand Down Expand Up @@ -325,10 +322,10 @@ AWS_AUTH_VERSIONS.forEach(VERSION => {
{ func: 'setup aws env' },
fn
]
}))
}));

TASKS.push(...aws_tasks);
AWS_AUTH_TASKS.push(...aws_tasks.map(t => t.name))
AWS_AUTH_TASKS.push(...aws_tasks.map(t => t.name));
});

const BUILD_VARIANTS = [];
Expand All @@ -342,31 +339,33 @@ const getTaskList = (() => {
return memo[key];
}
const taskList = BASE_TASKS.concat(TASKS);
const ret = taskList.filter(task => {
if (task.name.match(/^aws/)) return false;
const ret = taskList
.filter(task => {
if (task.name.match(/^aws/)) return false;

// skip unsupported tasks on windows
if (os.match(/^windows/) && task.tags.filter(tag => WINDOWS_SKIP_TAGS.has(tag)).length) {
return false;
}
// skip unsupported tasks on windows
if (os.match(/^windows/) && task.tags.filter(tag => WINDOWS_SKIP_TAGS.has(tag)).length) {
return false;
}

const tasksWithVars = task.commands.filter(task => !!task.vars);
if (!tasksWithVars.length) {
return true;
}
const tasksWithVars = task.commands.filter(task => !!task.vars);
if (!tasksWithVars.length) {
return true;
}

// kerberos tests don't require mongo orchestration
if (task.tags.filter(tag => tag === 'kerberos').length) {
return true;
}
// kerberos tests don't require mongo orchestration
if (task.tags.filter(tag => tag === 'kerberos').length) {
return true;
}

const { VERSION } = tasksWithVars[0].vars || {};
if (VERSION === 'latest') {
return semver.satisfies(semver.coerce(LATEST_EFFECTIVE_VERSION), mongoVersion);
}
const { VERSION } = tasksWithVars[0].vars || {};
if (VERSION === 'latest') {
return semver.satisfies(semver.coerce(LATEST_EFFECTIVE_VERSION), mongoVersion);
}

return semver.satisfies(semver.coerce(VERSION), mongoVersion);
}).map(x => x.name);
return semver.satisfies(semver.coerce(VERSION), mongoVersion);
})
.map(x => x.name);

memo[key] = ret;
return ret;
Expand Down Expand Up @@ -419,38 +418,48 @@ SINGLETON_TASKS.push({
]
});

SINGLETON_TASKS.push({
name: 'run-custom-csfle-tests',
tags: ['run-custom-csfle-tests'],
const oneOffFuncs = [
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ported over the CI changes, I actually took a stab at bringing in the bson-ext CI here too, but it started having too much overhead for this PR, but this sets us up to have easier one-off targets going forward.

{ func: 'run custom csfle tests', vars: { UNIFIED: 1, NODE_LTS_NAME: 'erbium' } },
{ func: 'run custom snappy tests', vars: { UNIFIED: 1, NODE_LTS_NAME: 'erbium' } }
];

const oneOffFuncAsTasks = oneOffFuncs.map(oneOffFunc => ({
name: `${oneOffFunc.func.split(' ').join('-')}`,
tags: ['run-custom-dependency-tests'],
commands: [
{
func: 'install dependencies',
vars: {
NODE_LTS_NAME: 'erbium',
},
NODE_LTS_NAME: 'erbium'
}
},
{
func: 'bootstrap mongo-orchestration',
vars: {
VERSION: '4.4',
VERSION: '5.0',
TOPOLOGY: 'server'
}
},
{ func: 'run custom csfle tests' }
oneOffFunc
]
});
}));

BUILD_VARIANTS.push({
name: 'lint',
display_name: 'lint',
run_on: 'rhel70',
tasks: ['run-checks']
}, {
name: 'ubuntu1804-custom-csfle-tests',
display_name: 'Custom FLE Version Test',
run_on: 'ubuntu1804-test',
tasks: ['run-custom-csfle-tests']
});
SINGLETON_TASKS.push(...oneOffFuncAsTasks);

BUILD_VARIANTS.push(
{
name: 'lint',
display_name: 'lint',
run_on: 'rhel70',
tasks: ['run-checks']
},
{
name: 'ubuntu1804-custom-dependency-tests',
display_name: 'Custom Dependency Version Test',
run_on: 'ubuntu1804-large',
tasks: oneOffFuncAsTasks.map(({ name }) => name)
}
);

// special case for MONGODB-AWS authentication
BUILD_VARIANTS.push({
Expand All @@ -464,7 +473,10 @@ BUILD_VARIANTS.push({
});

const fileData = yaml.safeLoad(fs.readFileSync(`${__dirname}/config.yml.in`, 'utf8'));
fileData.tasks = (fileData.tasks || []).concat(BASE_TASKS).concat(TASKS).concat(SINGLETON_TASKS);
fileData.tasks = (fileData.tasks || [])
.concat(BASE_TASKS)
.concat(TASKS)
.concat(SINGLETON_TASKS);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
fileData.tasks = (fileData.tasks || [])
.concat(BASE_TASKS)
.concat(TASKS)
.concat(SINGLETON_TASKS);
fileData.tasks = (fileData.tasks || []).concat(BASE_TASKS, TASKS, SINGLETON_TASKS);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done! did it locally along with prettier just to make sure the formatting is right

fileData.buildvariants = (fileData.buildvariants || []).concat(BUILD_VARIANTS);

fs.writeFileSync(`${__dirname}/config.yml`, yaml.safeDump(fileData, { lineWidth: 120 }), 'utf8');
19 changes: 19 additions & 0 deletions .evergreen/init-nvm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#! /usr/bin/env bash

export PATH="/opt/mongodbtoolchain/v2/bin:$PATH"
NODE_ARTIFACTS_PATH="${PROJECT_DIRECTORY}/node-artifacts"
export NVM_DIR="${NODE_ARTIFACTS_PATH}/nvm"

if [[ "$OS" == "Windows_NT" ]]; then
NVM_HOME=$(cygpath -w "$NVM_DIR")
export NVM_HOME
NVM_SYMLINK=$(cygpath -w "$NODE_ARTIFACTS_PATH/bin")
export NVM_SYMLINK
NVM_ARTIFACTS_PATH=$(cygpath -w "$NODE_ARTIFACTS_PATH/bin")
export NVM_ARTIFACTS_PATH
PATH=$(cygpath $NVM_SYMLINK):$(cygpath $NVM_HOME):$PATH
export PATH
echo "updated path on windows PATH=$PATH"
else
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
fi
12 changes: 12 additions & 0 deletions .evergreen/run-snappy-version-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#! /usr/bin/env bash

source "${PROJECT_DIRECTORY}/.evergreen/init-nvm.sh"
export MONGODB_URI="${MONGODB_URI}"

npm i --no-save snappy@6

npx mocha test/unit/snappy.test.js

npm i --no-save snappy@7

npx mocha test/unit/snappy.test.js
37 changes: 35 additions & 2 deletions lib/core/connection/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
'use strict';

const parsePackageVersion = require('../../utils').parsePackageVersion;
const MongoError = require('../error').MongoError;

const require_optional = require('optional-require')(require);

function debugOptions(debugFields, options) {
Expand All @@ -16,7 +19,15 @@ function retrieveBSON() {
BSON.native = false;

const optionalBSON = require_optional('bson-ext');
const bsonExtVersion = parsePackageVersion(
require_optional('bson-ext/package.json') || { version: '0.0.0' }
);
if (optionalBSON) {
if (bsonExtVersion.major >= 4) {
throw new MongoError(
'bson-ext version 4 and above does not work with the 3.x version of the mongodb driver'
);
}
optionalBSON.native = true;
return optionalBSON;
}
Expand All @@ -31,21 +42,43 @@ function noSnappyWarning() {
);
}

const PKG_VERSION = Symbol('kPkgVersion');

// Facilitate loading Snappy optionally
function retrieveSnappy() {
let snappy = require_optional('snappy');
const snappy = require_optional('snappy');
if (!snappy) {
snappy = {
return {
compress: noSnappyWarning,
uncompress: noSnappyWarning,
compressSync: noSnappyWarning,
uncompressSync: noSnappyWarning
};
}

const snappyPkg = require_optional('snappy/package.json') || { version: '0.0.0' };
const version = parsePackageVersion(snappyPkg);
snappy[PKG_VERSION] = version;
if (version.major >= 7) {
const compressOriginal = snappy.compress;
const uncompressOriginal = snappy.uncompress;
snappy.compress = (data, callback) => {
Copy link
Contributor Author

@nbbeeken nbbeeken Aug 25, 2021

Choose a reason for hiding this comment

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

Slightly different approach taken, just wrap the functions here, the actual usage site needs no changes now.

compressOriginal(data)
.then(res => callback(undefined, res))
.catch(error => callback(error));
};
snappy.uncompress = (data, callback) => {
uncompressOriginal(data)
.then(res => callback(undefined, res))
.catch(error => callback(error));
};
}

return snappy;
}

module.exports = {
PKG_VERSION,
debugOptions,
retrieveBSON,
retrieveSnappy
Expand Down
Loading