Skip to content

Add version to test tool #1969

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .autover/changes/efa829ed-59af-46eb-a5e5-ef471698c82d.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Projects": [
{
"Name": "Amazon.Lambda.TestTool",
"Type": "Patch",
"ChangelogMessages": [
"Breaking change: Switch to use commands to invoke the tool. For example to run the Lambda emulator use the command 'dotnet lambda-test-tool start --lambda-emulator-port 5050'",
"Add new info command to get metadata about the tool. For example getting the version number of the tool."
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

using System.Diagnostics;
using System.Text.Json;
using Amazon.Lambda.TestTool.Commands.Settings;
using Amazon.Lambda.TestTool.Extensions;
using Amazon.Lambda.TestTool.Models;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace Amazon.Lambda.TestTool.Commands.Settings;

/// <summary>
/// Represents the settings for configuring the <see cref="RunCommand"/>, which is the default command.
/// Represents the settings for configuring the <see cref="RunCommand"/>.
/// </summary>
public sealed class RunCommandSettings : CommandSettings
{
Expand Down Expand Up @@ -36,22 +36,6 @@ public sealed class RunCommandSettings : CommandSettings
[Description("Disable auto launching the test tool's web interface in a browser.")]
public bool NoLaunchWindow { get; set; }

/// <summary>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were leftover from the old version of the tooling and are not used in the new version.

/// If set to true the test tool will pause waiting for a key input before exiting.
/// The is useful when executing from an IDE so you can avoid having the output window immediately disappear after executing the Lambda code.
/// The default value is true.
/// </summary>
[CommandOption("--pause-exit")]
[Description("If set to true the test tool will pause waiting for a key input before exiting. The is useful when executing from an IDE so you can avoid having the output window immediately disappear after executing the Lambda code. The default value is true.")]
public bool PauseExit { get; set; }

/// <summary>
/// Disables logging in the application
/// </summary>
[CommandOption("--disable-logs")]
[Description("Disables logging in the application")]
public bool DisableLogs { get; set; }

/// <summary>
/// The API Gateway Emulator Mode specifies the format of the event that API Gateway sends to a Lambda integration,
/// and how API Gateway interprets the response from Lambda.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using Amazon.Lambda.TestTool.Models;
using Spectre.Console.Cli;
using System.ComponentModel;

namespace Amazon.Lambda.TestTool.Commands.Settings;

/// <summary>
/// Represents the settings for configuring the <see cref="ToolInfoCommand"/>.
/// </summary>
public sealed class ToolInfoCommandSettings : CommandSettings
{
public enum InfoFormat
{
Text,
Json
}

/// <summary>
/// The format the info is displayed as.
/// The available formats are: Text, Json.
/// </summary>
[CommandOption("--format <FORMAT>")]
[Description(
"The format the info is displayed as. " +
"The available formats are: Text, Json.")]
public InfoFormat? Format { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using System.Text;
using System.Text.Json;
using Amazon.Lambda.TestTool.Commands.Settings;
using Amazon.Lambda.TestTool.Models;
using Amazon.Lambda.TestTool.Services;
using Amazon.Lambda.TestTool.Utilities;
using Spectre.Console.Cli;

namespace Amazon.Lambda.TestTool.Commands;

/// <summary>
/// Command to display tool information like the version of the tool.
/// </summary>
/// <param name="toolInteractiveService"></param>
public class ToolInfoCommand(IToolInteractiveService toolInteractiveService)
: Command<ToolInfoCommandSettings>
{
/// <summary>
/// The method responsible for executing the <see cref="RunCommand"/>.
/// </summary>
public override int Execute(CommandContext context, ToolInfoCommandSettings settings)
{
var info = CollectInformation();

var formattedInfo = settings.Format switch
{
ToolInfoCommandSettings.InfoFormat.Text => GenerateToolInfoText(info),
ToolInfoCommandSettings.InfoFormat.Json => GenerateToolInfoJson(info),
_ => GenerateToolInfoText(info)
};

toolInteractiveService.WriteLine(formattedInfo);
return CommandReturnCodes.Success;
}

private string GenerateToolInfoText(IDictionary<string, string> info)
{
var stringBuilder = new StringBuilder();
foreach(var kvp in info)
{
stringBuilder.AppendLine($"{kvp.Key}: {kvp.Value}");
}

return stringBuilder.ToString();
}

private string GenerateToolInfoJson(IDictionary<string, string> info)
{
var stream = new MemoryStream();
Utf8JsonWriter utf8JsonWriter = new Utf8JsonWriter(stream, options: new JsonWriterOptions()
{
Indented = false
});

utf8JsonWriter.WriteStartObject();

foreach (var kvp in info)
{
utf8JsonWriter.WriteString(kvp.Key, kvp.Value);
}

utf8JsonWriter.WriteEndObject();
utf8JsonWriter.Flush();

stream.Position = 0;
return new StreamReader(stream).ReadToEnd();
}

private Dictionary<string, string> CollectInformation()
{
var info = new Dictionary<string, string>();
info["Version"] = Utils.DetermineToolVersion();
info["InstallPath"] = GetInstallPath();
return info;
}

private string GetInstallPath() => Directory.GetParent(typeof(Utils).Assembly.Location)!.FullName;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@

var registrar = new TypeRegistrar(serviceCollection);

var app = new CommandApp<RunCommand>(registrar);
var app = new CommandApp(registrar);
app.Configure(config =>
{
config.AddCommand<RunCommand>("start")
.WithDescription("Start the Lambda and/or API Gateway emulator.");
config.AddCommand<ToolInfoCommand>("info")
.WithDescription("Display information about the tool including the version number.");

config.SetApplicationName(Constants.ToolName);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static string DetermineToolVersion()
AssemblyInformationalVersionAttribute? attribute = null;
try
{
var assembly = Assembly.GetEntryAssembly();
var assembly = typeof(Utils).Assembly;
if (assembly == null)
return unknownVersion;
attribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Xunit;
using Amazon.Lambda.TestTool.Services.IO;
using Amazon.Lambda.TestTool.Utilities;
using System.Text.Json.Nodes;

namespace Amazon.Lambda.TestTool.UnitTests.Commands;

Expand Down Expand Up @@ -100,4 +101,41 @@ public async Task ExecuteAsync_EnvPorts_SuccessfulLaunch()
Assert.Equal(CommandReturnCodes.Success, result);
Assert.True(isApiRunning);
}

[Fact]
public void VerifyToolInfo()
{
var writeCalls = 0;
string? versionInfo = null;
Mock<IToolInteractiveService> mockInteractiveService = new Mock<IToolInteractiveService>();
mockInteractiveService.Setup(i => i.WriteLine(It.IsAny<string>()))
.Callback((string message) =>
{
writeCalls++;
versionInfo = message;
});

var settings = new ToolInfoCommandSettings { Format = ToolInfoCommandSettings.InfoFormat.Json };
var command = new ToolInfoCommand(mockInteractiveService.Object);
var context = new CommandContext(new List<string>(), _mockRemainingArgs.Object, "run", null);
command.Execute(context, settings);

Assert.Equal(1, writeCalls);
Assert.True(!string.IsNullOrEmpty(versionInfo));

JsonNode? jsonNode = JsonNode.Parse(versionInfo);
Assert.NotNull(jsonNode);

var version = jsonNode["Version"]?.ToString();
Assert.NotNull(version);

// The Version.TryParse does not like the preview suffix
version = version.Replace("-preview", "");
Assert.True(Version.TryParse(version, out var _));

var installPath = jsonNode["InstallPath"]?.ToString();
Assert.NotNull(installPath);
Assert.True(Directory.Exists(installPath));
Assert.True(Path.IsPathFullyQualified(installPath));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,6 @@ public void NoLaunchWindow_DefaultsToFalse()
Assert.False(settings.NoLaunchWindow);
}

[Fact]
public void DisableLogs_DefaultsToFalse()
{
// Arrange
var settings = new RunCommandSettings();

// Assert
Assert.False(settings.DisableLogs);
}

[Fact]
public void PauseExit_DefaultsToFalse()
{
// Arrange
var settings = new RunCommandSettings();

// Assert
Assert.False(settings.PauseExit);
}

[Fact]
public void ApiGatewayEmulatorMode_DefaultsToNull()
{
Expand Down
Loading