dependabot-nuget 0.311.0 → 0.312.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 +7 -0
- 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 +33 -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 +1 -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 +116 -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 +8 -0
- metadata +25 -23
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs
CHANGED
@@ -832,10 +832,8 @@ public partial class DiscoveryWorkerTests
|
|
832
832
|
{
|
833
833
|
FilePath = "myproj.csproj",
|
834
834
|
Dependencies = [
|
835
|
-
new("Some.Package", "1.2.3.4", DependencyType.PackageReference, TargetFrameworks: ["net7.0"], IsDirect: true),
|
836
|
-
new("
|
837
|
-
new("Transitive.Dependency", "5.6.7.8", DependencyType.Unknown, TargetFrameworks: ["net7.0"], IsTransitive: true),
|
838
|
-
new("Transitive.Dependency", "5.6.7.8", DependencyType.Unknown, TargetFrameworks: ["net8.0"], IsTransitive: true),
|
835
|
+
new("Some.Package", "1.2.3.4", DependencyType.PackageReference, TargetFrameworks: ["net7.0", "net8.0"], IsDirect: true),
|
836
|
+
new("Transitive.Dependency", "5.6.7.8", DependencyType.Unknown, TargetFrameworks: ["net7.0", "net8.0"], IsTransitive: true),
|
839
837
|
],
|
840
838
|
Properties = [
|
841
839
|
new("TargetFrameworks", "net7.0;net8.0", "myproj.csproj"),
|
@@ -1191,11 +1189,7 @@ public partial class DiscoveryWorkerTests
|
|
1191
1189
|
{
|
1192
1190
|
FilePath = "project.csproj",
|
1193
1191
|
Dependencies = [
|
1194
|
-
new("Some.Package", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0-android"], IsDirect: true),
|
1195
|
-
new("Some.Package", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0-ios"], IsDirect: true),
|
1196
|
-
new("Some.Package", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0-maccatalyst"], IsDirect: true),
|
1197
|
-
new("Some.Package", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0-macos"], IsDirect: true),
|
1198
|
-
new("Some.Package", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0-windows"], IsDirect: true),
|
1192
|
+
new("Some.Package", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0-android", "net8.0-ios", "net8.0-maccatalyst", "net8.0-macos", "net8.0-windows"], IsDirect: true),
|
1199
1193
|
],
|
1200
1194
|
Properties = [
|
1201
1195
|
new("TargetFrameworks", "net8.0-ios;net8.0-android;net8.0-macos;net8.0-maccatalyst;net8.0-windows", @"src/project.csproj"),
|
@@ -673,8 +673,7 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
673
673
|
FilePath = "src/project.csproj",
|
674
674
|
TargetFrameworks = ["net7.0", "net8.0"],
|
675
675
|
Dependencies = [
|
676
|
-
new("Some.Package", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net7.0"], IsDirect: true),
|
677
|
-
new("Some.Package", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
|
676
|
+
new("Some.Package", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net7.0", "net8.0"], IsDirect: true),
|
678
677
|
],
|
679
678
|
Properties = [
|
680
679
|
new("TargetFrameworks", "net7.0;net8.0", "src/project.csproj")
|
@@ -1,4 +1,5 @@
|
|
1
1
|
using System.Collections.Immutable;
|
2
|
+
using System.Text;
|
2
3
|
|
3
4
|
using NuGetUpdater.Core.Discover;
|
4
5
|
using NuGetUpdater.Core.Test.Update;
|
@@ -297,8 +298,7 @@ public class SdkProjectDiscoveryTests : DiscoveryWorkerTestBase
|
|
297
298
|
FilePath = "library.csproj",
|
298
299
|
Dependencies =
|
299
300
|
[
|
300
|
-
new("Some.Dependency", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net7.0"], IsDirect: true),
|
301
|
-
new("Some.Dependency", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
|
301
|
+
new("Some.Dependency", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net7.0", "net8.0"], IsDirect: true),
|
302
302
|
],
|
303
303
|
ImportedFiles = [],
|
304
304
|
Properties =
|
@@ -524,6 +524,62 @@ public class SdkProjectDiscoveryTests : DiscoveryWorkerTestBase
|
|
524
524
|
);
|
525
525
|
}
|
526
526
|
|
527
|
+
[Fact]
|
528
|
+
public async Task TransitiveDependenciesWithoutAssembliesAreReported()
|
529
|
+
{
|
530
|
+
await TestDiscoverAsync(
|
531
|
+
packages:
|
532
|
+
[
|
533
|
+
MockNuGetPackage.CreateSimplePackage("Some.Dependency", "1.2.3", "net9.0", [(null, [("Transitive.Dependency", "4.5.6")])]),
|
534
|
+
new MockNuGetPackage(
|
535
|
+
"Transitive.Dependency",
|
536
|
+
"4.5.6",
|
537
|
+
Files: [
|
538
|
+
("build/Transitive.Dependency.targets", Encoding.UTF8.GetBytes("<Project />"))
|
539
|
+
],
|
540
|
+
DependencyGroups: [(null, [("Super.Transitive.Dependency", "7.8.9")])]
|
541
|
+
),
|
542
|
+
MockNuGetPackage.CreateSimplePackage("Super.Transitive.Dependency", "7.8.9", "net9.0"),
|
543
|
+
],
|
544
|
+
startingDirectory: "src",
|
545
|
+
projectPath: "src/library.csproj",
|
546
|
+
files:
|
547
|
+
[
|
548
|
+
("src/library.csproj", """
|
549
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
550
|
+
<PropertyGroup>
|
551
|
+
<TargetFramework>net9.0</TargetFramework>
|
552
|
+
</PropertyGroup>
|
553
|
+
<ItemGroup>
|
554
|
+
<PackageReference Include="Some.Dependency" Version="1.2.3" />
|
555
|
+
</ItemGroup>
|
556
|
+
</Project>
|
557
|
+
""")
|
558
|
+
],
|
559
|
+
expectedProjects:
|
560
|
+
[
|
561
|
+
new()
|
562
|
+
{
|
563
|
+
FilePath = "library.csproj",
|
564
|
+
Dependencies =
|
565
|
+
[
|
566
|
+
new("Some.Dependency", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net9.0"], IsDirect: true),
|
567
|
+
new("Transitive.Dependency", "4.5.6", DependencyType.Unknown, TargetFrameworks: ["net9.0"], IsTransitive: true),
|
568
|
+
new("Super.Transitive.Dependency", "7.8.9", DependencyType.Unknown, TargetFrameworks: ["net9.0"], IsTransitive: true),
|
569
|
+
],
|
570
|
+
ImportedFiles = [],
|
571
|
+
Properties =
|
572
|
+
[
|
573
|
+
new("TargetFramework", "net9.0", "src/library.csproj"),
|
574
|
+
],
|
575
|
+
TargetFrameworks = ["net9.0"],
|
576
|
+
ReferencedProjectPaths = [],
|
577
|
+
AdditionalFiles = [],
|
578
|
+
},
|
579
|
+
]
|
580
|
+
);
|
581
|
+
}
|
582
|
+
|
527
583
|
private static async Task TestDiscoverAsync(string startingDirectory, string projectPath, TestFile[] files, ImmutableArray<ExpectedSdkProjectDiscoveryResult> expectedProjects, MockNuGetPackage[]? packages = null)
|
528
584
|
{
|
529
585
|
using var testDirectory = await TemporaryDirectory.CreateWithContentsAsync(files);
|
@@ -0,0 +1,116 @@
|
|
1
|
+
using NuGetUpdater.Core.Run;
|
2
|
+
using NuGetUpdater.Core.Run.ApiModel;
|
3
|
+
using NuGetUpdater.Core.Test.Utilities;
|
4
|
+
|
5
|
+
using Xunit;
|
6
|
+
|
7
|
+
namespace NuGetUpdater.Core.Test.Run;
|
8
|
+
|
9
|
+
public class HttpApiHandlerTests
|
10
|
+
{
|
11
|
+
[Fact]
|
12
|
+
public async Task FailedRequestWithContentReportsData()
|
13
|
+
{
|
14
|
+
// arrange
|
15
|
+
// this mimics an error that can be returned by the server
|
16
|
+
var errorContent = """{"errors":[{"status":400,"title":"Bad Request","detail":"some-detail"}]}""";
|
17
|
+
using var http = TestHttpServer.CreateTestStringServer((method, url) =>
|
18
|
+
{
|
19
|
+
return (400, errorContent);
|
20
|
+
});
|
21
|
+
var handler = new HttpApiHandler(http.BaseUrl, "TEST-ID");
|
22
|
+
|
23
|
+
// act
|
24
|
+
var exception = await Assert.ThrowsAsync<HttpRequestException>(() => handler.IncrementMetric(new()
|
25
|
+
{
|
26
|
+
// body is irrelevant for this test
|
27
|
+
Metric = "TEST",
|
28
|
+
}));
|
29
|
+
|
30
|
+
// assert
|
31
|
+
var expectedMessage = $"400 (BadRequest): {errorContent}";
|
32
|
+
Assert.Equal(expectedMessage, exception.Message);
|
33
|
+
}
|
34
|
+
|
35
|
+
[Fact]
|
36
|
+
public async Task FailedRequestWithNoContentOnlyReportsStatusCode()
|
37
|
+
{
|
38
|
+
// arrange
|
39
|
+
using var http = TestHttpServer.CreateTestServer((method, url) =>
|
40
|
+
{
|
41
|
+
// no error content returned
|
42
|
+
return (500, null);
|
43
|
+
});
|
44
|
+
var handler = new HttpApiHandler(http.BaseUrl, "TEST-ID");
|
45
|
+
|
46
|
+
// act
|
47
|
+
var exception = await Assert.ThrowsAsync<HttpRequestException>(() => handler.IncrementMetric(new()
|
48
|
+
{
|
49
|
+
// body is irrelevant for this test
|
50
|
+
Metric = "TEST",
|
51
|
+
}));
|
52
|
+
|
53
|
+
// assert
|
54
|
+
var expectedMessage = $"500 (InternalServerError)";
|
55
|
+
Assert.Equal(expectedMessage, exception.Message);
|
56
|
+
}
|
57
|
+
|
58
|
+
[Theory]
|
59
|
+
[MemberData(nameof(ErrorsAreSentToTheCorrectEndpointTestData))]
|
60
|
+
public async Task ErrorsAreSentToTheCorrectEndpoint(JobErrorBase error, params string[] expectedEndpoints)
|
61
|
+
{
|
62
|
+
// arrange
|
63
|
+
var actualEndpoints = new List<string>();
|
64
|
+
using var http = TestHttpServer.CreateTestStringServer((method, url) =>
|
65
|
+
{
|
66
|
+
var expectedPrefix = "/update_jobs/TEST-ID/";
|
67
|
+
var actualPathAndQuery = new Uri(url).PathAndQuery;
|
68
|
+
if (!actualPathAndQuery.StartsWith(expectedPrefix))
|
69
|
+
{
|
70
|
+
throw new Exception($"Didn't find expected prefix: [{expectedPrefix}]");
|
71
|
+
}
|
72
|
+
|
73
|
+
actualEndpoints.Add(actualPathAndQuery[expectedPrefix.Length..]);
|
74
|
+
return (200, "ok");
|
75
|
+
});
|
76
|
+
var handler = new HttpApiHandler(http.BaseUrl, "TEST-ID");
|
77
|
+
|
78
|
+
// act
|
79
|
+
await handler.RecordUpdateJobError(error);
|
80
|
+
|
81
|
+
// assert
|
82
|
+
AssertEx.Equal(expectedEndpoints, actualEndpoints);
|
83
|
+
}
|
84
|
+
|
85
|
+
[Fact]
|
86
|
+
public void ErrorsAreSentToTheCorrectEndpoint_AllTypesAreTested()
|
87
|
+
{
|
88
|
+
var remainingErrorTypes = typeof(JobErrorBase).Assembly
|
89
|
+
.GetTypes()
|
90
|
+
.Where(t => t.IsSubclassOf(typeof(JobErrorBase)))
|
91
|
+
.Select(t => t.Name)
|
92
|
+
.ToHashSet();
|
93
|
+
foreach (var testData in ErrorsAreSentToTheCorrectEndpointTestData())
|
94
|
+
{
|
95
|
+
var seenErrorType = testData[0].GetType().Name;
|
96
|
+
remainingErrorTypes.Remove(seenErrorType);
|
97
|
+
}
|
98
|
+
|
99
|
+
Assert.Empty(remainingErrorTypes);
|
100
|
+
}
|
101
|
+
|
102
|
+
public static IEnumerable<object[]> ErrorsAreSentToTheCorrectEndpointTestData()
|
103
|
+
{
|
104
|
+
yield return [new BadRequirement("unused"), "record_update_job_error"];
|
105
|
+
yield return [new DependencyFileNotFound("unused"), "record_update_job_error"];
|
106
|
+
yield return [new DependencyFileNotParseable("unused"), "record_update_job_error"];
|
107
|
+
yield return [new DependencyNotFound("unused"), "record_update_job_error"];
|
108
|
+
yield return [new JobRepoNotFound("unused"), "record_update_job_error"];
|
109
|
+
yield return [new PrivateSourceAuthenticationFailure(["unused"]), "record_update_job_error"];
|
110
|
+
yield return [new PrivateSourceBadResponse(["unused"]), "record_update_job_error"];
|
111
|
+
yield return [new PullRequestExistsForLatestVersion("unused", "unused"), "record_update_job_error"];
|
112
|
+
yield return [new SecurityUpdateNotNeeded("unused"), "record_update_job_error"];
|
113
|
+
yield return [new UnknownError(new Exception("unused"), "unused"), "record_update_job_error", "record_update_job_unknown_error", "increment_metric"];
|
114
|
+
yield return [new UpdateNotPossible(["unused"]), "record_update_job_error"];
|
115
|
+
}
|
116
|
+
}
|
@@ -190,8 +190,7 @@ public class MessageReportTests
|
|
190
190
|
"""
|
191
191
|
Error type: unknown_error
|
192
192
|
- error-class: NotImplementedException
|
193
|
-
- error-message: error message
|
194
|
-
- error-backtrace: <unknown>
|
193
|
+
- error-message: System.NotImplementedException: error message
|
195
194
|
- package-manager: nuget
|
196
195
|
- job-id: TEST-JOB-ID
|
197
196
|
"""
|
@@ -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
|
}
|