Skip to content
This repository has been archived by the owner on Jul 21, 2020. It is now read-only.

Commit

Permalink
serialize ExecutionContext before sending it to the appdomain, #136
Browse files Browse the repository at this point in the history
  • Loading branch information
sriv committed Jul 15, 2018
1 parent ec2c588 commit 70b213d
Show file tree
Hide file tree
Showing 14 changed files with 261 additions and 136 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ IntegrationTestSample/.gauge
IntegrationTestSample/logs
IntegrationTestSample/reports
.fake
TestResults.xml
*TestResults.xml
paket-files
gauge-tests
.vs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="HookExecutionProcessorTests.cs" />
<Compile Include="ExecuteStepProcessorTests.cs" />
<Compile Include="IntegrationTestsBase.cs" />
<Compile Include="RefactorHelperTests.cs" />
Expand Down
61 changes: 61 additions & 0 deletions Runner.IntegrationTests/HookExecutionProcessorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2015 ThoughtWorks, Inc.
//
// This file is part of Gauge-CSharp.
//
// Gauge-CSharp is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Gauge-CSharp is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Gauge-CSharp. If not, see <http://www.gnu.org/licenses/>.

using Gauge.CSharp.Runner.Processors;
using Gauge.Messages;
using NUnit.Framework;

namespace Gauge.CSharp.Runner.IntegrationTests
{
public class HookExecutionProcessorTests : IntegrationTestsBase
{
[Test]
public void ShouldPasssExecutionContextToHook()
{
var sandbox = SandboxBuilder.Build();
var stepExecutionStartingProcessor = new StepExecutionStartingProcessor(new MethodExecutor(sandbox));

var message = new Message
{
MessageId = 1234,
MessageType = Message.Types.MessageType.StepExecutionStarting,
StepExecutionStartingRequest = new StepExecutionStartingRequest
{
CurrentExecutionInfo = new ExecutionInfo
{
CurrentSpec = new SpecInfo { Name = "Foo Spec" },
CurrentScenario = new ScenarioInfo { Name = "Foo Scenario" },
CurrentStep = new StepInfo
{
Step = new ExecuteStepRequest
{
ParsedStepText = "Foo Step",
ActualStepText = "Foo Step"
}
}
}
}
};
var result = stepExecutionStartingProcessor.Process(message);

AssertRunnerDomainDidNotLoadUsersAssembly();
var protoExecutionResult = result.ExecutionStatusResponse.ExecutionResult;
Assert.IsNotNull(protoExecutionResult);
Assert.IsFalse(protoExecutionResult.Failed);
}
}
}
7 changes: 3 additions & 4 deletions Runner.UnitTests/MethodExecutorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using Gauge.CSharp.Core;
using Gauge.CSharp.Lib;
using Gauge.CSharp.Runner.Models;
Expand Down Expand Up @@ -52,7 +51,7 @@ public void ShouldExecuteHooks()
var hooksStrategy = new HooksStrategy();
var executionResult = new ExecutionResult {Success = true};
mockSandBox.Setup(sandbox =>
sandbox.ExecuteHooks("hooks", hooksStrategy, new List<string>(), It.IsAny<Gauge.CSharp.Lib.ExecutionContext>())
sandbox.ExecuteHooks("hooks", hooksStrategy, new List<string>(), It.IsAny<ExecutionContext>())
).Returns(executionResult).Verifiable();

new MethodExecutor(mockSandBox.Object).ExecuteHooks("hooks", hooksStrategy, new List<string>(), new Gauge.CSharp.Lib.ExecutionContext());
Expand All @@ -72,7 +71,7 @@ public void ShouldExecuteHooksAndNotTakeScreenshotOnFailureWhenDisabled()
StackTrace = "StackTrace"
};
mockSandBox.Setup(sandbox =>
sandbox.ExecuteHooks("hooks", hooksStrategy, new List<string>(), It.IsAny<Gauge.CSharp.Lib.ExecutionContext>())
sandbox.ExecuteHooks("hooks", hooksStrategy, new List<string>(), It.IsAny<ExecutionContext>())
).Returns(result).Verifiable();

var screenshotEnabled = Utils.TryReadEnvValue("SCREENSHOT_ON_FAILURE");
Expand All @@ -94,7 +93,7 @@ public void ShouldExecuteMethod()
var args = new[] {"Bar", "String"};
mockSandBox.Setup(sandbox => sandbox.ExecuteMethod(gaugeMethod, It.IsAny<string[]>()))
.Returns(() => new ExecutionResult {Success = true})
.Callback(() => Thread.Sleep(1)); // Simulate a delay in method execution
.Callback(() => System.Threading.Thread.Sleep(1)); // Simulate a delay in method execution

var executionResult = new MethodExecutor(mockSandBox.Object).Execute(gaugeMethod, args);

