ci: Fix flaky direct access transaction tests (#9235)

This commit is contained in:
Diamond Lewis
2024-07-21 05:11:03 -05:00
committed by GitHub
parent 71a34eccc2
commit 5d09a1fd81

View File

@@ -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++;