예제 #1
0
        public async Task WhenRequestingNonHumanReadableFormat_ThenNonHumanReadableDataIsReturned()
        {
            var output = new StringBuilder();

            output.AppendLine("IMAGE               CREATED AT                  CREATED BY                                      SIZE                COMMENT");
            output.AppendLine("ecea3d792cd1        2018-01-08T20:07:42Z        cmd /S /C #(nop)  CMD [\"cmd\" \" / C\" \"type C:\\…   40960                Comment1");
            output.AppendLine("<missing>           2018-01-08T20:07:42Z        cmd /S /C #(nop) COPY file:f7c8910f60a7ec8d3…   41822                 ");
            output.AppendLine("<missing>           2018-01-03T04:23:16Z        Install update 10.0.16299.192                   100010759                 ");
            output.AppendLine("<missing>           2017-09-29T10:50:38+01:00   Apply image 10.0.16299.15                       203295012                 ");

            var shellExecutor = new Mock <IShellExecutor>();

            shellExecutor
            .Setup(e => e.Execute(Commands.Docker, " image history -H=False imageName"))
            .ReturnsAsync(new ShellExecuteResult(true, output.ToString(), ""));

            var dockerImage = new DockerImage("imageName", shellExecutor.Object);

            var results = await dockerImage.History().CreateOutputInHumanReadableFormat(false).SearchAsync();

            results.Count.Should().Be(4);
            results[0].Id.Should().Be("ecea3d792cd1");
            results[0].CreatedBy.Should().Be("cmd /S /C #(nop)  CMD [\"cmd\" \" / C\" \"type C:\\…");
            results[0].Comment.Should().Be("Comment1");
            results[0].CreatedAt.Should().Be(new DateTime(2018, 1, 8, 20, 7, 42));
            results[0].CreatedSince.Should().BeNullOrEmpty();
            results[0].Size.Should().Be("40960");
        }
예제 #2
0
        public async Task WhenCommandSucceeds_ReturnsDockerContainer()
        {
            // Arrange
            var mockDockerClient = BuildMockDockerClient(true, true);

            var mockCommand = MotherFor.CommandWrapper
                              .ThatSucceeds()
                              .WithOutput("thisisacontaineridthatisover12chars")
                              .Build();

            var mockCommandFactory = MotherFor.CommandFactory
                                     .ForWorkingDirectory(_workingDirectory)
                                     .ForCommandReturn(DockerCommands.Image.RunContainer(ExpectedId, null), mockCommand)
                                     .Build();

            var dockerImage = new DockerImageResult
            {
                Id         = ExpectedId,
                Repository = ExpectedRepository,
                Tag        = ExpectedTag
            };

            var sut = new DockerImage(mockDockerClient, mockCommandFactory, dockerImage);

            // Act
            var result = await sut.StartContainerAsync();

            // Assert
            result.Should().BeOfType <DockerContainer>();
        }
예제 #3
0
        public async Task WhenNotDeleted_CallsStartContainer()
        {
            // Arrange
            var mockDockerClient = BuildMockDockerClient(true, true);

            var mockCommand = MotherFor.CommandWrapper.ThatSucceeds().WithOutput("twelvecharac").Build();

            var mockCommandFactory = MotherFor.CommandFactory
                                     .ForWorkingDirectory(_workingDirectory)
                                     .ForCommandReturn(DockerCommands.Image.RunContainer(ExpectedId, null), mockCommand)
                                     .Build();

            var dockerImage = new DockerImageResult
            {
                Id         = ExpectedId,
                Repository = ExpectedRepository,
                Tag        = ExpectedTag
            };

            var sut = new DockerImage(mockDockerClient, mockCommandFactory, dockerImage);

            // Act
            await sut.StartContainerAsync();

            // Assert
            mockCommandFactory.Received(1).RunCommand(DockerCommands.Image.RunContainer(ExpectedId, null), _workingDirectory, Arg.Any <CancellationToken?>());
        }
