1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

fix cluster.test.ts tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-04-08 10:42:29 -04:00
parent 199f142559
commit ffb840f0ed
6 changed files with 36 additions and 58 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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();
});

View File

@ -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);

View File

@ -108,6 +108,7 @@ export const getDiForUnitTesting = (
debug: noop,
error: (message: string, ...args: any) => console.error(message, ...args),
info: noop,
silly: noop,
}));
}

View File

@ -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);