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"));