Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
324 changes: 163 additions & 161 deletions npm-shrinkwrap.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,15 @@
"mocha": "^10.6.0",
"mock-fs": "^5.2.0",
"mock-require": "^3.0.3",
"nock": "^14.0.4",
"nock": "^15.0.0-beta.5",
"oclif": "^4.22.0",
"rewire": "^7.0.0",
"simple-git": "^3.14.1",
"sinon": "^19.0.0",
"string-to-stream": "^3.0.1",
"ts-node": "^10.4.0",
"typescript": "^5.8.2"
"typescript": "^5.8.2",
"undici": "^7.10.0"
},
"dependencies": {
"@balena/compose": "^7.0.9",
Expand All @@ -174,7 +175,7 @@
"balena-errors": "^4.7.3",
"balena-image-fs": "^7.5.2",
"balena-preload": "^18.0.4",
"balena-sdk": "^21.3.0",
"balena-sdk": "^21.4.7",
"balena-semver": "^2.3.0",
"balena-settings-client": "^5.0.2",
"balena-settings-storage": "^8.1.0",
Expand Down
4 changes: 2 additions & 2 deletions tests/auth/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ describe('Utils:', async function () {
});
});

return describe('given the token does authenticate with the server', function () {
describe('given the token does authenticate with the server', function () {
beforeEach(function () {
this.balenaAuthIsLoggedInStub = sinon.stub(balena.auth, 'isLoggedIn');
return this.balenaAuthIsLoggedInStub.resolves(true);
Expand All @@ -118,7 +118,7 @@ describe('Utils:', async function () {
return this.balenaAuthIsLoggedInStub.restore();
});

return it('should eventually be true', function () {
it('should eventually be true', function () {
const promise = utils.loginIfTokenValid(tokens.johndoe.token);
return expect(promise).to.eventually.be.true;
});
Expand Down
25 changes: 12 additions & 13 deletions tests/commands/deploy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import type { Request as ReleaseRequest } from '@balena/compose/dist/release';
import { expect } from 'chai';
import { promises as fs } from 'fs';
import * as _ from 'lodash';
import type * as nock from 'nock';
import * as path from 'path';
import * as sinon from 'sinon';

Expand Down Expand Up @@ -181,8 +180,8 @@ describe('balena deploy', function () {
];

api.expectPostRelease({
inspectRequest: (_uri: string, requestBody: nock.Body) => {
const body = requestBody.valueOf() as Partial<ReleaseRequest>;
inspectRequest: async (request: Request) => {
const body = (await request.json()) as Partial<ReleaseRequest>;
expect(body.contract).to.deep.equal({
name: 'testContract',
type: 'sw.application',
Expand Down Expand Up @@ -232,8 +231,8 @@ describe('balena deploy', function () {
];

api.expectPostRelease({
inspectRequest: (_uri: string, requestBody: nock.Body) => {
const body = requestBody.valueOf() as Partial<ReleaseRequest>;
inspectRequest: async (request: Request) => {
const body = (await request.json()) as Partial<ReleaseRequest>;
expect(body.contract).to.deep.equal({
name: 'testContract',
type: 'sw.application',
Expand Down Expand Up @@ -298,21 +297,21 @@ describe('balena deploy', function () {
statusCode: 500,
// b/c failed requests are retried
times: maxRequestRetries,
inspectRequest: (_uri, requestBody) => {
const imageBody = requestBody as Partial<
inspectRequest: async (request: Request) => {
const body = (await request.json()) as Partial<
import('@balena/compose/dist/release/models').ImageModel
>;
expect(imageBody.status).to.equal('success');
expect(body.status).to.equal('success');
failedImagePatchRequests++;
},
});
// Check that the CLI patches the release with status="failed"
api.expectPatchRelease({
inspectRequest: (_uri, requestBody) => {
const releaseBody = requestBody as Partial<
inspectRequest: async (request: Request) => {
const body = (await request.json()) as Partial<
import('@balena/compose/dist/release/models').ReleaseModel
>;
expect(releaseBody.status).to.equal('failed');
expect(body.status).to.equal('failed');
},
});
api.expectPostImageLabel();
Expand Down Expand Up @@ -386,8 +385,8 @@ describe('balena deploy', function () {
let succesfullImagePatchRequests = 0;
api
.optPatch(/^\/v7\/image($|[(?])/, { times: maxRequestRetries })
.reply((_uri, requestBody) => {
const imageBody = requestBody as Partial<
.reply(async (request) => {
const imageBody = (await request.json()) as Partial<
import('@balena/compose/dist/release/models').ImageModel
>;
expect(imageBody.status).to.equal('success');
Expand Down
37 changes: 19 additions & 18 deletions tests/nock/balena-api-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@ export class BalenaAPIMock extends NockMock {
}

public expectDownloadConfig(opts: ScopeOpts = {}) {
this.optPost('/download-config', opts).reply(200, (_uri, body) => {
let deviceType = 'raspberrypi3';
if (typeof body === 'object' && 'deviceType' in body) {
deviceType = body.deviceType;
}
return JSON.parse(`{
this.optPost('/download-config', opts).reply(
200,
async (request: Request) => {
const body = await request.json();
let deviceType = 'raspberrypi3';
if (typeof body === 'object' && 'deviceType' in body) {
deviceType = body.deviceType;
}
return JSON.parse(`{
"applicationId":1301645,
"deviceType":"${deviceType}",
"userId":43699,
Expand All @@ -79,7 +82,8 @@ export class BalenaAPIMock extends NockMock {
"deltaEndpoint":"https://delta.balena-cloud.com",
"apiKey":"nothingtoseehere"
}`);
});
},
);
}

public expectApplicationProvisioning(opts: ScopeOpts = {}) {
Expand Down Expand Up @@ -223,7 +227,7 @@ export class BalenaAPIMock extends NockMock {
this.optGet(
providedUuid.length !== 32
? /^\/v\d+\/device($|\?)/
: /^\/v\d+\/device\(uuid=%27[0-9a-f]{32}%27\)/,
: /^\/v\d+\/device\(uuid='[0-9a-f]{32}'\)/,
opts,
).reply(200, {
d: [
Expand Down Expand Up @@ -284,8 +288,8 @@ export class BalenaAPIMock extends NockMock {

public expectGetAppServiceVars(opts: ScopeOpts = {}) {
this.optGet(/^\/v\d+\/service_environment_variable($|\?)/, opts).reply(
function (uri, _requestBody) {
const match = uri.match(/service_name%20eq%20%27(.+?)%27/);
function (request) {
const match = request.url.match(/service_name%20eq%20%27(.+?)%27/);
const serviceName = match?.[1] || undefined;
let varArray: any[];
if (serviceName) {
Expand Down Expand Up @@ -332,8 +336,8 @@ export class BalenaAPIMock extends NockMock {
this.optGet(
/^\/v\d+\/device_service_environment_variable($|\?)/,
opts,
).reply(function (uri, _requestBody) {
const match = uri.match(/service_name%20eq%20%27(.+?)%27/);
).reply(function (request) {
const match = request.url.match(/service_name%20eq%20%27(.+?)%27/);
const serviceName = match?.[1] || undefined;
let varArray: any[];
if (serviceName) {
Expand Down Expand Up @@ -381,12 +385,9 @@ export class BalenaAPIMock extends NockMock {
serviceName: string;
}) {
const serviceId = opts.serviceId || 243768;
this.optGet(/^\/v\d+\/service(\(\w+=\d+,\w+=%27\w+%27\))?$/, opts).reply(
200,
{
d: [{ id: serviceId, service_name: opts.serviceName }],
},
);
this.optGet(/^\/v\d+\/service(\(\w+=\d+,\w+='\w+'\))?$/, opts).reply(200, {
d: [{ id: serviceId, service_name: opts.serviceName }],
});
}

public expectGetServiceFromApp(opts: {
Expand Down
31 changes: 11 additions & 20 deletions tests/nock/builder-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@
*/

import * as path from 'path';
import * as zlib from 'zlib';

import { NockMock } from './nock-mock';
import { promisify } from 'util';

const gunzipAsync = promisify(zlib.gunzip);

export const builderResponsePath = path.normalize(
path.join(__dirname, '..', 'test-data', 'builder-response'),
Expand All @@ -40,20 +35,16 @@ export class BuilderMock extends NockMock {
checkURI: (uri: string) => Promise<void> | void;
checkBuildRequestBody: (requestBody: string | Buffer) => Promise<void>;
}) {
this.optPost(/^\/v3\/build($|[(?])/, opts).reply(
async function (uri, requestBody) {
await opts.checkURI(uri);
if (typeof requestBody === 'string') {
const gzipped = Buffer.from(requestBody, 'hex');
const gunzipped = await gunzipAsync(gzipped);
await opts.checkBuildRequestBody(gunzipped);
return [opts.responseCode, opts.responseBody];
} else {
throw new Error(
`unexpected requestBody type "${typeof requestBody}"`,
);
}
},
);
this.optPost(/^\/v3\/build($|[(?])/, opts).reply(async function (
request: Request,
) {
await opts.checkURI(request.url);
const requestBody = await request.text();
if (typeof requestBody !== 'string') {
throw new Error(`unexpected requestBody type "${typeof requestBody}"`);
}
await opts.checkBuildRequestBody(requestBody);
return [opts.responseCode, opts.responseBody];
});
}
}
12 changes: 6 additions & 6 deletions tests/nock/docker-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ export class DockerMock extends NockMock {
this.optPost(
new RegExp(`^/build\\?(|.+&)${qs.stringify({ t: opts.tag })}&`),
opts,
).reply(async function (uri, requestBody) {
await opts.checkURI(uri);
if (typeof requestBody === 'string') {
await opts.checkBuildRequestBody(requestBody);
return [opts.responseCode, opts.responseBody];
} else {
).reply(async function (request) {
await opts.checkURI(request.url);
const requestBody = await request.text();
if (typeof requestBody !== 'string') {
throw new Error(`unexpected requestBody type "${typeof requestBody}"`);
}
await opts.checkBuildRequestBody(requestBody);
return [opts.responseCode, opts.responseBody];
});
}

Expand Down
39 changes: 10 additions & 29 deletions tests/nock/nock-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,47 +100,28 @@ export class NockMock {
return this.optMethod('post', uri, opts);
}

protected inspectNoOp(_uri: string, _requestBody: nock.Body): void {
return undefined;
protected inspectNoOp(_request: Request): void | Promise<void> {
return;
}

protected getInspectedReplyBodyFunction(
inspectRequest: (uri: string, requestBody: nock.Body) => void,
inspectRequest: (request: Request) => void | Promise<void>,
replyBody: nock.ReplyBody,
) {
return function (
this: nock.ReplyFnContext,
uri: string,
requestBody: nock.Body,
cb: (err: NodeJS.ErrnoException | null, result: nock.ReplyBody) => void,
) {
try {
inspectRequest(uri, requestBody);
} catch (err) {
cb(err, '');
}
cb(null, replyBody);
return async function (request: Request): Promise<nock.ReplyBody> {
await inspectRequest(request);
return replyBody;
};
}

protected getInspectedReplyFileFunction(
inspectRequest: (uri: string, requestBody: nock.Body) => void,
inspectRequest: (request: Request) => void | Promise<void>,
replyBodyFile: string,
) {
return function (
this: nock.ReplyFnContext,
uri: string,
requestBody: nock.Body,
cb: (err: NodeJS.ErrnoException | null, result: nock.ReplyBody) => void,
) {
try {
inspectRequest(uri, requestBody);
} catch (err) {
cb(err, '');
}

return async function (request: Request): Promise<nock.ReplyBody> {
await inspectRequest(request);
const replyBody = fs.readFileSync(replyBodyFile);
cb(null, replyBody);
return replyBody;
};
}

Expand Down
4 changes: 2 additions & 2 deletions tests/nock/supervisor-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ export class SupervisorMock extends NockMock {
}, 10);
},
});
this.optGet('/v2/local/logs', opts).reply((_uri, _reqBody, cb) => {
cb(null, [200, chunkedStream]);
this.optGet('/v2/local/logs', opts).reply(() => {
return [200, chunkedStream];
});
}
}
Loading