(refactor): exec tests
This commit is contained in:
parent
b68d8c1bca
commit
4bb2edcd77
@ -8,7 +8,7 @@
|
||||
|
||||
<!-- NuGet package metadata -->
|
||||
<PackageId>PodmanClient.DotNet</PackageId>
|
||||
<Version>1.0.2</Version>
|
||||
<Version>1.0.3</Version>
|
||||
<Authors>Maksym Sadovnychyy</Authors>
|
||||
<Company>MAKS-IT</Company>
|
||||
<Product>PodmanClient</Product>
|
||||
|
||||
54
src/PodmanClientDotNet.Tests/Archives/Tar.cs
Normal file
54
src/PodmanClientDotNet.Tests/Archives/Tar.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using ICSharpCode.SharpZipLib.Tar;
|
||||
|
||||
namespace MaksIT.PodmanClientDotNet.Tests.Archives
|
||||
{
|
||||
public static class Tar
|
||||
{
|
||||
public static void CreateTarFromDirectory(string sourceDirectory, Stream outputStream)
|
||||
{
|
||||
using (var tarOutputStream = new TarOutputStream(outputStream))
|
||||
{
|
||||
tarOutputStream.IsStreamOwner = false;
|
||||
AddDirectoryFilesToTar(tarOutputStream, sourceDirectory, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void AddDirectoryFilesToTar(TarOutputStream tarOutputStream, string sourceDirectory, bool recursive, string baseDirectory = null)
|
||||
{
|
||||
// If baseDirectory is null, set it to the sourceDirectory to start with
|
||||
if (baseDirectory == null)
|
||||
{
|
||||
baseDirectory = sourceDirectory;
|
||||
}
|
||||
|
||||
var directoryInfo = new DirectoryInfo(sourceDirectory);
|
||||
|
||||
foreach (var fileInfo in directoryInfo.GetFiles())
|
||||
{
|
||||
// Calculate the relative path for the file within the base directory
|
||||
string relativePath = Path.GetRelativePath(baseDirectory, fileInfo.FullName);
|
||||
|
||||
// Create tar entry with the relative path
|
||||
var entry = TarEntry.CreateEntryFromFile(fileInfo.FullName);
|
||||
entry.Name = relativePath.Replace(Path.DirectorySeparatorChar, '/'); // Use Unix-style path separators
|
||||
tarOutputStream.PutNextEntry(entry);
|
||||
|
||||
using (var fileStream = fileInfo.OpenRead())
|
||||
{
|
||||
fileStream.CopyTo(tarOutputStream);
|
||||
}
|
||||
|
||||
tarOutputStream.CloseEntry();
|
||||
}
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
foreach (var subDirectory in directoryInfo.GetDirectories())
|
||||
{
|
||||
// Recurse into subdirectories, passing the base directory
|
||||
AddDirectoryFilesToTar(tarOutputStream, subDirectory.FullName, true, baseDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using MaksIT.PodmanClientDotNet.Tests.Archives;
|
||||
|
||||
namespace MaksIT.PodmanClientDotNet.Tests {
|
||||
public class PodmanClientContainersTests {
|
||||
@ -15,11 +15,11 @@ namespace MaksIT.PodmanClientDotNet.Tests {
|
||||
_client = new PodmanClient(logger, "http://wks0002.corp.maks-it.com:8080", 60);
|
||||
}
|
||||
|
||||
#region Success
|
||||
#region Success Cases
|
||||
[Fact]
|
||||
public async Task PodmanClient_ContainerLifecycle_Success() {
|
||||
// Arrange
|
||||
string containerName = "test-container";
|
||||
string containerName = $"podman-client-test-{Guid.NewGuid()}";
|
||||
string image = "alpine:latest";
|
||||
|
||||
// Act & Assert
|
||||
@ -30,20 +30,54 @@ namespace MaksIT.PodmanClientDotNet.Tests {
|
||||
await ForceDeleteContainerAsync(containerId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CopyFilesToContainer_Success() {
|
||||
// Arrange
|
||||
string containerName = $"podman-client-test-{Guid.NewGuid()}";
|
||||
string image = "alpine:latest";
|
||||
string pathInContainer = "/podman-test-copy";
|
||||
|
||||
// Create temporary folder with random files
|
||||
string tempFolderPath = CreateTemporaryFolderWithFiles();
|
||||
|
||||
try {
|
||||
// Act
|
||||
await PullImageAsync(image);
|
||||
var containerId = await CreateContainerAsync(containerName, image);
|
||||
await StartContainerAsync(containerId);
|
||||
|
||||
// Archive the folder and copy to container
|
||||
using (var tarStream = CreateTarStream(tempFolderPath)) {
|
||||
await CopyToContainerAsync(containerId, tarStream, pathInContainer);
|
||||
}
|
||||
|
||||
// Stop and delete the container
|
||||
await StopContainerAsync(containerId);
|
||||
await ForceDeleteContainerAsync(containerId);
|
||||
}
|
||||
finally {
|
||||
// Cleanup: Delete temporary folder
|
||||
if (Directory.Exists(tempFolderPath)) {
|
||||
Directory.Delete(tempFolderPath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
private async Task PullImageAsync(string image) {
|
||||
// Implement the logic to pull the image
|
||||
var exception = await Record.ExceptionAsync(() => _client.PullImageAsync(image));
|
||||
Assert.Null(exception); // Expect no exceptions if the pull was successful
|
||||
}
|
||||
|
||||
private async Task<string> CreateContainerAsync(string containerName, string image) {
|
||||
var createResponse = await _client.CreateContainerAsync(
|
||||
name: containerName,
|
||||
image: image,
|
||||
command: new List<string> {
|
||||
"sh", "-c",
|
||||
"sleep infinity"
|
||||
});
|
||||
name: containerName,
|
||||
image: image,
|
||||
command: new List<string> {
|
||||
"sh", "-c",
|
||||
"sleep infinity"
|
||||
});
|
||||
Assert.NotNull(createResponse);
|
||||
Assert.False(string.IsNullOrEmpty(createResponse.Id)); // Ensure a valid container ID is returned
|
||||
return createResponse.Id;
|
||||
@ -63,42 +97,51 @@ namespace MaksIT.PodmanClientDotNet.Tests {
|
||||
var exception = await Record.ExceptionAsync(() => _client.ForceDeleteContainerAsync(containerId));
|
||||
Assert.Null(exception); // Expect no exceptions if the container was deleted successfully
|
||||
}
|
||||
|
||||
private async Task CopyToContainerAsync(string containerId, Stream tarStream, string path) {
|
||||
var exception = await Record.ExceptionAsync(() => _client.ExtractArchiveToContainerAsync(containerId, tarStream, path));
|
||||
Assert.Null(exception); // Expect no exceptions if the copy was successful
|
||||
}
|
||||
|
||||
private string CreateTemporaryFolderWithFiles() {
|
||||
string tempFolder = Path.Combine(Path.GetTempPath(), $"podman-test-{Guid.NewGuid()}");
|
||||
Directory.CreateDirectory(tempFolder);
|
||||
|
||||
// Create some random files
|
||||
for (int i = 0; i < 5; i++) {
|
||||
File.WriteAllText(Path.Combine(tempFolder, $"test-file-{i}.txt"), $"This is test file {i}");
|
||||
}
|
||||
|
||||
return tempFolder;
|
||||
}
|
||||
|
||||
private Stream CreateTarStream(string folderPath) {
|
||||
var memoryStream = new MemoryStream();
|
||||
Tar.CreateTarFromDirectory(folderPath, memoryStream);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin); // Reset the stream position for reading
|
||||
return memoryStream;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Fail
|
||||
#region Fail Cases
|
||||
[Fact]
|
||||
public async Task StartContainerAsync_Should_HandleErrors() {
|
||||
// Arrange
|
||||
string invalidContainerId = "invalid-container-id";
|
||||
|
||||
// Act
|
||||
var exception = await Record.ExceptionAsync(() => _client.StartContainerAsync(invalidContainerId));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(exception); // Expect an exception due to invalid container ID
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task StopContainerAsync_Should_HandleErrors() {
|
||||
// Arrange
|
||||
string invalidContainerId = "invalid-container-id";
|
||||
|
||||
// Act
|
||||
var exception = await Record.ExceptionAsync(() => _client.StopContainerAsync(invalidContainerId));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(exception); // Expect an exception due to invalid container ID
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ForceDeleteContainerAsync_Should_HandleErrors() {
|
||||
// Arrange
|
||||
string invalidContainerId = "invalid-container-id";
|
||||
|
||||
// Act
|
||||
var exception = await Record.ExceptionAsync(() => _client.ForceDeleteContainerAsync(invalidContainerId));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(exception); // Expect an exception due to invalid container ID
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageReference Include="xunit" Version="2.9.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
||||
193
src/PodmanClientDotNet.Tests/PodmanClientExecTests.cs
Normal file
193
src/PodmanClientDotNet.Tests/PodmanClientExecTests.cs
Normal file
@ -0,0 +1,193 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Xunit;
|
||||
|
||||
namespace MaksIT.PodmanClientDotNet.Tests {
|
||||
public class PodmanClientExecTests {
|
||||
private readonly PodmanClient _client;
|
||||
|
||||
public PodmanClientExecTests() {
|
||||
var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
|
||||
var logger = loggerFactory.CreateLogger<PodmanClient>();
|
||||
|
||||
_client = new PodmanClient(logger, "http://wks0002.corp.maks-it.com:8080", 60);
|
||||
}
|
||||
|
||||
#region Success Cases
|
||||
|
||||
[Fact]
|
||||
public async Task Full_ContainerLifecycle_With_Exec_Should_Succeed() {
|
||||
// Arrange
|
||||
string containerName = $"podman-client-test-{Guid.NewGuid()}";
|
||||
string image = "alpine:latest";
|
||||
|
||||
// Act & Assert
|
||||
// 1. Pull the image
|
||||
await PullImageAsync(image);
|
||||
|
||||
// 2. Create the container with sleep infinity command
|
||||
var containerId = await CreateContainerAsync(containerName, image);
|
||||
|
||||
// 3. Start the container
|
||||
await StartContainerAsync(containerId);
|
||||
|
||||
// 4. Execute a command in the container to install a package (e.g., "apk add curl")
|
||||
var execId = await CreateExecAsync(containerName, new[] { "apk", "add", "--no-cache", "curl" });
|
||||
await StartExecAsync(execId);
|
||||
|
||||
// 5. Stop the container
|
||||
await StopContainerAsync(containerId);
|
||||
|
||||
// 6. Delete the container
|
||||
await ForceDeleteContainerAsync(containerId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
private async Task PullImageAsync(string image) {
|
||||
var exception = await Record.ExceptionAsync(() => _client.PullImageAsync(image));
|
||||
Assert.Null(exception); // Expect no exceptions if the pull was successful
|
||||
}
|
||||
|
||||
private async Task<string> CreateContainerAsync(string containerName, string image) {
|
||||
var createResponse = await _client.CreateContainerAsync(
|
||||
name: containerName,
|
||||
image: image,
|
||||
command: new List<string> {
|
||||
"sh", "-c",
|
||||
"sleep infinity"
|
||||
});
|
||||
Assert.NotNull(createResponse);
|
||||
Assert.False(string.IsNullOrEmpty(createResponse.Id)); // Ensure a valid container ID is returned
|
||||
return createResponse.Id;
|
||||
}
|
||||
|
||||
private async Task StartContainerAsync(string containerId) {
|
||||
var exception = await Record.ExceptionAsync(() => _client.StartContainerAsync(containerId));
|
||||
Assert.Null(exception); // Expect no exceptions if the container was started successfully
|
||||
}
|
||||
|
||||
private async Task<string> CreateExecAsync(string containerName, string[] cmd) {
|
||||
var execResponse = await _client.CreateExecAsync(containerName, cmd);
|
||||
Assert.NotNull(execResponse);
|
||||
Assert.False(string.IsNullOrEmpty(execResponse.Id)); // Ensure a valid exec ID is returned
|
||||
return execResponse.Id;
|
||||
}
|
||||
|
||||
private async Task StartExecAsync(string execId) {
|
||||
var exception = await Record.ExceptionAsync(() => _client.StartExecAsync(execId));
|
||||
Assert.Null(exception); // Expect no exceptions if the exec command was started successfully
|
||||
}
|
||||
|
||||
private async Task StopContainerAsync(string containerId) {
|
||||
var exception = await Record.ExceptionAsync(() => _client.StopContainerAsync(containerId));
|
||||
Assert.Null(exception); // Expect no exceptions if the container was stopped successfully
|
||||
}
|
||||
|
||||
private async Task ForceDeleteContainerAsync(string containerId) {
|
||||
var exception = await Record.ExceptionAsync(() => _client.ForceDeleteContainerAsync(containerId));
|
||||
Assert.Null(exception); // Expect no exceptions if the container was deleted successfully
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fail Cases
|
||||
|
||||
[Fact]
|
||||
public async Task PullImageAsync_Should_HandleErrors() {
|
||||
// Arrange
|
||||
string invalidImageReference = "invalidimage:latest"; // Intentionally wrong image
|
||||
|
||||
// Act
|
||||
var exception = await Record.ExceptionAsync(() => _client.PullImageAsync(invalidImageReference));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(exception);
|
||||
Assert.IsType<HttpRequestException>(exception); // Ensure it's the expected type
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateContainerAsync_Should_HandleErrors() {
|
||||
// Arrange
|
||||
string invalidImage = "invalidimage:latest"; // Intentionally wrong image
|
||||
string containerName = "test-container";
|
||||
|
||||
// Act
|
||||
var exception = await Record.ExceptionAsync(() => _client.CreateContainerAsync(containerName, invalidImage, new List<string> { "sh", "-c", "sleep infinity" }));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(exception);
|
||||
Assert.IsType<HttpRequestException>(exception); // Ensure it's the expected type
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task StartContainerAsync_Should_HandleErrors() {
|
||||
// Arrange
|
||||
string invalidContainerId = "invalid-container-id"; // Intentionally wrong container ID
|
||||
|
||||
// Act
|
||||
var exception = await Record.ExceptionAsync(() => _client.StartContainerAsync(invalidContainerId));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(exception);
|
||||
Assert.IsType<HttpRequestException>(exception); // Ensure it's the expected type
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateExecAsync_Should_HandleErrors() {
|
||||
// Arrange
|
||||
string containerName = "invalid-container"; // Intentionally wrong container name
|
||||
var cmd = new[] { "apk", "add", "--no-cache", "curl" };
|
||||
|
||||
// Act
|
||||
var exception = await Record.ExceptionAsync(() => _client.CreateExecAsync(containerName, cmd));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(exception);
|
||||
Assert.IsType<HttpRequestException>(exception); // Ensure it's the expected type
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task StartExecAsync_Should_HandleErrors() {
|
||||
// Arrange
|
||||
string invalidExecId = "invalid-exec-id"; // Intentionally wrong exec ID
|
||||
|
||||
// Act
|
||||
var exception = await Record.ExceptionAsync(() => _client.StartExecAsync(invalidExecId));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(exception);
|
||||
Assert.IsType<HttpRequestException>(exception); // Ensure it's the expected type
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task StopContainerAsync_Should_HandleErrors() {
|
||||
// Arrange
|
||||
string invalidContainerId = "invalid-container-id"; // Intentionally wrong container ID
|
||||
|
||||
// Act
|
||||
var exception = await Record.ExceptionAsync(() => _client.StopContainerAsync(invalidContainerId));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(exception);
|
||||
Assert.IsType<HttpRequestException>(exception); // Ensure it's the expected type
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ForceDeleteContainerAsync_Should_HandleErrors() {
|
||||
// Arrange
|
||||
string invalidContainerId = "invalid-container-id"; // Intentionally wrong container ID
|
||||
|
||||
// Act
|
||||
var exception = await Record.ExceptionAsync(() => _client.ForceDeleteContainerAsync(invalidContainerId));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(exception);
|
||||
Assert.IsType<HttpRequestException>(exception); // Ensure it's the expected type
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,8 @@ public class PodmanClientImagesTests {
|
||||
_client = new PodmanClient(logger, "http://wks0002.corp.maks-it.com:8080", 60);
|
||||
}
|
||||
|
||||
#region Success Cases
|
||||
|
||||
[Fact]
|
||||
public async Task PodmanClient_IntegrationTests() {
|
||||
// Test 1: Pull Image - Success
|
||||
@ -23,6 +25,9 @@ public class PodmanClientImagesTests {
|
||||
// Test 2: Tag Image - Success
|
||||
await TagImageAsync_Should_Succeed();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
private async Task PullImageAsync_Should_Succeed() {
|
||||
// Arrange
|
||||
@ -47,7 +52,9 @@ public class PodmanClientImagesTests {
|
||||
// Assert
|
||||
Assert.Null(exception); // Expect no exceptions if the tagging was successful
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Fail Cases
|
||||
[Fact]
|
||||
public async Task PodmanClient_PullImage_Errors() {
|
||||
|
||||
@ -76,4 +83,5 @@ public class PodmanClientImagesTests {
|
||||
Assert.NotNull(exception); // Expect an exception due to nonexistent image
|
||||
Assert.IsType<HttpRequestException>(exception); // Ensure it's the expected type
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user