/// <nodoc />
        public DeploymentProxyService(
            ProxyServiceConfiguration configuration,
            HostParameters hostParameters,
            IAbsFileSystem fileSystem = null,
            IClock clock = null,
            IDeploymentServiceClient client = null)
        {
            clock ??= SystemClock.Instance;
            Configuration        = configuration;
            Root                 = new AbsolutePath(configuration.RootPath);
            Clock                = clock;
            ContentCacheRequests = new VolatileMap <(string, string), AsyncLazy <BoolResult> >(Clock);
            ProxyAddress         = new VolatileMap <UnitValue, AsyncLazy <string> >(Clock);
            Client               = client ?? DeploymentLauncherHost.Instance.CreateServiceClient();
            HostParameters       = hostParameters;

            DownloadQueue = new ActionQueue(configuration.DownloadConcurrency ?? Environment.ProcessorCount);

            Store = new FileSystemContentStoreInternal(
                fileSystem ?? new PassThroughFileSystem(),
                Clock,
                DeploymentUtilities.GetCasRootPath(Root),
                new ConfigurationModel(new ContentStoreConfiguration(new MaxSizeQuota($"{Configuration.RetentionSizeGb}GB"))),
                settings: new ContentStoreSettings()
            {
                TraceFileSystemContentStoreDiagnosticMessages = true,
            });
        }
 static void ValidateAssemblyGetFiles(Assembly assembly)
 {
     if (DeploymentUtilities.IsAssemblyInSingleFile(assembly.GetName().Name))
     {
         ValidateInMemoryGetFiles(assembly);
     }
     else
     {
         ValidateOnDiskGetFiles(assembly);
     }
 }
 private void ValidateAssemblyLocation(Assembly assembly)
 {
     if (DeploymentUtilities.IsAssemblyInSingleFile(assembly.GetName().Name))
     {
         ValidateInMemoryAssemblyLocation(assembly);
     }
     else
     {
         ValidateOnDiskAssemblyLocation(assembly);
     }
 }
            private string[] CreateCommandLine(DistributedCacheServiceArguments arguments)
            {
                var configurationText = DeploymentUtilities.JsonSerialize(arguments.Configuration);
                var configurationPath = Path.Combine(arguments.DataRootPath, "ServerCacheConfiguration.json");

                Directory.CreateDirectory(arguments.DataRootPath);
                File.WriteAllText(configurationPath, configurationText);

                return(new[]
                {
                    "--cacheconfigurationPath", configurationPath
                });
            }
        void ValidateLoadFromInAppAssembly(Assembly assembly)
        {
            string fullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assembly.GetName().Name + ".dll");

            if (DeploymentUtilities.IsAssemblyInSingleFile(assembly.GetName().Name))
            {
                Assert.Throws <FileNotFoundException>(() => Assembly.LoadFrom(fullPath));
            }
            else
            {
                ValidateLoadFromFile(fullPath);
            }
        }
Exemplo n.º 6
0
        void ValidateAssemblyFullyQualifiedName(Assembly assembly)
        {
            var modules = assembly.GetModules();

            Assert.Equal(1, modules.Length);
            var module = modules[0];

            if (DeploymentUtilities.IsAssemblyInSingleFile(assembly.GetName().Name))
            {
                ValidateUnknownModuleFullyQualifiedName(module);
            }
            else
            {
                ValidateOnDiskModuleFullyQualifiedName(module);
            }
        }
