-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* #441 - Fix exit code 1 if Harmony patching failled Use LogWarning instead LogError Change codestyle - filescoped namespace, explicit modifiers for better code readability * #441 - Fix exit code 1 if Harmony patching failled Review fixes
- Loading branch information
Showing
1 changed file
with
79 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,106 +1,107 @@ | ||
using System; | ||
|
||
using HarmonyLib; | ||
using System; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
using Xunit.Sdk; | ||
|
||
namespace Allure.XUnit | ||
namespace Allure.XUnit; | ||
|
||
internal static class AllureXunitPatcher | ||
{ | ||
static class AllureXunitPatcher | ||
{ | ||
const string ALLURE_ID = "io.qameta.allure.xunit"; | ||
static bool isPatched = false; | ||
static IRunnerLogger logger; | ||
private const string ALLURE_ID = "io.qameta.allure.xunit"; | ||
private static bool _isPatched; | ||
private static IRunnerLogger _logger; | ||
|
||
static AllureMessageSink CurrentSink | ||
private static AllureMessageSink CurrentSink | ||
{ | ||
get | ||
{ | ||
get | ||
var sink = AllureMessageSink.CurrentSink; | ||
|
||
if (sink is null) | ||
{ | ||
var sink = AllureMessageSink.CurrentSink; | ||
if (sink is null) | ||
{ | ||
logger.LogWarning("Unable to get current message sink."); | ||
} | ||
return sink; | ||
_logger.LogWarning("Unable to get current message sink."); | ||
} | ||
|
||
return sink; | ||
} | ||
} | ||
|
||
public static void PatchXunit(IRunnerLogger runnerLogger) | ||
public static void PatchXunit(IRunnerLogger runnerLogger) | ||
{ | ||
if (_isPatched) | ||
{ | ||
if (isPatched) | ||
{ | ||
logger.LogMessage( | ||
"Patching is skipped: Xunit is already patched" | ||
); | ||
return; | ||
} | ||
|
||
logger = runnerLogger; | ||
var patcher = new Harmony(ALLURE_ID); | ||
PatchXunitTestRunnerCtors(patcher); | ||
isPatched = true; | ||
_logger.LogMessage( | ||
"Patching is skipped: Xunit is already patched" | ||
); | ||
return; | ||
} | ||
|
||
static void PatchXunitTestRunnerCtors(Harmony patcher) | ||
_logger = runnerLogger; | ||
|
||
var patcher = new Harmony(ALLURE_ID); | ||
PatchXunitTestRunnerCtors(patcher); | ||
_isPatched = true; | ||
} | ||
|
||
private static void PatchXunitTestRunnerCtors(Harmony patcher) | ||
{ | ||
var testRunnerType = typeof(XunitTestRunner); | ||
var wasPatched = false; | ||
|
||
foreach (var ctor in testRunnerType.GetConstructors()) | ||
{ | ||
var testRunnerType = typeof(XunitTestRunner); | ||
var wasPatched = false; | ||
foreach (var ctor in testRunnerType.GetConstructors()) | ||
try | ||
{ | ||
try | ||
{ | ||
patcher.Patch( | ||
ctor, | ||
prefix: new HarmonyMethod( | ||
typeof(AllureXunitPatcher), | ||
nameof(OnTestRunnerCreating) | ||
), | ||
postfix: new HarmonyMethod( | ||
typeof(AllureXunitPatcher), | ||
nameof(OnTestRunnerCreated) | ||
) | ||
); | ||
wasPatched = true; | ||
logger.LogImportantMessage( | ||
"{0}'s {1} has been patched", | ||
testRunnerType.Name, | ||
ctor.ToString() | ||
); | ||
} | ||
catch (Exception e) | ||
{ | ||
logger.LogError( | ||
"Unable to patch {0}'s {1}: {2}", | ||
testRunnerType.Name, | ||
ctor.ToString(), | ||
e.ToString() | ||
); | ||
} | ||
} | ||
patcher.Patch( | ||
ctor, | ||
prefix: new HarmonyMethod( | ||
typeof(AllureXunitPatcher), | ||
nameof(OnTestRunnerCreating) | ||
), | ||
postfix: new HarmonyMethod( | ||
typeof(AllureXunitPatcher), | ||
nameof(OnTestRunnerCreated) | ||
) | ||
); | ||
|
||
wasPatched = true; | ||
|
||
if (!wasPatched) | ||
_logger.LogImportantMessage( | ||
"{0}'s {1} has been patched", | ||
testRunnerType.Name, | ||
ctor.ToString() | ||
); | ||
} | ||
catch (Exception e) | ||
{ | ||
logger.LogWarning( | ||
"No constructors of {0} were pathched. Some theories may " + | ||
"miss their parameters in the report", | ||
testRunnerType.Name | ||
_logger.LogWarning( | ||
"Unable to patch {0}'s {1}: {2}", | ||
testRunnerType.Name, | ||
ctor.ToString(), | ||
e.ToString() | ||
); | ||
} | ||
} | ||
|
||
static void OnTestRunnerCreating(ITest test, ref string skipReason) | ||
if (!wasPatched) | ||
{ | ||
if (!CurrentSink.SelectByTestPlan(test)) | ||
{ | ||
skipReason = "Deselected by the testplan."; | ||
} | ||
_logger.LogWarning( | ||
"No constructors of {0} were patched. Some theories may " + | ||
"miss their parameters in the report", | ||
testRunnerType.Name | ||
); | ||
} | ||
} | ||
|
||
static void OnTestRunnerCreated( | ||
ITest test, | ||
object[] testMethodArguments | ||
) => | ||
CurrentSink.OnTestArgumentsCreated(test, testMethodArguments); | ||
private static void OnTestRunnerCreating(ITest test, ref string skipReason) | ||
{ | ||
if (!CurrentSink.SelectByTestPlan(test)) | ||
{ | ||
skipReason = "Deselected by the test plan."; | ||
} | ||
} | ||
|
||
private static void OnTestRunnerCreated(ITest test, object[] testMethodArguments) => | ||
CurrentSink.OnTestArgumentsCreated(test, testMethodArguments); | ||
} |