diff --git a/src/main/__test__/context-handler.test.ts b/src/main/__test__/context-handler.test.ts index 92e9d5ae25..5d11dbdf70 100644 --- a/src/main/__test__/context-handler.test.ts +++ b/src/main/__test__/context-handler.test.ts @@ -3,68 +3,43 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { UserStore } from "../../common/user-store"; import type { ClusterContextHandler } from "../context-handler/context-handler"; -import type { PrometheusService, PrometheusProviderRegistry } from "../prometheus"; -import { PrometheusProvider } from "../prometheus"; -import mockFs from "mock-fs"; import { getDiForUnitTesting } from "../getDiForUnitTesting"; import createContextHandlerInjectable from "../context-handler/create-context-handler.injectable"; import type { Cluster } from "../../common/cluster/cluster"; import createKubeAuthProxyInjectable from "../kube-auth-proxy/create-kube-auth-proxy.injectable"; -import prometheusProviderRegistryInjectable from "../prometheus/prometheus-provider-registry.injectable"; - -jest.mock("electron", () => ({ - app: { - getVersion: () => "99.99.99", - getName: () => "lens", - setName: jest.fn(), - setPath: jest.fn(), - getPath: () => "tmp", - getLocale: () => "en", - setLoginItemSettings: jest.fn(), - }, - ipcMain: { - on: jest.fn(), - handle: jest.fn(), - }, -})); +import type { DiContainer } from "@ogre-tools/injectable"; +import { getInjectable } from "@ogre-tools/injectable"; +import type { PrometheusProvider } from "../prometheus/provider"; +import { prometheusProviderInjectionToken } from "../prometheus/provider"; +import { runInAction } from "mobx"; enum ServiceResult { Success, Failure, - Undefined, } -class TestProvider extends PrometheusProvider { - name = "TestProvider1"; - rateAccuracy = "1h"; - isConfigurable = false; - - constructor(public id: string, public alwaysFail: ServiceResult) { - super(); - } - - getQuery(): string { +const createTestPrometheusProvider = (kind: string, alwaysFail: ServiceResult): PrometheusProvider => ({ + kind, + name: "TestProvider1", + isConfigurable: false, + getQuery: () => { throw new Error("getQuery is not implemented."); - } - - async getPrometheusService(): Promise { - switch (this.alwaysFail) { + }, + getPrometheusService: async () => { + switch (alwaysFail) { case ServiceResult.Success: return { - id: this.id, + kind, namespace: "default", port: 7000, service: "", }; case ServiceResult.Failure: throw new Error("does fail"); - case ServiceResult.Undefined: - return undefined; } - } -} + }, +}); const clusterStub = { getProxyKubeconfig: () => ({ @@ -74,53 +49,34 @@ const clusterStub = { } as unknown as Cluster; describe("ContextHandler", () => { - let createContextHandler: (cluster: Cluster) => ClusterContextHandler | undefined; - let prometheusProviderRegistry: PrometheusProviderRegistry; + let createContextHandler: (cluster: Cluster) => ClusterContextHandler; + let di: DiContainer; beforeEach(() => { - const di = getDiForUnitTesting({ doGeneralOverrides: true }); - - mockFs({ - "tmp": {}, - }); - + di = getDiForUnitTesting({ doGeneralOverrides: true }); di.override(createKubeAuthProxyInjectable, () => ({} as any)); - prometheusProviderRegistry = di.inject(prometheusProviderRegistryInjectable); - createContextHandler = di.inject(createContextHandlerInjectable); }); - afterEach(() => { - UserStore.resetInstance(); - mockFs.restore(); - }); - describe("getPrometheusService", () => { it.each([ - [0, 0], - [0, 1], - [0, 2], - [0, 3], - ])("should throw from %d success(es) after %d failure(s)", async (successes, failures) => { - let count = 0; + [0], + [1], + [2], + [3], + ])("should throw after %d failure(s)", async (failures) => { + runInAction(() => { + for (let i = 0; i < failures; i += 1) { + di.register(getInjectable({ + id: `test-prometheus-provider-failure-${i}`, + injectionToken: prometheusProviderInjectionToken, + instantiate: () => createTestPrometheusProvider(`id_failure_${i}`, ServiceResult.Failure), + })); + } + }); - for (let i = 0; i < failures; i += 1) { - const serviceResult = i % 2 === 0 ? ServiceResult.Failure : ServiceResult.Undefined; - - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, serviceResult)); - } - - for (let i = 0; i < successes; i += 1) { - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success)); - } - - expect(() => { - // TODO: Unit test shouldn't access protected or private methods - const contextHandler = createContextHandler(clusterStub) as unknown as { getPrometheusService(): Promise }; - - return contextHandler.getPrometheusService(); - }).rejects.toBeDefined(); + expect(() => createContextHandler(clusterStub).getPrometheusDetails()).rejects.toThrowError(); }); it.each([ @@ -133,24 +89,27 @@ describe("ContextHandler", () => { [2, 2], [2, 3], ])("should pick the first provider of %d success(es) after %d failure(s)", async (successes, failures) => { - let count = 0; + runInAction(() => { + for (let i = 0; i < failures; i += 1) { + di.register(getInjectable({ + id: `test-prometheus-provider-failure-${i}`, + injectionToken: prometheusProviderInjectionToken, + instantiate: () => createTestPrometheusProvider(`id_failure_${i}`, ServiceResult.Failure), + })); + } - for (let i = 0; i < failures; i += 1) { - const serviceResult = i % 2 === 0 ? ServiceResult.Failure : ServiceResult.Undefined; + for (let i = 0; i < successes; i += 1) { + di.register(getInjectable({ + id: `test-prometheus-provider-success-${i}`, + injectionToken: prometheusProviderInjectionToken, + instantiate: () => createTestPrometheusProvider(`id_success_${i}`, ServiceResult.Success), + })); + } + }); - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, serviceResult)); - } + const details = await createContextHandler(clusterStub).getPrometheusDetails(); - for (let i = 0; i < successes; i += 1) { - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success)); - } - - // TODO: Unit test shouldn't access protected or private methods - const contextHandler = createContextHandler(clusterStub) as unknown as { getPrometheusService(): Promise }; - - const service = await contextHandler.getPrometheusService(); - - expect(service.id === `id_${failures}`); + expect(details.provider.kind === `id_failure_${failures}`); }); it.each([ @@ -163,24 +122,27 @@ describe("ContextHandler", () => { [2, 2], [2, 3], ])("should pick the first provider of %d success(es) before %d failure(s)", async (successes, failures) => { - let count = 0; + runInAction(() => { + for (let i = 0; i < failures; i += 1) { + di.register(getInjectable({ + id: `test-prometheus-provider-failure-${i}`, + injectionToken: prometheusProviderInjectionToken, + instantiate: () => createTestPrometheusProvider(`id_failure_${i}`, ServiceResult.Failure), + })); + } - for (let i = 0; i < successes; i += 1) { - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success)); - } + for (let i = 0; i < successes; i += 1) { + di.register(getInjectable({ + id: `test-prometheus-provider-success-${i}`, + injectionToken: prometheusProviderInjectionToken, + instantiate: () => createTestPrometheusProvider(`id_success_${i}`, ServiceResult.Success), + })); + } + }); - for (let i = 0; i < failures; i += 1) { - const serviceResult = i % 2 === 0 ? ServiceResult.Failure : ServiceResult.Undefined; + const details = await createContextHandler(clusterStub).getPrometheusDetails(); - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, serviceResult)); - } - - // TODO: Unit test shouldn't access protected or private methods - const contextHandler = createContextHandler(clusterStub) as unknown as { getPrometheusService(): Promise }; - - const service = await contextHandler.getPrometheusService(); - - expect(service.id === "id_0"); + expect(details.provider.kind === "id_failure_0"); }); it.each([ @@ -193,45 +155,37 @@ describe("ContextHandler", () => { [2, 2], [2, 3], ])("should pick the first provider of %d success(es) between %d failure(s)", async (successes, failures) => { - let count = 0; const beforeSuccesses = Math.floor(successes / 2); - const afterSuccesses = successes - beforeSuccesses; - for (let i = 0; i < beforeSuccesses; i += 1) { - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success)); - } + runInAction(() => { + for (let i = 0; i < beforeSuccesses; i += 1) { + di.register(getInjectable({ + id: `test-prometheus-provider-success-${i}`, + injectionToken: prometheusProviderInjectionToken, + instantiate: () => createTestPrometheusProvider(`id_success_${i}`, ServiceResult.Success), + })); + } - for (let i = 0; i < failures; i += 1) { - const serviceResult = i % 2 === 0 ? ServiceResult.Failure : ServiceResult.Undefined; + for (let i = 0; i < failures; i += 1) { + di.register(getInjectable({ + id: `test-prometheus-provider-failure-${i}`, + injectionToken: prometheusProviderInjectionToken, + instantiate: () => createTestPrometheusProvider(`id_failure_${i}`, ServiceResult.Failure), + })); + } - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, serviceResult)); - } + for (let i = beforeSuccesses; i < successes; i += 1) { + di.register(getInjectable({ + id: `test-prometheus-provider-success-${i}`, + injectionToken: prometheusProviderInjectionToken, + instantiate: () => createTestPrometheusProvider(`id_success_${i}`, ServiceResult.Success), + })); + } + }); - for (let i = 0; i < afterSuccesses; i += 1) { - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success)); - } + const details = await createContextHandler(clusterStub).getPrometheusDetails(); - // TODO: Unit test shouldn't access protected or private methods - const contextHandler = createContextHandler(clusterStub) as unknown as { getPrometheusService(): Promise }; - - const service = await contextHandler.getPrometheusService(); - - expect(service.id === "id_0"); - }); - - it("shouldn't pick the second provider of 2 success(es) after 1 failure(s)", async () => { - let count = 0; - - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Failure)); - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success)); - prometheusProviderRegistry.registerProvider(new TestProvider(`id_${count++}`, ServiceResult.Success)); - - // TODO: Unit test shouldn't access protected or private methods - const contextHandler = createContextHandler(clusterStub) as unknown as { getPrometheusService(): Promise }; - - const service = await contextHandler.getPrometheusService(); - - expect(service.id).not.toBe("id_2"); + expect(details.provider.kind === "id_success_0"); }); }); }); diff --git a/src/main/context-handler/context-handler.ts b/src/main/context-handler/context-handler.ts index a603af964d..4a46405b1d 100644 --- a/src/main/context-handler/context-handler.ts +++ b/src/main/context-handler/context-handler.ts @@ -10,11 +10,11 @@ import type httpProxy from "http-proxy"; import type { UrlWithStringQuery } from "url"; import url from "url"; import { CoreV1Api } from "@kubernetes/client-node"; -import logger from "../logger"; import type { KubeAuthProxy } from "../kube-auth-proxy/kube-auth-proxy"; import type { CreateKubeAuthProxy } from "../kube-auth-proxy/create-kube-auth-proxy.injectable"; import type { GetPrometheusProviderByKind } from "../prometheus/get-by-kind.injectable"; import type { IComputedValue } from "mobx"; +import type { Logger } from "../../common/logger"; export interface PrometheusDetails { prometheusPath: string; @@ -33,6 +33,7 @@ export interface ContextHandlerDependencies { getPrometheusProviderByKind: GetPrometheusProviderByKind; readonly authProxyCa: string; readonly prometheusProviders: IComputedValue; + readonly logger: Logger; } export interface ClusterContextHandler { @@ -78,7 +79,7 @@ export class ContextHandler implements ClusterContextHandler { protected ensurePrometheusProvider(service: PrometheusService): PrometheusProvider { if (!this.prometheusProvider) { - logger.info(`[CONTEXT-HANDLER]: using ${service.kind} as prometheus provider for clusterId=${this.cluster.id}`); + this.dependencies.logger.info(`[CONTEXT-HANDLER]: using ${service.kind} as prometheus provider for clusterId=${this.cluster.id}`); this.prometheusProvider = service.kind; } diff --git a/src/main/context-handler/create-context-handler.injectable.ts b/src/main/context-handler/create-context-handler.injectable.ts index 530f6c8385..1567721ac4 100644 --- a/src/main/context-handler/create-context-handler.injectable.ts +++ b/src/main/context-handler/create-context-handler.injectable.ts @@ -11,6 +11,7 @@ import kubeAuthProxyCertificateInjectable from "../kube-auth-proxy/kube-auth-pro import URLParse from "url-parse"; import getPrometheusProviderByKindInjectable from "../prometheus/get-by-kind.injectable"; import prometheusProvidersInjectable from "../prometheus/providers.injectable"; +import loggerInjectable from "../../common/logger.injectable"; const createContextHandlerInjectable = getInjectable({ id: "create-context-handler", @@ -20,6 +21,7 @@ const createContextHandlerInjectable = getInjectable({ createKubeAuthProxy: di.inject(createKubeAuthProxyInjectable), getPrometheusProviderByKind: di.inject(getPrometheusProviderByKindInjectable), prometheusProviders: di.inject(prometheusProvidersInjectable), + logger: di.inject(loggerInjectable), }; return (cluster: Cluster): ClusterContextHandler => {