Exemplo n.º 7
0
        public void BaseDirectory()
        {
            // We need to somehow detect the 3.1 backward compat case where single-file extracts everything onto disk
            // The application assembly seems like the best detection mechanism - if it's a single-file
            // but even the application assembly is not loaded from bundle -> fully extracted.
            if (DeploymentUtilities.IsSingleFile && !DeploymentUtilities.IsAssemblyInSingleFile(typeof(AppDomainBaseDirectory).Assembly.GetName().Name))
            {
                Assert.NotEqual(DeploymentUtilities.ExecutableLocation, AppDomain.CurrentDomain.BaseDirectory);
#pragma warning disable IL3000
                Assert.Equal(Path.GetDirectoryName(typeof(AppDomainBaseDirectory).Assembly.Location) + Path.DirectorySeparatorChar, AppDomain.CurrentDomain.BaseDirectory);
#pragma warning restore IL3000
            }
            else
            {
                Assert.Equal(DeploymentUtilities.ExecutableLocation + Path.DirectorySeparatorChar, AppDomain.CurrentDomain.BaseDirectory);
            }
        }
Exemplo n.º 8
0
        public void TestStringConvertibleSettings()
        {
            var serialized = @"{ 'Mode': 'WriteBothPreferDistributed', 'TimeThreshold': '3d5h10m42s' }"
                             .Replace('\'', '"');;

            var deserialized          = DeploymentUtilities.JsonDeserialize <TestConfig>(serialized);
            var deserializedWithNulls = DeploymentUtilities.JsonDeserialize <TestConfigWithNulls>(serialized);

            Assert.Equal(ContentMetadataStoreMode.WriteBothPreferDistributed, deserialized.Mode.Value);

            var expectedTimeThreshold = TimeSpan.FromDays(3) + TimeSpan.FromHours(5) + TimeSpan.FromMinutes(10) + TimeSpan.FromSeconds(42);

            Assert.Equal(expectedTimeThreshold, deserialized.TimeThreshold.Value);

            Assert.Equal(ContentMetadataStoreMode.WriteBothPreferDistributed, deserializedWithNulls.Mode.Value.Value);
            Assert.Equal(expectedTimeThreshold, deserializedWithNulls.TimeThreshold.Value.Value);
        }
        public void LoadFrameworkAssemblyFromPathAndUnload()
        {
            var assembly = typeof(System.Xml.XmlReader).Assembly;

#pragma warning disable IL3000
            string fullPath = DeploymentUtilities.IsSelfContained
                ? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assembly.GetName().Name + ".dll")
                : assembly.Location;
