Skip to content

Commit

Permalink
Merge pull request #63 from nowsprinting/feature/cli_errorhandling
Browse files Browse the repository at this point in the history
Can overwrite error handling settings by command line arguments
  • Loading branch information
Kuniwak authored Jun 4, 2024
2 parents 3f8d196 + a744d8c commit aaf61cf
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 51 deletions.
14 changes: 1 addition & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,13 @@ UNITY_YAML_MERGE?=$(UNITY_HOME)/Tools/UnityYAMLMerge
STANDALONE_PLAYER=StandaloneOSX
endif

define ARGUMENTS_FOR_ARGUMENT_CAPTURE_TESTS
-STR_ARG STRING_BY_ARGUMENT \
-BOOL_ARG_TRUE TRUE \
-BOOL_ARG_FALSE FALSE \
-BOOL_ARG_NO_VALUE \
-INT_ARG_1 1 \
-LONG_ARG_MAX 9223372036854775807 \
-FLOAT_ARG_2_3 2.3 \
-DOUBLE_ARG_4_5 4.5
endef

define ENVIRONMENT_VARIABLES_FOR_ARGUMENT_CAPTURE_TESTS
STR_ENV=STRING_BY_ENVIRONMENT_VARIABLE
endef

define base_arguments
-projectPath $(PROJECT_HOME) \
-logFile $(LOG_DIR)/test_$(TEST_PLATFORM).log \
$(ARGUMENTS_FOR_ARGUMENT_CAPTURE_TESTS)
-logFile $(LOG_DIR)/test_$(TEST_PLATFORM).log
endef

define test_arguments
Expand Down
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,14 @@ This item can also be overridden from the commandline (see below).

#### Error Handling Settings

Set up a filter to catch abnormal log messages and notify Slack.
Set up a filter to catch abnormal log messages and notify using Reporter.

<dl>
<dt>handle Exception</dt><dd>Notify Slack when exception detected in log</dd>
<dt>handle Error</dt><dd>Notify Slack when error detected in log</dd>
<dt>handle Assert</dt><dd>Notify Slack when assert detected in log</dd>
<dt>handle Warning</dt><dd>Notify Slack when warning detected in log</dd>
<dt>Ignore Messages</dt><dd>Log messages containing this string will not be notified to Slack</dd>
<dt>Handle Exception</dt><dd>Report when exception is detected in log</dd>
<dt>Handle Error</dt><dd>Report when error message is detected in log</dd>
<dt>Handle Assert</dt><dd>Report when assert message is detected in log</dd>
<dt>Handle Warning</dt><dd>Report when warning message is detected in log</dd>
<dt>Ignore Messages</dt><dd>Log messages containing this string will not be report</dd>
</dl>


Expand Down Expand Up @@ -224,6 +224,10 @@ For details on each argument, see the entry of the same name in the "Generate an
<dt>RANDOM_SEED</dt><dd>Specifies when you want to fix the seed given to the pseudo-random number generator</dd>
<dt>TIME_SCALE</dt><dd>Specifies the Time.timeScale. Default is 1.0</dd>
<dt>JUNIT_REPORT_PATH</dt><dd>Specifies the JUnit-style report file output path</dd>
<dt>HANDLE_EXCEPTION</dt><dd>Overwrites whether to report when an exception occurs with TRUE/FALSE</dd>
<dt>HANDLE_ERROR</dt><dd>Overwrites whether to report when an error message is detected with TRUE/FALSE</dd>
<dt>HANDLE_ASSERT</dt><dd>Overwrites whether to report when an assert message is detected with TRUE/FALSE</dd>
<dt>HANDLE_WARNING</dt><dd>Overwrites whether to report when an warning message is detected with TRUE/FALSE</dd>
</dl>

In both cases, the key should be prefixed with `-` and specified as `-LIFESPAN_SEC 60`.
Expand Down
16 changes: 10 additions & 6 deletions README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,14 @@ v1.0.0時点では `EmergencyExitAgent` の使用を想定しています。

#### エラーハンドリング設定

異常系ログメッセージを捕捉してSlackに通知するフィルタを設定します
異常系ログメッセージを捕捉してレポータで通知するフィルタを設定します

<dl>
<dt>handle Exception</dt><dd>例外を検知したらSlackに通知します</dd>
<dt>handle Error</dt><dd>エラーを検知したらSlackに通知します</dd>
<dt>handle Assert</dt><dd>アサート違反を検知したらSlackに通知します</dd>
<dt>handle Warning</dt><dd>警告を検知したらSlackに通知します</dd>
<dt>Ignore Messages</dt><dd>ここに設定した文字列を含むメッセージはSlackに通知しません</dd>
<dt>handle Exception</dt><dd>例外を検知したらレポータで通知します</dd>
<dt>handle Error</dt><dd>エラーを検知したらレポータで通知します</dd>
<dt>handle Assert</dt><dd>アサート違反を検知したらレポータで通知します</dd>
<dt>handle Warning</dt><dd>警告を検知したらレポータで通知します</dd>
<dt>Ignore Messages</dt><dd>ここに設定した文字列を含むメッセージはレポータで通知しません</dd>
</dl>


