UNPKG

postchain-client

Version:

Client library for accessing a Postchain node through REST.

114 lines 6.36 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { FailoverStrategy, Method } from "../../src/blockchainClient/enums"; import { retryRequest } from "../../src/blockchainClient/failoverStrategies"; import { handleRequest } from "../../src/blockchainClient/httpUtil"; import { createNodeManager } from "../../src/blockchainClient/nodeManager"; import { mockNodeUrls } from "../common/mocks"; jest.mock("../../src/blockchainClient/httpUtil", () => ({ handleRequest: jest.fn(), })); const mockHandleRequest = handleRequest; describe("Sticky node feature", () => { afterEach(() => { jest.clearAllMocks(); jest.restoreAllMocks(); }); describe("sticky node logic", () => { const endpointUrlPool = mockNodeUrls; const retryRequestConfig = { endpointPool: endpointUrlPool.map(url => ({ url, whenAvailable: 0 })), failoverStrategy: FailoverStrategy.TryNextOnError, statusPollCount: 1, statusPollInterval: 1, attemptsPerEndpoint: 2, attemptInterval: 100, unreachableDuration: 5000, }; const successfullResponse = { error: null, statusCode: 200, rspBody: "" }; const failedResponse = { error: null, statusCode: 500, rspBody: "" }; it("should NOT retain a node when sticky node is disabled.", () => __awaiter(void 0, void 0, void 0, function* () { mockHandleRequest .mockResolvedValueOnce(successfullResponse) .mockResolvedValueOnce(successfullResponse) .mockResolvedValueOnce(successfullResponse); const nodeManager = createNodeManager({ nodeUrls: endpointUrlPool, useStickyNode: false, unavailableDuration: 5000, }); for (let i = 0; i < 3; i++) { yield retryRequest({ method: Method.GET, path: "/path", config: Object.assign(Object.assign({}, retryRequestConfig), { nodeManager }), validateStatusCode: statusCode => ![500, 503].includes(statusCode), }); } const requestNodes = mockHandleRequest.mock.calls.map(call => call[2]); expect(requestNodes.every(node => node === requestNodes[0])).toBe(false); })); it("should be possible to retain the same node in between requests.", () => __awaiter(void 0, void 0, void 0, function* () { mockHandleRequest .mockResolvedValueOnce(successfullResponse) .mockResolvedValueOnce(successfullResponse) .mockResolvedValueOnce(successfullResponse); const nodeManager = createNodeManager({ nodeUrls: endpointUrlPool, useStickyNode: true, unavailableDuration: 5000, }); for (let i = 0; i < 3; i++) { yield retryRequest({ method: Method.GET, path: "/path", config: Object.assign(Object.assign({}, retryRequestConfig), { nodeManager }), validateStatusCode: statusCode => ![500, 503].includes(statusCode), }); } const selectedStickyNode = mockHandleRequest.mock.calls[0][2]; expect(mockHandleRequest.mock.calls[1][2]).toBe(selectedStickyNode); expect(mockHandleRequest.mock.calls[2][2]).toBe(selectedStickyNode); expect(mockHandleRequest).toHaveBeenCalledTimes(3); })); it("should set new sticky node, when the original one fails.", () => __awaiter(void 0, void 0, void 0, function* () { mockHandleRequest .mockResolvedValueOnce(failedResponse) .mockResolvedValueOnce(failedResponse) .mockResolvedValueOnce(failedResponse) .mockResolvedValueOnce(successfullResponse) .mockResolvedValueOnce(failedResponse) .mockResolvedValueOnce(failedResponse) .mockResolvedValueOnce(successfullResponse); const nodeManager = createNodeManager({ nodeUrls: endpointUrlPool, useStickyNode: true, unavailableDuration: 5000, }); for (let i = 0; i < 2; i++) { yield retryRequest({ method: Method.GET, path: "/path", config: Object.assign(Object.assign({}, retryRequestConfig), { nodeManager }), validateStatusCode: statusCode => ![500, 503].includes(statusCode), }); } const nodeOfRequest = mockHandleRequest.mock.calls.map(call => call[2]); expect(nodeOfRequest[0]).toBe(nodeOfRequest[1]); // Both requests should have used the same node, and both should have failed. expect(nodeOfRequest[2]).not.toBe(nodeOfRequest[0]); // Should have picked a new node, and the request should have failed. expect(nodeOfRequest[3]).toBe(nodeOfRequest[2]); // Should have retried on a new node, succeeded, and set it as the new sticky node. expect(nodeOfRequest[4]).toBe(nodeOfRequest[3]); // Should have used the sticky node, but request should have failed. expect(nodeOfRequest[5]).toBe(nodeOfRequest[4]); // Should have used the sticky node again, but request should have failed. expect(nodeOfRequest[6]).not.toBe(nodeOfRequest[5]); // Should have picked a new node and succeeded. expect(mockHandleRequest).toHaveBeenCalledTimes(7); })); }); }); //# sourceMappingURL=stickyNode.test.js.map