From a377295642498a351f9861014ed608edd7d74f6b Mon Sep 17 00:00:00 2001 From: Gabriel-Ladzaretti <97394622+Gabriel-Ladzaretti@users.noreply.github.com> Date: Wed, 11 May 2022 07:03:58 +0300 Subject: [PATCH] refactor(versioning/distro): Move date handling into distro.ts (#15271) * refactor(versioning/distro): Move date handling into distro.ts - moved all time/date handling into distro.ts - date freeze for ubuntu/distro unit tests * refactor(versioning/distro): Move date handling into distro.ts - restore deleted test cases for ubuntu unit tests * refactor(versioning/distro): Move date handling into distro.ts - removed distro time mocking * refactor(versioning/distro): Move date handling into distro.ts - DistroInfo constructor is no longer date dependent - Restored DateTime mock * refactor(versioning/distro): Move date handling into distro.ts - convert a while to a for loop * refactor(versioning/distro): Move date handling into distro.ts - unit tests went further back in time * Update lib/modules/versioning/distro.spec.ts * refactor(versioning/distro): Move date handling into distro.ts - cr changes * refactor(versioning/distro): Move date handling into distro.ts - cr changes Co-authored-by: Michael Kriese <michael.kriese@visualon.de> Co-authored-by: Rhys Arkins <rhys@arkins.net> --- lib/modules/versioning/distro.spec.ts | 95 ++++++++++++--------- lib/modules/versioning/distro.ts | 47 ++++++++-- lib/modules/versioning/ubuntu/index.spec.ts | 11 --- lib/modules/versioning/ubuntu/index.ts | 10 +-- 4 files changed, 99 insertions(+), 64 deletions(-) diff --git a/lib/modules/versioning/distro.spec.ts b/lib/modules/versioning/distro.spec.ts index d0dd67db08..d451437ab4 100644 --- a/lib/modules/versioning/distro.spec.ts +++ b/lib/modules/versioning/distro.spec.ts @@ -1,8 +1,14 @@ +import { DateTime, Settings } from 'luxon'; import { DistroInfo } from './distro'; describe('modules/versioning/distro', () => { const di = new DistroInfo('data/ubuntu-distro-info.json'); + beforeAll(() => { + const dt = DateTime.fromISO('2021-03-20'); + jest.spyOn(Settings, 'now').mockReturnValue(dt.valueOf()); + }); + it.each` version | expected ${'jammy'} | ${true} @@ -73,68 +79,77 @@ describe('modules/versioning/distro', () => { it.each` version | expected + ${'eoan'} | ${true} ${'focal'} | ${false} - ${'groovy'} | ${true} - ${'hirsute'} | ${true} + ${'groovy'} | ${false} + ${'hirsute'} | ${false} ${'impish'} | ${false} ${'jammy'} | ${false} + ${'19.10'} | ${true} ${'20.04'} | ${false} - ${'20.10'} | ${true} - ${'21.04'} | ${true} + ${'20.10'} | ${false} + ${'21.04'} | ${false} ${'21.10'} | ${false} ${'22.04'} | ${false} `('isEolLts("$version") === $expected', ({ version, expected }) => { expect(di.isEolLts(version)).toBe(expected); }); - it('retrieves most recent release schedule with version', () => { - expect(di.getNLatest(0)).toEqual({ - codename: 'Jammy Jellyfish', - created: '2021-10-14', - eol: '2027-04-21', - eol_esm: '2032-04-21', - eol_server: '2027-04-21', - release: '2022-04-21', - series: 'jammy', - version: '22.04', + it.each` + version | expected + ${'focal'} | ${true} + ${'groovy'} | ${true} + ${'hirsute'} | ${false} + ${'impish'} | ${false} + ${'jammy'} | ${false} + ${'20.04'} | ${true} + ${'20.10'} | ${true} + ${'21.04'} | ${false} + ${'21.10'} | ${false} + ${'22.04'} | ${false} + ${'24.04'} | ${false} + `('isReleased("$version") === $expected', ({ version, expected }) => { + expect(di.isReleased(version)).toBe(expected); + }); + + it('retrieves schedule of the previous previous release', () => { + expect(di.getNLatest(2)).toMatchObject({ + series: 'eoan', + version: '19.10', }); }); - it('sends an out of bound argument', () => { - expect(di.getNLatest(-1)).toBeNull(); + it('retrieves schedule of the previous release', () => { + expect(di.getNLatest(1)).toMatchObject({ + series: 'focal', + version: '20.04', + }); }); - it('sends a float as an argument', () => { - expect(di.getNLatest(0.1)).toEqual({ - codename: 'Jammy Jellyfish', - created: '2021-10-14', - eol: '2027-04-21', - eol_esm: '2032-04-21', - eol_server: '2027-04-21', - release: '2022-04-21', - series: 'jammy', - version: '22.04', + it('retrieves schedule of the most recent release', () => { + expect(di.getNLatest(0)).toMatchObject({ + series: 'groovy', + version: '20.10', }); }); - it('retrieves before most recent release schedule with version', () => { - expect(di.getNLatest(1)).toEqual({ - codename: 'Impish Indri', - series: 'impish', - created: '2021-04-22', - release: '2021-10-14', - eol: '2022-07-14', - version: '21.10', + it('sends a float as an argument', () => { + expect(di.getNLatest(0.1)).toMatchObject({ + series: 'groovy', + version: '20.10', }); }); + it('sends an out of bound argument', () => { + expect(di.getNLatest(-1)).toBeNull(); + }); + + it('sends another out of bound argument', () => { + expect(di.getNLatest(100)).toBeNull(); + }); + it('retrieves focal release schedule', () => { - expect(di.getSchedule('20.04')).toEqual({ - codename: 'Focal Fossa', - created: '2019-10-17', - eol: '2025-04-23', - eol_esm: '2030-04-23', - eol_server: '2025-04-23', + expect(di.getSchedule('20.04')).toMatchObject({ release: '2020-04-23', series: 'focal', }); diff --git a/lib/modules/versioning/distro.ts b/lib/modules/versioning/distro.ts index eba5d8af96..7d52f6f3aa 100644 --- a/lib/modules/versioning/distro.ts +++ b/lib/modules/versioning/distro.ts @@ -19,6 +19,9 @@ export type DistroInfoRecord = Record<string, DistroSchedule>; export type DistroInfoRecordWithVersion = { version: string } & DistroSchedule; +// Days to delay new releases +const delay = 1; + export class DistroInfo { private readonly _codenameToVersion = new Map< string, @@ -127,8 +130,8 @@ export class DistroInfo { } if (end) { - const now = DateTime.now(); - const eol = DateTime.fromISO(end); + const now = DateTime.now().toUTC(); + const eol = DateTime.fromISO(end, { zone: 'utc' }); return eol < now; } @@ -136,6 +139,25 @@ export class DistroInfo { return true; } + /** + * Check if a given version has been released + * @param input A codename/semVer + * @returns false if unreleased or has no schedule, true otherwise + */ + public isReleased(input: string): boolean { + const ver = this.getVersionByCodename(input); + const schedule = this.getSchedule(ver); + + if (!schedule) { + return false; + } + + const now = DateTime.now().minus({ day: delay }).toUTC(); + const release = DateTime.fromISO(schedule.release, { zone: 'utc' }); + + return release < now; + } + /** * Get distro info for the release that has N other newer releases. * Example: n=0 corresponds to the latest available release, n=1 the release before, etc. @@ -145,12 +167,25 @@ export class DistroInfo { */ public getNLatest(n: number): DistroInfoRecordWithVersion | null { const len = this._sortedInfo.length - 1; - const i = len - Math.floor(n); + let idx = -1; + + if (n < 0) { + return null; + } + + for (let i = len; i >= 0; i--) { + if (this.isReleased(this._sortedInfo[i].version)) { + // 'i' holds the latest released version index + // compensate for the requested 'n' + idx = i - Math.floor(n); + break; + } + } - if (len >= i && i >= 0) { - return this._sortedInfo[i]; + if (idx > len || idx < 0) { + return null; } - return null; + return this._sortedInfo[idx]; } } diff --git a/lib/modules/versioning/ubuntu/index.spec.ts b/lib/modules/versioning/ubuntu/index.spec.ts index 0287985b11..0c8233e644 100644 --- a/lib/modules/versioning/ubuntu/index.spec.ts +++ b/lib/modules/versioning/ubuntu/index.spec.ts @@ -155,17 +155,6 @@ describe('modules/versioning/ubuntu/index', () => { ${'20.04'} | ${true} ${'20.10'} | ${false} ${'22.04'} | ${false} - ${'42.01'} | ${false} - ${'42.02'} | ${false} - ${'42.03'} | ${false} - ${'42.04'} | ${true} - ${'42.05'} | ${false} - ${'42.06'} | ${false} - ${'42.07'} | ${false} - ${'42.08'} | ${false} - ${'42.09'} | ${false} - ${'42.10'} | ${false} - ${'42.11'} | ${false} ${'2020.04'} | ${false} ${'warty'} | ${false} ${'hoary'} | ${false} diff --git a/lib/modules/versioning/ubuntu/index.ts b/lib/modules/versioning/ubuntu/index.ts index b49f5ad230..304488dbba 100644 --- a/lib/modules/versioning/ubuntu/index.ts +++ b/lib/modules/versioning/ubuntu/index.ts @@ -1,4 +1,3 @@ -import { DateTime } from 'luxon'; import { regEx } from '../../../util/regex'; import { DistroInfo } from '../distro'; import type { NewValueConfig, VersioningApi } from '../types'; @@ -43,12 +42,9 @@ function isStable(version: string): boolean { return false; } - const schedule = di.getSchedule(ver); - if ( - schedule && - DateTime.fromISO(schedule.release).toUTC() > - DateTime.now().minus({ days: 1 }).toUTC() - ) { + const match = ver.match(regEx(/^\d+.\d+/)); + + if (!di.isReleased(match ? match[0] : ver)) { return false; } -- GitLab