Skip to content

Commit

Permalink
fix(DryMongoBinary::locateBinary): check if download-lock still exists
Browse files Browse the repository at this point in the history
and treat it like the binary does not exists

fixes #872
  • Loading branch information
hasezoey committed May 16, 2024
1 parent 9db479f commit c600609
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
20 changes: 19 additions & 1 deletion packages/mongodb-memory-server-core/src/util/DryMongoBinary.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import debug from 'debug';
import { DEFAULT_VERSION, envToBool, resolveConfig, ResolveConfigVariables } from './resolveConfig';
import { assertion, checkBinaryPermissions, isNullOrUndefined, pathExists } from './utils';
import {
assertion,
checkBinaryPermissions,
isNullOrUndefined,
lockfilePath,
pathExists,
} from './utils';
import * as path from 'path';
import { arch, homedir, platform } from 'os';
import findCacheDir from 'find-cache-dir';
Expand Down Expand Up @@ -100,6 +106,18 @@ export class DryMongoBinary {
return undefined;
}

// check for the race-condition of "extraction started, but not finished"
// or said differently, the file "exists" but is not fully extracted yet
// see https://github.com/nodkz/mongodb-memory-server/issues/872
if (
returnValue[0] &&
(await pathExists(lockfilePath(path.dirname(returnValue[1]), useOpts.version)))
) {
log('locateBinary: binary found, but also a download-lock, trying to resolve lock');

return undefined;
}

log(`locateBinary: found binary at "${returnValue[1]}"`);
this.binaryCache.set(opts.version, returnValue[1]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,28 @@ describe('DryBinary', () => {
expect(binary.DryMongoBinary.generateDownloadPath).toHaveBeenCalled();
});

it('should return "undefined" if binary can be found but also a download-lock', async () => {
jest
.spyOn(binary.DryMongoBinary, 'generateDownloadPath')
.mockResolvedValue([true, '/tmp/1.1.1']);

const originalPathExists = utils.pathExists;

const utilsSpy = jest.spyOn(utils, 'pathExists').mockImplementation((path) => {
if (path === '/tmp/1.1.1.lock' || path === '/tmp/1.1.1') {
return Promise.resolve(true);
}

return originalPathExists(path);
});

const returnValue = await binary.DryMongoBinary.locateBinary({ version: '1.1.1' });
expect(returnValue).toBeUndefined();
expect(binary.DryMongoBinary.binaryCache.size).toBe(0);
expect(binary.DryMongoBinary.generateDownloadPath).toHaveBeenCalled();
expect(utilsSpy).toHaveBeenCalledWith('/tmp/1.1.1.lock');
});

it('should return cached version if exists', async () => {
const mockBinary = '/custom/path';
binary.DryMongoBinary.binaryCache.set('1.1.1', mockBinary);
Expand Down

0 comments on commit c600609

Please sign in to comment.