Skip to content

Commit d8eb5a6

Browse files
Use temp directory as TestExecutionDirectory in RunTestsOnHelix.sh (#45022)
I looked into using the temp directory on Unix like we do on Windows and it uncovered two issues (#3923 was an earlier report) 1) Helix sets `$TMPDIR` to `/tmp/helix` but on macOS `/tmp` is a symlink to `/private/tmp` and a bunch of tests then fail since parts of the sdk see `/tmp` and other parts see the resolved `/private/tmp` path and checks for path equality and other similar logic fails (see also #37687) -> this was relatively easy to solve by making sure we use the resolved path as the TestExecutionDirectory. Ideally we'd solve the underlying symlink equality issue but that's a bigger change. 2) the test `GivenWorkloadUpdateAcrossFeatureBandsItUpdatesPacks` started failing in CI but only on Linux. I tried reproducing it locally but it always passed. Then I stepped through it under the debugger and noticed that I got this exception [here](https://github.com/dotnet/sdk/blob/7ad934d3ac49c0dabaa500b5f9de73493292807b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs#L258-L263): > System.IO.IOException : The process cannot access the file '/Users/alexander/dev/sdk/artifacts/tmp/Debug/GivenWorkload---B940FC6C/dotnet/metadata/workloads/InstalledPacks/v1/mock-pack-2/2.0.0/5.0.100' because it is being used by another process. ... but we're swallowing the exception so the test accidentally passed because the workload GC was aborted. I tracked it down to us not closing the file stream created by File.Create() during the test, once I fixed that the test now consistently failed everywhere (it asserts that the file should exist but it gets deleted during workload GC). This was fixed by mocking up a 5.0.1xx SDK install so that the installation records for that feature band won't be deleted. We're now correctly closing all file streams created by File.Create() in the codebase. Co-authored-by: Daniel Plaisted <[email protected]>
1 parent cb21681 commit d8eb5a6

File tree

10 files changed

+25
-23
lines changed

10 files changed

+25
-23
lines changed

build/RunTestsOnHelix.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ export MicrosoftNETBuildExtensionsTargets=$HELIX_CORRELATION_PAYLOAD/ex/msbuildE
99
export DOTNET_ROOT=$HELIX_CORRELATION_PAYLOAD/d
1010
export PATH=$DOTNET_ROOT:$PATH
1111

12-
export TestExecutionDirectory=$(pwd)/testExecutionDirectory
13-
mkdir $TestExecutionDirectory
12+
export TestExecutionDirectory=$(realpath "$(mktemp -d "${TMPDIR:-/tmp}"/dotnetSdkTests.XXXXXXXX)")
1413
export DOTNET_CLI_HOME=$TestExecutionDirectory/.dotnet
1514
cp -a $HELIX_CORRELATION_PAYLOAD/t/TestExecutionDirectoryFiles/. $TestExecutionDirectory/
1615

@@ -36,4 +35,4 @@ dotnet nuget remove source dotnet-libraries-transport --configfile $TestExecutio
3635
dotnet nuget remove source dotnet-tools-transport --configfile $TestExecutionDirectory/NuGet.config
3736
dotnet nuget remove source dotnet-libraries --configfile $TestExecutionDirectory/NuGet.config
3837
dotnet nuget remove source dotnet-eng --configfile $TestExecutionDirectory/NuGet.config
39-
dotnet nuget list source --configfile $TestExecutionDirectory/NuGet.config
38+
dotnet nuget list source --configfile $TestExecutionDirectory/NuGet.config

src/WebSdk/Publish/Tasks/Tasks/MsDeploy/CreateMSDeployScript.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ public override bool Execute()
2121
{
2222
if (!File.Exists(ScriptFullPath))
2323
{
24-
File.Create(ScriptFullPath);
24+
File.Create(ScriptFullPath).Close();
2525
}
2626

2727
File.WriteAllLines(ScriptFullPath, GetReplacedFileContents(Resources.MsDeployBatchFile));
2828

2929
if (!File.Exists(ReadMeFullPath))
3030
{
31-
File.Create(ReadMeFullPath);
31+
File.Create(ReadMeFullPath).Close();
3232
}
3333

3434
File.WriteAllLines(ReadMeFullPath, GetReplacedFileContents(Resources.MsDeployReadMe));

src/WebSdk/Publish/Tasks/Tasks/MsDeploy/CreateManifestFile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public override bool Execute()
106106
{
107107
if (!File.Exists(ManifestFile))
108108
{
109-
File.Create(ManifestFile);
109+
File.Create(ManifestFile).Close();
110110
}
111111
WriteManifestsToFile(Log, m_manifests, ManifestFile);
112112
}

src/WebSdk/Publish/Tasks/Tasks/MsDeploy/CreateParameterFile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ public override bool Execute()
286286
{
287287
if (!File.Exists(DeclareSetParameterFile))
288288
{
289-
File.Create(DeclareSetParameterFile);
289+
File.Create(DeclareSetParameterFile).Close();
290290
}
291291

292292
if (!string.IsNullOrEmpty(DeclareParameterFile))

test/HelixTasks/SDKCustomCreateXUnitWorkItemsWithTestExclusion.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,6 @@ private async Task<List<ITaskItem>> PrepareWorkItem(ITaskItem xunitProject)
132132
throw new NotImplementedException("does not support non support the runtime specified");
133133
}
134134

135-
// On mac due to https://github.com/dotnet/sdk/issues/3923, we run against workitem directory
136-
// but on Windows, if we running against working item diretory, we would hit long path.
137135
string testExecutionDirectory = netFramework ? "-e DOTNET_SDK_TEST_EXECUTION_DIRECTORY=%TestExecutionDirectory%" : IsPosixShell ? "-testExecutionDirectory $TestExecutionDirectory" : "-testExecutionDirectory %TestExecutionDirectory%";
138136

139137
string msbuildAdditionalSdkResolverFolder = netFramework ? "-e DOTNET_SDK_TEST_MSBUILDSDKRESOLVER_FOLDER=%HELIX_CORRELATION_PAYLOAD%\\r" : IsPosixShell ? "" : "-msbuildAdditionalSdkResolverFolder %HELIX_CORRELATION_PAYLOAD%\\r";

test/Microsoft.DotNet.MSBuildSdkResolver.Tests/GivenAnEnvironmentForResolution.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public void ItIgnoresInvalidPath()
1717
[Fact]
1818
public void ItDoesNotReturnNullDotnetRootOnExtraPathSeparator()
1919
{
20-
File.Create(Path.Combine(Directory.GetCurrentDirectory(), "dotnet.exe"));
20+
File.Create(Path.Combine(Directory.GetCurrentDirectory(), "dotnet.exe")).Close();
2121
Func<string, string> getPathEnvVarFunc = (input) => input.Equals("PATH") ? $"fake{Path.PathSeparator}" : string.Empty;
2222
var result = NativeWrapper.EnvironmentProvider.GetDotnetExeDirectory(getPathEnvVarFunc);
2323
result.Should().NotBeNullOrWhiteSpace();

test/dotnet-workload-install.Tests/GivenFileBasedWorkloadInstall.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public void GivenManagedInstallItCanGetFeatureBandsWhenFilesArePresent()
7979
{
8080
string path = Path.Combine(dotnetRoot, "metadata", "workloads", version.ToString(), "InstalledWorkloads");
8181
Directory.CreateDirectory(path);
82-
File.Create(Path.Combine(path, "6.0.100"));
82+
File.Create(Path.Combine(path, "6.0.100")).Close();
8383
}
8484

8585
IEnumerable<SdkFeatureBand> featureBands = installer.GetWorkloadInstallationRecordRepository().GetFeatureBandsWithInstallationRecords();
@@ -357,7 +357,7 @@ public void GivenManagedInstallItCanGetDownloads()
357357
// Write workload install record
358358
var workloadsRecordPath = Path.Combine(dotnetRoot, "metadata", "workloads", version, "InstalledWorkloads");
359359
Directory.CreateDirectory(workloadsRecordPath);
360-
File.Create(Path.Combine(workloadsRecordPath, "android-sdk-workload"));
360+
File.Create(Path.Combine(workloadsRecordPath, "android-sdk-workload")).Close();
361361

362362
var downloads = installer.GetDownloads(new[] { new WorkloadId("android-sdk-workload"), new WorkloadId("android-buildtools-workload") }, new SdkFeatureBand(version), false).ToList();
363363

@@ -384,7 +384,7 @@ public void GivenManagedInstallItCanInstallPacksFromOfflineCache()
384384
// Write mock cache
385385
Directory.CreateDirectory(cachePath);
386386
var nupkgPath = Path.Combine(cachePath, $"{packId}.{packVersion}.nupkg");
387-
File.Create(nupkgPath);
387+
File.Create(nupkgPath).Close();
388388

389389
CliTransaction.RunNew(context => installer.InstallWorkloads(new[] { new WorkloadId("android-sdk-workload") }, new SdkFeatureBand(version), context, new DirectoryPath(cachePath)));
390390
var mockNugetInstaller = nugetInstaller as MockNuGetPackageDownloader;

test/dotnet-workload-install.Tests/GivenWorkloadManifestUpdater.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public async Task GivenAdvertisingManifestUpdateItDoesNotUpdateWhenNotDue()
6767
{
6868
(var manifestUpdater, var nugetDownloader, var sentinelPath) = GetTestUpdater();
6969

70-
File.Create(sentinelPath);
70+
File.Create(sentinelPath).Close();
7171
var createTime = DateTime.Now;
7272

7373
await manifestUpdater.BackgroundUpdateAdvertisingManifestsWhenRequiredAsync();
@@ -242,7 +242,7 @@ public async Task ItCanFallbackAndAdvertiseCorrectUpdate(bool useOfflineCache)
242242
{
243243
offlineCacheDir = Path.Combine(testDir, "offlineCache");
244244
Directory.CreateDirectory(offlineCacheDir);
245-
File.Create(Path.Combine(offlineCacheDir, $"{testManifestName}.Manifest-6.0.200.nupkg"));
245+
File.Create(Path.Combine(offlineCacheDir, $"{testManifestName}.Manifest-6.0.200.nupkg")).Close();
246246

247247
await manifestUpdater.UpdateAdvertisingManifestsAsync(includePreviews: true, offlineCache: new DirectoryPath(offlineCacheDir));
248248
}
@@ -550,8 +550,8 @@ public async Task GivenWorkloadManifestUpdateItChoosesHighestManifestVersionInCa
550550
// Write multiple manifest packages to the offline cache
551551
var offlineCache = Path.Combine(testDir, "cache");
552552
Directory.CreateDirectory(offlineCache);
553-
File.Create(Path.Combine(offlineCache, $"{manifestId}.manifest-{featureBand}.2.0.0.nupkg"));
554-
File.Create(Path.Combine(offlineCache, $"{manifestId}.manifest-{featureBand}.3.0.0.nupkg"));
553+
File.Create(Path.Combine(offlineCache, $"{manifestId}.manifest-{featureBand}.2.0.0.nupkg")).Close();
554+
File.Create(Path.Combine(offlineCache, $"{manifestId}.manifest-{featureBand}.3.0.0.nupkg")).Close();
555555

556556
var workloadManifestProvider = new MockManifestProvider(new string[] { Path.Combine(installedManifestDir, manifestId, _manifestFileName) });
557557
var nugetDownloader = new MockNuGetPackageDownloader(dotnetRoot);

test/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public void GivenManagedInstallItCanGarbageCollect()
5959
// Write workload install record for 6.0.300
6060
var workloadsRecordPath = Path.Combine(_dotnetRoot, "metadata", "workloads", sdkVersions[1], "InstalledWorkloads");
6161
Directory.CreateDirectory(workloadsRecordPath);
62-
File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build"));
62+
File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build")).Close();
6363

6464
installer.GarbageCollect(getResolver);
6565

@@ -130,7 +130,7 @@ public void GarbageCollectManifests()
130130
// Write workload install record for xamarin-android-build workload for 6.0.300
131131
var workloadsRecordPath = Path.Combine(_dotnetRoot, "metadata", "workloads", "6.0.300", "InstalledWorkloads");
132132
Directory.CreateDirectory(workloadsRecordPath);
133-
File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build"));
133+
File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build")).Close();
134134

135135
// These packs are referenced by xamarin-android-build from the 3.0 manifest, which is the latest one and therefore the one that will be kept
136136
var packsToKeep = new PackInfo[]
@@ -210,7 +210,7 @@ public void GarbageCollectManifestsWithInstallState()
210210
// Write workload install record for xamarin-android-build workload for 6.0.300
211211
var workloadsRecordPath = Path.Combine(_dotnetRoot, "metadata", "workloads", "6.0.300", "InstalledWorkloads");
212212
Directory.CreateDirectory(workloadsRecordPath);
213-
File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build"));
213+
File.Create(Path.Combine(workloadsRecordPath, "xamarin-android-build")).Close();
214214

215215
// These packs are referenced by xamarin-android-build from the 2.0 manifest, which is the one that should be kept due to the install state
216216
var packsToKeep = new PackInfo[]

test/dotnet-workload-update.Tests/GivenDotnetWorkloadUpdate.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ public void GivenWorkloadUpdateAcrossFeatureBandsItUpdatesPacks(bool userLocal)
209209
var sdkFeatureVersion = "6.0.100";
210210
var installingWorkload = "simple-workload";
211211

212+
// Mock up a 5.0.1xx SDK install so that the installation records for that feature band won't be deleted
213+
string dotnetDllPath = Path.Combine(dotnetRoot, "sdk", "5.0.110", "dotnet.dll");
214+
Directory.CreateDirectory(Path.GetDirectoryName(dotnetDllPath));
215+
File.Create(dotnetDllPath).Close();
216+
212217
string installRoot = userLocal ? userProfileDir : dotnetRoot;
213218
if (userLocal)
214219
{
@@ -228,12 +233,12 @@ public void GivenWorkloadUpdateAcrossFeatureBandsItUpdatesPacks(bool userLocal)
228233
foreach (var pack in workloadPacks)
229234
{
230235
Directory.CreateDirectory(Path.Combine(packRecordDir, pack.Id, pack.Version));
231-
File.Create(Path.Combine(packRecordDir, pack.Id, pack.Version, oldFeatureBand));
236+
File.Create(Path.Combine(packRecordDir, pack.Id, pack.Version, oldFeatureBand)).Close();
232237
}
233238
Directory.CreateDirectory(Path.Combine(installRoot, "metadata", "workloads", oldFeatureBand, "InstalledWorkloads"));
234239
Directory.CreateDirectory(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads"));
235-
File.Create(Path.Combine(installRoot, "metadata", "workloads", oldFeatureBand, "InstalledWorkloads", installingWorkload));
236-
File.Create(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installingWorkload));
240+
File.Create(Path.Combine(installRoot, "metadata", "workloads", oldFeatureBand, "InstalledWorkloads", installingWorkload)).Close();
241+
File.Create(Path.Combine(installRoot, "metadata", "workloads", sdkFeatureVersion, "InstalledWorkloads", installingWorkload)).Close();
237242

238243
// Update workload (without installing any workloads to this feature band)
239244
var updateParseResult = Parser.Instance.Parse(new string[] { "dotnet", "workload", "update", "--from-previous-sdk" });

0 commit comments

Comments
 (0)