Skip to content

Commit

Permalink
Firmware archive related bug fixes (#307)
Browse files Browse the repository at this point in the history
  • Loading branch information
frobijn authored Dec 16, 2024
1 parent b5020e6 commit ab17999
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 38 deletions.
8 changes: 7 additions & 1 deletion nanoFirmwareFlasher.Library/ExitCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,13 @@ public enum ExitCodes
/// <summary>
/// Error clearing cache location.
/// </summary>
[Display(Name = "Error occured when clearing the firmware cache location.")]
[Display(Name = "Error occurred when clearing the firmware cache location.")]
E9014 = 9014,

/// <summary>
/// Can't find the target in the firmware archive.
/// </summary>
[Display(Name = "Can't find the target in the firmware archive.")]
E9015 = 9015,
}
}
34 changes: 34 additions & 0 deletions nanoFirmwareFlasher.Library/FirmwareArchiveManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,40 @@ public List<CloudSmithPackageDetail> GetTargetList(
return targetPackages;
}

/// <summary>
/// Get the latest version present in the firmware archive for the specified target.
/// </summary>
/// <param name="preview">Option for preview version.</param>
/// <param name="target">Target to find the latest version of.</param>
/// <returns>The <see cref="CloudSmithPackageDetail"/> with details on latest firmware package for the target, or <see langword="null"/> if none is present.</returns>
public CloudSmithPackageDetail GetLatestVersion(
bool preview,
string target)
{
CloudSmithPackageDetail result = null;
Version latest = null;
if (Directory.Exists(_archivePath) && !string.IsNullOrEmpty(target))
{
foreach (string filePath in Directory.EnumerateFiles(_archivePath, $"{target}-*{INFOFILE_EXTENSION}"))
{
PersistedPackageInformation packageInformation = JsonConvert.DeserializeObject<PersistedPackageInformation>(File.ReadAllText(filePath));
if (packageInformation is not null && packageInformation.IsPreview == preview)
{
if (Version.TryParse(packageInformation.Version, out Version version))
{
if (latest is null || latest < version)
{
latest = version;
result = packageInformation;
}
}
}
}
}

return result;
}

/// <summary>
/// Download a firmware package from the repository and add it to the archive directory
/// </summary>
Expand Down
14 changes: 13 additions & 1 deletion nanoFirmwareFlasher.Library/FirmwarePackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,18 @@ void UpdateLocationPathAndFileName(bool initial)

}

if (archiveDirectoryPath is not null && Version is null)
{
// Find the latest version in the archive directory
var archiveManager = new FirmwareArchiveManager(archiveDirectoryPath);
Version = archiveManager.GetLatestVersion(_preview, _targetName)?.Version;
if (Version is null)
{
// Package is considered to be not present, even if it does exist in the cache location
return (ExitCodes.E9015, null);
}
}

// create the download folder
try
{
Expand All @@ -369,7 +381,7 @@ void UpdateLocationPathAndFileName(bool initial)
if (!File.Exists(archiveFileName))
{
// Package is considered to be not present, even if it does exist in the cache location
return (ExitCodes.E9007, null);
return (ExitCodes.E9015, null);
}

if (!skipDownload)
Expand Down
49 changes: 36 additions & 13 deletions nanoFirmwareFlasher.Tests/FirmwarePackageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ where d.StartsWith(targetName + "-")

[TestMethod]
[TestCategory("CloudSmith")]
public void FirmwarePackage_DebugFirmware_Download()
public void FirmwarePackage_LegacyVirtualDevice_Download()
{
#region Setup
using var output = new OutputWriterHelper();
Expand Down Expand Up @@ -236,32 +236,55 @@ public void FirmwarePackage_FromArchive()
{
Assert.Inconclusive("Cannot download the ESP32 package.");
}
string testTargetName = "NO_REAL_TARGET";
string testVersion = "0.0.0.0";
File.Copy(Path.Combine(cacheDirectory, package.Name, $"{package.Name}-{package.Version}.zip"), Path.Combine(archiveDirectory, $"{testTargetName}-{testVersion}.zip"));
string testTarget1Name = "TARGET1_IN_ARCHIVE_ONLY";
string testTarget2Name = "TARGET2_IN_ARCHIVE_ONLY";
string testVersion = "1.23.4.5";
string testOldVersion = "1.6.7.8";

// Copy the package to the archive directory, modified for TARGET1_IN_ARCHIVE_ONLY and TARGET2_IN_ARCHIVE_ONLY
File.Copy(Path.Combine(cacheDirectory, package.Name, $"{package.Name}-{package.Version}.zip"), Path.Combine(archiveDirectory, $"{testTarget1Name}-{testVersion}.zip"));
File.WriteAllText(Path.Combine(archiveDirectory, $"{testTarget1Name}-{testVersion}.zip.json"), $@"{{ ""Name"": ""{testTarget1Name}"", ""Version"": ""{testVersion}"", ""Platform"": ""esp32"" }}");
File.Copy(Path.Combine(cacheDirectory, package.Name, $"{package.Name}-{package.Version}.zip"), Path.Combine(archiveDirectory, $"{testTarget2Name}-{testVersion}.zip"));
File.WriteAllText(Path.Combine(archiveDirectory, $"{testTarget2Name}-{testVersion}.zip.json"), $@"{{ ""Name"": ""{testTarget2Name}"", ""Version"": ""{testVersion}"", ""Platform"": ""esp32"" }}");

// Create an invalid package for an earlier version of TARGET2_IN_ARCHIVE_ONLY - this should not be used
File.WriteAllText(Path.Combine(archiveDirectory, $"{testTarget2Name}-{testOldVersion}.zip"), "");
File.WriteAllText(Path.Combine(archiveDirectory, $"{testTarget2Name}-{testOldVersion}.zip.json"), $@"{{ ""Name"": ""{testTarget2Name}"", ""Version"": ""{testOldVersion}"", ""Platform"": ""esp32"" }}");
#endregion

#region Get package that exist in the archive directory but not in the repository
#region Get package that exist in the archive directory but not in the repository; include version
output.Reset();
var actual = new Esp32Firmware(testTargetName, testVersion, false, null);
var actual = new Esp32Firmware(testTarget1Name, testVersion, false, null);
exitCode = actual.DownloadAndExtractAsync(archiveDirectory).GetAwaiter().GetResult();

Assert.AreEqual(ExitCodes.OK, exitCode);
output.AssertAreEqual("");
Assert.IsTrue(Directory.Exists(Path.Combine(cacheDirectory, testTargetName)));
Assert.IsTrue(File.Exists(Path.Combine(cacheDirectory, testTargetName, $"{testTargetName}-{testVersion}.zip")));
Assert.IsTrue(File.Exists(Path.Combine(cacheDirectory, testTargetName, "nanoCLR.bin")));
Assert.IsTrue(Directory.Exists(Path.Combine(cacheDirectory, testTarget1Name)));
Assert.IsTrue(File.Exists(Path.Combine(cacheDirectory, testTarget1Name, $"{testTarget1Name}-{testVersion}.zip")));
Assert.IsTrue(File.Exists(Path.Combine(cacheDirectory, testTarget1Name, "nanoCLR.bin")));
#endregion

#region Get package that exist in the archive directory but not in the repository; do not include version
output.Reset();
actual = new Esp32Firmware(testTarget2Name, null, false, null);
exitCode = actual.DownloadAndExtractAsync(archiveDirectory).GetAwaiter().GetResult();

Assert.AreEqual(ExitCodes.OK, exitCode);
output.AssertAreEqual("");
Assert.IsTrue(Directory.Exists(Path.Combine(cacheDirectory, testTarget2Name)));
Assert.IsTrue(File.Exists(Path.Combine(cacheDirectory, testTarget2Name, $"{testTarget2Name}-{testVersion}.zip")));
Assert.IsTrue(File.Exists(Path.Combine(cacheDirectory, testTarget2Name, "nanoCLR.bin")));
#endregion

#region Get package that does not exist in the archive directory
testTargetName = "MISSING_TARGET";
testTarget1Name = "MISSING_TARGET";

actual = new Esp32Firmware(testTargetName, testVersion, false, null);
actual = new Esp32Firmware(testTarget1Name, testVersion, false, null);
exitCode = actual.DownloadAndExtractAsync(archiveDirectory).GetAwaiter().GetResult();

Assert.AreEqual(ExitCodes.E9007, exitCode);
Assert.AreEqual(ExitCodes.E9015, exitCode);
output.AssertAreEqual("");
Assert.IsFalse(File.Exists(Path.Combine(cacheDirectory, testTargetName, $"{testTargetName}-{testVersion}.zip")));
Assert.IsFalse(File.Exists(Path.Combine(cacheDirectory, testTarget1Name, $"{testTarget1Name}-{testVersion}.zip")));
#endregion
}
}
Expand Down
34 changes: 17 additions & 17 deletions nanoFirmwareFlasher.Tests/ToolFirmwareArchiveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ public void FirmwareArchive_Platform_UpdateArchive_ListTargets()
#endregion

