Compare commits

...

9 Commits

Author SHA1 Message Date
2267906162 trying to debug build.spec.ts
Change-type: patch
2025-06-10 15:37:23 -04:00
3fe91dff3f forgot live
Change-type: patch
2025-06-10 15:06:48 -04:00
fc89eec6ab test
Change-type: patch
2025-06-10 14:50:31 -04:00
10af727450 no rewiremock.proxy
Change-type: patch
2025-06-10 14:29:57 -04:00
d8b3a90091 per file
Change-type: patch
2025-06-10 13:42:27 -04:00
b0ac9d9521 Deduplicate dependencies 2025-06-10 12:49:34 -04:00
8ceaa4735d Remove dependency rewire
Change-type: patch
2025-06-10 12:49:34 -04:00
5561c2cf2d Replace usage of rewire with rewiremock
Change-type: patch
2025-06-10 12:49:34 -04:00
0417ac5264 Add dependency rewiremock
Change-type: patch
2025-06-10 10:55:11 -04:00
8 changed files with 1115 additions and 572 deletions

1536
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load Diff

View File

@ -124,7 +124,6 @@
"@types/node-cleanup": "^2.1.2",
"@types/prettyjson": "^0.0.33",
"@types/progress-stream": "^2.0.2",
"@types/rewire": "^2.5.30",
"@types/rimraf": "^3.0.2",
"@types/semver": "^7.3.9",
"@types/shell-escape": "^0.2.0",
@ -155,7 +154,7 @@
"mock-require": "^3.0.3",
"nock": "^14.0.4",
"oclif": "^4.17.0",
"rewire": "^7.0.0",
"rewiremock": "^3.14.6",
"simple-git": "^3.14.1",
"sinon": "^19.0.0",
"string-to-stream": "^3.0.1",

View File

