Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions packages/mongodb-downloader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@
},
"dependencies": {
"debug": "^4.4.0",
"tar": "^6.1.15",
"decompress": "^4.2.1",
"mongodb-download-url": "^1.6.3",
"node-fetch": "^2.7.0"
"node-fetch": "^2.7.0",
"promise-retry": "^2.0.1",
"signal-exit": "^4.1.0",
"tar": "^6.1.15",
"mongodb-download-url": "^1.6.3"
},
"devDependencies": {
"@mongodb-js/eslint-config-devtools": "0.9.12",
Expand All @@ -67,6 +69,8 @@
"@types/decompress": "^4.2.4",
"@types/mocha": "^9.1.1",
"@types/node": "^22.15.30",
"@types/promise-retry": "^1.1.6",
"@types/signal-exit": "^3.0.4",
"@types/tar": "^6.1.5",
"depcheck": "^1.4.7",
"eslint": "^7.25.0",
Expand Down
126 changes: 126 additions & 0 deletions packages/mongodb-downloader/src/download-integration.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { expect } from 'chai';
import { promises as fs } from 'fs';
import path from 'path';
import os from 'os';
import { MongoDbDownloader } from './index';

describe('downloader with Locking', function () {
this.timeout(60000);

let tmpDir: string;

beforeEach(async function () {
tmpDir = path.join(os.tmpdir(), `download-integration-tests-${Date.now()}`);
await fs.mkdir(tmpDir, { recursive: true });
});
const version = '8.2.0';

afterEach(async function () {
try {
await fs.rm(tmpDir, { recursive: true });
} catch {
// Ignore cleanup errors
}
});

it('should prevent concurrent downloads of the same version', async function () {
const downloader = new MongoDbDownloader({ tmpdir: tmpDir });

const results = await Promise.all([
downloader.downloadMongoDbWithVersionInfo(version),
downloader.downloadMongoDbWithVersionInfo(version),
downloader.downloadMongoDbWithVersionInfo(version),
]);

// All results should be identical
expect(results[0].version).to.equal(version);
expect(results[1].version).to.equal(version);
expect(results[2].version).to.equal(version);

expect(results[0].downloadedBinDir).to.equal(results[1].downloadedBinDir);
expect(results[1].downloadedBinDir).to.equal(results[2].downloadedBinDir);

// Verify the downloaded directory exists and contains mongod
expect(await fs.stat(results[0].downloadedBinDir)).to.be.ok;
expect(await fs.stat(path.join(results[0].downloadedBinDir, 'mongod'))).to
.be.ok;
});

it('should wait for existing download to complete', async function () {
// First, download MongoDB normally
const downloader = new MongoDbDownloader({ tmpdir: tmpDir });
const result = await downloader.downloadMongoDbWithVersionInfo(version);

expect(result.version).to.equal(version);
expect(result.downloadedBinDir).to.be.a('string');

// Verify the downloaded directory exists and contains mongod
expect(await fs.stat(result.downloadedBinDir)).to.be.ok;
expect(await fs.stat(path.join(result.downloadedBinDir, 'mongod'))).to.be
.ok;
});

it('should skip download if already completed', async function () {
// First download
const downloader = new MongoDbDownloader({ tmpdir: tmpDir });
const result1 = await downloader.downloadMongoDbWithVersionInfo(version);

// Second download should use cached result
const result2 = await downloader.downloadMongoDbWithVersionInfo(version);

expect(result1.version).to.equal(version);
expect(result2.version).to.equal(version);
expect(result1.downloadedBinDir).to.equal(result2.downloadedBinDir);

// Verify the downloaded directory exists and contains mongod
expect(await fs.stat(result1.downloadedBinDir)).to.be.ok;
expect(await fs.stat(path.join(result1.downloadedBinDir, 'mongod'))).to.be
.ok;
});

it('should handle different versions independently', async function () {
const version2 = '8.1.0';

// Download different versions
const downloader = new MongoDbDownloader({ tmpdir: tmpDir });
const [result1, result2] = await Promise.all([
downloader.downloadMongoDbWithVersionInfo(version),
downloader.downloadMongoDbWithVersionInfo(version2),
]);

expect(result1.version).to.equal(version);
expect(result2.version).to.equal(version2);
expect(result1.downloadedBinDir).to.not.equal(result2.downloadedBinDir);

// Verify both downloaded directories exist and contain mongod
expect(await fs.stat(result1.downloadedBinDir)).to.be.ok;
expect(await fs.stat(path.join(result1.downloadedBinDir, 'mongod'))).to.be
.ok;
expect(await fs.stat(result2.downloadedBinDir)).to.be.ok;
expect(await fs.stat(path.join(result2.downloadedBinDir, 'mongod'))).to.be
.ok;
});

it('should handle promise caching correctly', async function () {
const version = '8.2.0';

// Start multiple downloads in sequence (not parallel)
const downloader = new MongoDbDownloader({ tmpdir: tmpDir });
const result1 = await downloader.downloadMongoDbWithVersionInfo(version);
const result2 = await downloader.downloadMongoDbWithVersionInfo(version);
const result3 = await downloader.downloadMongoDbWithVersionInfo(version);

// All should return the same result
expect(result1.version).to.equal(version);
expect(result2.version).to.equal(version);
expect(result3.version).to.equal(version);

expect(result1.downloadedBinDir).to.equal(result2.downloadedBinDir);
expect(result2.downloadedBinDir).to.equal(result3.downloadedBinDir);

// Verify the downloaded directory exists and contains mongod
expect(await fs.stat(result1.downloadedBinDir)).to.be.ok;
expect(await fs.stat(path.join(result1.downloadedBinDir, 'mongod'))).to.be
.ok;
});
});
Loading
Loading