Skip to content

Commit

Permalink
test: extented the test for copying precompiled binaries
Browse files Browse the repository at this point in the history
  • Loading branch information
aryamohanan committed Aug 13, 2024
1 parent 2029137 commit b988d7e
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 19 deletions.
78 changes: 60 additions & 18 deletions packages/collector/test/nativeModuleRetry/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,33 +66,61 @@ describe('retry loading native addons', function () {
function runCopyPrecompiledForNativeAddonTest(agentControls, opts) {
let controls;

const check = async (nativeModuleFolder, backupPath) => {
const nativeModuleFiles = await fsPromise.readdir(nativeModuleFolder);
const backupPathFiles = await fsPromise.readdir(backupPath);
const rename = async (oldPath, newPath) => {
try {
await fsPromise.rename(oldPath, newPath);
} catch (err) {
if (err.code === 'EXDEV' || err.code === 'ENOTEMPTY') {
await copyFolder(oldPath, newPath);
await fsPromise.rm(oldPath, { recursive: true });
} else {
throw err;
}
}
};

expect(nativeModuleFiles.length).to.equal(backupPathFiles.length);
async function copyFolder(src, dest) {
await fsPromise.mkdir(dest, { recursive: true });
const entries = await fsPromise.readdir(src, { withFileTypes: true });

const copyPromises = entries.map(async entry => {
const srcPath = `${src}/${entry.name}`;
const destPath = `${dest}/${entry.name}`;

if (entry.isDirectory()) {
await copyFolder(srcPath, destPath);
} else {
await fsPromise.copyFile(srcPath, destPath);
}
});

await Promise.all(copyPromises);
}
const check = async copiedBinaryPath => {
const targetDirectory = 'precompiled';

const directoryPath = path.join(copiedBinaryPath, targetDirectory);
['binding.gyp', 'build', 'package.json', 'src'].forEach(file => {
expect(fs.existsSync(path.join(backupPath, file))).to.be.true;
expect(fs.existsSync(path.join(directoryPath, file))).to.be.true;
});

if (backupPath.includes('event-loop-stats')) {
expect(fs.existsSync(path.join(backupPath, 'src', 'eventLoopStats.cc'))).to.be.true;
expect(fs.existsSync(path.join(backupPath, 'src', 'eventLoopStats.js'))).to.be.true;
expect(fs.existsSync(path.join(backupPath, 'src', 'eventLoopStats.d.ts'))).to.be.true;
expect(fs.existsSync(path.join(backupPath, 'build', 'node_gyp_bins', 'python3'))).to.be.true;
expect(fs.existsSync(path.join(backupPath, 'build', 'Release', 'eventLoopStats.node'))).to.be.true;
if (directoryPath.includes('event-loop-stats')) {
expect(fs.existsSync(path.join(directoryPath, 'src', 'eventLoopStats.cc'))).to.be.true;
expect(fs.existsSync(path.join(directoryPath, 'src', 'eventLoopStats.js'))).to.be.true;
expect(fs.existsSync(path.join(directoryPath, 'build', 'Release', 'eventLoopStats.node'))).to.be.true;
}

if (backupPath.includes('gcstats.js')) {
expect(fs.existsSync(path.join(backupPath, 'src', 'gcstats.cc'))).to.be.true;
expect(fs.existsSync(path.join(backupPath, 'src', 'gcstats.js'))).to.be.true;
expect(fs.existsSync(path.join(backupPath, 'build', 'node_gyp_bins', 'python3'))).to.be.true;
expect(fs.existsSync(path.join(backupPath, 'build', 'Release', 'gcstats.node'))).to.be.true;
if (directoryPath.includes('gcstats.js')) {
expect(fs.existsSync(path.join(directoryPath, 'src', 'gcstats.cc'))).to.be.true;
expect(fs.existsSync(path.join(directoryPath, 'src', 'gcstats.js'))).to.be.true;
expect(fs.existsSync(path.join(directoryPath, 'build', 'Release', 'gcstats.node'))).to.be.true;
}
};

before(async () => {
// remove the dependency temporarily
await rename(opts.nativeModuleFolder, opts.backupPath);

controls = new ProcessControls({
appPath: path.join(__dirname, 'app'),
agentControls,
Expand All @@ -109,6 +137,7 @@ function runCopyPrecompiledForNativeAddonTest(agentControls, opts) {

after(async () => {
await controls.stop();
await rename(opts.backupPath, opts.nativeModuleFolder);
});

afterEach(async () => {
Expand All @@ -124,8 +153,21 @@ function runCopyPrecompiledForNativeAddonTest(agentControls, opts) {
agentControls.getEvents()
]).then(opts.check)
));
it('should copy the precompiled binaries', async () => {
await check(opts.nativeModuleFolder, opts.backupPath);
});

describe('validate precompiled binaries', () => {
it('should successfully copy the precompiled binaries', async () => {
// For the test, the precompiled binaries are copied to the path node_modules/@instana/shared-metrics.
const copiedBinaryPath = require('path').join(
__dirname,
'..',
'..',
'..',
'shared-metrics',
'node_modules',
`${opts.name}`
);
await check(copiedBinaryPath);
});
});
}
3 changes: 2 additions & 1 deletion packages/shared-metrics/src/util/nativeModuleRetry.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ function copyPrecompiled(opts, loaderEmitter, callback) {
const targetDir = path.join(opts.nativeModulePath, 'precompiled');

fse
.copy(path.join(os.tmpdir(), opts.nativeModuleName), targetDir)
.copy(path.join(os.tmpdir(), opts.nativeModuleName), targetDir, { dereference: true })
.then(() => {
// We have unpacked and copied the correct precompiled native addon. The next attempt to require the
// dependency should work.
Expand All @@ -198,6 +198,7 @@ function copyPrecompiled(opts, loaderEmitter, callback) {
// it will remember and not try to load anything from that path again (a `false` will be
// put into the cache for that cache key). Instead, we force a new path, by adding precompiled
// to the module path and use the absolute path to the module to load it.
logger.debug(`Successfully copied the precompiled build for ${opts.nativeModuleName} ${label}.`);
opts.loadFrom = targetDir;
callback(true);
})
Expand Down

0 comments on commit b988d7e

Please sign in to comment.