diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/IDeploymentAwareTestRequestHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/IDeploymentAwareTestRequestHandler.cs new file mode 100644 index 0000000000..fce03ff6ff --- /dev/null +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/IDeploymentAwareTestRequestHandler.cs @@ -0,0 +1,15 @@ +// 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.VisualStudio.TestPlatform.CommunicationUtilities; + +/// +/// This interface holds additional values for a request handler when rewriting paths is used. +/// This is in case when --local-path and --remote-path parameters are provided and testhost is running +/// in a remote deployment. This interface is used only to avoid changes to public API of TestRequestHandler. +/// +internal interface IDeploymentAwareTestRequestHandler +{ + string LocalPath { get; set; } + string RemotePath { get; set; } +} \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/IPathConverter.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/IPathConverter.cs new file mode 100644 index 0000000000..3a310e8ca3 --- /dev/null +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/IPathConverter.cs @@ -0,0 +1,36 @@ +// 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.VisualStudio.TestPlatform.CommunicationUtilities; + +using System.Collections.Generic; +using System.Collections.ObjectModel; + +using ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + +internal interface IPathConverter +{ + string? UpdatePath(string? path, PathConversionDirection updateDirection); + + IEnumerable UpdatePaths(IEnumerable paths, PathConversionDirection updateDirection); + + TestCase UpdateTestCase(TestCase testCase, PathConversionDirection updateDirection); + + IEnumerable UpdateTestCases(IEnumerable testCases, PathConversionDirection updateDirection); + + TestRunCompleteEventArgs UpdateTestRunCompleteEventArgs(TestRunCompleteEventArgs testRunCompleteEventArgs, PathConversionDirection updateDirection); + + TestRunChangedEventArgs UpdateTestRunChangedEventArgs(TestRunChangedEventArgs testRunChangedArgs, PathConversionDirection updateDirection); + + Collection UpdateAttachmentSets(Collection attachmentSets, PathConversionDirection updateDirection); + + ICollection UpdateAttachmentSets(ICollection attachmentSets, PathConversionDirection updateDirection); + + DiscoveryCriteria UpdateDiscoveryCriteria(DiscoveryCriteria discoveryCriteria, PathConversionDirection updateDirection); + + TestRunCriteriaWithSources UpdateTestRunCriteriaWithSources(TestRunCriteriaWithSources testRunCriteriaWithSources, PathConversionDirection updateDirection); + + TestRunCriteriaWithTests UpdateTestRunCriteriaWithTests(TestRunCriteriaWithTests testRunCriteriaWithTests, PathConversionDirection updateDirection); +} diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/NullPathConverter.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/NullPathConverter.cs new file mode 100644 index 0000000000..2d375688a4 --- /dev/null +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/NullPathConverter.cs @@ -0,0 +1,42 @@ +// 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.VisualStudio.TestPlatform.CommunicationUtilities; + +using System.Collections.Generic; +using ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; +using System.Collections.ObjectModel; +using System; + +internal class NullPathConverter : IPathConverter +{ + private static readonly Lazy LazyInstance = new(() => new NullPathConverter()); + + private NullPathConverter() { } + + public static NullPathConverter Instance => LazyInstance.Value; + + Collection IPathConverter.UpdateAttachmentSets(Collection attachmentSets, PathConversionDirection _) => attachmentSets; + + ICollection IPathConverter.UpdateAttachmentSets(ICollection attachmentSets, PathConversionDirection _) => attachmentSets; + + DiscoveryCriteria IPathConverter.UpdateDiscoveryCriteria(DiscoveryCriteria discoveryCriteria, PathConversionDirection _) => discoveryCriteria; + + string? IPathConverter.UpdatePath(string? path, PathConversionDirection _) => path; + + IEnumerable IPathConverter.UpdatePaths(IEnumerable paths, PathConversionDirection _) => paths; + + TestCase IPathConverter.UpdateTestCase(TestCase testCase, PathConversionDirection _) => testCase; + + IEnumerable IPathConverter.UpdateTestCases(IEnumerable testCases, PathConversionDirection _) => testCases; + + TestRunChangedEventArgs IPathConverter.UpdateTestRunChangedEventArgs(TestRunChangedEventArgs testRunChangedArgs, PathConversionDirection _) => testRunChangedArgs; + + TestRunCompleteEventArgs IPathConverter.UpdateTestRunCompleteEventArgs(TestRunCompleteEventArgs testRunCompleteEventArgs, PathConversionDirection _) => testRunCompleteEventArgs; + + TestRunCriteriaWithSources IPathConverter.UpdateTestRunCriteriaWithSources(TestRunCriteriaWithSources testRunCriteriaWithSources, PathConversionDirection _) => testRunCriteriaWithSources; + + TestRunCriteriaWithTests IPathConverter.UpdateTestRunCriteriaWithTests(TestRunCriteriaWithTests testRunCriteriaWithTests, PathConversionDirection _) => testRunCriteriaWithTests; +} diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/PathConversionDirection.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/PathConversionDirection.cs new file mode 100644 index 0000000000..a8c6591ac6 --- /dev/null +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/PathConversionDirection.cs @@ -0,0 +1,10 @@ +// 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.VisualStudio.TestPlatform.CommunicationUtilities; + +internal enum PathConversionDirection +{ + Receive, + Send +} diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/PathConverter.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/PathConverter.cs new file mode 100644 index 0000000000..7f02c971a6 --- /dev/null +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/PathConverter.cs @@ -0,0 +1,151 @@ +// 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.VisualStudio.TestPlatform.CommunicationUtilities; + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; + +using ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; +using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; + +/// +/// Converts paths in received and sent objects, to make testhost seem like it run a local test, +/// while it was in fact running a test on a remote system, in a totally different path. This is for UWP which +/// does testhost deployment. +/// The modifications here rely on combination of side-effects, and actually replacing the values, because +/// we cannot modify the properties on our public objects, and add setters. +/// +internal class PathConverter : IPathConverter +{ + // The path on this computer to which we deployed the test dll and test runner + private readonly string _deploymentPath = ""; + // The path on the remote system where test dll was originally placed, and from which we + // copied it to this system. For vstest.console, which is on the other side of this, the names + // are inverted, it sends us their local path, and thinks about our local path as remote. + private readonly string _originalPath = ""; + + public PathConverter(string originalPath!!, string deploymentPath!!, IFileHelper fileHelper!!) + { + _originalPath = fileHelper.GetFullPath(originalPath).TrimEnd('\\').TrimEnd('/') + Path.DirectorySeparatorChar; + _deploymentPath = fileHelper.GetFullPath(deploymentPath).TrimEnd('\\').TrimEnd('/') + Path.DirectorySeparatorChar; + } + + public string? UpdatePath(string? path, PathConversionDirection updateDirection) + { + if (path == null) + return path; + + string find; + string replaceWith; + if (updateDirection == PathConversionDirection.Receive) + { + // Request is incoming, the path that is local to the sender (for us that is "remote" path) + // needs to be replaced with our path + find = _originalPath; + replaceWith = _deploymentPath; + } + else + { + find = _deploymentPath; + replaceWith = _originalPath; + } + + var result = path?.Replace(find, replaceWith); + return result; + } + + public IEnumerable UpdatePaths(IEnumerable paths!!, PathConversionDirection updateDirection) + { + return paths.Select(i => UpdatePath(i, updateDirection)).ToList(); + } + + public TestCase UpdateTestCase(TestCase testCase!!, PathConversionDirection updateDirection) + { + testCase.CodeFilePath = UpdatePath(testCase.CodeFilePath, updateDirection); + testCase.Source = UpdatePath(testCase.Source, updateDirection); + return testCase; + } + + public IEnumerable UpdateTestCases(IEnumerable testCases!!, PathConversionDirection updateDirection) + { + testCases.ToList().ForEach(tc => UpdateTestCase(tc, updateDirection)); + return testCases; + } + + public TestRunCompleteEventArgs UpdateTestRunCompleteEventArgs(TestRunCompleteEventArgs testRunCompleteEventArgs!!, PathConversionDirection updateDirection) + { + UpdateAttachmentSets(testRunCompleteEventArgs.AttachmentSets, updateDirection); + return testRunCompleteEventArgs; + } + + public TestRunChangedEventArgs UpdateTestRunChangedEventArgs(TestRunChangedEventArgs testRunChangedArgs!!, PathConversionDirection updateDirection) + { + UpdateTestResults(testRunChangedArgs.NewTestResults, updateDirection); + UpdateTestCases(testRunChangedArgs.ActiveTests, updateDirection); + return testRunChangedArgs; + } + + public Collection UpdateAttachmentSets(Collection attachmentSets!!, PathConversionDirection updateDirection) + { + attachmentSets.ToList().ForEach(i => UpdateAttachmentSet(i, updateDirection)); + return attachmentSets; + } + + public ICollection UpdateAttachmentSets(ICollection attachmentSets!!, PathConversionDirection updateDirection) + { + attachmentSets.ToList().ForEach(i => UpdateAttachmentSet(i, updateDirection)); + return attachmentSets; + } + + private AttachmentSet UpdateAttachmentSet(AttachmentSet attachmentSet!!, PathConversionDirection updateDirection) + { + attachmentSet.Attachments.ToList().ForEach(a => UpdateAttachment(a, updateDirection)); + return attachmentSet; + } + + private UriDataAttachment UpdateAttachment(UriDataAttachment attachment!!, PathConversionDirection _) + { + // todo: convert uri? https://github.com/microsoft/vstest/issues/3367 + return attachment; + } + + private IEnumerable UpdateTestResults(IEnumerable testResults!!, PathConversionDirection updateDirection) + { + foreach (var tr in testResults) + { + UpdateAttachmentSets(tr.Attachments, updateDirection); + UpdateTestCase(tr.TestCase, updateDirection); + } + return testResults; + } + + public DiscoveryCriteria UpdateDiscoveryCriteria(DiscoveryCriteria discoveryCriteria!!, PathConversionDirection updateDirection) + { + discoveryCriteria.Package = UpdatePath(discoveryCriteria.Package, updateDirection); + foreach (var adapter in discoveryCriteria.AdapterSourceMap.ToList()) + { + var updatedPaths = UpdatePaths(adapter.Value, updateDirection); + discoveryCriteria.AdapterSourceMap[adapter.Key] = updatedPaths; + } + return discoveryCriteria; + } + + public TestRunCriteriaWithSources UpdateTestRunCriteriaWithSources(TestRunCriteriaWithSources testRunCriteriaWithSources!!, PathConversionDirection updateDirection) + { + testRunCriteriaWithSources.AdapterSourceMap.ToList().ForEach(adapter => testRunCriteriaWithSources.AdapterSourceMap[adapter.Key] = UpdatePaths(adapter.Value, updateDirection)); + var package = UpdatePath(testRunCriteriaWithSources.Package, updateDirection); + return new TestRunCriteriaWithSources(testRunCriteriaWithSources.AdapterSourceMap, package, testRunCriteriaWithSources.RunSettings, testRunCriteriaWithSources.TestExecutionContext); + } + + public TestRunCriteriaWithTests UpdateTestRunCriteriaWithTests(TestRunCriteriaWithTests testRunCriteriaWithTests!!, PathConversionDirection updateDirection) + { + var tests = UpdateTestCases(testRunCriteriaWithTests.Tests, updateDirection); + var package = UpdatePath(testRunCriteriaWithTests.Package, updateDirection); + return new TestRunCriteriaWithTests(tests, package, testRunCriteriaWithTests.RunSettings, testRunCriteriaWithTests.TestExecutionContext); + } +} diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs index 461c405002..17a7f48661 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs @@ -23,8 +23,10 @@ namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; using CrossPlatResources = CrossPlatEngine.Resources.Resources; using ObjectModelConstants = TestPlatform.ObjectModel.Constants; +using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; +using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; -public class TestRequestHandler : ITestRequestHandler +public class TestRequestHandler : ITestRequestHandler, IDeploymentAwareTestRequestHandler { private int _protocolVersion = 1; @@ -39,14 +41,18 @@ public class TestRequestHandler : ITestRequestHandler private ICommunicationChannel _channel; private readonly JobQueue _jobQueue; + private readonly IFileHelper _fileHelper; private readonly ManualResetEventSlim _requestSenderConnected; private readonly ManualResetEventSlim _testHostManagerFactoryReady; private readonly ManualResetEventSlim _sessionCompleted; private Action _onLaunchAdapterProcessWithDebuggerAttachedAckReceived; private Action _onAttachDebuggerAckRecieved; + private IPathConverter _pathConverter; private Exception _messageProcessingUnrecoverableError; public TestHostConnectionInfo ConnectionInfo { get; set; } + string IDeploymentAwareTestRequestHandler.LocalPath { get; set; } + string IDeploymentAwareTestRequestHandler.RemotePath { get; set; } /// /// Initializes a new instance of the . @@ -72,6 +78,9 @@ protected TestRequestHandler( _onLaunchAdapterProcessWithDebuggerAttachedAckReceived = onLaunchAdapterProcessWithDebuggerAttachedAckReceived; _onAttachDebuggerAckRecieved = onAttachDebuggerAckRecieved; _jobQueue = jobQueue; + + _fileHelper = new FileHelper(); + _pathConverter = NullPathConverter.Instance; } protected TestRequestHandler(IDataSerializer dataSerializer, ICommunicationEndpointFactory communicationEndpointFactory) @@ -91,11 +100,21 @@ protected TestRequestHandler(IDataSerializer dataSerializer, ICommunicationEndpo 25000000, true, (message) => EqtTrace.Error(message)); + + _fileHelper = new FileHelper(); + _pathConverter = NullPathConverter.Instance; } /// public virtual void InitializeCommunication() { + if (this is IDeploymentAwareTestRequestHandler self + && !string.IsNullOrWhiteSpace(self.LocalPath) + && !string.IsNullOrWhiteSpace(self.RemotePath)) + { + _pathConverter = new PathConverter(self.LocalPath, self.RemotePath, _fileHelper); + } + _communicationEndPoint = _communicationEndpointFactory.Create(ConnectionInfo.Role); _communicationEndPoint.Connected += (sender, connectedArgs) => { @@ -143,14 +162,16 @@ public void Close() /// public void SendTestCases(IEnumerable discoveredTestCases) { - var data = _dataSerializer.SerializePayload(MessageType.TestCasesFound, discoveredTestCases, _protocolVersion); + var updatedTestCases = _pathConverter.UpdateTestCases(discoveredTestCases, PathConversionDirection.Send); + var data = _dataSerializer.SerializePayload(MessageType.TestCasesFound, updatedTestCases, _protocolVersion); SendData(data); } /// public void SendTestRunStatistics(TestRunChangedEventArgs testRunChangedArgs) { - var data = _dataSerializer.SerializePayload(MessageType.TestRunStatsChange, testRunChangedArgs, _protocolVersion); + var updatedTestRunChangedEventArgs = _pathConverter.UpdateTestRunChangedEventArgs(testRunChangedArgs, PathConversionDirection.Send); + var data = _dataSerializer.SerializePayload(MessageType.TestRunStatsChange, updatedTestRunChangedEventArgs, _protocolVersion); SendData(data); } @@ -181,16 +202,16 @@ public void SendExecutionComplete( curentArgs.IsCanceled, curentArgs.IsAborted, _messageProcessingUnrecoverableError, - curentArgs.AttachmentSets, curentArgs.InvokedDataCollectors, curentArgs.ElapsedTimeInRunningTests + _pathConverter.UpdateAttachmentSets(curentArgs.AttachmentSets, PathConversionDirection.Send), curentArgs.InvokedDataCollectors, curentArgs.ElapsedTimeInRunningTests ); } var data = _dataSerializer.SerializePayload( MessageType.ExecutionComplete, new TestRunCompletePayload { - TestRunCompleteArgs = testRunCompleteArgs, - LastRunTests = lastChunkArgs, - RunAttachments = runContextAttachments, + TestRunCompleteArgs = _pathConverter.UpdateTestRunCompleteEventArgs(testRunCompleteArgs, PathConversionDirection.Send), + LastRunTests = _pathConverter.UpdateTestRunChangedEventArgs(lastChunkArgs, PathConversionDirection.Send), + RunAttachments = _pathConverter.UpdateAttachmentSets(runContextAttachments, PathConversionDirection.Send), ExecutorUris = executorUris }, _protocolVersion); @@ -205,7 +226,7 @@ public void DiscoveryComplete(DiscoveryCompleteEventArgs discoveryCompleteEventA new DiscoveryCompletePayload { TotalTests = discoveryCompleteEventArgs.TotalCount, - LastDiscoveredTests = discoveryCompleteEventArgs.IsAborted ? null : lastChunk, + LastDiscoveredTests = discoveryCompleteEventArgs.IsAborted ? null : _pathConverter.UpdateTestCases(lastChunk, PathConversionDirection.Send), IsAborted = discoveryCompleteEventArgs.IsAborted, Metrics = discoveryCompleteEventArgs.Metrics, FullyDiscoveredSources = discoveryCompleteEventArgs.FullyDiscoveredSources, @@ -335,7 +356,7 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec { _testHostManagerFactoryReady.Wait(); var discoveryEventsHandler = new TestDiscoveryEventHandler(this); - var pathToAdditionalExtensions = _dataSerializer.DeserializePayload>(message); + var pathToAdditionalExtensions = _pathConverter.UpdatePaths(_dataSerializer.DeserializePayload>(message), PathConversionDirection.Receive); Action job = () => { EqtTrace.Info("TestRequestHandler.OnMessageReceived: Running job '{0}'.", message.MessageType); @@ -359,7 +380,8 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec { _testHostManagerFactoryReady.Wait(); var discoveryEventsHandler = new TestDiscoveryEventHandler(this); - var discoveryCriteria = _dataSerializer.DeserializePayload(message); + var discoveryCriteria = _pathConverter.UpdateDiscoveryCriteria(_dataSerializer.DeserializePayload(message), PathConversionDirection.Receive); + Action job = () => { EqtTrace.Info("TestRequestHandler.OnMessageReceived: Running job '{0}'.", message.MessageType); @@ -385,7 +407,7 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec { _testHostManagerFactoryReady.Wait(); var testInitializeEventsHandler = new TestInitializeEventsHandler(this); - var pathToAdditionalExtensions = _dataSerializer.DeserializePayload>(message); + var pathToAdditionalExtensions = _pathConverter.UpdatePaths(_dataSerializer.DeserializePayload>(message), PathConversionDirection.Receive); Action job = () => { EqtTrace.Info("TestRequestHandler.OnMessageReceived: Running job '{0}'.", message.MessageType); @@ -409,7 +431,7 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec { var testRunEventsHandler = new TestRunEventsHandler(this); _testHostManagerFactoryReady.Wait(); - var testRunCriteriaWithSources = _dataSerializer.DeserializePayload(message); + var testRunCriteriaWithSources = _pathConverter.UpdateTestRunCriteriaWithSources(_dataSerializer.DeserializePayload(message), PathConversionDirection.Receive); Action job = () => { EqtTrace.Info("TestRequestHandler.OnMessageReceived: Running job '{0}'.", message.MessageType); @@ -440,8 +462,7 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec { var testRunEventsHandler = new TestRunEventsHandler(this); _testHostManagerFactoryReady.Wait(); - var testRunCriteriaWithTests = - _dataSerializer.DeserializePayload(message); + var testRunCriteriaWithTests = _pathConverter.UpdateTestRunCriteriaWithTests(_dataSerializer.DeserializePayload(message), PathConversionDirection.Receive); Action job = () => { diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Friends.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Friends.cs index b52f4adf02..0270330197 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Friends.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Friends.cs @@ -9,7 +9,32 @@ [assembly: InternalsVisibleTo("datacollector, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("datacollector.PlatformTests, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("testhost, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net452, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net46, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net461, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net462, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net47, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net471, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net472, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net48, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("testhost.x86, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net452.x86, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net46.x86, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net461.x86, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net462.x86, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net47.x86, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net471.x86, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net472.x86, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net48.x86, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.arm64, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net452.arm64, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net46.arm64, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net461.arm64, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net462.arm64, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net47.arm64, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net471.arm64, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net472.arm64, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("testhost.net48.arm64, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("vstest.console, PublicKey = 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] diff --git a/src/testhost.x86/DefaultEngineInvoker.cs b/src/testhost.x86/DefaultEngineInvoker.cs index 0c950fb006..a63a1da786 100644 --- a/src/testhost.x86/DefaultEngineInvoker.cs +++ b/src/testhost.x86/DefaultEngineInvoker.cs @@ -61,6 +61,13 @@ internal class DefaultEngineInvoker : private const string TelemetryOptedIn = "--telemetryoptedin"; + // this path is where the sources were originally located on the source system + // we are in a testhost that runs on the remote system, so this local path is + // actually remote for us and the remote path is local for us. + private const string LocalPath = "--local-path"; + + private const string RemotePath = "--remote-path"; + private readonly ITestRequestHandler _requestHandler; private readonly IDataCollectionTestCaseEventSender _dataCollectionTestCaseEventSender; @@ -83,6 +90,17 @@ public void Invoke(IDictionary argsDictionary) { InitializeEqtTrace(argsDictionary); + // We don't have a way to pass these values to TestRequestHandler directly + // beacuse of it's public interface, we work around that by making it implement a second interface + if (_requestHandler is IDeploymentAwareTestRequestHandler deployedHandler) + { + if (argsDictionary.ContainsKey(RemotePath) && argsDictionary.ContainsKey(LocalPath)) + { + deployedHandler.LocalPath = argsDictionary[LocalPath]; + deployedHandler.RemotePath = argsDictionary[RemotePath]; + } + } + if (EqtTrace.IsVerboseEnabled) { var version = typeof(DefaultEngineInvoker)