Skip to content

Commit c08853b

Browse files
authored
Hotfix. Remove extra whitespace from commands when using chaining for ExecuteCommand and ExecuteCommandMonitor components. (#564)
1 parent 67a1d27 commit c08853b

File tree

6 files changed

+68
-5
lines changed

6 files changed

+68
-5
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.1.14
1+
2.1.15

src/VirtualClient/VirtualClient.Dependencies.UnitTests/ExecuteCommandTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,36 @@ public async Task ExecuteCommandSupportsCommandChainingOnUnixSystems(string full
103103
}
104104
}
105105

106+
[Test]
107+
[TestCase(
108+
"sudo dmesg && sudo lsblk && sudo mount && sudo df -h && sudo find /sys -name scheduler -print",
109+
"sudo dmesg;sudo lsblk;sudo mount;sudo df -h;sudo find /sys -name scheduler -print")]
110+
public async Task ExecuteCommandSupportsCommandChainingOnUnixSystems_Bug_1(string fullCommand, string expectedCommandExecuted)
111+
{
112+
// Bug Scenario:
113+
// Spaces (whitespace) in the commands due to the chaining SHOULD NOT cause
114+
// parsing issues.
115+
//
116+
// e.g.
117+
// "sudo dmesg && sudo lsblk " resulting in the command being identified as "sudo o lsblk"
118+
119+
this.SetupDefaults(PlatformID.Unix);
120+
121+
using (TestExecuteCommand command = new TestExecuteCommand(this.mockFixture))
122+
{
123+
command.Parameters[nameof(ExecuteCommand.Command)] = fullCommand;
124+
List<string> expectedCommands = new List<string>(expectedCommandExecuted.Split(';'));
125+
126+
this.mockFixture.ProcessManager.OnProcessCreated = (process) =>
127+
{
128+
expectedCommands.Remove(process.FullCommand());
129+
};
130+
131+
await command.ExecuteAsync(CancellationToken.None);
132+
Assert.IsEmpty(expectedCommands);
133+
}
134+
}
135+
106136
[Test]
107137
[TestCase("C:\\\\Users\\User\\anycommand&&C:\\\\home\\user\\anyothercommand", "C:\\\\Users\\User\\anycommand;C:\\\\home\\user\\anyothercommand")]
108138
[TestCase("C:\\\\Users\\User\\anycommand --argument=1&&C:\\\\home\\user\\anyothercommand --argument=2", "C:\\\\Users\\User\\anycommand --argument=1;C:\\\\home\\user\\anyothercommand --argument=2")]

src/VirtualClient/VirtualClient.Dependencies/ExecuteCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ private IEnumerable<string> GetCommandsToExecute()
188188
List<string> commandsToExecute = new List<string>();
189189
bool sudo = this.Command.StartsWith("sudo", StringComparison.OrdinalIgnoreCase);
190190

191-
IEnumerable<string> commands = this.Command.Split("&&", StringSplitOptions.RemoveEmptyEntries & StringSplitOptions.TrimEntries);
191+
IEnumerable<string> commands = this.Command.Split("&&", StringSplitOptions.RemoveEmptyEntries)?.Select(cmd => cmd.Trim());
192192

193193
foreach (string fullCommand in commands)
194194
{

src/VirtualClient/VirtualClient.Main/ExecuteProfileCommand.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,11 @@ protected async Task<EnvironmentLayout> ReadEnvironmentLayoutAsync(IServiceColle
427427
$"Invalid path specified. An environment layout file does not exist at path '{layoutFullPath}'.");
428428
}
429429

430-
string layoutContent = await systemManagement.FileSystem.File.ReadAllTextAsync(layoutFullPath)
431-
.ConfigureAwait(false);
430+
string layoutContent = await RetryPolicies.FileOperations
431+
.ExecuteAsync(() =>
432+
{
433+
return systemManagement.FileSystem.File.ReadAllTextAsync(layoutFullPath);
434+
});
432435

433436
layout = layoutContent.FromJson<EnvironmentLayout>();
434437
}

src/VirtualClient/VirtualClient.Monitors.UnitTests/ExecuteCommandMonitorTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,36 @@ public async Task ExecuteCommandMonitorSupportsCommandChaining(string originalCo
103103
}
104104
}
105105

106+
[Test]
107+
[TestCase(
108+
"sudo dmesg && sudo lsblk && sudo mount && sudo df -h && sudo find /sys -name scheduler -print",
109+
"sudo dmesg;sudo lsblk;sudo mount;sudo df -h;sudo find /sys -name scheduler -print")]
110+
public async Task ExecuteCommandMonitorSupportsCommandChainingOnUnixSystems_Bug_1(string fullCommand, string expectedCommandExecuted)
111+
{
112+
// Bug Scenario:
113+
// Spaces (whitespace) in the commands due to the chaining SHOULD NOT cause
114+
// parsing issues.
115+
//
116+
// e.g.
117+
// "sudo dmesg && sudo lsblk " resulting in the command being identified as "sudo o lsblk"
118+
119+
this.SetupDefaults(PlatformID.Unix);
120+
List<string> commandsExecuted = new List<string>(expectedCommandExecuted.Split(";"));
121+
122+
using (TestExecuteCommandMonitor monitor = new TestExecuteCommandMonitor(this))
123+
{
124+
monitor.Parameters[nameof(ExecuteCommandMonitor.Command)] = fullCommand;
125+
126+
this.ProcessManager.OnProcessCreated = (process) =>
127+
{
128+
commandsExecuted.Remove(process.FullCommand());
129+
};
130+
131+
await monitor.ExecuteCommandAsync(EventContext.None, CancellationToken.None);
132+
Assert.IsEmpty(commandsExecuted);
133+
}
134+
}
135+
106136
[Test]
107137
[TestCase("C:\\\\Users\\User\\anycommand&&C:\\\\home\\user\\anyothercommand", "C:\\\\Users\\User\\anycommand;C:\\\\home\\user\\anyothercommand")]
108138
[TestCase("C:\\\\Users\\User\\anycommand --argument=1&&C:\\\\home\\user\\anyothercommand --argument=2", "C:\\\\Users\\User\\anycommand --argument=1;C:\\\\home\\user\\anyothercommand --argument=2")]

src/VirtualClient/VirtualClient.Monitors/ExecuteCommandMonitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ private IEnumerable<string> GetCommandsToExecute()
357357
List<string> commandsToExecute = new List<string>();
358358
bool sudo = this.Command.StartsWith("sudo", StringComparison.OrdinalIgnoreCase);
359359

360-
IEnumerable<string> commands = this.Command.Split("&&", StringSplitOptions.RemoveEmptyEntries & StringSplitOptions.TrimEntries);
360+
IEnumerable<string> commands = this.Command.Split("&&", StringSplitOptions.RemoveEmptyEntries)?.Select(cmd => cmd.Trim());
361361

362362
foreach (string fullCommand in commands)
363363
{

0 commit comments

Comments
 (0)