Expand Down Expand Up @@ -226,6 +226,10 @@ $(UNITY) \
<dt>RANDOM_SEED</dt><dd>疑似乱数発生器に与えるシードを固定したいときに指定します</dd>
<dt>TIME_SCALE</dt><dd>Time.timeScaleを指定します。デフォルトは1.0</dd>
<dt>JUNIT_REPORT_PATH</dt><dd>JUnit形式のレポートファイル出力パスを指定します</dd>
<dt>HANDLE_EXCEPTION</dt><dd>例外を検知したときに通知を行なうかを TRUE/ FALSEで上書きします</dd>
<dt>HANDLE_ERROR</dt><dd>エラーを検知したときに通知を行なうかを TRUE/ FALSEで上書きします</dd>
<dt>HANDLE_ASSERT</dt><dd>アサート違反を検知したときに通知を行なうかを TRUE/ FALSEで上書きします</dd>
<dt>HANDLE_WARNING</dt><dd>警告を検知したときに通知を行なうかを TRUE/ FALSEで上書きします</dd>
</dl>

いずれも、キーの先頭に`-`を付けて`-LIFESPAN_SEC 60`のように指定してください。
Expand Down
11 changes: 6 additions & 5 deletions Runtime/ArgumentCapture/Argument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ public class Argument<T> : IArgument<T>
private readonly (bool, T) _captured;

/// <summary>
/// Constructor
/// Constructor.
/// </summary>
/// <param name="key"></param>
/// <param name="defaultValue"></param>
public Argument(string key, T defaultValue = default(T))
/// <param name="key">Key of arguments</param>
/// <param name="defaultValue">Use this value if not specified key in arguments</param>
/// <param name="args">Command line arguments for testing</param>
public Argument(string key, T defaultValue = default, string[] args = null)
{
_defaultValue = defaultValue;
_captured = ArgumentCapture.Capture<T>(key);
_captured = ArgumentCapture.Capture<T>(key, args);
}

/// <inheritdoc/>
Expand Down
14 changes: 9 additions & 5 deletions Runtime/ArgumentCapture/ArgumentCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ namespace DeNA.Anjin.ArgumentCapture
{
internal static class ArgumentCapture
{
internal static (bool, T) Capture<T>(string key)
internal static (bool, T) Capture<T>(string key, string[] args = null)
{
string captureString = null;
#if UNITY_EDITOR
captureString = CaptureString(key);
captureString = CaptureString(key, args);
#elif UNITY_ANDROID
captureString = ArgumentCaptureAndroid.CaptureString(key);
#elif UNITY_IOS
Expand Down Expand Up @@ -45,17 +45,21 @@ internal static (bool, T) Capture<T>(string key)
return (false, default(T));
}

private static string CaptureString(string key)
private static string CaptureString(string key, string[] args = null)
{
// Arguments first
var args = Environment.GetCommandLineArgs();
if (args == null)
{
args = Environment.GetCommandLineArgs();
}

for (var i = 0; i < args.Length; i++)
{
if (args[i].ToLower().Equals($"-{key.ToLower()}"))
{
if (i == args.Length - 1)
{
return string.Empty; // In Bool, it's possible that the termination is KEY.
return true.ToString(); // In Bool, it's possible that the termination is KEY.
}

return args[i + 1];
Expand Down
20 changes: 20 additions & 0 deletions Runtime/Settings/Arguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,26 @@ public class Arguments
/// </summary>
public virtual IArgument<string> JUnitReportPath => new Argument<string>("JUNIT_REPORT_PATH");

/// <summary>
/// Specifies the enable/disable handling Exception (optional).
/// </summary>
public virtual IArgument<bool> HandleException => new Argument<bool>("HANDLE_EXCEPTION");

/// <summary>
/// Specifies the enable/disable handling Error (optional).
/// </summary>
public virtual IArgument<bool> HandleError => new Argument<bool>("HANDLE_ERROR");

/// <summary>
/// Specifies the enable/disable handling Assert (optional).
/// </summary>
public virtual IArgument<bool> HandleAssert => new Argument<bool>("HANDLE_ASSERT");

/// <summary>
/// Specifies the enable/disable handling Warning (optional).
/// </summary>
public virtual IArgument<bool> HandleWarning => new Argument<bool>("HANDLE_WARNING");

/// <summary>
/// Web API token used for Slack notifications.
///
Expand Down
20 changes: 20 additions & 0 deletions Runtime/Settings/AutopilotSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,26 @@ public void OverrideByCommandLineArguments(Arguments args)
junitReportPath = args.JUnitReportPath.Value();
}

if (args.HandleException.IsCaptured())
{
handleException = args.HandleException.Value();
}

if (args.HandleError.IsCaptured())
{
handleError = args.HandleError.Value();
}

if (args.HandleAssert.IsCaptured())
{
handleAssert = args.HandleAssert.Value();
}

if (args.HandleWarning.IsCaptured())
{
handleWarning = args.HandleWarning.Value();
}

if (args.SlackToken.IsCaptured())
{
#pragma warning disable CS0618 // Type or member is obsolete
Expand Down
39 changes: 23 additions & 16 deletions Tests/Runtime/ArgumentCapture/ArgumentTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,21 @@ namespace DeNA.Anjin.ArgumentCapture
{
/// <summary>
/// Test arguments when launch from the command line.
/// It will almost always fail when executed from the Unity editor GUI.
/// This is actually a test of <c>ArgumentCapture</c>.
/// </summary>
[TestFixture]
[IgnoreWindowMode("Need command line arguments")]
public class ArgumentTest
{
[Test]
public void String_inArgument_gotValue()
{
var arg = new Argument<string>("STR_ARG");
var arg = new Argument<string>("STR_ARG", args: new[] { "-STR_ARG", "STRING_BY_ARGUMENT" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.EqualTo("STRING_BY_ARGUMENT"));
}

[Test]
[IgnoreWindowMode("Need command line arguments. see Makefile")]
public void String_inEnvironmentVariable_gotValue()
{
var arg = new Argument<string>("STR_ENV");
Expand All @@ -44,95 +43,103 @@ public void String_notExist_gotDefault()
[Test]
public void Bool_inArgumentTrue_gotTrue()
{
var arg = new Argument<bool>("BOOL_ARG_TRUE");
var arg = new Argument<bool>("BOOL_ARG_TRUE", args: new[] { "-BOOL_ARG_TRUE", "TRUE" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.True);
}

[Test]
public void Bool_inArgumentFalse_gotFalse()
{
var arg = new Argument<bool>("BOOL_ARG_FALSE");
var arg = new Argument<bool>("BOOL_ARG_FALSE", args: new[] { "-BOOL_ARG_FALSE", "FALSE" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.False);
}

[Test]
public void Bool_inArgumentNoValue_gotTrue()
public void Bool_inArgumentNoValue_HasNextArgumentKey_gotTrue()
{
var arg = new Argument<bool>("BOOL_ARG_NO_VALUE");
var arg = new Argument<bool>("BOOL_ARG_NO_VALUE", args: new[] { "-BOOL_ARG_NO_VALUE", "-NEXT_ARG" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.True);
}

[Test]
public void Bool_inArgumentNoValue_NoNextArgumentKey_gotTrue()
{
var arg = new Argument<bool>("BOOL_ARG_NO_VALUE", args: new[] { "-BOOL_ARG_NO_VALUE" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.True);
}

[Test]
public void Bool_invalidValue_gotDefault()
{
var arg = new Argument<bool>("STR_ARG");
var arg = new Argument<bool>("STR_ARG", args: new[] { "-STR_ARG", "STRING_BY_ARGUMENT" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.EqualTo(default(bool)));
}

[Test]
public void Int_inArgument_gotValue()
{
var arg = new Argument<int>("INT_ARG_1");
var arg = new Argument<int>("INT_ARG_1", args: new[] { "-INT_ARG_1", "1" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.EqualTo(1));
}

[Test]
public void Int_invalidValue_gotDefault()
{
var arg = new Argument<int>("STR_ARG");
var arg = new Argument<int>("STR_ARG", args: new[] { "-STR_ARG", "STRING_BY_ARGUMENT" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.EqualTo(default(int)));
}

[Test]
public void Long_inArgument_gotValue()
{
var arg = new Argument<long>("LONG_ARG_MAX");
var arg = new Argument<long>("LONG_ARG_MAX", args: new[] { "-LONG_ARG_MAX", "9223372036854775807" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.EqualTo(long.MaxValue));
}

[Test]
public void Long_invalidValue_gotDefault()
{
var arg = new Argument<long>("STR_ARG");
var arg = new Argument<long>("STR_ARG", args: new[] { "-STR_ARG", "STRING_BY_ARGUMENT" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.EqualTo(default(long)));
}

[Test]
public void Float_inArgument_gotValue()
{
var arg = new Argument<float>("FLOAT_ARG_2_3");
var arg = new Argument<float>("FLOAT_ARG_2_3", args: new[] { "-FLOAT_ARG_2_3", "2.3" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.EqualTo(2.3f).Using(FloatEqualityComparer.Instance));
}

[Test]
public void Float_invalidValue_gotDefault()
{
var arg = new Argument<float>("STR_ARG");
var arg = new Argument<float>("STR_ARG", args: new[] { "-STR_ARG", "STRING_BY_ARGUMENT" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.EqualTo(default(float)));
}

[Test]
public void Double_inArgument_gotValue()
{
var arg = new Argument<double>("DOUBLE_ARG_4_5");
var arg = new Argument<double>("DOUBLE_ARG_4_5", args: new[] { "-DOUBLE_ARG_4_5", "4.5" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.EqualTo(4.5d).Using(FloatEqualityComparer.Instance));
}

[Test]
public void Double_invalidValue_gotDefault()
{
var arg = new Argument<double>("STR_ARG");
var arg = new Argument<double>("STR_ARG", args: new[] { "-STR_ARG", "STRING_BY_ARGUMENT" });
Assert.That(arg.IsCaptured, Is.True);
Assert.That(arg.Value(), Is.EqualTo(default(double)));
}
Expand Down
Loading

0 comments on commit aaf61cf

Please sign in to comment.