diff --git a/.evergreen/functions.yml b/.evergreen/functions.yml index 6fd181879c1..4cbffe9e7b8 100644 --- a/.evergreen/functions.yml +++ b/.evergreen/functions.yml @@ -693,7 +693,7 @@ functions: fi if [[ "$IS_UBUNTU" == "true" ]]; then - # TODO: linux_deb + npm run --unsafe-perm --workspace @mongodb-js/compass-smoke-tests start -- --package=linux_deb --tests=time-to-first-query npm run --unsafe-perm --workspace @mongodb-js/compass-smoke-tests start -- --package=linux_tar --tests=time-to-first-query fi diff --git a/packages/compass-smoke-tests/src/installers/apt.ts b/packages/compass-smoke-tests/src/installers/apt.ts new file mode 100644 index 00000000000..014616ad6c6 --- /dev/null +++ b/packages/compass-smoke-tests/src/installers/apt.ts @@ -0,0 +1,20 @@ +import assert from 'node:assert/strict'; +import cp from 'node:child_process'; + +/** + * Call apt to get the package name + */ +export function getPackageName(filepath: string) { + const result = cp.spawnSync('apt', ['show', filepath], { encoding: 'utf8' }); + assert.equal( + result.status, + 0, + `Expected a clean exit, got status ${result.status || 'null'}` + ); + const packageMatch = result.stdout.match(/Package: (?.+)/); + assert(packageMatch, 'Expected a line in the output with the package name'); + assert(packageMatch.groups); + const { name } = packageMatch.groups; + assert(typeof name === 'string'); + return name; +} diff --git a/packages/compass-smoke-tests/src/installers/index.ts b/packages/compass-smoke-tests/src/installers/index.ts index 4a37c38b991..df8495a14a4 100644 --- a/packages/compass-smoke-tests/src/installers/index.ts +++ b/packages/compass-smoke-tests/src/installers/index.ts @@ -5,6 +5,7 @@ import { installWindowsZIP } from './windows-zip'; import { installWindowsMSI } from './windows-msi'; import { installWindowsSetup } from './windows-setup'; import { installLinuxTar } from './linux-tar'; +import { installLinuxDeb } from './linux-deb'; export function getInstaller(kind: PackageKind) { if (kind === 'osx_dmg') { @@ -19,6 +20,8 @@ export function getInstaller(kind: PackageKind) { return installWindowsSetup; } else if (kind === 'linux_tar') { return installLinuxTar; + } else if (kind === 'linux_deb') { + return installLinuxDeb; } else { throw new Error(`Installer for '${kind}' is not yet implemented`); } diff --git a/packages/compass-smoke-tests/src/installers/linux-deb.ts b/packages/compass-smoke-tests/src/installers/linux-deb.ts new file mode 100644 index 00000000000..1e77d796e11 --- /dev/null +++ b/packages/compass-smoke-tests/src/installers/linux-deb.ts @@ -0,0 +1,53 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import path from 'node:path'; + +import type { InstalledAppInfo, InstallablePackage } from './types'; +import { execute } from '../execute'; +import * as apt from './apt'; + +export function installLinuxDeb({ + appName, + filepath, +}: InstallablePackage): InstalledAppInfo { + const packageName = apt.getPackageName(filepath); + const installPath = `/usr/lib/${packageName}`; + const appPath = path.resolve(installPath, appName); + + function uninstall() { + execute('sudo', ['apt', 'remove', '--yes', '--purge', packageName]); + } + + console.warn( + "Installing globally, since we haven't discovered a way to specify an install path" + ); + + if (fs.existsSync(installPath)) { + console.warn( + 'Found an existing install directory (likely from a previous run): Uninstalling first' + ); + uninstall(); + } + + assert( + !fs.existsSync(installPath), + `Expected no install directory to exist: ${installPath}` + ); + console.warn( + "Installing globally, since we haven't discovered a way to specify an install path" + ); + execute('sudo', ['apt', 'install', filepath]); + + assert( + fs.existsSync(installPath), + `Expected an install directory to exist: ${installPath}` + ); + + // Check that the executable will run without being quarantined or similar + execute('xvfb-run', [appPath, '--version']); + + return { + appPath: installPath, + uninstall, + }; +}