예제 #4
0
        public void WhenImageExistsFails_ItDoesNotSetDeletedState()
        {
            // Arrange
            var mockDockerClient = BuildMockDockerClient(false, true);

            var mockCommand = MotherFor.CommandWrapper.ThatFails().WithExitCode(-1).Build();

            var mockCommandFactory = MotherFor.CommandFactory
                                     .ForWorkingDirectory(_workingDirectory)
                                     .ForCommandReturn(DockerCommands.Image.RunContainer(ExpectedId, null), mockCommand)
                                     .Build();

            var dockerImage = new DockerImageResult
            {
                Id         = ExpectedId,
                Repository = ExpectedRepository,
                Tag        = ExpectedTag
            };

            var sut = new DockerImage(mockDockerClient, mockCommandFactory, dockerImage);

            // Act
            Assert.CatchAsync(async() => await sut.StartContainerAsync());

            // Assert
            sut.Deleted.Should().BeFalse();
        }
예제 #5
0
        public async Task WhenCommandFails_CallsImageExists()
        {
            // Arrange
            var mockDockerClient = BuildMockDockerClient(true, true);

            var mockCommand = MotherFor.CommandWrapper.ThatFails().WithExitCode(-1).Build();

            var mockCommandFactory = MotherFor.CommandFactory
                                     .ForWorkingDirectory(_workingDirectory)
                                     .ForCommandReturn(DockerCommands.Image.RunContainer(ExpectedId, null), mockCommand)
                                     .Build();

            var dockerImage = new DockerImageResult
            {
                Id         = ExpectedId,
                Repository = ExpectedRepository,
                Tag        = ExpectedTag
            };

            var sut = new DockerImage(mockDockerClient, mockCommandFactory, dockerImage);

            // Act
            Assert.CatchAsync(async() => await sut.StartContainerAsync());

            // Assert
            await mockDockerClient.Received(1).ImageExistsAsync(Arg.Any <string>());
        }
예제 #6
0
        public void WhenCommandFails_ThrowsDockerCommandException()
        {
            // Arrange
            var mockDockerClient = BuildMockDockerClient(true, true);

            var mockCommand = MotherFor.CommandWrapper.ThatFails().WithExitCode(-1).Build();

            var mockCommandFactory = MotherFor.CommandFactory
                                     .ForWorkingDirectory(_workingDirectory)
                                     .ForCommandReturn(DockerCommands.Image.RunContainer(ExpectedId, null), mockCommand)
                                     .Build();

            var dockerImage = new DockerImageResult
            {
                Id         = ExpectedId,
                Repository = ExpectedRepository,
                Tag        = ExpectedTag
            };

            var sut = new DockerImage(mockDockerClient, mockCommandFactory, dockerImage);

            // Act
            var exception = Assert.CatchAsync(async() => await sut.StartContainerAsync());

            // Assert
            exception.Should().BeOfType <DockerCommandException>();
        }
예제 #7
0
        public void WhenContainerCpuLimitSpecifiedIsTooHigh()
        {
            // Arrange
            var aboveMaxCpuCount = Environment.ProcessorCount + 0.1m;

            var mockDockerClient = BuildMockDockerClient(true, true);

            var mockCommand = MotherFor.CommandWrapper.ThatFails().WithExitCode(-1).Build();

            var mockCommandFactory = MotherFor.CommandFactory
                                     .ForWorkingDirectory(_workingDirectory)
                                     .ForCommandReturn(DockerCommands.Image.RunContainer(ExpectedId, new StartContainerOptions().WithCpuLimit(aboveMaxCpuCount)), mockCommand)
                                     .Build();

            var dockerImage = new DockerImageResult
            {
                Id         = ExpectedId,
                Repository = ExpectedRepository,
                Tag        = ExpectedTag
            };

            var sut = new DockerImage(mockDockerClient, mockCommandFactory, dockerImage);

            // Act
            var exception = Assert.CatchAsync(async() => await sut.StartContainerAsync(o => o.WithCpuLimit(aboveMaxCpuCount)));

            // Assert
            exception.Should().BeOfType <ArgumentException>();
        }
