Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix failing to start shell being hidden from user #5626

Closed
wants to merge 86 commits into from

Conversation

Nokel81
Copy link
Collaborator

@Nokel81 Nokel81 commented Jun 14, 2022

Signed-off-by: Sebastian Malton sebastian@malton.name

fixes #5513

@Nokel81 Nokel81 added the bug Something isn't working label Jun 14, 2022
@Nokel81 Nokel81 added this to the 5.7.0 milestone Jun 14, 2022
@Nokel81 Nokel81 requested a review from a team as a code owner June 14, 2022 16:21
@Nokel81 Nokel81 requested review from jweak and JAtula and removed request for a team June 14, 2022 16:21
@Nokel81 Nokel81 modified the milestones: 5.7.0, 5.6.0 Jun 27, 2022
@Nokel81 Nokel81 modified the milestones: 6.0.0, 6.1.0 Jul 21, 2022
@Nokel81 Nokel81 marked this pull request as draft July 22, 2022 14:46
@Nokel81 Nokel81 modified the milestones: 6.1.0, 6.0.1 Jul 29, 2022
@Nokel81 Nokel81 modified the milestones: 6.0.1, 6.0.2 Aug 9, 2022
@Nokel81 Nokel81 removed this from the 6.0.2 milestone Sep 2, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Oct 5, 2022

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@Nokel81 Nokel81 marked this pull request as ready for review October 5, 2022 20:46
@github-actions
Copy link
Contributor

github-actions bot commented Oct 5, 2022

Conflicts have been resolved. A maintainer will review the pull request shortly.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 5, 2022

Conflicts have been resolved. A maintainer will review the pull request shortly.

@github-actions
Copy link
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@@ -82,7 +82,7 @@ const setupLensProxyInjectable = getInjectable({
};
},

causesSideEffects: true,
// causesSideEffects: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove line

this.connections.set(tab.id, { api, terminal });
});

const connectionPromise = api.connect();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we not awaiting for promise?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that the users of connect can be sync for when they want to do things that are not related to the connection being fully active.

Comment on lines +21 to +22
import type { RequestFromChannel } from "../../../renderer/utils/channel/request-from-channel.injectable";
import requestFromChannelInjectable from "../../../renderer/utils/channel/request-from-channel.injectable";
Copy link
Contributor

@jansav jansav Jan 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't be removing the injection token. requestFromChannel is contract which is implemented separately in renderer and main but the contract is same.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important thing is that channel is something that can be called from anywhere and it doesn't know who answers. That being said, the "request" or "message" doesn't even have to go over IPC, the listener and caller can be located in same environment. (It doesn't work like this yet due YAGNI but conceptually that's what Channel is.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contract isn't the same. A request channel being requested on has no meaning on main and thus main shouldn't even know about it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

main can request stuff from channel. It just doesn't know who answers it, might be main or renderer.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it cannot, where is that possible?


const provideInitialValuesForSyncBoxesInjectable = getInjectable({
id: "provide-initial-values-for-sync-boxes",

instantiate: (di) => ({
id: "provide-initial-values-for-sync-boxes",
run: async () => {
const requestFromChannel = di.inject(requestFromChannelInjectionToken);
const requestFromChannel = di.inject(requestFromChannelInjectable);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert, see above discussion about the requirement for injectionToken.

Comment on lines 59 to 62
afterEach(() => {
builder.quit();
});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this implies that there is some shared global state in the builder. We need to figure out what that is and remove it. There shouldn't be any requirement for cleanups after test.

@@ -703,6 +706,13 @@ export const getApplicationBuilder = () => {
await startApplication({ shouldStartHidden: true });
},

quit() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This isn't correct way to quit the application. This should use all same code than we use when application is quit in real life. Extract the function used in production and use it here.

  2. quit shouldn't be part of all behavioural tests. There should be explicit behavioural tests for quitting the application and rest of them shouldn't know anything about it. That being said, afterEach requirement is not welcome.

@@ -449,7 +449,7 @@
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.11.1",
"webpack-node-externals": "^3.0.0",
"xterm": "^4.19.0",
"xterm": "^5.0.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit removes the last usage for earlier introduce image-snapshot dependency. Could you remove it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure also

@@ -450,27 +449,15 @@
"webpack-dev-server": "^4.11.1",
"webpack-node-externals": "^3.0.0",
"xterm": "^5.0.0",
"xterm-addon-fit": "^0.5.0"
"xterm-addon-fit": "^0.5.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this commit part of this monster PR at all? Doesn't have anything to do with fixing something, it's adding stuff.

@@ -27,14 +27,21 @@ const shellApiRequestInjectable = getInjectable({
const nodeName = searchParams.get("node");
const shellToken = searchParams.get("shellToken");

console.log("got shell api request", { tabId, clusterId: cluster?.id, nodeName });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switch to using logger.

"create-release-pr": "node ./scripts/create-release-pr.mjs"
"create-release-pr": "node ./scripts/create-release-pr.mjs",
"prefix-canvas-deps": "npx swc ./scripts/fix-canvas-deps.ts -o ./scripts/fix-canvas-deps.mjs",
"fix-canvas-deps": "node ./scripts/fix-canvas-deps.mjs"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the requirement for canvas in the first place? This is complexity which shouldn't be included without very good reason.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Canvas is required for some of the tests IIRC, might not be necessary if we upgrade to xtermJs 5 which adds the DOM based renderer for testing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this complexity, I would say that we stop testing xtermjs directly and only test the contract (our wrapper).


expect(actual).toHaveLength(0);
it("does not show the kube object status", async () => {
await waitFor(() => expect(rendered.baseElement.querySelectorAll(".KubeObjectStatusIcon")).toHaveLength(0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is slow unit test. In unit test we should always know if the item is there or not.

);

expect(actual).toHaveLength(1);
await waitFor(() => expect(rendered.baseElement.querySelectorAll(".KubeObjectStatusIcon")).toHaveLength(1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is slow unit test. In unit test we should always know if the item is there or not.

@@ -136,7 +137,7 @@ describe("opening application window using tray", () => {
});

it("starts loading of content for the application window", () => {
expect(callForApplicationWindowHtmlMock).toHaveBeenCalledWith("https://lens.app:42");
expect(callForApplicationWindowHtmlMock).toHaveBeenCalledWith(matches((val) => val.startsWith("http://lens.app:")));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side-effect with the port number :(

return (query) => new TerminalApi(deps, query);
return (query) => {
const hostedClusterId = di.inject(hostedClusterIdInjectable);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This injection should be done in the instantiate time and not in the function.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes good point.

@@ -20,12 +20,12 @@ import { disposer, isDefined, isRequestError, toJS } from "../utils";
import type { Response } from "request";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Update (mostly just) snapshots and a few other tests"

Please be more careful with commit names, this one does a lot more than it says. Almost skipped reviewing because it said "update snapshots"

@@ -43,7 +43,7 @@ describe("listing active helm repositories in preferences", () => {

builder.beforeApplicationStart((mainDi) => {
mainDi.override(readYamlFileInjectable, () => readYamlFileMock);
mainDi.override(execFileInjectable, () => execFileMock);
mainDi.override(exrequestPublicHelmRepositoriesInjectable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo?

@@ -30,7 +30,7 @@ describe("preferences - navigation to kubernetes preferences", () => {
mainDi.override(
getActiveHelmRepositoriesInjectable,
() => async () => ({ callWasSuccessful: true, response: [] }),
);
);requestPublicHelmRepositoriesInjectable;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo?

/**
* This fetch is for requesting items from the Lens Proxy and thus does not cause side effects
*/
const lensFetchInjectable = getInjectable({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we override this in behavioural test with a fake that does whatever the "server" does. So basically maps the request to correct route in backend.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah sure.

});
export default getGlobalOverride(computeUnixShellEnvironmentInjectable, () => async () => ({
callWasSuccessful: true,
response: process.env,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is introducing side effect to override. In global override the response should be always same.

@@ -78,7 +79,7 @@
"build:theme-vars": "yarn run ts-node build/build_theme_vars.ts",
"lint": "PROD=true yarn run eslint --ext js,ts,tsx --max-warnings=0 .",
"lint:fix": "yarn run lint --fix",
"postinstall": "yarn run fix-canvas-deps",
"postinstall": "yarn run fix-canvas-deps && yarn run compile:node-fetch",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of these introduce level of complexity that makes me question why they are really needed.

import type { DiContainer } from "@ogre-tools/injectable";
import appPathsInjectable from "./app-paths.injectable";

describe("app-paths", () => {
let builder: ApplicationBuilder;

beforeEach(() => {
builder = getApplicationBuilder();
setupInitializingApplicationBuilder(b => builder = b);
Copy link
Contributor

@jansav jansav Jan 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh. This would be hiding a lot of important details. It also introduces dependency between order of these before each loops. If the motivation is to remove the requirement for afterEach from usages, then we should figure out why we need the afterEach at all. It shouldn't be there.

Comment on lines 749 to 753
// console.log({
// resource,
// allowed: toJS([...this.allowedResources]),
// });

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug code


const newVal = await getter();

runInAction(() => box.set(newVal));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dangerous. Transaction should be controlled from the useplace.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not when you expect the helper function to be an action

@@ -1,11 +0,0 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit doesn't explain at all why these global overrides were removed?

Comment on lines +77 to +79
/**
* This is needed for getting XTermJs to work in tests
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we override x-term-js with something that mimics the behaviour but is in our full control?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is worth it. But maybe

@@ -0,0 +1,46 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole file feels like an amazing kludge, and brittle too. Is there really no other way?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I could not find one after banging my head for a few days. The fact that we use Electron seem to break some of the dependencies auto detecting certain configuration things.

@Nokel81 Nokel81 closed this Jan 11, 2023
@Nokel81 Nokel81 modified the milestones: 6.3.1, 6.4.0 Jan 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/terminal bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to connect to Pods' shell using lens
3 participants