示例#1
0
        public void ShouldRemoveArtifactsWhenDaysSpecified()
        {
            result = Clean("retentionPolicySet1", 3, null);

            result.AssertSuccess();

            Assert.False(fileSystem.DirectoryExists(Path.Combine(stagingDirectory, "Acme.1.0.0")));
            Assert.False(fileSystem.FileExists(Path.Combine(packagesDirectory, "Acme.1.0.0.nupkg")));
        }
示例#2
0
        public void ShouldAppendToVersionedFolderIfAlreadyExisting()
        {
            fileSystem.DirectoryExists("C:\\Applications\\Acme.Web\\1.0.0").Returns(true);
            fileSystem.DirectoryExists("C:\\Applications\\Acme.Web\\1.0.0_1").Returns(true);
            fileSystem.DirectoryExists("C:\\Applications\\Acme.Web\\1.0.0_2").Returns(true);

            convention.Install(new RunningDeployment("C:\\Package.nupkg", variables));

            Assert.That(variables.Get("OctopusOriginalPackageDirectoryPath"), Is.EqualTo("C:\\Applications\\Acme.Web\\1.0.0_3"));
        }
        public void ShouldAppendToVersionedFolderIfAlreadyExisting()
        {
            variables.Set("Octopus.Tentacle.Agent.ApplicationDirectoryPath", TestEnvironment.ConstructRootedPath());

            fileSystem.DirectoryExists(Arg.Is <string>(path => path.EndsWith(Path.Combine("Acme.Web", "1.0.0")))).Returns(true);
            fileSystem.DirectoryExists(Arg.Is <string>(path => path.EndsWith(Path.Combine("Acme.Web", "1.0.0_1")))).Returns(true);
            fileSystem.DirectoryExists(Arg.Is <string>(path => path.EndsWith(Path.Combine("Acme.Web", "1.0.0_2")))).Returns(true);


            convention.Install(new RunningDeployment(PackageLocation, variables));

            Assert.That(variables.Get("OctopusOriginalPackageDirectoryPath"), Is.StringEnding(Path.Combine("Acme.Web", "1.0.0_3")));
        }
        public void ShouldAppendToVersionedFolderIfAlreadyExisting()
        {
            variables.Set("Octopus.Tentacle.Agent.ApplicationDirectoryPath", TestEnvironment.ConstructRootedPath());

            fileSystem.DirectoryExists(Arg.Is <string>(path => path.EndsWith(Path.Combine("Acme.Web", "1.0.0")))).Returns(true);
            fileSystem.DirectoryExists(Arg.Is <string>(path => path.EndsWith(Path.Combine("Acme.Web", "1.0.0_1")))).Returns(true);
            fileSystem.DirectoryExists(Arg.Is <string>(path => path.EndsWith(Path.Combine("Acme.Web", "1.0.0_2")))).Returns(true);


            extractPackage.ExtractToApplicationDirectory(PathToPackage);

            Assert.That(variables.Get("OctopusOriginalPackageDirectoryPath"), Does.EndWith(Path.Combine("Acme.Web", "1.0.0_3")));
        }
        public void ReplaceVariables(RunningDeployment deployment)
        {
            var targets = deployment.Variables.GetPaths(ActionVariables.StructuredConfigurationVariablesTargets);
            var onlyPerformJsonReplacement = deployment.Variables.GetFlag(ActionVariables.StructuredConfigurationFallbackFlag);

            foreach (var target in targets)
            {
                if (fileSystem.DirectoryExists(target))
                {
                    log.Warn($"Skipping structured variable replacement on '{target}' because it is a directory.");
                    continue;
                }

                var matchingFiles = MatchingFiles(deployment, target);

                if (!matchingFiles.Any())
                {
                    log.Warn($"No files were found that match the replacement target pattern '{target}'");
                    continue;
                }

                foreach (var filePath in matchingFiles)
                {
                    var replacersToTry = GetReplacersToTryForFile(filePath, onlyPerformJsonReplacement).ToArray();
                    DoReplacement(filePath, deployment.Variables, replacersToTry);
                }
            }
        }
