Skip to content

Commit

Permalink
Adjust CI checks (polkadot-js#7851)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacogr authored Jul 9, 2022
1 parent fcd0367 commit d8b9878
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 116 deletions.
10 changes: 10 additions & 0 deletions jest-ci.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2017-2022 @polkadot/apps authors & contributors
// SPDX-License-Identifier: Apache-2.0

const config = require('@polkadot/dev/config/jest.cjs');

module.exports = {
...config,
moduleNameMapper: {},
testTimeout: 2 * 60 * 1000
};
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"url": "https://github.com/polkadot-js/apps.git"
},
"sideEffects": false,
"type": "module",
"version": "0.116.2-93-x",
"workspaces": [
"packages/*"
Expand All @@ -36,8 +37,8 @@
"build:release:www": "yarn polkadot-ci-ghact-build && yarn build:release:ghpages && yarn build:release:ipfs",
"build:robohash": "node scripts/robohash.cjs",
"build:www": "rm -rf packages/apps/build && mkdir -p packages/apps/build && yarn run build:i18n && cd packages/apps && yarn webpack --config webpack.config.cjs",
"ci:chainEndpoints": "NODE_OPTIONS=--max_old_space_size=8192 polkadot-dev-run-test --runInBand packages/apps-config/src/ci/chainEndpoints",
"ci:chainTypes": "NODE_OPTIONS=--max_old_space_size=8192 polkadot-dev-run-test --runInBand packages/apps-config/src/ci/chainTypes",
"ci:chainEndpoints": "NODE_OPTIONS=--experimental-vm-modules polkadot-dev-run-test --config ./jest-ci.config.cjs --runInBand --detectOpenHandles packages/apps-config/src/ci/chainEndpoints",
"ci:chainTypes": "NODE_OPTIONS=--experimental-vm-modules polkadot-dev-run-test --config ./jest-ci.config.cjs --runInBand --detectOpenHandles packages/apps-config/src/ci/chainTypes",
"clean": "polkadot-dev-clean-build",
"clean:electronBuild": "cd packages/apps-electron && polkadot-dev-clean-build",
"clean:electronRelease": "cd packages/apps-electron && rm -rf release",
Expand Down
6 changes: 5 additions & 1 deletion packages/apps-config/src/ci/chainEndpoints.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// Copyright 2017-2022 @polkadot/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { checkEndpoints } from './util';
import { checkEndpoints } from './runner';

describe('--SLOW--: check configured chain endpoints', (): void => {
beforeAll((): void => {
jest.setTimeout(2 * 60 * 1000);
});

checkEndpoints('./.github/chain-endpoints.md', [
'No DNS entry for',
'Timeout connecting to',
Expand Down
6 changes: 5 additions & 1 deletion packages/apps-config/src/ci/chainTypes.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// Copyright 2017-2022 @polkadot/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { checkEndpoints } from './util';
import { checkEndpoints } from './runner';

describe.skip('--SLOW--: check configured chain types', (): void => {
beforeAll((): void => {
jest.setTimeout(2 * 60 * 1000);
});

checkEndpoints('./.github/chain-types.md', [
'Unknown types'
]);
Expand Down
88 changes: 88 additions & 0 deletions packages/apps-config/src/ci/check.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2017-2022 @polkadot/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0

import fs from 'fs';

import { ApiPromise, WsProvider } from '@polkadot/api';
import { assert, isError } from '@polkadot/util';

import { typesBundle, typesChain } from '../api';
import { fetchJson } from './fetch';

interface DnsResponse {
Answer?: { name: string }[];
Question: { name: string }[];
}

const TICK = '`';

export function checkEndpoint (issueFile: string, failures: string[]): (name: string, ws: string) => Promise<boolean> {
return async (name: string, ws: string): Promise<boolean> => {
const [,, hostWithPort] = ws.split('/');
const [host] = hostWithPort.split(':');
const json = await fetchJson<DnsResponse>(`https://dns.google/resolve?name=${host}`);

let provider: WsProvider | null = null;
let api: ApiPromise | null = null;
let timerId: NodeJS.Timeout | null = null;

try {
assert(json.Answer, `No DNS entry for ${host}`);

provider = new WsProvider(ws, false);
api = new ApiPromise({
provider,
throwOnConnect: true,
throwOnUnknown: false,
typesBundle,
typesChain
});

setTimeout((): void => {
provider &&
provider
.connect()
.catch(() => undefined);
}, 1000);

await Promise.race([
// eslint-disable-next-line promise/param-names
new Promise((_, reject): void => {
timerId = setTimeout((): void => {
timerId = null;
reject(new Error(`Timeout connecting to ${ws}`));
}, 30_000);
}),
api.isReadyOrError
.then((a) => a.rpc.chain.getBlock())
.then((b) => console.log(b.toHuman()))
]);
} catch (error) {
if (isError(error) && failures.some((f) => (error as Error).message.includes(f))) {
process.env.CI_LOG && fs.appendFileSync(issueFile, `\n${TICK}${name} @ ${ws} ${error.message}${TICK}\n`);

throw error;
}

console.error(JSON.stringify(error));
} finally {
if (timerId) {
clearTimeout(timerId);
}

if (provider) {
try {
if (api) {
await api.disconnect();
} else {
await provider.disconnect();
}
} catch {
// ignore
}
}
}

return Promise.resolve(true);
};
}
38 changes: 38 additions & 0 deletions packages/apps-config/src/ci/fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2017-2022 @polkadot/apps authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { fetch } from '@polkadot/x-fetch';

// a fetch with a 2s timeout
async function fetchWithTimeout (url: string, timeout = 2000): Promise<Response> {
const controller = new AbortController();
let isAborted = false;
const id = setTimeout((): void => {
console.log(`Timeout on ${url}`);

isAborted = true;
controller.abort();
}, timeout);

try {
const response = await fetch(url, { signal: controller.signal });

clearTimeout(id);

return response;
} catch (error) {
if (!isAborted) {
clearTimeout(id);
}

throw error;
}
}

export function fetchJson <T> (url: string, timeout = 2000): Promise<T> {
return fetchWithTimeout(url, timeout).then<T>((r) => r.json());
}

export function fetchText (url: string, timeout = 2000): Promise<string> {
return fetchWithTimeout(url, timeout).then((r) => r.text());
}
37 changes: 37 additions & 0 deletions packages/apps-config/src/ci/runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2017-2022 @polkadot/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { isString } from '@polkadot/util';

import { createWsEndpoints } from '../endpoints';
import { checkEndpoint } from './check';

interface Endpoint {
name: string;
ws: string;
}

export function checkEndpoints (issueFile: string, failures: string[]): void {
const checker = checkEndpoint(issueFile, failures);

it.each(
createWsEndpoints()
.filter(({ isDisabled, isUnreachable, value }) =>
!isDisabled &&
!isUnreachable &&
value &&
isString(value) &&
!value.includes('127.0.0.1') &&
!value.startsWith('light://')
)
.map(({ text, value }): Partial<Endpoint> => ({
name: text as string,
ws: value
}))
.filter((v): v is Endpoint => !!v.ws)
)('%name @ %$ws', ({ name, ws }): Promise<void> => {
console.error(`>>> ${name} @ ${ws}`);

return checker(name, ws).then((r) => expect(r).toBe(true));
});
}
112 changes: 0 additions & 112 deletions packages/apps-config/src/ci/util.ts

This file was deleted.

0 comments on commit d8b9878

Please sign in to comment.