ci: Fix flaky direct access transaction tests (#9235)
This commit is contained in:
@@ -2,16 +2,17 @@ const ParseServerRESTController = require('../lib/ParseServerRESTController')
|
|||||||
.ParseServerRESTController;
|
.ParseServerRESTController;
|
||||||
const ParseServer = require('../lib/ParseServer').default;
|
const ParseServer = require('../lib/ParseServer').default;
|
||||||
const Parse = require('parse/node').Parse;
|
const Parse = require('parse/node').Parse;
|
||||||
const TestUtils = require('../lib/TestUtils');
|
|
||||||
|
|
||||||
let RESTController;
|
let RESTController;
|
||||||
|
|
||||||
describe('ParseServerRESTController', () => {
|
describe('ParseServerRESTController', () => {
|
||||||
|
let createSpy;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
RESTController = ParseServerRESTController(
|
RESTController = ParseServerRESTController(
|
||||||
Parse.applicationId,
|
Parse.applicationId,
|
||||||
ParseServer.promiseRouter({ appId: Parse.applicationId })
|
ParseServer.promiseRouter({ appId: Parse.applicationId })
|
||||||
);
|
);
|
||||||
|
createSpy = spyOn(databaseAdapter, 'createObject').and.callThrough();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle a get request', async () => {
|
it('should handle a get request', async () => {
|
||||||
@@ -133,24 +134,11 @@ describe('ParseServerRESTController', () => {
|
|||||||
process.env.PARSE_SERVER_TEST_DB === 'postgres'
|
process.env.PARSE_SERVER_TEST_DB === 'postgres'
|
||||||
) {
|
) {
|
||||||
describe('transactions', () => {
|
describe('transactions', () => {
|
||||||
beforeEach(async () => {
|
|
||||||
await TestUtils.destroyAllDataPermanently(true);
|
|
||||||
if (process.env.MONGODB_TOPOLOGY === 'replicaset') {
|
|
||||||
await reconfigureServer({
|
|
||||||
databaseAdapter: undefined,
|
|
||||||
databaseURI:
|
|
||||||
'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase?replicaSet=replicaset',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
await reconfigureServer();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle a batch request with transaction = true', async () => {
|
it('should handle a batch request with transaction = true', async () => {
|
||||||
const myObject = new Parse.Object('MyObject'); // This is important because transaction only works on pre-existing collections
|
const myObject = new Parse.Object('MyObject'); // This is important because transaction only works on pre-existing collections
|
||||||
await myObject.save();
|
await myObject.save();
|
||||||
await myObject.destroy();
|
await myObject.destroy();
|
||||||
spyOn(databaseAdapter, 'createObject').and.callThrough();
|
createSpy.calls.reset();
|
||||||
const response = await RESTController.request('POST', 'batch', {
|
const response = await RESTController.request('POST', 'batch', {
|
||||||
requests: [
|
requests: [
|
||||||
{
|
{
|
||||||
@@ -173,10 +161,10 @@ describe('ParseServerRESTController', () => {
|
|||||||
expect(response[1].success.createdAt).toBeDefined();
|
expect(response[1].success.createdAt).toBeDefined();
|
||||||
const query = new Parse.Query('MyObject');
|
const query = new Parse.Query('MyObject');
|
||||||
const results = await query.find();
|
const results = await query.find();
|
||||||
expect(databaseAdapter.createObject.calls.count() % 2).toBe(0);
|
expect(createSpy.calls.count()).toBe(2);
|
||||||
for (let i = 0; i + 1 < databaseAdapter.createObject.calls.length; i = i + 2) {
|
for (let i = 0; i + 1 < createSpy.calls.length; i = i + 2) {
|
||||||
expect(databaseAdapter.createObject.calls.argsFor(i)[3]).toBe(
|
expect(createSpy.calls.argsFor(i)[3]).toBe(
|
||||||
databaseAdapter.createObject.calls.argsFor(i + 1)[3]
|
createSpy.calls.argsFor(i + 1)[3]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect(results.map(result => result.get('key')).sort()).toEqual(['value1', 'value2']);
|
expect(results.map(result => result.get('key')).sort()).toEqual(['value1', 'value2']);
|
||||||
@@ -184,9 +172,11 @@ describe('ParseServerRESTController', () => {
|
|||||||
|
|
||||||
it('should not save anything when one operation fails in a transaction', async () => {
|
it('should not save anything when one operation fails in a transaction', async () => {
|
||||||
const myObject = new Parse.Object('MyObject'); // This is important because transaction only works on pre-existing collections
|
const myObject = new Parse.Object('MyObject'); // This is important because transaction only works on pre-existing collections
|
||||||
await myObject.save();
|
await myObject.save({ key: 'stringField' });
|
||||||
await myObject.destroy();
|
await myObject.destroy();
|
||||||
|
createSpy.calls.reset();
|
||||||
try {
|
try {
|
||||||
|
// Saving a number to a string field should fail
|
||||||
await RESTController.request('POST', 'batch', {
|
await RESTController.request('POST', 'batch', {
|
||||||
requests: [
|
requests: [
|
||||||
{
|
{
|
||||||
@@ -294,20 +284,21 @@ describe('ParseServerRESTController', () => {
|
|||||||
it('should generate separate session for each call', async () => {
|
it('should generate separate session for each call', async () => {
|
||||||
await reconfigureServer();
|
await reconfigureServer();
|
||||||
const myObject = new Parse.Object('MyObject'); // This is important because transaction only works on pre-existing collections
|
const myObject = new Parse.Object('MyObject'); // This is important because transaction only works on pre-existing collections
|
||||||
await myObject.save();
|
await myObject.save({ key: 'stringField' });
|
||||||
await myObject.destroy();
|
await myObject.destroy();
|
||||||
|
|
||||||
const myObject2 = new Parse.Object('MyObject2'); // This is important because transaction only works on pre-existing collections
|
const myObject2 = new Parse.Object('MyObject2'); // This is important because transaction only works on pre-existing collections
|
||||||
await myObject2.save();
|
await myObject2.save({ key: 'stringField' });
|
||||||
await myObject2.destroy();
|
await myObject2.destroy();
|
||||||
|
|
||||||
spyOn(databaseAdapter, 'createObject').and.callThrough();
|
createSpy.calls.reset();
|
||||||
|
|
||||||
let myObjectCalls = 0;
|
let myObjectCalls = 0;
|
||||||
Parse.Cloud.beforeSave('MyObject', async () => {
|
Parse.Cloud.beforeSave('MyObject', async () => {
|
||||||
myObjectCalls++;
|
myObjectCalls++;
|
||||||
if (myObjectCalls === 2) {
|
if (myObjectCalls === 2) {
|
||||||
try {
|
try {
|
||||||
|
// Saving a number to a string field should fail
|
||||||
await RESTController.request('POST', 'batch', {
|
await RESTController.request('POST', 'batch', {
|
||||||
requests: [
|
requests: [
|
||||||
{
|
{
|
||||||
@@ -459,14 +450,14 @@ describe('ParseServerRESTController', () => {
|
|||||||
const results3 = await query3.find();
|
const results3 = await query3.find();
|
||||||
expect(results3.map(result => result.get('key')).sort()).toEqual(['value1', 'value2']);
|
expect(results3.map(result => result.get('key')).sort()).toEqual(['value1', 'value2']);
|
||||||
|
|
||||||
expect(databaseAdapter.createObject.calls.count() >= 13).toEqual(true);
|
expect(createSpy.calls.count() >= 13).toEqual(true);
|
||||||
let transactionalSession;
|
let transactionalSession;
|
||||||
let transactionalSession2;
|
let transactionalSession2;
|
||||||
let myObjectDBCalls = 0;
|
let myObjectDBCalls = 0;
|
||||||
let myObject2DBCalls = 0;
|
let myObject2DBCalls = 0;
|
||||||
let myObject3DBCalls = 0;
|
let myObject3DBCalls = 0;
|
||||||
for (let i = 0; i < databaseAdapter.createObject.calls.count(); i++) {
|
for (let i = 0; i < createSpy.calls.count(); i++) {
|
||||||
const args = databaseAdapter.createObject.calls.argsFor(i);
|
const args = createSpy.calls.argsFor(i);
|
||||||
switch (args[0]) {
|
switch (args[0]) {
|
||||||
case 'MyObject':
|
case 'MyObject':
|
||||||
myObjectDBCalls++;
|
myObjectDBCalls++;
|
||||||
|
|||||||
Reference in New Issue
Block a user