示例#6
0
 public void TearDown()
 {
     if (fileSystem.DirectoryExists(tempDirectory))
     {
         fileSystem.DeleteDirectory(tempDirectory, FailureOptions.IgnoreFailure);
     }
 }
        public void Install(RunningDeployment deployment)
        {
            if (!deployment.Variables.GetFlag(SpecialVariables.Package.JsonConfigurationVariablesEnabled))
            {
                return;
            }

            foreach (var target in deployment.Variables.GetPaths(SpecialVariables.Package.JsonConfigurationVariablesTargets))
            {
                if (fileSystem.DirectoryExists(target))
                {
                    Log.Warn($"Skipping JSON variable replacement on '{target}' because it is a directory.");
                    continue;
                }

                var matchingFiles = fileSystem.EnumerateFiles(deployment.CurrentDirectory, target)
                                    .Select(Path.GetFullPath).ToList();

                if (!matchingFiles.Any())
                {
                    Log.Warn($"No files were found that match the replacement target pattern '{target}'");
                    continue;
                }

                foreach (var file in matchingFiles)
                {
                    Log.Info($"Performing JSON variable replacement on '{file}'");
                    jsonConfigurationVariableReplacer.ModifyJsonFile(file, deployment.Variables);
                }
            }
        }
示例#8
0
        public void ShouldNotDeleteDirectoryWhereRetainedDeployedToSame()
        {
            var journalEntries = new List <JournalEntry>
            {
                fourDayOldDeployment,
                fourDayOldSameLocationDeployment,
                twoDayOldDeployment,
            };

            deploymentJournal.GetAllJournalEntries().Returns(journalEntries);
            fileSystem.FileExists(fourDayOldSameLocationDeployment.Package.DeployedFrom).Returns(true);
            fileSystem.DirectoryExists(fourDayOldSameLocationDeployment.ExtractedTo).Returns(true);

            const int days = 3;

            retentionPolicy.ApplyRetentionPolicy(policySet1, days, null);

            // Ensure the directories are the same
            Assert.AreEqual(twoDayOldDeployment.ExtractedTo, fourDayOldSameLocationDeployment.ExtractedTo);

            // The old directory was not removed...
            fileSystem.DidNotReceive().DeleteDirectory(Arg.Is <string>(s => s.Equals(fourDayOldSameLocationDeployment.ExtractedTo)));

            // ...despite being removed from the journal
            deploymentJournal.Received().RemoveJournalEntries(Arg.Is <IEnumerable <string> >(ids => ids.Contains(fourDayOldSameLocationDeployment.Id)));

            // and unique directory still removed
            fileSystem.Received().DeleteDirectory(Arg.Is <string>(s => s.Equals(fourDayOldDeployment.ExtractedTo)));
        }
示例#9
0
        public void ReplaceVariables(string currentDirectory, List <string> targets)
        {
            var onlyPerformJsonReplacement = variables.GetFlag(ActionVariables.StructuredConfigurationFallbackFlag);

            foreach (var target in targets)
            {
                if (fileSystem.DirectoryExists(target))
                {
                    log.Warn($"Skipping structured variable replacement on '{target}' because it is a directory.");
                    continue;
                }

                var matchingFiles = MatchingFiles(currentDirectory, target);

                if (!matchingFiles.Any())
                {
                    log.Warn($"No files were found that match the replacement target pattern '{target}'");
                    continue;
                }

                foreach (var filePath in matchingFiles)
                {
                    var replacersToTry = GetReplacersToTryForFile(filePath, onlyPerformJsonReplacement).ToArray();

                    log.Verbose($"The registered replacers we will try, in order, are: " + string.Join(",", replacersToTry.Select(r => r.GetType().Name)));

                    DoReplacement(filePath, variables, replacersToTry);
                }
            }
        }
