Skip to content

Commit 6a5520c

Browse files
committed
Add integration test for unreachable nuget feeds
1 parent 7051db5 commit 6a5520c

File tree

12 files changed

+165
-9
lines changed

12 files changed

+165
-9
lines changed

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.Nuget.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -389,13 +389,17 @@ private bool IsFeedReachable(string feed)
389389
{
390390
logger.LogInfo($"Checking if Nuget feed '{feed}' is reachable...");
391391
using HttpClient client = new();
392-
var timeoutSeconds = 1;
393-
var tryCount = 4;
392+
int timeoutMilliSeconds = int.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetFeedResponsivenessInitialTimeout), out timeoutMilliSeconds)
393+
? timeoutMilliSeconds
394+
: 1000;
395+
int tryCount = int.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetFeedResponsivenessRequestCount), out tryCount)
396+
? tryCount
397+
: 4;
394398

395399
for (var i = 0; i < tryCount; i++)
396400
{
397401
using var cts = new CancellationTokenSource();
398-
cts.CancelAfter(timeoutSeconds * 1000);
402+
cts.CancelAfter(timeoutMilliSeconds);
399403
try
400404
{
401405
ExecuteGetRequest(feed, client, cts.Token).GetAwaiter().GetResult();
@@ -407,8 +411,8 @@ private bool IsFeedReachable(string feed)
407411
tce.CancellationToken == cts.Token &&
408412
cts.Token.IsCancellationRequested)
409413
{
410-
logger.LogWarning($"Didn't receive answer from Nuget feed '{feed}' in {timeoutSeconds} seconds.");
411-
timeoutSeconds *= 2;
414+
logger.LogWarning($"Didn't receive answer from Nuget feed '{feed}' in {timeoutMilliSeconds}ms.");
415+
timeoutMilliSeconds *= 2;
412416
continue;
413417
}
414418

@@ -418,7 +422,7 @@ private bool IsFeedReachable(string feed)
418422
}
419423
}
420424

421-
logger.LogError($"Didn't receive answer from Nuget feed '{feed}'. Tried it {tryCount} times.");
425+
logger.LogWarning($"Didn't receive answer from Nuget feed '{feed}'. Tried it {tryCount} times.");
422426
return false;
423427
}
424428

@@ -428,17 +432,18 @@ private bool CheckFeeds(List<FileInfo> allFiles)
428432
var feeds = GetAllFeeds(allFiles);
429433

430434
var excludedFeeds = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ExcludedNugetFeedsFromResponsivenessCheck)
431-
?.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries)
435+
?.Split(" ", StringSplitOptions.RemoveEmptyEntries)
432436
.ToHashSet() ?? [];
433437

434438
if (excludedFeeds.Count > 0)
435439
{
436-
logger.LogInfo($"Excluded feeds from responsiveness check: {string.Join(", ", excludedFeeds.OrderBy(f => f))}");
440+
logger.LogInfo($"Excluded Nuget feeds from responsiveness check: {string.Join(", ", excludedFeeds.OrderBy(f => f))}");
437441
}
438442

439443
var allFeedsReachable = feeds.All(feed => excludedFeeds.Contains(feed) || IsFeedReachable(feed));
440444
if (!allFeedsReachable)
441445
{
446+
logger.LogWarning("Found unreachable Nuget feed in C# analysis with build-mode 'none'. This may cause missing dependencies in the analysis.");
442447
diagnosticsWriter.AddEntry(new DiagnosticMessage(
443448
Language.CSharp,
444449
"buildless/unreachable-feed",

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/EnvironmentVariableNames.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,17 @@ internal class EnvironmentVariableNames
2525
/// <summary>
2626
/// Specifies the NuGet feeds to exclude from the responsiveness check.
2727
/// </summary>
28-
public const string ExcludedNugetFeedsFromResponsivenessCheck = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_EXCLUDED_FROM_CHECK";
28+
public const string ExcludedNugetFeedsFromResponsivenessCheck = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_EXCLUDED";
29+
30+
/// <summary>
31+
/// Specifies the timeout for the initial check of NuGet feeds responsiveness.
32+
/// </summary>
33+
public const string NugetFeedResponsivenessInitialTimeout = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_TIMEOUT";
34+
35+
/// <summary>
36+
/// Specifies how many requests to make to the NuGet feed to check its responsiveness.
37+
/// </summary>
38+
public const string NugetFeedResponsivenessRequestCount = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_LIMIT";
2939

3040
/// <summary>
3141
/// Specifies the location of the diagnostic directory.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| [...]/newtonsoft.json/13.0.3/lib/net6.0/Newtonsoft.Json.dll |
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import csharp
2+
3+
private string getPath(Assembly a) {
4+
not a.getCompilation().getOutputAssembly() = a and
5+
exists(string s | s = a.getFile().getAbsolutePath() |
6+
result = "[...]/" + s.substring(s.indexOf("newtonsoft.json"), s.length())
7+
)
8+
}
9+
10+
from Assembly a
11+
select getPath(a)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
| All Nuget feeds reachable | 0.0 |
2+
| Fallback nuget restore | 1.0 |
3+
| Project files on filesystem | 1.0 |
4+
| Resolved assembly conflicts | 7.0 |
5+
| Restored .NET framework variants | 0.0 |
6+
| Solution files on filesystem | 1.0 |
7+
| Source files generated | 0.0 |
8+
| Source files on filesystem | 1.0 |
9+
| Successfully ran fallback nuget restore | 1.0 |
10+
| Unresolved references | 0.0 |
11+
| UseWPF set | 0.0 |
12+
| UseWindowsForms set | 0.0 |
13+
| WebView extraction enabled | 1.0 |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import csharp
2+
import semmle.code.csharp.commons.Diagnostics
3+
4+
query predicate compilationInfo(string key, float value) {
5+
key != "Resolved references" and
6+
not key.matches("Compiler diagnostic count for%") and
7+
exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) |
8+
key = infoKey and
9+
value = infoValue.toFloat()
10+
or
11+
not exists(infoValue.toFloat()) and
12+
key = infoKey + ": " + infoValue and
13+
value = 1
14+
)
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"markdownMessage": "C# analysis with build-mode 'none' completed.",
3+
"severity": "unknown",
4+
"source": {
5+
"extractorName": "csharp",
6+
"id": "csharp/autobuilder/buildless/complete",
7+
"name": "C# analysis with build-mode 'none' completed"
8+
},
9+
"visibility": {
10+
"cliSummaryTable": true,
11+
"statusPage": false,
12+
"telemetry": true
13+
}
14+
}
15+
{
16+
"markdownMessage": "C# with build-mode set to 'none'. This means that all C# source in the working directory will be scanned, with build tools, such as Nuget and Dotnet CLIs, only contributing information about external dependencies.",
17+
"severity": "note",
18+
"source": {
19+
"extractorName": "csharp",
20+
"id": "csharp/autobuilder/buildless/mode-active",
21+
"name": "C# with build-mode set to 'none'"
22+
},
23+
"visibility": {
24+
"cliSummaryTable": true,
25+
"statusPage": true,
26+
"telemetry": true
27+
}
28+
}
29+
{
30+
"markdownMessage": "Found unreachable Nuget feed in C# analysis with build-mode 'none'. This may cause missing dependencies in the analysis.",
31+
"severity": "warning",
32+
"source": {
33+
"extractorName": "csharp",
34+
"id": "csharp/autobuilder/buildless/unreachable-feed",
35+
"name": "Found unreachable Nuget feed in C# analysis with build-mode 'none'"
36+
},
37+
"visibility": {
38+
"cliSummaryTable": true,
39+
"statusPage": true,
40+
"telemetry": true
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class Program
2+
{
3+
static void Main(string[] args)
4+
{
5+
}
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<packageSources>
4+
<clear />
5+
<add key="x" value="https://localhost:53/packages/" />
6+
<add key="y" value="https://localhost:80/packages/" />
7+
</packageSources>
8+
</configuration>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFrameworks>net8.0</TargetFrameworks>
6+
</PropertyGroup>
7+
8+
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
9+
<RemoveDir Directories=".\bin" />
10+
<RemoveDir Directories=".\obj" />
11+
</Target>
12+
13+
<ItemGroup>
14+
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
15+
</ItemGroup>
16+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.5.002.0
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "proj", "proj\proj.csproj", "{6ED00460-7666-4AE9-A405-4B6C8B02279A}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(SolutionProperties) = preSolution
14+
HideSolutionNode = FALSE
15+
EndGlobalSection
16+
GlobalSection(ExtensibilityGlobals) = postSolution
17+
SolutionGuid = {4ED55A1C-066C-43DF-B32E-7EAA035985EE}
18+
EndGlobalSection
19+
EndGlobal
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from create_database_utils import *
2+
from diagnostics_test_utils import *
3+
import os
4+
5+
os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK"] = "true" # Enable NuGet feed check
6+
os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_TIMEOUT"] = "1" # 1ms, the GET request should fail with such short timeout
7+
os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_LIMIT"] = "1" # Limit the count of checks to 1
8+
os.environ["CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_CHECK_EXCLUDED"] = "https://abc.de:8000/packages/" # Exclude this feed from check
9+
run_codeql_database_create([], lang="csharp", extra_args=["--build-mode=none"])
10+
check_diagnostics()

0 commit comments

Comments
 (0)