From ffb840f0ed0f663f99fedc194c2c19f5bedeeaf9 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 8 Apr 2022 10:42:29 -0400 Subject: [PATCH] fix cluster.test.ts tests Signed-off-by: Sebastian Malton --- src/common/cluster/cluster.ts | 57 +++++++++---------- src/common/logger.ts | 1 + src/main/__test__/cluster.test.ts | 27 +-------- .../create-cluster.injectable.ts | 2 + src/main/getDiForUnitTesting.ts | 1 + .../create-cluster.injectable.ts | 6 +- 6 files changed, 36 insertions(+), 58 deletions(-) diff --git a/src/common/cluster/cluster.ts b/src/common/cluster/cluster.ts index 0720b579a3..56d46e1107 100644 --- a/src/common/cluster/cluster.ts +++ b/src/common/cluster/cluster.ts @@ -3,7 +3,6 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { ipcMain } from "electron"; import { action, comparer, computed, makeObservable, observable, reaction, when } from "mobx"; import { broadcastMessage } from "../ipc"; import type { ClusterContextHandler } from "../../main/context-handler/context-handler"; @@ -14,7 +13,6 @@ import type { KubeconfigManager } from "../../main/kubeconfig-manager/kubeconfig import { loadConfigFromFile, loadConfigFromFileSync, validateKubeConfig } from "../kube-helpers"; import type { KubeApiResource, KubeResource } from "../rbac"; import { apiResourceRecord, apiResources } from "../rbac"; -import logger from "../../main/logger"; import { VersionDetector } from "../../main/cluster-detectors/version-detector"; import { DetectorRegistry } from "../../main/cluster-detectors/detector-registry"; import plimit from "p-limit"; @@ -26,11 +24,13 @@ import { clusterListNamespaceForbiddenChannel } from "../ipc/cluster"; import type { CanI } from "./authorization-review.injectable"; import type { ListNamespaces } from "./list-namespaces.injectable"; import assert from "assert"; +import type { Logger } from "../logger"; export interface ClusterDependencies { readonly directoryForKubeConfigs: string; - createKubeconfigManager: (cluster: Cluster) => KubeconfigManager; - createContextHandler: (cluster: Cluster) => ClusterContextHandler; + readonly logger: Logger; + createKubeconfigManager: (cluster: Cluster) => KubeconfigManager | undefined; + createContextHandler: (cluster: Cluster) => ClusterContextHandler | undefined; createKubectl: (clusterVersion: string) => Kubectl; createAuthorizationReview: (config: KubeConfig) => CanI; createListNamespaces: (config: KubeConfig) => ListNamespaces; @@ -256,17 +256,14 @@ export class Cluster implements ClusterModel, ClusterState { this.apiUrl = cluster.server; - if (ipcMain) { - // for the time being, until renderer gets its own cluster type - this._contextHandler = this.dependencies.createContextHandler(this); - this._proxyKubeconfigManager = this.dependencies.createKubeconfigManager(this); - - logger.debug(`[CLUSTER]: Cluster init success`, { - id: this.id, - context: this.contextName, - apiUrl: this.apiUrl, - }); - } + // for the time being, until renderer gets its own cluster type + this._contextHandler = this.dependencies.createContextHandler(this); + this._proxyKubeconfigManager = this.dependencies.createKubeconfigManager(this); + this.dependencies.logger.debug(`[CLUSTER]: Cluster init success`, { + id: this.id, + context: this.contextName, + apiUrl: this.apiUrl, + }); } /** @@ -309,7 +306,7 @@ export class Cluster implements ClusterModel, ClusterState { * @internal */ protected bindEvents() { - logger.info(`[CLUSTER]: bind events`, this.getMeta()); + this.dependencies.logger.info(`[CLUSTER]: bind events`, this.getMeta()); const refreshTimer = setInterval(() => !this.disconnected && this.refresh(), 30000); // every 30s const refreshMetadataTimer = setInterval(() => !this.disconnected && this.refreshMetadata(), 900000); // every 15 minutes @@ -330,13 +327,13 @@ export class Cluster implements ClusterModel, ClusterState { * @internal */ protected async recreateProxyKubeconfig() { - logger.info("[CLUSTER]: Recreating proxy kubeconfig"); + this.dependencies.logger.info("[CLUSTER]: Recreating proxy kubeconfig"); try { await this.proxyKubeconfigManager.clear(); await this.getProxyKubeconfig(); } catch (error) { - logger.error(`[CLUSTER]: failed to recreate proxy kubeconfig`, error); + this.dependencies.logger.error(`[CLUSTER]: failed to recreate proxy kubeconfig`, error); } } @@ -350,7 +347,7 @@ export class Cluster implements ClusterModel, ClusterState { return this.pushState(); } - logger.info(`[CLUSTER]: activate`, this.getMeta()); + this.dependencies.logger.info(`[CLUSTER]: activate`, this.getMeta()); if (!this.eventsDisposer.length) { this.bindEvents(); @@ -368,7 +365,7 @@ export class Cluster implements ClusterModel, ClusterState { await this.refreshAccessibility(); // download kubectl in background, so it's not blocking dashboard this.ensureKubectl() - .catch(error => logger.warn(`[CLUSTER]: failed to download kubectl for clusterId=${this.id}`, error)); + .catch(error => this.dependencies.logger.warn(`[CLUSTER]: failed to download kubectl for clusterId=${this.id}`, error)); this.broadcastConnectUpdate("Connected, waiting for view to load ..."); } @@ -392,7 +389,7 @@ export class Cluster implements ClusterModel, ClusterState { */ @action async reconnect() { - logger.info(`[CLUSTER]: reconnect`, this.getMeta()); + this.dependencies.logger.info(`[CLUSTER]: reconnect`, this.getMeta()); await this.contextHandler?.restartServer(); this.disconnected = false; } @@ -402,10 +399,10 @@ export class Cluster implements ClusterModel, ClusterState { */ @action disconnect(): void { if (this.disconnected) { - return void logger.debug("[CLUSTER]: already disconnected", { id: this.id }); + return void this.dependencies.logger.debug("[CLUSTER]: already disconnected", { id: this.id }); } - logger.info(`[CLUSTER]: disconnecting`, { id: this.id }); + this.dependencies.logger.info(`[CLUSTER]: disconnecting`, { id: this.id }); this.eventsDisposer(); this.contextHandler?.stopServer(); this.disconnected = true; @@ -416,7 +413,7 @@ export class Cluster implements ClusterModel, ClusterState { this.allowedNamespaces = []; this.resourceAccessStatuses.clear(); this.pushState(); - logger.info(`[CLUSTER]: disconnected`, { id: this.id }); + this.dependencies.logger.info(`[CLUSTER]: disconnected`, { id: this.id }); } /** @@ -425,7 +422,7 @@ export class Cluster implements ClusterModel, ClusterState { */ @action async refresh(opts: ClusterRefreshOptions = {}) { - logger.info(`[CLUSTER]: refresh`, this.getMeta()); + this.dependencies.logger.info(`[CLUSTER]: refresh`, this.getMeta()); await this.refreshConnectionStatus(); if (this.accessible) { @@ -443,7 +440,7 @@ export class Cluster implements ClusterModel, ClusterState { */ @action async refreshMetadata() { - logger.info(`[CLUSTER]: refreshMetadata`, this.getMeta()); + this.dependencies.logger.info(`[CLUSTER]: refreshMetadata`, this.getMeta()); const metadata = await DetectorRegistry.getInstance().detectForCluster(this); const existingMetadata = this.metadata; @@ -514,7 +511,7 @@ export class Cluster implements ClusterModel, ClusterState { return ClusterStatus.AccessGranted; } catch (error) { - logger.error(`[CLUSTER]: Failed to connect to "${this.contextName}": ${error}`); + this.dependencies.logger.error(`[CLUSTER]: Failed to connect to "${this.contextName}": ${error}`); if (isRequestError(error)) { if (error.statusCode) { @@ -594,7 +591,7 @@ export class Cluster implements ClusterModel, ClusterState { * @param state cluster state */ pushState(state = this.getState()) { - logger.silly(`[CLUSTER]: push-state`, state); + this.dependencies.logger.silly(`[CLUSTER]: push-state`, state); broadcastMessage("cluster:state", this.id, state); } @@ -617,7 +614,7 @@ export class Cluster implements ClusterModel, ClusterState { broadcastConnectUpdate(message: string, isError = false): void { const update: KubeAuthUpdate = { message, isError }; - logger.debug(`[CLUSTER]: broadcasting connection update`, { ...update, meta: this.getMeta() }); + this.dependencies.logger.debug(`[CLUSTER]: broadcasting connection update`, { ...update, meta: this.getMeta() }); broadcastMessage(`cluster:${this.id}:connection-update`, update); } @@ -637,7 +634,7 @@ export class Cluster implements ClusterModel, ClusterState { if (namespaceList.length === 0 && error instanceof HttpError && error.statusCode === 403) { const { response } = error as HttpError & { response: Response }; - logger.info("[CLUSTER]: listing namespaces is forbidden, broadcasting", { clusterId: this.id, error: response.body }); + this.dependencies.logger.info("[CLUSTER]: listing namespaces is forbidden, broadcasting", { clusterId: this.id, error: response.body }); broadcastMessage(clusterListNamespaceForbiddenChannel, this.id); } diff --git a/src/common/logger.ts b/src/common/logger.ts index 172f3e2fe8..7df4db08c7 100644 --- a/src/common/logger.ts +++ b/src/common/logger.ts @@ -15,6 +15,7 @@ export interface Logger { error: (message: string, ...args: any) => void; debug: (message: string, ...args: any) => void; warn: (message: string, ...args: any) => void; + silly: (message: string, ...args: any) => void; } const logLevel = process.env.LOG_LEVEL diff --git a/src/main/__test__/cluster.test.ts b/src/main/__test__/cluster.test.ts index f8c699b473..9f63448139 100644 --- a/src/main/__test__/cluster.test.ts +++ b/src/main/__test__/cluster.test.ts @@ -3,32 +3,6 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -const logger = { - silly: jest.fn(), - debug: jest.fn(), - log: jest.fn(), - info: jest.fn(), - error: jest.fn(), - crit: jest.fn(), -}; - -jest.mock("winston", () => ({ - format: { - colorize: jest.fn(), - combine: jest.fn(), - simple: jest.fn(), - label: jest.fn(), - timestamp: jest.fn(), - printf: jest.fn(), - splat: jest.fn(), - }, - createLogger: jest.fn().mockReturnValue(logger), - transports: { - Console: jest.fn(), - File: jest.fn(), - }, -})); - jest.mock("../../common/ipc"); jest.mock("request"); jest.mock("request-promise-native"); @@ -109,6 +83,7 @@ describe("create clusters", () => { }); afterEach(() => { + cluster.disconnect(); mockFs.restore(); }); diff --git a/src/main/create-cluster/create-cluster.injectable.ts b/src/main/create-cluster/create-cluster.injectable.ts index d62c37e9c7..633e7937af 100644 --- a/src/main/create-cluster/create-cluster.injectable.ts +++ b/src/main/create-cluster/create-cluster.injectable.ts @@ -12,6 +12,7 @@ import createContextHandlerInjectable from "../context-handler/create-context-ha import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token"; import authorizationReviewInjectable from "../../common/cluster/authorization-review.injectable"; import listNamespacesInjectable from "../../common/cluster/list-namespaces.injectable"; +import loggerInjectable from "../../common/logger.injectable"; const createClusterInjectable = getInjectable({ id: "create-cluster", @@ -24,6 +25,7 @@ const createClusterInjectable = getInjectable({ createContextHandler: di.inject(createContextHandlerInjectable), createAuthorizationReview: di.inject(authorizationReviewInjectable), createListNamespaces: di.inject(listNamespacesInjectable), + logger: di.inject(loggerInjectable), }; return (model) => new Cluster(dependencies, model); diff --git a/src/main/getDiForUnitTesting.ts b/src/main/getDiForUnitTesting.ts index 823500a074..5473407285 100644 --- a/src/main/getDiForUnitTesting.ts +++ b/src/main/getDiForUnitTesting.ts @@ -108,6 +108,7 @@ export const getDiForUnitTesting = ( debug: noop, error: (message: string, ...args: any) => console.error(message, ...args), info: noop, + silly: noop, })); } diff --git a/src/renderer/create-cluster/create-cluster.injectable.ts b/src/renderer/create-cluster/create-cluster.injectable.ts index a1c244568c..e9a46d6c72 100644 --- a/src/renderer/create-cluster/create-cluster.injectable.ts +++ b/src/renderer/create-cluster/create-cluster.injectable.ts @@ -7,6 +7,7 @@ import type { ClusterDependencies } from "../../common/cluster/cluster"; import { Cluster } from "../../common/cluster/cluster"; import directoryForKubeConfigsInjectable from "../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable"; import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token"; +import loggerInjectable from "../../common/logger.injectable"; const createClusterInjectable = getInjectable({ id: "create-cluster", @@ -14,11 +15,12 @@ const createClusterInjectable = getInjectable({ instantiate: (di) => { const dependencies: ClusterDependencies = { directoryForKubeConfigs: di.inject(directoryForKubeConfigsInjectable), - createKubeconfigManager: () => { throw new Error("Tried to access back-end feature in front-end."); }, + createKubeconfigManager: () => undefined, createKubectl: () => { throw new Error("Tried to access back-end feature in front-end.");}, - createContextHandler: () => { throw new Error("Tried to access back-end feature in front-end."); }, + createContextHandler: () => undefined, createAuthorizationReview: () => { throw new Error("Tried to access back-end feature in front-end."); }, createListNamespaces: () => { throw new Error("Tried to access back-end feature in front-end."); }, + logger: di.inject(loggerInjectable), }; return (model) => new Cluster(dependencies, model);