From 9e870b08a7802ca0132d6fd99a7d89cfdb8314cb Mon Sep 17 00:00:00 2001 From: Paulo Castro Date: Sat, 15 Feb 2020 20:07:09 +0000 Subject: [PATCH] Add tests for project directory validation Change-type: patch --- tests/commands/build.spec.ts | 23 +++++++++ tests/commands/deploy.spec.ts | 25 +++++++++ tests/commands/push.spec.ts | 95 +++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) diff --git a/tests/commands/build.spec.ts b/tests/commands/build.spec.ts index 35f984b6..d3a8a0f3 100644 --- a/tests/commands/build.spec.ts +++ b/tests/commands/build.spec.ts @@ -18,6 +18,7 @@ // tslint:disable-next-line:no-var-requires require('../config-tests'); // required for side effects +import { expect } from 'chai'; import * as _ from 'lodash'; import { fs } from 'mz'; import * as path from 'path'; @@ -30,6 +31,7 @@ import { testDockerBuildStream, } from '../docker-build'; import { DockerMock, dockerResponsePath } from '../docker-mock'; +import { cleanOutput, runCommand } from '../helpers'; const repoPath = path.normalize(path.join(__dirname, '..', '..')); const projectsPath = path.join(repoPath, 'tests', 'test-data', 'projects'); @@ -224,3 +226,24 @@ describe('balena build', function() { }); }); }); + +describe('balena build: project validation', function() { + it('should raise ExpectedError if a Dockerfile cannot be found', async () => { + const projectPath = path.join( + projectsPath, + 'docker-compose', + 'basic', + 'service2', + ); + const expectedErrorLines = [ + 'Error: no "Dockerfile[.*]", "docker-compose.yml" or "package.json" file', + `found in source folder "${projectPath}"`, + ]; + + const { out, err } = await runCommand(`build ${projectPath} -a testApp`); + expect( + cleanOutput(err).map(line => line.replace(/\s{2,}/g, ' ')), + ).to.include.members(expectedErrorLines); + expect(out).to.be.empty; + }); +}); diff --git a/tests/commands/deploy.spec.ts b/tests/commands/deploy.spec.ts index 5758bf6c..0b7227bf 100644 --- a/tests/commands/deploy.spec.ts +++ b/tests/commands/deploy.spec.ts @@ -18,12 +18,14 @@ // tslint:disable-next-line:no-var-requires require('../config-tests'); // required for side effects +import { expect } from 'chai'; import { fs } from 'mz'; import * as path from 'path'; import { BalenaAPIMock } from '../balena-api-mock'; import { ExpectedTarStreamFiles, testDockerBuildStream } from '../docker-build'; import { DockerMock, dockerResponsePath } from '../docker-mock'; +import { cleanOutput, runCommand } from '../helpers'; const repoPath = path.normalize(path.join(__dirname, '..', '..')); const projectsPath = path.join(repoPath, 'tests', 'test-data', 'projects'); @@ -129,3 +131,26 @@ describe('balena deploy', function() { }); }); }); + +describe('balena deploy: project validation', function() { + it('should raise ExpectedError if a Dockerfile cannot be found', async () => { + const projectPath = path.join( + projectsPath, + 'docker-compose', + 'basic', + 'service2', + ); + const expectedErrorLines = [ + 'Error: no "Dockerfile[.*]", "docker-compose.yml" or "package.json" file', + `found in source folder "${projectPath}"`, + ]; + + const { out, err } = await runCommand( + `deploy testApp --source ${projectPath}`, + ); + expect( + cleanOutput(err).map(line => line.replace(/\s{2,}/g, ' ')), + ).to.include.members(expectedErrorLines); + expect(out).to.be.empty; + }); +}); diff --git a/tests/commands/push.spec.ts b/tests/commands/push.spec.ts index e9bff5d3..fb7f6753 100644 --- a/tests/commands/push.spec.ts +++ b/tests/commands/push.spec.ts @@ -18,6 +18,7 @@ // tslint:disable-next-line:no-var-requires require('../config-tests'); // required for side effects +import { expect } from 'chai'; import { fs } from 'mz'; import * as path from 'path'; @@ -28,6 +29,7 @@ import { expectStreamNoCRLF, testPushBuildStream, } from '../docker-build'; +import { cleanOutput, runCommand } from '../helpers'; const repoPath = path.normalize(path.join(__dirname, '..', '..')); const projectsPath = path.join(repoPath, 'tests', 'test-data', 'projects'); @@ -242,3 +244,96 @@ describe('balena push', function() { }); }); }); + +describe('balena push: project validation', function() { + it('should raise ExpectedError if the project folder is not a directory', async () => { + const projectPath = path.join( + projectsPath, + 'docker-compose', + 'basic', + 'docker-compose.yml', + ); + const expectedErrorLines = [ + `Could not access source folder: "${projectPath}"`, + ]; + + const { out, err } = await runCommand( + `push testApp --source ${projectPath}`, + ); + expect( + cleanOutput(err).map(line => line.replace(/\s{2,}/g, ' ')), + ).to.include.members(expectedErrorLines); + expect(out).to.be.empty; + }); + + it('should raise ExpectedError if a Dockerfile cannot be found', async () => { + const projectPath = path.join( + projectsPath, + 'docker-compose', + 'basic', + 'service2', + ); + const expectedErrorLines = [ + 'Error: no "Dockerfile[.*]", "docker-compose.yml" or "package.json" file', + `found in source folder "${projectPath}"`, + ]; + + const { out, err } = await runCommand( + `push testApp --source ${projectPath}`, + ); + expect( + cleanOutput(err).map(line => line.replace(/\s{2,}/g, ' ')), + ).to.include.members(expectedErrorLines); + expect(out).to.be.empty; + }); + + it('should log a warning if a docker-compose.yml exists in a parent folder', async () => { + const projectPath = path.join( + projectsPath, + 'docker-compose', + 'basic', + 'service1', + ); + const expectedErrorLines = [ + 'The --nolive flag is only valid when pushing to a local mode device', + ]; + const expectedOutputLines = [ + '[Warn] "docker-compose.y[a]ml" file found in parent directory: please check', + "[Warn] that the correct folder was specified. (Suppress with '--noparent-check'.)", + ]; + + const { out, err } = await runCommand( + `push testApp --source ${projectPath} --nolive`, + ); + expect( + cleanOutput(err).map(line => line.replace(/\s{2,}/g, ' ')), + ).to.include.members(expectedErrorLines); + expect( + cleanOutput(out).map(line => line.replace(/\s{2,}/g, ' ')), + ).to.include.members(expectedOutputLines); + }); + + it('should suppress a parent folder check with --noparent-check', async () => { + const projectPath = path.join( + projectsPath, + 'docker-compose', + 'basic', + 'service1', + ); + const expectedErrorLines = [ + 'The --nolive flag is only valid when pushing to a local mode device', + ]; + const expectedOutputLines = [ + '[Warn] "docker-compose.y[a]ml" file found in parent directory: please check', + "[Warn] that the correct folder was specified. (Suppress with '--noparent-check'.)", + ]; + + const { out, err } = await runCommand( + `push testApp --source ${projectPath} --nolive --noparent-check`, + ); + expect( + cleanOutput(err).map(line => line.replace(/\s{2,}/g, ' ')), + ).to.include.members(expectedErrorLines); + expect(out).to.be.empty; + }); +});