using System;
using System.Diagnostics;
using Xunit;
using Amazon.Common.DotNetCli.Tools.Test.Mocks;
#if NETCOREAPP3_1_OR_GREATER
using System.Runtime.InteropServices;
#endif
namespace Amazon.Common.DotNetCli.Tools.Test;
public class PosixUserHelperTest
{
///
/// This is more of a quasi-functional test than a unit test.
/// If run under MacOS or Linux, it will confirm that UID and GID can be retrieved
///
[Fact]
public void TestGetEffectiveUser()
{
#if NETCOREAPP3_1_OR_GREATER
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ||
RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD))
{
var mockLogger = new MockToolLogger();
Assert.True(PosixUserHelper.IsRunningInPosix);
var user = PosixUserHelper.GetEffectiveUser(mockLogger);
Assert.True(user.HasValue);
Assert.True(user.Value.UserID >= 0);
Assert.True(user.Value.GroupID >= 0);
}
else
{
Assert.False(PosixUserHelper.IsRunningInPosix);
}
#else
Assert.False(PosixUserHelper.IsRunningInPosix);
#endif
}
///
/// This mocks execution of the "id" commands
///
[Fact]
public void TestGetEffectiveUserSucceeds()
{
var mockProcesses = new MockIdProcessFactory(new[]
{
new ProcessInstance.ProcessResults
{
Executed = true,
ExitCode = 0,
Output = "998",
Error = ""
},
new ProcessInstance.ProcessResults
{
Executed = true,
ExitCode = 0,
Output = "999",
Error = ""
}
});
var mockLogger = new MockToolLogger();
var user = PosixUserHelper.GetEffectiveUser(mockLogger, mockProcesses);
Assert.True(user.HasValue);
Assert.True(user.Value.UserID >= 998);
Assert.True(user.Value.GroupID >= 999);
}
[Fact]
public void TestGetEffectiveUserFails()
{
var mockProcesses = new MockIdProcessFactory(new[]
{
new ProcessInstance.ProcessResults
{
Executed = true,
ExitCode = 0,
Output = "998",
Error = ""
},
new ProcessInstance.ProcessResults
{
Executed = true,
ExitCode = -1,
Output = "",
Error = "Sad trombones"
}
});
var mockLogger = new MockToolLogger();
var user = PosixUserHelper.GetEffectiveUser(mockLogger, mockProcesses);
Assert.False(user.HasValue);
Assert.Equal( "Error executing \"id -g\" - exit code -1 Sad trombones\nWarning: Unable to get effective group from \"id -g\"\n", mockLogger.Log);
}
///
/// Mock for process factory so that we can fake "id" results
///
private class MockIdProcessFactory : IProcessFactory
{
private readonly ProcessInstance.ProcessResults[] _mockedResults;
private int _counter;
public MockIdProcessFactory(ProcessInstance.ProcessResults[] mockedResults)
{
_mockedResults = mockedResults;
}
public ProcessInstance.ProcessResults RunProcess(ProcessStartInfo info, int timeout = 60000)
{
if (_counter < _mockedResults.Length)
{
return _mockedResults[_counter++];
}
throw new Exception("Out of mocked process responses");
}
}
}