Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(endoflife): Mock time #22575

Merged
merged 1 commit into from
Jun 4, 2023
Merged
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
6 changes: 6 additions & 0 deletions lib/modules/datasource/endoflife-date/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DateTime, Settings } from 'luxon';
import { getPkgReleases } from '..';
import { Fixtures } from '../../../../test/fixtures';
import * as httpMock from '../../../../test/http-mock';
Expand All @@ -12,6 +13,11 @@ const packageName = 'amazon-eks';
const eksMockPath = `/${packageName}.json`;

describe('modules/datasource/endoflife-date/index', () => {
beforeAll(() => {
const now = DateTime.fromISO('2023-06-03');
Settings.now = () => now.valueOf();
});

describe('getReleases', () => {
it('processes real data', async () => {
httpMock
Expand Down
7 changes: 2 additions & 5 deletions lib/modules/datasource/endoflife-date/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { joinUrlParts } from '../../../util/url';
import { Datasource } from '../datasource';
import type { GetReleasesConfig, ReleaseResult } from '../types';
import { datasource, registryUrl } from './common';
import { EndoflifeHttpResponseScheme } from './schema';
import { EndoflifeDateVersions } from './schema';

export class EndoflifeDatePackagesource extends Datasource {
static readonly id = datasource;
Expand Down Expand Up @@ -41,10 +41,7 @@ export class EndoflifeDatePackagesource extends Datasource {
const url = joinUrlParts(registryUrl, `${packageName}.json`);

try {
const response = await this.http.getJson(
url,
EndoflifeHttpResponseScheme
);
const response = await this.http.getJson(url, EndoflifeDateVersions);

result.releases.push(...response.body);

Expand Down
57 changes: 25 additions & 32 deletions lib/modules/datasource/endoflife-date/schema.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,35 @@
import { DateTime } from 'luxon';
import { z } from 'zod';
import { UtcDate } from '../../../util/schema-utils';
import type { Release } from '../types';

const EndoflifeDateVersionScheme = z
const ExpireableField = z.union([
UtcDate.transform((x) => {
const now = DateTime.now().toUTC();
return x <= now;
}),
z.boolean(),
]);

export const EndoflifeDateVersions = z
.object({
cycle: z.string(),
latest: z.optional(z.string()),
releaseDate: z.optional(z.string()),
eol: z.optional(z.union([z.string(), z.boolean()])),
discontinued: z.optional(z.union([z.string(), z.boolean()])),
eol: z.optional(ExpireableField),
discontinued: z.optional(ExpireableField),
})
.transform(({ cycle, latest, releaseDate, eol, discontinued }): Release => {
let isDeprecated = false;

// If "eol" date or "discontinued" date has passed or any of the values is explicitly true, set to deprecated
// "support" is not checked because support periods sometimes end before the EOL.
if (
eol === true ||
discontinued === true ||
(typeof eol === 'string' &&
DateTime.fromISO(eol, { zone: 'utc' }) <= DateTime.now().toUTC()) ||
(typeof discontinued === 'string' &&
DateTime.fromISO(discontinued, { zone: 'utc' }) <=
DateTime.now().toUTC())
) {
isDeprecated = true;
}

let version = cycle;
if (latest !== undefined) {
version = latest;
.transform(
({
cycle,
latest,
releaseDate: releaseTimestamp,
eol,
discontinued,
}): Release => {
const version = latest ?? cycle;
const isDeprecated = eol === true || discontinued === true;
return { version, releaseTimestamp, isDeprecated };
}

return {
version,
releaseTimestamp: releaseDate,
isDeprecated,
};
});

export const EndoflifeHttpResponseScheme = z.array(EndoflifeDateVersionScheme);
)
.array();
14 changes: 13 additions & 1 deletion lib/util/schema-utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { z } from 'zod';
import { Json, Json5, LooseArray, LooseRecord } from './schema-utils';
import { Json, Json5, LooseArray, LooseRecord, UtcDate } from './schema-utils';

describe('util/schema-utils', () => {
describe('LooseArray', () => {
Expand Down Expand Up @@ -258,4 +258,16 @@ describe('util/schema-utils', () => {
});
});
});

describe('UtcDate', () => {
it('parses date', () => {
expect(UtcDate.parse('2020-04-04').toString()).toBe(
'2020-04-04T00:00:00.000Z'
);
});

it('rejects invalid date', () => {
expect(() => UtcDate.parse('foobar')).toThrow();
});
});
});
12 changes: 12 additions & 0 deletions lib/util/schema-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import JSON5 from 'json5';
import { DateTime } from 'luxon';
import type { JsonValue } from 'type-fest';
import { z } from 'zod';

Expand Down Expand Up @@ -211,3 +212,14 @@ export const Json5 = z.string().transform((str, ctx): JsonValue => {
return z.NEVER;
}
});

export const UtcDate = z
.string({ description: 'ISO 8601 string' })
.transform((str, ctx): DateTime => {
const date = DateTime.fromISO(str, { zone: 'utc' });
if (!date.isValid) {
ctx.addIssue({ code: 'custom', message: 'Invalid date' });
return z.NEVER;
}
return date;
});