diff --git a/.evergreen/buildvariants-and-tasks.in.yml b/.evergreen/buildvariants-and-tasks.in.yml index 2659cf057fc..0087df4ac71 100644 --- a/.evergreen/buildvariants-and-tasks.in.yml +++ b/.evergreen/buildvariants-and-tasks.in.yml @@ -480,8 +480,7 @@ tasks: - func: prepare - func: install - func: bootstrap - vars: - scope: 'compass-e2e-tests' + - func: spawn-signing-server - func: smoketest-packaged-app vars: mongodb_version: latest-enterprise diff --git a/.evergreen/buildvariants-and-tasks.yml b/.evergreen/buildvariants-and-tasks.yml index 3c79e271bf0..e14b23712ff 100644 --- a/.evergreen/buildvariants-and-tasks.yml +++ b/.evergreen/buildvariants-and-tasks.yml @@ -504,8 +504,7 @@ tasks: - func: prepare - func: install - func: bootstrap - vars: - scope: compass-e2e-tests + - func: spawn-signing-server - func: smoketest-packaged-app vars: mongodb_version: latest-enterprise diff --git a/package-lock.json b/package-lock.json index b4056550cd1..02efd34d02f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7998,6 +7998,10 @@ "resolved": "configs/mocha-config-compass", "link": true }, + "node_modules/@mongodb-js/mocked-compass": { + "resolved": "packages/mocked-compass", + "link": true + }, "node_modules/@mongodb-js/mongodb-constants": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/@mongodb-js/mongodb-constants/-/mongodb-constants-0.10.2.tgz", @@ -13169,6 +13173,17 @@ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==" }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "node_modules/@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -43271,6 +43286,7 @@ "@mongodb-js/tsconfig-compass": "^1.0.7", "@types/chai-as-promised": "^7.1.4", "@types/cross-spawn": "^6.0.2", + "@types/express": "^5.0.0", "@types/yargs": "^17.0.33", "@wdio/types": "^8.32.2", "bson": "^6.10.1", @@ -43284,6 +43300,7 @@ "electron": "^32.2.7", "electron-to-chromium": "^1.5.75", "eslint": "^7.25.0", + "express": "^4.21.2", "glob": "^10.2.5", "hadron-build": "^25.5.17", "lodash": "^4.17.21", @@ -43321,6 +43338,32 @@ "oidc-mock-provider": "bin/oidc-mock-provider.js" } }, + "packages/compass-e2e-tests/node_modules/@types/express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", + "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "packages/compass-e2e-tests/node_modules/@types/express-serve-static-core": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.3.tgz", + "integrity": "sha512-JEhMNwUJt7bw728CydvYzntD0XJeTmDnvwLlbfbAhE7Tbslm/ax6bdIiUwTgeVlZTsJQPwZwKpAkyDtIjsvx3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "packages/compass-e2e-tests/node_modules/@types/node": { "version": "20.17.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.9.tgz", @@ -48700,6 +48743,119 @@ "mocha": "^10.2.0" } }, + "packages/mocked-compass": { + "name": "@mongodb-js/mocked-compass", + "version": "99.0.0", + "license": "SSPL", + "devDependencies": { + "@mongodb-js/eslint-config-compass": "^1.1.9", + "@mongodb-js/mocha-config-compass": "^1.4.4", + "@mongodb-js/prettier-config-compass": "^1.0.4", + "@mongodb-js/sbom-tools": "^0.7.0", + "@mongodb-js/tsconfig-compass": "^1.0.7", + "@mongodb-js/webpack-config-compass": "^1.4.9", + "@types/mocha": "^9.0.0", + "@types/sinon-chai": "^3.2.5", + "depcheck": "^1.4.1", + "electron": "^32.2.7", + "eslint": "^7.25.0", + "hadron-build": "^25.5.17", + "mocha": "^10.2.0", + "nyc": "^15.1.0", + "prettier": "^2.7.1", + "sinon": "^17.0.1", + "typescript": "^5.0.4" + } + }, + "packages/mocked-compass/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "packages/mocked-compass/node_modules/@sinonjs/fake-timers": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", + "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "packages/mocked-compass/node_modules/@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" + } + }, + "packages/mocked-compass/node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "packages/mocked-compass/node_modules/just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true, + "license": "MIT" + }, + "packages/mocked-compass/node_modules/nise": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" + } + }, + "packages/mocked-compass/node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, + "packages/mocked-compass/node_modules/sinon": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, "packages/mongodb-explain-compat": { "version": "3.1.3", "license": "SSPL", @@ -58519,6 +58675,106 @@ } } }, + "@mongodb-js/mocked-compass": { + "version": "file:packages/mocked-compass", + "requires": { + "@mongodb-js/eslint-config-compass": "^1.1.9", + "@mongodb-js/mocha-config-compass": "^1.4.4", + "@mongodb-js/prettier-config-compass": "^1.0.4", + "@mongodb-js/sbom-tools": "^0.7.0", + "@mongodb-js/tsconfig-compass": "^1.0.7", + "@mongodb-js/webpack-config-compass": "^1.4.9", + "@types/mocha": "^9.0.0", + "@types/sinon-chai": "^3.2.5", + "depcheck": "^1.4.1", + "electron": "^32.2.7", + "eslint": "^7.25.0", + "hadron-build": "^25.5.17", + "mocha": "^10.2.0", + "nyc": "^15.1.0", + "prettier": "^2.7.1", + "sinon": "^17.0.1", + "typescript": "^5.0.4" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", + "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1" + } + }, + "@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" + }, + "dependencies": { + "type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true + } + } + }, + "just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true + }, + "nise": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" + } + }, + "path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true + }, + "sinon": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", + "supports-color": "^7.2.0" + } + } + } + }, "@mongodb-js/mongodb-constants": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/@mongodb-js/mongodb-constants/-/mongodb-constants-0.10.2.tgz", @@ -62993,6 +63249,16 @@ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==" }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "@types/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", @@ -66374,6 +66640,7 @@ "@mongodb-js/tsconfig-compass": "^1.0.7", "@types/chai-as-promised": "^7.1.4", "@types/cross-spawn": "^6.0.2", + "@types/express": "^5.0.0", "@types/yargs": "^17.0.33", "@wdio/types": "^8.32.2", "bson": "^6.10.1", @@ -66387,6 +66654,7 @@ "electron": "^32.2.7", "electron-to-chromium": "^1.5.75", "eslint": "^7.25.0", + "express": "^4.21.2", "glob": "^10.2.5", "hadron-build": "^25.5.17", "lodash": "^4.17.21", @@ -66420,6 +66688,30 @@ "yargs": "17.7.2" } }, + "@types/express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", + "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.3.tgz", + "integrity": "sha512-JEhMNwUJt7bw728CydvYzntD0XJeTmDnvwLlbfbAhE7Tbslm/ax6bdIiUwTgeVlZTsJQPwZwKpAkyDtIjsvx3g==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "@types/node": { "version": "20.17.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.9.tgz", diff --git a/packages/compass-e2e-tests/helpers/mock-auto-update-server.ts b/packages/compass-e2e-tests/helpers/mock-auto-update-server.ts new file mode 100644 index 00000000000..6f2cd276401 --- /dev/null +++ b/packages/compass-e2e-tests/helpers/mock-auto-update-server.ts @@ -0,0 +1,213 @@ +import path from 'path'; +import express from 'express'; + +type AvailableUpdate = + | { + version: string; + notes: string; + } + | undefined; + +export function startAutoUpdateServer({ + expectedPlatform, + expectedChannel, + expectedVersion, + newVersion, + filename, + mockedDistDir, + newNotes, + port, +}: { + // the fake update will only apply to this exact platform + expectedPlatform: string; + // which channel the version applies to + expectedChannel: 'dev' | 'beta' | 'stable'; + // the fake update will only apply to versions matching exactly this string + expectedVersion: string; + // the fake version number of what we'll allow updating to + newVersion: string; + // the of the (probably fake) file containing the new version + filename: string; + // where to read the file from + mockedDistDir: string; + // the release notes of the new version + newNotes: string; + // port number for the this fake update server we're starting + port: number; +}) { + const app = express(); + + app.use((req, res, next) => { + console.log(req.method, req.path); + next(); + }); + + const updatablePlatforms = [ + 'linux-x64', + 'win32-x64', + 'darwin-x64', + 'darwin-arm64', + ].join('|'); + + // http://localhost:3000/api/v2/update/compass/dev/darwin-arm64/1.45.0/check + app.get( + `/api/v2/update/:distribution/:channel/:platform(${updatablePlatforms})/:version/check`, + (req, res) => { + const match = { + route: 'check', + params: req.params, + }; + console.log(match); + + let availableUpdate: AvailableUpdate = undefined; + + if ( + req.params.channel === expectedChannel && + req.params.platform === expectedPlatform && + req.params.version === expectedVersion + ) { + availableUpdate = { + version: newVersion, + notes: newNotes, + }; + } + + if (!availableUpdate) { + console.log( + 'no update for', + req.params.channel, + req.params.platform, + req.params.version + ); + res.status(204).send(); + return; + } + + const response = { + name: availableUpdate.version, + from: req.params.version, + to: availableUpdate.version, + }; + + console.log('response:', response); + res.json(response); + } + ); + + // http://localhost:3000/api/v2/update/compass/dev/win32-x64/1.45.0/RELEASES + app.get( + '/api/v2/update/:distribution/:channel/:platform(windows|win32-x64)/:version/RELEASES', + (req, res) => { + const match = { + route: 'windows-releases', + params: req.params, + }; + console.log(match); + // TODO: implement this + res.send(match); + } + ); + + // http://localhost:3000/api/v2/update/compass/dev/win32-x64/1.45.0/something.nupkg + app.get( + '/api/v2/update/:distribution/:channel/:platform(windows|win32-x64)/:version/:nupkg', + (req, res) => { + const match = { + route: 'windows-nupkg', + params: req.params, + }; + console.log(match); + // TODO: implement this + res.send(match); + } + ); + + // http://localhost:3000/api/v2/update/compass/dev/darwin-arm64/1.45.0 + app.get( + '/api/v2/update/:distribution/:channel/:platform(osx|darwin-x64|darwin-arm64)/:version', + (req, res) => { + const match = { + route: 'mac-version', + params: req.params, + }; + console.log(match); + //res.send(match); + + let availableUpdate: AvailableUpdate = undefined; + + if ( + req.params.channel === expectedChannel && + req.params.platform === expectedPlatform && + req.params.version === expectedVersion + ) { + availableUpdate = { + version: newVersion, + notes: newNotes, + }; + } + + if (!availableUpdate) { + console.log( + 'no update for', + req.params.channel, + req.params.platform, + req.params.version + ); + res.status(204).send(); + return; + } + + const response = { + url: `http://localhost:${port}/download/${filename}`, + name: availableUpdate.version, + notes: availableUpdate.notes || '', + from: req.params.version, + to: availableUpdate.version, + }; + + console.log('response:', response); + res.json(response); + } + ); + + // Usually the update file would be on S3 somewhere. We're not uploading the + // mocked compass anywhere on the internet, we're serving it ourselves. So + // this server just tells Compass to download the new update from here. + app.get('/download/:filename', (req, res) => { + const match = { + route: 'fake-download', + params: req.params, + }; + console.log(match); + + if (req.params.filename !== filename) { + console.log('filename does not match', req.params.filename, filename); + res.status(404).send(); + return; + } + + res.sendFile(path.join(mockedDistDir, filename)); + }); + + // fallback to 404 for anything unknown, with some debugging + app.get('/*', (req, res) => { + res.status(404).send(req.path); + }); + + const server = app.listen(port, () => { + console.log(`Listening on port ${port}`); + }); + + return { server, app }; +} + +/* +const { server } = start({ + expectedPlatform: 'darwin-arm64', + expectedVersion: '0.0.1-dev.0', + newVersion: '1.46.0', + newURL: 'TODO', + newNotes: 'release notes go here', + port: 3000, +}); +*/ diff --git a/packages/compass-e2e-tests/index.ts b/packages/compass-e2e-tests/index.ts index 86a31aec1a1..705c72bdceb 100644 --- a/packages/compass-e2e-tests/index.ts +++ b/packages/compass-e2e-tests/index.ts @@ -52,7 +52,9 @@ let runnerPromise: Promise | undefined; async function main() { const e2eTestGroupsAmount = context.testGroups; const e2eTestGroup = context.testGroup; - const e2eTestFilter = context.testFilter; + const e2eTestFilter = context.testFilter.includes(',') + ? `{${context.testFilter}}` + : context.testFilter; const tests = ( await glob(`tests/**/${e2eTestFilter}.{test,spec}.ts`, { diff --git a/packages/compass-e2e-tests/package.json b/packages/compass-e2e-tests/package.json index 57becd4d887..a100028b54c 100644 --- a/packages/compass-e2e-tests/package.json +++ b/packages/compass-e2e-tests/package.json @@ -41,6 +41,7 @@ "@mongodb-js/tsconfig-compass": "^1.0.7", "@types/chai-as-promised": "^7.1.4", "@types/cross-spawn": "^6.0.2", + "@types/express": "^5.0.0", "@types/yargs": "^17.0.33", "@wdio/types": "^8.32.2", "bson": "^6.10.1", @@ -54,6 +55,7 @@ "electron": "^32.2.7", "electron-to-chromium": "^1.5.75", "eslint": "^7.25.0", + "express": "^4.21.2", "glob": "^10.2.5", "hadron-build": "^25.5.17", "lodash": "^4.17.21", diff --git a/packages/compass-e2e-tests/smoke-test.ts b/packages/compass-e2e-tests/smoke-test.ts index f7f4a5b2258..7085e84eb91 100755 --- a/packages/compass-e2e-tests/smoke-test.ts +++ b/packages/compass-e2e-tests/smoke-test.ts @@ -16,6 +16,14 @@ const argv = yargs(hideBin(process.argv)) .detectLocale(false) .version(false) .strict() + .option('distribution', { + type: 'string', + default: () => process.env.HADRON_DISTRIBUTION, + }) + .option('channel', { + type: 'string', + default: () => process.env.HADRON_CHANNEL, + }) .option('bucketName', { type: 'string', default: () => process.env.EVERGREEN_BUCKET_NAME, @@ -63,6 +71,12 @@ const argv = yargs(hideBin(process.argv)) 'If specified it will only run the smoke tests for the specified installer/package', }) .check((argv) => { + if (!(argv.distribution && argv.channel)) { + throw new Error( + 'HADRON_DISTRIBUTION and HADRON_CHANNEL are required for building the new mocked compass' + ); + } + if (!argv.skipDownload) { if (!(argv.bucketName && argv.bucketKeyPrefix)) { throw new Error( @@ -168,6 +182,8 @@ async function run() { verifyPackagesExist(packages); + await buildMockedCompass(); + // TODO(COMPASS-8533): extract or install each package and then test the Compass binary for (const pkg of packages) { let appInfo: InstalledAppInfo | undefined = undefined; @@ -365,6 +381,16 @@ function verifyPackagesExist(packages: Package[]): void { } } +function buildMockedCompass(): Promise { + return execute('npm', [ + 'run', + '--unsafe-perm', + 'package-compass', + '--workspace', + '@mongodb-js/mocked-compass', + ]); +} + function testInstalledApp(appInfo: InstalledAppInfo): Promise { return execute( 'npm', @@ -375,7 +401,7 @@ function testInstalledApp(appInfo: InstalledAppInfo): Promise { '--workspace', 'compass-e2e-tests', '--', - '--test-filter=time-to-first-query', + '--test-filter=auto-update', ], { env: { diff --git a/packages/compass-e2e-tests/tests/auto-update.test.ts b/packages/compass-e2e-tests/tests/auto-update.test.ts new file mode 100644 index 00000000000..3bb1a7649fb --- /dev/null +++ b/packages/compass-e2e-tests/tests/auto-update.test.ts @@ -0,0 +1,93 @@ +import { expect } from 'chai'; +import path from 'path'; +import { + init, + cleanup, + screenshotIfFailed, + runCompassOnce, +} from '../helpers/compass'; +import type { Compass } from '../helpers/compass'; +import { startAutoUpdateServer } from '../helpers/mock-auto-update-server'; + +import type { Server } from 'http'; + +describe('Auto update', function () { + let compass: Compass | undefined; + let server: Server | undefined; + + beforeEach(async function () {}); + + afterEach(async function () { + delete process.env.HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE; + + if (server) { + server.close(); + } + if (compass) { + await screenshotIfFailed(compass, this.currentTest); + await cleanup(compass); + compass = undefined; + } + }); + + // TODO(COMPASS-8533): requires support for more installers + it('notifies the user of a new version if auto update is not supported'); + + it('tells the user when they are already on the latest version'); + + it('automatically updates to the latest version if auto update is supported', async function () { + // NOTE: This test is destructive by its very nature in that it replaces the + // copy of Compass that it runs. Therefore it should be the last test we run + // before re-installing Compass again. + + const port = 3000; + + const { stdout } = await runCompassOnce(['--version']); + const match = stdout + .trim() + .match(/^MongoDB Compass( (Dev|Beta|Stable))? (.*)$/); + const currentChannel = ((match && match[2]) ?? 'Stable').toLowerCase() as + | 'dev' + | 'beta' + | 'stable'; + const currentVersion = match && match[3]; + expect(currentVersion).to.not.be.undefined; + + // TODO: calculate this + const currentPlatform = 'darwin-arm64'; + + // TODO: read this from the mocked-compass package.json + const newVersion = '99.0.0-dev'; + + // TODO: calculate this + const filename = `mongodb-compass-${newVersion}-darwin-arm64.zip`; + + // start the auto-update server with info about mocked compass + ({ server } = startAutoUpdateServer({ + // TODO: take into account the expected distribution + expectedPlatform: currentPlatform, + expectedChannel: currentChannel, + expectedVersion: currentVersion as string, + newVersion, + filename, + mockedDistDir: path.join(__dirname, '..', '..', 'mocked-compass', 'dist'), + newNotes: 'something', + port, + })); + + // start compass + process.env.HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE = `http://localhost:${port}`; + compass = await init(this.test?.fullTitle(), { firstRun: true }); + + const browser = compass.browser; + + console.log('pausing for a bit'); + await browser.pause(60_000); + + // wait for it to hit the auto-update endpoint + // wait for it to get the toast + // close compass + // run compass on the command line + // check that it wrote the expected file + }); +}); diff --git a/packages/compass-e2e-tests/tests/time-to-first-query.test.ts b/packages/compass-e2e-tests/tests/time-to-first-query.test.ts index e6b8fdf4c47..ad59201c311 100644 --- a/packages/compass-e2e-tests/tests/time-to-first-query.test.ts +++ b/packages/compass-e2e-tests/tests/time-to-first-query.test.ts @@ -19,7 +19,6 @@ describe('Time to first query', function () { // cleanup outside of the test so that the time it takes to run does not // get added to the time it took to run the first query if (compass) { - // even though this is after (not afterEach) currentTest points to the last test await screenshotIfFailed(compass, this.currentTest); await cleanup(compass); compass = undefined; diff --git a/packages/mocked-compass/.depcheckrc b/packages/mocked-compass/.depcheckrc new file mode 100644 index 00000000000..ab0ef21b740 --- /dev/null +++ b/packages/mocked-compass/.depcheckrc @@ -0,0 +1,8 @@ +ignores: + - '@mongodb-js/prettier-config-compass' + - '@mongodb-js/tsconfig-compass' + - '@types/chai' + - '@types/sinon-chai' + - 'sinon' +ignore-patterns: + - 'dist' diff --git a/packages/mocked-compass/.eslintignore b/packages/mocked-compass/.eslintignore new file mode 100644 index 00000000000..1b823a2c19a --- /dev/null +++ b/packages/mocked-compass/.eslintignore @@ -0,0 +1,2 @@ +dist +build diff --git a/packages/mocked-compass/.eslintrc.js b/packages/mocked-compass/.eslintrc.js new file mode 100644 index 00000000000..e4cf824b6ac --- /dev/null +++ b/packages/mocked-compass/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + root: true, + extends: ['@mongodb-js/eslint-config-compass'], + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./tsconfig-lint.json'], + }, +}; diff --git a/packages/mocked-compass/.gitignore b/packages/mocked-compass/.gitignore new file mode 100644 index 00000000000..f9839f194cb --- /dev/null +++ b/packages/mocked-compass/.gitignore @@ -0,0 +1,24 @@ +npm-debug.log +build/ +dist/ +node_modules +.DS_Store +.idea/ +*.swp +*.iml +.cache* +src/app/templates.js +src/connect/static-connect.html +report.json +.user-data/ +.compiled-sources/ +src/app/.compiled-less/ +expansions.yml +expansions.raw.yml +.nvmrc +.vscode +src/app/fonts/akzid* +src/app/fonts/Euclid* +src/app/fonts/MongoDB* +.compile-cache-mappings.json +macnotary diff --git a/packages/mocked-compass/.mocharc.js b/packages/mocked-compass/.mocharc.js new file mode 100644 index 00000000000..7e473d17b76 --- /dev/null +++ b/packages/mocked-compass/.mocharc.js @@ -0,0 +1 @@ +module.exports = require('@mongodb-js/mocha-config-compass'); diff --git a/packages/mocked-compass/.prettierignore b/packages/mocked-compass/.prettierignore new file mode 100644 index 00000000000..57051100119 --- /dev/null +++ b/packages/mocked-compass/.prettierignore @@ -0,0 +1,8 @@ +.nyc_output +dist +coverage +build +src/deps + +# Generated +THIRD-PARTY-NOTICES.md diff --git a/packages/mocked-compass/.prettierrc.json b/packages/mocked-compass/.prettierrc.json new file mode 100644 index 00000000000..18853d1532e --- /dev/null +++ b/packages/mocked-compass/.prettierrc.json @@ -0,0 +1 @@ +"@mongodb-js/prettier-config-compass" diff --git a/packages/mocked-compass/LICENSE b/packages/mocked-compass/LICENSE new file mode 100644 index 00000000000..019ca56d7eb --- /dev/null +++ b/packages/mocked-compass/LICENSE @@ -0,0 +1,560 @@ + Server Side Public License + VERSION 1, OCTOBER 16, 2018 + + Copyright © 2018 MongoDB, Inc. + + Everyone is permitted to copy and distribute verbatim copies of this + license document, but changing it is not allowed. + + TERMS AND CONDITIONS + + 0. Definitions. + + “This License” refers to Server Side Public License. + + “Copyright” also means copyright-like laws that apply to other kinds of + works, such as semiconductor masks. + + “The Program” refers to any copyrightable work licensed under this + License. Each licensee is addressed as “you”. “Licensees” and + “recipients” may be individuals or organizations. + + To “modify” a work means to copy from or adapt all or part of the work in + a fashion requiring copyright permission, other than the making of an + exact copy. The resulting work is called a “modified version” of the + earlier work or a work “based on” the earlier work. + + A “covered work” means either the unmodified Program or a work based on + the Program. + + To “propagate” a work means to do anything with it that, without + permission, would make you directly or secondarily liable for + infringement under applicable copyright law, except executing it on a + computer or modifying a private copy. Propagation includes copying, + distribution (with or without modification), making available to the + public, and in some countries other activities as well. + + To “convey” a work means any kind of propagation that enables other + parties to make or receive copies. Mere interaction with a user through a + computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays “Appropriate Legal Notices” to the + extent that it includes a convenient and prominently visible feature that + (1) displays an appropriate copyright notice, and (2) tells the user that + there is no warranty for the work (except to the extent that warranties + are provided), that licensees may convey the work under this License, and + how to view a copy of this License. If the interface presents a list of + user commands or options, such as a menu, a prominent item in the list + meets this criterion. + + 1. Source Code. + + The “source code” for a work means the preferred form of the work for + making modifications to it. “Object code” means any non-source form of a + work. + + A “Standard Interface” means an interface that either is an official + standard defined by a recognized standards body, or, in the case of + interfaces specified for a particular programming language, one that is + widely used among developers working in that language. The “System + Libraries” of an executable work include anything, other than the work as + a whole, that (a) is included in the normal form of packaging a Major + Component, but which is not part of that Major Component, and (b) serves + only to enable use of the work with that Major Component, or to implement + a Standard Interface for which an implementation is available to the + public in source code form. A “Major Component”, in this context, means a + major essential component (kernel, window system, and so on) of the + specific operating system (if any) on which the executable work runs, or + a compiler used to produce the work, or an object code interpreter used + to run it. + + The “Corresponding Source” for a work in object code form means all the + source code needed to generate, install, and (for an executable work) run + the object code and to modify the work, including scripts to control + those activities. However, it does not include the work's System + Libraries, or general-purpose tools or generally available free programs + which are used unmodified in performing those activities but which are + not part of the work. For example, Corresponding Source includes + interface definition files associated with source files for the work, and + the source code for shared libraries and dynamically linked subprograms + that the work is specifically designed to require, such as by intimate + data communication or control flow between those subprograms and other + parts of the work. + + The Corresponding Source need not include anything that users can + regenerate automatically from other parts of the Corresponding Source. + + The Corresponding Source for a work in source code form is that same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of + copyright on the Program, and are irrevocable provided the stated + conditions are met. This License explicitly affirms your unlimited + permission to run the unmodified Program, subject to section 13. The + output from running a covered work is covered by this License only if the + output, given its content, constitutes a covered work. This License + acknowledges your rights of fair use or other equivalent, as provided by + copyright law. Subject to section 13, you may make, run and propagate + covered works that you do not convey, without conditions so long as your + license otherwise remains in force. You may convey covered works to + others for the sole purpose of having them make modifications exclusively + for you, or provide you with facilities for running those works, provided + that you comply with the terms of this License in conveying all + material for which you do not control copyright. Those thus making or + running the covered works for you must do so exclusively on your + behalf, under your direction and control, on terms that prohibit them + from making any copies of your copyrighted material outside their + relationship with you. + + Conveying under any other circumstances is permitted solely under the + conditions stated below. Sublicensing is not allowed; section 10 makes it + unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological + measure under any applicable law fulfilling obligations under article 11 + of the WIPO copyright treaty adopted on 20 December 1996, or similar laws + prohibiting or restricting circumvention of such measures. + + When you convey a covered work, you waive any legal power to forbid + circumvention of technological measures to the extent such circumvention is + effected by exercising rights under this License with respect to the + covered work, and you disclaim any intention to limit operation or + modification of the work as a means of enforcing, against the work's users, + your or third parties' legal rights to forbid circumvention of + technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you + receive it, in any medium, provided that you conspicuously and + appropriately publish on each copy an appropriate copyright notice; keep + intact all notices stating that this License and any non-permissive terms + added in accord with section 7 apply to the code; keep intact all notices + of the absence of any warranty; and give all recipients a copy of this + License along with the Program. You may charge any price or no price for + each copy that you convey, and you may offer support or warranty + protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to + produce it from the Program, in the form of source code under the terms + of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, + and giving a relevant date. + + b) The work must carry prominent notices stating that it is released + under this License and any conditions added under section 7. This + requirement modifies the requirement in section 4 to “keep intact all + notices”. + + c) You must license the entire work, as a whole, under this License to + anyone who comes into possession of a copy. This License will therefore + apply, along with any applicable section 7 additional terms, to the + whole of the work, and all its parts, regardless of how they are + packaged. This License gives no permission to license the work in any + other way, but it does not invalidate such permission if you have + separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your work + need not make them do so. + + A compilation of a covered work with other separate and independent + works, which are not by their nature extensions of the covered work, and + which are not combined with it such as to form a larger program, in or on + a volume of a storage or distribution medium, is called an “aggregate” if + the compilation and its resulting copyright are not used to limit the + access or legal rights of the compilation's users beyond what the + individual works permit. Inclusion of a covered work in an aggregate does + not cause this License to apply to the other parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms of + sections 4 and 5, provided that you also convey the machine-readable + Corresponding Source under the terms of this License, in one of these + ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium customarily + used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a written + offer, valid for at least three years and valid for as long as you + offer spare parts or customer support for that product model, to give + anyone who possesses the object code either (1) a copy of the + Corresponding Source for all the software in the product that is + covered by this License, on a durable physical medium customarily used + for software interchange, for a price no more than your reasonable cost + of physically performing this conveying of source, or (2) access to + copy the Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This alternative is + allowed only occasionally and noncommercially, and only if you received + the object code with such an offer, in accord with subsection 6b. + + d) Convey the object code by offering access from a designated place + (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to copy + the object code is a network server, the Corresponding Source may be on + a different server (operated by you or a third party) that supports + equivalent copying facilities, provided you maintain clear directions + next to the object code saying where to find the Corresponding Source. + Regardless of what server hosts the Corresponding Source, you remain + obligated to ensure that it is available for as long as needed to + satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided you + inform other peers where the object code and Corresponding Source of + the work are being offered to the general public at no charge under + subsection 6d. + + A separable portion of the object code, whose source code is excluded + from the Corresponding Source as a System Library, need not be included + in conveying the object code work. + + A “User Product” is either (1) a “consumer product”, which means any + tangible personal property which is normally used for personal, family, + or household purposes, or (2) anything designed or sold for incorporation + into a dwelling. In determining whether a product is a consumer product, + doubtful cases shall be resolved in favor of coverage. For a particular + product received by a particular user, “normally used” refers to a + typical or common use of that class of product, regardless of the status + of the particular user or of the way in which the particular user + actually uses, or expects or is expected to use, the product. A product + is a consumer product regardless of whether the product has substantial + commercial, industrial or non-consumer uses, unless such uses represent + the only significant mode of use of the product. + + “Installation Information” for a User Product means any methods, + procedures, authorization keys, or other information required to install + and execute modified versions of a covered work in that User Product from + a modified version of its Corresponding Source. The information must + suffice to ensure that the continued functioning of the modified object + code is in no case prevented or interfered with solely because + modification has been made. + + If you convey an object code work under this section in, or with, or + specifically for use in, a User Product, and the conveying occurs as part + of a transaction in which the right of possession and use of the User + Product is transferred to the recipient in perpetuity or for a fixed term + (regardless of how the transaction is characterized), the Corresponding + Source conveyed under this section must be accompanied by the + Installation Information. But this requirement does not apply if neither + you nor any third party retains the ability to install modified object + code on the User Product (for example, the work has been installed in + ROM). + + The requirement to provide Installation Information does not include a + requirement to continue to provide support service, warranty, or updates + for a work that has been modified or installed by the recipient, or for + the User Product in which it has been modified or installed. Access + to a network may be denied when the modification itself materially + and adversely affects the operation of the network or violates the + rules and protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, in + accord with this section must be in a format that is publicly documented + (and with an implementation available to the public in source code form), + and must require no special password or key for unpacking, reading or + copying. + + 7. Additional Terms. + + “Additional permissions” are terms that supplement the terms of this + License by making exceptions from one or more of its conditions. + Additional permissions that are applicable to the entire Program shall be + treated as though they were included in this License, to the extent that + they are valid under applicable law. If additional permissions apply only + to part of the Program, that part may be used separately under those + permissions, but the entire Program remains governed by this License + without regard to the additional permissions. When you convey a copy of + a covered work, you may at your option remove any additional permissions + from that copy, or from any part of it. (Additional permissions may be + written to require their own removal in certain cases when you modify the + work.) You may place additional permissions on material, added by you to + a covered work, for which you have or can give appropriate copyright + permission. + + Notwithstanding any other provision of this License, for material you add + to a covered work, you may (if authorized by the copyright holders of + that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some trade + names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that material + by anyone who conveys the material (or modified versions of it) with + contractual assumptions of liability to the recipient, for any + liability that these contractual assumptions directly impose on those + licensors and authors. + + All other non-permissive additional terms are considered “further + restrictions” within the meaning of section 10. If the Program as you + received it, or any part of it, contains a notice stating that it is + governed by this License along with a term that is a further restriction, + you may remove that term. If a license document contains a further + restriction but permits relicensing or conveying under this License, you + may add to a covered work material governed by the terms of that license + document, provided that the further restriction does not survive such + relicensing or conveying. + + If you add terms to a covered work in accord with this section, you must + place, in the relevant source files, a statement of the additional terms + that apply to those files, or a notice indicating where to find the + applicable terms. Additional terms, permissive or non-permissive, may be + stated in the form of a separately written license, or stated as + exceptions; the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly + provided under this License. Any attempt otherwise to propagate or modify + it is void, and will automatically terminate your rights under this + License (including any patent licenses granted under the third paragraph + of section 11). + + However, if you cease all violation of this License, then your license + from a particular copyright holder is reinstated (a) provisionally, + unless and until the copyright holder explicitly and finally terminates + your license, and (b) permanently, if the copyright holder fails to + notify you of the violation by some reasonable means prior to 60 days + after the cessation. + + Moreover, your license from a particular copyright holder is reinstated + permanently if the copyright holder notifies you of the violation by some + reasonable means, this is the first time you have received notice of + violation of this License (for any work) from that copyright holder, and + you cure the violation prior to 30 days after your receipt of the notice. + + Termination of your rights under this section does not terminate the + licenses of parties who have received copies or rights from you under + this License. If your rights have been terminated and not permanently + reinstated, you do not qualify to receive new licenses for the same + material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or run a + copy of the Program. Ancillary propagation of a covered work occurring + solely as a consequence of using peer-to-peer transmission to receive a + copy likewise does not require acceptance. However, nothing other than + this License grants you permission to propagate or modify any covered + work. These actions infringe copyright if you do not accept this License. + Therefore, by modifying or propagating a covered work, you indicate your + acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically receives + a license from the original licensors, to run, modify and propagate that + work, subject to this License. You are not responsible for enforcing + compliance by third parties with this License. + + An “entity transaction” is a transaction transferring control of an + organization, or substantially all assets of one, or subdividing an + organization, or merging organizations. If propagation of a covered work + results from an entity transaction, each party to that transaction who + receives a copy of the work also receives whatever licenses to the work + the party's predecessor in interest had or could give under the previous + paragraph, plus a right to possession of the Corresponding Source of the + work from the predecessor in interest, if the predecessor has it or can + get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the rights + granted or affirmed under this License. For example, you may not impose a + license fee, royalty, or other charge for exercise of rights granted + under this License, and you may not initiate litigation (including a + cross-claim or counterclaim in a lawsuit) alleging that any patent claim + is infringed by making, using, selling, offering for sale, or importing + the Program or any portion of it. + + 11. Patents. + + A “contributor” is a copyright holder who authorizes use under this + License of the Program or a work on which the Program is based. The work + thus licensed is called the contributor's “contributor version”. + + A contributor's “essential patent claims” are all patent claims owned or + controlled by the contributor, whether already acquired or hereafter + acquired, that would be infringed by some manner, permitted by this + License, of making, using, or selling its contributor version, but do not + include claims that would be infringed only as a consequence of further + modification of the contributor version. For purposes of this definition, + “control” includes the right to grant patent sublicenses in a manner + consistent with the requirements of this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free + patent license under the contributor's essential patent claims, to make, + use, sell, offer for sale, import and otherwise run, modify and propagate + the contents of its contributor version. + + In the following three paragraphs, a “patent license” is any express + agreement or commitment, however denominated, not to enforce a patent + (such as an express permission to practice a patent or covenant not to + sue for patent infringement). To “grant” such a patent license to a party + means to make such an agreement or commitment not to enforce a patent + against the party. + + If you convey a covered work, knowingly relying on a patent license, and + the Corresponding Source of the work is not available for anyone to copy, + free of charge and under the terms of this License, through a publicly + available network server or other readily accessible means, then you must + either (1) cause the Corresponding Source to be so available, or (2) + arrange to deprive yourself of the benefit of the patent license for this + particular work, or (3) arrange, in a manner consistent with the + requirements of this License, to extend the patent license to downstream + recipients. “Knowingly relying” means you have actual knowledge that, but + for the patent license, your conveying the covered work in a country, or + your recipient's use of the covered work in a country, would infringe + one or more identifiable patents in that country that you have reason + to believe are valid. + + If, pursuant to or in connection with a single transaction or + arrangement, you convey, or propagate by procuring conveyance of, a + covered work, and grant a patent license to some of the parties receiving + the covered work authorizing them to use, propagate, modify or convey a + specific copy of the covered work, then the patent license you grant is + automatically extended to all recipients of the covered work and works + based on it. + + A patent license is “discriminatory” if it does not include within the + scope of its coverage, prohibits the exercise of, or is conditioned on + the non-exercise of one or more of the rights that are specifically + granted under this License. You may not convey a covered work if you are + a party to an arrangement with a third party that is in the business of + distributing software, under which you make payment to the third party + based on the extent of your activity of conveying the work, and under + which the third party grants, to any of the parties who would receive the + covered work from you, a discriminatory patent license (a) in connection + with copies of the covered work conveyed by you (or copies made from + those copies), or (b) primarily for and in connection with specific + products or compilations that contain the covered work, unless you + entered into that arrangement, or that patent license was granted, prior + to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting any + implied license or other defenses to infringement that may otherwise be + available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot use, + propagate or convey a covered work so as to satisfy simultaneously your + obligations under this License and any other pertinent obligations, then + as a consequence you may not use, propagate or convey it at all. For + example, if you agree to terms that obligate you to collect a royalty for + further conveying from those to whom you convey the Program, the only way + you could satisfy both those terms and this License would be to refrain + entirely from conveying the Program. + + 13. Offering the Program as a Service. + + If you make the functionality of the Program or a modified version + available to third parties as a service, you must make the Service Source + Code available via network download to everyone at no charge, under the + terms of this License. Making the functionality of the Program or + modified version available to third parties as a service includes, + without limitation, enabling third parties to interact with the + functionality of the Program or modified version remotely through a + computer network, offering a service the value of which entirely or + primarily derives from the value of the Program or modified version, or + offering a service that accomplishes for users the primary purpose of the + Program or modified version. + + “Service Source Code” means the Corresponding Source for the Program or + the modified version, and the Corresponding Source for all programs that + you use to make the Program or modified version available as a service, + including, without limitation, management software, user interfaces, + application program interfaces, automation software, monitoring software, + backup software, storage software and hosting software, all such that a + user could run an instance of the service using the Service Source Code + you make available. + + 14. Revised Versions of this License. + + MongoDB, Inc. may publish revised and/or new versions of the Server Side + Public License from time to time. Such new versions will be similar in + spirit to the present version, but may differ in detail to address new + problems or concerns. + + Each version is given a distinguishing version number. If the Program + specifies that a certain numbered version of the Server Side Public + License “or any later version” applies to it, you have the option of + following the terms and conditions either of that numbered version or of + any later version published by MongoDB, Inc. If the Program does not + specify a version number of the Server Side Public License, you may + choose any version ever published by MongoDB, Inc. + + If the Program specifies that a proxy can decide which future versions of + the Server Side Public License can be used, that proxy's public statement + of acceptance of a version permanently authorizes you to choose that + version for the Program. + + Later license versions may give you additional or different permissions. + However, no additional obligations are imposed on any author or copyright + holder as a result of your choosing to follow a later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY + APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY + OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM + IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF + ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS + THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING + ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF + THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO + LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU + OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER + PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided above + cannot be given local legal effect according to their terms, reviewing + courts shall apply local law that most closely approximates an absolute + waiver of all civil liability in connection with the Program, unless a + warranty or assumption of liability accompanies a copy of the Program in + return for a fee. + + END OF TERMS AND CONDITIONS + +This product also includes the MongoDB Crypt library (mongodb_crypt_v1) +which is covered by the MongoDB Enterprise Agreement. diff --git a/packages/mocked-compass/THIRD-PARTY-NOTICES.md b/packages/mocked-compass/THIRD-PARTY-NOTICES.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/mocked-compass/app-icons/README.md b/packages/mocked-compass/app-icons/README.md new file mode 100644 index 00000000000..a7762e80201 --- /dev/null +++ b/packages/mocked-compass/app-icons/README.md @@ -0,0 +1 @@ +Application icons and installer images for different platforms. diff --git a/packages/mocked-compass/app-icons/darwin/background.png b/packages/mocked-compass/app-icons/darwin/background.png new file mode 100644 index 00000000000..2ebabff5deb Binary files /dev/null and b/packages/mocked-compass/app-icons/darwin/background.png differ diff --git a/packages/mocked-compass/app-icons/darwin/background@2x.png b/packages/mocked-compass/app-icons/darwin/background@2x.png new file mode 100644 index 00000000000..0b001016e41 Binary files /dev/null and b/packages/mocked-compass/app-icons/darwin/background@2x.png differ diff --git a/packages/mocked-compass/app-icons/darwin/mongodb-compass-logo-beta.icns b/packages/mocked-compass/app-icons/darwin/mongodb-compass-logo-beta.icns new file mode 100644 index 00000000000..0b3464cce10 Binary files /dev/null and b/packages/mocked-compass/app-icons/darwin/mongodb-compass-logo-beta.icns differ diff --git a/packages/mocked-compass/app-icons/darwin/mongodb-compass-logo-dev.icns b/packages/mocked-compass/app-icons/darwin/mongodb-compass-logo-dev.icns new file mode 100644 index 00000000000..0c2013a5382 Binary files /dev/null and b/packages/mocked-compass/app-icons/darwin/mongodb-compass-logo-dev.icns differ diff --git a/packages/mocked-compass/app-icons/darwin/mongodb-compass-logo-stable.icns b/packages/mocked-compass/app-icons/darwin/mongodb-compass-logo-stable.icns new file mode 100644 index 00000000000..c49eb6c1aa5 Binary files /dev/null and b/packages/mocked-compass/app-icons/darwin/mongodb-compass-logo-stable.icns differ diff --git a/packages/mocked-compass/app-icons/linux/mongodb-compass-logo-beta.png b/packages/mocked-compass/app-icons/linux/mongodb-compass-logo-beta.png new file mode 100644 index 00000000000..188c7899bf7 Binary files /dev/null and b/packages/mocked-compass/app-icons/linux/mongodb-compass-logo-beta.png differ diff --git a/packages/mocked-compass/app-icons/linux/mongodb-compass-logo-dev.png b/packages/mocked-compass/app-icons/linux/mongodb-compass-logo-dev.png new file mode 100644 index 00000000000..a1fbe8c15a2 Binary files /dev/null and b/packages/mocked-compass/app-icons/linux/mongodb-compass-logo-dev.png differ diff --git a/packages/mocked-compass/app-icons/linux/mongodb-compass-logo-stable.png b/packages/mocked-compass/app-icons/linux/mongodb-compass-logo-stable.png new file mode 100644 index 00000000000..110a3460232 Binary files /dev/null and b/packages/mocked-compass/app-icons/linux/mongodb-compass-logo-stable.png differ diff --git a/packages/mocked-compass/app-icons/win32/background.jpg b/packages/mocked-compass/app-icons/win32/background.jpg new file mode 100644 index 00000000000..90b627751cd Binary files /dev/null and b/packages/mocked-compass/app-icons/win32/background.jpg differ diff --git a/packages/mocked-compass/app-icons/win32/banner.jpg b/packages/mocked-compass/app-icons/win32/banner.jpg new file mode 100644 index 00000000000..e08bb7cf3f0 Binary files /dev/null and b/packages/mocked-compass/app-icons/win32/banner.jpg differ diff --git a/packages/mocked-compass/app-icons/win32/mongodb-compass-installer-loading.gif b/packages/mocked-compass/app-icons/win32/mongodb-compass-installer-loading.gif new file mode 100644 index 00000000000..15e9b4b91a8 Binary files /dev/null and b/packages/mocked-compass/app-icons/win32/mongodb-compass-installer-loading.gif differ diff --git a/packages/mocked-compass/app-icons/win32/mongodb-compass-logo-beta.ico b/packages/mocked-compass/app-icons/win32/mongodb-compass-logo-beta.ico new file mode 100644 index 00000000000..ca6c8c13a84 Binary files /dev/null and b/packages/mocked-compass/app-icons/win32/mongodb-compass-logo-beta.ico differ diff --git a/packages/mocked-compass/app-icons/win32/mongodb-compass-logo-dev.ico b/packages/mocked-compass/app-icons/win32/mongodb-compass-logo-dev.ico new file mode 100644 index 00000000000..1722e2237e4 Binary files /dev/null and b/packages/mocked-compass/app-icons/win32/mongodb-compass-logo-dev.ico differ diff --git a/packages/mocked-compass/app-icons/win32/mongodb-compass-logo-stable.ico b/packages/mocked-compass/app-icons/win32/mongodb-compass-logo-stable.ico new file mode 100644 index 00000000000..fe134e8cf68 Binary files /dev/null and b/packages/mocked-compass/app-icons/win32/mongodb-compass-logo-stable.ico differ diff --git a/packages/mocked-compass/package.json b/packages/mocked-compass/package.json new file mode 100644 index 00000000000..b6270cf5de7 --- /dev/null +++ b/packages/mocked-compass/package.json @@ -0,0 +1,147 @@ +{ + "name": "@mongodb-js/mocked-compass", + "description": "A fake version of Compass far in the future for testing auto-update", + "author": { + "name": "MongoDB Inc", + "email": "compass@mongodb.com" + }, + "private": true, + "bugs": { + "url": "https://jira.mongodb.org/projects/COMPASS/issues", + "email": "compass@mongodb.com" + }, + "homepage": "https://github.com/mongodb-js/compass", + "version": "99.0.0", + "main": "build/main.js", + "repository": { + "type": "git", + "url": "https://github.com/mongodb-js/compass.git" + }, + "license": "SSPL", + "config": { + "hadron": { + "endpoint": "https://compass.mongodb.com", + "protocols": [ + { + "name": "MongoDB Protocol", + "schemes": [ + "mongodb" + ] + }, + { + "name": "MongoDB+SRV Protocol", + "schemes": [ + "mongodb+srv" + ] + } + ], + "distributions": { + "compass": { + "name": "mongodb-compass", + "productName": "MongoDB Compass", + "bundleId": "com.mongodb.compass", + "plugins-directory": ".mongodb/compass/plugins", + "upgradeCode": "0152273D-2F9F-4913-B67F-0FCD3557FFD1" + }, + "compass-readonly": { + "name": "mongodb-compass-readonly", + "productName": "MongoDB Compass Readonly", + "bundleId": "com.mongodb.compass.readonly", + "plugins-directory": ".mongodb/compass-readonly/plugins", + "upgradeCode": "2176EC1D-EF71-49D4-B3B4-9E15B289D79A", + "readonly": true + } + }, + "build": { + "win32": { + "icon": { + "stable": "app-icons/win32/mongodb-compass-logo-stable.ico", + "beta": "app-icons/win32/mongodb-compass-logo-beta.ico", + "dev": "app-icons/win32/mongodb-compass-logo-dev.ico" + }, + "favicon_url": "https://compass.mongodb.com/favicon.ico", + "loading_gif": "app-icons/win32/mongodb-compass-installer-loading.gif", + "background": "app-icons/win32/background.jpg", + "banner": "app-icons/win32/banner.jpg" + }, + "darwin": { + "icon": { + "stable": "app-icons/darwin/mongodb-compass-logo-stable.icns", + "beta": "app-icons/darwin/mongodb-compass-logo-beta.icns", + "dev": "app-icons/darwin/mongodb-compass-logo-dev.icns" + }, + "dmg_background": "app-icons/darwin/background.png", + "app_category_type": "public.app-category.productivity" + }, + "linux": { + "icon": { + "stable": "app-icons/linux/mongodb-compass-logo-stable.png", + "beta": "app-icons/linux/mongodb-compass-logo-beta.png", + "dev": "app-icons/linux/mongodb-compass-logo-dev.png" + }, + "deb_section": "Databases", + "rpm_categories": [ + "Office", + "Database", + "Building", + "Debugger", + "IDE", + "GUIDesigner", + "Profiling" + ] + } + }, + "asar": { + "unpack": [] + }, + "rebuild": { + "onlyModules": [] + }, + "macosEntitlements": "./scripts/macos-entitlements.xml" + } + }, + "scripts": { + "typecheck": "tsc -p tsconfig-lint.json --noEmit", + "eslint": "eslint", + "prettier": "prettier", + "lint": "npm run eslint . && npm run prettier -- --check .", + "depcheck": "depcheck", + "check": "npm run typecheck && npm run lint && npm run depcheck", + "test": "mocha", + "test-cov": "nyc --compact=false --produce-source-map=false -x \"**/*.spec.*\" --reporter=lcov --reporter=text --reporter=html npm run test", + "test-watch": "npm run test -- --watch", + "test-ci": "npm run test-cov", + "reformat": "npm run eslint . -- --fix && npm run prettier -- --write .", + "prestart": "npm run compile --workspace=@mongodb-js/webpack-config-compass", + "start": "HADRON_DISTRIBUTION=${HADRON_DISTRIBUTION:-compass} npm run webpack serve -- --mode development", + "webpack": "webpack-compass", + "compile": "npm run webpack -- --mode production", + "package-compass-nocompile": "HADRON_APP_VERSION=99.0.0-dev DEV_VERSION_IDENTIFIER='' hadron-build release", + "prepackage-compass": "npm run compile", + "package-compass": "npm run package-compass-nocompile", + "package-compass-debug": "DEBUG='hadron*,compass*' HADRON_SKIP_INSTALLER=true NO_ASAR=true npm run package-compass", + "upload": "hadron-build upload", + "download": "hadron-build download", + "evergreen-expansions": "hadron-build info --format=yaml --flatten > expansions.yml", + "build-info": "hadron-build info" + }, + "devDependencies": { + "@mongodb-js/eslint-config-compass": "^1.1.9", + "@mongodb-js/mocha-config-compass": "^1.4.4", + "@mongodb-js/prettier-config-compass": "^1.0.4", + "@mongodb-js/sbom-tools": "^0.7.0", + "@mongodb-js/tsconfig-compass": "^1.0.7", + "@mongodb-js/webpack-config-compass": "^1.4.9", + "@types/mocha": "^9.0.0", + "@types/sinon-chai": "^3.2.5", + "depcheck": "^1.4.1", + "electron": "^32.2.7", + "eslint": "^7.25.0", + "hadron-build": "^25.5.17", + "mocha": "^10.2.0", + "nyc": "^15.1.0", + "prettier": "^2.7.1", + "sinon": "^17.0.1", + "typescript": "^5.0.4" + } +} diff --git a/packages/mocked-compass/src/main/index.spec.tsx b/packages/mocked-compass/src/main/index.spec.tsx new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/mocked-compass/src/main/index.ts b/packages/mocked-compass/src/main/index.ts new file mode 100644 index 00000000000..54385b8fba8 --- /dev/null +++ b/packages/mocked-compass/src/main/index.ts @@ -0,0 +1,16 @@ +import electron from 'electron'; +import fs from 'fs'; +import path from 'path'; + +electron.app.once('ready', () => { + // Signal that the app got ready by touching a file + const appDataPath = electron.app.getAppPath(); + const p = path.resolve(appDataPath, '../../../../ready.signal'); + // eslint-disable-next-line no-console + console.log('Writing signal to', p); + fs.writeFileSync(p, 'Hello from a future Compass!', { + encoding: 'utf8', + }); + // Exit ... + process.exit(); +}); diff --git a/packages/mocked-compass/tsconfig-lint.json b/packages/mocked-compass/tsconfig-lint.json new file mode 100644 index 00000000000..21ad88e5082 --- /dev/null +++ b/packages/mocked-compass/tsconfig-lint.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["**/*"], + "exclude": ["**/node_modules", "**/.*/", "dist", "build"] +} diff --git a/packages/mocked-compass/tsconfig.json b/packages/mocked-compass/tsconfig.json new file mode 100644 index 00000000000..e5a5bcfe46f --- /dev/null +++ b/packages/mocked-compass/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "@mongodb-js/tsconfig-compass/tsconfig.common.json", + "compilerOptions": {}, + "include": ["src/**/*"], + "exclude": ["./src/**/*.spec.*"] +} diff --git a/packages/mocked-compass/webpack.config.js b/packages/mocked-compass/webpack.config.js new file mode 100644 index 00000000000..691f4baab84 --- /dev/null +++ b/packages/mocked-compass/webpack.config.js @@ -0,0 +1,122 @@ +'use strict'; +// @ts-check +const path = require('path'); +// @ts-ignore +const HadronBuildTarget = require('hadron-build/lib/target'); +const { WebpackDependenciesPlugin } = require('@mongodb-js/sbom-tools'); + +const { + createElectronMainConfig, + webpackArgsWithDefaults, + isServe, + webpack, + merge, +} = require('@mongodb-js/webpack-config-compass'); + +module.exports = (_env, args) => { + const opts = { + ...webpackArgsWithDefaults(args), + outputPath: path.resolve(__dirname, 'build'), + hot: true, + }; + + process.env.NODE_ENV = opts.nodeEnv; + + const mainConfig = createElectronMainConfig({ + ...opts, + // Explicitly provide entry name and outputFilename so that it's not changed + // between dev, prod, or any other build mode. It's important for the main + // entrypoint as it would be require additional logic for electron to start + // the app correctly. Having a stable name allows us to avoid this + entry: { main: path.resolve(__dirname, 'src', 'main', 'index.ts') }, + outputFilename: '[name].js', + }); + + const externals = { + // Runtime implementation depends on worker file existing near the library + // main import and for that reason it needs to stay external to compass (and + // compass-shell plugin) + '@mongosh/node-runtime-worker-thread': + 'commonjs2 @mongosh/node-runtime-worker-thread', + }; + + // Having persistent build cache makes initial dev build slower, but + // subsequent builds much much faster + const cache = { + /** @type {'filesystem'} */ + type: 'filesystem', + allowCollectingMemory: opts.nodeEnv !== 'production', + buildDependencies: { + config: [__filename], + }, + }; + + const snapshot = { + unmanagedPaths: [ + path.resolve('..', '..', 'node_modules', '@mongosh', 'browser-repl'), + ], + }; + + const target = new HadronBuildTarget(__dirname); + + // This should be provided either with env vars directly or from hadron-build + // when application is compiled + const hadronEnvConfig = { + // Required env variables with defaults + HADRON_APP_VERSION: target.version, + HADRON_DISTRIBUTION: target.distribution, + HADRON_PRODUCT: target.name, + HADRON_PRODUCT_NAME: isServe(opts) + ? `${target.productName} Local` + : target.productName, + HADRON_READONLY: String(target.readonly), + HADRON_ISOLATED: String(target.isolated), + HADRON_CHANNEL: target.channel, + HADRON_AUTO_UPDATE_ENDPOINT: target.autoUpdateBaseUrl, + // Optional env variables that will be set only by Evergreen CI for publicly + // published releases + HADRON_METRICS_INTERCOM_APP_ID: null, + HADRON_METRICS_SEGMENT_API_KEY: null, + HADRON_METRICS_SEGMENT_HOST: null, + }; + + const compileOnlyPlugins = isServe(opts) + ? [] + : [ + // ignoring type here as JSDoc still uses webpack@4 that is + // resolved from plugins not yet updated to the new config + /** @type {any} */ ( + new WebpackDependenciesPlugin({ + outputFilename: path.resolve( + __dirname, + '..', + '..', + '.sbom', + 'dependencies.json' + ), + includeExternalProductionDependencies: true, + includePackages: ['electron'], + }) + ), + ]; + + return [ + merge(mainConfig, { + cache, + snapshot, + externals, + plugins: [ + new webpack.EnvironmentPlugin(hadronEnvConfig), + // In local dev mode, this flag is used to disable web security when + // creating windows. It allows @mongosh/node-runtime-worker-thread + // worker to load itself from the file path on the localhost + new webpack.DefinePlugin({ + 'process.env.DISABLE_ELECTRON_WEB_SECURITY': JSON.stringify( + isServe(opts) ? '1' : '0' + ), + }), + ...compileOnlyPlugins, + ], + }), + ]; +};