Ejemplo n.º 1
0
        protected FrontEndHostController RunEngineAndGetFrontEndHostController(
            ICommandLineConfiguration config,
            AppDeployment appDeployment,
            string testRootDirectory,
            bool rememberAllChangedTrackedInputs,
            Action <EngineTestHooksData> verifyEngineTestHooksData = null)
        {
            var result = CreateAndRunEngine(
                config,
                appDeployment,
                testRootDirectory,
                rememberAllChangedTrackedInputs,
                out var engine,
                verifyEngineTestHooksData);

            m_frontEndContext = engine.Context.ToFrontEndContext(LoggingContext);
            verifyEngineTestHooksData?.Invoke(engine.TestHooks);

            // If the engine reloaded and created a new pipGraph we need to udpate the Test file system with that new pipgraph as well
            if (!engine.TestHooks.GraphReuseResult.IsNoReuse)
            {
                FileSystem = (IMutableFileSystem)engine.Context.FileSystem;
            }

            if (!result.IsSuccess)
            {
                Assert.True(false, $"Failed to run the engine. See '{testRootDirectory ?? TestOutputDirectory}' for more details.");
            }

            return((FrontEndHostController)engine.FrontEndController);
        }
Ejemplo n.º 2
0
        protected virtual BuildXLEngineResult CreateAndRunEngine(
            ICommandLineConfiguration config,
            AppDeployment appDeployment,
            string testRootDirectory,
            bool rememberAllChangedTrackedInputs,
            out BuildXLEngine engine,
            Action <EngineTestHooksData> verifyEngineTestHooksData = null,
            TestCache testCache = null)
        {
            testCache = testCache ?? TestCache;

            using (EngineTestHooksData testHooks = new EngineTestHooksData
            {
                AppDeployment = appDeployment,
                CacheFactory = (context) => new EngineCache(
                    testCache.GetArtifacts(context),
                    testCache.Fingerprints)
            })
            {
                engine = CreateEngine(config, appDeployment, testRootDirectory, rememberAllChangedTrackedInputs, verifyEngineTestHooksData);

                // Ignore DX222 for csc.exe being outside of src directory
                IgnoreWarnings();

                engine.TestHooks = testHooks;

                var result = engine.RunForFrontEndTests(LoggingContext);
                return(result);
            }
        }
Ejemplo n.º 3
0
        protected virtual BuildXLEngine CreateEngine(ICommandLineConfiguration config,
                                                     AppDeployment appDeployment,
                                                     string testRootDirectory,
                                                     bool rememberAllChangedTrackedInputs,
                                                     Action <EngineTestHooksData> verifyEngineTestHooksData = null)
        {
            var engineContext = EngineContext.CreateNew(CancellationToken.None, PathTable, FileSystem);

            var factory = FrontEndControllerFactory.Create(
                FrontEndMode.NormalMode,
                LoggingContext,
                config,
                // Set the timeout to a large number to avoid useless performance collections in tests.
                new PerformanceCollector(TimeSpan.FromHours(1)),
                collectMemoryAsSoonAsPossible: false);

            var engine = BuildXLEngine.Create(
                LoggingContext,
                engineContext,
                config,
                factory,
                rememberAllChangedTrackedInputs: rememberAllChangedTrackedInputs
                );

            return(engine);
        }
Ejemplo n.º 4
0
 private void RunAndAssertGraphCacheHit(ICommandLineConfiguration config, AppDeployment appDeployment, bool rememberAllChangedTrackedInputs = false)
 {
     using (var hostController = RunEngineAndGetFrontEndHostController(config, appDeployment, null, rememberAllChangedTrackedInputs))
     {
         AssertNotLogged(LogEventId.EndSerializingPipGraph);
         XAssert.IsNull(hostController.Workspace);
     }
 }
Ejemplo n.º 5
0
 protected static AppDeployment CreateAppDeployment(TempFileStorage tempFiles)
 {
     string manifestPath = tempFiles.GetFileName(AppDeployment.DeploymentManifestFileName);
     File.WriteAllText(
         Path.Combine(Path.GetDirectoryName(manifestPath), AppDeployment.DeploymentManifestFileName),
         AssemblyHelper.GetAssemblyLocation(Assembly.GetExecutingAssembly()));
     AppDeployment appDeployment = AppDeployment.ReadDeploymentManifest(Path.GetDirectoryName(manifestPath), AppDeployment.DeploymentManifestFileName, skipManifestCheckTestHook: true);
     return appDeployment;
 }