예제 #8
0
        public async Task WhenCommandSucceeds_ItDoesNotChangeDeletedState()
        {
            // Arrange
            var mockDockerClient = BuildMockDockerClient(true, true);

            var mockCommand = MotherFor.CommandWrapper
                              .ThatSucceeds()
                              .WithOutput("avalidcontainerid")
                              .Build();

            var mockCommandFactory = MotherFor.CommandFactory
                                     .ForWorkingDirectory(_workingDirectory)
                                     .ForCommandReturn(DockerCommands.Image.RunContainer(ExpectedId, null), mockCommand)
                                     .Build();

            var dockerImage = new DockerImageResult
            {
                Id         = ExpectedId,
                Repository = ExpectedRepository,
                Tag        = ExpectedTag
            };

            var sut = new DockerImage(mockDockerClient, mockCommandFactory, dockerImage);
            var initialDeletedState = sut.Deleted;

            // Act
            await sut.StartContainerAsync();

            // Assert
            sut.Deleted.Should().Be(initialDeletedState);
        }
예제 #9
0
        public async Task WhenCommandSucceeds_DoesNotCallImageExists()
        {
            // Arrange
            var mockDockerClient = BuildMockDockerClient(true, true);

            var mockCommand = MotherFor.CommandWrapper
                              .ThatSucceeds()
                              .WithOutput("avalidcontainerid")
                              .Build();

            var mockCommandFactory = MotherFor.CommandFactory
                                     .ForWorkingDirectory(_workingDirectory)
                                     .ForCommandReturn(DockerCommands.Image.RunContainer(ExpectedId, null), mockCommand)
                                     .Build();

            var dockerImage = new DockerImageResult
            {
                Id         = ExpectedId,
                Repository = ExpectedRepository,
                Tag        = ExpectedTag
            };

            var sut = new DockerImage(mockDockerClient, mockCommandFactory, dockerImage);

            // Act
            await sut.StartContainerAsync();

            // Assert
            await mockDockerClient.DidNotReceive().ImageExistsAsync(Arg.Any <string>());
        }
예제 #10
0
        public void ShouldAddDockerWrapperToChain(OperatingSystem operatingSystem)
        {
            // Given
            DockerImage dockerImage = "mcr.microsoft.com/windows/servercore";
            var         wrapperInfo = new DockerWrapperInfo(
                dockerImage,
                Enumerable.Empty <DockerVolume>(),
                Enumerable.Empty <CommandLineArgument>(),
                Enumerable.Empty <EnvironmentVariable>(),
                operatingSystem,
                true,
                DockerPullType.Missing);

            var wrapper = CreateInstance();

            // When
            using (wrapper.Using(wrapperInfo))
            {
                // Then
                _virtualEnvironment.Verify(i => i.Set(operatingSystem));
                _envChain.Verify(i => i.Append(_virtualEnvironment.Object));
                _processChain.Verify(i => i.Append(_dockerProcessWrapper.Object));
                if (operatingSystem == OperatingSystem.Windows)
                {
                    _processChain.Verify(i => i.Append(_cmdProcessWrapper.Object));
                }
                else
                {
                    _processChain.Verify(i => i.Append(_shProcessWrapper.Object));
                }
            }
        }
예제 #11
0
        public void WhenCommandSucceeds_ButNoValidContainerIdInResponse(params string[] output)
        {
            // Arrange
            var mockDockerClient = BuildMockDockerClient(true, true);

            var mockCommand = MotherFor.CommandWrapper.ThatSucceeds().WithOutput(output).Build();

            var mockCommandFactory = MotherFor.CommandFactory
                                     .ForWorkingDirectory(_workingDirectory)
                                     .ForCommandReturn(DockerCommands.Image.RunContainer(ExpectedId, null), mockCommand)
                                     .Build();

            var dockerImage = new DockerImageResult
            {
                Id         = ExpectedId,
                Repository = ExpectedRepository,
                Tag        = ExpectedTag
            };

            var sut = new DockerImage(mockDockerClient, mockCommandFactory, dockerImage);

            // Act
            var exception = Assert.CatchAsync(async() => await sut.StartContainerAsync());

            // Assert
            exception.Should().BeOfType <DockerCommandUnexpectedOutputException>();
        }
