Fix projectmodel-server regression
1. Address the null reference exception when a project dependency is broken. 2. Address the duplicate key issues after the logic of redirecting System pacage to reference assembly was added Update projectmodel-server and tests 1. Fix test timeout caused by undisconnected socket; 2. Update project model server
This commit is contained in:
parent
c4b3925e46
commit
b9f2d8fe3d
12 changed files with 81 additions and 48 deletions
|
@ -156,6 +156,18 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
||||||
|
|
||||||
private LibraryExport ExportProject(ProjectDescription project)
|
private LibraryExport ExportProject(ProjectDescription project)
|
||||||
{
|
{
|
||||||
|
if (!project.Resolved)
|
||||||
|
{
|
||||||
|
// For a unresolved project reference returns a export with empty asset.
|
||||||
|
return new LibraryExport(library: project,
|
||||||
|
compileAssemblies: Enumerable.Empty<LibraryAsset>(),
|
||||||
|
sourceReferences: Enumerable.Empty<string>(),
|
||||||
|
nativeLibraries: Enumerable.Empty<LibraryAsset>(),
|
||||||
|
runtimeAssets: Enumerable.Empty<string>(),
|
||||||
|
runtimeAssemblies: Array.Empty<LibraryAsset>(),
|
||||||
|
analyzers: Array.Empty<AnalyzerReference>());
|
||||||
|
}
|
||||||
|
|
||||||
var compileAssemblies = new List<LibraryAsset>();
|
var compileAssemblies = new List<LibraryAsset>();
|
||||||
var runtimeAssets = new List<string>();
|
var runtimeAssets = new List<string>();
|
||||||
var sourceReferences = new List<string>();
|
var sourceReferences = new List<string>();
|
||||||
|
@ -174,7 +186,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
||||||
compileAssemblies.Add(compileAsset);
|
compileAssemblies.Add(compileAsset);
|
||||||
runtimeAssets.Add(pdbPath);
|
runtimeAssets.Add(pdbPath);
|
||||||
}
|
}
|
||||||
else if(project.Project.Files.SourceFiles.Any())
|
else if (project.Project.Files.SourceFiles.Any())
|
||||||
{
|
{
|
||||||
var outputCalculator = project.GetOutputPathCalculator();
|
var outputCalculator = project.GetOutputPathCalculator();
|
||||||
var assemblyPath = outputCalculator.GetAssemblyPath(_configuration);
|
var assemblyPath = outputCalculator.GetAssemblyPath(_configuration);
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return Value;
|
return Value ?? nameof(Unspecified);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanSatisfyConstraint(LibraryType constraint)
|
public bool CanSatisfyConstraint(LibraryType constraint)
|
||||||
|
|
|
@ -267,6 +267,7 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
ReferenceAssemblyDependencyResolver referenceAssemblyDependencyResolver,
|
ReferenceAssemblyDependencyResolver referenceAssemblyDependencyResolver,
|
||||||
out bool requiresFrameworkAssemblies)
|
out bool requiresFrameworkAssemblies)
|
||||||
{
|
{
|
||||||
|
// Remark: the LibraryType in the key of the given dictionary are all "Unspecified" at the beginning.
|
||||||
requiresFrameworkAssemblies = false;
|
requiresFrameworkAssemblies = false;
|
||||||
|
|
||||||
foreach (var pair in libraries.ToList())
|
foreach (var pair in libraries.ToList())
|
||||||
|
@ -294,41 +295,50 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
// Remove the original package reference
|
// Remove the original package reference
|
||||||
libraries.Remove(pair.Key);
|
libraries.Remove(pair.Key);
|
||||||
|
|
||||||
// Add the reference to the refernce assembly.
|
// Insert a reference assembly key if there isn't one
|
||||||
libraries[new LibraryKey(replacement.Identity.Name)] = replacement;
|
var key = new LibraryKey(replacement.Identity.Name, LibraryType.ReferenceAssembly);
|
||||||
|
if (!libraries.ContainsKey(key))
|
||||||
continue;
|
{
|
||||||
|
libraries[key] = replacement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var pair in libraries.ToList())
|
||||||
|
{
|
||||||
|
var library = pair.Value;
|
||||||
library.Framework = library.Framework ?? TargetFramework;
|
library.Framework = library.Framework ?? TargetFramework;
|
||||||
foreach (var dependency in library.Dependencies)
|
foreach (var dependency in library.Dependencies)
|
||||||
{
|
{
|
||||||
var keyType = dependency.Target == LibraryType.ReferenceAssembly ? LibraryType.ReferenceAssembly : LibraryType.Unspecified;
|
var keyType = dependency.Target == LibraryType.ReferenceAssembly ?
|
||||||
|
LibraryType.ReferenceAssembly :
|
||||||
|
LibraryType.Unspecified;
|
||||||
|
|
||||||
var key = new LibraryKey(dependency.Name, keyType);
|
var key = new LibraryKey(dependency.Name, keyType);
|
||||||
|
|
||||||
LibraryDescription dep;
|
LibraryDescription dependencyDescription;
|
||||||
if (!libraries.TryGetValue(key, out dep))
|
if (!libraries.TryGetValue(key, out dependencyDescription))
|
||||||
{
|
{
|
||||||
if (Equals(LibraryType.ReferenceAssembly, dependency.Target))
|
if (keyType == LibraryType.ReferenceAssembly)
|
||||||
{
|
{
|
||||||
requiresFrameworkAssemblies = true;
|
// a dependency is specified to be reference assembly but fail to match
|
||||||
|
// then add a unresolved dependency
|
||||||
dep = referenceAssemblyDependencyResolver.GetDescription(dependency, TargetFramework) ??
|
dependencyDescription = referenceAssemblyDependencyResolver.GetDescription(dependency, TargetFramework) ??
|
||||||
UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
||||||
|
libraries[key] = dependencyDescription;
|
||||||
dep.Framework = TargetFramework;
|
|
||||||
libraries[key] = dep;
|
|
||||||
}
|
}
|
||||||
else
|
else if (!libraries.TryGetValue(new LibraryKey(dependency.Name, LibraryType.ReferenceAssembly), out dependencyDescription))
|
||||||
{
|
{
|
||||||
dep = UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
// a dependency which type is unspecified fails to match, then try to find a
|
||||||
libraries[key] = dep;
|
// reference assembly type dependency
|
||||||
|
dependencyDescription = UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
||||||
|
libraries[key] = dependencyDescription;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dep.RequestedRanges.Add(dependency);
|
dependencyDescription.RequestedRanges.Add(dependency);
|
||||||
dep.Parents.Add(library);
|
dependencyDescription.Parents.Add(library);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
|
||||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
{
|
{
|
||||||
// There is no reference assemblies path outside of windows
|
// There is no reference assemblies path outside of windows
|
||||||
// The enviorment variable can be used to specify one
|
// The environment variable can be used to specify one
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
||||||
|
|
||||||
var allExports = context.CreateExporter(configuration)
|
var allExports = context.CreateExporter(configuration)
|
||||||
.GetAllExports()
|
.GetAllExports()
|
||||||
.ToDictionary(export => export.Library.GetUniqueName());
|
.ToDictionary(export => export.Library.Identity.Name);
|
||||||
|
|
||||||
var allSourceFiles = new List<string>(context.ProjectFile.Files.SourceFiles);
|
var allSourceFiles = new List<string>(context.ProjectFile.Files.SourceFiles);
|
||||||
var allFileReferences = new List<string>();
|
var allFileReferences = new List<string>();
|
||||||
var allProjectReferences = new List<ProjectReferenceDescription>();
|
var allProjectReferences = new List<ProjectReferenceDescription>();
|
||||||
|
@ -42,10 +43,8 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
||||||
|
|
||||||
// All exports are returned. When the same library name have a ReferenceAssembly type export and a Package type export
|
// All exports are returned. When the same library name have a ReferenceAssembly type export and a Package type export
|
||||||
// both will be listed as dependencies. Prefix "fx/" will be added to ReferenceAssembly type dependency.
|
// both will be listed as dependencies. Prefix "fx/" will be added to ReferenceAssembly type dependency.
|
||||||
foreach (var pair in allExports)
|
foreach (var export in allExports.Values)
|
||||||
{
|
{
|
||||||
var export = pair.Value;
|
|
||||||
|
|
||||||
allSourceFiles.AddRange(export.SourceReferences);
|
allSourceFiles.AddRange(export.SourceReferences);
|
||||||
allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath));
|
allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath));
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Graph;
|
||||||
using Microsoft.DotNet.ProjectModel.Server.Helpers;
|
using Microsoft.DotNet.ProjectModel.Server.Helpers;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.ProjectModel.Server.Models
|
namespace Microsoft.DotNet.ProjectModel.Server.Models
|
||||||
|
@ -54,27 +55,32 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models
|
||||||
|
|
||||||
public static DependencyDescription Create(LibraryDescription library,
|
public static DependencyDescription Create(LibraryDescription library,
|
||||||
List<DiagnosticMessage> diagnostics,
|
List<DiagnosticMessage> diagnostics,
|
||||||
Dictionary<string, LibraryExport> allExports)
|
IDictionary<string, LibraryExport> exportsLookup)
|
||||||
{
|
{
|
||||||
var name = library.GetUniqueName();
|
|
||||||
return new DependencyDescription
|
return new DependencyDescription
|
||||||
{
|
{
|
||||||
Name = name,
|
Name = library.Identity.Name,
|
||||||
DisplayName = library.Identity.Name,
|
DisplayName = library.Identity.Name,
|
||||||
Version = library.Identity.Version?.ToNormalizedString(),
|
Version = library.Identity.Version?.ToNormalizedString(),
|
||||||
Type = library.Identity.Type.Value,
|
Type = library.Identity.Type.Value,
|
||||||
Resolved = library.Resolved,
|
Resolved = library.Resolved,
|
||||||
Path = library.Path,
|
Path = library.Path,
|
||||||
Dependencies = library.Dependencies.Select(dependency => new DependencyItem
|
Dependencies = library.Dependencies.Select(dependency => GetDependencyItem(dependency, exportsLookup)),
|
||||||
{
|
|
||||||
Name = dependency.GetUniqueName(),
|
|
||||||
Version = allExports[dependency.GetUniqueName()].Library.Identity.Version?.ToNormalizedString()
|
|
||||||
}),
|
|
||||||
Errors = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Error)
|
Errors = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Error)
|
||||||
.Select(d => new DiagnosticMessageView(d)),
|
.Select(d => new DiagnosticMessageView(d)),
|
||||||
Warnings = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Warning)
|
Warnings = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Warning)
|
||||||
.Select(d => new DiagnosticMessageView(d))
|
.Select(d => new DiagnosticMessageView(d))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DependencyItem GetDependencyItem(LibraryRange dependency,
|
||||||
|
IDictionary<string, LibraryExport> exportsLookup)
|
||||||
|
{
|
||||||
|
return new DependencyItem
|
||||||
|
{
|
||||||
|
Name = dependency.Name,
|
||||||
|
Version = exportsLookup[dependency.Name].Library.Identity.Version?.ToNormalizedString()
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
// swallow
|
// swallow
|
||||||
_log.LogWarning($"Ignore {nameof(IOException)} during sending message: \"{ex.Message}\".");
|
_log.LogInformation($"Ignore {nameof(IOException)} during sending message: \"{ex.Message}\".");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +79,7 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
_log.LogWarning($"Ignore {nameof(IOException)} during receiving messages: \"{ex}\".");
|
_log.LogInformation($"Ignore {nameof(IOException)} during receiving messages: \"{ex}\".");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@ using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
@ -29,18 +30,19 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
||||||
// works in visual studio
|
// works in visual studio
|
||||||
private readonly Dictionary<string, int> _projectContexts = new Dictionary<string, int>();
|
private readonly Dictionary<string, int> _projectContexts = new Dictionary<string, int>();
|
||||||
private int _nextContextId;
|
private int _nextContextId;
|
||||||
|
private readonly Socket _socket;
|
||||||
|
|
||||||
public DthTestClient(DthTestServer server)
|
public DthTestClient(DthTestServer server)
|
||||||
{
|
{
|
||||||
var socket = new Socket(AddressFamily.InterNetwork,
|
_socket = new Socket(AddressFamily.InterNetwork,
|
||||||
SocketType.Stream,
|
SocketType.Stream,
|
||||||
ProtocolType.Tcp);
|
ProtocolType.Tcp);
|
||||||
|
|
||||||
socket.Connect(new IPEndPoint(IPAddress.Loopback, server.Port));
|
_socket.Connect(new IPEndPoint(IPAddress.Loopback, server.Port));
|
||||||
|
|
||||||
_hostId = server.HostId;
|
_hostId = server.HostId;
|
||||||
|
|
||||||
_networkStream = new NetworkStream(socket);
|
_networkStream = new NetworkStream(_socket);
|
||||||
_reader = new BinaryReader(_networkStream);
|
_reader = new BinaryReader(_networkStream);
|
||||||
_writer = new BinaryWriter(_networkStream);
|
_writer = new BinaryWriter(_networkStream);
|
||||||
|
|
||||||
|
@ -221,6 +223,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
||||||
_writer.Dispose();
|
_writer.Dispose();
|
||||||
_networkStream.Dispose();
|
_networkStream.Dispose();
|
||||||
_readCancellationToken.Cancel();
|
_readCancellationToken.Cancel();
|
||||||
|
_socket.Shutdown(SocketShutdown.Both);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadMessage(CancellationToken cancellationToken)
|
private void ReadMessage(CancellationToken cancellationToken)
|
||||||
|
|
|
@ -5,13 +5,14 @@ using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Server;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
||||||
{
|
{
|
||||||
public class DthTestServer : IDisposable
|
public class DthTestServer : IDisposable
|
||||||
{
|
{
|
||||||
private readonly Program _program;
|
private readonly ProjectModelServerCommand _program;
|
||||||
private readonly Thread _thread;
|
private readonly Thread _thread;
|
||||||
|
|
||||||
public DthTestServer(ILoggerFactory loggerFactory)
|
public DthTestServer(ILoggerFactory loggerFactory)
|
||||||
|
@ -21,9 +22,9 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
||||||
Port = FindFreePort();
|
Port = FindFreePort();
|
||||||
HostId = Guid.NewGuid().ToString();
|
HostId = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
_program = new Program(Port, HostId, LoggerFactory);
|
_program = new ProjectModelServerCommand(Port, HostId, LoggerFactory);
|
||||||
|
|
||||||
_thread = new Thread(() => { _program.OpenChannel(); });
|
_thread = new Thread(() => { _program.OpenChannel(); }) { IsBackground = true };
|
||||||
_thread.Start();
|
_thread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("Project", "UnresolvedProjectSample", "EmptyLibrary", "Project")]
|
[InlineData("Project", "UnresolvedProjectSample", "EmptyLibrary", "Project")]
|
||||||
[InlineData("Package", "UnresolvedPackageSample", "NoSuchPackage", null)]
|
[InlineData("Package", "UnresolvedPackageSample", "NoSuchPackage", null)]
|
||||||
[InlineData("Package", "IncompatiblePackageSample", "Newtonsoft.Json", "Package")]
|
[InlineData("Package", "IncompatiblePackageSample", "Microsoft.Web.Administration", "Package")]
|
||||||
public void DthCompilation_Initialize_UnresolvedDependency(string referenceType,
|
public void DthCompilation_Initialize_UnresolvedDependency(string referenceType,
|
||||||
string testProjectName,
|
string testProjectName,
|
||||||
string expectedUnresolvedDependency,
|
string expectedUnresolvedDependency,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"NETStandard.Library": "1.0.0-rc2-23728",
|
||||||
"EmptyLibrary": ""
|
"EmptyLibrary": ""
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Newtonsoft.Json": "4.5.11"
|
"NETStandard.Library": "1.0.0-rc2-23728",
|
||||||
|
"Microsoft.Web.Administration": "7.0.0"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
"dnxcore50": {
|
"dnxcore50": {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue