mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
fix: Sandbox policy tuning for tmp write access (#145)
* fix: Sandbox policy tuning for tmp write access * fix: Remove numbers from test * Update sandbox/profiles/pnpm-restrictive.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com> * fix: Sandbox E2E test to consider Linux bubblewrap tmpfs mount * Update sandbox/profiles/pnpm-restrictive.yml Co-authored-by: Sahil Bansal <bansalsahil315@gmail.com> Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com> * fix: Migrate deny rules from pnpm to npm policy --------- Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Sahil Bansal <bansalsahil315@gmail.com>
This commit is contained in:
co-authored by
Copilot
Sahil Bansal
parent
b332e1d6d4
commit
4600ab0245
+178
@@ -0,0 +1,178 @@
|
||||
const fs = require('fs');
|
||||
const { execSync } = require('child_process');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
// Package managers to test
|
||||
const PACKAGE_MANAGERS = ['npm', 'pnpm'];
|
||||
|
||||
// Well-known dependencies to install
|
||||
const TEST_DEPENDENCIES = ['lodash'];
|
||||
|
||||
const results = { passed: 0, failed: 0, tests: [] };
|
||||
|
||||
function test(name, fn) {
|
||||
try {
|
||||
const result = fn();
|
||||
results.tests.push({ name, status: result ? 'PASS' : 'FAIL', error: null });
|
||||
result ? results.passed++ : results.failed++;
|
||||
} catch (e) {
|
||||
results.tests.push({ name, status: 'ERROR', error: e.message });
|
||||
results.failed++;
|
||||
}
|
||||
}
|
||||
|
||||
function exec(cmd, options = {}) {
|
||||
try {
|
||||
const output = execSync(cmd, {
|
||||
encoding: 'utf8',
|
||||
timeout: 120000, // 2 minutes
|
||||
...options
|
||||
});
|
||||
return { success: true, output };
|
||||
} catch (e) {
|
||||
return { success: false, error: e.message, output: e.stdout || '' };
|
||||
}
|
||||
}
|
||||
|
||||
function createTempDir(prefix) {
|
||||
return fs.mkdtempSync(path.join(os.tmpdir(), prefix));
|
||||
}
|
||||
|
||||
function cleanup(dir) {
|
||||
try {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
} catch (e) {
|
||||
// Ignore cleanup errors
|
||||
}
|
||||
}
|
||||
|
||||
function testPackageManager(pm) {
|
||||
const testDir = createTempDir(`pmg-e2e-${pm}-`);
|
||||
console.log(`\n Test directory: ${testDir}`);
|
||||
|
||||
try {
|
||||
// Initialize project
|
||||
test(`${pm}: Initialize project`, () => {
|
||||
const initCmd = pm === 'npm' ? 'npm init -y' : 'pnpm init';
|
||||
const result = exec(initCmd, { cwd: testDir });
|
||||
if (!result.success) {
|
||||
console.log(` ❌ FAIL: ${result.error}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const packageJsonExists = fs.existsSync(path.join(testDir, 'package.json'));
|
||||
if (packageJsonExists) {
|
||||
console.log(` ✅ PASS: Project initialized`);
|
||||
return true;
|
||||
}
|
||||
console.log(` ❌ FAIL: package.json not created`);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Add dependencies
|
||||
const depsStr = TEST_DEPENDENCIES.join(', ');
|
||||
test(`${pm}: Add dependencies (${depsStr})`, () => {
|
||||
const depsList = TEST_DEPENDENCIES.join(' ');
|
||||
const addCmd = pm === 'npm'
|
||||
? `npm install ${depsList}`
|
||||
: `pnpm add ${depsList}`;
|
||||
const result = exec(addCmd, { cwd: testDir });
|
||||
if (!result.success) {
|
||||
console.log(` ❌ FAIL: ${result.error}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify dependencies were added to package.json
|
||||
const packageJson = JSON.parse(fs.readFileSync(path.join(testDir, 'package.json'), 'utf8'));
|
||||
const missingDeps = TEST_DEPENDENCIES.filter(
|
||||
dep => !packageJson.dependencies || !packageJson.dependencies[dep]
|
||||
);
|
||||
if (missingDeps.length === 0) {
|
||||
console.log(` ✅ PASS: Dependencies added`);
|
||||
return true;
|
||||
}
|
||||
console.log(` ❌ FAIL: Missing dependencies in package.json: ${missingDeps.join(', ')}`);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Verify node_modules exists
|
||||
test(`${pm}: Verify node_modules created`, () => {
|
||||
const nodeModulesExists = fs.existsSync(path.join(testDir, 'node_modules'));
|
||||
if (!nodeModulesExists) {
|
||||
console.log(` ❌ FAIL: node_modules missing`);
|
||||
return false;
|
||||
}
|
||||
const missingDeps = TEST_DEPENDENCIES.filter(
|
||||
dep => !fs.existsSync(path.join(testDir, 'node_modules', dep))
|
||||
);
|
||||
if (missingDeps.length === 0) {
|
||||
console.log(` ✅ PASS: node_modules and dependencies exist`);
|
||||
return true;
|
||||
}
|
||||
console.log(` ❌ FAIL: Missing in node_modules: ${missingDeps.join(', ')}`);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Clean install (remove node_modules and reinstall)
|
||||
test(`${pm}: Clean install`, () => {
|
||||
// Remove node_modules
|
||||
const nodeModulesPath = path.join(testDir, 'node_modules');
|
||||
fs.rmSync(nodeModulesPath, { recursive: true, force: true });
|
||||
|
||||
// Reinstall
|
||||
const installCmd = pm === 'npm' ? 'npm install' : 'pnpm install';
|
||||
const result = exec(installCmd, { cwd: testDir });
|
||||
if (!result.success) {
|
||||
console.log(` ❌ FAIL: ${result.error}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify node_modules recreated with all dependencies
|
||||
const missingDeps = TEST_DEPENDENCIES.filter(
|
||||
dep => !fs.existsSync(path.join(testDir, 'node_modules', dep))
|
||||
);
|
||||
if (missingDeps.length === 0) {
|
||||
console.log(` ✅ PASS: Clean install successful`);
|
||||
return true;
|
||||
}
|
||||
console.log(` ❌ FAIL: Dependencies not reinstalled: ${missingDeps.join(', ')}`);
|
||||
return false;
|
||||
});
|
||||
|
||||
} finally {
|
||||
cleanup(testDir);
|
||||
console.log(` Cleaned up: ${testDir}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Main
|
||||
console.log('=== PMG Package Manager E2E Tests ===\n');
|
||||
console.log('This script tests basic npm/pnpm flows to ensure sandbox compatibility.\n');
|
||||
|
||||
for (const pm of PACKAGE_MANAGERS) {
|
||||
// Check if package manager is available
|
||||
const checkResult = exec(`which ${pm}`);
|
||||
if (!checkResult.success) {
|
||||
console.log(`--- Skipping ${pm} (not installed) ---`);
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(`--- Testing ${pm.toUpperCase()} ---`);
|
||||
testPackageManager(pm);
|
||||
}
|
||||
|
||||
// Summary
|
||||
console.log('\n=== SUMMARY ===');
|
||||
console.log(`Passed: ${results.passed}/${results.tests.length}`);
|
||||
console.log(`Failed: ${results.failed}/${results.tests.length}`);
|
||||
|
||||
if (results.failed > 0) {
|
||||
console.log('\nFailed tests:');
|
||||
results.tests.filter(t => t.status !== 'PASS').forEach(t => {
|
||||
console.log(` - ${t.name}: ${t.status} ${t.error || ''}`);
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('\nAll tests passed!');
|
||||
Reference in New Issue
Block a user