Ejemplo n.º 6
0
 private void updateCheck_DoWork(object sender, DoWorkEventArgs e)
 {
     try
     {
         e.Result = AppDeployment.CheckForDetailedUpdate();
     }
     catch (Exception x)
     {
         e.Result = x;
     }
 }
Ejemplo n.º 7
0
        public void Test()
        {
            string root = Path.Combine(TemporaryDirectory, "testDeployment");

            Directory.CreateDirectory(root);
            File.WriteAllText(
                Path.Combine(root, TestServerManifestName),
                @"included1.dll
included1.pdb
excluded1.txt
subdir" + Path.DirectorySeparatorChar + "included2.exe" + Environment.NewLine +
                AppDeployment.BuildXLBrandingManifestFileName);

            File.WriteAllText(Path.Combine(root, "included1.dll"), "test");
            // Include pdbs to aid with call stacks when debugging
            File.WriteAllText(Path.Combine(root, "included1.pdb"), "test");
            File.WriteAllText(Path.Combine(root, "excluded1.txt"), "test");
            File.WriteAllText(Path.Combine(root, "excluded2.dll"), "test");
            File.WriteAllText(Path.Combine(root, AppDeployment.BuildXLBrandingManifestFileName), "test");
            Directory.CreateDirectory(Path.Combine(root, "subdir"));
            File.WriteAllText(Path.Combine(root, "subdir", "included2.exe"), "test");

            // Create an initial app deployment and verify it is correct
            AppDeployment deployment = AppDeployment.ReadDeploymentManifest(root, TestServerManifestName);

            // Verify the file count. PDB files should only be included for the server deployment.
            XAssert.AreEqual(4, deployment.GetRelevantRelativePaths(forServerDeployment: true).Count());
            XAssert.AreEqual(3, deployment.GetRelevantRelativePaths(forServerDeployment: false).Count());
            Fingerprint originalHash = deployment.TimestampBasedHash;

            // Now mess with files that should not impact the state and make sure they are excluded

            // This file is excluded because of the extension. It is in the manifest
            UpdateFile(Path.Combine(root, "excluded1.txt"));

            // This file is excluded because it isn't in the deployment manifest
            UpdateFile(Path.Combine(root, "excluded2.dll"));

            AppDeployment deployment2 = AppDeployment.ReadDeploymentManifest(root, TestServerManifestName);

            XAssert.AreEqual(
                deployment.TimestampBasedHash.ToHex(),
                deployment2.TimestampBasedHash.ToHex());

            // Mess with a file that is in the deployment and check that the hash does change
            UpdateFile(Path.Combine(root, "subdir", "included2.exe"));
            AppDeployment deployment3 = AppDeployment.ReadDeploymentManifest(root, TestServerManifestName);

            XAssert.AreNotEqual(
                deployment.TimestampBasedHash.ToHex(),
                deployment3.TimestampBasedHash.ToHex());
        }
Ejemplo n.º 8
0
 private void update_ProgressChanged(UpdateProgress e, ILongWaitBroker broker)
 {
     if (broker.IsCanceled)
     {
         AppDeployment.UpdateAsyncCancel();
     }
     else
     {
         long updateBytes = Math.Max(_updateInfo.UpdateSizeBytes ?? 0, e.BytesTotal);
         broker.Message       = GetProgressMessage(e.BytesCompleted, updateBytes);
         broker.ProgressValue = updateBytes == 0
             ? 0 : (int)Math.Min(99, e.BytesCompleted * 100 / updateBytes);
     }
 }
Ejemplo n.º 9
0
        public void IdentityManifestMissing(bool includeInDeploymentManifest)
        {
            string root = Path.Combine(TemporaryDirectory, "testDeployment");

            Directory.CreateDirectory(root);
            File.WriteAllText(
                Path.Combine(root, TestServerManifestName),
                "included1.dll" + Environment.NewLine +
                (includeInDeploymentManifest ? AppDeployment.BuildXLBrandingManifestFileName : string.Empty));

            if (!includeInDeploymentManifest)
            {
                File.WriteAllText(Path.Combine(root, AppDeployment.BuildXLBrandingManifestFileName), "whatever");
            }

            Assert.Throws <BuildXLException>(() => AppDeployment.ReadDeploymentManifest(root, TestServerManifestName));
        }