示例#10
0
        public void SetUp()
        {
            fileSystem        = Substitute.For <ICalamariFileSystem>();
            deploymentJournal = Substitute.For <IDeploymentJournal>();
            clock             = Substitute.For <IClock>();
            retentionPolicy   = new RetentionPolicy(fileSystem, deploymentJournal, clock);

            now = new DateTimeOffset(new DateTime(2015, 01, 15), new TimeSpan(0, 0, 0));
            clock.GetUtcTime().Returns(now);

            // Deployed 4 days prior to 'now'
            fourDayOldDeployment = new JournalEntry("fourDayOld", "blah", "blah", "blah", "blah", "blah", policySet1,
                                                    now.AddDays(-4).LocalDateTime,
                                                    "C:\\packages\\Acme.1.0.0.nupkg", "C:\\Applications\\Acme.1.0.0", null, true);

            // Deployed 4 days prior to 'now' but to the same location as the latest successful deployment
            fourDayOldSameLocationDeployment = new JournalEntry("twoDayOld", "blah", "blah", "blah", "blah", "blah", policySet1,
                                                                now.AddDays(-4).LocalDateTime,
                                                                "C:\\packages\\Acme.1.2.0.nupkg", "C:\\Applications\\Acme.1.2.0", null, true);

            // Deployed 3 days prior to 'now'
            threeDayOldDeployment = new JournalEntry("threeDayOld", "blah", "blah", "blah", "blah", "blah", policySet1,
                                                     now.AddDays(-3).LocalDateTime,
                                                     "C:\\packages\\Acme.1.1.0.nupkg", "C:\\Applications\\Acme.1.1.0", null, true);

            // Deployed 2 days prior to 'now'
            twoDayOldDeployment = new JournalEntry("twoDayOld", "blah", "blah", "blah", "blah", "blah", policySet1,
                                                   now.AddDays(-2).LocalDateTime,
                                                   "C:\\packages\\Acme.1.2.0.nupkg", "C:\\Applications\\Acme.1.2.0", null, true);

            // Deployed (unsuccessfully) 1 day prior to 'now'
            oneDayOldUnsuccessfulDeployment = new JournalEntry("oneDayOldUnsuccessful", "blah", "blah", "blah", "blah", "blah", policySet1,
                                                               now.AddDays(-1).LocalDateTime,
                                                               "C:\\packages\\Acme.1.3.0.nupkg", "C:\\Applications\\Acme.1.3.0", null, false);

            // Deployed 5 days prior to 'now', but has a different policy-set
            fiveDayOldNonMatchingDeployment = new JournalEntry("fiveDayOld", "blah", "blah", "blah", "blah", "blah", policySet2,
                                                               now.AddDays(-5).LocalDateTime,
                                                               "C:\\packages\\Beta.1.0.0.nupkg", "C:\\Applications\\Beta.1.0.0", null, true);

            var journalEntries = new List <JournalEntry>
            {
                fiveDayOldNonMatchingDeployment,
                fourDayOldDeployment,
                threeDayOldDeployment,
                twoDayOldDeployment,
                oneDayOldUnsuccessfulDeployment
            };

            deploymentJournal.GetAllJournalEntries().Returns(journalEntries);

            foreach (var journalEntry in journalEntries)
            {
                fileSystem.FileExists(journalEntry.ExtractedFrom).Returns(true);
                fileSystem.DirectoryExists(journalEntry.ExtractedTo).Returns(true);
            }

            Environment.SetEnvironmentVariable("TentacleHome", @"Q:\TentacleHome");
        }
示例#11
0
        public ConfigurationTransformTestCaseBuilder FileExists(string fileName)
        {
            fileSystem.FileExists(fileName).Returns(true);
            var directory = Path.GetDirectoryName(fileName);

            fileSystem.DirectoryExists(directory).Returns(true);
            files.Add(fileName);
            return(this);
        }
        public void SetUp()
        {
            var variables = new CalamariVariableDictionary();

            variables.Set(SpecialVariables.OriginalPackageDirectoryPath, TestEnvironment.ConstructRootedPath("applications", "Acme", "1.0.0"));
            deployment = new RunningDeployment(TestEnvironment.ConstructRootedPath("Packages"), variables);
            configurationVariableReplacer = Substitute.For <IJsonConfigurationVariableReplacer>();
            fileSystem = Substitute.For <ICalamariFileSystem>();
            fileSystem.DirectoryExists(Arg.Any <string>()).Returns(false);
        }
        public void ShouldNotAttemptToRunOnDirectories()
        {
            deployment.Variables.Set(SpecialVariables.Package.JsonConfigurationVariablesEnabled, "true");
            deployment.Variables.Set(SpecialVariables.Package.JsonConfigurationVariablesTargets, "approot");
            fileSystem.DirectoryExists(Arg.Any <string>()).Returns(true);

            var convention = new JsonConfigurationVariablesConvention(configurationVariableReplacer, fileSystem);

            convention.Install(deployment);
            configurationVariableReplacer.DidNotReceiveWithAnyArgs().ModifyJsonFile(null, null);
        }