예제 #12
0
        public async Task WhenRequestingToNotTruncate_ThenUntruncatedDataIsReturned()
        {
            var output = new StringBuilder();

            output.AppendLine("IMAGE                                                                     CREATED             CREATED BY                                                                                           SIZE                COMMENT");
            output.AppendLine("sha256:ecea3d792cd143caccdf16935cfa1e4d0ec566a6d9e64eac25dfe9087c806702   3 weeks ago         cmd /S /C #(nop)  CMD [\"cmd\" \" / C\" \"type C:\\hello.txt\"]                                              41kB                Comment1");
            output.AppendLine("<missing>                                                                 3 weeks ago         cmd /S /C #(nop) COPY file:f7c8910f60a7ec8d3a775a4b5ae8797e5a3efb9d531b782e2a57d2f65314d2dd in C:    41.8kB                ");
            output.AppendLine("<missing>                                                                 4 weeks ago         Install update 10.0.16299.192                                                                        100MB                ");
            output.AppendLine("<missing>                                                                 4 months ago        Apply image 10.0.16299.15                                                                            203MB                ");

            var shellExecutor = new Mock <IShellExecutor>();

            shellExecutor
            .Setup(e => e.Execute(Commands.Docker, " image history --no-trunc -H=True imageName"))
            .ReturnsAsync(new ShellExecuteResult(true, output.ToString(), ""));

            var dockerImage = new DockerImage("imageName", shellExecutor.Object);

            var results = await dockerImage.History().DoNotTruncate(true).SearchAsync();

            results.Count.Should().Be(4);
            results[0].Id.Should().Be("sha256:ecea3d792cd143caccdf16935cfa1e4d0ec566a6d9e64eac25dfe9087c806702");
            results[0].CreatedBy.Should().Be("cmd /S /C #(nop)  CMD [\"cmd\" \" / C\" \"type C:\\hello.txt\"]");
            results[0].Comment.Should().Be("Comment1");
            results[0].CreatedAt.Should().Be(DateTime.MinValue);
            results[0].CreatedSince.Should().Be("3 weeks ago");
            results[0].Size.Should().Be("41kB");
        }
예제 #13
0
        public void GetHostnameFromHubImageNamePrefix(string repository, string name, string tag)
        {
            const string hubImageNamePrefix = "myregistry.azurecr.io";
            IDockerImage image = new DockerImage(repository, name, tag, hubImageNamePrefix);

            Assert.Equal(hubImageNamePrefix, image.GetHostname());
        }
예제 #14
0
        public ApiResult UpdateImageVersion([FromBody] UpdateImageVersionRequest request)
        {
            var arr = request.Image.Split(':');

            DockerImage dockerImage = new DockerImage()
            {
                Image   = arr[0].Replace("registry-vpc.cn-hangzhou.aliyuncs.com", "registry.cn-hangzhou.aliyuncs.com"),
                Version = arr[1]
            };

            var deployments = KubeHelper.Client.ListNamespacedDeployment(request.NS).Items;

            foreach (var v1Deployment in deployments)
            {
                var deployMentImage = v1Deployment.Spec.Template.Spec.Containers[0].Image.Split(':')[0]
                                      .Replace("registry-vpc.cn-hangzhou.aliyuncs.com", "registry.cn-hangzhou.aliyuncs.com");

                if (deployMentImage == dockerImage.Image)
                {
                    var patch = new JsonPatchDocument <V1Deployment>();

                    patch.Replace(t => t.Spec.Template.Spec.Containers[0].Image, request.Image);

                    KubeHelper.Client.PatchNamespacedDeployment(new V1Patch(patch), v1Deployment.Metadata.Name,
                                                                request.NS);
                }
            }

            return(new ApiResult());
        }
