using System; using System.Diagnostics; using System.IO; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Net.Sockets; using NLog; using DemoInstaller; namespace DemoInstaller_Test { [TestClass] public class TestP4Server { private static Logger logger = LogManager.GetCurrentClassLogger(); [TestMethod] public void TestBasic() { string root = "c:\\temp\\test-p4d"; string port = "6666"; var p4d = Utilities.DeployP4TestServer(root, port, false); var svr = new DemoInstaller.P4Server("6666", "robert", ""); Assert.IsTrue(svr.Connect()); Assert.IsTrue(svr.userIsSuperuser()); Assert.IsTrue(svr.updateTypemap()); Utilities.RemoveTestServer(p4d, root); } } public class Utilities { private static Logger logger = LogManager.GetCurrentClassLogger(); static string p4d_exe = "p4d.exe"; static string p4d_cmd = @"-p {0} -r ""{1}"" -In {2} -L p4d.log -J journal"; public static Process DeployP4TestServer(string testRoot, string port, bool unicode, string testName = "") { logger.Info("DeployP4TestServer"); string assemblyFile = typeof(Utilities).Assembly.CodeBase; String unitTestDir = Path.GetDirectoryName(assemblyFile); String EnvPath = Environment.GetEnvironmentVariable("path"); String CurWDir = Environment.CurrentDirectory; var testServerRoot = Path.Combine(testRoot, "server"); var testClientsRoot = Path.Combine(testRoot, "clients"); CreateDir(testServerRoot, 10); try { Environment.CurrentDirectory = testServerRoot; } catch (Exception ex) { bool dirExists = Directory.Exists(testServerRoot); logger.Error("Can't cd to {0}, {1}", testServerRoot, ex.Message); return null; } ProcessStartInfo si; Process p4d = new Process(); //start p4d si = new ProcessStartInfo(p4d_exe); if (string.IsNullOrEmpty(testName)) testName = "UnitTestServer"; si.Arguments = String.Format(p4d_cmd, port, testServerRoot, testName); si.WorkingDirectory = testServerRoot; si.UseShellExecute = false; si.RedirectStandardOutput = true; si.CreateNoWindow = true; logger.Info("{0} {1}", si.FileName, si.Arguments); p4d.StartInfo = si; p4d.Start(); Environment.CurrentDirectory = CurWDir; // Give p4d time to start up DateTime started = DateTime.UtcNow; TcpClient client = new TcpClient(); while (DateTime.UtcNow.Subtract(started).Milliseconds < 500) { client.Connect("localhost", 6666); if (client.Connected) return p4d; } // that didn't work return p4d; } public static void RemoveTestServer(Process p, String testRoot, bool resetDepot = false, bool unicode = false) { logger.Info("RemoveTestServer"); if (p != null) { if (!p.HasExited) p.Kill(); p.WaitForExit(); // sleep for a second to let the system clean up // System.Threading.Thread.Sleep(100); } ClobberDirectory(testRoot); //MainTest.RememberToCleanup(rubbishBin); //MainTest.RememberToCleanup(testRoot); //// Flag for next unit test to reset depot - see DeployP4TestServer //ResetServer.SetResetRequired(unicode, resetDepot); } public static void ClobberDirectory(String path) { DirectoryInfo di = new DirectoryInfo(path); ClobberDirectory(di); } public static void ClobberDirectory(DirectoryInfo di) { string comSpec = Environment.GetEnvironmentVariable("ComSpec"); Process Zapper = new Process(); ProcessStartInfo si = new ProcessStartInfo(comSpec, "/c rd /S /Q " + di.FullName); si.WorkingDirectory = Path.GetDirectoryName(di.FullName); si.UseShellExecute = true; Zapper.StartInfo = si; try { Zapper.Start(); } catch (Exception ex) { logger.Info("In ClobberDirectory, Zapper.Start() failed: {0}", ex.Message); } if (Zapper.HasExited == false) { Zapper.WaitForExit(); } if (Directory.Exists(di.FullName)) { bool worked = false; int retries = 0; do { if (!di.Exists) return; try { FileInfo[] files = di.GetFiles(); foreach (FileInfo fi in files) { if (fi.IsReadOnly) fi.IsReadOnly = false; fi.Delete(); } DirectoryInfo[] subDirs = di.GetDirectories(); foreach (DirectoryInfo sdi in subDirs) { ClobberDirectory(sdi); } di.Delete(); worked = true; } catch (Exception) { System.Threading.Thread.Sleep(100); } retries++; } while (!worked && retries < 2); } } private static void CreateDir(string path, int retries) { while ((Directory.Exists(path) == false) && (retries > 0)) { try { Directory.CreateDirectory(path); if (Directory.Exists(path)) { break; } retries--; System.Threading.Thread.Sleep(1000); } catch (Exception ex) { retries--; bool dirExists = Directory.Exists(path); Trace.WriteLine(ex.Message); if (dirExists) { break; } System.Threading.Thread.Sleep(200); } } } private static void DelDir(string dirPath) { if (!Directory.Exists(dirPath)) return; try { Directory.Delete(dirPath, true); } catch { try { // delete failed, try to rename it Directory.Move(dirPath, string.Format("{0}-{1}", dirPath, DateTime.Now.Ticks)); } catch { // rename failed, try to clobber it (can be slow so last resort) Utilities.ClobberDirectory(dirPath); } } } } }