From a26668913ccc9c31fc7c5655309bd7c667d6ee65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sat, 30 Jan 2021 20:15:09 +0100 Subject: [PATCH] scaffolder-backend: attempt to fix windows test errors in master --- .changeset/little-cherries-hug.md | 5 +++ plugins/scaffolder-backend/package.json | 2 ++ .../src/scaffolder/jobs/processor.test.ts | 32 ++++++++++++++++--- .../src/scaffolder/jobs/processor.ts | 6 ++-- .../src/scaffolder/stages/prepare/file.ts | 3 +- .../scaffolder/stages/prepare/github.test.ts | 2 +- .../stages/templater/cookiecutter.test.ts | 4 +-- .../stages/templater/cookiecutter.ts | 4 +-- 8 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 .changeset/little-cherries-hug.md diff --git a/.changeset/little-cherries-hug.md b/.changeset/little-cherries-hug.md new file mode 100644 index 0000000000..5fb42cbdad --- /dev/null +++ b/.changeset/little-cherries-hug.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Attempt to fix windows test errors in master diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 57b62be2cd..7af9f567e3 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -62,7 +62,9 @@ "@backstage/cli": "^0.5.0", "@backstage/test-utils": "^0.1.5", "@types/fs-extra": "^9.0.1", + "@types/mock-fs": "^4.13.0", "@types/supertest": "^2.0.8", + "mock-fs": "^4.13.0", "supertest": "^4.0.2", "yaml": "^1.10.0", "msw": "^0.21.2" diff --git a/plugins/scaffolder-backend/src/scaffolder/jobs/processor.test.ts b/plugins/scaffolder-backend/src/scaffolder/jobs/processor.test.ts index 5ff2bd1640..c782037ec8 100644 --- a/plugins/scaffolder-backend/src/scaffolder/jobs/processor.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/jobs/processor.test.ts @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import os from 'os'; -import { JobProcessor } from './processor'; import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; -import { StageInput } from './types'; -import { RequiredTemplateValues } from '../stages/templater'; import parseGitUrl from 'git-url-parse'; +import mockFs from 'mock-fs'; +import os from 'os'; +import { RequiredTemplateValues } from '../stages/templater'; +import { makeLogStream } from './logger'; +import { JobProcessor } from './processor'; +import { StageInput } from './types'; describe('JobProcessor', () => { const mockEntity: TemplateEntityV1alpha1 = { @@ -32,7 +34,7 @@ describe('JobProcessor', () => { name: 'graphql-starter', title: 'GraphQL Service', description: - 'A GraphQL starter template for backstage to get you up and running\nthe best pracices with GraphQL\n', + 'A GraphQL starter template for backstage to get you up and running\nthe best practices with GraphQL\n', uid: '9cf16bad-16e0-4213-b314-c4eec773c50b', etag: 'ZTkxMjUxMjUtYWY3Yi00MjU2LWFkYWMtZTZjNjU5ZjJhOWM2', @@ -71,6 +73,25 @@ describe('JobProcessor', () => { const workingDirectory = os.platform() === 'win32' ? 'C:\\tmp' : '/tmp'; + // NOTE(freben): Without this line, mock-fs makes winston/logform break. + // There are a number of reported issues with logform and its use of dynamic + // strings for imports. It confuses webpack. The basic fix is to trigger + // those imports before mock-fs runs. I wanted to add a mock dir + // 'node_modules': mockFs.passthrough(), but that doesn't seem to be a thing + // in mock-fs 4. + // Probable REAL fix: https://github.com/winstonjs/logform/pull/117 + makeLogStream({}); + + beforeEach(() => { + mockFs({ + [workingDirectory]: mockFs.directory(), + }); + }); + + afterEach(() => { + mockFs.restore(); + }); + describe('create', () => { it('creates should create a new job with a unique id', async () => { const processor = new JobProcessor(workingDirectory); @@ -157,6 +178,7 @@ describe('JobProcessor', () => { expect(processor.get(job.id)).toBe(job); }); }); + describe('process', () => { it('throws an error when the status of the job is not in pending state', async () => { const processor = new JobProcessor(workingDirectory); diff --git a/plugins/scaffolder-backend/src/scaffolder/jobs/processor.ts b/plugins/scaffolder-backend/src/scaffolder/jobs/processor.ts index 08423872f2..425fc07946 100644 --- a/plugins/scaffolder-backend/src/scaffolder/jobs/processor.ts +++ b/plugins/scaffolder-backend/src/scaffolder/jobs/processor.ts @@ -131,7 +131,7 @@ export class JobProcessor implements Processor { try { for (const stage of job.stages) { - // Create a logger for each stage so we can create seperate + // Create a logger for each stage so we can create separate // Streams for each step. const { logger, log, stream } = makeLogStream({ id: job.id, @@ -151,8 +151,8 @@ export class JobProcessor implements Processor { logStream: stream, }); - // If the handler returns something, then let's merge this onto the ontext - // For the next stage to use as it might be relevant. + // If the handler returns something, then let's merge this onto the + // context for the next stage to use as it might be relevant. if (handlerResponse) { job.context = { ...job.context, diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/prepare/file.ts b/plugins/scaffolder-backend/src/scaffolder/stages/prepare/file.ts index cbf81bdb06..4d49ba222e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/prepare/file.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/prepare/file.ts @@ -15,6 +15,7 @@ */ import fs from 'fs-extra'; import path from 'path'; +import { fileURLToPath } from 'url'; import { InputError } from '@backstage/backend-common'; import { PreparerBase, PreparerOptions } from './types'; @@ -27,7 +28,7 @@ export class FilePreparer implements PreparerBase { const checkoutDir = path.join(workspacePath, 'checkout'); await fs.ensureDir(checkoutDir); - const templatePath = url.slice('file://'.length); + const templatePath = fileURLToPath(url); await fs.copy(templatePath, checkoutDir, { recursive: true, diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/prepare/github.test.ts b/plugins/scaffolder-backend/src/scaffolder/stages/prepare/github.test.ts index a5fad5eaaa..301f015c1e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/prepare/github.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/prepare/github.test.ts @@ -60,7 +60,7 @@ describe('GitHubPreparer', () => { path.resolve(checkoutPath, 'templates', 'graphql-starter', 'template'), templatePath, ); - expect(fs.rmdir).toHaveBeenCalledWith('/tmp/template/.git'); + expect(fs.rmdir).toHaveBeenCalledWith(path.resolve(templatePath, '.git')); }); it('calls the clone command with the correct arguments for a repository when no path is provided', async () => { diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts index 8172986d69..1a3ad76499 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.test.ts @@ -227,8 +227,8 @@ describe('CookieCutter Templater', () => { args: expect.arrayContaining([ '--no-input', '-o', - 'tempdir/intermediate', - 'tempdir/template', + path.join('tempdir', 'intermediate'), + path.join('tempdir', 'template'), '--verbose', ]), logStream: stream, diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts index d19112561a..09d4faa37c 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/templater/cookiecutter.ts @@ -26,7 +26,7 @@ export class CookieCutter implements TemplaterBase { directory: string, ): Promise> { try { - return await fs.readJSON(`${directory}/cookiecutter.json`); + return await fs.readJSON(path.join(directory, 'cookiecutter.json')); } catch (ex) { if (ex.code !== 'ENOENT') { throw ex; @@ -54,7 +54,7 @@ export class CookieCutter implements TemplaterBase { ...values, }; - await fs.writeJSON(`${templateDir}/cookiecutter.json`, cookieInfo); + await fs.writeJSON(path.join(templateDir, 'cookiecutter.json'), cookieInfo); const cookieCutterInstalled = await commandExists('cookiecutter'); if (cookieCutterInstalled) {