fix: don't propagate GDK_BACKEND to subprocs#29606
Conversation
|
The |
|
@zcbenz i think that CircleCI may set that 🤔 what do you think we should do? i think this got missed the first time bc of my CircleCI login problem |
|
Hmm the reliable way to do the test is to start a child app with controlled environment variables. An example is how |
spec-main/chromium-spec.ts
Outdated
|
|
||
| it('does not propagate GDK_BACKEND', async () => { | ||
| const appPath = path.join(fixturesPath, 'api', 'gdk-backend-check'); | ||
| appProcess = ChildProcess.spawn(process.execPath, [appPath]); |
There was a problem hiding this comment.
The child process should have GDK_BACKEND explicitly cleared in its environment variables.
Also we can probably add a test to explicitly set the GDK_BACKEND and check the result.
ckerr
left a comment
There was a problem hiding this comment.
Several comments in this review but most of them are nits. I've tested this patch on a Wayland system (hirsute) & it WfM.
| options.environment["MM_NOTTTY"] = "1"; | ||
|
|
||
| // If the user set a GDK_BACKEND value of their own, use that, | ||
| // otherwise unset it becuase Chromium is setting GDK_BACKEND |
| throw new Error(`Process exited with code "${code}" signal "${signal}" output "${output}" stderr "${stderr}"`); | ||
| } | ||
|
|
||
| output = output.replace(/(\r\n|\n|\r)/gm, ''); |
There was a problem hiding this comment.
nit The global flag isn't needed here
| const appPath = path.join(fixturesPath, 'api', 'gdk-backend-check'); | ||
| appProcess = ChildProcess.spawn(process.execPath, [appPath], { | ||
| env: { | ||
| GDK_BACKEND: 'wayland' |
There was a problem hiding this comment.
(opinion, style) This test repeats this hardcoded string later in the test. If we make a local variable named GDK_BACKEND then the repetition would be avoided, plus this line could then be slightly tighter as env: { GDK_BACKEND }.
| throw new Error(`Process exited with code "${code}" signal "${signal}" output "${output}" stderr "${stderr}"`); | ||
| } | ||
|
|
||
| output = output.replace(/(\r\n|\n|\r)/gm, ''); |
There was a problem hiding this comment.
nit The global flag isn't needed here
| output = output.replace(/(\r\n|\n|\r)/gm, ''); | ||
|
|
||
| const backend = String(process.env.GDK_BACKEND); | ||
| expect(output).to.not.equal(backend); |
There was a problem hiding this comment.
I think this test will fail if run on a system where the parent process' GDK_BACKEND actually is 'wayland'?
Maybe we should inject nonsense values into the child instead of using x11/wayland in these tests to ensure there's not conflict with the system the tests are running on
| } | ||
| }); | ||
|
|
||
| it('does not propagate GDK_BACKEND', async () => { |
There was a problem hiding this comment.
OK there are some nits in this PR but overall I think the PR is good & works. This right here is the main thing that need to get changed -- the production code in this PR changes the environment variables in XDGUtil(), right before calling base::LaucnhProcess to invoke xdg-open or xdg-mail or (some various distro-specific way of trashing a file). This is fine, I think it addresses the use case in #28436
But this test is just looking at an arbitrarily-spawned ChildProcess. XDGUtil() isn't invoked for that and so I don't think these tests ever reach the codepaths that we're changing.
I see at least three options:
(1) decouple the GDK_BACKEND environment clobbering from Electron's XDGUtil() command, use extract-method to move it somewhere else that is more accessible by our tests
(2) Leave the production code where it is and use xdg-open to test the environment. This requires more complexity & setup in the tests, but should work with the production code as-is.. Loosely speaking, xdg-open works by looking at the filetype of the file being opened and looks for that file suffix in a .desktop file somewhere in the $XDG_DATA_HOME folder. When it finds it, It tries to launch the that .desktop file's app with the specified file. So we could make use of this by creating a script that takes a filename as input and dumps its environment variables to that file. Then we invent a file suffix that's not used by anyone else and create a fake .desktop entry that invokes our env-dumper script to "handle" that fake filesuffix. Then we call XDGOpen() for that file, which does reach the codepath we want to test. It should kick off our env dumper script. Then we can inspect the dumped env to see if the test passed. Then we remove the fake .desktop file from XDG_DATA_HOME to ensure our tests don't pollute the account running the test. 💫
(3) Remove the tests altogether. They are not testing what they're supposed to, so they shouldn't be left as-is. And doing a real test for this is kind of a pain. 🙂
My preference would be to try (2) but I wouldn't block the PR on it.
| // will make sure that they get unset from the environment via | ||
| // AlterEnvironment(). |
There was a problem hiding this comment.
Nice job explaining clearly & succinctly that passing in an empty string will clobber the value altogether 👍
My first thought reading the code was "This isn't unsetting it; it's setting it to an empty string" so it's great explain (a) that's not the case and (b) that it's AlterEnvironment that strips out key/vals where val is an empty string
Co-authored-by: Charles Kerr <charles@charleskerr.com>
|
Has there been any progress on this? |
|
Closed due to inactivity |
Description of Change
#28898
was created before the Chromium changes to
absl::optionaland so caused build failures when it was merged.Checklist
npm testpassesRelease Notes
Notes: none.