Expand Down
4 changes: 2 additions & 2 deletions Runner.UnitTests/SandboxHookExecutionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void Setup()
.Returns(new List<Type> {typeof(DefaultScreenGrabber)});
_mockAssemblyLoader.Setup(loader => loader.ClassInstanceManagerTypes)
.Returns(new List<Type> {typeof(DefaultClassInstanceManager)});
_mockAssemblyLoader.Setup(loader => loader.GetTargetLibAssembly()).Returns(GetType().Assembly);
_mockAssemblyLoader.Setup(loader => loader.GetTargetLibAssembly()).Returns(typeof(ExecutionContext).Assembly);
_mockHookRegistry = new Mock<IHookRegistry>();
var mockHookMethod = new Mock<IHookMethod>();
mockHookMethod.Setup(method => method.Method).Returns("DummyHook");
Expand Down Expand Up @@ -126,7 +126,7 @@ public void ShouldExecuteHookWithExecutionContext(string hookType)
_mockHookRegistry.Setup(expression).Returns(_hookMethods).Verifiable();

var sandbox = new Sandbox(_mockAssemblyLoader.Object, _mockHookRegistry.Object, _mockFileWrapper.Object);
var expected = new ExecutionContext(new ExecutionContext.Specification("TestSpec", "TestFileName", false, new List<string>()), null, null );
var expected = new ExecutionContext(new ExecutionContext.Specification("TestSpec", "TestFileName", false, new List<string>()), null, null);
var executionResult = sandbox.ExecuteHooks(hookType, _mockStrategy.Object, _applicableTags, expected);

Assert.True(executionResult.Success);
Expand Down
6 changes: 3 additions & 3 deletions Runner/ExecutionInfoMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ public ExecutionContext ExecutionInfoFrom(Messages.ExecutionInfo currentExecutio
StepFrom(currentExecutionInfo.CurrentStep));
}

public ExecutionContext.Specification SpecificationFrom(Messages.SpecInfo currentSpec)
private ExecutionContext.Specification SpecificationFrom(Messages.SpecInfo currentSpec)
{
return currentSpec != null ? new ExecutionContext.Specification(currentSpec.Name, currentSpec.FileName, currentSpec.IsFailed, currentSpec.Tags.ToArray()) : new ExecutionContext.Specification();
}

public ExecutionContext.Scenario ScenarioFrom(Messages.ScenarioInfo currentScenario)
private ExecutionContext.Scenario ScenarioFrom(Messages.ScenarioInfo currentScenario)
{
return currentScenario != null ? new ExecutionContext.Scenario(currentScenario.Name, currentScenario.IsFailed, currentScenario.Tags.ToArray()) : new ExecutionContext.Scenario();
}

public ExecutionContext.StepDetails StepFrom(Messages.StepInfo currentStep)
private ExecutionContext.StepDetails StepFrom(Messages.StepInfo currentStep)
{
if (currentStep == null || currentStep.Step == null)
return new ExecutionContext.StepDetails();
Expand Down
32 changes: 31 additions & 1 deletion Runner/Gauge.CSharp.Runner.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.6'">
<PropertyGroup>
<__paket__Grpc_Core_targets>net45\Grpc.Core</__paket__Grpc_Core_targets>
</PropertyGroup>
</When>
</Choose>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
Expand Down Expand Up @@ -236,6 +243,18 @@
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.6'">
<ItemGroup>
<Reference Include="Grpc.Core">
<HintPath>..\packages\Grpc.Core\lib\net45\Grpc.Core.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Import Project="..\packages\Grpc.Core\build\$(__paket__Grpc_Core_targets).targets" Condition="Exists('..\packages\Grpc.Core\build\$(__paket__Grpc_Core_targets).targets')" Label="Paket" />
<ItemGroup>
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll">
<Paket>True</Paket>
Expand Down Expand Up @@ -310,6 +329,17 @@
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.6'">
<ItemGroup>
<Reference Include="System.Interactive.Async">
<HintPath>..\packages\System.Interactive.Async\lib\net46\System.Interactive.Async.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.6'">
<ItemGroup>
Expand All @@ -330,4 +360,4 @@
</ItemGroup>
</When>
</Choose>
</Project>
</Project>
2 changes: 1 addition & 1 deletion Runner/ISandbox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public interface ISandbox
IEnumerable<byte[]> GetAllPendingScreenshots();
void StartExecutionScope(string tag);
void CloseExectionScope();
ExecutionResult ExecuteHooks(string hookType, IHooksStrategy strategy, IList<string> applicableTags, ExecutionContext executionContext);
ExecutionResult ExecuteHooks(string hookType, IHooksStrategy strategy, IList<string> applicableTags, object executionContext);

IEnumerable<string> Refactor(GaugeMethod methodInfo, IList<Tuple<int, int>> parameterPositions,
IList<string> parametersList, string newStepValue);
Expand Down
3 changes: 3 additions & 0 deletions Runner/MethodExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
using Gauge.Messages;
using Google.Protobuf;
using NLog;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;

namespace Gauge.CSharp.Runner
{
Expand Down
3 changes: 2 additions & 1 deletion Runner/Processors/HookExecutionProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ protected virtual ProtoExecutionResult ExecuteHooks(Message request)
var applicableTags = GetApplicableTags(request);
var mapper = new ExecutionInfoMapper();
var executionContext = mapper.ExecutionInfoFrom(GetExecutionInfo(request));
return MethodExecutor.ExecuteHooks(HookType, Strategy, applicableTags, executionContext); }
return MethodExecutor.ExecuteHooks(HookType, Strategy, applicableTags, executionContext);
}

