diff --git a/TestPlatform.sln b/TestPlatform.sln
index 091ee3b0c9..bbd177eff0 100644
--- a/TestPlatform.sln
+++ b/TestPlatform.sln
@@ -95,6 +95,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SimpleDataCollector", "test
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SimpleTestProject", "test\TestAssets\SimpleTestProject\SimpleTestProject.xproj", "{0CC51637-B665-47B0-A093-042D31785928}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Performance", "Performance", "{44DABCFB-7AA0-4682-B7F7-067E0ABA1D14}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.TestPlatform.PerformanceTests", "test\Performance\Microsoft.TestPlatform.PerformanceTests\Microsoft.TestPlatform.PerformanceTests.xproj", "{12D59CED-9916-4C3F-AF82-12E019757FD2}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -233,6 +237,10 @@ Global
{0CC51637-B665-47B0-A093-042D31785928}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CC51637-B665-47B0-A093-042D31785928}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CC51637-B665-47B0-A093-042D31785928}.Release|Any CPU.Build.0 = Release|Any CPU
+ {12D59CED-9916-4C3F-AF82-12E019757FD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {12D59CED-9916-4C3F-AF82-12E019757FD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {12D59CED-9916-4C3F-AF82-12E019757FD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {12D59CED-9916-4C3F-AF82-12E019757FD2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -275,5 +283,7 @@ Global
{50D7D355-08F6-4DFD-AEAA-9BCE41C94C18} = {463031A2-7F16-4E38-9944-1F5161D04933}
{D7F7A9F5-5646-44E7-990C-500844E9272E} = {50D7D355-08F6-4DFD-AEAA-9BCE41C94C18}
{0CC51637-B665-47B0-A093-042D31785928} = {50D7D355-08F6-4DFD-AEAA-9BCE41C94C18}
+ {44DABCFB-7AA0-4682-B7F7-067E0ABA1D14} = {463031A2-7F16-4E38-9944-1F5161D04933}
+ {12D59CED-9916-4C3F-AF82-12E019757FD2} = {44DABCFB-7AA0-4682-B7F7-067E0ABA1D14}
EndGlobalSection
EndGlobal
diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs
index 06da1f28d8..893215107b 100644
--- a/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs
+++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs
@@ -275,7 +275,7 @@ private TimeSpan RunTestsInternal()
totalTests);
stopwatch.Stop();
- this.testPlatformEventSource.ExecutionStop(totalTests);
+ this.testPlatformEventSource.ExecutionStop(this.testRunCache.TotalExecutedTests);
this.BeforeRaisingTestRunComplete(exceptionsHitDuringRunTests);
return stopwatch.Elapsed;
}
diff --git a/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/Constants.cs b/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/Constants.cs
new file mode 100644
index 0000000000..4ac8615d49
--- /dev/null
+++ b/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/Constants.cs
@@ -0,0 +1,69 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.TestPlatform.TestUtilities.PerfInstrumentation
+{
+ ///
+ /// The constants.
+ ///
+ public class Constants
+ {
+ ///
+ /// The discovery task.
+ ///
+ public const string DiscoveryTask = "Discovery";
+
+ ///
+ /// The execution task.
+ ///
+ public const string ExecutionTask = "Execution";
+
+ ///
+ /// The execution request task.
+ ///
+ public const string ExecutionRequestTask = "ExecutionRequest";
+
+ ///
+ /// The discovery request task.
+ ///
+ public const string DiscoveryRequestTask = "DiscoveryRequest";
+
+ ///
+ /// The test host task.
+ ///
+ public const string TestHostTask = "TestHost";
+
+ ///
+ /// The vs test console task.
+ ///
+ public const string VsTestConsoleTask = "VsTestConsole";
+
+ ///
+ /// The adapter search task.
+ ///
+ public const string AdapterSearchTask = "AdapterSearch";
+
+ ///
+ /// The adapter execution task.
+ ///
+ public const string AdapterExecutionTask = "AdapterExecution";
+
+ ///
+ /// The adapter discovery task.
+ ///
+ public const string AdapterDiscoveryTask = "AdapterDiscovery";
+
+ #region PayLoad Property Names
+
+ ///
+ /// The execution uri property.
+ ///
+ public const string ExecutionUriProperty = "executorUri";
+
+ ///
+ /// The number of tests property.
+ ///
+ public const string NumberOfTestsProperty = "numberOfTests";
+ #endregion
+
+ }
+}
diff --git a/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/PerfAnalyzer.cs b/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/PerfAnalyzer.cs
new file mode 100644
index 0000000000..c7291343b6
--- /dev/null
+++ b/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/PerfAnalyzer.cs
@@ -0,0 +1,242 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.TestPlatform.TestUtilities.PerfInstrumentation
+{
+ using System.Collections.Generic;
+
+#if NET46
+ using Microsoft.Diagnostics.Tracing;
+ using Microsoft.Diagnostics.Tracing.Parsers;
+ using Microsoft.Diagnostics.Tracing.Session;
+ using System;
+ using System.Linq;
+#endif
+
+ ///
+ /// The perf analyzer.
+ ///
+ public class PerfAnalyzer
+ {
+ ///
+ /// The etw session provider name.
+ ///
+ private const string ETWSessionProviderName = "TestPlatform";
+
+#if NET46
+ private string perfDataFileName;
+ private TraceEventSession traceEventSession;
+ private Dictionary> testPlatformTaskMap;
+#endif
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public PerfAnalyzer()
+ {
+#if NET46
+ this.perfDataFileName = "TestPlatformEventsData.etl";
+ this.testPlatformTaskMap = new Dictionary>();
+ this.traceEventSession = new TraceEventSession("TestPlatofrmSession", this.perfDataFileName);
+#endif
+ }
+
+ ///
+ /// The enable provider.
+ ///
+ public void EnableProvider()
+ {
+#if NET46
+ this.traceEventSession.StopOnDispose = true;
+ this.traceEventSession.EnableProvider(ETWSessionProviderName);
+#endif
+ }
+
+ ///
+ /// The disable provider.
+ ///
+ public void DisableProvider()
+ {
+#if NET46
+ this.traceEventSession.Dispose();
+#endif
+ }
+
+ ///
+ /// The analyze events data.
+ ///
+ public void AnalyzeEventsData()
+ {
+#if NET46
+ using (var source = new ETWTraceEventSource(this.perfDataFileName))
+ {
+ // Open the file
+ var parser = new DynamicTraceEventParser(source);
+ parser.All += delegate(TraceEvent data)
+ {
+ try
+ {
+ if (data.ProviderName.Equals("TestPlatform") && !data.EventName.Equals("ManifestData"))
+ {
+ Console.WriteLine("Received Event : {0}", data.ToString());
+ var key = data.ProcessID + "_" + data.ThreadID.ToString() + "_" + data.TaskName;
+
+ if (!testPlatformTaskMap.ContainsKey(key))
+ {
+ var list = new List { CreateTestPlatformTask(data) };
+ testPlatformTaskMap.Add(key, list);
+ }
+ else
+ {
+ if (data.Opcode == TraceEventOpcode.Start)
+ {
+ testPlatformTaskMap[key].Add(CreateTestPlatformTask(data));
+ }
+ else
+ {
+ UpdateTask(testPlatformTaskMap[key].Last(), data);
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ }
+ };
+ source.Process(); // Read the file, processing the callbacks.
+ }
+#endif
+ }
+
+ ///
+ /// The get elapsed time by task name.
+ ///
+ ///
+ /// The task name.
+ ///
+ ///
+ /// The .
+ ///
+ public double GetElapsedTimeByTaskName(string taskName)
+ {
+ var timeTaken = 0.0;
+#if NET46
+ var key = GetEventKey(taskName);
+
+ if (key != null)
+ {
+ var task = testPlatformTaskMap[key].First();
+ timeTaken = task.EventStopped - task.EventStarted;
+ }
+#endif
+ return timeTaken;
+ }
+
+ ///
+ /// The get event data by task name.
+ ///
+ ///
+ /// The task name.
+ ///
+ ///
+ /// The .
+ ///
+ public IDictionary GetEventDataByTaskName(string taskName)
+ {
+ IDictionary properties = new Dictionary();
+#if NET46
+ var key = GetEventKey(taskName);
+
+ if(key != null)
+ {
+ properties = testPlatformTaskMap[key].First().PayLoadProperties;
+ }
+#endif
+ return properties;
+ }
+
+ public double GetAdapterExecutionTime(string executorUri)
+ {
+ var timeTaken = 0.0;
+#if NET46
+ var key = GetEventKey(Constants.AdapterExecutionTask);
+
+ if(key != null)
+ {
+ var task = testPlatformTaskMap[key].FirstOrDefault(t => t.PayLoadProperties["executorUri"].Equals(executorUri));
+ timeTaken = task.EventStopped - task.EventStarted;
+ }
+#endif
+ return timeTaken;
+ }
+
+ public long GetAdapterExecutedTests(string executorUri)
+ {
+ long totalTestsExecuted = 0;
+#if NET46
+ var key = GetEventKey(Constants.AdapterExecutionTask);
+
+ if (key != null)
+ {
+ var task = testPlatformTaskMap[key].FirstOrDefault(t => t.PayLoadProperties["executorUri"].Equals(executorUri));
+ long.TryParse(task.PayLoadProperties["numberOfTests"].ToString(), out totalTestsExecuted);
+ }
+#endif
+ return totalTestsExecuted;
+ }
+
+#if NET46
+
+ private string GetEventKey(string taskName)
+ {
+ string key = null;
+
+ key = testPlatformTaskMap.Keys.FirstOrDefault(k => k.Split('_')[2].Equals(taskName));
+
+ return key;
+ }
+
+ private static TestPlatformTask CreateTestPlatformTask(TraceEvent data)
+ {
+ var task = new TestPlatformTask(data.TaskName, data.TimeStampRelativeMSec);
+ task.PayLoadProperties = GetPayloadProperties(data);
+ return task;
+ }
+
+ private static void UpdateTask(TestPlatformTask task, TraceEvent data)
+ {
+ task.EventStopped = data.TimeStampRelativeMSec;
+ var payLoadProperties = GetPayloadProperties(data);
+
+ //Merging dictionaries look for better way
+ foreach (var k in payLoadProperties.Keys)
+ {
+ if (!task.PayLoadProperties.ContainsKey(k))
+ {
+ task.PayLoadProperties.Add(k, payLoadProperties[k]);
+ }
+ }
+ }
+
+ private static IDictionary GetPayloadProperties(TraceEvent data)
+ {
+ var payLoadProperties = new Dictionary();
+
+ foreach (var payLoad in data.PayloadNames)
+ {
+ var payLoadData = data.PayloadByName(payLoad).ToString();
+ if (!payLoadProperties.ContainsKey(payLoad))
+ {
+ payLoadProperties.Add(payLoad, payLoadData);
+ }
+ else
+ {
+ payLoadProperties[payLoad] = payLoadData;
+ }
+ }
+
+ return payLoadProperties;
+ }
+#endif
+ }
+}
diff --git a/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/PerformanceTestBase.cs b/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/PerformanceTestBase.cs
new file mode 100644
index 0000000000..87eda9ea0c
--- /dev/null
+++ b/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/PerformanceTestBase.cs
@@ -0,0 +1,134 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.TestPlatform.TestUtilities.PerfInstrumentation
+{
+ using System.Collections;
+ using System.Collections.Generic;
+
+ using Microsoft.TestPlatform.TestUtilities;
+
+ ///
+ /// The performance test base.
+ ///
+ public class PerformanceTestBase : IntegrationTestBase
+ {
+ private PerfAnalyzer perfAnalyzer;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public PerformanceTestBase()
+ : base()
+ {
+ this.perfAnalyzer = new PerfAnalyzer();
+ }
+
+ ///
+ /// The run execution performance tests.
+ ///
+ ///
+ /// The test asset.
+ ///
+ ///
+ /// The test adapter path.
+ ///
+ ///
+ /// The run settings.
+ ///
+ public void RunExecutionPerformanceTests(string testAsset, string testAdapterPath, string runSettings)
+ {
+ // Start session and listen
+#if NET46
+ this.perfAnalyzer.EnableProvider();
+#endif
+ // Run Test
+ this.InvokeVsTestForExecution(testAsset, testAdapterPath, runSettings);
+
+ // Stop Listening
+#if NET46
+ this.perfAnalyzer.DisableProvider();
+#endif
+ }
+
+ ///
+ /// The run discovery performance tests.
+ ///
+ ///
+ /// The test asset.
+ ///
+ ///
+ /// The test adapter path.
+ ///
+ ///
+ /// The run settings.
+ ///
+ public void RunDiscoveryPerformanceTests(string testAsset, string testAdapterPath, string runSettings)
+ {
+ // Start session and listen
+#if NET46
+ this.perfAnalyzer.EnableProvider();
+#endif
+ // Run Test
+ this.InvokeVsTestForDiscovery(testAsset, testAdapterPath, runSettings);
+
+ // Stop Listening
+#if NET46
+ this.perfAnalyzer.DisableProvider();
+#endif
+ }
+
+ ///
+ /// The analyze perf data.
+ ///
+ public void AnalyzePerfData()
+ {
+ this.perfAnalyzer.AnalyzeEventsData();
+ }
+
+ ///
+ /// The get execution time.
+ ///
+ ///
+ /// The .
+ ///
+ public double GetExecutionTime()
+ {
+ return this.perfAnalyzer.GetElapsedTimeByTaskName(Constants.ExecutionTask);
+ }
+
+ public double GetDiscoveryTime()
+ {
+ return this.perfAnalyzer.GetElapsedTimeByTaskName(Constants.DiscoveryTask);
+ }
+
+ public double GetVsTestTime()
+ {
+ return this.perfAnalyzer.GetElapsedTimeByTaskName(Constants.VsTestConsoleTask);
+ }
+
+ public double GetTestHostTime()
+ {
+ return this.perfAnalyzer.GetElapsedTimeByTaskName(Constants.TestHostTask);
+ }
+
+ public double GetAdapterSearchTime()
+ {
+ return this.perfAnalyzer.GetElapsedTimeByTaskName(Constants.AdapterSearchTask);
+ }
+
+ public IDictionary GetDiscoveryData()
+ {
+ return this.perfAnalyzer.GetEventDataByTaskName(Constants.AdapterDiscoveryTask);
+ }
+
+ public IDictionary GetExecutionData()
+ {
+ return this.perfAnalyzer.GetEventDataByTaskName(Constants.AdapterExecutionTask);
+ }
+
+ public double GetAdapterExecutionTime(string executorUri)
+ {
+ return this.perfAnalyzer.GetAdapterExecutionTime(executorUri);
+ }
+ }
+}
diff --git a/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/TestPlatformTask.cs b/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/TestPlatformTask.cs
new file mode 100644
index 0000000000..9507c7113a
--- /dev/null
+++ b/test/Microsoft.TestPlatform.TestUtilities/PerfInstrumentation/TestPlatformTask.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.TestPlatform.TestUtilities.PerfInstrumentation
+{
+ using System.Collections.Generic;
+
+ ///
+ /// The test platform task.
+ ///
+ public class TestPlatformTask
+ {
+ public string TaskName { get; set; }
+
+ public double EventStarted { get; set; }
+
+ public double EventStopped { get; set; }
+
+ public IDictionary PayLoadProperties { get; set; }
+
+ public TestPlatformTask(string taskName, double eventStarted)
+ {
+ this.EventStarted = eventStarted;
+ this.TaskName = taskName;
+ this.PayLoadProperties = new Dictionary();
+ }
+ }
+}
diff --git a/test/Microsoft.TestPlatform.TestUtilities/project.json b/test/Microsoft.TestPlatform.TestUtilities/project.json
index 959f01fc62..78f3980d00 100644
--- a/test/Microsoft.TestPlatform.TestUtilities/project.json
+++ b/test/Microsoft.TestPlatform.TestUtilities/project.json
@@ -26,7 +26,10 @@
},
"net46": {
"frameworkAssemblies": {
- "System.Runtime": ""
+ "System.Runtime": ""
+ },
+ "dependencies": {
+ "Microsoft.Diagnostics.Tracing.TraceEvent": "1.0.41"
}
}
}
diff --git a/test/Performance/Microsoft.TestPlatform.PerformanceTests/Microsoft.TestPlatform.PerformanceTests.xproj b/test/Performance/Microsoft.TestPlatform.PerformanceTests/Microsoft.TestPlatform.PerformanceTests.xproj
new file mode 100644
index 0000000000..cce084146a
--- /dev/null
+++ b/test/Performance/Microsoft.TestPlatform.PerformanceTests/Microsoft.TestPlatform.PerformanceTests.xproj
@@ -0,0 +1,22 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 12d59ced-9916-4c3f-af82-12e019757fd2
+ Microsoft.TestPlatform.PerformanceTests
+ .\obj
+ .\bin\
+ v4.5.2
+
+
+ 2.0
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Performance/Microsoft.TestPlatform.PerformanceTests/PerformanceTests.cs b/test/Performance/Microsoft.TestPlatform.PerformanceTests/PerformanceTests.cs
new file mode 100644
index 0000000000..f82848e218
--- /dev/null
+++ b/test/Performance/Microsoft.TestPlatform.PerformanceTests/PerformanceTests.cs
@@ -0,0 +1,101 @@
+// 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.PerformanceTests
+{
+ using Microsoft.TestPlatform.TestUtilities.PerfInstrumentation;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ ///
+ /// The performance tests.
+ ///
+ [TestClass]
+ public class PerformanceTests : PerformanceTestBase
+ {
+ [TestMethod]
+ public void ExecutionPerformanceTest()
+ {
+ this.RunExecutionPerformanceTests(this.GetSampleTestAssembly(), this.GetTestAdapterPath(), string.Empty);
+
+ this.ValidateSummaryStatus(1, 1, 1);
+ this.ValidatePassedTests("SampleUnitTestProject.UnitTest1.PassingTest");
+ this.ValidateFailedTests("SampleUnitTestProject.UnitTest1.FailingTest");
+ this.ValidateSkippedTests("SampleUnitTestProject.UnitTest1.SkippingTest");
+
+ this.AnalyzePerfData();
+ var actualExecutionTime = this.GetExecutionTime();
+
+ // Sample Assert statement to verify the performance. 500 will be replaced by the actual threshold value.
+ Assert.IsTrue(actualExecutionTime < 500);
+ }
+
+ [TestMethod]
+ public void DiscoveryPerformanceTest()
+ {
+ this.RunDiscoveryPerformanceTests(this.GetSampleTestAssembly(), this.GetTestAdapterPath(), string.Empty);
+
+ this.ValidateDiscoveredTests(
+ "SampleUnitTestProject.UnitTest1.PassingTest",
+ "SampleUnitTestProject.UnitTest1.FailingTest",
+ "SampleUnitTestProject.UnitTest1.SkippingTest");
+
+ this.AnalyzePerfData();
+ var actualDiscoveryTime = this.GetDiscoveryTime();
+
+ // Sample Assert statement to verify the performance. 500 will be replaced by the actual threshold value.
+ Assert.IsTrue(actualDiscoveryTime < 500);
+ }
+
+ [TestMethod]
+ public void VsTestConsolePerformanceTest()
+ {
+ this.RunExecutionPerformanceTests(this.GetSampleTestAssembly(), this.GetTestAdapterPath(), string.Empty);
+
+ this.ValidateSummaryStatus(1, 1, 1);
+ this.ValidatePassedTests("SampleUnitTestProject.UnitTest1.PassingTest");
+ this.ValidateFailedTests("SampleUnitTestProject.UnitTest1.FailingTest");
+ this.ValidateSkippedTests("SampleUnitTestProject.UnitTest1.SkippingTest");
+
+ this.AnalyzePerfData();
+ var actualVsTestTime = this.GetVsTestTime();
+
+ // Sample Assert statement to verify the performance. 1500 will be replaced by the actual threshold value.
+ Assert.IsTrue(actualVsTestTime < 1500);
+ }
+
+ [TestMethod]
+ public void TestHostPerformanceTest()
+ {
+ this.RunExecutionPerformanceTests(this.GetSampleTestAssembly(), this.GetTestAdapterPath(), string.Empty);
+
+ this.ValidateSummaryStatus(1, 1, 1);
+ this.ValidatePassedTests("SampleUnitTestProject.UnitTest1.PassingTest");
+ this.ValidateFailedTests("SampleUnitTestProject.UnitTest1.FailingTest");
+ this.ValidateSkippedTests("SampleUnitTestProject.UnitTest1.SkippingTest");
+
+ this.AnalyzePerfData();
+ var actualTestHostTime = this.GetTestHostTime();
+
+ // Sample Assert statement to verify the performance. 1000 will be replaced by the actual threshold value.
+ Assert.IsTrue(actualTestHostTime < 1000);
+ }
+
+ [TestMethod]
+ public void MsTestV2AdapterPerformanceTest()
+ {
+ this.RunExecutionPerformanceTests(this.GetSampleTestAssembly(), this.GetTestAdapterPath(), string.Empty);
+
+ this.ValidateSummaryStatus(1, 1, 1);
+ this.ValidatePassedTests("SampleUnitTestProject.UnitTest1.PassingTest");
+ this.ValidateFailedTests("SampleUnitTestProject.UnitTest1.FailingTest");
+ this.ValidateSkippedTests("SampleUnitTestProject.UnitTest1.SkippingTest");
+
+ this.AnalyzePerfData();
+
+ var actualAdapterTimeTaken = this.GetAdapterExecutionTime("executor://mstestadapter/v2");
+
+ // Sample Assert statement to verify the performance. 300 will be replaced by the actual threshold value.
+ Assert.IsTrue(actualAdapterTimeTaken < 300);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Performance/Microsoft.TestPlatform.PerformanceTests/Properties/AssemblyInfo.cs b/test/Performance/Microsoft.TestPlatform.PerformanceTests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..fa7b252b08
--- /dev/null
+++ b/test/Performance/Microsoft.TestPlatform.PerformanceTests/Properties/AssemblyInfo.cs
@@ -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.PerformanceTests")]
+[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("12d59ced-9916-4c3f-af82-12e019757fd2")]
diff --git a/test/Performance/Microsoft.TestPlatform.PerformanceTests/project.json b/test/Performance/Microsoft.TestPlatform.PerformanceTests/project.json
new file mode 100644
index 0000000000..c8a85d4e31
--- /dev/null
+++ b/test/Performance/Microsoft.TestPlatform.PerformanceTests/project.json
@@ -0,0 +1,47 @@
+{
+ "version": "15.0.0-*",
+
+ "buildOptions": {
+ "delaySign": true,
+ "keyFile": "../../../scripts/key.snk",
+ "warningsAsErrors": true,
+ "additionalArguments": [ "/ruleset:../../../scripts/stylecop.test.ruleset", "/additionalFile:../../../scripts/stylecop.json" ]
+ },
+
+ "dependencies": {
+ "MSTest.TestFramework": "1.0.0-preview",
+ "MSTest.TestAdapter": {
+ "version": "1.0.3-preview",
+ "exclude": "compile"
+ },
+
+ "StyleCop.Analyzers": {
+ "version": "1.0.0",
+ "type": "build"
+ },
+
+ "Microsoft.TestPlatform.TestUtilities": "15.0.0-*"
+ },
+
+ "frameworks": {
+ "netcoreapp1.0": {
+ "imports": [
+ "dnxcore50",
+ "portable-net45+win8"
+ ],
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0"
+ },
+ "dotnet-test-mstest": {
+ "version": "1.0.1-preview",
+ "exclude": "compile"
+ }
+ }
+ },
+ "net46": { }
+ },
+
+ "testRunner": "mstest"
+}