Skip to content

Commit

Permalink
refa (all operations): we now throw an argument exception if the give…
Browse files Browse the repository at this point in the history
…n host-device-model/manufacturer parameters is dud
  • Loading branch information
ksidirop-laerdal committed Jan 30, 2025
1 parent 33662a0 commit b4c15f0
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ namespace Laerdal.McuMgr.Tests.FileDownloader
public partial class FileDownloaderTestbed
{
[Theory]
[InlineData("FDT.BD.STAE.GIRFP.010", "")]
[InlineData("FDT.BD.STAE.GIRFP.020", null)]
[InlineData("FDT.BD.STAE.GIRFP.030", "foo/bar/")] // paths are not allowed
[InlineData("FDT.BD.STAE.GIRFP.040", "/foo/bar/")] // to end with a slash
public void BeginDownload_ShouldThrowArgumentException_GivenInvalidRemoteFilePath(string testcaseNickname, string remoteFilePath)
[InlineData("FDT.BD.STAE.GIP.010", "", "foobar", "acme corp.")]
[InlineData("FDT.BD.STAE.GIP.020", null, "foobar", "acme corp.")]
[InlineData("FDT.BD.STAE.GIP.030", "foo/bar/", "foobar", "acme corp.")] // paths are not allowed
[InlineData("FDT.BD.STAE.GIP.040", "/foo/bar/", "foobar", "acme corp.")] // to end with a slash
[InlineData("FDT.BD.STAE.GIP.050", "/foo/bar", "", "acme corp.")] // invalid hostDeviceModel
[InlineData("FDT.BD.STAE.GIP.060", "/foo/bar", " ", "acme corp.")] // invalid hostDeviceModel
[InlineData("FDT.BD.STAE.GIP.070", "/foo/bar", "foobar", "")] // invalid hostDeviceManufacturer
[InlineData("FDT.BD.STAE.GIP.080", "/foo/bar", "foobar", " ")] // invalid hostDeviceManufacturer
public void BeginDownload_ShouldThrowArgumentException_GivenInvalidParameters(string testcaseNickname, string remoteFilePath, string hostDeviceModel, string hostDeviceManufacturer)
{
// Arrange
var mockedFileData = new byte[] { 1, 2, 3 };
Expand All @@ -26,10 +30,9 @@ public void BeginDownload_ShouldThrowArgumentException_GivenInvalidRemoteFilePat

// Act
var work = new Func<EFileDownloaderVerdict>(() => fileDownloader.BeginDownload(
hostDeviceModel: "foobar",
hostDeviceManufacturer: "acme corp.",

remoteFilePath: remoteFilePath
remoteFilePath: remoteFilePath,
hostDeviceModel: hostDeviceModel,
hostDeviceManufacturer: hostDeviceManufacturer
));

// Assert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ namespace Laerdal.McuMgr.Tests.FileUploader
public partial class FileUploaderTestbed
{
[Theory]
[InlineData("FUT.BD.STAE.GIRFP.010", "")]
[InlineData("FUT.BD.STAE.GIRFP.020", null)]
[InlineData("FUT.BD.STAE.GIRFP.030", "foo/bar/")] // paths are not allowed
[InlineData("FUT.BD.STAE.GIRFP.040", "/foo/bar/")] // to end with a slash
public void BeginUpload_ShouldThrowArgumentException_GivenInvalidRemoteFilePath(string testcaseNickname, string remoteFilePath)
[InlineData("FUT.BD.STAE.GIP.010", "", "foobar", "acme corp.")]
[InlineData("FUT.BD.STAE.GIP.020", null, "foobar", "acme corp.")]
[InlineData("FUT.BD.STAE.GIP.030", "foo/bar/", "foobar", "acme corp.")] // paths are not allowed
[InlineData("FUT.BD.STAE.GIP.040", "/foo/bar/", "foobar", "acme corp.")] // to end with a slash
[InlineData("FUT.BD.STAE.GIP.050", "/foo/bar", "", "acme corp.")] // invalid hostDeviceModel
[InlineData("FUT.BD.STAE.GIP.060", "/foo/bar", " ", "acme corp.")] // invalid hostDeviceModel
[InlineData("FUT.BD.STAE.GIP.070", "/foo/bar", "foobar", "")] // invalid hostDeviceManufacturer
[InlineData("FUT.BD.STAE.GIP.080", "/foo/bar", "foobar", " ")] // invalid hostDeviceManufacturer
public void BeginUpload_ShouldThrowArgumentException_GivenInvalidParameters(string testcaseNickname, string remoteFilePath, string hostDeviceModel, string hostDeviceManufacturer)
{
// Arrange
var mockedFileData = new byte[] { 1, 2, 3 };
Expand All @@ -26,8 +30,8 @@ public void BeginUpload_ShouldThrowArgumentException_GivenInvalidRemoteFilePath(

// Act
var work = new Func<EFileUploaderVerdict>(() => fileUploader.BeginUpload(
hostDeviceModel: "foobar",
hostDeviceManufacturer: "acme corp.",
hostDeviceModel: hostDeviceModel,
hostDeviceManufacturer: hostDeviceManufacturer,

data: mockedFileData,
remoteFilePath: remoteFilePath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ namespace Laerdal.McuMgr.Tests.FirmwareInstaller
public partial class FirmwareInstallerTestbed
{
[Theory]
[InlineData("FIT.BI.STAE.GIFDB.010", null)]
[InlineData("FIT.BI.STAE.GIFDB.020", new byte[] {})]
public void BeginInstallation_ShouldThrowArgumentException_GivenInvalidFirmwareDataBytes(string testcaseNickname, byte[] mockedFileData)
[InlineData("FIT.BI.STAE.GIFDB.010", new byte[] {}, "foobar", "acme corp.")]
[InlineData("FIT.BI.STAE.GIFDB.020", null, "foobar", "acme corp.")]
[InlineData("FIT.BI.STAE.GIFDB.030", new byte[] { 1 }, "", "acme corp.")] // invalid hostDeviceModel
[InlineData("FIT.BI.STAE.GIFDB.040", new byte[] { 1 }, " ", "acme corp.")] // invalid hostDeviceModel
[InlineData("FIT.BI.STAE.GIFDB.050", new byte[] { 1 }, "foobar", "")] // invalid hostDeviceManufacturer
[InlineData("FIT.BI.STAE.GIFDB.060", new byte[] { 1 }, "foobar", " ")] // invalid hostDeviceManufacturer
public void BeginInstallation_ShouldThrowArgumentException_GivenInvalidParameters(string testcaseNickname, byte[] mockedFileData, string hostDeviceModel, string hostDeviceManufacturer)
{
// Arrange
var mockedNativeFirmwareInstallerProxy = new MockedGreenNativeFirmwareInstallerProxySpy1(new GenericNativeFirmwareInstallerCallbacksProxy_());
Expand All @@ -23,8 +27,8 @@ public void BeginInstallation_ShouldThrowArgumentException_GivenInvalidFirmwareD
// Act
var work = new Func<EFirmwareInstallationVerdict>(() => firmwareInstaller.BeginInstallation(
data: mockedFileData,
hostDeviceModel: "foobar",
hostDeviceManufacturer: "acme corp."
hostDeviceModel: hostDeviceModel,
hostDeviceManufacturer: hostDeviceManufacturer
));

// Assert
Expand Down
29 changes: 25 additions & 4 deletions Laerdal.McuMgr/Shared/Common/Helpers/RemoteFilePathHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,32 @@ namespace Laerdal.McuMgr.Common.Helpers
{
static internal class RemoteFilePathHelpers
{
static public void ValidateRemoteFilePathsWithDataBytes<T>(IDictionary<string, T> remoteFilePathsWithTheirDataBytes)
static internal string ValidateAndSanitizeRemoteFilePath(string remoteFilePath)
{
remoteFilePathsWithTheirDataBytes = remoteFilePathsWithTheirDataBytes ?? throw new ArgumentNullException(nameof(remoteFilePathsWithTheirDataBytes));
ValidateRemoteFilePath(remoteFilePath); //throws an exception if something is wrong

return SanitizeRemoteFilePath(remoteFilePath);
}

static public IReadOnlyDictionary<string, T> ValidateAndSanitizeRemoteFilePathsWithData<T>(IDictionary<string, T> remoteFilePathsWithTheirDataBytes)
{
ValidateRemoteFilePathsWithData(remoteFilePathsWithTheirDataBytes); //throws an exception if something is wrong

foreach (var pathAndDataBytes in remoteFilePathsWithTheirDataBytes)
return SanitizeRemoteFilePathsWithData(remoteFilePathsWithTheirDataBytes);
}

static internal string[] ValidateAndSanitizeRemoteFilePaths(IEnumerable<string> remoteFilePaths)
{
ValidateRemoteFilePaths(remoteFilePaths); //throws an exception if something is wrong

return SanitizeRemoteFilePaths(remoteFilePaths);
}

static public void ValidateRemoteFilePathsWithData<T>(IDictionary<string, T> remoteFilePathsWithTheirData)
{
remoteFilePathsWithTheirData = remoteFilePathsWithTheirData ?? throw new ArgumentNullException(nameof(remoteFilePathsWithTheirData));

foreach (var pathAndDataBytes in remoteFilePathsWithTheirData)
{
ValidatePayload(pathAndDataBytes.Value);
ValidateRemoteFilePath(pathAndDataBytes.Key);
Expand Down Expand Up @@ -70,7 +91,7 @@ static public IReadOnlyDictionary<string, T> SanitizeRemoteFilePathsWithData<T>(

return results;
}

//used by the downloader
static internal string[] SanitizeRemoteFilePaths(IEnumerable<string> remoteFilePaths)
{
Expand Down
24 changes: 20 additions & 4 deletions Laerdal.McuMgr/Shared/FileDownloader/FileDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,13 @@ public EFileDownloaderVerdict BeginDownload(
int? windowCapacity = null //not applicable currently but nordic considers these for future use
)
{
RemoteFilePathHelpers.ValidateRemoteFilePath(remoteFilePath); // order
remoteFilePath = RemoteFilePathHelpers.SanitizeRemoteFilePath(remoteFilePath); // order
if (string.IsNullOrWhiteSpace(hostDeviceModel))
throw new ArgumentException("Host device model cannot be null or whitespace", nameof(hostDeviceModel));

if (string.IsNullOrWhiteSpace(hostDeviceManufacturer))
throw new ArgumentException("Host device manufacturer cannot be null or whitespace", nameof(hostDeviceManufacturer));

remoteFilePath = RemoteFilePathHelpers.ValidateAndSanitizeRemoteFilePath(remoteFilePath);

var failsafeConnectionSettings = ConnectionSettingsHelpers.GetFailSafeConnectionSettingsIfHostDeviceIsProblematic(
initialMtuSize: initialMtuSize,
Expand Down Expand Up @@ -175,8 +180,13 @@ public async Task<IDictionary<string, byte[]>> DownloadAsync(
int? memoryAlignment = null
)
{
RemoteFilePathHelpers.ValidateRemoteFilePaths(remoteFilePaths); // order
var sanitizedUniqueRemoteFilesPaths = RemoteFilePathHelpers.SanitizeRemoteFilePaths(remoteFilePaths); // order
if (string.IsNullOrWhiteSpace(hostDeviceModel))
throw new ArgumentException("Host device model cannot be null or whitespace", nameof(hostDeviceModel));

if (string.IsNullOrWhiteSpace(hostDeviceManufacturer))
throw new ArgumentException("Host device manufacturer cannot be null or whitespace", nameof(hostDeviceManufacturer));

var sanitizedUniqueRemoteFilesPaths = RemoteFilePathHelpers.ValidateAndSanitizeRemoteFilePaths(remoteFilePaths);

var results = sanitizedUniqueRemoteFilesPaths.ToDictionary(
keySelector: x => x,
Expand Down Expand Up @@ -231,6 +241,12 @@ public async Task<byte[]> DownloadAsync(
if (maxTriesCount <= 0)
throw new ArgumentOutOfRangeException(nameof(maxTriesCount), maxTriesCount, "Must be greater than zero!");

if (string.IsNullOrWhiteSpace(hostDeviceModel))
throw new ArgumentException("Host device model cannot be null or whitespace", nameof(hostDeviceModel));

if (string.IsNullOrWhiteSpace(hostDeviceManufacturer))
throw new ArgumentException("Host device manufacturer cannot be null or whitespace", nameof(hostDeviceManufacturer));

gracefulCancellationTimeoutInMs = gracefulCancellationTimeoutInMs >= 0 //we want to ensure that the timeout is always sane
? gracefulCancellationTimeoutInMs
: DefaultGracefulCancellationTimeoutInMs;
Expand Down
26 changes: 20 additions & 6 deletions Laerdal.McuMgr/Shared/FileUploader/FileUploader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ public EFileUploaderVerdict BeginUpload(
int? memoryAlignment = null
)
{
data = data ?? throw new ArgumentNullException(nameof(data));
if (string.IsNullOrWhiteSpace(hostDeviceModel))
throw new ArgumentException("Host device model cannot be null or whitespace", nameof(hostDeviceModel));

if (string.IsNullOrWhiteSpace(hostDeviceManufacturer))
throw new ArgumentException("Host device manufacturer cannot be null or whitespace", nameof(hostDeviceManufacturer));

RemoteFilePathHelpers.ValidateRemoteFilePath(remoteFilePath); // order
remoteFilePath = RemoteFilePathHelpers.SanitizeRemoteFilePath(remoteFilePath); // order
data = data ?? throw new ArgumentNullException(nameof(data));
remoteFilePath = RemoteFilePathHelpers.ValidateAndSanitizeRemoteFilePath(remoteFilePath);

var failsafeConnectionSettings = ConnectionSettingsHelpers.GetFailSafeConnectionSettingsIfHostDeviceIsProblematic(
hostDeviceModel: hostDeviceModel,
Expand Down Expand Up @@ -217,11 +221,15 @@ public async Task<IEnumerable<string>> UploadAsync<TData>(
int? memoryAlignment = null
) where TData : notnull
{
RemoteFilePathHelpers.ValidateRemoteFilePathsWithDataBytes(remoteFilePathsAndTheirData);
var sanitizedRemoteFilePathsAndTheirData = RemoteFilePathHelpers.SanitizeRemoteFilePathsWithData(remoteFilePathsAndTheirData);
if (string.IsNullOrWhiteSpace(hostDeviceModel))
throw new ArgumentException("Host device model cannot be null or whitespace", nameof(hostDeviceModel));

var filesThatFailedToBeUploaded = new List<string>(2);
if (string.IsNullOrWhiteSpace(hostDeviceManufacturer))
throw new ArgumentException("Host device manufacturer cannot be null or whitespace", nameof(hostDeviceManufacturer));

var sanitizedRemoteFilePathsAndTheirData = RemoteFilePathHelpers.ValidateAndSanitizeRemoteFilePathsWithData(remoteFilePathsAndTheirData);

var filesThatFailedToBeUploaded = new List<string>(2);
foreach (var x in sanitizedRemoteFilePathsAndTheirData)
{
try
Expand Down Expand Up @@ -287,6 +295,12 @@ public async Task UploadAsync<TData>(

if (maxTriesCount <= 0)
throw new ArgumentOutOfRangeException(nameof(maxTriesCount), maxTriesCount, "Must be greater than zero");

if (string.IsNullOrWhiteSpace(hostDeviceModel))
throw new ArgumentException("Host device model cannot be null or whitespace", nameof(hostDeviceModel));

if (string.IsNullOrWhiteSpace(hostDeviceManufacturer))
throw new ArgumentException("Host device manufacturer cannot be null or whitespace", nameof(hostDeviceManufacturer));

var dataArray = await GetDataAsByteArray_(data, autodisposeStream);

Expand Down
12 changes: 12 additions & 0 deletions Laerdal.McuMgr/Shared/FirmwareInstaller/FirmwareInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ public EFirmwareInstallationVerdict BeginInstallation(
if (data == null || !data.Any())
throw new ArgumentException("The data byte-array parameter is null or empty", nameof(data));

if (string.IsNullOrWhiteSpace(hostDeviceModel))
throw new ArgumentException("Host device model cannot be null or whitespace", nameof(hostDeviceModel));

if (string.IsNullOrWhiteSpace(hostDeviceManufacturer))
throw new ArgumentException("Host device manufacturer cannot be null or whitespace", nameof(hostDeviceManufacturer));

var failsafeConnectionSettings = ConnectionSettingsHelpers.GetFailSafeConnectionSettingsIfHostDeviceIsProblematic(
uploadingNotDownloading: true,

Expand Down Expand Up @@ -205,6 +211,12 @@ public async Task InstallAsync(
if (maxTriesCount <= 0)
throw new ArgumentOutOfRangeException(nameof(maxTriesCount), maxTriesCount, "The maximum amount of tries must be greater than zero");

if (string.IsNullOrWhiteSpace(hostDeviceModel))
throw new ArgumentException("Host device model cannot be null or whitespace", nameof(hostDeviceModel));

if (string.IsNullOrWhiteSpace(hostDeviceManufacturer))
throw new ArgumentException("Host device manufacturer cannot be null or whitespace", nameof(hostDeviceManufacturer));

gracefulCancellationTimeoutInMs = gracefulCancellationTimeoutInMs >= 0 //we want to ensure that the timeout is always sane
? gracefulCancellationTimeoutInMs
: DefaultGracefulCancellationTimeoutInMs;
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,8 @@ private void CleanupDeviceResetter()
);

await _massFileUploader.UploadAsync(
hostDeviceModel: DeviceInfo.Model,
hostDeviceManufacturer: DeviceInfo.Manufacturer,
maxTriesPerUpload: MassFileUploadingMaxTriesPerUpload,
timeoutPerUploadInMs: 4 * 60 * 1_000, //4mins per upload
sleepTimeBetweenRetriesInMs: MassFileUploadingSleepTimeBetweenRetriesInSecs * 1_000,
Expand Down

0 comments on commit b4c15f0

Please sign in to comment.