Ejemplo n.º 10
0
        public void TestMissingManifestFile()
        {
            var manifestRootDir = TemporaryDirectory;
            var manifestPath    = Path.Combine(manifestRootDir, AppDeployment.DeploymentManifestFileName);

            File.WriteAllText(manifestPath, AssemblyHelper.GetAssemblyLocation(Assembly.GetExecutingAssembly()));

            var appDeployment = AppDeployment.ReadDeploymentManifest(
                manifestRootDir,
                AppDeployment.DeploymentManifestFileName,
                skipManifestCheckTestHook: true);

            string deploymentDir = ServerDeployment.ComputeDeploymentDir(manifestRootDir);

            Directory.CreateDirectory(deploymentDir);

            XAssert.IsTrue(ServerDeployment.IsServerDeploymentOutOfSync(manifestRootDir, appDeployment, out deploymentDir));
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Checks if the deployed server bits are still up-to-date.
        /// </summary>
        public static bool IsServerDeploymentOutOfSync(string serverDeploymentRoot, AppDeployment clientApp, out string deploymentDir)
        {
            deploymentDir = ComputeDeploymentDir(serverDeploymentRoot);
            if (Directory.Exists(deploymentDir))
            {
                try
                {
                    // Calculates a hash of the contents of the BuildXL binaries from the server deployment directory.
                    AppDeployment serverDeployment = AppDeployment.ReadDeploymentManifest(deploymentDir, AppDeployment.ServerDeploymentManifestFileName);
                    return(clientApp.TimestampBasedHash.ToHex() != serverDeployment.TimestampBasedHash.ToHex());
                }
                catch (BuildXLException)
                {
                    // This case occurs when the deployment directory is missing or the ServerDeploymentManifestFile is missing
                    return(true);
                }
            }

            return(true);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// If the deployment hash of the client is not the same as the deployment hash of the server cache, creates a new deployment cache. Otherwise, does nothing.
        /// </summary>
        /// <exception cref="IOException">
        /// Throws if the copy fails</exception>
        public static ServerDeployment GetOrCreateServerDeploymentCache(string serverDeploymentRoot, AppDeployment clientApp)
        {
            var deploymentDir = ComputeDeploymentDir(serverDeploymentRoot);

            ServerDeploymentCacheCreated?cacheCreated = null;

            if (!Directory.Exists(deploymentDir) || clientApp.TimestampBasedHash.ToHex() != GetDeploymentCacheHash(deploymentDir))
            {
                cacheCreated = CreateServerDeployment(deploymentDir, clientApp);
            }

            return(new ServerDeployment(deploymentDir, cacheCreated));
        }
Ejemplo n.º 13
0
 private void BeginUpdate(ILongWaitBroker broker)
 {
     AppDeployment.UpdateAsync(ev => update_ProgressChanged(ev, broker), update_Complete);
 }
Ejemplo n.º 14
0
        private void updateCheck_Complete(object sender, RunWorkerCompletedEventArgs e)
        {
            var exTrust = e.Result as TrustNotGrantedException;

            if (exTrust != null)
            {
                if (ShowUpgradeForm(AppDeployment.GetVersionFromUpdateLocation(), false, true))
                {
                    AppDeployment.OpenInstallLink(ParentWindow);
                }
                return;
            }
            var ex = e.Result as Exception;

            if (ex != null)
            {
                // Show an error message box to allow a user to inspect the exception stack trace
                MessageDlg.ShowWithException(ParentWindow,
                                             Resources.UpgradeManager_updateCheck_Complete_Failed_attempting_to_check_for_an_upgrade_, ex);
                // Show no upgrade found message to allow a user to turn off or on this checking
                ShowUpgradeForm(null, false, false);
                return;
            }
            _updateInfo = e.Result as UpdateCheckDetails;
            if (_updateInfo != null && _updateInfo.UpdateAvailable)
            {
                if (!ShowUpgradeForm(_updateInfo.AvailableVersion, true, true))
                {
                    return;
                }

                using (var longWaitUpdate = new LongWaitDlg
                {
                    Text = string.Format(Resources.UpgradeManager_updateCheck_Complete_Upgrading__0_, Program.Name),
                    Message = GetProgressMessage(0, _updateInfo.UpdateSizeBytes ?? 0),
                    ProgressValue = 0
                })
                {
                    longWaitUpdate.PerformWork(ParentWindow, 500, broker =>
                    {
                        BeginUpdate(broker);
                        _endUpdateEvent.WaitOne();
                        _endUpdateEvent.Dispose();
                        broker.ProgressValue = 100;
                    });
                }
                if (_completeArgs == null || _completeArgs.Cancelled)
                {
                    return;
                }

                if (_completeArgs.Error != null)
                {
                    MessageDlg.ShowWithException(ParentWindow,
                                                 Resources.UpgradeManager_updateCheck_Complete_Failed_attempting_to_upgrade_, _completeArgs.Error);
                    if (ShowUpgradeForm(null, false, true))
                    {
                        AppDeployment.OpenInstallLink(ParentWindow);
                    }
                    return;
                }

                AppDeployment.Restart();
            }
            else if (!_startup)
            {
                ShowUpgradeForm(null, false, false);
            }
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Checks if the deployed server bits are still up-to-date.
 /// </summary>
 public static bool IsServerDeploymentOutOfSync(string serverDeploymentRoot, AppDeployment clientApp, out string deploymentDir)
 {
     deploymentDir = ComputeDeploymentDir(serverDeploymentRoot);
     return(!Directory.Exists(deploymentDir) || clientApp.TimestampBasedHash.ToHex() != GetDeploymentCacheHash(deploymentDir));
 }
Ejemplo n.º 16
0
        protected IList <AbsolutePath> RunAndRetrieveSpecs(ICommandLineConfiguration config, AppDeployment appDeployment, bool rememberAllChangedTrackedInputs = false)
        {
            IList <AbsolutePath> specs;

            using (var controller = RunEngineAndGetFrontEndHostController(config, appDeployment, null, rememberAllChangedTrackedInputs))
            {
                var workspace = controller.Workspace;
                specs = workspace.GetAllSpecFiles().Where(spec => !workspace.PreludeModule.Specs.ContainsKey(spec)).ToList();
            }

            Assert.True(specs != null);
            return(specs);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// If the deployment hash of the client is not the same as the deployment hash of the server cache, creates a new deployment cache. Otherwise, does nothing.
        /// </summary>
        /// <exception cref="IOException">
        /// Throws if the copy fails</exception>
        public static ServerDeployment GetOrCreateServerDeploymentCache(string serverDeploymentRoot, AppDeployment clientApp)
        {
            ServerDeploymentCacheCreated?cacheCreated = null;

            if (IsServerDeploymentOutOfSync(serverDeploymentRoot, clientApp, out var deploymentDir))
            {
                cacheCreated = CreateServerDeployment(deploymentDir, clientApp);
            }

            return(new ServerDeployment(deploymentDir, cacheCreated));
        }
Ejemplo n.º 18
0
        private static ServerDeploymentCacheCreated CreateServerDeployment(string destDir, AppDeployment clientApp)
        {
            Stopwatch st = Stopwatch.StartNew();

            // Every time the server cache gets created, a file with the result of GetDeploymentHash is created, so we avoid computing this again
            // The assumption is that nobody but this process modifies the server cache folder
            string serverDeploymentHashFile = Path.Combine(destDir, ServerDeploymentHashFilename);

            // Deletes the existing cache directory if it exists, so we avoid accumulating garbage.
            if (Directory.Exists(destDir))
            {
                // Check if the main root process (likely bxl.exe) is in use before attempting to delete, so we avoid partially deleting files
                // Not completely bullet proof (there can be a race) but it is highly unlikely the process starts to be in use right after this check
                KillServer(destDir);

                // Delete the deployment hash file first to make sure the deployment cache cannot be used in case the
                // cleanup of the other files is interrupted.
                PoisonServerDeployment(destDir);

                // Remove all files regardless of files being readonly
                FileUtilities.DeleteDirectoryContents(destDir, true);
            }

            // Perform the deployment
            AppDeployment    serverDeployment = AppDeployment.ReadDeploymentManifest(clientApp.BaseDirectory, AppDeployment.ServerDeploymentManifestFileName);
            HashSet <string> directories      = new HashSet <string>();
            List <KeyValuePair <string, string> > filesToCopy = new List <KeyValuePair <string, string> >();

            foreach (string path in serverDeployment.GetRelevantRelativePaths(forServerDeployment: true).Concat(new string[] { AppDeployment.ServerDeploymentManifestFileName }))
            {
                string targetPath = Path.Combine(destDir, path);
                string sourcePath = Path.Combine(clientApp.BaseDirectory, path);
                string directory  = Path.GetDirectoryName(targetPath);
                if (directories.Add(directory))
                {
                    FileUtilities.CreateDirectory(directory);
                }

                filesToCopy.Add(new KeyValuePair <string, string>(sourcePath, targetPath));
            }

            // Because some deployments use virtualized vpak, using a very parallelized copy is beneficial
            Parallel.ForEach(
                filesToCopy,
                new ParallelOptions()
            {
                MaxDegreeOfParallelism = 50,
            },
                (fileToCopy) =>
            {
                if (File.Exists(fileToCopy.Key))
                {
                    File.Copy(fileToCopy.Key, fileToCopy.Value);
                }
            });

#if !FEATURE_CORECLR
            var ngenExe = Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), @"ngen.exe");
            var destExe = Path.Combine(destDir, System.AppDomain.CurrentDomain.FriendlyName);

            // queue:1 means it runs in the background
            var  ngenArgs = "install " + destExe + " /queue:1";
            bool runNgen  = File.Exists(ngenExe);
            if (runNgen)
            {
                ProcessStartInfo startInfo = new ProcessStartInfo(ngenExe, ngenArgs);
                startInfo.UseShellExecute = false;
                startInfo.CreateNoWindow  = true;
                Process.Start(startInfo);
            }
#endif
            using (var file = new StreamWriter(File.OpenWrite(serverDeploymentHashFile)))
            {
                file.WriteLine(clientApp.TimestampBasedHash);

                // This isn't actually consumed. It is only used for debugging
                file.WriteLine("Debug info:");
#if !FEATURE_CORECLR
                if (runNgen)
                {
                    file.WriteLine("Ran Ngen: " + ngenExe + " " + ngenArgs);
                }
#endif
                file.WriteLine(clientApp.TimestampBasedHashDebug);
            }

            ServerDeploymentCacheCreated cacheCreated = default(ServerDeploymentCacheCreated);
            cacheCreated.TimeToCreateServerCacheMilliseconds = st.ElapsedMilliseconds;

            return(cacheCreated);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Calculates a hash of the contents of the BuildXL binaries from the server deployment directory.
        /// </summary>
        public static string GetDeploymentCacheHash(string deploymentDir)
        {
            AppDeployment serverDeployment = AppDeployment.ReadDeploymentManifest(deploymentDir, AppDeployment.ServerDeploymentManifestFileName);

            return(serverDeployment.TimestampBasedHash.ToHex());
        }
Ejemplo n.º 20
0
        private static ServerDeploymentCacheCreated CreateServerDeployment(string destDir, AppDeployment clientApp)
        {
            Stopwatch st = Stopwatch.StartNew();

            // Check if the main server process is in use before attempting to delete the deployment, this way we avoid partially deleting files
            // due to access permission issues. This is not completely bullet proof (there can be a race) but it is highly unlikely the
            // process starts to be in use right after this check
            KillServer(destDir);

            // Deletes the existing cache directory if it exists, so we avoid accumulating garbage.
            if (Directory.Exists(destDir))
            {
                // Remove all files regardless of files being readonly
                FileUtilities.DeleteDirectoryContents(destDir, true);
            }

            // Perform the deployment
            AppDeployment    serverDeployment = AppDeployment.ReadDeploymentManifest(clientApp.BaseDirectory, AppDeployment.ServerDeploymentManifestFileName);
            HashSet <string> directories      = new HashSet <string>();
            List <KeyValuePair <string, string> > filesToCopy = new List <KeyValuePair <string, string> >();

            foreach (string path in serverDeployment.GetRelevantRelativePaths(forServerDeployment: true).Concat(new string[] { AppDeployment.ServerDeploymentManifestFileName }))
            {
                string targetPath = Path.Combine(destDir, path);
                string sourcePath = Path.Combine(clientApp.BaseDirectory, path);
                string directory  = Path.GetDirectoryName(targetPath);
                if (directories.Add(directory))
                {
                    FileUtilities.CreateDirectory(directory);
                }

                filesToCopy.Add(new KeyValuePair <string, string>(sourcePath, targetPath));
            }

            // Because some deployments use virtualized vpak, using a very parallelized copy is beneficial
            Parallel.ForEach(
                filesToCopy,
                new ParallelOptions()
            {
                MaxDegreeOfParallelism = 50,
            },
                (fileToCopy) =>
            {
                if (File.Exists(fileToCopy.Key))
                {
                    File.Copy(fileToCopy.Key, fileToCopy.Value);
                }
            });

#if NET_FRAMEWORK
            var ngenExe = Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), @"ngen.exe");
            var destExe = Path.Combine(destDir, System.AppDomain.CurrentDomain.FriendlyName);

            // queue:1 means it runs in the background
            if (File.Exists(ngenExe))
            {
                var ngenArgs = "install " + destExe + " /queue:1";
                ProcessStartInfo startInfo = new ProcessStartInfo(ngenExe, ngenArgs);
                startInfo.UseShellExecute = false;
                startInfo.CreateNoWindow  = true;
                Process.Start(startInfo);
            }
#endif

            ServerDeploymentCacheCreated cacheCreated = default(ServerDeploymentCacheCreated);
            cacheCreated.TimeToCreateServerCacheMilliseconds = st.ElapsedMilliseconds;

            return(cacheCreated);
        }