예제 #15
0
        public async Task WhenCommandSucceeds_ResultContainsTruncatedContainerId()
        {
            // Arrange
            var mockDockerClient = BuildMockDockerClient(true, true);
            var fullContainerId  = "thisislongerthantwelvecharacters";

            var mockCommand = MotherFor.CommandWrapper
                              .ThatSucceeds()
                              .WithOutput(fullContainerId)
                              .Build();

            var mockCommandFactory = MotherFor.CommandFactory
                                     .ForWorkingDirectory(_workingDirectory)
                                     .ForCommandReturn(DockerCommands.Image.RunContainer(ExpectedId, null), mockCommand)
                                     .Build();

            var dockerImage = new DockerImageResult
            {
                Id         = ExpectedId,
                Repository = ExpectedRepository,
                Tag        = ExpectedTag
            };

            var expectedResult = new DockerContainer(mockDockerClient, mockCommandFactory, "thisislonger", new DockerPortMapping[0]);

            var sut = new DockerImage(mockDockerClient, mockCommandFactory, dockerImage);

            // Act
            var result = await sut.StartContainerAsync();

            // Assert
            result.Should().BeEquivalentTo(expectedResult);
        }
        public void DockerfileArchiveTar()
        {
            // Given
            var image = new DockerImage("Testcontainers", "Test", "1.0.0");

            var expected = new SortedSet <string> {
                "Dockerfile", "setup/setup.sh"
            };

            var actual = new SortedSet <string>();

            var dockerFileArchive = new DockerfileArchive("Assets", "Dockerfile", image, TestcontainersSettings.Logger);

            // When
            using (var tarOut = new FileInfo(dockerFileArchive.Tar()).OpenRead())
            {
                using (var tarIn = TarArchive.CreateInputTarArchive(tarOut, Encoding.UTF8))
                {
                    tarIn.ProgressMessageEvent += (_, entry, _) => actual.Add(entry.Name);
                    tarIn.ListContents();
                }
            }

            // Then
            Assert.Equal(expected, actual);
        }
        public DockerImageViewModel(DockerService service, DockerImage image)
        {
            Service = service;
            Image   = image;
            Id      = image.Id;

            Update();
        }
예제 #18
0
    public static void DockerPushManifest(this BuildContextBase context, DockerImage dockerImage)
    {
        var manifestTags = context.GetDockerTags(dockerImage);

        foreach (var tag in manifestTags)
        {
            context.DockerManifestPush(tag);
        }
    }
예제 #19
0
    public static void DockerPushImage(this BuildContextBase context, DockerImage dockerImage)
    {
        var tags = context.GetDockerTags(dockerImage, dockerImage.Architecture);

        foreach (var tag in tags)
        {
            context.DockerPush(tag);
        }
    }
예제 #20
0
    public static void DockerTestImage(this BuildContextBase context, DockerImage dockerImage)
    {
        var tags = context.GetDockerTags(dockerImage, dockerImage.Architecture);

        foreach (var tag in tags)
        {
            context.DockerTestRun(tag, dockerImage.Architecture, "/repo", "/showvariable", "FullSemver");
        }
    }
예제 #21
0
    public static void DockerPullImage(this ICakeContext context, DockerImage dockerImage)
    {
        var tag      = $"{dockerImage.DockerImageName()}:{dockerImage.Distro}-sdk-{dockerImage.TargetFramework}";
        var platform = $"linux/{dockerImage.Architecture.ToString().ToLower()}";

        context.DockerPull(new DockerImagePullSettings {
            Platform = platform
        }, tag);
    }
            public void WhenImageNameGetsAssigned(ParseDockerImageFixtureSerializable serializable, string fullName)
            {
                var expected = serializable.Image;

                // Given
                var dockerImage = new DockerImage(fullName);

                // When
                // Then
                Assert.Equal(expected.Repository, dockerImage.Repository);
                Assert.Equal(expected.Name, dockerImage.Name);
                Assert.Equal(expected.Tag, dockerImage.Tag);
            }
        private void AddChildren(IReadOnlyCollection <DockerImage> allImages, DockerImage parent)
        {
            var children = allImages.Where(i => i.ParentId == parent.Id).ToList();

            if (children.Count > 0)
            {
                parent.Children = children;

                foreach (DockerImage child in children)
                {
                    AddChildren(allImages, child);
                }
            }
        }
