dependabot-nuget 0.311.0 → 0.313.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/VersionFinder.cs +7 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/BadResponseException.cs +12 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +121 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +64 -17
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UnknownError.cs +12 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/HttpApiHandler.cs +19 -50
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/IApiHandler.cs +57 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +10 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +13 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +15 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/VersionFinderTests.cs +74 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +3 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +1 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +58 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/HttpApiHandlerTests.cs +157 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/JobErrorBaseTests.cs +86 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +1 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +227 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +40 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/TestApiHandler.cs +2 -39
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestHttpServer.cs +9 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackageReferenceUpdaterTests.cs +99 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +16 -0
- metadata +26 -23
@@ -16,8 +16,6 @@ using Xunit;
|
|
16
16
|
|
17
17
|
namespace NuGetUpdater.Core.Test.Run;
|
18
18
|
|
19
|
-
using static NuGetUpdater.Core.Utilities.EOLHandling;
|
20
|
-
|
21
19
|
using TestFile = (string Path, string Content);
|
22
20
|
using RawTestFile = (string Path, byte[] Content);
|
23
21
|
|
@@ -2777,6 +2775,162 @@ public class RunWorkerTests
|
|
2777
2775
|
);
|
2778
2776
|
}
|
2779
2777
|
|
2778
|
+
[Fact]
|
2779
|
+
public async Task AnalysisResultWithoutUpdatedDependenciesDoesNotCauseError()
|
2780
|
+
{
|
2781
|
+
await RunAsync(
|
2782
|
+
job: new()
|
2783
|
+
{
|
2784
|
+
Source = new()
|
2785
|
+
{
|
2786
|
+
Provider = "github",
|
2787
|
+
Repo = "test/repo",
|
2788
|
+
},
|
2789
|
+
Dependencies = [
|
2790
|
+
"Some.Package"
|
2791
|
+
],
|
2792
|
+
},
|
2793
|
+
files: [
|
2794
|
+
("project.csproj", "contents irrelevant")
|
2795
|
+
],
|
2796
|
+
discoveryWorker: new TestDiscoveryWorker(_input =>
|
2797
|
+
{
|
2798
|
+
return Task.FromResult(new WorkspaceDiscoveryResult()
|
2799
|
+
{
|
2800
|
+
Path = "",
|
2801
|
+
Projects = [
|
2802
|
+
new()
|
2803
|
+
{
|
2804
|
+
FilePath = "project.csproj",
|
2805
|
+
Dependencies = [
|
2806
|
+
new("Some.Package", "1.0.0", DependencyType.PackageReference)
|
2807
|
+
],
|
2808
|
+
ImportedFiles = [],
|
2809
|
+
AdditionalFiles = [],
|
2810
|
+
}
|
2811
|
+
]
|
2812
|
+
});
|
2813
|
+
}),
|
2814
|
+
analyzeWorker: new TestAnalyzeWorker(_input =>
|
2815
|
+
{
|
2816
|
+
return Task.FromResult(new AnalysisResult()
|
2817
|
+
{
|
2818
|
+
CanUpdate = true,
|
2819
|
+
UpdatedVersion = "1.1.0",
|
2820
|
+
UpdatedDependencies = [], // this is what was causing the problem
|
2821
|
+
});
|
2822
|
+
}),
|
2823
|
+
updaterWorker: new TestUpdaterWorker(async input =>
|
2824
|
+
{
|
2825
|
+
var repoRootPath = input.Item1;
|
2826
|
+
var filePath = input.Item2;
|
2827
|
+
await File.WriteAllTextAsync(Path.Join(repoRootPath, filePath), "updated contents irrelevant");
|
2828
|
+
return new UpdateOperationResult()
|
2829
|
+
{
|
2830
|
+
UpdateOperations = [
|
2831
|
+
new DirectUpdate()
|
2832
|
+
{
|
2833
|
+
DependencyName = "Some.Package",
|
2834
|
+
NewVersion = NuGetVersion.Parse("1.1.0"),
|
2835
|
+
UpdatedFiles = ["project.csproj"]
|
2836
|
+
}
|
2837
|
+
]
|
2838
|
+
};
|
2839
|
+
}),
|
2840
|
+
expectedResult: new()
|
2841
|
+
{
|
2842
|
+
Base64DependencyFiles = [
|
2843
|
+
new()
|
2844
|
+
{
|
2845
|
+
Directory = "/",
|
2846
|
+
Name = "project.csproj",
|
2847
|
+
Content = Convert.ToBase64String(Encoding.UTF8.GetBytes("contents irrelevant")),
|
2848
|
+
ContentEncoding = "base64"
|
2849
|
+
}
|
2850
|
+
],
|
2851
|
+
BaseCommitSha = "TEST-COMMIT-SHA",
|
2852
|
+
},
|
2853
|
+
expectedApiMessages: [
|
2854
|
+
new UpdatedDependencyList()
|
2855
|
+
{
|
2856
|
+
Dependencies = [
|
2857
|
+
new()
|
2858
|
+
{
|
2859
|
+
Name = "Some.Package",
|
2860
|
+
Version = "1.0.0",
|
2861
|
+
Requirements = [
|
2862
|
+
new()
|
2863
|
+
{
|
2864
|
+
Requirement = "1.0.0",
|
2865
|
+
File = "/project.csproj",
|
2866
|
+
Groups = ["dependencies"],
|
2867
|
+
}
|
2868
|
+
]
|
2869
|
+
}
|
2870
|
+
],
|
2871
|
+
DependencyFiles = ["/project.csproj"]
|
2872
|
+
},
|
2873
|
+
new IncrementMetric()
|
2874
|
+
{
|
2875
|
+
Metric = "updater.started",
|
2876
|
+
Tags = new()
|
2877
|
+
{
|
2878
|
+
["operation"] = "group_update_all_versions"
|
2879
|
+
}
|
2880
|
+
},
|
2881
|
+
new CreatePullRequest()
|
2882
|
+
{
|
2883
|
+
Dependencies =
|
2884
|
+
[
|
2885
|
+
new ReportedDependency()
|
2886
|
+
{
|
2887
|
+
Name = "Some.Package",
|
2888
|
+
Version = "1.1.0",
|
2889
|
+
Requirements =
|
2890
|
+
[
|
2891
|
+
new ReportedRequirement()
|
2892
|
+
{
|
2893
|
+
Requirement = "1.1.0",
|
2894
|
+
File = "/project.csproj",
|
2895
|
+
Groups = ["dependencies"],
|
2896
|
+
Source = new()
|
2897
|
+
{
|
2898
|
+
SourceUrl = null,
|
2899
|
+
Type = "nuget_repo",
|
2900
|
+
}
|
2901
|
+
}
|
2902
|
+
],
|
2903
|
+
PreviousVersion = "1.0.0",
|
2904
|
+
PreviousRequirements =
|
2905
|
+
[
|
2906
|
+
new ReportedRequirement()
|
2907
|
+
{
|
2908
|
+
Requirement = "1.0.0",
|
2909
|
+
File = "/project.csproj",
|
2910
|
+
Groups = ["dependencies"],
|
2911
|
+
}
|
2912
|
+
],
|
2913
|
+
}
|
2914
|
+
],
|
2915
|
+
UpdatedDependencyFiles =
|
2916
|
+
[
|
2917
|
+
new DependencyFile()
|
2918
|
+
{
|
2919
|
+
Name = "project.csproj",
|
2920
|
+
Directory = "/",
|
2921
|
+
Content = "updated contents irrelevant",
|
2922
|
+
},
|
2923
|
+
],
|
2924
|
+
BaseCommitSha = "TEST-COMMIT-SHA",
|
2925
|
+
CommitMessage = TestPullRequestCommitMessage,
|
2926
|
+
PrTitle = TestPullRequestTitle,
|
2927
|
+
PrBody = TestPullRequestBody,
|
2928
|
+
},
|
2929
|
+
new MarkAsProcessed("TEST-COMMIT-SHA"),
|
2930
|
+
]
|
2931
|
+
);
|
2932
|
+
}
|
2933
|
+
|
2780
2934
|
[Fact]
|
2781
2935
|
public async Task ByteOrderMarksAreDetectedAndRestored()
|
2782
2936
|
{
|
@@ -3266,6 +3420,50 @@ public class RunWorkerTests
|
|
3266
3420
|
);
|
3267
3421
|
}
|
3268
3422
|
|
3423
|
+
[Fact]
|
3424
|
+
public async Task UnknownErrorsGenerateAllRequiredApiCalls()
|
3425
|
+
{
|
3426
|
+
await RunAsync(
|
3427
|
+
job: new Job()
|
3428
|
+
{
|
3429
|
+
Source = new()
|
3430
|
+
{
|
3431
|
+
Provider = "github",
|
3432
|
+
Repo = "test/repo",
|
3433
|
+
Directory = "some-dir",
|
3434
|
+
}
|
3435
|
+
},
|
3436
|
+
packages: [],
|
3437
|
+
files: [],
|
3438
|
+
discoveryWorker: new TestDiscoveryWorker(_input =>
|
3439
|
+
{
|
3440
|
+
throw new FileNotFoundException("some required file is missing");
|
3441
|
+
}),
|
3442
|
+
analyzeWorker: TestAnalyzeWorker.FromResults(), // unreachable
|
3443
|
+
updaterWorker: TestUpdaterWorker.FromResults(), // unreachable
|
3444
|
+
expectedResult: new RunResult()
|
3445
|
+
{
|
3446
|
+
Base64DependencyFiles = [],
|
3447
|
+
BaseCommitSha = "TEST-COMMIT-SHA",
|
3448
|
+
},
|
3449
|
+
expectedApiMessages:
|
3450
|
+
[
|
3451
|
+
new UnknownError(new FileNotFoundException("some required file is missing"), "TEST-JOB-ID"), // from record_update_job_error
|
3452
|
+
new UnknownError(new FileNotFoundException("some required file is missing"), "TEST-JOB-ID"), // from record_update_job_unknown_error
|
3453
|
+
new IncrementMetric()
|
3454
|
+
{
|
3455
|
+
Metric = "updater.update_job_unknown_error",
|
3456
|
+
Tags = new()
|
3457
|
+
{
|
3458
|
+
["package_manager"] = "nuget",
|
3459
|
+
["class_name"] = "FileNotFoundException"
|
3460
|
+
}
|
3461
|
+
},
|
3462
|
+
new MarkAsProcessed("TEST-COMMIT-SHA")
|
3463
|
+
]
|
3464
|
+
);
|
3465
|
+
}
|
3466
|
+
|
3269
3467
|
internal static Task RunAsync(Job job, TestFile[] files, IDiscoveryWorker? discoveryWorker, IAnalyzeWorker? analyzeWorker, IUpdaterWorker? updaterWorker, RunResult expectedResult, object[] expectedApiMessages, MockNuGetPackage[]? packages = null, ExperimentsManager? experimentsManager = null, string? repoContentsPath = null)
|
3270
3468
|
{
|
3271
3469
|
var rawTestFiles = files.Select(f => (f.Path, Encoding.UTF8.GetBytes(f.Content))).ToArray();
|
@@ -3300,13 +3498,36 @@ public class RunWorkerTests
|
|
3300
3498
|
var actualResult = await worker.RunAsync(job, repoContentsPathDirectoryInfo, "TEST-COMMIT-SHA");
|
3301
3499
|
var actualApiMessages = testApiHandler.ReceivedMessages
|
3302
3500
|
.Select(m =>
|
3303
|
-
|
3501
|
+
{
|
3502
|
+
object newObject;
|
3503
|
+
switch (m.Object)
|
3304
3504
|
{
|
3305
3505
|
// this isn't the place to verify the generated text
|
3306
|
-
CreatePullRequest create
|
3307
|
-
|
3308
|
-
|
3506
|
+
case CreatePullRequest create:
|
3507
|
+
newObject = create with { CommitMessage = TestPullRequestCommitMessage, PrTitle = TestPullRequestTitle, PrBody = TestPullRequestBody };
|
3508
|
+
break;
|
3509
|
+
case UpdatePullRequest update:
|
3510
|
+
newObject = update with { CommitMessage = TestPullRequestCommitMessage, PrTitle = TestPullRequestTitle, PrBody = TestPullRequestBody };
|
3511
|
+
break;
|
3512
|
+
// don't test callstacks
|
3513
|
+
case UnknownError unknown:
|
3514
|
+
var message = (string)unknown.Details["error-message"];
|
3515
|
+
var stackTraceOffset = message.IndexOf('\n');
|
3516
|
+
if (stackTraceOffset >= 0)
|
3517
|
+
{
|
3518
|
+
var messageWithoutStackTrace = message[..stackTraceOffset].TrimEnd('\r');
|
3519
|
+
unknown.Details["error-message"] = messageWithoutStackTrace;
|
3520
|
+
}
|
3521
|
+
|
3522
|
+
newObject = unknown;
|
3523
|
+
break;
|
3524
|
+
default:
|
3525
|
+
newObject = m.Object;
|
3526
|
+
break;
|
3309
3527
|
}
|
3528
|
+
|
3529
|
+
return (m.Type, Object: newObject);
|
3530
|
+
}
|
3310
3531
|
).ToArray();
|
3311
3532
|
|
3312
3533
|
// assert
|
@@ -8,7 +8,7 @@ using Xunit;
|
|
8
8
|
|
9
9
|
namespace NuGetUpdater.Core.Test.Run;
|
10
10
|
|
11
|
-
public class SerializationTests
|
11
|
+
public class SerializationTests : TestBase
|
12
12
|
{
|
13
13
|
[Fact]
|
14
14
|
public void DeserializeJob()
|
@@ -260,15 +260,9 @@ public class SerializationTests
|
|
260
260
|
}
|
261
261
|
|
262
262
|
[Theory]
|
263
|
-
[MemberData(nameof(
|
263
|
+
[MemberData(nameof(SerializeErrorTypesData))]
|
264
264
|
public void SerializeError(JobErrorBase error, string expectedSerialization)
|
265
265
|
{
|
266
|
-
if (error is UnknownError unknown)
|
267
|
-
{
|
268
|
-
// special case the exception's call stack to make it testable
|
269
|
-
unknown.Details["error-backtrace"] = "TEST-BACKTRACE";
|
270
|
-
}
|
271
|
-
|
272
266
|
var actual = HttpApiHandler.Serialize(error);
|
273
267
|
Assert.Equal(expectedSerialization, actual);
|
274
268
|
}
|
@@ -279,7 +273,7 @@ public class SerializationTests
|
|
279
273
|
var untestedTypes = typeof(JobErrorBase).Assembly.GetTypes()
|
280
274
|
.Where(t => t.IsSubclassOf(typeof(JobErrorBase)))
|
281
275
|
.ToHashSet();
|
282
|
-
foreach (object?[] data in
|
276
|
+
foreach (object?[] data in SerializeErrorTypesData())
|
283
277
|
{
|
284
278
|
var testedErrorType = data[0]!.GetType();
|
285
279
|
untestedTypes.Remove(testedErrorType);
|
@@ -601,7 +595,42 @@ public class SerializationTests
|
|
601
595
|
Assert.Equal(expected, actual);
|
602
596
|
}
|
603
597
|
|
604
|
-
|
598
|
+
[Fact]
|
599
|
+
public void SerializeRealUnknownErrorWithInnerException()
|
600
|
+
{
|
601
|
+
// arrange
|
602
|
+
using var tempDir = new TemporaryDirectory();
|
603
|
+
var action = new Action(() =>
|
604
|
+
{
|
605
|
+
try
|
606
|
+
{
|
607
|
+
throw new NotImplementedException("inner message");
|
608
|
+
}
|
609
|
+
catch (Exception ex)
|
610
|
+
{
|
611
|
+
throw new InvalidOperationException("outer message", ex);
|
612
|
+
}
|
613
|
+
});
|
614
|
+
var ex = Assert.Throws<InvalidOperationException>(action);
|
615
|
+
|
616
|
+
// act
|
617
|
+
var error = JobErrorBase.ErrorFromException(ex, "TEST-JOB-ID", tempDir.DirectoryPath);
|
618
|
+
|
619
|
+
// assert
|
620
|
+
// real exception message should look like this:
|
621
|
+
// System.InvalidOperationException: outer message
|
622
|
+
// ---> System.NotImplementedException: inner message
|
623
|
+
// at Namespace.Class.Method() in file.cs:line 123
|
624
|
+
// --- End of inner exception stack trace ---
|
625
|
+
// at Namespace.Class.Method() in file.cs:line 456
|
626
|
+
var errorMessage = Assert.IsType<string>(error.Details["error-message"]);
|
627
|
+
var lines = errorMessage.Split('\n').Select(l => l.TrimEnd('\r')).ToArray();
|
628
|
+
Assert.Equal("System.InvalidOperationException: outer message", lines[0]);
|
629
|
+
Assert.Equal(" ---> System.NotImplementedException: inner message", lines[1]);
|
630
|
+
Assert.Contains(" --- End of inner exception stack trace ---", lines[2..]);
|
631
|
+
}
|
632
|
+
|
633
|
+
public static IEnumerable<object?[]> SerializeErrorTypesData()
|
605
634
|
{
|
606
635
|
yield return
|
607
636
|
[
|
@@ -679,7 +708,7 @@ public class SerializationTests
|
|
679
708
|
[
|
680
709
|
new UnknownError(new Exception("some message"), "JOB-ID"),
|
681
710
|
"""
|
682
|
-
{"data":{"error-type":"unknown_error","error-details":{"error-class":"Exception","error-message":"some message","error-backtrace":"
|
711
|
+
{"data":{"error-type":"unknown_error","error-details":{"error-class":"Exception","error-message":"System.Exception: some message","error-backtrace":"","package-manager":"nuget","job-id":"JOB-ID"}}}
|
683
712
|
"""
|
684
713
|
];
|
685
714
|
|
@@ -1,5 +1,4 @@
|
|
1
1
|
using NuGetUpdater.Core.Run;
|
2
|
-
using NuGetUpdater.Core.Run.ApiModel;
|
3
2
|
|
4
3
|
namespace NuGetUpdater.Core.Test;
|
5
4
|
|
@@ -9,45 +8,9 @@ internal class TestApiHandler : IApiHandler
|
|
9
8
|
|
10
9
|
public IEnumerable<(Type Type, object Object)> ReceivedMessages => _receivedMessages;
|
11
10
|
|
12
|
-
public Task
|
11
|
+
public Task SendAsync(string endpoint, object body, string method)
|
13
12
|
{
|
14
|
-
_receivedMessages.Add((
|
15
|
-
return Task.CompletedTask;
|
16
|
-
}
|
17
|
-
|
18
|
-
public Task UpdateDependencyList(UpdatedDependencyList updatedDependencyList)
|
19
|
-
{
|
20
|
-
_receivedMessages.Add((updatedDependencyList.GetType(), updatedDependencyList));
|
21
|
-
return Task.CompletedTask;
|
22
|
-
}
|
23
|
-
|
24
|
-
public Task IncrementMetric(IncrementMetric incrementMetric)
|
25
|
-
{
|
26
|
-
_receivedMessages.Add((incrementMetric.GetType(), incrementMetric));
|
27
|
-
return Task.CompletedTask;
|
28
|
-
}
|
29
|
-
|
30
|
-
public Task CreatePullRequest(CreatePullRequest createPullRequest)
|
31
|
-
{
|
32
|
-
_receivedMessages.Add((createPullRequest.GetType(), createPullRequest));
|
33
|
-
return Task.CompletedTask;
|
34
|
-
}
|
35
|
-
|
36
|
-
public Task ClosePullRequest(ClosePullRequest closePullRequest)
|
37
|
-
{
|
38
|
-
_receivedMessages.Add((closePullRequest.GetType(), closePullRequest));
|
39
|
-
return Task.CompletedTask;
|
40
|
-
}
|
41
|
-
|
42
|
-
public Task UpdatePullRequest(UpdatePullRequest updatePullRequest)
|
43
|
-
{
|
44
|
-
_receivedMessages.Add((updatePullRequest.GetType(), updatePullRequest));
|
45
|
-
return Task.CompletedTask;
|
46
|
-
}
|
47
|
-
|
48
|
-
public Task MarkAsProcessed(MarkAsProcessed markAsProcessed)
|
49
|
-
{
|
50
|
-
_receivedMessages.Add((markAsProcessed.GetType(), markAsProcessed));
|
13
|
+
_receivedMessages.Add((body.GetType(), body));
|
51
14
|
return Task.CompletedTask;
|
52
15
|
}
|
53
16
|
}
|
@@ -10,13 +10,13 @@ namespace NuGetUpdater.Core.Test
|
|
10
10
|
{
|
11
11
|
public class TestHttpServer : IDisposable
|
12
12
|
{
|
13
|
-
private readonly Func<string, string, (int, byte[])> _requestHandler;
|
13
|
+
private readonly Func<string, string, (int, byte[]?)> _requestHandler;
|
14
14
|
private readonly HttpListener _listener;
|
15
15
|
private bool _runServer = true;
|
16
16
|
|
17
17
|
public string BaseUrl { get; }
|
18
18
|
|
19
|
-
private TestHttpServer(string baseurl, Func<string, string, (int, byte[])> requestHandler)
|
19
|
+
private TestHttpServer(string baseurl, Func<string, string, (int, byte[]?)> requestHandler)
|
20
20
|
{
|
21
21
|
BaseUrl = baseurl;
|
22
22
|
_requestHandler = requestHandler;
|
@@ -45,7 +45,11 @@ namespace NuGetUpdater.Core.Test
|
|
45
45
|
var context = await _listener.GetContextAsync();
|
46
46
|
var (statusCode, response) = _requestHandler(context.Request.HttpMethod, context.Request.Url!.AbsoluteUri);
|
47
47
|
context.Response.StatusCode = statusCode;
|
48
|
-
|
48
|
+
if (response is not null)
|
49
|
+
{
|
50
|
+
await context.Response.OutputStream.WriteAsync(response);
|
51
|
+
}
|
52
|
+
|
49
53
|
context.Response.Close();
|
50
54
|
}
|
51
55
|
}
|
@@ -57,7 +61,7 @@ namespace NuGetUpdater.Core.Test
|
|
57
61
|
return CreateTestServer((method, url) => requestHandler(url));
|
58
62
|
}
|
59
63
|
|
60
|
-
public static TestHttpServer CreateTestServer(Func<string, string, (int, byte[])> requestHandler)
|
64
|
+
public static TestHttpServer CreateTestServer(Func<string, string, (int, byte[]?)> requestHandler)
|
61
65
|
{
|
62
66
|
// static lock to ensure the port is not recycled after `FindFreePort()` and before we can start the real server
|
63
67
|
lock (PortGate)
|
@@ -77,7 +81,7 @@ namespace NuGetUpdater.Core.Test
|
|
77
81
|
|
78
82
|
public static TestHttpServer CreateTestStringServer(Func<string, string, (int, string)> requestHandler)
|
79
83
|
{
|
80
|
-
Func<string, string, (int, byte[])> bytesRequestHandler = (method, url) =>
|
84
|
+
Func<string, string, (int, byte[]?)> bytesRequestHandler = (method, url) =>
|
81
85
|
{
|
82
86
|
var (statusCode, response) = requestHandler(method, url);
|
83
87
|
return (statusCode, Encoding.UTF8.GetBytes(response));
|
@@ -55,7 +55,7 @@ public class PackageReferenceUpdaterTests
|
|
55
55
|
|
56
56
|
// assert
|
57
57
|
await buildFile.SaveAsync();
|
58
|
-
var actualContents = await File.ReadAllTextAsync(fullProjectPath);
|
58
|
+
var actualContents = await File.ReadAllTextAsync(fullProjectPath, TestContext.Current.CancellationToken);
|
59
59
|
var expectedContents = """
|
60
60
|
<Project Sdk="Microsoft.NET.Sdk">
|
61
61
|
<PropertyGroup>
|
@@ -71,6 +71,104 @@ public class PackageReferenceUpdaterTests
|
|
71
71
|
Assert.Equal(expectedContents, actualContents);
|
72
72
|
}
|
73
73
|
|
74
|
+
[Fact]
|
75
|
+
public async Task DirectBuildFileChangesAreMaintainedWhenPinningTransitiveDependency_DirectoryPackagesPropsIsDiscovered()
|
76
|
+
{
|
77
|
+
// arrange
|
78
|
+
using var tempDir = await TemporaryDirectory.CreateWithContentsAsync(
|
79
|
+
[
|
80
|
+
("project.csproj", """
|
81
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
82
|
+
<PropertyGroup>
|
83
|
+
<TargetFramework>net9.0</TargetFramework>
|
84
|
+
</PropertyGroup>
|
85
|
+
<ItemGroup>
|
86
|
+
<PackageReference Include="Completely.Different.Package" />
|
87
|
+
<PackageReference Include="Some.Package" />
|
88
|
+
</ItemGroup>
|
89
|
+
</Project>
|
90
|
+
"""),
|
91
|
+
("Directory.Packages.props", """
|
92
|
+
<Project>
|
93
|
+
<PropertyGroup>
|
94
|
+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
95
|
+
</PropertyGroup>
|
96
|
+
<ItemGroup>
|
97
|
+
<PackageVersion Include="Completely.Different.Package" Version="1.0.0" />
|
98
|
+
<PackageVersion Include="Some.Package" Version="1.0.0" />
|
99
|
+
</ItemGroup>
|
100
|
+
</Project>
|
101
|
+
""")
|
102
|
+
]);
|
103
|
+
var packages = new[]
|
104
|
+
{
|
105
|
+
MockNuGetPackage.CreateSimplePackage("Completely.Different.Package", "1.0.0", "net9.0"),
|
106
|
+
MockNuGetPackage.CreateSimplePackage("Completely.Different.Package", "2.0.0", "net9.0"),
|
107
|
+
MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net9.0", [(null, [("Transitive.Package", "1.0.0")])]),
|
108
|
+
MockNuGetPackage.CreateSimplePackage("Transitive.Package", "1.0.0", "net9.0"),
|
109
|
+
MockNuGetPackage.CreateSimplePackage("Transitive.Package", "2.0.0", "net9.0"),
|
110
|
+
};
|
111
|
+
await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, tempDir.DirectoryPath);
|
112
|
+
var fullProjectPath = Path.Combine(tempDir.DirectoryPath, "project.csproj");
|
113
|
+
var fullDirectoryPackagesPath = Path.Combine(tempDir.DirectoryPath, "Directory.Packages.props");
|
114
|
+
var buildFiles = new[]
|
115
|
+
{
|
116
|
+
ProjectBuildFile.Open(tempDir.DirectoryPath, fullProjectPath),
|
117
|
+
ProjectBuildFile.Open(tempDir.DirectoryPath, fullDirectoryPackagesPath)
|
118
|
+
}.ToImmutableArray();
|
119
|
+
var experimentsManager = new ExperimentsManager();
|
120
|
+
|
121
|
+
// act
|
122
|
+
// pin transitive dependency
|
123
|
+
var updatedFiles = await PackageReferenceUpdater.UpdateTransitiveDependencyAsync(
|
124
|
+
tempDir.DirectoryPath,
|
125
|
+
fullProjectPath,
|
126
|
+
"Transitive.Package",
|
127
|
+
"2.0.0",
|
128
|
+
buildFiles,
|
129
|
+
experimentsManager,
|
130
|
+
new TestLogger());
|
131
|
+
|
132
|
+
// subsequent update should not overwrite previous change
|
133
|
+
PackageReferenceUpdater.TryUpdateDependencyVersion(buildFiles, "Completely.Different.Package", "1.0.0", "2.0.0", new TestLogger());
|
134
|
+
|
135
|
+
// assert
|
136
|
+
foreach (var bf in buildFiles)
|
137
|
+
{
|
138
|
+
await bf.SaveAsync();
|
139
|
+
}
|
140
|
+
|
141
|
+
var actualProjectContents = await File.ReadAllTextAsync(fullProjectPath, TestContext.Current.CancellationToken);
|
142
|
+
var expectedProjectContents = """
|
143
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
144
|
+
<PropertyGroup>
|
145
|
+
<TargetFramework>net9.0</TargetFramework>
|
146
|
+
</PropertyGroup>
|
147
|
+
<ItemGroup>
|
148
|
+
<PackageReference Include="Completely.Different.Package" />
|
149
|
+
<PackageReference Include="Some.Package" />
|
150
|
+
<PackageReference Include="Transitive.Package" />
|
151
|
+
</ItemGroup>
|
152
|
+
</Project>
|
153
|
+
""";
|
154
|
+
Assert.Equal(expectedProjectContents.Replace("\r", ""), actualProjectContents.Replace("\r", ""));
|
155
|
+
|
156
|
+
var actualDirectoryPackagesContents = await File.ReadAllTextAsync(fullDirectoryPackagesPath, TestContext.Current.CancellationToken);
|
157
|
+
var expectedDirectoryPackagesContents = """
|
158
|
+
<Project>
|
159
|
+
<PropertyGroup>
|
160
|
+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
161
|
+
</PropertyGroup>
|
162
|
+
<ItemGroup>
|
163
|
+
<PackageVersion Include="Completely.Different.Package" Version="2.0.0" />
|
164
|
+
<PackageVersion Include="Some.Package" Version="1.0.0" />
|
165
|
+
<PackageVersion Include="Transitive.Package" Version="2.0.0" />
|
166
|
+
</ItemGroup>
|
167
|
+
</Project>
|
168
|
+
""";
|
169
|
+
Assert.Equal(expectedDirectoryPackagesContents.Replace("\r", ""), actualDirectoryPackagesContents.Replace("\r", ""));
|
170
|
+
}
|
171
|
+
|
74
172
|
[Theory]
|
75
173
|
[MemberData(nameof(ComputeUpdateOperationsTestData))]
|
76
174
|
public async Task ComputeUpdateOperations
|
@@ -1852,6 +1852,22 @@ public class MSBuildHelperTests : TestBase
|
|
1852
1852
|
// expectedError
|
1853
1853
|
new UpdateNotPossible(["Some.Package.1.2.3"]),
|
1854
1854
|
];
|
1855
|
+
|
1856
|
+
yield return
|
1857
|
+
[
|
1858
|
+
// output
|
1859
|
+
"Failed to fetch results from V2 feed at 'http://nuget.example.com/FindPackagesById()?id='Some.Package'&semVerLevel=2.0.0' with following message : Response status code does not indicate success: 404.",
|
1860
|
+
// expectedError
|
1861
|
+
new DependencyNotFound("Some.Package"),
|
1862
|
+
];
|
1863
|
+
|
1864
|
+
yield return
|
1865
|
+
[
|
1866
|
+
// output
|
1867
|
+
"This part is not reported.\nAn error occurred while reading file '/path/to/packages.config': Some error message.\nThis part is not reported.",
|
1868
|
+
// expectedError
|
1869
|
+
new DependencyFileNotParseable("/path/to/packages.config", "Some error message."),
|
1870
|
+
];
|
1855
1871
|
}
|
1856
1872
|
|
1857
1873
|
public static IEnumerable<object[]> GetTopLevelPackageDependencyInfosTestData()
|