Skip to content

Commit 04db406

Browse files
authored
refactor(NODE-3717): move gridfs and csfle tests to the integration directory (#3062)
1 parent b9fbac5 commit 04db406

14 files changed

+1968
-290
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
"check:kerberos": "mocha --config \"test/manual/mocharc.json\" test/manual/kerberos.test.js",
114114
"check:tls": "mocha --config \"test/manual/mocharc.json\" test/manual/tls_support.test.js",
115115
"check:ldap": "mocha --config \"test/manual/mocharc.json\" test/manual/ldap.test.js",
116-
"check:csfle": "mocha --file test/tools/runner test/functional/client_side_encryption",
116+
"check:csfle": "mocha --file test/tools/runner test/integration/client-side-encryption",
117117
"check:snappy": "mocha --file test/tools/runner test/functional/unit_snappy.test.js",
118118
"prepare": "node etc/prepare.js",
119119
"release": "standard-version -i HISTORY.md",
File renamed without changes.
File renamed without changes.

test/functional/client_side_encryption/prose.test.js renamed to test/integration/client-side-encryption/client_side_encryption.prose.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22
const BSON = require('bson');
33
const chai = require('chai');
4-
const { deadlockTests } = require('./deadlock_tests.js');
4+
const { deadlockTests } = require('./client_side_encryption.prose.deadlock');
55
const expect = chai.expect;
66
chai.use(require('chai-subset'));
77

test/functional/client_side_encryption/spec.test.js renamed to test/integration/client-side-encryption/client_side_encryption.spec.test.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
'use strict';
22

33
const path = require('path');
4-
const TestRunnerContext = require('../spec-runner').TestRunnerContext;
5-
const gatherTestSuites = require('../spec-runner').gatherTestSuites;
6-
const generateTopologyTests = require('../spec-runner').generateTopologyTests;
4+
const {
5+
TestRunnerContext,
6+
gatherTestSuites,
7+
generateTopologyTests
8+
} = require('../../tools/spec-runner');
79

810
describe('Client Side Encryption', function () {
911
// TODO: Replace this with using the filter once the filter works on describe blocks
File renamed without changes.
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
'use strict';
2+
3+
const { EJSON } = require('bson');
4+
const { setupDatabase } = require('./../shared');
5+
const { expect } = require('chai');
6+
const { GridFSBucket } = require('../../../src');
7+
8+
describe('GridFS', function () {
9+
before(function () {
10+
return setupDatabase(this.configuration);
11+
});
12+
13+
const UPLOAD_SPEC = require('../../spec/gridfs/gridfs-upload.json');
14+
UPLOAD_SPEC.tests.forEach(function (specTest) {
15+
(function (testSpec) {
16+
it(testSpec.description, {
17+
metadata: { requires: { topology: ['single'] } },
18+
19+
test(done) {
20+
const configuration = this.configuration;
21+
const client = configuration.newClient(configuration.writeConcernMax(), {
22+
maxPoolSize: 1
23+
});
24+
client.connect(function (err, client) {
25+
const db = client.db(configuration.db);
26+
db.dropDatabase(function (error) {
27+
expect(error).to.not.exist;
28+
29+
const bucket = new GridFSBucket(db, { bucketName: 'expected' });
30+
const res = bucket.openUploadStream(
31+
testSpec.act.arguments.filename,
32+
testSpec.act.arguments.options
33+
);
34+
const buf = Buffer.from(testSpec.act.arguments.source.$hex, 'hex');
35+
36+
res.on('error', function (err) {
37+
expect(err).to.not.exist;
38+
});
39+
40+
res.on('finish', function () {
41+
const data = testSpec.assert.data;
42+
let num = data.length;
43+
data.forEach(function (data) {
44+
const collection = data.insert;
45+
db.collection(collection)
46+
.find({})
47+
.toArray(function (error, docs) {
48+
expect(data.documents.length).to.equal(docs.length);
49+
50+
for (let i = 0; i < docs.length; ++i) {
51+
testResultDoc(data.documents[i], docs[i], res.id);
52+
}
53+
54+
if (--num === 0) {
55+
client.close(done);
56+
}
57+
});
58+
});
59+
});
60+
61+
res.write(buf);
62+
res.end();
63+
});
64+
});
65+
}
66+
});
67+
})(specTest);
68+
});
69+
70+
const DOWNLOAD_SPEC = require('../../spec/gridfs/gridfs-download.json');
71+
DOWNLOAD_SPEC.tests.forEach(function (specTest) {
72+
(function (testSpec) {
73+
it(testSpec.description, {
74+
metadata: { requires: { topology: ['single'] } },
75+
76+
test(done) {
77+
const configuration = this.configuration;
78+
const client = configuration.newClient(configuration.writeConcernMax(), {
79+
maxPoolSize: 1
80+
});
81+
client.connect(function (err, client) {
82+
const db = client.db(configuration.db);
83+
db.dropDatabase(function (err) {
84+
expect(err).to.not.exist;
85+
const BUCKET_NAME = 'fs';
86+
87+
const _runTest = function () {
88+
const bucket = new GridFSBucket(db, { bucketName: BUCKET_NAME });
89+
let res = Buffer.alloc(0);
90+
91+
const download = bucket.openDownloadStream(
92+
EJSON.parse(JSON.stringify(testSpec.act.arguments.id), { relaxed: true })
93+
);
94+
95+
download.on('data', function (chunk) {
96+
res = Buffer.concat([res, chunk]);
97+
});
98+
99+
let errorReported = false;
100+
download.on('error', function (error) {
101+
errorReported = true;
102+
if (!testSpec.assert.error) {
103+
expect.fail('Should be unreached');
104+
105+
// We need to abort in order to close the underlying cursor,
106+
// and by extension the implicit session used for the cursor.
107+
// This is only necessary if the cursor is not exhausted
108+
download.abort();
109+
client.close(done);
110+
}
111+
expect(error.toString().indexOf(testSpec.assert.error) !== -1).to.equal(true);
112+
113+
// We need to abort in order to close the underlying cursor,
114+
// and by extension the implicit session used for the cursor.
115+
// This is only necessary if the cursor is not exhausted
116+
download.abort();
117+
client.close(done);
118+
});
119+
120+
download.on('end', function () {
121+
const result = testSpec.assert.result;
122+
if (!result) {
123+
if (errorReported) {
124+
return;
125+
}
126+
127+
// We need to abort in order to close the underlying cursor,
128+
// and by extension the implicit session used for the cursor.
129+
// This is only necessary if the cursor is not exhausted
130+
download.abort();
131+
client.close(done);
132+
expect.fail('errorReported should be set');
133+
}
134+
135+
expect(res.toString('hex')).to.equal(result.$hex);
136+
137+
// We need to abort in order to close the underlying cursor,
138+
// and by extension the implicit session used for the cursor.
139+
// This is only necessary if the cursor is not exhausted
140+
download.abort();
141+
client.close(done);
142+
});
143+
};
144+
145+
const keys = Object.keys(DOWNLOAD_SPEC.data);
146+
let numCollections = Object.keys(DOWNLOAD_SPEC.data).length;
147+
keys.forEach(function (collection) {
148+
const data = DOWNLOAD_SPEC.data[collection].map(function (v) {
149+
return deflateTestDoc(v);
150+
});
151+
152+
db.collection(BUCKET_NAME + '.' + collection).insertMany(data, function (error) {
153+
expect(error).to.not.exist;
154+
155+
if (--numCollections === 0) {
156+
if (testSpec.arrange) {
157+
// only support 1 arrange op for now
158+
expect(testSpec.arrange.data.length).to.equal(1);
159+
applyArrange(db, deflateTestDoc(testSpec.arrange.data[0]), function (error) {
160+
expect(error).to.not.exist;
161+
_runTest();
162+
});
163+
} else {
164+
_runTest();
165+
}
166+
}
167+
});
168+
});
169+
});
170+
});
171+
}
172+
});
173+
})(specTest);
174+
});
175+
176+
function testResultDoc(specDoc, resDoc, result) {
177+
const specKeys = Object.keys(specDoc)
178+
.filter(key => key !== 'md5')
179+
.sort();
180+
const resKeys = Object.keys(resDoc).sort();
181+
182+
expect(specKeys.length === resKeys.length).to.equal(true);
183+
184+
for (let i = 0; i < specKeys.length; ++i) {
185+
const key = specKeys[i];
186+
expect(specKeys[i]).to.equal(resKeys[i]);
187+
if (specDoc[key] === '*actual') {
188+
expect(resDoc[key]).to.exist;
189+
} else if (specDoc[key] === '*result') {
190+
expect(resDoc[key].toString()).to.equal(result.toString());
191+
} else if (specDoc[key].$hex) {
192+
expect(resDoc[key]._bsontype === 'Binary').to.equal(true);
193+
expect(resDoc[key].toString('hex')).to.equal(specDoc[key].$hex);
194+
} else {
195+
if (typeof specDoc[key] === 'object') {
196+
expect(specDoc[key]).to.deep.equal(resDoc[key]);
197+
} else {
198+
expect(specDoc[key]).to.equal(resDoc[key]);
199+
}
200+
}
201+
}
202+
}
203+
204+
function deflateTestDoc(doc) {
205+
const ret = EJSON.parse(JSON.stringify(doc), { relaxed: true });
206+
convert$hexToBuffer(ret);
207+
return ret;
208+
}
209+
210+
function convert$hexToBuffer(doc) {
211+
const keys = Object.keys(doc);
212+
keys.forEach(function (key) {
213+
if (doc[key] && typeof doc[key] === 'object') {
214+
if (doc[key].$hex != null) {
215+
doc[key] = Buffer.from(doc[key].$hex, 'hex');
216+
} else {
217+
convert$hexToBuffer(doc[key]);
218+
}
219+
}
220+
});
221+
}
222+
223+
function applyArrange(db, command, callback) {
224+
// Don't count on commands being there since we need to test on 2.2 and 2.4
225+
if (command.delete) {
226+
if (command.deletes.length !== 1) {
227+
return callback(new Error('can only arrange with 1 delete'));
228+
}
229+
if (command.deletes[0].limit !== 1) {
230+
return callback(new Error('can only arrange with delete limit 1'));
231+
}
232+
db.collection(command.delete).deleteOne(command.deletes[0].q, callback);
233+
} else if (command.insert) {
234+
db.collection(command.insert).insertMany(command.documents, callback);
235+
} else if (command.update) {
236+
const bulk = [];
237+
for (let i = 0; i < command.updates.length; ++i) {
238+
bulk.push({
239+
updateOne: {
240+
filter: command.updates[i].q,
241+
update: command.updates[i].u
242+
}
243+
});
244+
}
245+
246+
db.collection(command.update).bulkWrite(bulk, callback);
247+
} else {
248+
const msg = 'Command not recognized: ' + require('util').inspect(command);
249+
callback(new Error(msg));
250+
}
251+
}
252+
});

0 commit comments

Comments
 (0)