Test transactions (#6022)
* Test transactions * test: Separate transaction tests for SDK
This commit is contained in:
committed by
GitHub
parent
f9b77c1bc7
commit
ad40386173
@@ -5,6 +5,9 @@ const MongoStorageAdapter = require('../lib/Adapters/Storage/Mongo/MongoStorageA
|
|||||||
const { MongoClient } = require('mongodb');
|
const { MongoClient } = require('mongodb');
|
||||||
const databaseURI =
|
const databaseURI =
|
||||||
'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase';
|
'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase';
|
||||||
|
const request = require('../lib/request');
|
||||||
|
const Config = require('../lib/Config');
|
||||||
|
const TestUtils = require('../lib/TestUtils');
|
||||||
|
|
||||||
const fakeClient = {
|
const fakeClient = {
|
||||||
s: { options: { dbName: null } },
|
s: { options: { dbName: null } },
|
||||||
@@ -316,4 +319,229 @@ describe_only_db('mongo')('MongoStorageAdapter', () => {
|
|||||||
undefined
|
undefined
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
process.env.MONGODB_VERSION === '4.0.4' &&
|
||||||
|
process.env.MONGODB_TOPOLOGY === 'replicaset' &&
|
||||||
|
process.env.MONGODB_STORAGE_ENGINE === 'wiredTiger'
|
||||||
|
) {
|
||||||
|
describe('transactions', () => {
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await reconfigureServer({
|
||||||
|
databaseAdapter: undefined,
|
||||||
|
databaseURI:
|
||||||
|
'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase?replicaSet=replicaset',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestUtils.destroyAllDataPermanently(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use transaction in a batch with transaction = true', async () => {
|
||||||
|
const myObject = new Parse.Object('MyObject');
|
||||||
|
await myObject.save();
|
||||||
|
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database
|
||||||
|
.adapter;
|
||||||
|
spyOn(
|
||||||
|
databaseAdapter.database.serverConfig,
|
||||||
|
'command'
|
||||||
|
).and.callThrough();
|
||||||
|
|
||||||
|
await request({
|
||||||
|
method: 'POST',
|
||||||
|
headers: headers,
|
||||||
|
url: 'http://localhost:8378/1/batch',
|
||||||
|
body: JSON.stringify({
|
||||||
|
requests: [
|
||||||
|
{
|
||||||
|
method: 'PUT',
|
||||||
|
path: '/1/classes/MyObject/' + myObject.id,
|
||||||
|
body: { myAttribute: 'myValue' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
transaction: true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
let found = false;
|
||||||
|
databaseAdapter.database.serverConfig.command.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
found = true;
|
||||||
|
expect(call.args[2].session.transaction.state).not.toBe(
|
||||||
|
'NO_TRANSACTION'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
expect(found).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not use transaction in a batch with transaction = false', async () => {
|
||||||
|
const myObject = new Parse.Object('MyObject');
|
||||||
|
await myObject.save();
|
||||||
|
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database
|
||||||
|
.adapter;
|
||||||
|
spyOn(
|
||||||
|
databaseAdapter.database.serverConfig,
|
||||||
|
'command'
|
||||||
|
).and.callThrough();
|
||||||
|
|
||||||
|
await request({
|
||||||
|
method: 'POST',
|
||||||
|
headers: headers,
|
||||||
|
url: 'http://localhost:8378/1/batch',
|
||||||
|
body: JSON.stringify({
|
||||||
|
requests: [
|
||||||
|
{
|
||||||
|
method: 'PUT',
|
||||||
|
path: '/1/classes/MyObject/' + myObject.id,
|
||||||
|
body: { myAttribute: 'myValue' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
transaction: false,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
let found = false;
|
||||||
|
databaseAdapter.database.serverConfig.command.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
found = true;
|
||||||
|
expect(call.args[2].session).toBe(undefined);
|
||||||
|
});
|
||||||
|
expect(found).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not use transaction in a batch with no transaction option sent', async () => {
|
||||||
|
const myObject = new Parse.Object('MyObject');
|
||||||
|
await myObject.save();
|
||||||
|
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database
|
||||||
|
.adapter;
|
||||||
|
spyOn(
|
||||||
|
databaseAdapter.database.serverConfig,
|
||||||
|
'command'
|
||||||
|
).and.callThrough();
|
||||||
|
|
||||||
|
await request({
|
||||||
|
method: 'POST',
|
||||||
|
headers: headers,
|
||||||
|
url: 'http://localhost:8378/1/batch',
|
||||||
|
body: JSON.stringify({
|
||||||
|
requests: [
|
||||||
|
{
|
||||||
|
method: 'PUT',
|
||||||
|
path: '/1/classes/MyObject/' + myObject.id,
|
||||||
|
body: { myAttribute: 'myValue' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
let found = false;
|
||||||
|
databaseAdapter.database.serverConfig.command.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
found = true;
|
||||||
|
expect(call.args[2].session).toBe(undefined);
|
||||||
|
});
|
||||||
|
expect(found).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not use transaction in a put request', async () => {
|
||||||
|
const myObject = new Parse.Object('MyObject');
|
||||||
|
await myObject.save();
|
||||||
|
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database
|
||||||
|
.adapter;
|
||||||
|
spyOn(
|
||||||
|
databaseAdapter.database.serverConfig,
|
||||||
|
'command'
|
||||||
|
).and.callThrough();
|
||||||
|
|
||||||
|
await request({
|
||||||
|
method: 'PUT',
|
||||||
|
headers: headers,
|
||||||
|
url: 'http://localhost:8378/1/classes/MyObject/' + myObject.id,
|
||||||
|
body: { myAttribute: 'myValue' },
|
||||||
|
});
|
||||||
|
|
||||||
|
let found = false;
|
||||||
|
databaseAdapter.database.serverConfig.command.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
found = true;
|
||||||
|
expect(call.args[2].session).toBe(undefined);
|
||||||
|
});
|
||||||
|
expect(found).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not use transactions when using SDK insert', async () => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database
|
||||||
|
.adapter;
|
||||||
|
spyOn(
|
||||||
|
databaseAdapter.database.serverConfig,
|
||||||
|
'insert'
|
||||||
|
).and.callThrough();
|
||||||
|
|
||||||
|
const myObject = new Parse.Object('MyObject');
|
||||||
|
await myObject.save();
|
||||||
|
|
||||||
|
const calls = databaseAdapter.database.serverConfig.insert.calls.all();
|
||||||
|
expect(calls.length).toBeGreaterThan(0);
|
||||||
|
calls.forEach(call => {
|
||||||
|
expect(call.args[2].session.transaction.state).toBe('NO_TRANSACTION');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not use transactions when using SDK update', async () => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database
|
||||||
|
.adapter;
|
||||||
|
spyOn(
|
||||||
|
databaseAdapter.database.serverConfig,
|
||||||
|
'update'
|
||||||
|
).and.callThrough();
|
||||||
|
|
||||||
|
const myObject = new Parse.Object('MyObject');
|
||||||
|
await myObject.save();
|
||||||
|
|
||||||
|
myObject.set('myAttribute', 'myValue');
|
||||||
|
await myObject.save();
|
||||||
|
|
||||||
|
const calls = databaseAdapter.database.serverConfig.update.calls.all();
|
||||||
|
expect(calls.length).toBeGreaterThan(0);
|
||||||
|
calls.forEach(call => {
|
||||||
|
expect(call.args[2].session.transaction.state).toBe('NO_TRANSACTION');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not use transactions when using SDK delete', async () => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database
|
||||||
|
.adapter;
|
||||||
|
spyOn(
|
||||||
|
databaseAdapter.database.serverConfig,
|
||||||
|
'remove'
|
||||||
|
).and.callThrough();
|
||||||
|
|
||||||
|
const myObject = new Parse.Object('MyObject');
|
||||||
|
await myObject.save();
|
||||||
|
|
||||||
|
await myObject.destroy();
|
||||||
|
|
||||||
|
const calls = databaseAdapter.database.serverConfig.remove.calls.all();
|
||||||
|
expect(calls.length).toBeGreaterThan(0);
|
||||||
|
calls.forEach(call => {
|
||||||
|
expect(call.args[2].session.transaction.state).toBe('NO_TRANSACTION');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user