Merge pull request #1211 from balena-io/1210-better-l4t-versioning

Allow semver comparison on L4T versions, and support 2 and 3 integer version forms
This commit is contained in:
CameronDiver 2020-03-06 16:11:27 +00:00 committed by GitHub
commit efebe11814
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 123 additions and 24 deletions

View File

@ -59,7 +59,7 @@ export function getOSSemver(path: string): Promise<string | undefined> {
return getOSReleaseField(path, 'VERSION');
}
const L4T_REGEX = /^.*-l4t-r(\d+\.\d+).*$/;
const L4T_REGEX = /^.*-l4t-r(\d+\.\d+(\.?\d+)?).*$/;
export async function getL4tVersion(): Promise<string | undefined> {
// We call `uname -r` on the host, and look for l4t
try {
@ -69,7 +69,15 @@ export async function getL4tVersion(): Promise<string | undefined> {
return;
}
return match[1];
let res = match[1];
if (match[2] == null) {
// We were only provided with 2 version numbers
// We add a .0 onto the end, to allow always being
// able to use semver comparisons
res += '.0';
}
return res;
} catch (e) {
log.error('Could not detect l4t version! Error: ', e);
return;

View File

@ -410,36 +410,127 @@ describe('Container contracts', () => {
});
describe('L4T version detection', () => {
it('should correctly parse L4T version strings', async () => {
let execStub = stub(child_process, 'exec').returns(
Promise.resolve([
Buffer.from('4.9.140-l4t-r32.2+g3dcbed5'),
Buffer.from(''),
]),
);
expect(await osRelease.getL4tVersion()).to.equal('32.2');
expect(execStub.callCount).to.equal(1);
execStub.restore();
let execStub: SinonStub;
const seedExec = (version: string) => {
execStub = stub(child_process, 'exec').returns(
Promise.resolve([
Buffer.from('4.4.38-l4t-r28.2+g174510d'),
Buffer.from(''),
]),
Promise.resolve([Buffer.from(version), Buffer.from('')]),
);
expect(await osRelease.getL4tVersion()).to.equal('28.2');
};
afterEach(() => {
execStub.restore();
});
it('should correctly parse L4T version strings', async () => {
seedExec('4.9.140-l4t-r32.2+g3dcbed5');
expect(await osRelease.getL4tVersion()).to.equal('32.2.0');
expect(execStub.callCount).to.equal(1);
execStub.restore();
seedExec('4.4.38-l4t-r28.2+g174510d');
expect(await osRelease.getL4tVersion()).to.equal('28.2.0');
expect(execStub.callCount).to.equal(1);
});
it('should correctly handle l4t versions which contain three numbers', async () => {
seedExec('4.4.38-l4t-r32.3.1+g174510d');
expect(await osRelease.getL4tVersion()).to.equal('32.3.1');
expect(execStub.callCount).to.equal(1);
});
it('should return undefined when there is no l4t string in uname', async () => {
const execStub = stub(child_process, 'exec').returns(
Promise.resolve([Buffer.from('4.18.14-yocto-standard'), Buffer.from('')]),
);
seedExec('4.18.14-yocto-standard');
expect(await osRelease.getL4tVersion()).to.be.undefined;
execStub.restore();
});
describe('L4T comparison', () => {
it('should allow semver matching even when l4t does not fulfill semver', async () => {
seedExec('4.4.38-l4t-r31.0');
expect(
await containerContractsFulfilled({
service: {
contract: {
type: 'sw.container',
slug: 'user-container',
requires: [
{
type: 'sw.l4t',
version: '>=31.0.0',
},
],
},
optional: false,
},
}),
)
.to.have.property('valid')
.that.equals(true);
expect(
await containerContractsFulfilled({
service: {
contract: {
type: 'sw.container',
slug: 'user-container',
requires: [
{
type: 'sw.l4t',
version: '<31.0.0',
},
],
},
optional: false,
},
}),
)
.to.have.property('valid')
.that.equals(false);
});
it('should allow semver matching when l4t does fulfill semver', async () => {
seedExec('4.4.38-l4t-r31.0.1');
expect(
await containerContractsFulfilled({
service: {
contract: {
type: 'sw.container',
slug: 'user-container',
requires: [
{
type: 'sw.l4t',
version: '>=31.0.0',
},
],
},
optional: false,
},
}),
)
.to.have.property('valid')
.that.equals(true);
expect(
await containerContractsFulfilled({
service: {
contract: {
type: 'sw.container',
slug: 'user-container',
requires: [
{
type: 'sw.l4t',
version: '<31.0.0',
},
],
},
optional: false,
},
}),
)
.to.have.property('valid')
.that.equals(false);
});
});
});