Skip to content

Commit 0afcbf3

Browse files
stephentoubCopilot
andcommitted
Repoint the .NET E2E process cwd before deleting work directories
The in-process transport points the host process cwd at the context work directory because the native worker inherits it. The assembly-level isolation attribute only restores the cwd around tests that actually execute, so the cwd could still reference a work directory that context disposal then deleted. Every later Process.Start failed resolving its executable because getcwd() returned ENOENT, cascading hundreds of .NET E2E failures in the in-process matrix cells. Repoint the cwd at its load-time value both before deleting the work directory and before creating a new context. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 812b44f2-ef93-4b32-b051-c7092f612279
1 parent ef24129 commit 0afcbf3

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

dotnet/test/Harness/E2ETestContext.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ private E2ETestContext(string homeDir, string workDir, string proxyUrl, ReplayPr
4040

4141
public static async Task<E2ETestContext> CreateAsync()
4242
{
43+
// A previous in-process context may have left this process's cwd inside a work
44+
// directory that has since been deleted. getcwd() then fails, which breaks
45+
// Process.Start below while it resolves the proxy executable. Repoint the cwd at
46+
// the ambient value first; SetCurrentDirectory succeeds even if the old cwd is gone.
47+
InProcessEnvIsolation.RestoreAmbientWorkingDirectory();
48+
4349
var repoRoot = FindRepoRoot();
4450

4551
var homeDir = Path.Combine(Path.GetTempPath(), $"copilot-test-config-{Guid.NewGuid()}");
@@ -478,6 +484,14 @@ public async ValueTask DisposeAsync()
478484
var isCI = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ACTIONS"));
479485
try { await _proxy.StopAsync(skipWritingCache: isCI); } catch (Exception ex) when (IsTransientCleanupException(ex)) { errors.Add(ex); }
480486

487+
// The in-process worker inherits this process's cwd, so ApplyInProcessEnvironment
488+
// may have pointed it at WorkDir. The assembly-level isolation attribute only
489+
// restores it around tests that actually execute, so a statically skipped test
490+
// can leave the cwd inside a directory this method is about to delete. Every
491+
// later Process.Start would then fail resolving its executable because getcwd()
492+
// returns ENOENT. Repoint the cwd before deleting anything.
493+
InProcessEnvIsolation.RestoreAmbientWorkingDirectory();
494+
481495
try { await DeleteDirectoryAsync(HomeDir); } catch (Exception ex) when (IsTransientCleanupException(ex)) { errors.Add(ex); }
482496
try { await DeleteDirectoryAsync(WorkDir); } catch (Exception ex) when (IsTransientCleanupException(ex)) { errors.Add(ex); }
483497

dotnet/test/Harness/InProcessEnvIsolation.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,22 @@ public static void NeutralizeAmbientCredentials()
6767
public static void SetWorkingDirectory(string path) =>
6868
Directory.SetCurrentDirectory(path);
6969

70+
// Repoints the process working directory at its load-time value. Callers must not
71+
// read Directory.GetCurrentDirectory() first: an in-process test can chdir into a
72+
// temp work dir that the harness then deletes, so getcwd() would throw
73+
// FileNotFoundException. SetCurrentDirectory to an absolute path succeeds
74+
// regardless of whether the old cwd still exists.
75+
public static void RestoreAmbientWorkingDirectory() =>
76+
Directory.SetCurrentDirectory(s_ambientCwd);
77+
7078
public static void RestoreAmbient()
7179
{
7280
// Unconditionally repoint the process cwd at its load-time value. We must
7381
// not read Directory.GetCurrentDirectory() first: an in-process test can
7482
// chdir into a temp work dir that the harness then deletes, so getcwd()
7583
// would throw FileNotFoundException. SetCurrentDirectory to an absolute
7684
// path succeeds regardless of whether the old cwd still exists.
77-
Directory.SetCurrentDirectory(s_ambientCwd);
85+
RestoreAmbientWorkingDirectory();
7886

7987
foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables())
8088
{

0 commit comments

Comments
 (0)