예제 #24
0
    public static bool SkipArm64Image(this ICakeContext context, DockerImage dockerImage)
    {
        if (dockerImage.Architecture != Architecture.Arm64)
        {
            return(false);
        }
        if (!Constants.DistrosToSkip.Contains(dockerImage.Distro))
        {
            return(false);
        }

        context.Information($"Skipping Target: {dockerImage.TargetFramework}, Distro: {dockerImage.Distro}, Arch: {dockerImage.Architecture}");
        return(true);
    }
예제 #25
0
        public async Task AddNewImage(DockerImage entity)
        {
            Guard.Against.Null(entity, nameof(entity));

            //Check if Docker Image Name already exists
            var exists = DockerImageNameTaken(entity.Name);

            if (exists)
            {
                throw new ServiceLayerValidationException("Image Name Must be Unique");
            }

            await _dockerImageRepo.AddAsync(entity);
        }
예제 #26
0
        private async Task PullImageToHost(DockerImage image)
        {
            var parameters = new ImagesCreateParameters
            {
                FromImage = image.ImageName,
                Tag       = image.ImageTag
            };

            var config = new AuthConfig();

            var progress = new Progress <JSONMessage>(stats => Console.WriteLine(stats.Status));

            await _dockerClient.Images.CreateImageAsync(parameters, config, progress, CancellationToken.None);
        }
예제 #27
0
            public void PrependForObjectConfiguration(string hubImageNamePrefix, string imageName, string expectedFullName)
            {
                // Given
                TestcontainersSettings.HubImageNamePrefix = hubImageNamePrefix;

                IDockerImage image = new DockerImage(imageName);

                // When
                IDockerContainer container = new TestcontainersBuilder <TestcontainersContainer>()
                                             .WithImage(image)
                                             .Build();

                // Then
                Assert.Equal(expectedFullName, container.Image.FullName);
            }
예제 #28
0
            public void DoNotPrependForObjectConfiguration()
            {
                // Given
                const string imageName = "bar:latest";

                IDockerImage image = new DockerImage(imageName);

                // When
                IDockerContainer container = new TestcontainersBuilder <TestcontainersContainer>()
                                             .WithImage(image)
                                             .Build();

                // Then
                Assert.Equal(imageName, container.Image.FullName);
            }
예제 #29
0
    private static IEnumerable <string> GetDockerTags(this BuildContextBase context, DockerImage dockerImage, Architecture?arch = null)
    {
        var name            = dockerImage.DockerImageName();
        var distro          = dockerImage.Distro;
        var targetFramework = dockerImage.TargetFramework;

        if (context.Version == null)
        {
            return(Enumerable.Empty <string>());
        }
        var tags = new List <string>
        {
            $"{name}:{context.Version.Version}-{distro}-{targetFramework}",
            $"{name}:{context.Version.SemVersion}-{distro}-{targetFramework}",
        };

        if (distro == Constants.DockerDistroLatest && targetFramework == Constants.Version50)
        {
            tags.AddRange(new[]
            {
                $"{name}:{context.Version.Version}",
                $"{name}:{context.Version.SemVersion}",

                $"{name}:{context.Version.Version}-{distro}",
                $"{name}:{context.Version.SemVersion}-{distro}"
            });

            if (context.IsStableRelease)
            {
                tags.AddRange(new[]
                {
                    $"{name}:latest",
                    $"{name}:latest-{targetFramework}",
                    $"{name}:latest-{distro}",
                    $"{name}:latest-{distro}-{targetFramework}",
                });
            }
        }

        if (!arch.HasValue)
        {
            return(tags.Distinct());
        }

        var suffix = arch.Value.ToSuffix();

        return(tags.Select(x => $"{x}-{suffix}").Distinct());
    }
예제 #30
0
        public async Task WhenImageDoesNotExist_ThenNoResultsAreReturned()
        {
            const string output = "Error response from daemon: No such image: nonExistentImage:latest";

            var shellExecutor = new Mock <IShellExecutor>();

            shellExecutor
            .Setup(e => e.Execute(Commands.Docker, " image history -H=True nonExistentImage"))
            .ReturnsAsync(new ShellExecuteResult(true, output.ToString(), ""));

            var dockerImage = new DockerImage("nonExistentImage", shellExecutor.Object);

            var results = await dockerImage.History().SearchAsync();

            results.Count.Should().Be(0);
        }