Fix Code Coverage (#151)

This is another large code review. I want to make a few more changes, but since these changes will stand on their own, I'll hold back on making this change set any larger than it already is.
Changes in this request:
To address Microsoft/vscode-mssql#326, instead of doing taskkill on the service layer when WaitForExit is executed, we now make an educated guess at which service layer was spawned when the test starts and do a Process.Kill on it when we shut down the test.
All the perf tests have been moved into a new project. This was done to keep them easily separated from code coverage test runs. At the same time the perf tests were separated into separate classes for logical categorization. This process will likely be repeated on the stress tests. The tests can still easily be ran from Visual Studio Test Explorer
To address Microsoft/vscode-mssql#349, a new SelfCleaningFile class was created to allow for easy cleanup of temporary files generated for integration tests via using blocks.
Due to some of the refactoring done while moving the perf tests to a new project, the TestBase class had to be switched to more of a helper class style. As such, all tests that use inherit from TestBase now create a TestBase object on start via a using block. This also simplifies the cleanup at the end of the test.

* Solution for hanging code coverage runs

Code coverage runs would hang in certain scenarios if a test failed before
the service process could be spawned. The taskkill command would fail to
find the service process. The test would then wait for opencover to exit,
but it would not since the service process it had spawned would still be
running, causing the test run to hang indefinitely.

Solution was to capture the service process after it launched and
explicitly kill it when shutting down the test driver.

* Setting the test name in the propery in the class and removign the parameter from each method

* New project for perf tests

* Reworking integration tests to cleanup temp files

* Changes as per @llali review comments

* Adding copyright notices
* Renaming TestBase => TestHelper
* Renaming SelfCleaningFile => SelfCleaningTempFile
* Removing code that sets TestName property

* Fixing compilation error due to removed code
This commit is contained in:
Benjamin Russell
2016-11-18 17:46:56 -08:00
committed by GitHub
parent a54d081363
commit db1e4ae351
23 changed files with 1249 additions and 1051 deletions

View File

@@ -13,7 +13,7 @@ using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
{
public class StressTests : TestBase
public class StressTests
{
/// <summary>
/// Simulate typing by a user to stress test the language service
@@ -21,24 +21,24 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
//[Fact]
public async Task TestLanguageService()
{
string textToType =
"SELECT * FROM sys.objects GO " +
"CREATE TABLE MyTable(" +
"FirstName CHAR," +
"LastName CHAR," +
"DateOfBirth DATETIME," +
"CONSTRAINT MyTableConstraint UNIQUE (FirstName, LastName, DateOfBirth)) GO " +
"INSERT INTO MyTable (FirstName, LastName, DateOfBirth) VALUES ('John', 'Doe', '19800101') GO " +
"SELECT * FROM MyTable GO " +
"ALTER TABLE MyTable DROP CONSTRAINT MyTableConstraint GO " +
"DROP TABLE MyTable GO ";
var ownerUri = System.IO.Path.GetTempFileName();
const string textToType = "SELECT * FROM sys.objects GO " +
"CREATE TABLE MyTable(" +
"FirstName CHAR," +
"LastName CHAR," +
"DateOfBirth DATETIME," +
"CONSTRAINT MyTableConstraint UNIQUE (FirstName, LastName, DateOfBirth)) GO " +
"INSERT INTO MyTable (FirstName, LastName, DateOfBirth) VALUES ('John', 'Doe', '19800101') GO " +
"SELECT * FROM MyTable GO " +
"ALTER TABLE MyTable DROP CONSTRAINT MyTableConstraint GO " +
"DROP TABLE MyTable GO ";
try
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
using (TestHelper testHelper = new TestHelper())
{
// Connect
bool connected = await Connect(ownerUri, ConnectionTestUtils.LocalhostConnection);
Assert.True(connected, "Connection is successful");
bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection);
Assert.True(connected, "Connection was not successful");
Thread.Sleep(10000); // Wait for intellisense to warm up
@@ -50,7 +50,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
{
for (int i = 0; i < textToType.Length; i++)
{
System.IO.File.WriteAllText(ownerUri, textToType.Substring(0, i + 1));
System.IO.File.WriteAllText(queryTempFile.FilePath, textToType.Substring(0, i + 1));
var contentChanges = new TextDocumentChangeEvent[1];
contentChanges[0] = new TextDocumentChangeEvent()
@@ -78,30 +78,30 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
TextDocument = new VersionedTextDocumentIdentifier()
{
Version = ++version,
Uri = ownerUri
Uri = queryTempFile.FilePath
}
};
await RequestChangeTextDocumentNotification(changeParams);
await testHelper.RequestChangeTextDocumentNotification(changeParams);
Thread.Sleep(50);
// If we just typed a space, request/resolve completion
if (textToType[i] == ' ')
{
var completions = await RequestCompletion(ownerUri, textToType.Substring(0, i + 1), 0, i + 1);
Assert.True(completions != null && completions.Length > 0, "Completion items list is not null and not empty");
var completions = await testHelper.RequestCompletion(queryTempFile.FilePath, textToType.Substring(0, i + 1), 0, i + 1);
Assert.True(completions != null && completions.Length > 0, "Completion items list was null or empty");
Thread.Sleep(50);
var item = await RequestResolveCompletion(completions[0]);
var item = await testHelper.RequestResolveCompletion(completions[0]);
Assert.NotNull(item);
}
}
// Clear the text document
System.IO.File.WriteAllText(ownerUri, "");
System.IO.File.WriteAllText(queryTempFile.FilePath, "");
var contentChanges2 = new TextDocumentChangeEvent[1];
contentChanges2[0] = new TextDocumentChangeEvent()
@@ -129,23 +129,14 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
TextDocument = new VersionedTextDocumentIdentifier()
{
Version = ++version,
Uri = ownerUri
Uri = queryTempFile.FilePath
}
};
await RequestChangeTextDocumentNotification(changeParams2);
await testHelper.RequestChangeTextDocumentNotification(changeParams2);
}
await Disconnect(ownerUri);
}
finally
{
try
{
System.IO.File.Delete(ownerUri);
}
catch {}
WaitForExit();
await testHelper.Disconnect(queryTempFile.FilePath);
}
}
@@ -155,13 +146,16 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
//[Fact]
public async Task TestQueryExecutionService()
{
string queryToRun = "SELECT * FROM sys.all_objects GO SELECT * FROM sys.objects GO SELECT * FROM sys.tables GO SELECT COUNT(*) FROM sys.objects";
var ownerUri = System.IO.Path.GetTempFileName();
const string queryToRun = "SELECT * FROM sys.all_objects GO " +
"SELECT * FROM sys.objects GO " +
"SELECT * FROM sys.tables GO " +
"SELECT COUNT(*) FROM sys.objects";
try
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
using (TestHelper testHelper = new TestHelper())
{
// Connect
bool connected = await Connect(ownerUri, ConnectionTestUtils.LocalhostConnection);
bool connected = await testHelper.Connect(queryTempFile.FilePath, ConnectionTestUtils.LocalhostConnection);
Assert.True(connected, "Connection is successful");
// Run queries repeatedly
@@ -169,7 +163,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
stopwatch.Start();
while (stopwatch.Elapsed < TimeSpan.FromMinutes(60))
{
var queryResult = await RunQuery(ownerUri, queryToRun, 10000);
var queryResult = await testHelper.RunQuery(queryTempFile.FilePath, queryToRun, 10000);
Assert.NotNull(queryResult);
Assert.NotNull(queryResult.BatchSummaries);
@@ -179,24 +173,15 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
Assert.NotNull(queryResult.BatchSummaries[2].ResultSetSummaries);
Assert.NotNull(queryResult.BatchSummaries[3].ResultSetSummaries);
Assert.NotNull(await ExecuteSubset(ownerUri, 0, 0, 0, 7));
Assert.NotNull(await ExecuteSubset(ownerUri, 1, 0, 0, 7));
Assert.NotNull(await ExecuteSubset(ownerUri, 2, 0, 0, 7));
Assert.NotNull(await ExecuteSubset(ownerUri, 3, 0, 0, 1));
Assert.NotNull(await testHelper.ExecuteSubset(queryTempFile.FilePath, 0, 0, 0, 7));
Assert.NotNull(await testHelper.ExecuteSubset(queryTempFile.FilePath, 1, 0, 0, 7));
Assert.NotNull(await testHelper.ExecuteSubset(queryTempFile.FilePath, 2, 0, 0, 7));
Assert.NotNull(await testHelper.ExecuteSubset(queryTempFile.FilePath, 3, 0, 0, 1));
Thread.Sleep(500);
}
await Disconnect(ownerUri);
}
finally
{
try
{
System.IO.File.Delete(ownerUri);
}
catch {}
WaitForExit();
await testHelper.Disconnect(queryTempFile.FilePath);
}
}
@@ -211,7 +196,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
var connection = ConnectionTestUtils.LocalhostConnection;
connection.Connection.Pooling = false;
try
using (TestHelper testHelper = new TestHelper())
{
// Connect/disconnect repeatedly
Stopwatch stopwatch = new Stopwatch();
@@ -219,18 +204,14 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests
while (stopwatch.Elapsed < TimeSpan.FromMinutes(60))
{
// Connect
bool connected = await Connect(ownerUri, connection);
bool connected = await testHelper.Connect(ownerUri, connection);
Assert.True(connected, "Connection is successful");
// Disconnect
bool disconnected = await Disconnect(ownerUri);
bool disconnected = await testHelper.Disconnect(ownerUri);
Assert.True(disconnected, "Disconnect is successful");
}
}
finally
{
WaitForExit();
}
}
}
}