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);
}
}
}
}
}