示例#14
0
        public IEnumerable <string> DetermineTransformFileNames(string sourceFile, XmlConfigTransformDefinition transformation)
        {
            var defaultTransformFileName = DetermineTransformFileName(sourceFile, transformation, true);
            var transformFileName        = DetermineTransformFileName(sourceFile, transformation, false);

            string fullTransformPath;

            if (Path.IsPathRooted(transformFileName))
            {
                fullTransformPath = Path.GetFullPath(GetDirectoryName(transformFileName));
            }
            else
            {
                var relativeTransformPath = fileSystem.GetRelativePath(sourceFile, transformFileName);
                fullTransformPath = Path.GetFullPath(Path.Combine(GetDirectoryName(sourceFile), GetDirectoryName(relativeTransformPath)));
            }

            if (!fileSystem.DirectoryExists(fullTransformPath))
            {
                yield break;
            }

            // The reason we use fileSystem.EnumerateFiles here is to get the actual file-names from the physical file-system.
            // This prevents any issues with mis-matched casing in transform specifications.
            foreach (var transformFile in fileSystem.EnumerateFiles(fullTransformPath, GetFileName(defaultTransformFileName), GetFileName(transformFileName)))
            {
                var sourceFileName = (transformation?.SourcePattern?.Contains(Path.DirectorySeparatorChar) ?? false)
                    ? fileSystem.GetRelativePath(transformFile, sourceFile).TrimStart('.', Path.DirectorySeparatorChar)
                    : GetFileName(sourceFile);

                if (transformation.Advanced && !transformation.IsSourceWildcard && !string.Equals(transformation.SourcePattern, sourceFileName, StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }

                if (transformation.Advanced && transformation.IsSourceWildcard && !DoesFileMatchWildcardPattern(sourceFileName, transformation.SourcePattern))
                {
                    continue;
                }

                if (!fileSystem.FileExists(transformFile))
                {
                    continue;
                }

                if (string.Equals(sourceFile, transformFile, StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }

                yield return(transformFile);
            }
        }
示例#15
0
        void DeleteExtractionDestination(JournalEntry deployment, List <JournalEntry> preservedEntries)
        {
            if (!fileSystem.DirectoryExists(deployment.ExtractedTo) ||
                preservedEntries.Any(entry => deployment.ExtractedTo.Equals(entry.ExtractedTo, StringComparison.Ordinal)))
            {
                return;
            }

            Log.Info($"Removing directory '{deployment.ExtractedTo}'");
            fileSystem.PurgeDirectory(deployment.ExtractedTo, FailureOptions.IgnoreFailure);

            try
            {
                fileSystem.DeleteDirectory(deployment.ExtractedTo);
            }
            catch (Exception ex)
            {
                Log.VerboseFormat("Could not delete directory '{0}' because some files could not be deleted: {1}",
                                  deployment.ExtractedFrom, ex.Message);
            }
        }
        // When a package has been installed once, Octopus gives users the ability to 'force' a redeployment of the package.
        // This is often useful for example if a deployment partially completes and the installation is in an invalid state
        // (e.g., corrupt files are left on disk, or the package is only half extracted). We *can't* just uninstall the package
        // or overwrite the files, since they might be locked by IIS or another process. So instead we create a new unique
        // directory.
        static string EnsureTargetPathExistsAndIsEmpty(string desiredTargetPath, ICalamariFileSystem fileSystem)
        {
            var target = desiredTargetPath;

            using (Semaphore.Acquire("Octopus.Calamari.ExtractionDirectory", "Another process is finding an extraction directory, please wait..."))
            {
                for (var i = 1; fileSystem.DirectoryExists(target) || fileSystem.FileExists(target); i++)
                {
                    target = desiredTargetPath + "_" + i;
                }

                fileSystem.EnsureDirectoryExists(target);
            }

            return(target);
        }
示例#17
0
        public void ApplyRetentionPolicy(string retentionPolicySet, int?days, int?releases)
        {
            var deployments = deploymentJournal.GetAllJournalEntries().Where(x => x.RetentionPolicySet == retentionPolicySet);

            if (days.HasValue && days.Value > 0)
            {
                deployments = deployments.Where(x => x.InstalledOn < clock.GetUtcTime().AddDays(-days.Value)).ToList();
            }
            else if (releases.HasValue && releases.Value > 0)
            {
                var skipped = 0;

                // Keep the current release, plus specified releases value
                // Unsuccessful releases are not included in the count of releases to keep
                deployments = deployments
                              .OrderByDescending(x => x.InstalledOn)
                              .SkipWhile((x) => (x.WasSuccessful ? skipped++ : skipped) <= releases.Value)
                              .ToList();
            }

            foreach (var deployment in deployments)
            {
                if (fileSystem.DirectoryExists(deployment.ExtractedTo))
                {
                    Log.VerboseFormat("Removing directory '{0}'", deployment.ExtractedTo);
                    fileSystem.PurgeDirectory(deployment.ExtractedTo, DeletionOptions.TryThreeTimesIgnoreFailure);

                    try
                    {
                        fileSystem.DeleteDirectory(deployment.ExtractedTo);
                    }
                    catch (Exception ex)
                    {
                        Log.VerboseFormat("Could not delete directory '{0}' because some files could not be deleted: {1}", deployment.ExtractedFrom, ex.Message);
                    }
                }

                if (!string.IsNullOrWhiteSpace(deployment.ExtractedFrom) && fileSystem.FileExists(deployment.ExtractedFrom))
                {
                    Log.VerboseFormat("Removing package file '{0}'", deployment.ExtractedFrom);
                    fileSystem.DeleteFile(deployment.ExtractedFrom, DeletionOptions.TryThreeTimesIgnoreFailure);
                }
            }

            deploymentJournal.RemoveJournalEntries(deployments.Select(x => x.Id));
        }
        /// <summary>
        /// Uploads multiple files given the globbing patterns provided by the selection properties.
        /// </summary>
        /// <param name="clientFactory"></param>
        /// <param name="deployment"></param>
        /// <param name="selection"></param>
        private IEnumerable <S3UploadResult> UploadMultiFileSelection(Func <AmazonS3Client> clientFactory, RunningDeployment deployment, S3MultiFileSelectionProperties selection)
        {
            Guard.NotNull(deployment, "Deployment may not be null");
            Guard.NotNull(selection, "Multi file selection properties may not be null");
            Guard.NotNull(clientFactory, "Client factory must not be null");

            var files = fileSystem.EnumerateFilesWithGlob(deployment.StagingDirectory, selection.Pattern).ToList();

            if (!files.Any())
            {
                Log.Info($"The glob pattern '{selection.Pattern}' didn't match any files. Nothing was uploaded to S3.");
                yield break;
            }

            Log.Info($"Glob pattern '{selection.Pattern}' matched {files.Count} files.");
            var substitutionPatterns = selection.VariableSubstitutionPatterns?.Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries) ?? new string[0];

            new SubstituteInFilesConvention(fileSystem, fileSubstituter,
                                            _ => substitutionPatterns.Any(),
                                            _ => substitutionPatterns)
            .Install(deployment);

            var patternSegments = selection.Pattern.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
            var baseDir         = deployment.StagingDirectory;

            foreach (var segment in patternSegments)
            {
                var newBaseDir = Path.Combine(baseDir, segment);
                if (!fileSystem.DirectoryExists(newBaseDir))
                {
                    break;
                }

                baseDir = newBaseDir;
            }

            foreach (var matchedFile in files)
            {
                yield return(CreateRequest(matchedFile, GetBucketKey(baseDir, matchedFile, new S3MultiFileSelectionBucketKeyAdapter(selection)), selection)
                             .Tee(x => LogPutObjectRequest(matchedFile, x))
                             //We only warn on multi file uploads
                             .Map(x => HandleUploadRequest(clientFactory(), x, WarnAndIgnoreException)));
            }
        }
示例#19
0
        private string GetChartLocation(RunningDeployment deployment)
        {
            var packagePath = deployment.Variables.Get(Deployment.SpecialVariables.Package.Output.InstallationDirectoryPath);

            var packageId = deployment.Variables.Get(Deployment.SpecialVariables.Package.NuGetPackageId);

            if (fileSystem.FileExists(Path.Combine(packagePath, "Chart.yaml")))
            {
                return(Path.Combine(packagePath, "Chart.yaml"));
            }

            packagePath = Path.Combine(packagePath, packageId);
            if (!fileSystem.DirectoryExists(packagePath) || !fileSystem.FileExists(Path.Combine(packagePath, "Chart.yaml")))
            {
                throw new CommandException($"Unexpected error. Chart.yaml was not found in {packagePath}");
            }

            return(packagePath);
        }
        private IEnumerable <string> DetermineTransformFileNames(string sourceFile, XmlConfigTransformDefinition transformation)
        {
            var defaultTransformFileName = DetermineTransformFileName(sourceFile, transformation, true);
            var transformFileName        = DetermineTransformFileName(sourceFile, transformation, false);

            var relativeTransformPath = fileSystem.GetRelativePath(sourceFile, transformFileName);
            var fullTransformPath     = Path.GetFullPath(Path.Combine(GetDirectoryName(sourceFile), GetDirectoryName(relativeTransformPath)));

            if (!fileSystem.DirectoryExists(fullTransformPath))
            {
                return(Enumerable.Empty <string>());
            }

            // The reason we use fileSystem.EnumerateFiles here is to get the actual file-names from the physical file-system.
            // This prevents any issues with mis-matched casing in transform specifications.
            return(fileSystem.EnumerateFiles(fullTransformPath,
                                             GetFileName(defaultTransformFileName),
                                             GetFileName(transformFileName)
                                             ));
        }
        string GetChartLocation(RunningDeployment deployment)
        {
            var installDir = deployment.Variables.Get(PackageVariables.Output.InstallationDirectoryPath);

            var packageId = deployment.Variables.Get(PackageVariables.IndexedPackageId(string.Empty));

            // Try the root directory
            if (fileSystem.FileExists(Path.Combine(installDir, "Chart.yaml")))
            {
                return(Path.Combine(installDir, "Chart.yaml"));
            }

            // Try the directory that matches the package id
            var packageIdPath = Path.Combine(installDir, packageId);

            if (fileSystem.DirectoryExists(packageIdPath) && fileSystem.FileExists(Path.Combine(packageIdPath, "Chart.yaml")))
            {
                return(packageIdPath);
            }

            /*
             * Although conventions suggests that the directory inside the helm archive matches the package ID, this
             * can not be assumed. If the standard locations above failed to locate the Chart.yaml file, loop over
             * all subdirectories to try and find the file.
             */
            foreach (var dir in fileSystem.EnumerateDirectories(installDir))
            {
                if (fileSystem.FileExists(Path.Combine(dir, "Chart.yaml")))
                {
                    return(dir);
                }
            }

            // Nothing worked
            throw new CommandException($"Unexpected error. Chart.yaml was not found in {packageIdPath}");
        }
示例#22
0
        public void SetUp()
        {
            fileSystem = Substitute.For<ICalamariFileSystem>();
            deploymentJournal = Substitute.For<IDeploymentJournal>();
            clock = Substitute.For<IClock>();
            retentionPolicy = new RetentionPolicy(fileSystem, deploymentJournal, clock);

            now = new DateTimeOffset(new DateTime(2015, 01, 15), new TimeSpan(0, 0, 0));
            clock.GetUtcTime().Returns(now);

            // Deployed 4 days prior to 'now'
            fourDayOldDeployment = new JournalEntry("fourDayOld", "blah", "blah", "blah", "blah", policySet1,
                now.AddDays(-4).LocalDateTime,
                "C:\\packages\\Acme.1.0.0.nupkg", "C:\\Applications\\Acme.1.0.0", null, true);

            // Deployed 3 days prior to 'now'
            threeDayOldDeployment = new JournalEntry("threeDayOld", "blah", "blah", "blah", "blah", policySet1,
                now.AddDays(-3).LocalDateTime,
                "C:\\packages\\Acme.1.1.0.nupkg", "C:\\Applications\\Acme.1.1.0", null, true);

            // Deployed 2 days prior to 'now'
            twoDayOldDeployment = new JournalEntry("twoDayOld", "blah", "blah", "blah", "blah", policySet1,
                now.AddDays(-2).LocalDateTime,
                "C:\\packages\\Acme.1.2.0.nupkg", "C:\\Applications\\Acme.1.2.0", null, true);

            // Deployed (unsuccessfully) 1 day prior to 'now'
            oneDayOldUnsuccessfulDeployment = new JournalEntry("oneDayOldUnsuccessful", "blah", "blah", "blah", "blah", policySet1,
                now.AddDays(-1).LocalDateTime,
                "C:\\packages\\Acme.1.3.0.nupkg", "C:\\Applications\\Acme.1.3.0", null, false);

            // Deployed 5 days prior to 'now', but has a different policy-set
            fiveDayOldNonMatchingDeployment = new JournalEntry("fiveDayOld", "blah", "blah", "blah", "blah", policySet2,
                now.AddDays(-5).LocalDateTime,
                "C:\\packages\\Beta.1.0.0.nupkg", "C:\\Applications\\Beta.1.0.0", null, true);

            var journalEntries = new List<JournalEntry>
            {
                fiveDayOldNonMatchingDeployment,
                fourDayOldDeployment,
                threeDayOldDeployment,
                twoDayOldDeployment,
                oneDayOldUnsuccessfulDeployment
            };

            deploymentJournal.GetAllJournalEntries().Returns(journalEntries);

            foreach (var journalEntry in journalEntries)
            {
                fileSystem.FileExists(journalEntry.ExtractedFrom).Returns(true);
                fileSystem.DirectoryExists(journalEntry.ExtractedTo).Returns(true);
            }
        }
        public IEnumerable <string> DetermineTransformFileNames(string sourceFile, XmlConfigTransformDefinition transformation, bool diagnosticLoggingEnabled, string currentDirectory)
        {
            var defaultTransformFileName = DetermineTransformFileName(sourceFile, transformation, true);
            var transformFileName        = DetermineTransformFileName(sourceFile, transformation, false);

            string fullTransformDirectoryPath;

            if (Path.IsPathRooted(transformFileName))
            {
                fullTransformDirectoryPath = Path.GetFullPath(GetDirectoryName(transformFileName));
            }
            else
            {
                var relativeTransformPath = fileSystem.GetRelativePath(sourceFile, transformFileName);
                fullTransformDirectoryPath = Path.GetFullPath(Path.Combine(GetDirectoryName(sourceFile), GetDirectoryName(relativeTransformPath)));
            }

            if (!fileSystem.DirectoryExists(fullTransformDirectoryPath))
            {
                if (diagnosticLoggingEnabled)
                {
                    log.Verbose($" - Skipping as transform folder \'{fullTransformDirectoryPath}\' does not exist");
                }
                yield break;
            }

            // The reason we use fileSystem.EnumerateFiles here is to get the actual file-names from the physical file-system.
            // This prevents any issues with mis-matched casing in transform specifications.
            var enumerateFiles = fileSystem.EnumerateFiles(fullTransformDirectoryPath, GetFileName(defaultTransformFileName), GetFileName(transformFileName)).Distinct().ToArray();

            if (enumerateFiles.Any())
            {
                foreach (var transformFile in enumerateFiles)
                {
                    var sourceFileName = GetSourceFileName(sourceFile, transformation, transformFileName, transformFile, currentDirectory);

                    if (transformation.Advanced && !transformation.IsSourceWildcard &&
                        !string.Equals(transformation.SourcePattern, sourceFileName, StringComparison.OrdinalIgnoreCase))
                    {
                        if (diagnosticLoggingEnabled)
                        {
                            log.Verbose($" - Skipping as file name \'{sourceFileName}\' does not match the target pattern \'{transformation.SourcePattern}\'");
                        }
                        continue;
                    }

                    if (transformation.Advanced && transformation.IsSourceWildcard &&
                        !DoesFileMatchWildcardPattern(sourceFileName, transformation.SourcePattern))
                    {
                        if (diagnosticLoggingEnabled)
                        {
                            log.Verbose($" - Skipping as file name \'{sourceFileName}\' does not match the wildcard target pattern \'{transformation.SourcePattern}\'");
                        }
                        continue;
                    }

                    if (!fileSystem.FileExists(transformFile))
                    {
                        if (diagnosticLoggingEnabled)
                        {
                            log.Verbose($" - Skipping as transform \'{transformFile}\' does not exist");
                        }
                        continue;
                    }

                    if (string.Equals(sourceFile, transformFile, StringComparison.OrdinalIgnoreCase))
                    {
                        if (diagnosticLoggingEnabled)
                        {
                            log.Verbose($" - Skipping as target \'{sourceFile}\' is the same as transform \'{transformFile}\'");
                        }
                        continue;
                    }

                    yield return(transformFile);
                }
            }
            else if (diagnosticLoggingEnabled)
            {
                if (GetFileName(defaultTransformFileName) == GetFileName(transformFileName))
                {
                    log.Verbose($" - skipping as transform \'{GetFileName(defaultTransformFileName)}\' could not be found in \'{fullTransformDirectoryPath}\'");
                }
                else
                {
                    log.Verbose($" - skipping as neither transform \'{GetFileName(defaultTransformFileName)}\' nor transform \'{GetFileName(transformFileName)}\' could be found in \'{fullTransformDirectoryPath}\'");
                }
            }
        }
示例#24
0
        public void SetUp()
        {
            fileSystem        = Substitute.For <ICalamariFileSystem>();
            deploymentJournal = Substitute.For <IDeploymentJournal>();
            clock             = Substitute.For <IClock>();
            retentionPolicy   = new RetentionPolicy(fileSystem, deploymentJournal, clock);

            now = new DateTimeOffset(new DateTime(2015, 01, 15), new TimeSpan(0, 0, 0));
            clock.GetUtcTime().Returns(now);

            // Deployed 4 days prior to 'now'
            fourDayOldDeployment = new JournalEntry("fourDayOld", "blah", "blah", "blah", policySet1,
                                                    now.AddDays(-4).LocalDateTime, "C:\\Applications\\Acme.1.0.0", null, true,
                                                    new DeployedPackage("blah", "blah", "C:\\packages\\Acme.1.0.0.nupkg"));

            // Deployed 4 days prior to 'now' but to the same location as the latest successful deployment
            fourDayOldSameLocationDeployment = new JournalEntry("fourDayOldSameLocation", "blah", "blah", "blah", policySet1,
                                                                now.AddDays(-4).LocalDateTime, "C:\\Applications\\Acme.1.2.0", null, true,
                                                                new DeployedPackage("blah", "blah", "C:\\packages\\Acme.1.2.0.nupkg"));

            // Deployed 3 days prior to 'now'
            threeDayOldDeployment = new JournalEntry("threeDayOld", "blah", "blah", "blah", policySet1,
                                                     now.AddDays(-3).LocalDateTime, "C:\\Applications\\Acme.1.1.0", null, true,
                                                     new DeployedPackage("blah", "blah", "C:\\packages\\Acme.1.1.0.nupkg"));

            // Deployed 2 days prior to 'now'
            twoDayOldDeployment = new JournalEntry("twoDayOld", "blah", "blah", "blah", policySet1,
                                                   now.AddDays(-2).LocalDateTime, "C:\\Applications\\Acme.1.2.0", null, true,
                                                   new DeployedPackage("blah", "blah", "C:\\packages\\Acme.1.2.0.nupkg"));

            // Deployed (unsuccessfully) 1 day prior to 'now'
            oneDayOldUnsuccessfulDeployment = new JournalEntry("oneDayOldUnsuccessful", "blah", "blah", "blah", policySet1,
                                                               now.AddDays(-1).LocalDateTime, "C:\\Applications\\Acme.1.3.0", null, false,
                                                               new DeployedPackage("blah", "blah", "C:\\packages\\Acme.1.3.0.nupkg"));

            // Deployed 5 days prior to 'now', but has a different policy-set
            fiveDayOldNonMatchingDeployment = new JournalEntry("fiveDayOld", "blah", "blah", "blah", policySet2,
                                                               now.AddDays(-5).LocalDateTime, "C:\\Applications\\Beta.1.0.0", null, true,
                                                               new DeployedPackage("blah", "blah", "C:\\packages\\Beta.1.0.0.nupkg"));

            // Step with multiple packages, deployed 4 days prior, and referencing the same source file as the latest successful
            // deployment from a different step
            fourDayOldMultiPackageDeployment = new JournalEntry("fourDayOldMultiPackage", "blah", "blah", "blah", policySet3,
                                                                now.AddDays(-4).LocalDateTime, null, null, true,
                                                                new []
            {
                new DeployedPackage("blah", "blah", "C:\\packages\\Acme.1.2.0.nupkg"),
                new DeployedPackage("foo", "blah", "C:\\packages\\Foo.0.0.9.nupkg")
            });

            // Step with multiple packages, deployed 2 days prior
            twoDayOldMultiPackageDeployment = new JournalEntry("twoDayOldMultiPackage", "blah", "blah", "blah", policySet3,
                                                               now.AddDays(-2).LocalDateTime, null, null, true,
                                                               new []
            {
                new DeployedPackage("blah", "blah", "C:\\packages\\Acme.1.2.0.nupkg"),
                new DeployedPackage("foo", "blah", "C:\\packages\\Foo.1.0.0.nupkg")
            });

            // We may reference packages which are not acquired (e.g. docker containers from script steps).
            // These will not have a `DeployedFrom` path.
            twoDayOldDeploymentWithPackageThatWasNotAcquired = new JournalEntry("twoDayOldNotAcquired",
                                                                                "blah", "blah", "blah", policySet4,
                                                                                now.AddDays(-2).LocalDateTime, null, null, true,
                                                                                new[]
            {
                new DeployedPackage("blah", "blah", null)
            });

            fiveDayOldDeploymentWithPackageThatWasNotAcquired = new JournalEntry("fiveDayOldNotAcquired",
                                                                                 "blah", "blah", "blah", policySet4,
                                                                                 now.AddDays(-5).LocalDateTime, null, null, true,
                                                                                 new[]
            {
                new DeployedPackage("blah", "blah", null)
            });


            var journalEntries = new List <JournalEntry>
            {
                fiveDayOldNonMatchingDeployment,
                fourDayOldDeployment,
                threeDayOldDeployment,
                twoDayOldDeployment,
                oneDayOldUnsuccessfulDeployment,
                fourDayOldMultiPackageDeployment,
                twoDayOldMultiPackageDeployment,
                fiveDayOldDeploymentWithPackageThatWasNotAcquired
            };

            deploymentJournal.GetAllJournalEntries().Returns(journalEntries);

            foreach (var journalEntry in journalEntries)
            {
                if (!string.IsNullOrEmpty(journalEntry.ExtractedTo))
                {
                    fileSystem.DirectoryExists(journalEntry.ExtractedTo).Returns(true);
                }

                foreach (var deployedPackage in journalEntry.Packages)
                {
                    fileSystem.FileExists(deployedPackage.DeployedFrom).Returns(true);
                }
            }

            Environment.SetEnvironmentVariable("TentacleHome", @"Q:\TentacleHome");
        }