From 0eef86b2bffa4ed7b5bb3aba2d97b1d74dcaae90 Mon Sep 17 00:00:00 2001 From: Faizan2304 Date: Thu, 15 Jun 2017 16:24:56 +0530 Subject: [PATCH] Clear extensions cache after discover/execution complete. (#853) * Clear cache after discover/execution complete. * Sort usings * Fix for issue: 1) https://github.com/Microsoft/vstest/issues/632 2) https://github.com/Microsoft/vstest/issues/844 * nitpick: Spelling * Addressed PR comment * spelling correction * nitpick: function name * Removed unused usings --- .../Execution/TestRunRequest.cs | 12 +++-- .../TestPlatform.cs | 8 ++++ .../ExtensionFramework/TestPluginCache.cs | 14 ++++++ .../Client/Interfaces/ITestPlatform.cs | 5 +++ .../TestPlatformHelpers/TestRequestManager.cs | 6 +++ .../TestPluginCacheTests.cs | 38 +++++++++++++++- .../TestRequestManagerTests.cs | 45 ++++++++++++++++--- 7 files changed, 114 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/Execution/TestRunRequest.cs b/src/Microsoft.TestPlatform.Client/Execution/TestRunRequest.cs index beed69f9b3..fb5e4c85fa 100644 --- a/src/Microsoft.TestPlatform.Client/Execution/TestRunRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Execution/TestRunRequest.cs @@ -3,19 +3,17 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.Execution { - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Threading; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestPlatform.Utilities; - - using ClientResources = Microsoft.VisualStudio.TestPlatform.Client.Resources.Resources; + using System; + using System.Collections.Generic; using System.Collections.ObjectModel; + using System.Diagnostics; + using System.Threading; + using ClientResources = Microsoft.VisualStudio.TestPlatform.Client.Resources.Resources; public class TestRunRequest : ITestRunRequest, ITestRunEventsHandler { diff --git a/src/Microsoft.TestPlatform.Client/TestPlatform.cs b/src/Microsoft.TestPlatform.Client/TestPlatform.cs index df62dbb1c5..4ebaa1b73f 100644 --- a/src/Microsoft.TestPlatform.Client/TestPlatform.cs +++ b/src/Microsoft.TestPlatform.Client/TestPlatform.cs @@ -158,6 +158,14 @@ public void UpdateExtensions(IEnumerable pathToAdditionalExtensions, boo .UseAdditionalExtensions(pathToAdditionalExtensions, loadOnlyWellKnownExtensions); } + /// + /// Clear test plugin cache + /// + public void ClearExtensions() + { + TestPluginCache.Instance.ClearExtensions(); + } + /// /// Update the test adapter paths provided through run settings to be used by the test service /// diff --git a/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginCache.cs b/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginCache.cs index 5cf745c4d0..e9c08fd7e6 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginCache.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionFramework/TestPluginCache.cs @@ -306,6 +306,20 @@ public void UpdateExtensions(IEnumerable additionalExtensionsPath, bool } } + /// + /// Clear test plugin cache + /// + public void ClearExtensions() + { + this.pathToExtensions = null; + this.TestExtensions?.InvalidateCache(); + + if (EqtTrace.IsVerboseEnabled) + { + EqtTrace.Verbose("TestPluginCache: Clearing test plugin cache"); + } + } + #endregion #region Utility methods diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestPlatform.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestPlatform.cs index 92e96286ae..5475c0ce6c 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestPlatform.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/ITestPlatform.cs @@ -18,6 +18,11 @@ public interface ITestPlatform : IDisposable /// Specifies whether only well known extensions should be loaded. void UpdateExtensions(IEnumerable pathToAdditionalExtensions, bool loadOnlyWellKnownExtensions); + /// + /// Clear the extension + /// + void ClearExtensions(); + /// /// Creates a discovery request /// diff --git a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs index 984e6a8caa..135c04cba0 100644 --- a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs +++ b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs @@ -180,6 +180,9 @@ ex is SettingsException || { this.testLoggerManager?.UnregisterDiscoveryEvents(discoveryRequest); discoveryEventsRegistrar?.UnregisterDiscoveryEvents(discoveryRequest); + + // Clear the extensions once request is complete, so that new request will not use extension from last request. + this.testPlatform.ClearExtensions(); } } @@ -340,6 +343,9 @@ ex is SettingsException || this.testLoggerManager.UnregisterTestRunEvents(testRunRequest); this.testRunResultAggregator.UnregisterTestRunEvents(testRunRequest); testRunEventsRegistrar?.UnregisterTestRunEvents(testRunRequest); + + // Clear the extensions once request is complete, so that new request will not use extension from last request. + this.testPlatform.ClearExtensions(); } } diff --git a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/TestPluginCacheTests.cs b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/TestPluginCacheTests.cs index 8a6ad3c8a8..d85f0ceb4c 100644 --- a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/TestPluginCacheTests.cs +++ b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/TestPluginCacheTests.cs @@ -127,10 +127,46 @@ public void UpdateAdditionalExtensionsShouldUpdatePathsThatDoNotExist() Assert.AreEqual(1, updatedExtensions.Count()); } - [Ignore] [TestMethod] public void UpdateAdditionalExtensionsShouldResetExtensionsDiscoveredFlag() { + SetupMockAdditionalPathExtensions(); + + TestPluginCache.Instance.DiscoverTestExtensions(TestPlatformConstants.TestAdapterRegexPattern); + + Assert.IsTrue(TestPluginCache.Instance.TestExtensions.AreTestDiscoverersCached); + + // update extensions + var additionalExtensions = new List { "foo.dll" }; + TestPluginCache.Instance.UpdateExtensions(additionalExtensions, true); + + Assert.IsFalse(TestPluginCache.Instance.TestExtensions.AreTestDiscoverersCached); + } + + [TestMethod] + public void ClearExtensionsShouldClearExtensionPath() + { + var additionalExtensions = new List { "foo.dll" }; + TestPluginCache.Instance.UpdateExtensions(additionalExtensions, true); + + TestPluginCache.Instance.ClearExtensions(); + + Assert.IsNull(TestPluginCache.Instance.PathToExtensions); + } + + [TestMethod] + public void ClearExtensionsShouldClearTestExtensionsCache() + { + SetupMockAdditionalPathExtensions(); + + TestPluginCache.Instance.DiscoverTestExtensions(TestPlatformConstants.TestAdapterRegexPattern); + + Assert.IsTrue(TestPluginCache.Instance.TestExtensions.AreTestDiscoverersCached); + + // Clear cache + TestPluginCache.Instance.ClearExtensions(); + + Assert.IsFalse(TestPluginCache.Instance.TestExtensions.AreTestDiscoverersCached); } #endregion diff --git a/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs b/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs index 0de6a826a3..64294dfe68 100644 --- a/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs +++ b/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs @@ -137,6 +137,23 @@ public void DiscoverTestsShouldReadTheBatchSizeFromSettingsAndSetItForDiscoveryC Assert.AreEqual(15, actualDiscoveryCriteria.FrequencyOfDiscoveredTestsEvent); } + [TestMethod] + public void DiscoverTestsShouldClearCacheAfterDiscovery() + { + var payload = new DiscoveryRequestPayload() + { + Sources = new List() { "a" }, + }; + + var mockDiscoveryRequest = new Mock(); + this.mockTestPlatform.Setup(mt => mt.CreateDiscoveryRequest(It.IsAny(), It.IsAny())).Callback( + (DiscoveryCriteria discoveryCriteria, ProtocolConfig config) => { }).Returns(mockDiscoveryRequest.Object); + + var success = this.testRequestManager.DiscoverTests(payload, new Mock().Object, It.IsAny()); + + this.mockTestPlatform.Verify(tp => tp.ClearExtensions(), Times.Once); + } + [TestMethod] public void DiscoverTestsShouldCallTestPlatformAndSucceed() { @@ -198,10 +215,10 @@ public void CancelTestRunShouldWaitForCreateTestRunRequest() this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny())).Callback( (TestRunCriteria runCriteria, ProtocolConfig config) => { - Thread.Sleep(1); - createRunRequestTime = sw.ElapsedMilliseconds; - observedCriteria = runCriteria; - }).Returns(mockRunRequest.Object); + Thread.Sleep(1); + createRunRequestTime = sw.ElapsedMilliseconds; + observedCriteria = runCriteria; + }).Returns(mockRunRequest.Object); mockRunRequest.Setup(mr => mr.CancelAsync()).Callback(() => { @@ -290,6 +307,22 @@ public void RunTestsShouldReadTheBatchSizeFromSettingsAndSetItForTestRunCriteria Assert.AreEqual(15, actualTestRunCriteria.FrequencyOfRunStatsChangeEvent); } + [TestMethod] + public void RunTestsShouldCallClearExtensionsAfterRun() + { + var payload = new TestRunRequestPayload() + { + Sources = new List() { "a" }, + }; + + var mockDiscoveryRequest = new Mock(); + this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny())).Callback( + (TestRunCriteria runCriteria, ProtocolConfig config) => { }).Returns(mockDiscoveryRequest.Object); + + var success = this.testRequestManager.RunTests(payload, new Mock().Object, new Mock().Object, It.IsAny()); + this.mockTestPlatform.Verify(tp => tp.ClearExtensions(), Times.Once); + } + [TestMethod] public void RunTestsWithSourcesShouldCallTestPlatformAndSucceed() { @@ -597,7 +630,7 @@ public void RunTestsShouldUpdateDesignModeIfRunnerIsInDesignMode(bool designMode var payload = new TestRunRequestPayload { RunSettings = runsettings, - Sources = new List {"c:\\testproject.dll"} + Sources = new List { "c:\\testproject.dll" } }; this.commandLineOptions.IsDesignMode = designModeValue; @@ -612,7 +645,7 @@ private static DiscoveryRequestPayload CreateDiscoveryPayload(string runsettings var discoveryPayload = new DiscoveryRequestPayload { RunSettings = runsettings, - Sources = new[] {"c:\\testproject.dll"} + Sources = new[] { "c:\\testproject.dll" } }; return discoveryPayload; }