#pragma warning restore IL3000

            if (DeploymentUtilities.IsAssemblyInSingleFile(assembly.GetName().Name))
            {
                Assert.Throws <FileNotFoundException>(() => Assembly.LoadFrom(fullPath));
            }
            else
            {
                ValidateLoadFromPathIntoALCAndUnload(nameof(LoadFrameworkAssemblyFromPathAndUnload), fullPath);
            }
        }
        /// <summary>
        /// Quick copy this artefact in the context of the specific package, and the specific containing artefact only.
        /// </summary>
        /// <param name="packageProject">The project.</param>
        /// <param name="parentArtefact">The deployable SharePoint artefact.</param>
        /// <param name="requiresQuickPackage">Flag to indicate it requires a quick package.</param>
        public override void QuickCopy(SharePointPackageArtefact packageProject, QuickCopyableSharePointArtefact parentArtefact, bool requiresQuickPackage)
        {
            if (parentArtefact == null)
            {
                throw new NotSupportedException();
            }
            else if (parentArtefact is SharePointPackageArtefact)
            {
                string sourcePathBase    = packageProject.BasePackagePath;
                string featureFolderName = this.FeatureFolderName;

                feature.Project.ProjectService.Logger.ActivateOutputWindow();
                feature.Project.ProjectService.Logger.WriteLine("------ Quick Copying Feature: " + this.FeatureFolderName + " ------", LogCategory.Status);

                // Feature.xml must first be Quick Copied.
                if (requiresQuickPackage)
                {
                    // Tokens consist of those from this package, and feature.
                    Dictionary <string, string> allTokens = new Dictionary <string, string>();
                    allTokens.AddRange(packageProject.GetReplacementTokens());
                    allTokens.AddRange(this.Tokens);

                    // TODO: Merge feature.feature.
                    feature.Project.ProjectService.Logger.ActivateOutputWindow();
                    feature.Project.ProjectService.Logger.WriteLine("WARNING: Quick packaging of changes to Feature.feature is not yet supported.  The last packaged version of the file will be copied.", LogCategory.Warning);

                    //QuickDeploymentUtilities.CopyFileWithTokenReplacement(packageProject.Project, file.Name, originalFileProjectRelative, sourcePackagePathProjectRelative, allTokens);
                }

                DeploymentUtilities.CopyFile(packageProject.Project, "Feature.xml", Path.Combine(sourcePathBase, featureFolderName), "{SharePointRoot}\\Template\\Features\\" + featureFolderName);

                // Process items in features.  Note that we are only processing items that have been set to be packaged.
                foreach (SharePointProjectItemArtefact spi in this.ChildArtefacts.Select(ca => ca as SharePointProjectItemArtefact))
                {
                    spi.QuickCopy(packageProject, this, requiresQuickPackage);
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
Exemplo n.º 11
0
        public override bool OnStart()
        {
            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

            // Replace lucene path in web.config
            var path = DeploymentUtilities.GetVirtualDirPath("API");

            DeploymentUtilities.WriteToConfig(path, path);

            // Replace base url
            DeploymentUtilities.UpdateBaseUrl("Web", @"Content\movie.core.js");
            DeploymentUtilities.UpdateWebUrl("Web", @"Content\movie.core.js");
            DeploymentUtilities.UpdateBaseUrl("Editorial", @"Content\controls\mm.admin.core.js");
            DeploymentUtilities.UpdateBaseUrl("Editorial", @"Content\movie.autocomplete.js");

            // Lucene setup
            DeploymentUtilities.HandleLucene("API");

            // Setup IIS settings
            DeploymentUtilities.SetupIISSettings();

            // Schedule monkey
            Task.Run(() =>
            {
                var installDirPath = DeploymentUtilities.GetVirtualDirPath("Web");
                DeploymentUtilities.ScheduleSmartMonkey(installDirPath);
            });

            // Run monkey
            Task.Run(() =>
            {
                var installDirPath = DeploymentUtilities.GetVirtualDirPath("Web");
                DeploymentUtilities.RunSmartMonkey(installDirPath);
            });

            // Mark as start
            var result = base.OnStart();

            return(result);
        }
        public void LoadFromFrameworkAssembly()
        {
            // Note: We're not testing CoreLib here since loading CoreLib explicitly from file is forbidden

            var assembly = typeof(System.Xml.XmlReader).Assembly;

#pragma warning disable IL3000
            string fullPath = DeploymentUtilities.IsAssemblyInSingleFile(assembly.GetName().Name)
                ? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assembly.GetName().Name + ".dll")
                : assembly.Location;
#pragma warning restore IL3000

            if (DeploymentUtilities.IsAssemblyInSingleFile(assembly.GetName().Name))
            {
                Assert.Throws <FileNotFoundException>(() => Assembly.LoadFrom(fullPath));
            }
            else
            {
                ValidateLoadFromFile(fullPath);
            }
        }
        public void AppContextDepsFiles()
        {
            string appContextDepsFiles = (string)AppContext.GetData("APP_CONTEXT_DEPS_FILES");
            string expectedPath        = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FeatureTest.deps.json");

            if (DeploymentUtilities.IsAssemblyInSingleFile(typeof(RuntimeProperties).Assembly.GetName().Name))
            {
                Assert.DoesNotContain(expectedPath, appContextDepsFiles);
            }
            else
            {
                Assert.Contains(expectedPath, appContextDepsFiles);
            }

            foreach (string path in appContextDepsFiles.Split(";", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
            {
                if (!File.Exists(path))
                {
                    throw new XunitException($"APP_CONTEXT_DEPS_FILES contains paths '{path}' which doesn't exist.");
                }
            }
        }
Exemplo n.º 14
0
        public async Task TestFullDeployment()
        {
            var sources = new Dictionary <string, string>()
            {
                { @"Env\RootFile.json", "{ 'key1': 1, 'key2': 2 }" },
                { @"Env\Subfolder\Hello.txt", "Hello world" },
                { @"Env\Foo.txt", "Baz" },

                { @"Files\Foo.txt", "Bar" },
            };

            Dictionary <string, string> getSourceDrop(string root, string prefix)
            {
                return(sources.Where(e => e.Key.StartsWith(root))
                       .ToDictionary(e => e.Key.Substring(prefix.Length), e => e.Value));
            }

            var expectedSourceDrops = new Dictionary <string, Dictionary <string, string> >()
            {
                {
                    "file://Env", getSourceDrop(@"Env\", @"Env\")
                },
                {
                    "file://Files/Foo.txt", getSourceDrop(@"Files\Foo.txt", @"Files\")
                },
                {
                    "file://Env/Foo.txt", getSourceDrop(@"Env\Foo.txt", @"Env\")
                }
            };

            var drops = new Dictionary <string, Dictionary <string, string> >()
            {
                {
                    "https://dev.azure.com/buildxlcachetest/drop/drops/dev/testdrop1?root=release/win-x64",
                    new Dictionary <string, string>
                    {
                        { @"file1.bin", "File content 1" },
                        { @"file2.txt", "File content 2" },
                        { @"sub\file3.dll", "File content 3" }
                    }
                },
                {
                    "https://dev.azure.com/buildxlcachetest/drop/drops/dev/testdrop2?root=debug",
                    new Dictionary <string, string>
                    {
                        { @"file1.bin", "File content 1" },
                        { @"file2.txt", "File content 2 changed" },
                        { @"sub\file5.dll", "File content 5" }
                    }
                }
            };

            var config = new TestDeploymentConfig()
            {
                Drops =
                {
                    new TestDeploymentConfig.DropDeploymentConfiguration()
                    {
                        { "Url [Ring:Ring_0]",        "https://dev.azure.com/buildxlcachetest/drop/drops/dev/testdrop1?root=release/win-x64" },
                        { "Url [Ring:Ring_1]",        "https://dev.azure.com/buildxlcachetest/drop/drops/dev/testdrop2?root=debug"           },
                    },
                    new TestDeploymentConfig.DropDeploymentConfiguration()
                    {
                        { "Url",                      "file://Env"                                                                           },
                    },
                    new TestDeploymentConfig.DropDeploymentConfiguration()
                    {
                        { "Url [Stamp:DefaultStamp]", "file://Files/Foo.txt"                                                                 },
                    },
                    new TestDeploymentConfig.DropDeploymentConfiguration()
                    {
                        { "Url [Stamp:DefaultStamp]", "file://Env/Foo.txt"                                                                   },
                    }
                }
            };

            var deploymentRunner = new DeploymentRunner(
                Context,
                sourceRoot: TestRootDirectoryPath / "src",
                deploymentRoot: TestRootDirectoryPath / "deploy",
                deploymentConfigurationPath: TestRootDirectoryPath / "DeploymentConfiguration.json",
                FileSystem,
                dropExeFilePath: TestRootDirectoryPath / @"dropbin\drop.exe",
                retentionSizeGb: 1,
                dropToken: DropToken);

            // Write source files
            WriteFiles(deploymentRunner.SourceRoot, sources);

            var configText = JsonSerializer.Serialize(config, new JsonSerializerOptions()
            {
                WriteIndented = true
            });

            FileSystem.WriteAllText(deploymentRunner.DeploymentConfigurationPath, configText);

            deploymentRunner.OverrideLaunchDropProcess = t =>
            {
                var dropContents = drops[t.dropUrl];
                WriteFiles(new AbsolutePath(t.targetDirectory) / (t.relativeRoot ?? ""), dropContents);
                return(BoolResult.Success);
            };

            await deploymentRunner.RunAsync().ShouldBeSuccess();

            var manifestText       = FileSystem.ReadAllText(deploymentRunner.DeploymentManifestPath);
            var deploymentManifest = JsonSerializer.Deserialize <DeploymentManifest>(manifestText);

            foreach (var drop in deploymentManifest.Drops)
            {
                var uri = new Uri(drop.Key);

                var expectedDropContents = uri.IsFile ? expectedSourceDrops[drop.Key] : drops[drop.Key];
                var layoutSpec           = deploymentManifest.Drops[drop.Key];
                layoutSpec.Count.Should().Be(expectedDropContents.Count);
                foreach (var fileAndContent in expectedDropContents)
                {
                    var hash         = new ContentHash(layoutSpec[fileAndContent.Key].Hash);
                    var expectedPath = deploymentRunner.DeploymentRoot / DeploymentUtilities.GetContentRelativePath(hash);

                    var text = FileSystem.ReadAllText(expectedPath);
                    text.Should().Be(fileAndContent.Value);
                }
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Quick copy this artefact in the context of the specific package, and the specific containing artefact only.
        /// </summary>
        /// <param name="packageProject">The project.</param>
        /// <param name="parentFeature">The deployable SharePoint artefact.</param>
        /// <param name="requiresQuickPackage">Flag to indicate it requires a quick package.</param>
        public void QuickCopy(SharePointPackageArtefact packageProject, SharePointProjectFeatureArtefact parentFeature, bool requiresQuickPackage)
        {
            if (file.DeploymentType != DeploymentType.NoDeployment)
            {
                // Determine the folder name of the parent feature (if applicable).
                string featureFolderName = parentFeature == null ? "" : parentFeature.FeatureFolderName;

                // The default destination path is given to us by the tooling (though includes tokens).
                string destinationPathHiveRelative = String.Empty;
                if (String.IsNullOrEmpty(file.DeploymentPath))
                {
                    destinationPathHiveRelative = file.DeploymentRoot;
                }
                else
                {
                    destinationPathHiveRelative = Path.Combine(file.DeploymentRoot, file.DeploymentPath);
                }

                // The source path of the packageable file begins with the base package path of the project.
                string sourcePackagePathProjectRelative = packageProject.BasePackagePath;

                // The remainder of the package path depends on the type of file.
                if (file.DeploymentType == DeploymentType.ElementFile || file.DeploymentType == DeploymentType.ElementManifest)
                {
                    // Source path within pkg is {FeatureName} + the item's relative path.
                    sourcePackagePathProjectRelative = Path.Combine(sourcePackagePathProjectRelative, featureFolderName);
                    sourcePackagePathProjectRelative = Path.Combine(sourcePackagePathProjectRelative, Path.GetDirectoryName(file.RelativePath));
                }
                if (file.DeploymentType == DeploymentType.AppGlobalResource || file.DeploymentType == DeploymentType.ApplicationResource)
                {
                    sourcePackagePathProjectRelative = Path.Combine(sourcePackagePathProjectRelative, Path.GetDirectoryName(file.RelativePath));
                }
                else if (file.DeploymentType == DeploymentType.RootFile || file.DeploymentType == DeploymentType.TemplateFile)
                {
                    // For both template and root files, these are stored relative to the pkg folder with a
                    // path matching file.DeploymentPath.
                    sourcePackagePathProjectRelative = Path.Combine(sourcePackagePathProjectRelative, Path.GetDirectoryName(file.DeploymentPath));
                }
                else
                {
                    // Unhandled file type.  Just show a message for now.
                    // TODO: check all the file types we should spuport and test.
                    packageProject.Project.ProjectService.Logger.ActivateOutputWindow();
                    packageProject.Project.ProjectService.Logger.WriteLine(string.Format("Unhandled File Type - {0} at {1} - please notify the CKSDEV team", file.DeploymentType, file.FullPath), LogCategory.Status);
                }

                // Make some final substitutions on the paths as necessary.
                sourcePackagePathProjectRelative = sourcePackagePathProjectRelative.Replace("{FeatureName}", featureFolderName);
                destinationPathHiveRelative      = destinationPathHiveRelative.Replace("{FeatureName}", featureFolderName);

                // First package (if appropriate), then quick copy the file.
                if (requiresQuickPackage)
                {
                    // The actual project file path is also given to us by the tooling.
                    string originalFileProjectRelative = Path.GetDirectoryName(file.FullPath);

                    Dictionary <string, string> allTokens = null;
                    if (DeploymentUtilities.IsTokenReplacementFile(file.Project, file.Name))
                    {
                        // Tokens consist of those from this package, SPI, and (optionally) the feature.
                        allTokens = new Dictionary <string, string>();
                        allTokens.AddRange(packageProject.GetReplacementTokens());
                        allTokens.AddRange(new SharePointProjectItemArtefact(file.ProjectItem).GetReplacementTokens());
                        if (parentFeature != null)
                        {
                            allTokens.AddRange(parentFeature.GetReplacementTokens());
                        }
                    }

                    DeploymentUtilities.CopyFileWithTokenReplacement(packageProject.Project, file.Name, originalFileProjectRelative, sourcePackagePathProjectRelative, allTokens);
                }

                DeploymentUtilities.CopyFile(packageProject.Project, file.Name, sourcePackagePathProjectRelative, destinationPathHiveRelative);
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Quicks the copy binaries.
        /// </summary>
        /// <param name="requiresQuickPackage">if set to <c>true</c> [requires quick package].</param>
        public void QuickCopyBinaries(bool requiresQuickPackage)
        {
            project.ProjectService.Logger.ActivateOutputWindow();
            project.ProjectService.Logger.WriteLine("------ Quick Copying Binaries: " + project.Name + " ------", LogCategory.Status);
            string currentProjectAssemblyName = Path.GetFileName(project.OutputFullPath);
            bool   baseAssemblyCopied         = false;

            if (project.IncludeAssemblyInPackage)
            {
                string packageBaseAssemblyPath = this.BasePackagePath;

                if (requiresQuickPackage)
                {
                    // Ensure the source file exists - it won't if the project has never been built.  In this case we
                    // let the CopyToGac() and CopyToBin() methods below handle the error.
                    if (File.Exists(project.OutputFullPath))
                    {
                        // Copy the binary from the source folder (e.g. bin/debug) to the appropriate place in the pkg folder.
                        DeploymentUtilities.CopyFileWithTokenReplacement(this.Project,
                                                                         currentProjectAssemblyName,
                                                                         Path.GetDirectoryName(project.OutputFullPath),
                                                                         packageBaseAssemblyPath,
                                                                         null
                                                                         );
                    }
                }

                string sourceAssembly = Path.Combine(packageBaseAssemblyPath, currentProjectAssemblyName);
                if (project.AssemblyDeploymentTarget == AssemblyDeploymentTarget.GlobalAssemblyCache)
                {
                    DeploymentUtilities.CopyToGac(project, sourceAssembly);
                }
                else
                {
                    DeploymentUtilities.CopyToBin(project, sourceAssembly);
                }
                baseAssemblyCopied = true;
            }

            foreach (IAssembly assembly in project.Package.Model.Assemblies)
            {
                string packageBaseAssemblyPath = this.BasePackagePath;
                string assemblyName            = assembly.Location;

                if (requiresQuickPackage)
                {
                    string originalAssemblyPath = null;
                    if (assembly is ICustomAssembly)
                    {
                        ICustomAssembly customAssembly = assembly as ICustomAssembly;
                        originalAssemblyPath = Path.GetDirectoryName(customAssembly.SourcePath);
                    }
                    else if (assembly is IProjectOutputAssembly)
                    {
                        IProjectOutputAssembly poAssembly = assembly as IProjectOutputAssembly;
                        string projectPath = poAssembly.ProjectPath;

                        // Happen if project is manually referenced in package
                        if (string.IsNullOrEmpty(projectPath))
                        {
                            if (currentProjectAssemblyName == poAssembly.Location)
                            {
                                if (baseAssemblyCopied)
                                {
                                    continue;
                                }

                                originalAssemblyPath = project.OutputFullPath;
                            }
                            else
                            {
                                project.ProjectService.Logger.ActivateOutputWindow();
                                project.ProjectService.Logger.WriteLine($"WARNING: can't find project path for {poAssembly.Location}", LogCategory.Warning);
                                continue;
                            }
                        }
                        else
                        {
                            string projPath = Path.GetDirectoryName(projectPath);
                            originalAssemblyPath = Path.Combine(projPath, this.AssemblyPath);
                        }
                    }

                    if (originalAssemblyPath != null)
                    {
                        string originalFullPath = Path.Combine(Path.GetDirectoryName(project.FullPath), originalAssemblyPath);
                        if (File.Exists(Path.Combine(originalFullPath, assemblyName)))
                        {
                            // Copy the binary from the source location (e.g. bin/debug) to the appropriate place in the pkg folder.
                            DeploymentUtilities.CopyFileWithTokenReplacement(this.Project,
                                                                             assemblyName,
                                                                             originalFullPath,
                                                                             packageBaseAssemblyPath,
                                                                             null
                                                                             );
                        }
                    }
                }

                string sourceAssembly = Path.Combine(packageBaseAssemblyPath, assemblyName);
                if (assembly.DeploymentTarget == DeploymentTarget.GlobalAssemblyCache)
                {
                    DeploymentUtilities.CopyToGac(project, sourceAssembly);
                }
                else
                {
                    DeploymentUtilities.CopyToBin(project, sourceAssembly);
                }
            }
        }
Exemplo n.º 17
0
        public async Task TestFullDeployment()
        {
            var sources = new Dictionary <string, string>()
            {
                { @"Stamp3\info.txt", "" },

                { @"Env\RootFile.json", "{ 'key1': 1, 'key2': 2 }" },
                { @"Env\Subfolder\Hello.txt", "Hello world" },
                { @"Env\Foo.txt", "Baz" },

                { @"Files\Foo.txt", "Bar" },
            };

            Dictionary <string, string> getSourceDrop(string root, string prefix)
            {
                return(sources.Where(e => e.Key.StartsWith(root))
                       .ToDictionary(e => e.Key.Substring(prefix.Length), e => e.Value));
            }

            var drops = new Dictionary <string, Dictionary <string, string> >()
            {
                {
                    "https://dev.azure.com/buildxlcachetest/drop/drops/dev/testdrop1?root=release/win-x64",
                    new Dictionary <string, string>
                    {
                        { @"file1.bin", "File content 1" },
                        { @"file2.txt", "File content 2" },
                        { @"sub\file3.dll", "File content 3" }
                    }
                },
                {
                    "https://dev.azure.com/buildxlcachetest/drop/drops/dev/testdrop2?root=debug",
                    new Dictionary <string, string>
                    {
                        { @"file1.bin", "File content 1" },
                        { @"file2.txt", "File content 2 changed" },
                        { @"sub\file5.dll", "File content 5" }
                    }
                },
                {
                    DeploymentUtilities.ConfigDropUri.OriginalString,
                    new Dictionary <string, string>()
                    {
                        { DeploymentUtilities.DeploymentConfigurationFileName, ConfigString }
                    }
                },
                {
                    "file://Env", getSourceDrop(@"Env\", @"Env\")
                },
                {
                    "file://Files/Foo.txt", getSourceDrop(@"Files\Foo.txt", @"Files\")
                },
                {
                    "file://Env/Foo.txt", getSourceDrop(@"Env\Foo.txt", @"Env\")
                },
                {
                    "file://Stamp3", getSourceDrop(@"Stamp3\", @"Stamp3\")
                }
            };

            var deploymentRoot = TestRootDirectoryPath / "deploy";
            var ingester       = new DeploymentIngester(
                Context,
                sourceRoot: base.TestRootDirectoryPath / "src",
                deploymentRoot: deploymentRoot,
                deploymentConfigurationPath: base.TestRootDirectoryPath / "DeploymentConfiguration.json",
                FileSystem,
                dropExeFilePath: base.TestRootDirectoryPath / @"dropbin\drop.exe",
                retentionSizeGb: 1,
                dropToken: DropToken);

            // Write source files
            WriteFiles(ingester.SourceRoot, sources);

            FileSystem.WriteAllText(ingester.DeploymentConfigurationPath, ConfigString);

            ingester.OverrideLaunchDropProcess = t =>
            {
                var dropContents = drops[t.dropUrl];
                WriteFiles(new AbsolutePath(t.targetDirectory) / (t.relativeRoot ?? ""), dropContents);
                return(BoolResult.Success);
            };

            await ingester.RunAsync().ShouldBeSuccess();

            var manifestText       = FileSystem.ReadAllText(ingester.DeploymentManifestPath);
            var deploymentManifest = JsonSerializer.Deserialize <DeploymentManifest>(manifestText);

            foreach (var drop in drops)
            {
                var uri = new Uri(drop.Key);
                var expectedDropContents = drops[drop.Key];
                var layoutSpec           = deploymentManifest.Drops[drop.Key];
                layoutSpec.Count.Should().Be(expectedDropContents.Count);
                foreach (var fileAndContent in expectedDropContents)
                {
                    var hash         = new ContentHash(layoutSpec[fileAndContent.Key].Hash);
                    var expectedPath = ingester.DeploymentRoot / DeploymentUtilities.GetContentRelativePath(hash);

                    var text = FileSystem.ReadAllText(expectedPath);
                    text.Should().Be(fileAndContent.Value);
                }
            }

            var clock             = new MemoryClock();
            var deploymentService = new DeploymentService(new DeploymentServiceConfiguration(), deploymentRoot, _ => new TestSecretsProvider(), clock);

            BoxRef <Task> uploadFileCompletion = Task.CompletedTask;

            deploymentService.OverrideCreateCentralStorage = t => new DeploymentTestCentralStorage(t.storageSecretName)
            {
                UploadFileCompletion = uploadFileCompletion
            };

            await verifyLaunchManifestAsync(new DeploymentParameters()
            {
                Stamp = "ST_S3",
                Ring  = "Ring_1"
            },
                                            new HashSet <(string targetPath, string drop)>()
            {
                ("bin", "https://dev.azure.com/buildxlcachetest/drop/drops/dev/testdrop2?root=debug"),
                ("", "file://Env"),
                ("info", "file://Stamp3"),
            });

            async Task <LauncherManifest> verifyLaunchManifestAsync(DeploymentParameters parameters, HashSet <(string targetPath, string drop)> expectedDrops)
            {
                var launchManifest = await deploymentService.UploadFilesAndGetManifestAsync(Context, parameters, waitForCompletion : true);

                var expectedDeploymentPathToHashMap = new Dictionary <string, string>();

                launchManifest.Drops.Count.Should().Be(expectedDrops.Count);
                foreach (var drop in launchManifest.Drops)
                {
                    var targetRelativePath = drop.TargetRelativePath ?? string.Empty;
                    expectedDrops.Should().Contain((targetRelativePath, drop.Url));

                    var dropSpec = deploymentManifest.Drops[drop.Url];
                    foreach (var dropFile in drops[drop.Url])
                    {
                        expectedDeploymentPathToHashMap[Path.Combine(targetRelativePath, dropFile.Key)] = dropSpec[dropFile.Key].Hash;
                    }
                }

                launchManifest.Deployment.Count.Should().Be(expectedDeploymentPathToHashMap.Count);

                foreach (var file in launchManifest.Deployment)
                {
                    var expectedHash = expectedDeploymentPathToHashMap[file.Key];
                    file.Value.Hash.Should().Be(expectedHash);
                }

                return(launchManifest);
            }
        }