private void ClearCacheForConfiguredLevel()
{
Expand Down
44 changes: 32 additions & 12 deletions Runner/Sandbox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ public IEnumerable<string> GetAllPendingMessages()
public IEnumerable<byte[]> GetAllPendingScreenshots()
{
var targetMessageCollectorType = _libAssembly.GetType("Gauge.CSharp.Lib.ScreenshotCollector");
var targetMethod = targetMessageCollectorType.GetMethod("GetAllPendingScreenshots",
var targetMethod = targetMessageCollectorType?.GetMethod("GetAllPendingScreenshots",
BindingFlags.Static | BindingFlags.Public);
return targetMethod.Invoke(null, null) as IEnumerable<byte[]>;
return targetMethod?.Invoke(null, null) as IEnumerable<byte[]>;
}

public void StartExecutionScope(string tag)
Expand All @@ -205,7 +205,7 @@ public void CloseExectionScope()

[DebuggerStepperBoundary]
[DebuggerHidden]
public ExecutionResult ExecuteHooks(string hookType, IHooksStrategy strategy, IList<string> applicableTags, ExecutionContext executionContext)
public ExecutionResult ExecuteHooks(string hookType, IHooksStrategy strategy, IList<string> applicableTags, object executionContext)
{
var methods = GetHookMethods(hookType, strategy, applicableTags);
var executionResult = new ExecutionResult
Expand Down Expand Up @@ -257,20 +257,40 @@ public override object InitializeLifetimeService()
[DebuggerHidden]
private void ExecuteHook(MethodInfo method, params object[] objects)
{
if (HasArguments(method, objects))
Execute(method, objects);
else
Execute(method);
var args = GetArguments(method, objects);
Execute(method, args);
}

private static bool HasArguments(MethodInfo method, object[] args)
private object[] GetArguments(MethodInfo method, object[] args)
{
var executionInfoType = "Gauge.CSharp.Lib.ExecutionInfo";
if (method.GetParameters().Length != args.Length)
return false;
return null;
var methodParams = method.GetParameters();
var argList = new List<object>();
for (var i = 0; i < args.Length; i++)
if (args[i].GetType() != method.GetParameters()[i].ParameterType)
return false;
return true;
{
var methodParamType = methodParams[i].ParameterType.FullName;
var argType = args[i].GetType().FullName;
if (argType != methodParamType)
throw new ArgumentException($"Invalid argument type, expected {methodParamType}, got {argType}");
if (methodParamType == executionInfoType)
{
var targetExecutionInfoType = _libAssembly.GetType(executionInfoType);
using (var ms = new MemoryStream())
{
var serializer = new DataContractJsonSerializer(typeof(ExecutionContext));
var targetExecutionInfoTypee = _libAssembly.GetType(executionInfoType);
var targetSerializer = new DataContractJsonSerializer(targetExecutionInfoType);
serializer.WriteObject(ms, args[i]);
ms.Position = 0;
argList.Add(targetSerializer.ReadObject(ms));
}
}
else
argList.Add(args[i]);
}
return args;
}

private IEnumerable<string> GetHookMethods(string hookType, IHooksStrategy strategy,
Expand Down
1 change: 0 additions & 1 deletion build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ Target.create "CopyBinaries" (fun _ ->
|> Seq.iter (fun (fromDir, toDir) -> Shell.copyDir toDir fromDir (fun _ -> true))
// copy the IntegrationTestSample.dll with test suites
Shell.copyFile "artifacts/gauge-csharp/itests" "IntegrationTestSample/gauge_bin/IntegrationTestSample.dll"
Run("ls", "", "artifacts/gauge-csharp")
// and do NOT copy its old Lib reference, it must be loaded by sandbox
// CopyFile "artifacts/gauge-csharp/itests" "IntegrationTestSample/gauge_bin/Gauge.CSharp.Lib.dll"
)
Expand Down
2 changes: 1 addition & 1 deletion paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ nuget NuGet.Core framework: >= net45
nuget System.Collections.Immutable 1.1.37 framework: >= net45
nuget System.Reflection.Metadata 1.1.0 framework: >= net45
// locked to this version because GaugeProjectBuilder does not like newer
nuget FSharp.Core 4.3.3
nuget FSharp.Core
nuget FAKE.Lib
nuget Microsoft.Web.Xdt
nuget Google.Protobuf
Expand Down
Loading

0 comments on commit 70b213d

Please sign in to comment.