Skip to content

Commit 28bbb85

Browse files
committed
test updating from the latest release to the newly packaged one
1 parent 139fa5d commit 28bbb85

File tree

10 files changed

+397
-172
lines changed

10 files changed

+397
-172
lines changed

packages/compass-e2e-tests/tests/auto-update.test.ts

Lines changed: 59 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,66 +13,71 @@ function wait(ms: number) {
1313
}
1414

1515
describe('Auto-update', function () {
16-
it('auto-update from', async function () {
17-
if (process.env.TEST_NAME !== 'auto-update-from') {
18-
// we don't want this test to execute along with all the others under
19-
// normal circumstances because it is destructive - it overwrites Compass
20-
// itself
21-
this.skip();
22-
}
23-
24-
// run the app and wait for it to auto-update
25-
console.log('starting compass the first time');
26-
const compass = await init('auto-update from', { firstRun: true });
27-
const { browser } = compass;
28-
try {
29-
await browser.$(Selectors.AutoUpdateToast).waitForDisplayed();
30-
31-
if (process.env.AUTO_UPDATE_UPDATABLE === 'true') {
32-
const restartButton = browser.$(Selectors.AutoUpdateRestartButton);
33-
await restartButton.waitForDisplayed();
34-
35-
// We could click the restart button to apply the update and restart the
36-
// app, but restarting the app confuses webdriverio or at least our test
37-
// helpers. So we're going to just restart the app manually.
38-
await browser.pause(1000);
39-
} else {
40-
// When auto-update is not supported the toast contains a link to
41-
// download
42-
const linkElement = browser.$(Selectors.AutoUpdateDownloadLink);
43-
await linkElement.waitForDisplayed();
44-
expect(await linkElement.getAttribute('href')).to.equal(
45-
'https://www.mongodb.com/try/download/compass?utm_source=compass&utm_medium=product'
46-
);
16+
for (const testName of ['auto-update-from', 'auto-update-to']) {
17+
it(testName, async function () {
18+
if (process.env.TEST_NAME !== testName) {
19+
// we don't want this test to execute along with all the others under
20+
// normal circumstances because it is destructive - it overwrites Compass
21+
// itself
22+
this.skip();
4723
}
48-
} finally {
49-
await browser.screenshot(screenshotPathName('auto-update-from'));
50-
await cleanup(compass);
51-
}
52-
53-
if (process.env.AUTO_UPDATE_UPDATABLE === 'true') {
54-
console.log(
55-
'pause to make sure the app properly exited before starting again'
56-
);
57-
await wait(10_000);
5824

59-
console.log('starting compass a second time');
60-
// run the app again and check that the version changed
61-
const compass = await init('auto-update from restart', {
62-
firstRun: false,
63-
});
25+
// run the app and wait for it to auto-update
26+
console.log('starting compass the first time');
27+
const compass = await init(testName, { firstRun: true });
6428
const { browser } = compass;
6529
try {
6630
await browser.$(Selectors.AutoUpdateToast).waitForDisplayed();
67-
await browser
68-
.$(Selectors.AutoUpdateReleaseNotesLink)
69-
.waitForDisplayed();
31+
32+
if (process.env.AUTO_UPDATE_UPDATABLE === 'true') {
33+
const restartButton = browser.$(Selectors.AutoUpdateRestartButton);
34+
await restartButton.waitForDisplayed();
35+
36+
// We could click the restart button to apply the update and restart the
37+
// app, but restarting the app confuses webdriverio or at least our test
38+
// helpers. So we're going to just restart the app manually.
39+
await browser.pause(1000);
40+
} else {
41+
// When auto-update is not supported the toast contains a link to
42+
// download
43+
const linkElement = browser.$(Selectors.AutoUpdateDownloadLink);
44+
await linkElement.waitForDisplayed();
45+
expect(await linkElement.getAttribute('href')).to.equal(
46+
'https://www.mongodb.com/try/download/compass?utm_source=compass&utm_medium=product'
47+
);
48+
49+
// TODO: when updating to a known version we know the version, so
50+
// check for the text
51+
}
7052
} finally {
71-
await browser.screenshot(
72-
screenshotPathName('auto-update-from-restart')
73-
);
53+
await browser.screenshot(screenshotPathName(testName));
7454
await cleanup(compass);
7555
}
76-
}
77-
});
56+
57+
if (process.env.AUTO_UPDATE_UPDATABLE === 'true') {
58+
console.log(
59+
'pause to make sure the app properly exited before starting again'
60+
);
61+
await wait(10_000);
62+
63+
console.log('starting compass a second time');
64+
// run the app again and check that the version changed
65+
const compass = await init(`${testName} restart`, {
66+
firstRun: false,
67+
});
68+
const { browser } = compass;
69+
try {
70+
await browser.$(Selectors.AutoUpdateToast).waitForDisplayed();
71+
await browser
72+
.$(Selectors.AutoUpdateReleaseNotesLink)
73+
.waitForDisplayed();
74+
// TODO: when updating to a known version we know the version, so
75+
// check for the text
76+
} finally {
77+
await browser.screenshot(screenshotPathName(`${testName}-restart`));
78+
await cleanup(compass);
79+
}
80+
}
81+
});
82+
}
7883
});

packages/compass-smoke-tests/src/build-info.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import { type PackageKind } from './packages';
88
import { type SmokeTestsContext } from './context';
99
import { pick } from 'lodash';
1010

11+
const SUPPORTED_CHANNELS = ['dev', 'beta', 'stable'] as const;
12+
13+
export type Channel = typeof SUPPORTED_CHANNELS[number];
14+
1115
function assertObjectHasKeys(
1216
obj: unknown,
1317
name: string,
@@ -25,13 +29,21 @@ function assertObjectHasKeys(
2529

2630
// subsets of the hadron-build info result
2731

28-
export const commonKeys = ['productName'] as const;
29-
export type CommonBuildInfo = Record<typeof commonKeys[number], string>;
32+
export const commonKeys = ['productName', 'version', 'channel'] as const;
33+
export type CommonBuildInfo = Record<typeof commonKeys[number], string> & {
34+
channel: Channel;
35+
};
3036

3137
export function assertCommonBuildInfo(
3238
buildInfo: unknown
3339
): asserts buildInfo is CommonBuildInfo {
3440
assertObjectHasKeys(buildInfo, 'buildInfo', commonKeys);
41+
assert(
42+
SUPPORTED_CHANNELS.includes((buildInfo as { channel: Channel }).channel),
43+
`Expected ${
44+
(buildInfo as { channel: Channel }).channel
45+
} to be in ${SUPPORTED_CHANNELS.join(',')}`
46+
);
3547
}
3648

3749
export const windowsFilenameKeys = [

packages/compass-smoke-tests/src/cli.ts

Lines changed: 41 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22
import assert from 'node:assert/strict';
33
import fs from 'node:fs';
44
import path from 'node:path';
5-
import { once } from 'node:events';
65

76
import yargs from 'yargs';
87
import { hideBin } from 'yargs/helpers';
98
import { pick } from 'lodash';
10-
import { execute, executeAsync } from './execute';
119
import {
1210
type PackageDetails,
1311
readPackageDetails,
@@ -16,18 +14,22 @@ import {
1614
import { createSandbox } from './directories';
1715
import { downloadFile } from './downloads';
1816
import { type PackageKind, SUPPORTED_PACKAGES } from './packages';
17+
import { getLatestRelease } from './releases';
18+
import { SUPPORTED_TESTS } from './tests/types';
1919
import { type SmokeTestsContext } from './context';
2020

2121
import { installMacDMG } from './installers/mac-dmg';
2222
import { installMacZIP } from './installers/mac-zip';
2323
import { installWindowsZIP } from './installers/windows-zip';
2424
import { installWindowsMSI } from './installers/windows-msi';
2525

26+
import { testTimeToFirstQuery } from './tests/time-to-first-query';
27+
import { testAutoUpdateFrom } from './tests/auto-update-from';
28+
import { testAutoUpdateTo } from './tests/auto-update-to';
29+
2630
const SUPPORTED_PLATFORMS = ['win32', 'darwin', 'linux'] as const;
2731
const SUPPORTED_ARCHS = ['x64', 'arm64'] as const;
2832

29-
const SUPPORTED_TESTS = ['time-to-first-query', 'auto-update-from'] as const;
30-
3133
function isSupportedPlatform(
3234
value: unknown
3335
): value is typeof SUPPORTED_PLATFORMS[number] {
@@ -198,9 +200,13 @@ async function run() {
198200
])
199201
);
200202

201-
const { kind, appName, filepath, autoUpdatable } = await getTestSubject(
202-
context
203-
);
203+
const {
204+
kind,
205+
appName,
206+
filepath,
207+
buildInfo: { channel, version },
208+
autoUpdatable,
209+
} = await getTestSubject(context);
204210
const install = getInstaller(kind);
205211

206212
try {
@@ -209,27 +215,51 @@ async function run() {
209215
}
210216

211217
for (const testName of context.tests) {
218+
const installerPath =
219+
testName === 'auto-update-to'
220+
? await getLatestRelease(
221+
channel,
222+
context.arch,
223+
kind,
224+
context.forceDownload
225+
)
226+
: filepath;
227+
212228
const { appPath, uninstall } = install({
213229
appName,
214-
filepath,
230+
filepath: installerPath,
215231
destinationPath: context.sandboxPath,
216232
});
217233

218234
try {
219235
if (testName === 'time-to-first-query') {
220236
// Auto-update does not work on mac in CI at the moment. So in that case
221237
// we just run the E2E tests to make sure the app at least starts up.
222-
runTimeToFirstQuery({
238+
testTimeToFirstQuery({
223239
appName,
224240
appPath,
225241
});
226242
}
227243
if (testName === 'auto-update-from') {
228-
await runUpdateTest({
244+
await testAutoUpdateFrom({
245+
appName,
246+
appPath,
247+
autoUpdatable,
248+
});
249+
}
250+
if (testName === 'auto-update-to') {
251+
assert(
252+
context.bucketKeyPrefix !== undefined,
253+
'Bucket key prefix is needed to download'
254+
);
255+
256+
await testAutoUpdateTo({
229257
appName,
230258
appPath,
231259
autoUpdatable,
232-
testName,
260+
channel,
261+
bucketKeyPrefix: context.bucketKeyPrefix,
262+
version,
233263
});
234264
}
235265
} finally {
@@ -246,110 +276,6 @@ async function run() {
246276
}
247277
}
248278

249-
async function importUpdateServer() {
250-
try {
251-
return (await import('compass-mongodb-com')).default;
252-
} catch (err: unknown) {
253-
console.log('Remember to npm link compass-mongodb-com');
254-
throw err;
255-
}
256-
}
257-
258-
async function startAutoUpdateServer() {
259-
console.log('Starting auto-update server');
260-
const { httpServer, updateChecker, start } = (await importUpdateServer())();
261-
start();
262-
await once(updateChecker, 'refreshed');
263-
264-
return httpServer;
265-
}
266-
267-
type RunE2ETestOptions = {
268-
appName: string;
269-
appPath: string;
270-
};
271-
272-
function runTimeToFirstQuery({ appName, appPath }: RunE2ETestOptions) {
273-
execute(
274-
'npm',
275-
[
276-
'run',
277-
'--unsafe-perm',
278-
'test-packaged',
279-
'--workspace',
280-
'compass-e2e-tests',
281-
'--',
282-
'--test-filter=time-to-first-query',
283-
],
284-
{
285-
// We need to use a shell to get environment variables setup correctly
286-
shell: true,
287-
env: {
288-
...process.env,
289-
COMPASS_APP_NAME: appName,
290-
COMPASS_APP_PATH: appPath,
291-
},
292-
}
293-
);
294-
}
295-
296-
type RunUpdateTestOptions = {
297-
appName: string;
298-
appPath: string;
299-
autoUpdatable?: boolean;
300-
testName: string;
301-
};
302-
303-
async function runUpdateTest({
304-
appName,
305-
appPath,
306-
autoUpdatable,
307-
testName,
308-
}: RunUpdateTestOptions) {
309-
process.env.PORT = '0'; // dynamic port
310-
process.env.UPDATE_CHECKER_ALLOW_DOWNGRADES = 'true';
311-
312-
const server = await startAutoUpdateServer();
313-
314-
const address = server.address();
315-
assert(typeof address === 'object' && address !== null);
316-
const port = address.port;
317-
const HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE = `http://localhost:${port}`;
318-
console.log({ HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE });
319-
320-
try {
321-
// must be async because the update server is running in the same process
322-
await executeAsync(
323-
'npm',
324-
[
325-
'run',
326-
'--unsafe-perm',
327-
'test-packaged',
328-
'--workspace',
329-
'compass-e2e-tests',
330-
'--',
331-
'--test-filter=auto-update',
332-
],
333-
{
334-
// We need to use a shell to get environment variables setup correctly
335-
shell: true,
336-
env: {
337-
...process.env,
338-
HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE,
339-
AUTO_UPDATE_UPDATABLE: (!!autoUpdatable).toString(),
340-
TEST_NAME: testName,
341-
COMPASS_APP_NAME: appName,
342-
COMPASS_APP_PATH: appPath,
343-
},
344-
}
345-
);
346-
} finally {
347-
console.log('Stopping auto-update server');
348-
server.close();
349-
delete process.env.UPDATE_CHECKER_ALLOW_DOWNGRADES;
350-
}
351-
}
352-
353279
run()
354280
.then(function () {
355281
console.log('done');

packages/compass-smoke-tests/src/context.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { type PackageKind } from './packages';
2+
import { type TestName } from './tests/types';
23

34
export type SmokeTestsContext = {
45
bucketName?: string;
@@ -9,6 +10,6 @@ export type SmokeTestsContext = {
910
forceDownload?: boolean;
1011
localPackage?: boolean;
1112
sandboxPath: string;
12-
tests: string[];
13+
tests: TestName[];
1314
skipCleanup: boolean;
1415
};

0 commit comments

Comments
 (0)