예제 #1
0
        public async Task ShouldNotUploadNewVersionOfDirectoryArtifactWhenHashesMatch()
        {
            using var templateDir = this.deepNestedStack;
            // Hash of lambda directory content before zipping
            // Zips are not idempotent - fields e.g. timestamps in central directory change with successive zips of the same content.
            var directoryHash = new DirectoryInfo(Path.Combine(templateDir, "lambdacomplex")).MD5();
            var template      = Path.Combine(templateDir, "base-stack.json");
            var projectId     = S3Util.GenerateProjectId(template);
            var logger        = new TestLogger(this.output);
            var mockSts       = TestHelpers.GetSTSMock();
            var mockS3        = TestHelpers.GetS3ClientWithBucketMock();
            var mockContext   = new Mock <IPSCloudFormationContext>();

            mockContext.Setup(c => c.Logger).Returns(logger);
            mockContext.Setup(c => c.Region).Returns(RegionEndpoint.EUWest1);
            mockS3.SetupSequence(s3 => s3.ListObjectsV2Async(It.IsAny <ListObjectsV2Request>(), default)).ReturnsAsync(
                new ListObjectsV2Response
            {
                S3Objects = new List <S3Object>
                {
                    new S3Object
                    {
                        BucketName = "test-bucket",
                        Key        = $"lambdacomplex-{projectId}-0000.zip"
                    }
                }
            }).ReturnsAsync(this.fileNotFound).ReturnsAsync(this.fileNotFound);

            mockS3.Setup(s3 => s3.GetObjectMetadataAsync(It.IsAny <GetObjectMetadataRequest>(), default)).ReturnsAsync(
                () =>
            {
                var resp = new GetObjectMetadataResponse();

                resp.Metadata.Add(S3Util.PackagerHashKey, directoryHash);
                return(resp);
            });

            var mockClientFactory = new Mock <IPSAwsClientFactory>();

            mockClientFactory.Setup(f => f.CreateS3Client()).Returns(mockS3.Object);
            mockClientFactory.Setup(f => f.CreateSTSClient()).Returns(mockSts.Object);

            using var workingDirectory = new TempDirectory();

            var packager = new PackagerUtils(
                new TestPathResolver(),
                logger,
                new S3Util(mockClientFactory.Object, mockContext.Object, template, "test-bucket", null, null),
                new OSInfo());

            var outputTemplatePath = await packager.ProcessTemplate(template, workingDirectory);

            this.output.WriteLine(string.Empty);
            this.output.WriteLine(await File.ReadAllTextAsync(outputTemplatePath));

            // Three objects should have been uploaded to S3
            mockS3.Verify(m => m.PutObjectAsync(It.IsAny <PutObjectRequest>(), default), Times.Exactly(2));
        }
예제 #2
0
        private TestLogger SetupMocks(string template)
        {
            var projectId   = S3Util.GenerateProjectId(template);
            var logger      = new TestLogger(this.output);
            var mockSts     = TestHelpers.GetSTSMock();
            var mockS3      = TestHelpers.GetS3ClientWithBucketMock();
            var mockContext = new Mock <IPSCloudFormationContext>();

            mockContext.Setup(c => c.Logger).Returns(logger);
            mockContext.Setup(c => c.Region).Returns(RegionEndpoint.EUWest1);
            mockS3.SetupSequence(s3 => s3.ListObjectsV2Async(It.IsAny <ListObjectsV2Request>(), default)).ReturnsAsync(
                new ListObjectsV2Response
            {
                S3Objects = new List <S3Object>
                {
                    new S3Object
                    {
                        BucketName = "test-bucket", Key = $"my_lambda-{projectId}-0000.zip"
                    }
                }
            }).ReturnsAsync(this.fileNotFound).ReturnsAsync(this.fileNotFound);

            mockS3.Setup(s3 => s3.GetObjectMetadataAsync(It.IsAny <GetObjectMetadataRequest>(), default)).ReturnsAsync(
                () =>
            {
                var resp = new GetObjectMetadataResponse();

                resp.Metadata.Add(S3Util.PackagerHashKey, "0");
                return(resp);
            });

            var mockClientFactory = new Mock <IPSAwsClientFactory>();

            mockClientFactory.Setup(f => f.CreateS3Client()).Returns(mockS3.Object);
            mockClientFactory.Setup(f => f.CreateSTSClient()).Returns(mockSts.Object);

            this.ClientFactory = mockClientFactory.Object;
            this.Context       = mockContext.Object;
            this.Logger        = logger;
            return(logger);
        }
