129 lines
4.4 KiB
C#
129 lines
4.4 KiB
C#
// Licensed to the .NET Foundation under one or more agreements.
|
|
// The .NET Foundation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using Microsoft.Extensions.FileSystemGlobbing;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Formats.Tar;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Xunit;
|
|
using Xunit.Abstractions;
|
|
|
|
namespace Microsoft.DotNet.SourceBuild.SmokeTests;
|
|
|
|
public static class Utilities
|
|
{
|
|
public static void ExtractTarball(string tarballPath, string outputDir, ITestOutputHelper outputHelper)
|
|
{
|
|
// TarFile doesn't properly handle hard links (https://github.com/dotnet/runtime/pull/85378#discussion_r1221817490),
|
|
// use 'tar' instead.
|
|
ExecuteHelper.ExecuteProcessValidateExitCode("tar", $"xzf {tarballPath} -C {outputDir}", outputHelper);
|
|
}
|
|
|
|
public static void ExtractTarball(string tarballPath, string outputDir, string targetFilePath)
|
|
{
|
|
Matcher matcher = new();
|
|
matcher.AddInclude(targetFilePath);
|
|
|
|
using FileStream fileStream = File.OpenRead(tarballPath);
|
|
using GZipStream decompressorStream = new(fileStream, CompressionMode.Decompress);
|
|
using TarReader reader = new(decompressorStream);
|
|
|
|
TarEntry entry;
|
|
while ((entry = reader.GetNextEntry()) is not null)
|
|
{
|
|
if (matcher.Match(entry.Name).HasMatches)
|
|
{
|
|
string outputPath = Path.Join(outputDir, entry.Name);
|
|
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
|
|
|
|
using FileStream outputFileStream = File.Create(outputPath);
|
|
entry.DataStream.CopyTo(outputFileStream);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static IEnumerable<string> GetTarballContentNames(string tarballPath)
|
|
{
|
|
using FileStream fileStream = File.OpenRead(tarballPath);
|
|
using GZipStream decompressorStream = new(fileStream, CompressionMode.Decompress);
|
|
using TarReader reader = new(decompressorStream);
|
|
|
|
TarEntry entry;
|
|
while ((entry = reader.GetNextEntry()) is not null)
|
|
{
|
|
yield return entry.Name;
|
|
}
|
|
}
|
|
|
|
public static void ExtractNupkg(string package, string outputDir)
|
|
{
|
|
Directory.CreateDirectory(outputDir);
|
|
|
|
using ZipArchive zip = ZipFile.OpenRead(package);
|
|
foreach (ZipArchiveEntry entry in zip.Entries)
|
|
{
|
|
string outputPath = Path.Combine(outputDir, entry.FullName);
|
|
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
|
|
entry.ExtractToFile(outputPath);
|
|
}
|
|
}
|
|
|
|
public static async Task RetryAsync(Func<Task> executor, ITestOutputHelper outputHelper)
|
|
{
|
|
await Utilities.RetryAsync(
|
|
async () =>
|
|
{
|
|
try
|
|
{
|
|
await executor();
|
|
return null;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return e;
|
|
}
|
|
},
|
|
outputHelper);
|
|
}
|
|
|
|
private static async Task RetryAsync(Func<Task<Exception?>> executor, ITestOutputHelper outputHelper)
|
|
{
|
|
const int maxRetries = 5;
|
|
const int waitFactor = 5;
|
|
|
|
int retryCount = 0;
|
|
|
|
Exception? exception = await executor();
|
|
while (exception != null)
|
|
{
|
|
retryCount++;
|
|
if (retryCount >= maxRetries)
|
|
{
|
|
throw new InvalidOperationException($"Failed after {retryCount} retries.", exception);
|
|
}
|
|
|
|
int waitTime = Convert.ToInt32(Math.Pow(waitFactor, retryCount - 1));
|
|
if (outputHelper != null)
|
|
{
|
|
outputHelper.WriteLine($"Retry {retryCount}/{maxRetries}, retrying in {waitTime} seconds...");
|
|
}
|
|
|
|
Thread.Sleep(TimeSpan.FromSeconds(waitTime));
|
|
exception = await executor();
|
|
}
|
|
}
|
|
|
|
public static string GetFile(string path, string pattern)
|
|
{
|
|
string[] files = Directory.GetFiles(path, pattern, SearchOption.AllDirectories);
|
|
Assert.False(files.Length > 1, $"Found multiple files matching the pattern {pattern}: {Environment.NewLine}{string.Join(Environment.NewLine, files)}");
|
|
Assert.False(files.Length == 0, $"Did not find any files matching the pattern {pattern}");
|
|
return files[0];
|
|
}
|
|
}
|