@ -3,12 +3,25 @@ import * as sinon from 'sinon';
import * as url from 'url';
import { getBalenaSdk } from '../../build/utils/lazy';
import tokens from './tokens';
import rewiremock from 'rewiremock';
const balena = getBalenaSdk();
describe('Utils:', async function () {
const rewire = await import('rewire');
const utils = rewire('../../build/auth/utils');
describe('Utils:', function () {
let utils: typeof import('../../build/auth/utils');
this.beforeEach(() => {
rewiremock.overrideEntryPoint(module);
utils = rewiremock(
'../../build/auth/utils',
) as unknown as typeof import('../../build/auth/utils');
rewiremock.enable();
});
this.afterEach(() => {
rewiremock.disable();
});
describe('.getDashboardLoginURL()', function () {
it('should eventually be a valid url', () =>
utils
@ -51,8 +64,8 @@ describe('Utils:', async function () {
return expect(promise).to.eventually.be.false;
});
it('should eventually be false if token is null', function () {
const promise = utils.loginIfTokenValid(null);
it('should eventually be false if token is undefined', function () {
const promise = utils.loginIfTokenValid(undefined);
return expect(promise).to.eventually.be.false;
});

View File

@ -17,7 +17,6 @@
import { expect } from 'chai';
import * as _ from 'lodash';
import * as mock from 'mock-require';
import { promises as fs } from 'fs';
import * as path from 'path';
@ -35,6 +34,7 @@ import {
getDockerignoreWarn2,
getDockerignoreWarn3,
} from '../projects';
import rewiremock from 'rewiremock';
const repoPath = path.normalize(path.join(__dirname, '..', '..'));
const projectsPath = path.join(repoPath, 'tests', 'test-data', 'projects');
@ -79,6 +79,10 @@ const commonComposeQueryParamsIntel = {
platform: 'linux/amd64',
};
const qemuModPath = '../../build/utils/qemu';
const fsModPath = 'fs';
const arch = 'rpi';
// "itSS" means "it() Skip Standalone"
const itSS = process.env.BALENA_CLI_TEST_TYPE === 'standalone' ? it.skip : it;
@ -87,7 +91,29 @@ describe('balena build', function () {
let docker: DockerMock;
const isWindows = process.platform === 'win32';
this.beforeEach(() => {
this.beforeEach(async () => {
const fsMod = await import(fsModPath);
const qemuMod = await import(qemuModPath);
const qemuBinPath = await qemuMod.getQemuPath(arch);
rewiremock.overrideEntryPoint(module);
// patch fs.access and fs.stat to pretend that a copy of the Qemu binary
// already exists locally, thus preventing a download during tests
rewiremock(fsModPath).with({
...fsMod,
promises: {
...fsMod.promises,
access: (p: string) =>
p === qemuBinPath ? undefined : fsMod.promises.access(p),
stat: (p: string) =>
p === qemuBinPath ? { size: 1 } : fsMod.promises.stat(p),
},
});
rewiremock(qemuModPath).with({
...qemuMod,
copyQemu: () => '',
});
rewiremock.enable();
api = new BalenaAPIMock();
docker = new DockerMock();
api.expectGetWhoAmI({ optional: true, persist: true });
@ -99,6 +125,7 @@ describe('balena build', function () {
// Check all expected api calls have been made and clean up.
api.done();
docker.done();
rewiremock.disable();
});
it('should create the expected tar stream (single container)', async () => {
@ -204,7 +231,7 @@ describe('balena build', function () {
});
});
// Skip Standalone because we patch the source code with `mock-require` to avoid
// Skip Standalone because we patch the source code via mock to avoid
// downloading and installing QEMU
itSS('should create the expected tar stream (--emulated)', async () => {
const projectPath = path.join(projectsPath, 'no-docker-compose', 'basic');
@ -253,50 +280,22 @@ describe('balena build', function () {
`[Info] Converting line endings CRLF -> LF for file: ${fname}`,
);
}
const arch = 'rpi';
const deviceType = 'raspberry-pi';
const fsModPath = 'fs';
const fsMod = await import(fsModPath);
const qemuModPath = '../../build/utils/qemu';
const qemuMod = await import(qemuModPath);
const qemuBinPath = await qemuMod.getQemuPath(arch);
try {
// patch fs.access and fs.stat to pretend that a copy of the Qemu binary
// already exists locally, thus preventing a download during tests
mock(fsModPath, {
...fsMod,
promises: {
...fsMod.promises,
access: (p: string) =>
p === qemuBinPath ? undefined : fsMod.promises.access(p),
stat: (p: string) =>
p === qemuBinPath ? { size: 1 } : fsMod.promises.stat(p),
},
});
mock(qemuModPath, {
...qemuMod,
copyQemu: () => '',
});
mock.reRequire('../../build/utils/qemu');
docker.expectGetInfo({ OperatingSystem: 'balenaOS 2.44.0+rev1' });
docker.expectGetManifestBusybox();
await testDockerBuildStream({
commandLine: `build ${projectPath} --emulated --deviceType ${deviceType} --arch ${arch}`,
dockerMock: docker,
expectedFilesByService: { main: expectedFiles },
expectedQueryParamsByService: {
main: Object.entries(commonQueryParamsArmV6),
},
expectedResponseLines,
projectPath,
responseBody,
responseCode: 200,
services: ['main'],
});
} finally {
mock.stop(fsModPath);
mock.stop(qemuModPath);
}
docker.expectGetInfo({ OperatingSystem: 'balenaOS 2.44.0+rev1' });
docker.expectGetManifestBusybox();
await testDockerBuildStream({
commandLine: `build ${projectPath} --emulated --deviceType ${deviceType} --arch ${arch}`,
dockerMock: docker,
expectedFilesByService: { main: expectedFiles },
expectedQueryParamsByService: {
main: Object.entries(commonQueryParamsArmV6),
},
expectedResponseLines,
projectPath,
responseBody,
responseCode: 200,
services: ['main'],
});
});
it('should create the expected tar stream (single container, --noconvert-eol, --multi-dockerignore)', async () => {

View File

@ -33,6 +33,7 @@ import type {
ExpectedTarStreamFilesByService,
} from '../projects';
import { getDockerignoreWarn1, getDockerignoreWarn3 } from '../projects';
import rewiremock from 'rewiremock';
const repoPath = path.normalize(path.join(__dirname, '..', '..'));
const projectsPath = path.join(repoPath, 'tests', 'test-data', 'projects');
@ -97,12 +98,16 @@ describe('balena deploy', function () {
docker.expectPostImagesTag();
docker.expectPostImagesPush();
docker.expectDeleteImages();
rewiremock.overrideEntryPoint(module);
rewiremock.enable();
});
this.afterEach(() => {
// Check all expected api calls have been made and clean up.
api.done();
docker.done();
rewiremock.disable();
});
it('should create the expected --build tar stream (single container)', async () => {

View File

@ -32,6 +32,7 @@ import {
getDockerignoreWarn3,
setupDockerignoreTestData,
} from '../projects';
import rewiremock from 'rewiremock';
const repoPath = path.normalize(path.join(__dirname, '..', '..'));
const projectsPath = path.join(repoPath, 'tests', 'test-data', 'projects');
@ -90,12 +91,16 @@ describe('balena push', function () {
builder = new BuilderMock();
api.expectGetWhoAmI({ optional: true, persist: true });
api.expectGetApplication();
rewiremock.overrideEntryPoint(module);
rewiremock.enable();
});
this.afterEach(() => {
// Check all expected api calls have been made and clean up.
api.done();
builder.done();
rewiremock.disable();
});
this.beforeAll(async () => {

View File

@ -41,6 +41,7 @@ import type {
ExpectedTarStreamFiles,
ExpectedTarStreamFilesByService,
} from './projects';
import rewiremock from 'rewiremock';
/**
* Run a few chai.expect() test assertions on a tar stream/buffer produced by
@ -198,7 +199,7 @@ export async function testDockerBuildStream(o: {
}
}
await resetDockerignoreCache();
resetDockerignoreCache();
const { exitCode, out, err } = await runCommand(o.commandLine);
@ -250,7 +251,7 @@ export async function testPushBuildStream(o: {
inspectTarStream(buildRequestBody, o.expectedFiles, o.projectPath),
});
await resetDockerignoreCache();
resetDockerignoreCache();
const { out, err } = await runCommand(o.commandLine);
@ -258,14 +259,11 @@ export async function testPushBuildStream(o: {
expect(cleanOutput(out, true)).to.include.members(expectedResponseLines);
}
export async function resetDockerignoreCache() {
const rewire = await import('rewire');
export function resetDockerignoreCache() {
if (process.env.BALENA_CLI_TEST_TYPE !== 'source') {
return;
}
const ignorePath = '../build/utils/ignore';
delete require.cache[require.resolve(ignorePath)];
const ignoreMod = rewire(ignorePath);
ignoreMod.__set__('dockerignoreByService', null);
rewiremock(ignorePath).with({ dockerignoreByService: null });
}

View File

@ -24,6 +24,7 @@ import { promisify } from 'util';
import { LivepushManager } from '../../../src/utils/device/live';
import { resetDockerignoreCache } from '../../docker-build';
import { setupDockerignoreTestData } from '../../projects';
import rewiremock from 'rewiremock';
const delay = promisify(setTimeout);
const FS_WATCH_DURATION_MS = 500;
@ -132,8 +133,15 @@ describeSS('LivepushManager::setupFilesystemWatcher', function () {
await setupDockerignoreTestData({ cleanup: true });
});
this.beforeEach(async () => {
await resetDockerignoreCache();
this.beforeEach(() => {
rewiremock.overrideEntryPoint(module);
rewiremock.enable();
resetDockerignoreCache();
});
this.afterEach(() => {
rewiremock.disable();
});
describe('for project no-docker-compose/basic', function () {