예제 #3
0
        public async Task ShouldNotUploadNewVersionOfTemplateArtifactWhenHashesMatch()
        {
            var templateDir = this.deepNestedStack;
            var template    = Path.Combine(templateDir, "base-stack.json");
            var projectId   = S3Util.GenerateProjectId(template);
            var logger      = new TestLogger(this.output);
            var mockSts     = TestHelpers.GetSTSMock();
            var mockS3      = TestHelpers.GetS3ClientWithBucketMock();
            var mockContext = new Mock <IPSCloudFormationContext>();

            mockContext.Setup(c => c.Logger).Returns(logger);
            mockContext.Setup(c => c.Region).Returns(RegionEndpoint.EUWest1);

            mockS3.SetupSequence(s3 => s3.ListObjectsV2Async(It.IsAny <ListObjectsV2Request>(), default))
            .ReturnsAsync(this.fileNotFound)
            .ReturnsAsync(
                new ListObjectsV2Response
            {
                S3Objects = new List <S3Object>
                {
                    new S3Object
                    {
                        BucketName = "test-bucket",
                        Key        = $"sub-nested-2-{projectId}-0000.json"
                    }
                }
            }).ReturnsAsync(this.fileNotFound);

            mockS3.Setup(s3 => s3.GetObjectMetadataAsync(It.IsAny <GetObjectMetadataRequest>(), default)).ReturnsAsync(
                () =>
            {
                var resp = new GetObjectMetadataResponse();

                resp.Metadata.Add(S3Util.PackagerHashKey, GetModifiedTemplateHash());
                return(resp);
            });

            var mockClientFactory = new Mock <IPSAwsClientFactory>();

            mockClientFactory.Setup(f => f.CreateS3Client()).Returns(mockS3.Object);
            mockClientFactory.Setup(f => f.CreateSTSClient()).Returns(mockSts.Object);

            using var workingDirectory = new TempDirectory();

            var packager = new PackagerUtils(
                new TestPathResolver(),
                logger,
                new S3Util(mockClientFactory.Object, mockContext.Object, template, "test-bucket", null, null),
                new OSInfo());

            var outputTemplatePath = await packager.ProcessTemplate(template, workingDirectory);

            this.output.WriteLine(string.Empty);
            this.output.WriteLine(await File.ReadAllTextAsync(outputTemplatePath));

            // Three objects should have been uploaded to S3
            mockS3.Verify(m => m.PutObjectAsync(It.IsAny <PutObjectRequest>(), default), Times.Exactly(2));

            // Bit hacky, but we need to know the hash of the template after modification.
            // Different on Windows and Linux due to line endings.
            string GetModifiedTemplateHash()
            {
                var re = new Regex(@"sub-nested-2\.json.*Hash: (?<hash>[0-9a-f]+)");

                var logLine = logger.DebugMessages.FirstOrDefault(line => re.IsMatch(line));

                if (logLine == null)
                {
                    return("0");
                }

                var mc = re.Match(logLine);

                return(mc.Groups["hash"].Value);
            }
        }
예제 #4
0
 static S3UtilTest()
 {
     RootTemplate = GetThisFilePath();
     ProjectId    = S3Util.GenerateProjectId(RootTemplate);
 }