#region List empty archive
int actual = Program.Main(["--listtargets", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fromfwarchive", "--fwarchivepath", archiveDirectory])
int actual = Program.Main(["--listtargets", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fromarchive", "--archivepath", archiveDirectory])
.GetAwaiter().GetResult();
Assert.AreEqual((int)ExitCodes.OK, actual);
#endregion

#region Update archive
output.Reset();
actual = Program.Main(["--updatefwarchive", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fwarchivepath", archiveDirectory])
actual = Program.Main(["--updatearchive", "--platform", $"{SupportedPlatform.ti_simplelink}", "--archivepath", archiveDirectory])
.GetAwaiter().GetResult();
Assert.AreEqual((int)ExitCodes.OK, actual);
#endregion

#region List filled archive
output.Reset();
actual = Program.Main(["--listtargets", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fromfwarchive", "--fwarchivepath", archiveDirectory])
actual = Program.Main(["--listtargets", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fromarchive", "--archivepath", archiveDirectory])
.GetAwaiter().GetResult();
Assert.AreEqual((int)ExitCodes.OK, actual);

Expand All @@ -70,14 +70,14 @@ public void FirmwareArchive_Target_UpdateArchive_ListTargets()

#region Update archive
output.Reset();
int actual = Program.Main(["--updatefwarchive", "--target", $"{allPackages[0].Name}", "--fwarchivepath", archiveDirectory])
int actual = Program.Main(["--updatearchive", "--target", $"{allPackages[0].Name}", "--archivepath", archiveDirectory])
.GetAwaiter().GetResult();
Assert.AreEqual((int)ExitCodes.OK, actual);
#endregion

#region List filled archive
output.Reset();
actual = Program.Main(["--listtargets", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fromfwarchive", "--fwarchivepath", archiveDirectory])
actual = Program.Main(["--listtargets", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fromarchive", "--archivepath", archiveDirectory])
.GetAwaiter().GetResult();
Assert.AreEqual((int)ExitCodes.OK, actual);

Expand All @@ -96,11 +96,11 @@ public void FirmwareArchive_ListTargets_InvalidArguments()
string testDirectory = TestDirectoryHelper.GetTestDirectory(TestContext);
string archiveDirectory = Path.Combine(testDirectory, "archive");

int actual = Program.Main(["--listtargets", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fromfwarchive", "--verbosity", "diagnostic"])
int actual = Program.Main(["--listtargets", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fromarchive", "--verbosity", "diagnostic"])
.GetAwaiter().GetResult();

Assert.AreEqual((int)ExitCodes.E9000, actual);
Assert.IsTrue(output.Output.Contains("--fwarchivepath is required when --fromfwarchive is specified."));
Assert.IsTrue(output.Output.Contains("--archivepath is required when --fromarchive is specified."));
}

[TestMethod]
Expand All @@ -110,25 +110,25 @@ public void FirmwareArchive_UpdateArchive_InvalidArguments()
string testDirectory = TestDirectoryHelper.GetTestDirectory(TestContext);
string archiveDirectory = Path.Combine(testDirectory, "archive");

int actual = Program.Main(["--updatefwarchive", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fromfwarchive", "--verbosity", "diagnostic"])
int actual = Program.Main(["--updatearchive", "--platform", $"{SupportedPlatform.ti_simplelink}", "--fromarchive", "--verbosity", "diagnostic"])
.GetAwaiter().GetResult();

Assert.AreEqual((int)ExitCodes.E9000, actual);
Assert.IsTrue(output.Output.Contains("Incompatible option --fromfwarchive combined with --updatefwarchive."));
Assert.IsTrue(output.Output.Contains("Incompatible option --fromarchive combined with --updatearchive."));

output.Reset();
actual = Program.Main(["--updatefwarchive", "--platform", $"{SupportedPlatform.ti_simplelink}", "--verbosity", "diagnostic"])
actual = Program.Main(["--updatearchive", "--platform", $"{SupportedPlatform.ti_simplelink}", "--verbosity", "diagnostic"])
.GetAwaiter().GetResult();

Assert.AreEqual((int)ExitCodes.E9000, actual);
Assert.IsTrue(output.Output.Contains("--fwarchivepath is required when --updatefwarchive is specified."));
Assert.IsTrue(output.Output.Contains("--archivepath is required when --updatearchive is specified."));

output.Reset();
actual = Program.Main(["--updatefwarchive", "--fwarchivepath", $"{SupportedPlatform.ti_simplelink}", "--verbosity", "diagnostic"])
actual = Program.Main(["--updatearchive", "--archivepath", $"{SupportedPlatform.ti_simplelink}", "--verbosity", "diagnostic"])
.GetAwaiter().GetResult();

Assert.AreEqual((int)ExitCodes.E9000, actual);
Assert.IsTrue(output.Output.Contains("--platform or --target is required when --updatefwarchive is specified."));
Assert.IsTrue(output.Output.Contains("--platform or --target is required when --updatearchive is specified."));
}

[TestMethod]
Expand All @@ -138,18 +138,18 @@ public void FirmwareArchive_UpdateFirmware_InvalidArguments()
string testDirectory = TestDirectoryHelper.GetTestDirectory(TestContext);
string archiveDirectory = Path.Combine(testDirectory, "archive");

int actual = Program.Main(["--serialport", "COM3", "--target", "SOME_TARGET", "--fromfwarchive", "--verbosity", "diagnostic"])
int actual = Program.Main(["--serialport", "COM3", "--target", "SOME_TARGET", "--fromarchive", "--verbosity", "diagnostic"])
.GetAwaiter().GetResult();

Assert.AreEqual((int)ExitCodes.E9000, actual);
Assert.IsTrue(output.Output.Contains("--fwarchivepath is required when --fromfwarchive is specified."));
Assert.IsTrue(output.Output.Contains("--archivepath is required when --fromarchive is specified."));

output.Reset();
actual = Program.Main(["--serialport", "COM3", "--target", "SOME_TARGET", "--fwarchivepath", archiveDirectory, "--verbosity", "diagnostic"])
actual = Program.Main(["--serialport", "COM3", "--target", "SOME_TARGET", "--archivepath", archiveDirectory, "--verbosity", "diagnostic"])
.GetAwaiter().GetResult();

Assert.AreEqual((int)ExitCodes.E9000, actual);
Assert.IsTrue(output.Output.Contains("--fromfwarchive is required when --fwarchivepath is specified."));
Assert.IsTrue(output.Output.Contains("--fromarchive is required when --archivepath is specified."));
}
}
}
12 changes: 6 additions & 6 deletions nanoFirmwareFlasher.Tool/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ static async Task RunOptionsAndReturnExitCodeAsync(Options o)
if (string.IsNullOrEmpty(o.FwArchivePath))
{
_exitCode = ExitCodes.E9000;
_extraMessage = "--fwarchivepath is required when --fromfwarchive is specified.";
_extraMessage = "--archivepath is required when --fromarchive is specified.";
return;
}

Expand Down Expand Up @@ -558,20 +558,20 @@ static async Task RunOptionsAndReturnExitCodeAsync(Options o)
if (o.FromFwArchive)
{
_exitCode = ExitCodes.E9000;
_extraMessage = "Incompatible option --fromfwarchive combined with --updatefwarchive.";
_extraMessage = "Incompatible option --fromarchive combined with --updatearchive.";
return;
}
if (string.IsNullOrEmpty(o.FwArchivePath))
{
_exitCode = ExitCodes.E9000;
_extraMessage = $"--fwarchivepath is required when --updatefwarchive is specified.";
_extraMessage = $"--archivepath is required when --updatearchive is specified.";
return;
}

if (o.Platform is null && string.IsNullOrEmpty(o.TargetName))
{
_exitCode = ExitCodes.E9000;
_extraMessage = $"--platform or --target is required when --updatefwarchive is specified.";
_extraMessage = $"--platform or --target is required when --updatearchive is specified.";
return;
}

Expand All @@ -591,14 +591,14 @@ static async Task RunOptionsAndReturnExitCodeAsync(Options o)
if (o.FromFwArchive)
{
_exitCode = ExitCodes.E9000;
_extraMessage = $"--fwarchivepath is required when --fromfwarchive is specified.";
_extraMessage = $"--archivepath is required when --fromarchive is specified.";
return;
}
}
else if (!o.FromFwArchive)
{
_exitCode = ExitCodes.E9000;
_extraMessage = $"--fromfwarchive is required when --fwarchivepath is specified.";
_extraMessage = $"--fromarchive is required when --archivepath is specified.";
return;
}
#endregion
Expand Down

0 comments on commit ab17999

Please sign in to comment.