diff --git a/.github/workflows/remove-lockdown-label.yml b/.github/workflows/remove-lockdown-label.yml
index 902802b93553..51c6b82c8a68 100644
--- a/.github/workflows/remove-lockdown-label.yml
+++ b/.github/workflows/remove-lockdown-label.yml
@@ -68,4 +68,4 @@ jobs:
name: 'Branch Lockdown'
});
console.log(`Removed Branch Lockdown label from PR #${pr.number}`);
- }
\ No newline at end of file
+ }
diff --git a/NuGet.config b/NuGet.config
index 09870da28882..d4b06f53eddb 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -6,6 +6,7 @@
+
@@ -37,6 +38,7 @@
+
diff --git a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs
index ff496c844e70..9859e15d5179 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs
@@ -216,6 +216,11 @@ private static async Task PushToLocalRegistryAsync(ILogger logger, BuiltIma
await containerRegistry.LoadAsync(builtImage, sourceImageReference, destinationImageReference, cancellationToken).ConfigureAwait(false);
logger.LogInformation(Strings.ContainerBuilder_ImageUploadedToLocalDaemon, destinationImageReference, containerRegistry);
}
+ catch (UnableToDownloadFromRepositoryException)
+ {
+ logger.LogError(Resource.FormatString(nameof(Strings.UnableToDownloadFromRepository)), sourceImageReference);
+ return 1;
+ }
catch (Exception ex)
{
logger.LogError(Resource.FormatString(nameof(Strings.RegistryOutputPushFailed), ex.Message));
@@ -243,11 +248,6 @@ private static async Task PushToRemoteRegistryAsync(ILogger logger, BuiltIm
logger.LogError(Resource.FormatString(nameof(Strings.UnableToDownloadFromRepository)), sourceImageReference);
return 1;
}
- catch (UnableToAccessRepositoryException)
- {
- logger.LogError(Resource.FormatString(nameof(Strings.UnableToAccessRepository), destinationImageReference.Repository, destinationImageReference.RemoteRegistry!.RegistryName));
- return 1;
- }
catch (Exception e)
{
logger.LogError(Resource.FormatString(nameof(Strings.RegistryOutputPushFailed), e.Message));
diff --git a/src/Containers/Microsoft.NET.Build.Containers/ImagePublisher.cs b/src/Containers/Microsoft.NET.Build.Containers/ImagePublisher.cs
index 1a16cbbad500..d6a9c56850ec 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/ImagePublisher.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/ImagePublisher.cs
@@ -107,6 +107,10 @@ private static async Task PushToLocalRegistryAsync(
await loadFunc(image, sourceImageReference, destinationImageReference, cancellationToken).ConfigureAwait(false);
Log.LogMessage(MessageImportance.High, Strings.ContainerBuilder_ImageUploadedToLocalDaemon, destinationImageReference, localRegistry);
}
+ catch (UnableToDownloadFromRepositoryException)
+ {
+ Log.LogErrorWithCodeFromResources(nameof(Strings.UnableToDownloadFromRepository), sourceImageReference);
+ }
catch (ContainerHttpException e)
{
Log.LogErrorFromException(e, true);
diff --git a/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs b/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs
index 100ff11d24cb..3472ba1c53b2 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs
@@ -75,6 +75,8 @@ internal sealed class Registry
private const string DockerHubRegistry1 = "registry-1.docker.io";
private const string DockerHubRegistry2 = "registry.hub.docker.com";
private static readonly int s_defaultChunkSizeBytes = 1024 * 64;
+ private const int MaxDownloadRetries = 5;
+ private readonly Func _retryDelayProvider;
private readonly ILogger _logger;
private readonly IRegistryAPI _registryAPI;
@@ -87,7 +89,7 @@ internal sealed class Registry
///
public string RegistryName { get; }
- internal Registry(string registryName, ILogger logger, IRegistryAPI registryAPI, RegistrySettings? settings = null) :
+ internal Registry(string registryName, ILogger logger, IRegistryAPI registryAPI, RegistrySettings? settings = null, Func? retryDelayProvider = null) :
this(new Uri($"https://{registryName}"), logger, registryAPI, settings)
{ }
@@ -96,7 +98,7 @@ internal Registry(string registryName, ILogger logger, RegistryMode mode, Regist
{ }
- internal Registry(Uri baseUri, ILogger logger, IRegistryAPI registryAPI, RegistrySettings? settings = null) :
+ internal Registry(Uri baseUri, ILogger logger, IRegistryAPI registryAPI, RegistrySettings? settings = null, Func? retryDelayProvider = null) :
this(baseUri, logger, new RegistryApiFactory(registryAPI), settings)
{ }
@@ -104,7 +106,7 @@ internal Registry(Uri baseUri, ILogger logger, RegistryMode mode, RegistrySettin
this(baseUri, logger, new RegistryApiFactory(mode), settings)
{ }
- private Registry(Uri baseUri, ILogger logger, RegistryApiFactory factory, RegistrySettings? settings = null)
+ private Registry(Uri baseUri, ILogger logger, RegistryApiFactory factory, RegistrySettings? settings = null, Func? retryDelayProvider = null)
{
RegistryName = DeriveRegistryName(baseUri);
@@ -118,6 +120,8 @@ private Registry(Uri baseUri, ILogger logger, RegistryApiFactory factory, Regist
_logger = logger;
_settings = settings ?? new RegistrySettings(RegistryName);
_registryAPI = factory.Create(RegistryName, BaseUri, logger, _settings.IsInsecure);
+
+ _retryDelayProvider = retryDelayProvider ?? (() => TimeSpan.FromSeconds(1));
}
private static string DeriveRegistryName(Uri baseUri)
@@ -404,33 +408,48 @@ public async Task DownloadBlobAsync(string repository, Descriptor descri
{
cancellationToken.ThrowIfCancellationRequested();
string localPath = ContentStore.PathForDescriptor(descriptor);
-
+
if (File.Exists(localPath))
{
// Assume file is up to date and just return it
return localPath;
}
-
+
string tempTarballPath = ContentStore.GetTempFile();
-
- try
+
+ int retryCount = 0;
+ while (retryCount < MaxDownloadRetries)
{
- // No local copy, so download one
- using Stream responseStream = await _registryAPI.Blob.GetStreamAsync(repository, descriptor.Digest, cancellationToken).ConfigureAwait(false);
-
- using (FileStream fs = File.Create(tempTarballPath))
+ try
{
- await responseStream.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
+ // No local copy, so download one
+ using Stream responseStream = await _registryAPI.Blob.GetStreamAsync(repository, descriptor.Digest, cancellationToken).ConfigureAwait(false);
+
+ using (FileStream fs = File.Create(tempTarballPath))
+ {
+ await responseStream.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
+ }
+
+ // Break the loop if successful
+ break;
+ }
+ catch (Exception ex)
+ {
+ retryCount++;
+ if (retryCount >= MaxDownloadRetries)
+ {
+ throw new UnableToDownloadFromRepositoryException(repository);
+ }
+
+ _logger.LogTrace("Download attempt {0}/{1} for repository '{2}' failed. Error: {3}", retryCount, MaxDownloadRetries, repository, ex.ToString());
+
+ // Wait before retrying
+ await Task.Delay(_retryDelayProvider(), cancellationToken).ConfigureAwait(false);
}
}
- catch (Exception)
- {
- throw new UnableToDownloadFromRepositoryException(repository);
- }
- cancellationToken.ThrowIfCancellationRequested();
-
+
File.Move(tempTarballPath, localPath, overwrite: true);
-
+
return localPath;
}
diff --git a/test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs b/test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs
index 7aefe1ca7791..82b7a4f3f5c3 100644
--- a/test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs
+++ b/test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs
@@ -4,6 +4,8 @@
using System.Formats.Tar;
using System.Runtime.CompilerServices;
using System.Text.Json;
+using FakeItEasy;
+using Microsoft.Build.Framework;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.NET.Build.Containers.LocalDaemons;
using Microsoft.NET.Build.Containers.Resources;
@@ -1431,9 +1433,10 @@ static string[] DecideEntrypoint(string rid, string appName, string workingDir)
}
[DockerAvailableFact]
- public async Task CheckErrorMessageWhenSourceRepositoryThrows()
+ public async void CheckDownloadErrorMessageWhenSourceRepositoryThrows()
{
- ILogger logger = _loggerFactory.CreateLogger(nameof(CheckErrorMessageWhenSourceRepositoryThrows));
+ var loggerFactory = new TestLoggerFactory(_testOutput);
+ var logger = loggerFactory.CreateLogger(nameof(CheckDownloadErrorMessageWhenSourceRepositoryThrows));
string rid = "win-x64";
string publishDirectory = BuildLocalApp(tfm: ToolsetInfo.CurrentTargetFramework, rid: rid);
@@ -1459,24 +1462,39 @@ public async Task CheckErrorMessageWhenSourceRepositoryThrows()
// Load the image into the local registry
var sourceReference = new SourceImageReference(registry, "some_random_image", DockerRegistryManager.Net9ImageTag, null);
- var destinationReference = new DestinationImageReference(registry, NewImageName(), new[] { rid });
- var sawMyException = false;
- try
- {
- await new DockerCli(_loggerFactory).LoadAsync(builtImage, sourceReference, destinationReference, default).ConfigureAwait(false);
- }
- catch (UnableToDownloadFromRepositoryException e)
- {
- sawMyException = true;
- Assert.Contains("The download of the image from repository some_random_image has failed", e.ToString());
- }
- Assert.True(sawMyException);
+ string archivePath = Path.Combine(TestSettings.TestArtifactsDirectory, nameof(CheckDownloadErrorMessageWhenSourceRepositoryThrows));
+ var destinationReference = new DestinationImageReference(new ArchiveFileRegistry(archivePath), NewImageName(), new[] { rid });
+
+ (var taskLog, var errors) = SetupTaskLog();
+ var telemetry = new Telemetry(sourceReference, destinationReference, taskLog);
+
+ await ImagePublisher.PublishImageAsync(builtImage, sourceReference, destinationReference, taskLog, telemetry, CancellationToken.None)
+ .ConfigureAwait(false);
+
+ // Assert the error message
+ Assert.True(taskLog.HasLoggedErrors);
+ Assert.NotNull(errors);
+ Assert.Single(errors);
+ Assert.Contains("Unable to download image from the repository", errors[0]);
static string[] DecideEntrypoint(string rid, string appName, string workingDir)
{
var binary = rid.StartsWith("win", StringComparison.Ordinal) ? $"{appName}.exe" : appName;
return new[] { $"{workingDir}/{binary}" };
}
+
+ static (Microsoft.Build.Utilities.TaskLoggingHelper, List errors) SetupTaskLog()
+ {
+ // We can use any Task, we just need TaskLoggingHelper
+ Tasks.CreateNewImage cni = new();
+ List errors = new();
+ IBuildEngine buildEngine = A.Fake();
+ A.CallTo(() => buildEngine.LogWarningEvent(A.Ignored)).Invokes((BuildWarningEventArgs e) => errors.Add(e.Message));
+ A.CallTo(() => buildEngine.LogErrorEvent(A.Ignored)).Invokes((BuildErrorEventArgs e) => errors.Add(e.Message));
+ A.CallTo(() => buildEngine.LogMessageEvent(A.Ignored)).Invokes((BuildMessageEventArgs e) => errors.Add(e.Message));
+ cni.BuildEngine = buildEngine;
+ return (cni.Log, errors);
+ }
}
[DockerAvailableFact(checkContainerdStoreAvailability: true)]
diff --git a/test/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs b/test/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs
index 37384ba7c18e..0c41f7ddb1b2 100644
--- a/test/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs
+++ b/test/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs
@@ -545,6 +545,77 @@ public void IsRegistryInsecure(string registryName, string? insecureRegistriesEn
Assert.Equal(expectedInsecure, registrySettings.IsInsecure);
}
+ [Fact]
+ public async Task DownloadBlobAsync_RetriesOnFailure()
+ {
+ // Arrange
+ var logger = _loggerFactory.CreateLogger(nameof(DownloadBlobAsync_RetriesOnFailure));
+
+ var repoName = "testRepo";
+ var descriptor = new Descriptor(SchemaTypes.OciLayerGzipV1, "sha256:testdigest1234", 1234);
+ var cancellationToken = CancellationToken.None;
+
+ var mockRegistryAPI = new Mock(MockBehavior.Strict);
+ mockRegistryAPI
+ .SetupSequence(api => api.Blob.GetStreamAsync(repoName, descriptor.Digest, cancellationToken))
+ .ThrowsAsync(new Exception("Simulated failure 1")) // First attempt fails
+ .ThrowsAsync(new Exception("Simulated failure 2")) // Second attempt fails
+ .ReturnsAsync(new MemoryStream(new byte[] { 1, 2, 3 })); // Third attempt succeeds
+
+ Registry registry = new(repoName, logger, mockRegistryAPI.Object, null, () => TimeSpan.Zero);
+
+ string? result = null;
+ try
+ {
+ // Act
+ result = await registry.DownloadBlobAsync(repoName, descriptor, cancellationToken);
+
+ // Assert
+ Assert.NotNull(result);
+ Assert.True(File.Exists(result)); // Ensure the file was successfully downloaded
+ mockRegistryAPI.Verify(api => api.Blob.GetStreamAsync(repoName, descriptor.Digest, cancellationToken), Times.Exactly(3)); // Verify retries
+ }
+ finally
+ {
+ // Cleanup
+ if (result != null)
+ {
+ File.Delete(result);
+ }
+ }
+ }
+
+ [Fact]
+ public async Task DownloadBlobAsync_ThrowsAfterMaxRetries()
+ {
+ // Arrange
+ var logger = _loggerFactory.CreateLogger(nameof(DownloadBlobAsync_ThrowsAfterMaxRetries));
+
+ var repoName = "testRepo";
+ var descriptor = new Descriptor(SchemaTypes.OciLayerGzipV1, "sha256:testdigest1234", 1234);
+ var cancellationToken = CancellationToken.None;
+
+ var mockRegistryAPI = new Mock(MockBehavior.Strict);
+ // Simulate 5 failures (assuming your retry logic attempts 5 times before throwing)
+ mockRegistryAPI
+ .SetupSequence(api => api.Blob.GetStreamAsync(repoName, descriptor.Digest, cancellationToken))
+ .ThrowsAsync(new Exception("Simulated failure 1"))
+ .ThrowsAsync(new Exception("Simulated failure 2"))
+ .ThrowsAsync(new Exception("Simulated failure 3"))
+ .ThrowsAsync(new Exception("Simulated failure 4"))
+ .ThrowsAsync(new Exception("Simulated failure 5"));
+
+ Registry registry = new(repoName, logger, mockRegistryAPI.Object, null, () => TimeSpan.Zero);
+
+ // Act & Assert
+ await Assert.ThrowsAsync(async () =>
+ {
+ await registry.DownloadBlobAsync(repoName, descriptor, cancellationToken);
+ });
+
+ mockRegistryAPI.Verify(api => api.Blob.GetStreamAsync(repoName, descriptor.Digest, cancellationToken), Times.Exactly(5));
+ }
+
private static NextChunkUploadInformation ChunkUploadSuccessful(Uri requestUri, Uri uploadUrl, int? contentLength, HttpStatusCode code = HttpStatusCode.Accepted)
{
return new(uploadUrl);
diff --git a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyNuGetReferenceCompat.cs b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyNuGetReferenceCompat.cs
index 9f6620e06afc..94133426e5f4 100644
--- a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyNuGetReferenceCompat.cs
+++ b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyNuGetReferenceCompat.cs
@@ -15,20 +15,9 @@ public GivenThatWeWantToVerifyNuGetReferenceCompat(ITestOutputHelper log) : base
[Theory]
[InlineData("net45", "Full", "netstandard1.0 netstandard1.1 net45", true, true)]
- [InlineData("net451", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 net45 net451", true, true)]
- [InlineData("net46", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 net45 net451 net46", true, true)]
- [InlineData("net461", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0 net45 net451 net46 net461", true, true)]
[InlineData("net462", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0 net45 net451 net46 net461 net462", true, true)]
- [InlineData("netstandard1.0", "Full", "netstandard1.0", true, true)]
- [InlineData("netstandard1.1", "Full", "netstandard1.0 netstandard1.1", true, true)]
- [InlineData("netstandard1.2", "Full", "netstandard1.0 netstandard1.1 netstandard1.2", true, true)]
- [InlineData("netstandard1.3", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3", true, true)]
- [InlineData("netstandard1.4", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4", true, true)]
- [InlineData("netstandard1.5", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5", true, true)]
[InlineData("netstandard1.6", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6", true, true)]
[InlineData("netstandard2.0", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0", true, true)]
- [InlineData("netcoreapp1.0", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netcoreapp1.0", true, true)]
- [InlineData("netcoreapp1.1", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netcoreapp1.0 netcoreapp1.1", true, true)]
[InlineData("netcoreapp2.0", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0 netcoreapp1.0 netcoreapp1.1 netcoreapp2.0", true, true)]
[InlineData("netstandard2.0", "OptIn", "net45 net451 net46 net461", true, true)]
@@ -48,31 +37,53 @@ public void Nuget_reference_compat(string referencerTarget, string testDescripti
return;
}
- foreach (string dependencyTarget in rawDependencyTargets.Split(',', ';', ' ').ToList())
- {
- TestProject dependencyProject = GetTestProject(ConstantStringValues.DependencyDirectoryNamePrefix + dependencyTarget.Replace('.', '_'), dependencyTarget, true);
- TestPackageReference dependencyPackageReference = new(
- dependencyProject.Name,
- "1.0.0",
- ConstantStringValues.ConstructNuGetPackageReferencePath(dependencyProject, identifier: referencerTarget + testDescription + rawDependencyTargets));
+ var dependencyPackageReferences = new List();
- // Skip creating the NuGet package if not running on Windows; or if the NuGet package already exists
- // https://github.com/dotnet/sdk/issues/335
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || dependencyProject.BuildsOnNonWindows)
+ // Process all dependencies in parallel
+ Parallel.ForEach(
+ rawDependencyTargets.Split(',', ';', ' ').Where(s => !string.IsNullOrWhiteSpace(s)),
+ new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
+ dependencyTarget =>
{
- if (!dependencyPackageReference.NuGetPackageExists())
+ // Create the dependency project and package
+ TestProject dependencyProject = GetTestProject(
+ ConstantStringValues.DependencyDirectoryNamePrefix + dependencyTarget.Replace('.', '_'),
+ dependencyTarget,
+ true);
+
+ TestPackageReference dependencyPackageReference = new(
+ dependencyProject.Name,
+ "1.0.0",
+ ConstantStringValues.ConstructNuGetPackageReferencePath(dependencyProject, identifier: referencerTarget + testDescription + rawDependencyTargets));
+
+ // Create package if it doesn't exist
+ if (!dependencyPackageReference.NuGetPackageExists() &&
+ (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || dependencyProject.BuildsOnNonWindows))
{
- // Create the NuGet packages
- var dependencyTestAsset = _testAssetsManager.CreateTestProject(dependencyProject, identifier: referencerTarget + testDescription + rawDependencyTargets);
- var dependencyRestoreCommand = dependencyTestAsset.GetRestoreCommand(Log, relativePath: dependencyProject.Name).Execute().Should().Pass();
- var dependencyProjectDirectory = Path.Combine(dependencyTestAsset.TestRoot, dependencyProject.Name);
+ if (!dependencyPackageReference.NuGetPackageExists())
+ {
+ var dependencyTestAsset = _testAssetsManager.CreateTestProject(
+ dependencyProject,
+ identifier: referencerTarget + testDescription + rawDependencyTargets);
+
+ dependencyTestAsset.GetRestoreCommand(Log, relativePath: dependencyProject.Name)
+ .Execute().Should().Pass();
+
+ var dependencyProjectDirectory = Path.Combine(
+ dependencyTestAsset.TestRoot,
+ dependencyProject.Name);
+
+ new PackCommand(Log, dependencyProjectDirectory)
+ .Execute().Should().Pass();
+ }
- var dependencyPackCommand = new PackCommand(Log, dependencyProjectDirectory);
- var dependencyPackResult = dependencyPackCommand.Execute().Should().Pass();
}
+ });
- referencerProject.PackageReferences.Add(dependencyPackageReference);
- }
+ // Add all references to the referencer project
+ foreach (var dependencyPackageReference in dependencyPackageReferences)
+ {
+ referencerProject.PackageReferences.Add(dependencyPackageReference);
}
// Skip running tests if no NuGet packages are referenced
diff --git a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyProjectReferenceCompat.cs b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyProjectReferenceCompat.cs
index ec38cc8e09a3..b3415d31e41a 100644
--- a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyProjectReferenceCompat.cs
+++ b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyProjectReferenceCompat.cs
@@ -13,20 +13,9 @@ public GivenThatWeWantToVerifyProjectReferenceCompat(ITestOutputHelper log) : ba
[Theory]
[InlineData("net45", "Full", "netstandard1.0 netstandard1.1 net45", true, true)]
- [InlineData("net451", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 net45 net451", true, true)]
- [InlineData("net46", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 net45 net451 net46", true, true)]
- [InlineData("net461", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0 net45 net451 net46 net461", true, true)]
[InlineData("net462", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0 net45 net451 net46 net461 net462", true, true)]
- [InlineData("netstandard1.0", "Full", "netstandard1.0", true, true)]
- [InlineData("netstandard1.1", "Full", "netstandard1.0 netstandard1.1", true, true)]
- [InlineData("netstandard1.2", "Full", "netstandard1.0 netstandard1.1 netstandard1.2", true, true)]
- [InlineData("netstandard1.3", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3", true, true)]
- [InlineData("netstandard1.4", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4", true, true)]
- [InlineData("netstandard1.5", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5", true, true)]
[InlineData("netstandard1.6", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6", true, true)]
[InlineData("netstandard2.0", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0", true, true)]
- [InlineData("netcoreapp1.0", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netcoreapp1.0", true, true)]
- [InlineData("netcoreapp1.1", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netcoreapp1.0 netcoreapp1.1", true, true)]
[InlineData("netcoreapp2.0", "Full", "netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0 netcoreapp1.0 netcoreapp1.1 netcoreapp2.0", true, true)]
public void Project_reference_compat(string referencerTarget, string testIDPostFix, string rawDependencyTargets,
diff --git a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs
index 2f4bc33dd4f1..1c07d735f69c 100644
--- a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs
+++ b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs
@@ -100,7 +100,7 @@ public void ILLink_runs_and_creates_linked_app(string targetFramework, bool refe
}
[RequiresMSBuildVersionTheory("17.0.0.32901")]
- [MemberData(nameof(SupportedTfms), MemberType = typeof(PublishTestUtils))]
+ [MemberData(nameof(Net8Plus), MemberType = typeof(PublishTestUtils))]
public void ILLink_links_simple_app_without_analysis_warnings_and_it_runs(string targetFramework)
{
foreach (var trimMode in new[] { "copyused", "link" })
@@ -252,7 +252,7 @@ public void ILLink_can_use_latest_with_unsupported_target_framework(string targe
}
[RequiresMSBuildVersionTheory("17.0.0.32901")]
- [MemberData(nameof(SupportedTfms), MemberType = typeof(PublishTestUtils))]
+ [MemberData(nameof(Net8Plus), MemberType = typeof(PublishTestUtils))]
public void PrepareForILLink_can_set_IsTrimmable(string targetFramework)
{
var projectName = "HelloWorld";
@@ -1169,7 +1169,7 @@ public void ILLink_ignores_host_config_settings_with_link_false()
}
[RequiresMSBuildVersionTheory("17.0.0.32901")]
- [MemberData(nameof(SupportedTfms), MemberType = typeof(PublishTestUtils))]
+ [MemberData(nameof(Net8Plus), MemberType = typeof(PublishTestUtils))]
public void ILLink_runs_incrementally(string targetFramework)
{
var projectName = "HelloWorld";
@@ -1272,7 +1272,7 @@ public void ILLink_net7_defaults_trim_nonframework()
}
[RequiresMSBuildVersionTheory("17.0.0.32901")]
- [MemberData(nameof(SupportedTfms), MemberType = typeof(PublishTestUtils))]
+ [MemberData(nameof(Net8Plus), MemberType = typeof(PublishTestUtils))]
public void ILLink_does_not_include_leftover_artifacts_on_second_run(string targetFramework)
{
var projectName = "HelloWorld";
@@ -1362,7 +1362,7 @@ public void ILLink_keeps_symbols_by_default(string targetFramework)
}
[RequiresMSBuildVersionTheory("17.0.0.32901")]
- [MemberData(nameof(SupportedTfms), MemberType = typeof(PublishTestUtils))]
+ [MemberData(nameof(Net8Plus), MemberType = typeof(PublishTestUtils))]
public void ILLink_removes_symbols_when_debugger_support_is_disabled(string targetFramework)
{
var projectName = "HelloWorld";
@@ -1398,7 +1398,7 @@ public GivenThatWeWantToRunILLink3(ITestOutputHelper log) : base(log)
}
[RequiresMSBuildVersionTheory("17.0.0.32901")]
- [MemberData(nameof(SupportedTfms), MemberType = typeof(PublishTestUtils))]
+ [MemberData(nameof(Net8Plus), MemberType = typeof(PublishTestUtils))]
public void ILLink_accepts_option_to_remove_symbols(string targetFramework)
{
var projectName = "HelloWorld";
@@ -1653,7 +1653,7 @@ public void ILLink_dont_display_informational_warning_by_default_on_net6plus(str
}
[RequiresMSBuildVersionTheory("17.0.0.32901")]
- [MemberData(nameof(SupportedTfms), MemberType = typeof(PublishTestUtils))]
+ [MemberData(nameof(Net8Plus), MemberType = typeof(PublishTestUtils))]
public void ILLink_dont_display_time_awareness_message_on_incremental_build(string targetFramework)
{
var projectName = "HelloWorld";
diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_MatchSpecifiedFiles/Tool.Test/Tool.Test.csproj b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_MatchSpecifiedFiles/Tool.Test/Tool.Test.csproj
index 803259499135..d99f085aa9a6 100644
--- a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_MatchSpecifiedFiles/Tool.Test/Tool.Test.csproj
+++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_MatchSpecifiedFiles/Tool.Test/Tool.Test.csproj
@@ -8,7 +8,7 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_MismatchSpecifiedFiles/Tool.Test/Tool.Test.csproj b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_MismatchSpecifiedFiles/Tool.Test/Tool.Test.csproj
index 803259499135..d99f085aa9a6 100644
--- a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_MismatchSpecifiedFiles/Tool.Test/Tool.Test.csproj
+++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_MismatchSpecifiedFiles/Tool.Test/Tool.Test.csproj
@@ -8,7 +8,7 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithFileName/Tool.Test/Tool.Test.csproj b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithFileName/Tool.Test/Tool.Test.csproj
index 803259499135..d99f085aa9a6 100644
--- a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithFileName/Tool.Test/Tool.Test.csproj
+++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithFileName/Tool.Test/Tool.Test.csproj
@@ -8,7 +8,7 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithGlobstar/Tool.Test/Tool.Test.csproj b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithGlobstar/Tool.Test/Tool.Test.csproj
index 803259499135..d99f085aa9a6 100644
--- a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithGlobstar/Tool.Test/Tool.Test.csproj
+++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithGlobstar/Tool.Test/Tool.Test.csproj
@@ -8,7 +8,7 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithWildcard/Tool.Test/Tool.Test.csproj b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithWildcard/Tool.Test/Tool.Test.csproj
index 803259499135..d99f085aa9a6 100644
--- a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithWildcard/Tool.Test/Tool.Test.csproj
+++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_PatternWithWildcard/Tool.Test/Tool.Test.csproj
@@ -8,7 +8,7 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_SupportSemicolonDelimitedList/Tool.Test/Tool.Test.csproj b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_SupportSemicolonDelimitedList/Tool.Test/Tool.Test.csproj
index 803259499135..d99f085aa9a6 100644
--- a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_SupportSemicolonDelimitedList/Tool.Test/Tool.Test.csproj
+++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/RestoreNuGet/Files_SupportSemicolonDelimitedList/Tool.Test/Tool.Test.csproj
@@ -8,7 +8,7 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/TestAssets/TestProjects/XUnitTestProject/XUnitTestProject.csproj b/test/TestAssets/TestProjects/XUnitTestProject/XUnitTestProject.csproj
index a173bf6b2be3..ee341f19374d 100644
--- a/test/TestAssets/TestProjects/XUnitTestProject/XUnitTestProject.csproj
+++ b/test/TestAssets/TestProjects/XUnitTestProject/XUnitTestProject.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/test/TestAssets/TestProjects/XunitMulti/VSTestXunitDesktopAndNetCore.csproj b/test/TestAssets/TestProjects/XunitMulti/VSTestXunitDesktopAndNetCore.csproj
index 5095d4b6d623..0ac70629036a 100644
--- a/test/TestAssets/TestProjects/XunitMulti/VSTestXunitDesktopAndNetCore.csproj
+++ b/test/TestAssets/TestProjects/XunitMulti/VSTestXunitDesktopAndNetCore.csproj
@@ -2,10 +2,10 @@
- net462;$(CurrentTargetFramework)
+ net48;$(CurrentTargetFramework)
-
+
DESKTOP;$(DefineConstants)
diff --git a/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs b/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs
index de666cf5d0ad..a92ea93517ea 100644
--- a/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs
+++ b/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestFromCsprojForMultipleTFM.cs
@@ -154,7 +154,7 @@ public void TestSlnWithMultitargetedProject()
TargetFrameworks = ToolsetInfo.CurrentTargetFramework,
};
- testProject.PackageReferences.Add(new TestPackageReference("Microsoft.NET.Test.Sdk", "16.7.1"));
+ testProject.PackageReferences.Add(new TestPackageReference("Microsoft.NET.Test.Sdk", "17.12.0"));
testProject.PackageReferences.Add(new TestPackageReference("xunit", "2.4.1"));
testProject.PackageReferences.Add(new TestPackageReference("xunit.runner.visualstudio", "2.4.3", privateAssets: "all"));