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

Cleanup TempDirectory implementation #5101

Merged
merged 1 commit into from
Feb 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ private static async Task<DotnetMuxerResult> CallTheMuxerCoreAsync(string args,
if (!args.Contains("-bl:") && !IsDotNetTestWithExeOrDll(args))
{
// We do this here rather than in the caller so that different retries produce different binlog file names.
string binlogFullPath = Path.Combine(TempDirectory.GetTestSuiteDirectory(), $"{binlogBaseFileName}-{Interlocked.Increment(ref s_binlogCounter)}.binlog");
string binlogFullPath = Path.Combine(TempDirectory.TestSuiteDirectory, $"{binlogBaseFileName}-{Interlocked.Increment(ref s_binlogCounter)}.binlog");
string binlogArg = $" -bl:\"{binlogFullPath}\"";
if (args.IndexOf("-- ", StringComparison.Ordinal) is int platformArgsIndex && platformArgsIndex > 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@ public class TempDirectory : IDisposable
/// <summary>
/// Initializes a new instance of the <see cref="TempDirectory"/> class.
/// </summary>
public TempDirectory(string? subDirectory = null, bool arcadeConvention = true, bool cleanup = true)
public TempDirectory(string? subDirectory = null)
{
if (Environment.GetEnvironmentVariable("Microsoft_Testing_TestInfrastructure_TempDirectory_Cleanup") == "0")
{
cleanup = false;
}

(_baseDirectory, Path) = CreateUniqueDirectory(subDirectory, arcadeConvention);
_cleanup = cleanup;
_cleanup = Environment.GetEnvironmentVariable("Microsoft_Testing_TestInfrastructure_TempDirectory_Cleanup") != "0";
(_baseDirectory, Path) = CreateUniqueDirectory(subDirectory);
}

public string Path { get; }

#pragma warning disable CS0618 // Type or member is obsolete - This is the only place where GetRepoRoot and GetTestSuiteDirectory should be called.
internal static string RepoRoot { get; } = GetRepoRoot();

internal static string TestSuiteDirectory { get; } = GetTestSuiteDirectory();
#pragma warning restore CS0618 // Type or member is obsolete

public void Dispose()
{
if (_isDisposed)
Expand Down Expand Up @@ -143,17 +144,21 @@ public string CopyFile(string filePath)
return destination;
}

internal static string GetTestSuiteDirectory()
[Obsolete("Don't use directly. Use TestSuiteDirectory property instead.")]
private static string GetTestSuiteDirectory()
=> System.IO.Path.Combine(RepoRoot, "artifacts", "tmp", Constants.BuildConfiguration, "testsuite");

[Obsolete("Don't use directly. Use RepoRoot property instead.")]
private static string GetRepoRoot()
{
string currentDirectory = AppContext.BaseDirectory;
while (System.IO.Path.GetFileName(currentDirectory) != "artifacts" && currentDirectory is not null)
{
currentDirectory = System.IO.Path.GetDirectoryName(currentDirectory)!;
}

return currentDirectory is null
? throw new InvalidOperationException("artifacts folder not found")
: System.IO.Path.Combine(currentDirectory, "tmp", Constants.BuildConfiguration, "testsuite");
return System.IO.Path.GetDirectoryName(currentDirectory)
?? throw new InvalidOperationException("artifacts folder not found");
}

/// <summary>
Expand All @@ -162,30 +167,17 @@ internal static string GetTestSuiteDirectory()
/// <returns>
/// Path of the created directory.
/// </returns>
internal static (string BaseDirectory, string FinalDirectory) CreateUniqueDirectory(string? subDirectory, bool arcadeConvention)
internal static (string BaseDirectory, string FinalDirectory) CreateUniqueDirectory(string? subDirectory)
{
if (arcadeConvention)
{
string currentDirectory = AppContext.BaseDirectory;
while (System.IO.Path.GetFileName(currentDirectory) != "artifacts" && currentDirectory is not null)
{
currentDirectory = System.IO.Path.GetDirectoryName(currentDirectory)!;
}

if (currentDirectory is null)
{
throw new InvalidOperationException("artifacts folder not found");
}
string directoryPath = System.IO.Path.Combine(TestSuiteDirectory, RandomId.Next());
Directory.CreateDirectory(directoryPath);

string directoryPath = System.IO.Path.Combine(GetTestSuiteDirectory(), RandomId.Next());
Directory.CreateDirectory(directoryPath);

string directoryBuildProps = System.IO.Path.Combine(directoryPath, "Directory.Build.props");
File.WriteAllText(directoryBuildProps, $"""
string directoryBuildProps = System.IO.Path.Combine(directoryPath, "Directory.Build.props");
File.WriteAllText(directoryBuildProps, $"""
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<RepoRoot>{System.IO.Path.GetDirectoryName(currentDirectory)}/</RepoRoot>
<RepoRoot>{RepoRoot}/</RepoRoot>
<!-- Do not warn about package downgrade. NuGet uses alphabetical sort as ordering so -dev or -ci are considered downgrades of -preview. -->
<NoWarn>NU1605</NoWarn>
<RunAnalyzers>false</RunAnalyzers>
Expand All @@ -195,8 +187,8 @@ internal static (string BaseDirectory, string FinalDirectory) CreateUniqueDirect
</Project>
""");

string directoryBuildTarget = System.IO.Path.Combine(directoryPath, "Directory.Build.targets");
File.WriteAllText(directoryBuildTarget, $"""
string directoryBuildTarget = System.IO.Path.Combine(directoryPath, "Directory.Build.targets");
File.WriteAllText(directoryBuildTarget, $"""
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ItemGroup>
Expand All @@ -215,8 +207,8 @@ we end up with a -dev or -ci version which will lose resolution over -preview de
</Project>
""");

string directoryPackagesProps = System.IO.Path.Combine(directoryPath, "Directory.Packages.props");
File.WriteAllText(directoryPackagesProps, """
string directoryPackagesProps = System.IO.Path.Combine(directoryPath, "Directory.Packages.props");
File.WriteAllText(directoryPackagesProps, """
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
Expand All @@ -225,41 +217,17 @@ we end up with a -dev or -ci version which will lose resolution over -preview de
</Project>
""");

string finalDirectory = directoryPath;
if (!string.IsNullOrWhiteSpace(subDirectory))
{
finalDirectory = System.IO.Path.Combine(directoryPath, subDirectory);
}

Directory.CreateDirectory(finalDirectory);

return (directoryPath, finalDirectory);
}
else
string finalDirectory = directoryPath;
if (!string.IsNullOrWhiteSpace(subDirectory))
{
string temp = GetTempPath();
string directoryPath = System.IO.Path.Combine(temp, "testingplatform", RandomId.Next());
string finalDirectory = directoryPath;
if (!string.IsNullOrWhiteSpace(subDirectory))
{
finalDirectory = System.IO.Path.Combine(directoryPath, subDirectory);
}
finalDirectory = System.IO.Path.Combine(directoryPath, subDirectory);
}

Directory.CreateDirectory(finalDirectory);
Directory.CreateDirectory(finalDirectory);

return (directoryPath, finalDirectory);
}
return (directoryPath, finalDirectory);
}

// AGENT_TEMPDIRECTORY is Azure DevOps variable, which is set to path
// that is cleaned up after every job. This is preferable to use over
// just the normal TEMP, because that is not cleaned up for every run.
//
// System.IO.Path.GetTempPath is banned from the rest of the code. This is the only
// place where we are allowed to use it. All other methods should use our GetTempPath (this method).
private static string GetTempPath() => Environment.GetEnvironmentVariable("AGENT_TEMPDIRECTORY")
?? System.IO.Path.GetTempPath();

public void Add(string fileContents)
{
List<InlineFile> files = InlineFileParser.ParseFiles(fileContents);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ public class TestAsset : IDisposable
private readonly string _assetCode;
private bool _isDisposed;

public TestAsset(string targetPath, string assetCode, bool cleanup = true)
public TestAsset(string targetPath, string assetCode)
{
_assetCode = assetCode;
_tempDirectory = new(targetPath, arcadeConvention: true, cleanup);
_tempDirectory = new(targetPath);
}

public string TargetAssetPath => _tempDirectory.Path;
Expand Down