Files
lodestar/packages/api/test/utils/genericServerTest.ts
Lion - dapplion be50e4e211 LightClient server no state cache + tracks head (#3461)
* WIP

* Refactor lightclient server db repositories

* WIP Lightclient refactor

* Lightclient tracking head

* Fix branch proof sorting

* Move lightclient code to package root

* Move LightclientServer code to module index

* Add e2e test and fix bugs

* Log sync committee periods

* Sync 3 periods

* Clean logging in LC

* Fix broken tests

* Rename getCommitteeUpdates route

* Use getStateV2 to download altair states

* Remove blockRoot from LightclientHeaderUpdate

* Polish lightclient

* Remove clock

* Remove beacon state transition dependency

* Add mock sync test

* Change getStateProof to GET

* Deprecate un-used db buckets

* Test fetching proofs on lightclient head state

* Test fetching proofs in sim test

* Test query serializtion

* Fix proof paths serdes in api

* Use Promise.all in storeSyncCommittee

* Rename finalizedHeader to checkpointHeader

* Remove genesisWitness

* Remove genesis proof dead code

* Rename lightclient_update to lightclient_header_update

* Pass only checkpoint root

* Use console levels in getLcLoggerConsole

* Remove stateProofPaths dead code

* Rename to initializeFromCheckpointRoot

* lightclient snapshot type has a single SyncCommittee

* Simplify tree position constants

* Log 'New sync committee period' message only once
2021-12-01 19:33:02 +01:00

76 lines
2.6 KiB
TypeScript

import {expect} from "chai";
import {IChainForkConfig} from "@chainsafe/lodestar-config";
import {RouteGeneric, ReqGeneric, Resolves} from "../../src/utils";
import {FetchOpts, HttpClient, IHttpClient} from "../../src/client/utils";
import {ServerRoutes} from "../../src/server/utils";
import {getMockApi, getTestServer} from "./utils";
import {registerRoutesGroup} from "../../src/server";
type IgnoreVoid<T> = T extends void ? undefined : T;
export type GenericServerTestCases<Api extends Record<string, RouteGeneric>> = {
[K in keyof Api]: {
args: Parameters<Api[K]>;
res: IgnoreVoid<Resolves<Api[K]>>;
query?: FetchOpts["query"];
};
};
export function runGenericServerTest<
Api extends Record<string, RouteGeneric>,
ReqTypes extends {[K in keyof Api]: ReqGeneric}
>(
config: IChainForkConfig,
getClient: (config: IChainForkConfig, https: IHttpClient) => Api,
getRoutes: (config: IChainForkConfig, api: Api) => ServerRoutes<Api, ReqTypes>,
testCases: GenericServerTestCases<Api>
): void {
const mockApi = getMockApi<Api>(testCases);
const {baseUrl, server} = getTestServer();
const httpClient = new HttpClientSpy({baseUrl});
const client = getClient(config, httpClient);
const routes = getRoutes(config, mockApi);
registerRoutesGroup(server, routes);
for (const key of Object.keys(testCases)) {
const routeId = key as keyof Api;
const testCase = testCases[routeId];
it(routeId as string, async () => {
// Register mock data for this route
mockApi[routeId].resolves(testCases[routeId].res as any);
// Do the call
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const res = await (client[routeId] as RouteGeneric)(...(testCase.args as any[]));
// Use spy to assert argument serialization
if (testCase.query) {
expect(httpClient.opts?.query).to.deep.equal(testCase.query, "Wrong fetch opts.query");
}
// Assert server handler called with correct args
expect(mockApi[routeId].callCount).to.equal(1, `mockApi[${routeId}] must be called once`);
expect(mockApi[routeId].getCall(0).args).to.deep.equal(testCase.args, `mockApi[${routeId}] wrong args`);
// Assert returned value is correct
expect(res).to.deep.equal(testCase.res, "Wrong returned value");
});
}
}
class HttpClientSpy extends HttpClient {
opts: FetchOpts | null = null;
async json<T>(opts: FetchOpts): Promise<T> {
this.opts = opts;
return super.json(opts);
}
async arrayBuffer(opts: FetchOpts): Promise<ArrayBuffer> {
this.opts = opts;
return super.arrayBuffer(opts);
}
}