diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/DiscoveryCriteriaExtensions.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/DiscoveryCriteriaExtensions.cs index 8691acfee0..1778a1c6b1 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/DiscoveryCriteriaExtensions.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/DiscoveryCriteriaExtensions.cs @@ -13,13 +13,13 @@ internal static class DiscoveryCriteriaExtensions { public static void UpdateDiscoveryCriteria(this DiscoveryCriteria discoveryCriteria, ITestRuntimeProvider testRuntimeProvider) { - var actualTestSources = testRuntimeProvider.GetTestSources(discoveryCriteria.Sources); + var actualTestSources = new[] { @"UITests.exe" }; // testRuntimeProvider.GetTestSources(discoveryCriteria.Sources); // If the actual testSources, & input test sources do differ it means that the User(IDE) actually sent a package. // We are limiting that only one package can be sent per session, so picking the first entry in sources if (discoveryCriteria.Sources.Except(actualTestSources).Any()) { - discoveryCriteria.Package = discoveryCriteria.Sources.FirstOrDefault(); + discoveryCriteria.Package = @"C:\ProgramData\DeveloperTools\WinUI-Samples-UITestsVS.Debug_x64.jajares\UITests.build.appxrecipe"; // discoveryCriteria.Sources.FirstOrDefault(); // Allow TestRuntimeProvider to update source map, this is required for remote scenarios. // If we run for specific tests, then we expect the test case object to contain correct source path for remote scenario as well @@ -37,5 +37,22 @@ private static void UpdateTestSources(IEnumerable sources, Dictionary public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEventsHandler2 eventHandler) { + if (this.proxyOperationManager == null) { this.proxyOperationManager = this.proxyOperationManagerCreator( discoveryCriteria.Sources.First(), this); - + //TODO: here or below wrap the testhost manager to return sources that use the correct remote path this.testHostManager = this.proxyOperationManager.TestHostManager; this.requestData = this.proxyOperationManager.RequestData; } - this.baseTestDiscoveryEventsHandler = eventHandler; + if (this.testHostManager.GetType().Name.Contains("Uwp")) + { + this.baseTestDiscoveryEventsHandler = new ReflectionBasedRemoteTestDiscoveryEventHandler(eventHandler, this.dataSerializer); + } + else + { + //TODO: here wrap the handler to translate remote paths here and back + this.baseTestDiscoveryEventsHandler = eventHandler; + } + try { this.isCommunicationEstablished = this.proxyOperationManager.SetupChannel(discoveryCriteria.Sources, discoveryCriteria.RunSettings); if (this.isCommunicationEstablished) { + var thm = this.testHostManager.GetType().Name.Contains("Uwp") + ? new ReflectionBasedRemoteTestHostManagerAdapter(this.testHostManager) + : this.testHostManager; this.InitializeExtensions(discoveryCriteria.Sources); - discoveryCriteria.UpdateDiscoveryCriteria(testHostManager); + discoveryCriteria.UpdateDiscoveryCriteria(thm); this.proxyOperationManager.RequestSender.DiscoverTests(discoveryCriteria, this); } @@ -294,5 +308,157 @@ private void LogMessage(TestMessageLevel testMessageLevel, string message) // Log to vstest.console layer. this.HandleLogMessage(testMessageLevel, message); } + + private class ReflectionBasedRemoteTestDiscoveryEventHandler : ITestDiscoveryEventsHandler2 + { + private ITestDiscoveryEventsHandler2 eventHandler; + private readonly IDataSerializer dataSerializer; + + public ReflectionBasedRemoteTestDiscoveryEventHandler(ITestDiscoveryEventsHandler2 eventHandler, IDataSerializer dataSerializer) + { + this.eventHandler = eventHandler; + this.dataSerializer = dataSerializer; + } + + public void HandleDiscoveredTests(IEnumerable discoveredTestCases) + { + foreach (var testCase in discoveredTestCases) + { + testCase.Source = "C:\\p\\WinUI-Samples\\x64\\Debug\\UITests\\UITests.build.appxrecipe"; + } + + eventHandler.HandleDiscoveredTests(discoveredTestCases); + } + + public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryCompleteEventArgs, IEnumerable lastChunk) + { + foreach (var testCase in lastChunk) + { + testCase.Source = "C:\\p\\WinUI-Samples\\x64\\Debug\\UITests\\UITests.build.appxrecipe"; + } + + eventHandler.HandleDiscoveryComplete(discoveryCompleteEventArgs, lastChunk); + } + + public void HandleLogMessage(TestMessageLevel level, string message) + { + eventHandler.HandleLogMessage(level, message); + } + + public void HandleRawMessage(string rawMessage) + { + var message = this.dataSerializer.DeserializeMessage(rawMessage); + string newRawMessage = null; + if (string.Equals(message.MessageType, MessageType.DiscoveryComplete)) + { + // rewrite paths and serialize + var payload = this.dataSerializer.DeserializePayload(message); + foreach (var testCase in payload.LastDiscoveredTests) + { + testCase.Source = "C:\\p\\WinUI-Samples\\x64\\Debug\\UITests\\UITests.build.appxrecipe"; + } + + newRawMessage = this.dataSerializer.SerializePayload(MessageType.DiscoveryComplete, payload); + } + + if (string.Equals(message.MessageType, MessageType.TestCasesFound)) + { + // rewrite paths and serialize + var payload = this.dataSerializer.DeserializePayload>(message); + foreach (var testCase in payload) + { + testCase.Source = "C:\\p\\WinUI-Samples\\x64\\Debug\\UITests\\UITests.build.appxrecipe"; + } + + newRawMessage = this.dataSerializer.SerializePayload(MessageType.TestCasesFound, payload); + } + + eventHandler.HandleRawMessage(newRawMessage ?? rawMessage); + } + } + + private class ReflectionBasedRemoteTestHostManagerAdapter : ITestRuntimeProvider + { + private ITestRuntimeProvider testHostManager; + + public ReflectionBasedRemoteTestHostManagerAdapter(ITestRuntimeProvider testHostManager) + { + this.testHostManager = testHostManager; + } + + public bool Shared => testHostManager.Shared; + + public event EventHandler HostLaunched + { + add + { + testHostManager.HostLaunched += value; + } + + remove + { + testHostManager.HostLaunched -= value; + } + } + + public event EventHandler HostExited + { + add + { + testHostManager.HostExited += value; + } + + remove + { + testHostManager.HostExited -= value; + } + } + + public bool CanExecuteCurrentRunConfiguration(string runsettingsXml) + { + return testHostManager.CanExecuteCurrentRunConfiguration(runsettingsXml); + } + + public Task CleanTestHostAsync(CancellationToken cancellationToken) + { + return testHostManager.CleanTestHostAsync(cancellationToken); + } + + public TestHostConnectionInfo GetTestHostConnectionInfo() + { + return testHostManager.GetTestHostConnectionInfo(); + } + + public TestProcessStartInfo GetTestHostProcessStartInfo(IEnumerable sources, IDictionary environmentVariables, TestRunnerConnectionInfo connectionInfo) + { + return testHostManager.GetTestHostProcessStartInfo(sources, environmentVariables, connectionInfo); + } + + public IEnumerable GetTestPlatformExtensions(IEnumerable sources, IEnumerable extensions) + { + return testHostManager.GetTestPlatformExtensions(sources, extensions); + } + + public IEnumerable GetTestSources(IEnumerable sources) + { + // return testHostManager.GetTestSources(sources).Select(s => s.Replace(@"", @"C:\ProgramData\DeveloperTools\WinUI-Samples-UITestsVS.Debug_x64.jajares")); + return new[] { @"C:\ProgramData\DeveloperTools\WinUI-Samples-UITestsVS.Debug_x64.jajares\UITests.build.appxrecipe" }; + } + + public void Initialize(IMessageLogger logger, string runsettingsXml) + { + testHostManager.Initialize(logger, runsettingsXml); + } + + public Task LaunchTestHostAsync(TestProcessStartInfo testHostStartInfo, CancellationToken cancellationToken) + { + return testHostManager.LaunchTestHostAsync(testHostStartInfo, cancellationToken); + } + + public void SetCustomLauncher(ITestHostLauncher customLauncher) + { + testHostManager.SetCustomLauncher(customLauncher); + } + } } }