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)
|
||||
{
|
||||
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 runtimeAssets = new List<string>();
|
||||
var sourceReferences = new List<string>();
|
||||
|
@ -174,7 +186,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
compileAssemblies.Add(compileAsset);
|
||||
runtimeAssets.Add(pdbPath);
|
||||
}
|
||||
else if(project.Project.Files.SourceFiles.Any())
|
||||
else if (project.Project.Files.SourceFiles.Any())
|
||||
{
|
||||
var outputCalculator = project.GetOutputPathCalculator();
|
||||
var assemblyPath = outputCalculator.GetAssemblyPath(_configuration);
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value;
|
||||
return Value ?? nameof(Unspecified);
|
||||
}
|
||||
|
||||
public bool CanSatisfyConstraint(LibraryType constraint)
|
||||
|
|
|
@ -267,6 +267,7 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
ReferenceAssemblyDependencyResolver referenceAssemblyDependencyResolver,
|
||||
out bool requiresFrameworkAssemblies)
|
||||
{
|
||||
// Remark: the LibraryType in the key of the given dictionary are all "Unspecified" at the beginning.
|
||||
requiresFrameworkAssemblies = false;
|
||||
|
||||
foreach (var pair in libraries.ToList())
|
||||
|
@ -294,41 +295,50 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
// Remove the original package reference
|
||||
libraries.Remove(pair.Key);
|
||||
|
||||
// Add the reference to the refernce assembly.
|
||||
libraries[new LibraryKey(replacement.Identity.Name)] = replacement;
|
||||
|
||||
continue;
|
||||
// Insert a reference assembly key if there isn't one
|
||||
var key = new LibraryKey(replacement.Identity.Name, LibraryType.ReferenceAssembly);
|
||||
if (!libraries.ContainsKey(key))
|
||||
{
|
||||
libraries[key] = replacement;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var pair in libraries.ToList())
|
||||
{
|
||||
var library = pair.Value;
|
||||
library.Framework = library.Framework ?? TargetFramework;
|
||||
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);
|
||||
|
||||
LibraryDescription dep;
|
||||
if (!libraries.TryGetValue(key, out dep))
|
||||
LibraryDescription dependencyDescription;
|
||||
if (!libraries.TryGetValue(key, out dependencyDescription))
|
||||
{
|
||||
if (Equals(LibraryType.ReferenceAssembly, dependency.Target))
|
||||
if (keyType == LibraryType.ReferenceAssembly)
|
||||
{
|
||||
requiresFrameworkAssemblies = true;
|
||||
|
||||
dep = referenceAssemblyDependencyResolver.GetDescription(dependency, TargetFramework) ??
|
||||
UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
||||
|
||||
dep.Framework = TargetFramework;
|
||||
libraries[key] = dep;
|
||||
// a dependency is specified to be reference assembly but fail to match
|
||||
// then add a unresolved dependency
|
||||
dependencyDescription = referenceAssemblyDependencyResolver.GetDescription(dependency, TargetFramework) ??
|
||||
UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
||||
libraries[key] = dependencyDescription;
|
||||
}
|
||||
else
|
||||
else if (!libraries.TryGetValue(new LibraryKey(dependency.Name, LibraryType.ReferenceAssembly), out dependencyDescription))
|
||||
{
|
||||
dep = UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
||||
libraries[key] = dep;
|
||||
// a dependency which type is unspecified fails to match, then try to find a
|
||||
// reference assembly type dependency
|
||||
dependencyDescription = UnresolvedDependencyProvider.GetDescription(dependency, TargetFramework);
|
||||
libraries[key] = dependencyDescription;
|
||||
}
|
||||
}
|
||||
|
||||
dep.RequestedRanges.Add(dependency);
|
||||
dep.Parents.Add(library);
|
||||
dependencyDescription.RequestedRanges.Add(dependency);
|
||||
dependencyDescription.Parents.Add(library);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
|
|||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.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;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
|||
|
||||
var allExports = context.CreateExporter(configuration)
|
||||
.GetAllExports()
|
||||
.ToDictionary(export => export.Library.GetUniqueName());
|
||||
.ToDictionary(export => export.Library.Identity.Name);
|
||||
|
||||
var allSourceFiles = new List<string>(context.ProjectFile.Files.SourceFiles);
|
||||
var allFileReferences = new List<string>();
|
||||
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
|
||||
// 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);
|
||||
allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath));
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||
using Microsoft.DotNet.ProjectModel.Graph;
|
||||
using Microsoft.DotNet.ProjectModel.Server.Helpers;
|
||||
|
||||
namespace Microsoft.DotNet.ProjectModel.Server.Models
|
||||
|
@ -54,27 +55,32 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models
|
|||
|
||||
public static DependencyDescription Create(LibraryDescription library,
|
||||
List<DiagnosticMessage> diagnostics,
|
||||
Dictionary<string, LibraryExport> allExports)
|
||||
IDictionary<string, LibraryExport> exportsLookup)
|
||||
{
|
||||
var name = library.GetUniqueName();
|
||||
return new DependencyDescription
|
||||
{
|
||||
Name = name,
|
||||
Name = library.Identity.Name,
|
||||
DisplayName = library.Identity.Name,
|
||||
Version = library.Identity.Version?.ToNormalizedString(),
|
||||
Type = library.Identity.Type.Value,
|
||||
Resolved = library.Resolved,
|
||||
Path = library.Path,
|
||||
Dependencies = library.Dependencies.Select(dependency => new DependencyItem
|
||||
{
|
||||
Name = dependency.GetUniqueName(),
|
||||
Version = allExports[dependency.GetUniqueName()].Library.Identity.Version?.ToNormalizedString()
|
||||
}),
|
||||
Dependencies = library.Dependencies.Select(dependency => GetDependencyItem(dependency, exportsLookup)),
|
||||
Errors = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Error)
|
||||
.Select(d => new DiagnosticMessageView(d)),
|
||||
Warnings = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Warning)
|
||||
.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)
|
||||
{
|
||||
// swallow
|
||||
_log.LogWarning($"Ignore {nameof(IOException)} during sending message: \"{ex.Message}\".");
|
||||
_log.LogInformation($"Ignore {nameof(IOException)} during sending message: \"{ex.Message}\".");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
|||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
_log.LogWarning($"Ignore {nameof(IOException)} during receiving messages: \"{ex}\".");
|
||||
_log.LogInformation($"Ignore {nameof(IOException)} during receiving messages: \"{ex}\".");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -87,4 +87,4 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ using System.Net;
|
|||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
|
@ -29,18 +30,19 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
|||
// works in visual studio
|
||||
private readonly Dictionary<string, int> _projectContexts = new Dictionary<string, int>();
|
||||
private int _nextContextId;
|
||||
private readonly Socket _socket;
|
||||
|
||||
public DthTestClient(DthTestServer server)
|
||||
{
|
||||
var socket = new Socket(AddressFamily.InterNetwork,
|
||||
SocketType.Stream,
|
||||
ProtocolType.Tcp);
|
||||
_socket = new Socket(AddressFamily.InterNetwork,
|
||||
SocketType.Stream,
|
||||
ProtocolType.Tcp);
|
||||
|
||||
socket.Connect(new IPEndPoint(IPAddress.Loopback, server.Port));
|
||||
_socket.Connect(new IPEndPoint(IPAddress.Loopback, server.Port));
|
||||
|
||||
_hostId = server.HostId;
|
||||
|
||||
_networkStream = new NetworkStream(socket);
|
||||
_networkStream = new NetworkStream(_socket);
|
||||
_reader = new BinaryReader(_networkStream);
|
||||
_writer = new BinaryWriter(_networkStream);
|
||||
|
||||
|
@ -221,6 +223,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
|||
_writer.Dispose();
|
||||
_networkStream.Dispose();
|
||||
_readCancellationToken.Cancel();
|
||||
_socket.Shutdown(SocketShutdown.Both);
|
||||
}
|
||||
|
||||
private void ReadMessage(CancellationToken cancellationToken)
|
||||
|
|
|
@ -5,13 +5,14 @@ using System;
|
|||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using Microsoft.DotNet.ProjectModel.Server;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
||||
{
|
||||
public class DthTestServer : IDisposable
|
||||
{
|
||||
private readonly Program _program;
|
||||
private readonly ProjectModelServerCommand _program;
|
||||
private readonly Thread _thread;
|
||||
|
||||
public DthTestServer(ILoggerFactory loggerFactory)
|
||||
|
@ -21,9 +22,9 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
|||
Port = FindFreePort();
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
|
|||
[Theory]
|
||||
[InlineData("Project", "UnresolvedProjectSample", "EmptyLibrary", "Project")]
|
||||
[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,
|
||||
string testProjectName,
|
||||
string expectedUnresolvedDependency,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"NETStandard.Library": "1.0.0-rc2-23728",
|
||||
"EmptyLibrary": ""
|
||||
},
|
||||
"frameworks": {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Newtonsoft.Json": "4.5.11"
|
||||
"NETStandard.Library": "1.0.0-rc2-23728",
|
||||
"Microsoft.Web.Administration": "7.0.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"dnxcore50": {
|
||||
|
|
Loading…
Reference in a new issue