Skip to content

Commit

Permalink
Refactors the Multi Version Scanner (#526)
Browse files Browse the repository at this point in the history
* fix naming.

* Supports target-framework configuration in config.yml.
Add logic to report instrumentation mismatch.
Refactoring.

* rework on the assembly process logic so that the AssemblyAnalyzer only process one assembly at a time.

* Removes the need of specifying target framework for each instrumentation set in the config.yml. The MVS will validate all target frameworks that the instrumented nuget package supports.
  • Loading branch information
vuqtran88 authored Apr 12, 2021
1 parent 2ba99ea commit dc85233
Show file tree
Hide file tree
Showing 12 changed files with 218 additions and 220 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2020 New Relic, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0


using System.Collections.Generic;

namespace NewRelic.Agent.ConsoleScanner
{
public class DownloadedNugetInfo
{
public DownloadedNugetInfo(List<string> dllFileLocations, string version, string packageName)
{
InstrumentedDllFileLocations = dllFileLocations;
PackageVersion = version;
PackageName = packageName;
}

public List<string> InstrumentedDllFileLocations { get; }
public string PackageVersion { get; }
public string PackageName { get; }

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class InstrumentationSet

public string XmlFile { get; set; }

public List<NugetSet> NugetAssemblies { get; set; }
public List<NugetSet> NugetPackages { get; set; }

public List<string> LocalAssemblies { get; set; }
}
Expand Down
2 changes: 1 addition & 1 deletion tests/Agent/MultiverseTesting/ConsoleScanner/NugetSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace NewRelic.Agent.ConsoleScanner
{
public class NugetSet
{
public string AssemblyName { get; set; }
public string PackageName { get; set; }
public string[] Versions { get; set; }
}
}
110 changes: 54 additions & 56 deletions tests/Agent/MultiverseTesting/ConsoleScanner/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,42 +49,34 @@ public static void ProcessAssemblies(ScannerConfiguration configuration)
{
foreach (var instrumentationSet in configuration.InstrumentationSets)
{
// TODO: deal with duplicate assembly names

// load the instrumentation.xml and create InstrumentationModel
var instrumentationModel = ReadInstrumentationFile(instrumentationSet);

List<string> dllFileLocations = new List<string>();

// nuget assemblies
var nugetDllFileLocations = GetNugetAssemblies(instrumentationSet, instrumentationModel.UniqueAssemblies);
if (nugetDllFileLocations != null)
{
dllFileLocations.AddRange(nugetDllFileLocations);
}
var downloadedNugetInfoList = GetNugetAssemblies(instrumentationSet, instrumentationModel.UniqueAssemblies);

// local assemblies
var localDllFileLocations = GetLocalAssemblies(instrumentationSet);
if (localDllFileLocations != null)
foreach(var downloadedNugetInfo in downloadedNugetInfoList)
{
dllFileLocations.AddRange(localDllFileLocations);
}
var dllFileNames = dllFileLocations.ToArray();
foreach (var intrumentedDllFileLocation in downloadedNugetInfo.InstrumentedDllFileLocations)
{
// Builds a model from the files
Console.WriteLine($"Starting scan of '{intrumentedDllFileLocation}'");
var assemblyAnalyzer = new AssemblyAnalyzer();
var assemblyAnalysis = assemblyAnalyzer.RunAssemblyAnalysis(intrumentedDllFileLocation);

// Builds a model from the files
Console.WriteLine($"Starting scan of '{string.Join(',', dllFileNames)}'");
var assemblyAnalyzer = new AssemblyAnalyzer();
var assemblyAnalysis = assemblyAnalyzer.RunAssemblyAnalysis(dllFileNames);
var instrumentationValidator = new InstrumentationValidator(assemblyAnalysis);

var instrumentationValidator = new InstrumentationValidator(assemblyAnalysis);
// just some debugging writes
Console.WriteLine($"Found {assemblyAnalysis.ClassesCount} classes");
Console.WriteLine("Scan complete");

// just some debugging writes
Console.WriteLine($"Found {assemblyAnalysis.ClassesCount} classes");
Console.WriteLine("Scan complete");
var targetFramework = Path.GetFileName(Path.GetDirectoryName(intrumentedDllFileLocation));

// run the validation
var report = instrumentationValidator.CheckInstrumentation(instrumentationModel, instrumentationSet.Name);
_instrumentationReports.Add(report);
// run the validation
var report = instrumentationValidator.CheckInstrumentation(instrumentationModel, instrumentationSet.Name, targetFramework, downloadedNugetInfo.PackageVersion, downloadedNugetInfo.PackageName);
_instrumentationReports.Add(report);
}
}
}
}

Expand All @@ -101,11 +93,12 @@ public static InstrumentationModel ReadInstrumentationFile(InstrumentationSet in
return instrumentationModel;
}

// TODO: not the best name, considering all it does
public static List<string> GetNugetPackages(string name, string[] versions, List<string> instrumentationAssemblies)
public static List<DownloadedNugetInfo> GetNugetPackages(string packageName, string[] versions, List<string> instrumentationAssemblies)
{
var addressPrefix = $"{_nugetSource}/{name.ToLower()}";
List<string> dllFileLocations = new List<string>();
var addressPrefix = $"{_nugetSource}/{packageName.ToLower()}";

var downloadedNugetInfos = new List<DownloadedNugetInfo>();

try
{
var webClient = new WebClient();
Expand All @@ -115,13 +108,15 @@ public static List<string> GetNugetPackages(string name, string[] versions, List

foreach (var version in versions)
{
var dllFileLocations = new List<string>();

// set up
var nugetDownloadedPackagePrefix = $"{name.ToLower()}.{version.ToLower()}";
var nugetDownloadedPackagePrefix = $"{packageName.ToLower()}.{version.ToLower()}";
var nugetExtractDirectoryName = $"{_nugetDataDirectory}\\{nugetDownloadedPackagePrefix}";
var nugetDownloadedPackageFileName = $"{_nugetDataDirectory}\\{nugetDownloadedPackagePrefix}.zip";

// example address: https://api.nuget.org/v3-flatcontainer/mongodb.driver.core/2.6.0/mongodb.driver.core.2.6.0.nupkg
var address = $"{addressPrefix}/{version.ToLower()}/{name.ToLower()}.{version.ToLower()}.nupkg";
var address = $"{addressPrefix}/{version.ToLower()}/{packageName.ToLower()}.{version.ToLower()}.nupkg";

// skip downloading on re-run
if (!File.Exists(nugetDownloadedPackageFileName))
Expand All @@ -130,23 +125,25 @@ public static List<string> GetNugetPackages(string name, string[] versions, List
var result = webClient.DownloadData(address);
File.WriteAllBytes(nugetDownloadedPackageFileName, result);

Console.WriteLine($"Downloaded package {name} {version}");
Console.WriteLine($"Downloaded package {packageName} {version}");
}

// extract dlls from package

// extract dlls from package

if (Directory.Exists(nugetExtractDirectoryName))
{
Directory.Delete(nugetExtractDirectoryName, true);
}
Directory.CreateDirectory(nugetExtractDirectoryName);
ZipFile.ExtractToDirectory(nugetDownloadedPackageFileName, nugetExtractDirectoryName);
if (Directory.Exists(nugetExtractDirectoryName))
{
Directory.Delete(nugetExtractDirectoryName, true);
}
Directory.CreateDirectory(nugetExtractDirectoryName);
ZipFile.ExtractToDirectory(nugetDownloadedPackageFileName, nugetExtractDirectoryName);

// TODO: this will get every version (net45, netstandard1.5) of the dll in the package, which may not be necessary;
foreach (var instrumentationAssembly in instrumentationAssemblies)
{
dllFileLocations.AddRange(Directory.GetFiles(nugetExtractDirectoryName, instrumentationAssembly + ".dll", SearchOption.AllDirectories));
}

downloadedNugetInfos.Add(new DownloadedNugetInfo(dllFileLocations, version, packageName));
}
}
catch (Exception ex)
Expand All @@ -155,44 +152,45 @@ public static List<string> GetNugetPackages(string name, string[] versions, List
Console.WriteLine($"GetNugetPackages exception : {ex}");
}

return dllFileLocations;
return downloadedNugetInfos;
}

public static List<string> GetNugetAssemblies(InstrumentationSet instrumentationSet, List<string> instrumentationAssemblies)
public static List<DownloadedNugetInfo> GetNugetAssemblies(InstrumentationSet instrumentationSet, List<string> instrumentationAssemblies)
{
List<string> fileList = new List<string>();
if (instrumentationSet.NugetAssemblies != null)
var downloadedNugetInfoList = new List<DownloadedNugetInfo>();
if (instrumentationSet.NugetPackages != null)
{
foreach (var nugetAssembly in instrumentationSet.NugetAssemblies)
foreach (var nugetPackage in instrumentationSet.NugetPackages)
{
fileList.AddRange(GetNugetPackages(nugetAssembly.AssemblyName, nugetAssembly.Versions, instrumentationAssemblies));
downloadedNugetInfoList.AddRange(GetNugetPackages(nugetPackage.PackageName, nugetPackage.Versions, instrumentationAssemblies));
}
}
return fileList;
}

public static List<string> GetLocalAssemblies(InstrumentationSet instrumentationSet)
{
return instrumentationSet.LocalAssemblies;
return downloadedNugetInfoList;
}

public static void PrintReport()
{
Console.WriteLine("============ REPORT ============");
foreach(var report in _instrumentationReports)
{
Console.WriteLine($"Instrumentation Set: {report.InstrumentationSetName}");
foreach(var assemblyReport in report.AssemblyReports)
Console.WriteLine($"Instrumentation set: {report.InstrumentationSetName}");
Console.WriteLine($"Nuget package: {report.PackageName} ver {report.PackageVersion}");
Console.WriteLine($"Target framework: {report.TargetFramework}");
Console.WriteLine($"");

foreach (var assemblyReport in report.AssemblyReports)
{
Console.Write("\t");
Console.WriteLine($"Assembly Name: {assemblyReport.AssemblyName}; Assembly Version: {assemblyReport.AssemblyVersion}");
Console.WriteLine($"Assembly Name: {assemblyReport.AssemblyName}");

var methodValidations = assemblyReport.GetMethodValidationsForPrint();
foreach (var line in methodValidations)
{
Console.WriteLine($"\t{line}");
}
}

Console.WriteLine($"");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"ConsoleScanner": {
"commandName": "Project",
"commandLineArgs": "\".\\config.yml\"",
"environmentVariables": {
"myvar": "sometvaluething"
}
"environmentVariables": {
"MVS_XML_PATH": "PATH_TO_THE_AGENT_WRAPPER_FOLDER"
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,11 @@ public void ProcessInstrumentationSet(InstrumentationSet instrumentationSet)
instrumentationSet.Name = GetSubstitutedValue(instrumentationSet.Name);
instrumentationSet.XmlFile = GetSubstitutedValue(instrumentationSet.XmlFile);

if (instrumentationSet.NugetAssemblies != null)
if (instrumentationSet.NugetPackages != null)
{
foreach (var nugetSet in instrumentationSet.NugetAssemblies)
foreach (var nugetSet in instrumentationSet.NugetPackages)
{
nugetSet.AssemblyName = GetSubstitutedValue(nugetSet.AssemblyName);
// not processing versions at this time since its not likely to be replace with an env var
nugetSet.PackageName = GetSubstitutedValue(nugetSet.PackageName);
}
}

Expand Down
Loading

0 comments on commit dc85233

Please sign in to comment.