зеркало из https://github.com/microsoft/vstest.git
First Draft for the Protocol tool. (#306)
* First Draft for the Protocol tool. Emits the json sent and recieved for Discovery, RunAll, RunSelected scenarios. * Fixing the Testplatform.sln build. * Changes as per discussion with Arun. - Removed the runnerlocation, adapter and testhost configs.
This commit is contained in:
Родитель
34a8665be2
Коммит
230c966318
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26005.1
|
||||
VisualStudioVersion = 15.0.26014.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED0C35EB-7F31-4841-A24F-8EB708FFA959}"
|
||||
EndProject
|
||||
|
@ -118,6 +118,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PerfTestProject", "test\Tes
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleDataCollector", "test\TestAssets\SimpleDataCollector\SimpleDataCollector.csproj", "{D62D754C-8F0A-406F-8BA7-E96C6FFA7C7C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TestPlatform.Protocol", "samples\Microsoft.TestPlatform.Protocol\Microsoft.TestPlatform.Protocol.csproj", "{97DD9467-B011-4736-AAC4-2C21BF554349}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleTestProject3", "test\TestAssets\SimpleTestProject3\SimpleTestProject3.csproj", "{82E75225-FA92-4F87-909D-039D62F96BFF}"
|
||||
EndProject
|
||||
Global
|
||||
|
@ -646,6 +648,18 @@ Global
|
|||
{D62D754C-8F0A-406F-8BA7-E96C6FFA7C7C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D62D754C-8F0A-406F-8BA7-E96C6FFA7C7C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D62D754C-8F0A-406F-8BA7-E96C6FFA7C7C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Debug|x64.Build.0 = Debug|x64
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Debug|x86.Build.0 = Debug|x86
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Release|x64.ActiveCfg = Release|x64
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Release|x64.Build.0 = Release|x64
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Release|x86.ActiveCfg = Release|x86
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349}.Release|x86.Build.0 = Release|x86
|
||||
{82E75225-FA92-4F87-909D-039D62F96BFF}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{82E75225-FA92-4F87-909D-039D62F96BFF}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{82E75225-FA92-4F87-909D-039D62F96BFF}.Debug|x64.ActiveCfg = Release|Any CPU
|
||||
|
@ -712,6 +726,7 @@ Global
|
|||
{A23E3408-D569-488E-A071-E1B3625C5F09} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
|
||||
{57B182B8-9014-4C6D-B966-B464DE3127D5} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
|
||||
{D62D754C-8F0A-406F-8BA7-E96C6FFA7C7C} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
|
||||
{97DD9467-B011-4736-AAC4-2C21BF554349} = {B9AB7A3D-4F63-48D2-86C0-70F52F6509AB}
|
||||
{82E75225-FA92-4F87-909D-039D62F96BFF} = {8DA7CBD9-F17E-41B6-90C4-CFF55848A25A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.TestPlatform.Protocol
|
||||
{
|
||||
using System.IO;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// JsonDataSerializes serializes and deserializes data using Json format
|
||||
/// </summary>
|
||||
public class JsonDataSerializer
|
||||
{
|
||||
private static JsonDataSerializer instance;
|
||||
|
||||
private static JsonSerializer serializer;
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="JsonDataSerializer"/> class from being created.
|
||||
/// </summary>
|
||||
private JsonDataSerializer()
|
||||
{
|
||||
serializer = JsonSerializer.Create(
|
||||
new JsonSerializerSettings
|
||||
{
|
||||
DateFormatHandling = DateFormatHandling.IsoDateFormat,
|
||||
DateParseHandling = DateParseHandling.DateTimeOffset,
|
||||
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
|
||||
TypeNameHandling = TypeNameHandling.None
|
||||
});
|
||||
#if DEBUG
|
||||
// MemoryTraceWriter can help diagnose serialization issues. Enable it for
|
||||
// debug builds only.
|
||||
serializer.TraceWriter = new MemoryTraceWriter();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the JSON Serializer instance.
|
||||
/// </summary>
|
||||
public static JsonDataSerializer Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
return instance ?? (instance = new JsonDataSerializer());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize a <see cref="Message"/> from raw JSON text.
|
||||
/// </summary>
|
||||
/// <param name="rawMessage">JSON string.</param>
|
||||
/// <returns>A <see cref="Message"/> instance.</returns>
|
||||
public Message DeserializeMessage(string rawMessage)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<Message>(rawMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize the <see cref="Message.Payload"/> for a message.
|
||||
/// </summary>
|
||||
/// <param name="message">A <see cref="Message"/> object.</param>
|
||||
/// <typeparam name="T">Payload type.</typeparam>
|
||||
/// <returns>The deserialized payload.</returns>
|
||||
public T DeserializePayload<T>(Message message)
|
||||
{
|
||||
T retValue = default(T);
|
||||
|
||||
// TODO: Currently we use json serializer auto only for non-testmessage types
|
||||
// CHECK: Can't we just use auto for everything
|
||||
if (Microsoft.TestPlatform.Protocol.MessageType.TestMessage.Equals(message.MessageType))
|
||||
{
|
||||
retValue = message.Payload.ToObject<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
retValue = message.Payload.ToObject<T>(serializer);
|
||||
}
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize raw JSON to an object using the default serializer.
|
||||
/// </summary>
|
||||
/// <param name="json">JSON string.</param>
|
||||
/// <typeparam name="T">Target type to deserialize.</typeparam>
|
||||
/// <returns>An instance of <see cref="T"/>.</returns>
|
||||
public T Deserialize<T>(string json)
|
||||
{
|
||||
using (var stringReader = new StringReader(json))
|
||||
using (var jsonReader = new JsonTextReader(stringReader))
|
||||
{
|
||||
return serializer.Deserialize<T>(jsonReader);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize an empty message.
|
||||
/// </summary>
|
||||
/// <param name="messageType">Type of the message.</param>
|
||||
/// <returns>Serialized message.</returns>
|
||||
public string SerializeMessage(string messageType)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new Message { MessageType = messageType });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize a message with payload.
|
||||
/// </summary>
|
||||
/// <param name="messageType">Type of the message.</param>
|
||||
/// <param name="payload">Payload for the message.</param>
|
||||
/// <returns>Serialized message.</returns>
|
||||
public string SerializePayload(string messageType, object payload)
|
||||
{
|
||||
JToken serializedPayload = null;
|
||||
|
||||
// TODO: Currently we use json serializer auto only for non-testmessage types
|
||||
// CHECK: Can't we just use auto for everything
|
||||
if (MessageType.TestMessage.Equals(messageType))
|
||||
{
|
||||
serializedPayload = JToken.FromObject(payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
serializedPayload = JToken.FromObject(payload, serializer);
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(new Message { MessageType = messageType, Payload = serializedPayload });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize an object to JSON using default serialization settings.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of object to serialize.</typeparam>
|
||||
/// <param name="data">Instance of the object to serialize.</param>
|
||||
/// <returns>JSON string.</returns>
|
||||
public string Serialize<T>(T data)
|
||||
{
|
||||
using (var stringWriter = new StringWriter())
|
||||
using (var jsonWriter = new JsonTextWriter(stringWriter))
|
||||
{
|
||||
serializer.Serialize(jsonWriter, data);
|
||||
|
||||
return stringWriter.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.TestPlatform.Protocol
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
public class Message
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the message type.
|
||||
/// </summary>
|
||||
public string MessageType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the payload.
|
||||
/// </summary>
|
||||
public JToken Payload { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// To string implementation.
|
||||
/// </summary>
|
||||
/// <returns> The <see cref="string"/>. </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "(" + MessageType + ") -> " + (Payload == null ? "null" : Payload.ToString(Formatting.Indented));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.TestPlatform.Protocol
|
||||
{
|
||||
/// <summary>
|
||||
/// The message type.
|
||||
/// </summary>
|
||||
public static class MessageType
|
||||
{
|
||||
/// <summary>
|
||||
/// The session start.
|
||||
/// </summary>
|
||||
public const string SessionStart = "TestSession.Start";
|
||||
|
||||
/// <summary>
|
||||
/// The session end.
|
||||
/// </summary>
|
||||
public const string SessionEnd = "TestSession.Terminate";
|
||||
|
||||
/// <summary>
|
||||
/// The is aborted.
|
||||
/// </summary>
|
||||
public const string SessionAbort = "TestSession.Abort";
|
||||
|
||||
/// <summary>
|
||||
/// The session connected.
|
||||
/// </summary>
|
||||
public const string SessionConnected = "TestSession.Connected";
|
||||
|
||||
/// <summary>
|
||||
/// Test Message
|
||||
/// </summary>
|
||||
public const string TestMessage = "TestSession.Message";
|
||||
|
||||
/// <summary>
|
||||
/// Protocol Version
|
||||
/// </summary>
|
||||
public const string VersionCheck = "ProtocolVersion";
|
||||
|
||||
/// <summary>
|
||||
/// The session start.
|
||||
/// </summary>
|
||||
public const string DiscoveryInitialize = "TestDiscovery.Initialize";
|
||||
|
||||
/// <summary>
|
||||
/// The discovery started.
|
||||
/// </summary>
|
||||
public const string StartDiscovery = "TestDiscovery.Start";
|
||||
|
||||
/// <summary>
|
||||
/// The test cases found.
|
||||
/// </summary>
|
||||
public const string TestCasesFound = "TestDiscovery.TestFound";
|
||||
|
||||
/// <summary>
|
||||
/// The discovery complete.
|
||||
/// </summary>
|
||||
public const string DiscoveryComplete = "TestDiscovery.Completed";
|
||||
|
||||
/// <summary>
|
||||
/// The session start.
|
||||
/// </summary>
|
||||
public const string ExecutionInitialize = "TestExecution.Initialize";
|
||||
|
||||
/// <summary>
|
||||
/// Cancel the current test run
|
||||
/// </summary>
|
||||
public const string CancelTestRun = "TestExecution.Cancel";
|
||||
|
||||
/// <summary>
|
||||
/// Cancel the current test run
|
||||
/// </summary>
|
||||
public const string AbortTestRun = "TestExecution.Abort";
|
||||
|
||||
/// <summary>
|
||||
/// Start test execution.
|
||||
/// </summary>
|
||||
public const string StartTestExecutionWithSources = "TestExecution.StartWithSources";
|
||||
|
||||
/// <summary>
|
||||
/// Start test execution.
|
||||
/// </summary>
|
||||
public const string StartTestExecutionWithTests = "TestExecution.StartWithTests";
|
||||
|
||||
/// <summary>
|
||||
/// The test run stats change.
|
||||
/// </summary>
|
||||
public const string TestRunStatsChange = "TestExecution.StatsChange";
|
||||
|
||||
/// <summary>
|
||||
/// The execution complete.
|
||||
/// </summary>
|
||||
public const string ExecutionComplete = "TestExecution.Completed";
|
||||
|
||||
/// <summary>
|
||||
/// The message to get runner process startInfo for run all tests in given sources
|
||||
/// </summary>
|
||||
public const string GetTestRunnerProcessStartInfoForRunAll = "TestExecution.GetTestRunnerProcessStartInfoForRunAll";
|
||||
|
||||
/// <summary>
|
||||
/// The message to get runner process startInfo for run selected tests
|
||||
/// </summary>
|
||||
public const string GetTestRunnerProcessStartInfoForRunSelected = "TestExecution.GetTestRunnerProcessStartInfoForRunSelected";
|
||||
|
||||
/// <summary>
|
||||
/// CustomTestHostLaunch
|
||||
/// </summary>
|
||||
public const string CustomTestHostLaunch = "TestExecution.CustomTestHostLaunch";
|
||||
|
||||
/// <summary>
|
||||
/// Custom Test Host launch callback
|
||||
/// </summary>
|
||||
public const string CustomTestHostLaunchCallback = "TestExecution.CustomTestHostLaunchCallback";
|
||||
|
||||
/// <summary>
|
||||
/// Extensions Initialization
|
||||
/// </summary>
|
||||
public const string ExtensionsInitialize = "Extensions.Initialize";
|
||||
|
||||
/// <summary>
|
||||
/// Start Test Run All Sources
|
||||
/// </summary>
|
||||
public const string TestRunAllSourcesWithDefaultHost = "TestExecution.RunAllWithDefaultHost";
|
||||
|
||||
/// <summary>
|
||||
/// Start Test Run - Testcases
|
||||
/// </summary>
|
||||
public const string TestRunSelectedTestCasesDefaultHost = "TestExecution.RunSelectedWithDefaultHost";
|
||||
|
||||
/// <summary>
|
||||
/// Launch Adapter Process With DebuggerAttached
|
||||
/// </summary>
|
||||
public const string LaunchAdapterProcessWithDebuggerAttached = "TestExecution.LaunchAdapterProcessWithDebuggerAttached";
|
||||
|
||||
/// <summary>
|
||||
/// Launch Adapter Process With DebuggerAttached
|
||||
/// </summary>
|
||||
public const string LaunchAdapterProcessWithDebuggerAttachedCallback = "TestExecution.LaunchAdapterProcessWithDebuggerAttachedCallback";
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.TestPlatform.Protocol
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// Facilitates communication using sockets
|
||||
/// </summary>
|
||||
public class SocketCommunicationManager
|
||||
{
|
||||
/// <summary>
|
||||
/// TCP Listener to host TCP channel and listen
|
||||
/// </summary>
|
||||
private TcpListener tcpListener;
|
||||
|
||||
/// <summary>
|
||||
/// Binary Writer to write to channel stream
|
||||
/// </summary>
|
||||
private BinaryWriter binaryWriter;
|
||||
|
||||
/// <summary>
|
||||
/// Binary reader to read from channel stream
|
||||
/// </summary>
|
||||
private BinaryReader binaryReader;
|
||||
|
||||
/// <summary>
|
||||
/// Serializer for the data objects
|
||||
/// </summary>
|
||||
private JsonDataSerializer dataSerializer;
|
||||
|
||||
/// <summary>
|
||||
/// Event used to maintain client connection state
|
||||
/// </summary>
|
||||
private ManualResetEvent clientConnectedEvent = new ManualResetEvent(false);
|
||||
|
||||
/// <summary>
|
||||
/// Sync object for sending messages
|
||||
/// SendMessage over socket channel is NOT thread-safe
|
||||
/// </summary>
|
||||
private object sendSyncObject = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Stream to use read timeout
|
||||
/// </summary>
|
||||
private NetworkStream stream;
|
||||
|
||||
private Socket socket;
|
||||
|
||||
/// <summary>
|
||||
/// The server stream read timeout constant (in microseconds).
|
||||
/// </summary>
|
||||
private const int StreamReadTimeout = 1000 * 1000;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SocketCommunicationManager"/> class.
|
||||
/// </summary>
|
||||
public SocketCommunicationManager() : this(JsonDataSerializer.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
internal SocketCommunicationManager(JsonDataSerializer dataSerializer)
|
||||
{
|
||||
this.dataSerializer = dataSerializer;
|
||||
}
|
||||
|
||||
#region ServerMethods
|
||||
|
||||
/// <summary>
|
||||
/// Host TCP Socket Server and start listening
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int HostServer()
|
||||
{
|
||||
var endpoint = new IPEndPoint(IPAddress.Loopback, 0);
|
||||
this.tcpListener = new TcpListener(endpoint);
|
||||
|
||||
this.tcpListener.Start();
|
||||
var portNumber = ((IPEndPoint)this.tcpListener.LocalEndpoint).Port;
|
||||
Console.WriteLine("Server started. Listening at port : {0}", portNumber);
|
||||
return portNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accepts client async
|
||||
/// </summary>
|
||||
public async Task AcceptClientAsync()
|
||||
{
|
||||
if (this.tcpListener != null)
|
||||
{
|
||||
this.clientConnectedEvent.Reset();
|
||||
|
||||
var client = await this.tcpListener.AcceptTcpClientAsync();
|
||||
this.socket = client.Client;
|
||||
this.stream = client.GetStream();
|
||||
this.binaryReader = new BinaryReader(this.stream);
|
||||
this.binaryWriter = new BinaryWriter(this.stream);
|
||||
|
||||
this.clientConnectedEvent.Set();
|
||||
|
||||
Console.WriteLine("Accepted Client request and set the flag");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for Client Connection
|
||||
/// </summary>
|
||||
/// <param name="clientConnectionTimeout">Time to Wait for the connection</param>
|
||||
/// <returns>True if Client is connected, false otherwise</returns>
|
||||
public bool WaitForClientConnection(int clientConnectionTimeout)
|
||||
{
|
||||
return this.clientConnectedEvent.WaitOne(clientConnectionTimeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop Listener
|
||||
/// </summary>
|
||||
public void StopServer()
|
||||
{
|
||||
this.tcpListener?.Stop();
|
||||
this.tcpListener = null;
|
||||
this.binaryReader?.Dispose();
|
||||
this.binaryWriter?.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Writes message to the binary writer.
|
||||
/// </summary>
|
||||
/// <param name="messageType">Type of Message to be sent, for instance TestSessionStart</param>
|
||||
public void SendMessage(string messageType)
|
||||
{
|
||||
var serializedObject = this.dataSerializer.SerializeMessage(messageType);
|
||||
this.WriteAndFlushToChannel(serializedObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads message from the binary reader
|
||||
/// </summary>
|
||||
/// <returns>Returns message read from the binary reader</returns>
|
||||
public Message ReceiveMessage()
|
||||
{
|
||||
var rawMessage = this.ReceiveRawMessage();
|
||||
return this.dataSerializer.DeserializeMessage(rawMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes message to the binary writer with payload
|
||||
/// </summary>
|
||||
/// <param name="messageType">Type of Message to be sent, for instance TestSessionStart</param>
|
||||
/// <param name="payload">payload to be sent</param>
|
||||
public void SendMessage(string messageType, object payload)
|
||||
{
|
||||
var rawMessage = this.dataSerializer.SerializePayload(messageType, payload);
|
||||
this.WriteAndFlushToChannel(rawMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The send hand shake message.
|
||||
/// </summary>
|
||||
public void SendHandShakeMessage()
|
||||
{
|
||||
this.SendMessage(MessageType.SessionStart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads message from the binary reader
|
||||
/// </summary>
|
||||
/// <returns> Raw message string </returns>
|
||||
public string ReceiveRawMessage()
|
||||
{
|
||||
var rawMessage = this.binaryReader.ReadString();
|
||||
Console.WriteLine("\n=========== Receiving Message ===========");
|
||||
Console.WriteLine(rawMessage);
|
||||
return rawMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the Message into actual TestPlatform objects
|
||||
/// </summary>
|
||||
/// <typeparam name="T"> The type of object to deserialize to. </typeparam>
|
||||
/// <param name="message"> Message object </param>
|
||||
/// <returns> TestPlatform object </returns>
|
||||
public T DeserializePayload<T>(Message message)
|
||||
{
|
||||
return this.dataSerializer.DeserializePayload<T>(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the data on socket and flushes the buffer
|
||||
/// </summary>
|
||||
/// <param name="rawMessage">message to write</param>
|
||||
private void WriteAndFlushToChannel(string rawMessage)
|
||||
{
|
||||
// Writing Message on binarywriter is not Thread-Safe
|
||||
// Need to sync one by one to avoid buffer corruption
|
||||
lock (this.sendSyncObject)
|
||||
{
|
||||
Console.WriteLine("\n=========== Sending Message ===========");
|
||||
Console.WriteLine(rawMessage);
|
||||
this.binaryWriter?.Write(rawMessage);
|
||||
this.binaryWriter?.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net46</TargetFramework>
|
||||
<AssemblyName>Microsoft.TestPlatform.Protocol</AssemblyName>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
|
||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" />
|
||||
<EmbeddedResource Include="**\*.resx" />
|
||||
<EmbeddedResource Include="compiler\resources\**\*" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.5' ">
|
||||
<PackageReference Include="System.Runtime.Serialization.Primitives">
|
||||
<Version>4.1.1</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json">
|
||||
<Version>8.0.3</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Sdk">
|
||||
<Version>1.0.0-alpha-20161104-2</Version>
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.TestPlatform.Protocol
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// Class used to define the DiscoveryRequestPayload sent by the Vstest.console translation layers into design mode
|
||||
/// </summary>
|
||||
public class DiscoveryRequestPayload
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings used for the discovery request.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public IEnumerable<string> Sources { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Settings used for the discovery request.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string RunSettings { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.TestPlatform.Protocol
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// Class used to define the TestRunRequestPayload sent to Vstest.console in design mode
|
||||
/// </summary>
|
||||
public class TestRunRequestPayload
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the sources for the test run request.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public List<string> Sources { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the test cases for the test run request.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public dynamic TestCases { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the settings used for the test run request.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string RunSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Settings used for the Run request.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool KeepAlive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is Debugging enabled
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool DebuggingEnabled { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
//// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.TestPlatform.Protocol
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
public class Program
|
||||
{
|
||||
private const string PORT_ARGUMENT = "/port:{0}";
|
||||
private const string PARENT_PROCESSID_ARGUMENT = "/parentprocessid:{0}";
|
||||
|
||||
private static SocketCommunicationManager communicationManager;
|
||||
private static JsonDataSerializer dataSerializer = JsonDataSerializer.Instance;
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
if(args == null || args.Length < 1)
|
||||
{
|
||||
Console.WriteLine("Please provide appropriate arguments. Arguments can be passed as following:");
|
||||
Console.WriteLine("Microsoft.TestPlatform.Protocol.exe --testassembly:\"[assemblyPath]\" --operation:\"[RunAll|RunSelected|Discovery]\" --testadapterpath:\"[path]\"");
|
||||
Console.WriteLine("or Microsoft.TestPlatform.Protocol.exe -a:\"[assemblyPath]\" -o:\"[RunAll|RunSelected|Discovery]\" -p:\"[path]\" \n");
|
||||
}
|
||||
|
||||
var executingLocation = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
|
||||
|
||||
// Default values
|
||||
var testAssembly = Path.Combine(executingLocation, "UnitTestProject.dll");
|
||||
string testadapterPath = null;
|
||||
string operation = "Discovery";
|
||||
var separator = new char[] { ':' };
|
||||
foreach (var arg in args)
|
||||
{
|
||||
if (arg.StartsWith("-p:") || arg.StartsWith("--testadapterpath:"))
|
||||
{
|
||||
testadapterPath = arg.Split(separator, 2)[1];
|
||||
}
|
||||
else if (arg.StartsWith("-a:") || arg.StartsWith("--testassembly:"))
|
||||
{
|
||||
testAssembly = arg.Split(separator,2)[1];
|
||||
}
|
||||
else if (arg.StartsWith("-o:") || arg.StartsWith("--operation:"))
|
||||
{
|
||||
operation = arg.Split(separator, 2)[1];
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("TestAdapter Path : {0}", testadapterPath);
|
||||
Console.WriteLine("TestAssembly Path : {0}", testAssembly);
|
||||
Console.WriteLine("Operation : {0}", operation);
|
||||
|
||||
var processManager = new RunnerProcessManager();
|
||||
communicationManager = new SocketCommunicationManager();
|
||||
|
||||
// Start the server
|
||||
var port = communicationManager.HostServer();
|
||||
|
||||
//Start runner exe and wait for the connection
|
||||
string parentProcessIdArgs = string.Format(CultureInfo.InvariantCulture, PARENT_PROCESSID_ARGUMENT, Process.GetCurrentProcess().Id);
|
||||
string portArgs = string.Format(CultureInfo.InvariantCulture, PORT_ARGUMENT, port);
|
||||
processManager.StartProcess(new string[2] { parentProcessIdArgs, portArgs });
|
||||
|
||||
communicationManager.AcceptClientAsync();
|
||||
communicationManager.WaitForClientConnection(Timeout.Infinite);
|
||||
HandShakeWithVsTestConsole();
|
||||
|
||||
//Actual operation
|
||||
dynamic discoveredTestCases;
|
||||
switch (operation.ToLower())
|
||||
{
|
||||
case "discovery":
|
||||
discoveredTestCases = DiscoverTests(testadapterPath, testAssembly);
|
||||
break;
|
||||
|
||||
case "runselected":
|
||||
discoveredTestCases = DiscoverTests(testadapterPath, testAssembly);
|
||||
RunSelectedTests(discoveredTestCases);
|
||||
break;
|
||||
|
||||
case "runall":
|
||||
default:
|
||||
RunAllTests(new List<string>() { testAssembly });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void HandShakeWithVsTestConsole()
|
||||
{
|
||||
//HandShake with vstest.console
|
||||
Console.WriteLine("=========== HandShake with vstest.console ==========");
|
||||
var message = communicationManager.ReceiveMessage();
|
||||
if (message.MessageType == MessageType.SessionConnected)
|
||||
{
|
||||
//Version Check
|
||||
communicationManager.SendMessage(MessageType.VersionCheck);
|
||||
message = communicationManager.ReceiveMessage();
|
||||
|
||||
if (message.MessageType == MessageType.VersionCheck)
|
||||
{
|
||||
var version = JsonDataSerializer.Instance.DeserializePayload<int>(message);
|
||||
|
||||
var success = version == 1;
|
||||
Console.WriteLine("Version Success: {0}", success);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static dynamic DiscoverTests(string testadapterPath, string testAssembly)
|
||||
{
|
||||
Console.WriteLine("Starting Operation : Discovery");
|
||||
|
||||
// Intialize the extensions
|
||||
if (testadapterPath != null)
|
||||
{
|
||||
communicationManager.SendMessage(MessageType.ExtensionsInitialize, new List<string>() { testadapterPath });
|
||||
}
|
||||
|
||||
// Start Discovery
|
||||
communicationManager.SendMessage(
|
||||
MessageType.StartDiscovery,
|
||||
new DiscoveryRequestPayload() { Sources = new List<string>() { testAssembly }, RunSettings = null });
|
||||
var isDiscoveryComplete = false;
|
||||
|
||||
dynamic testCases = null;
|
||||
|
||||
while (!isDiscoveryComplete)
|
||||
{
|
||||
var message = communicationManager.ReceiveMessage();
|
||||
|
||||
if (string.Equals(MessageType.TestCasesFound, message.MessageType))
|
||||
{
|
||||
// Handle discovered tests here.
|
||||
testCases = (JsonDataSerializer.Instance.DeserializePayload<dynamic>(message));
|
||||
}
|
||||
else if (string.Equals(MessageType.DiscoveryComplete, message.MessageType))
|
||||
{
|
||||
dynamic discoveryCompletePayload =
|
||||
JsonDataSerializer.Instance.DeserializePayload<dynamic>(message);
|
||||
|
||||
//Handle discovery complete here
|
||||
isDiscoveryComplete = true;
|
||||
}
|
||||
else if (string.Equals(MessageType.TestMessage, message.MessageType))
|
||||
{
|
||||
var testMessagePayload = dataSerializer.DeserializePayload<dynamic>(message);
|
||||
// Handle messages here.
|
||||
}
|
||||
}
|
||||
|
||||
return testCases;
|
||||
}
|
||||
|
||||
static void RunAllTests(List<string> sources)
|
||||
{
|
||||
Console.WriteLine("Starting Operation: RunAll");
|
||||
communicationManager.SendMessage(MessageType.TestRunAllSourcesWithDefaultHost, new TestRunRequestPayload() { Sources = sources, RunSettings = null });
|
||||
RecieveRunMesagesAndHandleRunComplete();
|
||||
}
|
||||
|
||||
static void RunSelectedTests(dynamic testCases)
|
||||
{
|
||||
Console.WriteLine("Starting Operation: RunSelected");
|
||||
communicationManager.SendMessage(MessageType.TestRunSelectedTestCasesDefaultHost, new TestRunRequestPayload() { TestCases = testCases, RunSettings = null });
|
||||
RecieveRunMesagesAndHandleRunComplete();
|
||||
}
|
||||
|
||||
static void RecieveRunMesagesAndHandleRunComplete()
|
||||
{
|
||||
var isTestRunComplete = false;
|
||||
|
||||
while (!isTestRunComplete)
|
||||
{
|
||||
var message = communicationManager.ReceiveMessage();
|
||||
|
||||
if (string.Equals(MessageType.TestRunStatsChange, message.MessageType))
|
||||
{
|
||||
var testRunChangedArgs = dataSerializer.DeserializePayload<dynamic>(message);
|
||||
// Handle TestRunStatsChange here
|
||||
}
|
||||
else if (string.Equals(MessageType.ExecutionComplete, message.MessageType))
|
||||
{
|
||||
var testRunCompletePayload = dataSerializer.DeserializePayload<dynamic>(message);
|
||||
|
||||
// Handle TestRunComplete here
|
||||
// Set the flag, to end the loop.
|
||||
isTestRunComplete = true;
|
||||
}
|
||||
else if (string.Equals(MessageType.TestMessage, message.MessageType))
|
||||
{
|
||||
var testMessagePayload = dataSerializer.DeserializePayload<dynamic>(message);
|
||||
// Handle log messages here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Microsoft.TestPlatform.Protocol")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("4ec14041-7804-4840-ae70-98babdc8b0e2")]
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"profiles": {
|
||||
"Microsoft.TestPlatform.Protocol": {
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.TestPlatform.Protocol
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// dotnet.exe process manager
|
||||
/// </summary>
|
||||
internal class RunnerProcessManager
|
||||
{
|
||||
private object syncObject = new object();
|
||||
|
||||
private bool vstestConsoleStarted = false;
|
||||
|
||||
private bool vstestConsoleExited = false;
|
||||
|
||||
private Process process;
|
||||
|
||||
public event EventHandler ProcessExited;
|
||||
|
||||
#region Constructor
|
||||
|
||||
public RunnerProcessManager()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion Constructor
|
||||
|
||||
public bool IsProcessInitialized()
|
||||
{
|
||||
lock (syncObject)
|
||||
{
|
||||
return this.vstestConsoleStarted && !vstestConsoleExited &&
|
||||
this.process != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call dotnet.exe with the parameters previously specified
|
||||
/// </summary>
|
||||
public void StartProcess(string[] args)
|
||||
{
|
||||
this.process = new Process();
|
||||
process.StartInfo.FileName = GetDotnetHostFullPath();
|
||||
|
||||
if (args != null)
|
||||
{
|
||||
process.StartInfo.Arguments = args.Length < 2 ? args[0] : string.Join(" ", args);
|
||||
}
|
||||
process.StartInfo.Arguments = "vstest" + " " + process.StartInfo.Arguments;
|
||||
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.CreateNoWindow = true;
|
||||
|
||||
process.Start();
|
||||
process.EnableRaisingEvents = true;
|
||||
process.Exited += Process_Exited;
|
||||
|
||||
lock (syncObject)
|
||||
{
|
||||
vstestConsoleExited = false;
|
||||
vstestConsoleStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void ShutdownProcess()
|
||||
{
|
||||
// Ideally process should die by itself
|
||||
if (IsProcessInitialized())
|
||||
{
|
||||
this.process.Kill();
|
||||
this.process.Dispose();
|
||||
this.process = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get full path for the .net host
|
||||
/// </summary>
|
||||
/// <returns>Full path to <c>dotnet</c> executable</returns>
|
||||
/// <remarks>Debuggers require the full path of executable to launch it.</remarks>
|
||||
private string GetDotnetHostFullPath()
|
||||
{
|
||||
char separator = ';';
|
||||
var dotnetExeName = "dotnet.exe";
|
||||
|
||||
#if !NET46
|
||||
// Use semicolon(;) as path separator for windows
|
||||
// colon(:) for Linux and OSX
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
separator = ':';
|
||||
dotnetExeName = "dotnet";
|
||||
}
|
||||
#endif
|
||||
|
||||
var pathString = Environment.GetEnvironmentVariable("PATH");
|
||||
foreach (string path in pathString.Split(separator))
|
||||
{
|
||||
string exeFullPath = Path.Combine(path.Trim(), dotnetExeName);
|
||||
if (File.Exists(exeFullPath))
|
||||
{
|
||||
return exeFullPath;
|
||||
}
|
||||
}
|
||||
|
||||
string errorMessage = String.Format("Unable to find dotnet.exe");
|
||||
Console.WriteLine("Error : {0}", errorMessage);
|
||||
throw new FileNotFoundException(errorMessage);
|
||||
}
|
||||
|
||||
private void Process_Exited(object sender, EventArgs e)
|
||||
{
|
||||
lock (syncObject)
|
||||
{
|
||||
vstestConsoleExited = true;
|
||||
this.ProcessExited?.Invoke(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,9 +8,62 @@ namespace UnitTestProject
|
|||
[TestClass]
|
||||
public class UnitTest
|
||||
{
|
||||
/// <summary>
|
||||
/// The passing test.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void TestMethod1()
|
||||
public void PassingTest()
|
||||
{
|
||||
Assert.AreEqual(2, 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The failing test.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void FailingTest()
|
||||
{
|
||||
Assert.AreEqual(2, 3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The skipping test.
|
||||
/// </summary>
|
||||
[Ignore]
|
||||
[TestMethod]
|
||||
public void SkippingTest()
|
||||
{
|
||||
}
|
||||
|
||||
[TestCategory("CategoryA")]
|
||||
[TestMethod]
|
||||
public void TestWithTestCategory()
|
||||
{
|
||||
Assert.AreEqual(1, 1);
|
||||
}
|
||||
|
||||
[Priority(0)]
|
||||
[TestMethod]
|
||||
public void TestWithPriority()
|
||||
{
|
||||
Assert.AreEqual(1, 1);
|
||||
}
|
||||
|
||||
[TestProperty("Property1", "Value1")]
|
||||
[TestProperty("Property2", "Value2")]
|
||||
[TestMethod]
|
||||
public void TestWithProperties()
|
||||
{
|
||||
Assert.AreEqual(1, 1);
|
||||
}
|
||||
|
||||
[TestCategory("CategoryA")]
|
||||
[Priority(1)]
|
||||
[TestProperty("Property2", "Value2")]
|
||||
[TestMethod]
|
||||
public void FailingTestWithTraits()
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp1.0;net46</TargetFrameworks>
|
||||
<OutputType Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">Exe</OutputType>
|
||||
<AssemblyName>UnitTestProject</AssemblyName>
|
||||
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);dnxcore50;portable-net45+win8</PackageTargetFallback>
|
||||
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
|
||||
|
@ -14,12 +14,10 @@
|
|||
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
|
||||
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="**\*.cs" />
|
||||
<Compile Include="**\*.cs" />
|
||||
<EmbeddedResource Include="compiler\resources\**\*" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Sdk">
|
||||
<Version>1.0.0-alpha-20161104-2</Version>
|
||||
|
@ -29,28 +27,30 @@
|
|||
<Version>1.6.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestFramework">
|
||||
<Version>1.0.4-preview</Version>
|
||||
<Version>1.0.8-rc</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestAdapter">
|
||||
<Version>1.1.8-rc</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">
|
||||
<PackageReference Include="Microsoft.NETCore.App">
|
||||
<Version>1.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk">
|
||||
<Version>15.0.0-preview-20161123-03</Version>
|
||||
<Version>15.0.0-preview-20161216-01</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
||||
<Reference Include="System.Runtime" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
</Project>
|
Загрузка…
Ссылка в новой задаче