-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Conversation
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
03e449b
to
ecffed8
Compare
Conflicts have been resolved. A maintainer will review the pull request shortly. |
Conflicts have been resolved. A maintainer will review the pull request shortly. |
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
ecffed8
to
2a5871e
Compare
@@ -82,7 +82,7 @@ const setupLensProxyInjectable = getInjectable({ | |||
}; | |||
}, | |||
|
|||
causesSideEffects: true, | |||
// causesSideEffects: true, |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we not await
ing for promise?
There was a problem hiding this comment.
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.
import type { RequestFromChannel } from "../../../renderer/utils/channel/request-from-channel.injectable"; | ||
import requestFromChannelInjectable from "../../../renderer/utils/channel/request-from-channel.injectable"; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
.
afterEach(() => { | ||
builder.quit(); | ||
}); | ||
|
There was a problem hiding this comment.
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() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
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.
-
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", |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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 }); |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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:"))); |
There was a problem hiding this comment.
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); | ||
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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"; |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo?
src/features/window-location/main/for-top-bar-state-handler.injectable.ts
Show resolved
Hide resolved
/** | ||
* This fetch is for requesting items from the Lens Proxy and thus does not cause side effects | ||
*/ | ||
const lensFetchInjectable = getInjectable({ |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
// console.log({ | ||
// resource, | ||
// allowed: toJS([...this.allowedResources]), | ||
// }); | ||
|
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 @@ | |||
/** |
There was a problem hiding this comment.
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?
/** | ||
* This is needed for getting XTermJs to work in tests | ||
*/ |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 @@ | |||
/** |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
Signed-off-by: Sebastian Malton sebastian@malton.name
fixes #5513