From 70ed020c876c52786ce7b490392f6cc3170664dc Mon Sep 17 00:00:00 2001 From: Mario Nebl Date: Fri, 17 Dec 2021 10:11:51 +1100 Subject: [PATCH] fix: handle docker edge cases (#10501) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Before * When docker wasn't running: crashed with a TypeError * When any image without `RepoTags` was present: crashed with TypeError * Typo in recommended command ("playwight") * No indication of `PW_TEST_IMAGE` env var in error output
Docker not running ``` Using config at ~redacted/playwright.config.ts ERROR get /images/json 500 dial unix docker.raw.sock: connect: connection refused TypeError: Cannot read property 'find' of null at launchDockerGridAgent (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:67:26) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Object.launch (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:43:9) at GridServer.createAgent (~redacted/node_modules/playwright-core/lib/grid/gridServer.js:356:5) at launchDockerContainer (~redacted/node_modules/@playwright/test/lib/cli.js:259:3) at Runner._run (~redacted/node_modules/@playwright/test/lib/runner.js:236:98) Running 1 test using 1 worker test.ts:9:1 › some redacted description ERROR get /images/json 500 dial unix docker.raw.sock: connect: connection refused TypeError: Cannot read property 'find' of null at launchDockerGridAgent (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:67:26) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Object.launch (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js ```
Image without repo tags ``` Using config at ~redacted/playwright.config.ts TypeError: Cannot read property 'includes' of undefined at ~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:67:55 at Array.find () at launchDockerGridAgent (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:67:26) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Object.launch (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:43:9) at GridServer.createAgent (~redacted/node_modules/playwright-core/lib/grid/gridServer.js:356:5) at launchDockerContainer (~redacted/node_modules/@playwright/test/lib/cli.js:259:3) at Runner._run (~redacted/node_modules/@playwright/test/lib/runner.js:236:98) Running 1 test using 1 worker some-test.ts › some description TypeError: Cannot read property 'includes' of undefined at ~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:67:55 at Array.find () at launchDockerGridAgent (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:67:26) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Object.launch (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.j ✘ editor-editor-wysiwyg--editor-wysiwyg.vr.ts:9:1 › actual element matches expected element (26ms) 1) some-test.ts › some description ===== 'Grid agent creation failed' 1 failed some-test.ts › some description ====== ```
## After * Helpful error message if docker isn't running * Doesn't crash when local-only images in list * No typo in `playwright install docker-image` command * When other playwright images are found they are listed and `PW_TEST_IMAGE` is mentioned ### After: Docker not running ``` Using config at ~redacted/playwright.config.ts Error fetching json: Error: connect ECONNREFUSED /var/run/docker.sock Error: ╔═════════════════════════════════════════╗ ║ Failed to list docker images ║ ║ Please ensure docker daemon is running. ║ ║ ║ ║ <3 Playwright Team ║ ╚═════════════════════════════════════════╝ at launchDockerGridAgent (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:61:11) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Object.launch (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:43:9) at GridServer.createAgent (~redacted/node_modules/playwright-core/lib/grid/gridServer.js:356:5) at launchDockerContainer (~redacted/node_modules/@playwright/test/lib/cli.js:259:3) at Runner._run (~redacted/node_modules/@playwright/test/lib/runner.js:236:98) Running 1 test using 1 worker test.ts:9:1 › description Error fetching json: Error: connect ECONNREFUSED /var/run/docker.sock Error: ╔═════════════════════════════════════════╗ ║ Failed to list docker images ║ ║ Please ensure docker daemon is running. ║ ║ ║ ║ <3 Playwright Team ║ ╚═════════════════════════════════════════╝ at launchDockerGridAgent (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:61:11) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Object.launch (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.j ✘ test.ts:9:1 › description 1) test.ts:9:1 › description ===== 'Grid agent creation failed' 1 failed test.ts:9:1 › description ====== ``` ## After: No exact match found ``` Using config at ~redacted/playwright.config.ts Error: ╔════════════════════════════════════════════════════════════════════════════╗ ║ Failed to find mcr.microsoft.com/playwright:v1.16.3-focal docker image. ║ ║ ║ ║ Available images: ║ ║ - mcr.microsoft.com/playwright:v1.16.3 ║ ║ - mcr.microsoft.com/playwright:v1.16.2-focal ║ ║ ║ ║ Use available images via PWTEST_IMAGE_NAME environment variable: ║ ║ PWTEST_IMAGE_NAME=mcr.microsoft.com/playwright:v1.16.3 playwright test ║ ║ ║ ║ Alternatively, please pull docker image with the following command: ║ ║ ║ ║ npx playwright install docker-image ║ ║ ║ ║ <3 Playwright Team ║ ╚════════════════════════════════════════════════════════════════════════════╝ at launchDockerGridAgent (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:92:11) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Object.launch (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:43:9) at GridServer.createAgent (~redacted/node_modules/playwright-core/lib/grid/gridServer.js:356:5) at launchDockerContainer (~redacted/node_modules/@playwright/test/lib/cli.js:259:3) at Runner._run (~redacted/node_modules/@playwright/test/lib/runner.js:236:98) Running 1 test using 1 worker editor-editor-wysiwyg--editor-wysiwyg.vr.ts:9:1 › actual element matches expected element Error: ╔════════════════════════════════════════════════════════════════════════════╗ ║ Failed to find mcr.microsoft.com/playwright:v1.16.3-focal docker image. ║ ║ ║ ║ Available images: ║ ║ - mcr.microsoft.com/playwright:v1.16.3 ║ ║ - mcr.microsoft.com/playwright:v1.16.2-focal ║ ║ ║ ║ Use available images via PWTEST_IMAGE_NAME environment variable: ║ ║ PWTEST_IMAGE_NAME=mcr.microsoft.com/playwright:v1.16.3 playwright test ║ ║ ║ ║ Alternatively, please pull docker image with the following command: ║ ║ ║ ║ npx playwright install docker-image ║ ║ ║ ║ <3 Playwright Team ║ ╚════════════════════════════════════════════════════════════════════════════╝ at launchDockerGridAgent (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.js:92:11) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Object.launch (~redacted/node_modules/playwright-core/lib/grid/dockerGridFactory.j ✘ test.ts:9:1 › description 1) test.ts:9:1 › description ===== 'Grid agent creation failed' 1 failed test.ts:9:1 › description ====== ``` --- .../src/grid/dockerGridFactory.ts | 53 ++++++++++++++++--- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/packages/playwright-core/src/grid/dockerGridFactory.ts b/packages/playwright-core/src/grid/dockerGridFactory.ts index b9a9410d90..2a7f6c4dda 100644 --- a/packages/playwright-core/src/grid/dockerGridFactory.ts +++ b/packages/playwright-core/src/grid/dockerGridFactory.ts @@ -34,21 +34,58 @@ const dockerFactory: GridFactory = { export default dockerFactory; +interface DockerImage { + Containers: number; + Created: number; + Id: string; + Labels: null | Record; + ParentId: string; + RepoDigests: null | string[]; + RepoTags: null | string[]; + SharedSize: number; + Size: number; + VirtualSize: number; +} + async function launchDockerGridAgent(agentId: string, gridURL: string): Promise<{vncUrl: string }> { const gridPort = new URL(gridURL).port || '80'; - const images = await getJSON('/images/json'); - let imageName = process.env.PWTEST_IMAGE_NAME; - if (!imageName) { - const packageJson = require('../../package.json'); - imageName = `mcr.microsoft.com/playwright:v${packageJson.version}-focal`; + const images: DockerImage[] | null = await getJSON('/images/json'); + + if (!images) { + throw new Error(`\n` + utils.wrapInASCIIBox([ + `Failed to list docker images`, + `Please ensure docker is running.`, + ``, + `<3 Playwright Team`, + ].join('\n'), 1)); } - const pwImage = images.find((image: any) => image.RepoTags.includes(imageName)); + + const imageName = process.env.PWTEST_IMAGE_NAME ?? `mcr.microsoft.com/playwright:v${require('../../package.json').version}-focal`; + const pwImage = images.find(image => image.RepoTags?.includes(imageName)); + if (!pwImage) { + const pwImages = images + .map(image => image.RepoTags?.find(tag => tag.startsWith('mcr.microsoft.com/playwright:'))) + .filter((tag): tag is string => typeof tag === 'string'); + + const usage = pwImages.length > 0 ? [ + ``, + `Available images:`, + ...pwImages.map(image => `- ${image}`), + ``, + `Use available images via PWTEST_IMAGE_NAME environment variable:`, + ` PWTEST_IMAGE_NAME=${pwImages[0]} playwright test`, + `` + ] : []; + + const pullPrefix = pwImages.length > 0 ? 'Alternatively, please' : 'Please'; + throw new Error(`\n` + utils.wrapInASCIIBox([ `Failed to find ${imageName} docker image.`, - `Please pull docker image with the following command:`, + ...usage, + `${pullPrefix} pull docker image with the following command:`, ``, - ` npx playwight install docker-image`, + ` npx playwright install docker-image`, ``, `<3 Playwright Team`, ].join('\n'), 1));