Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make all communication timeouts configurable. #1538

Merged
merged 17 commits into from
Apr 18, 2018

Conversation

smadala
Copy link
Contributor

@smadala smadala commented Apr 9, 2018

Description

  • There are various timeout error on slow machines. This PR address to make all the timeout
    configurable.
  • Refactor DefaultEngineInvoker.cs and Datacollector Program.cs to make them testable.

Related issue

#1544 #1361

Exxample output

PS C:\Users\samadala\src\vstest> $env:VSTEST_CONNECTION_TIMEOUT=1
PS C:\Users\samadala\src\vstest> C:\Users\samadala\src\vstest\artifacts\Debug\net451\win7-x64\vstest.console.exe C:\Users\samadala\src\vstest\test\TestAssets\SimpleTestProject\bin\Debug\net451\SimpleTestProject.dll /Inisolation
Microsoft (R) Test Execution Command Line Tool Version 15.7.0-dev
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
Microsoft.VisualStudio.TestPlatform.ObjectModel.TestPlatformException: vstest.console process failed to connect to testhost process after 1 seconds. This may occur due to machine slowness, please set environment variable VSTEST_CONNECTION_TIMEOUT to increase timeout.
   at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyOperationManager.HandleConnectionFailure(Boolean connected, Int32 connTimeout)
   at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyOperationManager.SetupChannel(IEnumerable`1 sources, CancellationToken cancellationToken)
   at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyExecutionManager.StartTestRun(TestRunCriteria testRunCriteria, ITestRunEventsHandler eventHandler)

@smadala smadala changed the title [WIP] Make all communication timeout configurable. Make all communication timeout configurable. Apr 11, 2018
}

return isValueSet;
}
Copy link
Contributor

@singhsarab singhsarab Apr 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not required in Abstraction.
For testing, either have EnvironmentHelper or directly use it in the tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

/// <summary>
/// Environment variable name to increase communication timeouts between processes.
/// </summary>
public const string VstestTimeoutIncreaseByTimes = "VSTEST_TIMEOUT_INCREASE_BY_TIMES";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VSTEST_TIMEOUT_INCREASE_BY_TIMES [](start = 60, length = 32)

How about VSTEST_CONNECTION_TIMEOUT?
We should have a simple settings, also make it consistent across

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, Done.

<body>
<trans-unit id="DataCollectorFailedToConnetToVSTestConsole">
<source>Datacollector process failed to connect to vstest.console in {0} milliseconds, Set enviroment variable {1} to increase timeout.</source>
<target state="new">Datacollector process failed to connect to vstest.console in {0} milliseconds, Set enviroment variable {1} to increase timeout.</target>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datacollector process failed to connect to vstest.console in {0} milliseconds [](start = 28, length = 77)

Datacollector process failed to connect to vstest.console in {0} milliseconds. Please set environment variable {1} to increase the connection timeout.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specify time in Seconds, & take input in seconds

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -0,0 +1,155 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we create a new class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For testing refactored it.

@smadala smadala changed the title Make all communication timeout configurable. Make all communication timeouts configurable. Apr 17, 2018
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to add more in CoreUtilities dll? can we move this to Testplatform.Utilities?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CoreUtilities have basic utilities on BCL. TestPlatform.Utilities has OM + BCL Utilities.

using System;
using ObjectModel;

public class EnvironmentHelper
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is an IEnvironment Interface in platform abstractions, should it not move there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will go for PlatformAbstration if there is need to do #if defs. This function not required that.

@@ -207,20 +206,22 @@ public void Initialize()
this.dataCollectionProcessId = this.dataCollectionLauncher.LaunchDataCollector(null, this.GetCommandLineArguments(this.dataCollectionPort));
EqtTrace.Info("ProxyDataCollectionManager.Initialize: Launched datacollector processId: {0} port: {1}", this.dataCollectionProcessId, this.dataCollectionPort);

ChangeConnectionTimeoutIfRequired(dataCollectionProcessId);
var connectionTimeout = GetConnectionTimeout(dataCollectionProcessId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please use this, just to follow current coding convention

/// <param name="clientConnectionTimeout">Client Connection Timeout.</param>
protected ProxyOperationManager(IRequestData requestData, ITestRequestSender requestSender, ITestRuntimeProvider testHostManager, int clientConnectionTimeout)
/// <param name="processHelper">IProcessHelper implementation. </param>
internal ProxyOperationManager(IRequestData requestData,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this.


this.mockRequestSender.Setup(rs => rs.WaitForRequestHandlerConnection(100000)).Returns(true);
this.testOperationManager.SetupChannel(Enumerable.Empty<string>(), CancellationToken.None);

this.mockRequestSender.Verify(rs => rs.WaitForRequestHandlerConnection(100000), Times.Exactly(1));

this.connectionTimeout = 400;
this.connectionTimeout = EnvironmentHelper.DefaultConnectionTimeout;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this


this.testOperationManager.SetupChannel(Enumerable.Empty<string>(), CancellationToken.None);

this.mockRequestSender.Verify(rs => rs.WaitForRequestHandlerConnection(this.connectionTimeout), Times.Exactly(1));
this.mockRequestSender.Verify(rs => rs.WaitForRequestHandlerConnection(this.connectionTimeout));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert this exactly change

this.mockDataCollectionRequestSender.Setup(x => x.WaitForRequestHandlerConnection(timeout * 1000)).Returns(true);

this.proxyDataCollectionManager.Initialize();
Environment.SetEnvironmentVariable(ProxyDataCollectionManager.TimeoutEnvironmentVaribleName, string.Empty);
Environment.SetEnvironmentVariable(EnvironmentHelper.VstestConnectionTimeout, string.Empty);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleanup?

}

[TestMethod]
public void RunShouldTimeoutBasedOneEnvVariable()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On*

var message = Assert.ThrowsException<TestPlatformException>(() => this.dataCollectorMain.Run(args)).Message;
Assert.AreEqual(message,
string.Format(
TestPlatform.DataCollector.Resources .Resources.DataCollectorFailedToConnetToVSTestConsole,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Connect*

private Mock<IEnvironment> mockEnvironment;
private Mock<IDataCollectionRequestHandler> mockDataCollectionRequestHandler;
private DataCollectorMain dataCollectorMain;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra line*

@smadala
Copy link
Contributor Author

smadala commented Apr 18, 2018

@singhsarab @mayankbansal018 Addressed all the comments. Please have a look once more.

this.SetParentProcessExitCallback(argsDictionary);

this.requestHandler.ConnectionInfo =
DefaultEngineInvoker.GetConnectionInfo(out var endpoint, argsDictionary);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

endpoint [](start = 63, length = 8)

remove endpoint, move logging in GetConnectionInfo()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (!this.testHostLaunched || !this.RequestSender.WaitForRequestHandlerConnection(connTimeout))
{
var errorMsg = CrossPlatEngineResources.InitializationFailed;
var connected = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could repurpose this.testHostLaunched to check for connectivity error

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

{
EqtTrace.Info("TestHostManagerCallbacks.ExitCallBack: Testhost processId: {0} exited with exitcode: 0 error: '{1}'", procId, testHostProcessStdErrorStr);
}

onHostExited(new HostProviderEventArgs(testHostProcessStdErrorStr, exitCode, procId));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testHostProcessStdErrorStr [](start = 51, length = 26)

remove if check simply log exitcode

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If exit code is non-zero we are writing to error level.

public static int GetConnectionTimeout()
{
var envVarValue = Environment.GetEnvironmentVariable(EnvironmentHelper.VstestConnectionTimeout);
if (!string.IsNullOrEmpty(envVarValue) && int.TryParse(envVarValue, out int value))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if user sets a very small value say 10, should we honor it? I would say we keep 90 or 60 something as min, & users value will only be honored if it is > min val
More over here we are not even checking for -ve values

Copy link
Contributor Author

@smadala smadala Apr 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handled -ve case. Keep min value 0, giving more choice to user.

CoreUtilitiesConstants.TesthostProcessName,
CoreUtilitiesConstants.DatacollectorProcessName,
EnvironmentHelper.DefaultConnectionTimeout,
EnvironmentHelper.VstestConnectionTimeout));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have exact string match in tests.
If someone changes string in resources, these tests should catch that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants