Skip to content

Commit

Permalink
Merge pull request #327 from moreal/feature/move-validation-to-comman…
Browse files Browse the repository at this point in the history
…d-line

feat(cli): implement `validation'  subcommand
  • Loading branch information
longfin authored Feb 26, 2021
2 parents c374c8a + d289922 commit d485f08
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using NineChronicles.Headless.Executable.Commands;
using NineChronicles.Headless.Executable.Tests.IO;
using Xunit;

namespace NineChronicles.Headless.Executable.Tests.Commands
{
public class ValidationCommandTest
{
private readonly StringIOConsole _console;
private readonly ValidationCommand _command;

public ValidationCommandTest()
{
_console = new StringIOConsole();
_command = new ValidationCommand(_console);
}

[Theory]
[InlineData("", -1, "The given private key, '', had an issue during parsing.\n")]
[InlineData("invalid hexadecimal", -1, "The given private key, 'invalid hexadecimal', had an issue during parsing.\n")]
[InlineData("000000000000000000000000000000000000000000000000000000000000000000", -1, "The given private key, '000000000000000000000000000000000000000000000000000000000000000000', had an issue during parsing.\n")]
[InlineData("ab8d591ccdcce263c39eb1f353e44b64869f0afea2df643bf6839ebde650d244", 0, "")]
[InlineData("d6c3e0d525dac340a132ae05aaa9f3e278d61b70d2b71326570e64aee249e566", 0, "")]
[InlineData("761f68d68426549df5904395b5ca5bce64a3da759085d8565242db42a5a1b0b9", 0, "")]
public void PrivateKey(string privateKeyHex, int exitCode, string errorOutput)
{
Assert.Equal(exitCode, _command.PrivateKey(privateKeyHex));
Assert.Equal(errorOutput, _console.Error.ToString());
}

[Theory]
[InlineData("", -1, "The given public key, '', had an issue during parsing.\n")]
[InlineData("invalid hexadecimal", -1, "The given public key, 'invalid hexadecimal', had an issue during parsing.\n")]
[InlineData("000000000000000000000000000000000000000000000000000000000000000000", -1, "The given public key, '000000000000000000000000000000000000000000000000000000000000000000', had an issue during parsing.\n")]
[InlineData("03b0868d9301b30c512d307ea67af4c8bef637ef099e39d32b808a43e6b41469c5", 0, "")]
[InlineData("03308c1618a75e85a5fb57f7e453a642c307dc6310e90a7418b1aec565d963534a", 0, "")]
[InlineData("028a6190bf643175b20e4a2d1d86fe6c4b8f7d5fe3d163632be4e59f83335824b8", 0, "")]
public void PublicKey(string publicKeyHex, int exitCode, string errorOutput)
{
Assert.Equal(exitCode, _command.PublicKey(publicKeyHex));
Assert.Equal(errorOutput, _console.Error.ToString());
}
}
}
32 changes: 32 additions & 0 deletions NineChronicles.Headless.Executable.Tests/IO/StringIOConsole.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.IO;
using NineChronicles.Headless.Executable.IO;

namespace NineChronicles.Headless.Executable.Tests.IO
{
public sealed class StringIOConsole : IConsole
{
public StringIOConsole(StringReader @in, StringWriter @out, StringWriter error)
{
In = @in;
Out = @out;
Error = error;
}

public StringIOConsole(string input = "")
: this(new StringReader(input), new StringWriter(), new StringWriter())
{
}

public StringReader In { get; }

public StringWriter Out { get; }

public StringWriter Error { get; }

TextReader IConsole.In => In;

TextWriter IConsole.Out => Out;

TextWriter IConsole.Error => Error;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>8</LangVersion>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference
Include="..\NineChronicles.Headless.Executable\NineChronicles.Headless.Executable.csproj" />
</ItemGroup>

</Project>
14 changes: 14 additions & 0 deletions NineChronicles.Headless.Executable.sln
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Libplanet.RocksDBStore", "L
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Libplanet.Stun", "Lib9c\.Libplanet\Libplanet.Stun\Libplanet.Stun.csproj", "{3B2875B4-B6C6-4929-B885-18A922110ED2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NineChronicles.Headless.Executable.Tests", "NineChronicles.Headless.Executable.Tests\NineChronicles.Headless.Executable.Tests.csproj", "{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -153,6 +155,18 @@ Global
{3B2875B4-B6C6-4929-B885-18A922110ED2}.Release|x64.Build.0 = Release|Any CPU
{3B2875B4-B6C6-4929-B885-18A922110ED2}.Release|x86.ActiveCfg = Release|Any CPU
{3B2875B4-B6C6-4929-B885-18A922110ED2}.Release|x86.Build.0 = Release|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Debug|x64.ActiveCfg = Debug|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Debug|x64.Build.0 = Debug|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Debug|x86.ActiveCfg = Debug|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Debug|x86.Build.0 = Debug|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Release|Any CPU.Build.0 = Release|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Release|x64.ActiveCfg = Release|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Release|x64.Build.0 = Release|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Release|x86.ActiveCfg = Release|Any CPU
{6E38A2CF-B93F-4CD5-9CAC-DE121998FF18}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
55 changes: 55 additions & 0 deletions NineChronicles.Headless.Executable/Commands/ValidationCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Cocona;
using Libplanet;
using Libplanet.Crypto;
using NineChronicles.Headless.Executable.IO;

namespace NineChronicles.Headless.Executable.Commands
{
public class ValidationCommand : CoconaLiteConsoleAppBase
{
private readonly IConsole _console;

public ValidationCommand(IConsole console)
{
_console = console;
}

[Command(Description = "Validate private key")]
public int PrivateKey(
[Argument(
Name = "PRIVATE-KEY",
Description = "A hexadecimal representation of private key to validate.")]
string privateKeyHex)
{
try
{
_ = new PrivateKey(ByteUtil.ParseHex(privateKeyHex));
return 0;
}
catch
{
_console.Error.WriteLine($"The given private key, '{privateKeyHex}', had an issue during parsing.");
return -1;
}
}

[Command(Description = "Validate public key")]
public int PublicKey(
[Argument(
Name = "PUBLIC-KEY",
Description = "A hexadecimal representation of public key to validate.")]
string publicKeyHex)
{
try
{
_ = new PublicKey(ByteUtil.ParseHex(publicKeyHex));
return 0;
}
catch
{
_console.Error.WriteLine($"The given public key, '{publicKeyHex}', had an issue during parsing.");
return -1;
}
}
}
}
11 changes: 11 additions & 0 deletions NineChronicles.Headless.Executable/IO/IConsole.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.IO;

namespace NineChronicles.Headless.Executable.IO
{
public interface IConsole
{
TextReader In { get; }
TextWriter Out { get; }
TextWriter Error { get; }
}
}
21 changes: 21 additions & 0 deletions NineChronicles.Headless.Executable/IO/StandardConsole.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.IO;

namespace NineChronicles.Headless.Executable.IO
{
public class StandardConsole : IConsole
{
public StandardConsole()
{
In = Console.In;
Out = Console.Out;
Error = Console.Error;
}

public TextReader In { get; }

public TextWriter Out { get; }

public TextWriter Error { get; }
}
}
9 changes: 7 additions & 2 deletions NineChronicles.Headless.Executable/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
using Libplanet;
using Libplanet.KeyStore;
using Microsoft.Extensions.Hosting;
using NineChronicles.Headless.Executable.Commands;
using NineChronicles.Headless.Executable.IO;
using NineChronicles.Headless.Properties;
using Org.BouncyCastle.Security;
using Sentry;
Expand All @@ -21,6 +23,7 @@

namespace NineChronicles.Headless.Executable
{
[HasSubCommands(typeof(ValidationCommand), "validation")]
public class Program : CoconaLiteConsoleAppBase
{
const string SentryDsn = "https://[email protected]/5287621";
Expand All @@ -33,7 +36,9 @@ static async Task Main(string[] args)
#if SENTRY || ! DEBUG
using var _ = SentrySdk.Init(ConfigureSentryOptions);
#endif
await CoconaLiteApp.RunAsync<Program>(args);
await CoconaLiteApp.Create()
.ConfigureServices(services => services.AddSingleton<IConsole, StandardConsole>())
.RunAsync<Program>(args);
}

static void ConfigureSentryOptions(SentryOptions o)
Expand All @@ -47,7 +52,7 @@ static void ConfigureSentryOptions(SentryOptions o)
#endif
}

[Command(Description = "Run headless application with options.")]
[PrimaryCommand]
public async Task Run(
bool noMiner = false,
[Option("app-protocol-version", new[] { 'V' }, Description = "App protocol version token")]
Expand Down

0 comments on commit d485f08

Please sign in to comment.