public BuildMachine(BuildMachineSettings settings) { Settings = settings; State = BuildMachineState.Idle; CurrentTimeout = 0; NeedClean = false; }
/// <summary> /// Returns the build template for the given configuration. /// </summary> /// <param name="sConfiguration">Configuration as returned by CMake.</param> /// <returns></returns> public static ezBuildTemplate Create(BuildMachineSettings settings, string sBuildType) { if (sBuildType == "C++") { if (settings.Configuration.StartsWith("Win")) { bool bIs64Bit = settings.Configuration.Contains("64"); if (settings.Configuration.Contains("2012")) { return(new ezBuildWinVS(settings, VSVersion.VS2012, bIs64Bit)); } else if (settings.Configuration.Contains("2013")) { return(new ezBuildWinVS(settings, VSVersion.VS2013, bIs64Bit)); } else if (settings.Configuration.Contains("2015")) { return(new ezBuildWinVS(settings, VSVersion.VS2015, bIs64Bit)); } } else if (settings.Configuration.StartsWith("Osx")) { if (settings.Configuration.Contains("MakeClang")) { return(new BuildMake(settings)); } else if (settings.Configuration.Contains("XcodeClang")) { return(new BuildOsxXcode(settings)); } } else if (settings.Configuration.StartsWith("Linux")) { if (settings.Configuration.Contains("MakeGcc")) { return(new BuildMake(settings)); } } } else if (sBuildType == "D") { if (settings.Configuration.StartsWith("WinVs")) { bool bIs64Bit = settings.Configuration.Contains("64"); if (settings.Configuration.Contains("2012")) { return(new ezBuildWinD(settings, VSVersion.VS2012, bIs64Bit)); } else if (settings.Configuration.Contains("2013")) { return(new ezBuildWinD(settings, VSVersion.VS2013, bIs64Bit)); } else if (settings.Configuration.Contains("2015")) { return(new ezBuildWinD(settings, VSVersion.VS2015, bIs64Bit)); } } } return(null); }
public bool Init(BuildMachineSettings settings) { _Settings = settings; try { // Make sure the given parameter is valid. if (!System.IO.Path.IsPathRooted(_Settings.AbsCodePath)) { Console.WriteLine("SVN Init failed: The path '{0}' is not absolute!", _Settings.AbsCodePath); return(false); } if (!System.IO.Directory.Exists(_Settings.AbsCodePath)) { Console.WriteLine("SVN Init failed: The path '{0}' does not exist!", _Settings.AbsCodePath); return(false); } Console.WriteLine("SVN Init: Code path: '{0}'.", _Settings.AbsCodePath); } catch (Exception ex) { Console.WriteLine(ex); return(false); } return(true); }
public bool Init(BuildMachineSettings settings) { _Result.Clean(); _Settings = settings; try { // Make sure the given parameter is valid. if (!System.IO.Path.IsPathRooted(_Settings.AbsCMakeWorkspace)) { Console.WriteLine("CMake Init failed: The path '{0}' is not absolute!", _Settings.AbsCMakeWorkspace); return(false); } if (!System.IO.Directory.Exists(_Settings.AbsCMakeWorkspace)) { Console.WriteLine("CMake Init failed: The path '{0}' does not exist!", _Settings.AbsCMakeWorkspace); return(false); } Console.WriteLine("CMake Init: Workspace: '{0}'.", _Settings.AbsCMakeWorkspace); // Run process to get configuration and code dir. ezProcessHelper.ProcessResult res = ezProcessHelper.RunExternalExe("cmake", ".", _Settings.AbsCMakeWorkspace, _Result); // Determine the configuration this server is taking care of if non is set. if (String.IsNullOrEmpty(_Settings.Configuration) && !DetermineConfiguration()) { return(false); } Console.WriteLine("CMake Init: Configuration: '{0}'.", _Settings.Configuration); // Determine the code directory this CMake workspace belongs to. if (!DetermineCodeDirectory()) { return(false); } // Determine the bin directory where executables are build to. if (!DetermineBinDirectory()) { return(false); } Console.WriteLine("CMake Init: Code Path: '{0}'.", _Settings.AbsCodePath); } catch (Exception ex) { Console.WriteLine(ex); return(false); } return(true); }
/// <summary> /// Returns the test template for the given configuration. /// </summary> /// <param name="sConfiguration">Configuration as returned by CMake.</param> /// <returns></returns> public static ezTestTemplate Create(BuildMachineSettings settings) { if (settings.Configuration.StartsWith("WinUWP")) { return(new ezTestUWP()); } else { return(new ezTestDefault()); } }
private string HandlePOSTConfiguration(BuildMachineSettings settings) { lock (_Lock) { // We got a new build machine! We use it's configurationName as it's ID as it should be chosen unique by the admin. _Machines[settings.ConfigurationName] = new BuildMachine(settings); DetermineCurrentRevisionOfBuildMachine(_Machines[settings.ConfigurationName]); Console.WriteLine("HandlePOSTConfiguration: New machine '{0}' connected!", settings.ConfigurationName); return(settings.ConfigurationName); } }
bool LoadSettings() { try { string sResultPath = System.IO.Path.Combine(_Result.Settings.AbsCMakeWorkspace, "settings.json"); if (!System.IO.File.Exists(sResultPath)) { Console.WriteLine("The build machine settings are not set yet.\n" + "Open '{0}', change the settings and restart this application.", sResultPath); SaveSettings(); return(false); } string sSerializedResult = System.IO.File.ReadAllText(sResultPath, Encoding.UTF8); BuildMachineSettings settings = JsonConvert.DeserializeObject <BuildMachineSettings>(sSerializedResult); // We take the whole settings except for the 'AbsCMakeWorkspace' which is the only parameter that is given to as as // a command line parameter and could differ if someone copied the settings from another build machine. settings.AbsCMakeWorkspace = _Result.Settings.AbsCMakeWorkspace; if (String.IsNullOrEmpty(settings.BuildType)) { settings.BuildType = "RelWithDebInfo"; } _Result.Settings = settings; if (!CheckSettings()) { return(false); } } catch (Exception ex) { Console.WriteLine("Writing json file failed: {0}", ex.Message); return(false); } return(true); }
public BuildOsxXcode(BuildMachineSettings settings) { _settings = settings; }
public ezBuildWinD(BuildMachineSettings settings, VSVersion version, bool bIs64Bit) { _settings = settings; _Version = version; _bIs64Bit = bIs64Bit; }
private BuildStepResults DeployAppX(ezCMake.TestTarget target, BuildMachineSettings settings, out string fullPackageName) { Console.WriteLine("Deploying AppX ..."); BuildStepResults result = new BuildStepResults(); fullPackageName = ""; string absSlnPath = Path.Combine(settings.AbsCMakeWorkspace, "ezEngine.sln"); if (!File.Exists(absSlnPath)) { result.Error("Visual Studio solution '{0}' does not exist.", absSlnPath); return(result); } // VSLauncher vs using devenv.exe directly. // // Pro VSLauncher: // - It picks always the appropriate VS version // - We know more certainly where it is // // Con VSLauncher: // - Spawns devenv.exe and closes again (we don't know when devenv.exe finishes or if it came up in the first place) // - No console output //string VSLauncherAbsPath = Environment.ExpandEnvironmentVariables(VSLauncherLocation); //if (!File.Exists(VSLauncherAbsPath)) //{ // result.Error("Did not find Visual Studio launcher at '{0}'.", VSLauncherAbsPath); // return result; //} // Using this registry key we should always get the newest devenv version. // Since newer versions can use old compilers & SDKs this should be perfectly fine. // https://social.msdn.microsoft.com/Forums/vstudio/en-US/568e32af-d724-4ac6-8e8f-72181c4320b3/set-default-version-of-visual-studio?forum=vssetup string devEnvPath; try { using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\App Paths\devenv.exe")) { if (key != null) { devEnvPath = key.GetValue("") as string; if (devEnvPath == null) { result.Error("Failed to read Visual Studio location from registry key: No string value in key found."); return(result); } } else { result.Error("Failed to read Visual Studio location from registry key: Registry key not found."); return(result); } } } catch (Exception e) { result.Error("Failed to read Visual Studio location from registry key: {0}", e); return(result); } // Use ".com" version which writes into stdout devEnvPath = devEnvPath.Replace("devenv.exe", "devenv.com"); if (!File.Exists(devEnvPath)) { result.Error("Did not find Visual Studio installation at '{0}'.", devEnvPath); return(result); } // "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.com" "F:\Development\current_development\ezEngine\build_uwp64\ezEngine.sln" /Deploy "RelWithDebInfo|x64" /project CoreTest string platform = settings.Configuration.EndsWith("64") ? "x64" : "Win32"; // No ARM support yet. var deployProcessResults = ezProcessHelper.RunExternalExe(devEnvPath, string.Format("\"{0}\" /Deploy \"{1}|{2}\" /project {3}", absSlnPath, settings.BuildType, platform, target.Name), null, result); result.Duration = deployProcessResults.Duration; if (deployProcessResults.ExitCode != 0) { result.Error("Deployment failed:\n{0}", deployProcessResults.StdOut); result.Success = false; } else { // Get full package name from deploy output. // From the build configuration we only know the package name, not the full identifier. This little parse saves us from searching the package registry. string fullPackageNameStartString = "Full package name: \""; int begin = deployProcessResults.StdOut.LastIndexOf(fullPackageNameStartString) + fullPackageNameStartString.Length; int end = deployProcessResults.StdOut.IndexOf("\"", begin); if (begin < 0 || end < 0) { result.Error("Failed to parse full package name from Visual Studio output. Output was:\n'{0}'.", deployProcessResults.StdOut); return(result); } fullPackageName = deployProcessResults.StdOut.Substring(begin, end - begin); result.Success = true; } return(result); }
static private string GetFileserverPath(BuildMachineSettings settings) { return(Path.Combine(settings.AbsCodePath, relativeFileservePath)); }
public override ezTest.TestTargetResult BuildTarget(ezCMake.TestTarget target, BuildMachineSettings settings) { ezTest.TestTargetResult res = new ezTest.TestTargetResult(); res.Name = target.Name; res.NeedsHardwareAccess = target.NeedsHardwareAccess; res.Experimental = target.Experimental; // Prepare output path (may fail, and we don't want to go through the rest if it does) string outputFilename = GetOutputFileName(target, settings); string absOutputPath = System.IO.Path.Combine(settings.AbsOutputFolder, outputFilename); if (!DeleteOutputFile(absOutputPath, ref res)) { return(res); } // Deploy app. string fullPackageName; var deployResult = DeployAppX(target, settings, out fullPackageName); res.MergeIn(deployResult); if (!deployResult.Success) { return(res); } // Start AppX uint appXPid; var startResult = StartAppX(fullPackageName, GetDefaultTestArgs(outputFilename, settings), out appXPid); res.MergeIn(startResult); if (!startResult.Success) { return(res); } Process appXProcess; try { appXProcess = Process.GetProcessById((int)appXPid); } catch (Exception e) { res.Error("Failed to get process handle to test app: {0}", e); return(res); } // Start fileserver. string absFilerserveFilename = GetFileserverPath(settings); if (!File.Exists(absFilerserveFilename)) { res.Error("No fileserver found. File '{0}' does not exist.", absFilerserveFilename); } else { string absBinDir = Path.Combine(settings.AbsBinPath, settings.Configuration); string absTestDataPath = Path.Combine(settings.AbsCodePath, relativeTestDataPath); // 20s timeout for connect, 2s timeout for closing after connection loss. string args = string.Format("-specialdirs project \"{0}\" eztest \"{1}\" -fs_start -fs_wait_timeout 20 -fs_close_timeout 2", absTestDataPath, settings.AbsOutputFolder); res.ProcessRes = ezProcessHelper.RunExternalExe(absFilerserveFilename, args, absBinDir, res); res.Duration += res.ProcessRes.Duration; res.Success = (res.ProcessRes.ExitCode == 0); } // Top watch. // Check whether the AppX is dead by now. if (!appXProcess.HasExited) { res.Error("Fileserve is no longer running but the AppX is."); res.Success = false; appXProcess.Kill(); } // Can't read exit code: "Process was not started by this object, so requested information cannot be determined" /*else * { * if (appXProcess.ExitCode != 0) * { * res.Error("Test AppX exited with {0}", appXProcess.ExitCode); * res.Success = false; * } * }*/ appXProcess.Dispose(); appXProcess = null; // Read test output. if (File.Exists(absOutputPath)) { res.TestResultJSON = File.ReadAllText(absOutputPath, Encoding.UTF8); //TODO: use test json output as stdout substitute until pipes are implemented. res.ProcessRes.StdOut = res.TestResultJSON; try { // Parse test output to figure out what the result is as we can't use the exit code. var values = Newtonsoft.Json.JsonConvert.DeserializeObject <System.Collections.Generic.Dictionary <string, dynamic> >(res.TestResultJSON); var errors = values["errors"] as Newtonsoft.Json.Linq.JArray; res.Success = errors.Count == 0; } catch (Exception e) { res.Success = false; res.Error("Failed to parse test output: '{0}'", e.ToString()); } } else { res.Error("No output file present!"); res.Success = false; } if (!res.Success && !res.Experimental) { res.Error("Testing '{0}' failed!", res.Name); } return(res); }
static protected string GetDefaultTestArgs(string outputFilename, BuildMachineSettings settings) { return(string.Format("-json \"{0}\" -rev {1} -nogui -all", outputFilename, settings.Revision)); }
private void HandleRequest(object state) { HttpListenerContext context = (HttpListenerContext)state; try { HttpListenerRequest request = context.Request; // Get message text string sMessageText; using (var reader = new StreamReader(request.InputStream, UTF8Encoding.UTF8)) { sMessageText = reader.ReadToEnd(); } string sResponseMessage = null; // If no query was given, show help page if (request.QueryString.AllKeys.Count() == 0) { sResponseMessage = ShowHelpPage(); } else { // Retrieve type of message. ezBuildRequestMessageType eType = ezBuildRequestMessageType.INVALID_REQUEST; try { if (request.QueryString.AllKeys.Contains("type")) { eType = (ezBuildRequestMessageType)Convert.ToInt32(request.QueryString["type"]); } } catch (FormatException) { eType = ezBuildRequestMessageType.INVALID_REQUEST; Console.WriteLine("'type' of request invalid or not present!"); context.Response.StatusCode = 400; // Bad Request context.Response.OutputStream.Close(); return; } // Handle message switch (eType) { case ezBuildRequestMessageType.POSTConfiguration: { BuildMachineSettings settings = Newtonsoft.Json.JsonConvert.DeserializeObject <BuildMachineSettings>(sMessageText); sResponseMessage = HandlePOSTConfiguration(settings); } break; case ezBuildRequestMessageType.GETPing: { string sID = request.QueryString["ID"]; sResponseMessage = HandleGETPing(sID); } break; case ezBuildRequestMessageType.GETWork: { string sID = request.QueryString["ID"]; sResponseMessage = HandleGETWork(sID); } break; case ezBuildRequestMessageType.POSTBuildResult: { string sID = request.QueryString["ID"]; string sFilename = request.QueryString["File"]; sResponseMessage = POSTBuildResult(sID, sFilename, sMessageText); } break; case ezBuildRequestMessageType.GETStatus: { sResponseMessage = HandleGetStatus(); } break; case ezBuildRequestMessageType.GETCheckHEADRevision: { _iLastSVNCheckTimestamp = 0; sResponseMessage = "Checking SVN Request received."; } break; case ezBuildRequestMessageType.GETPostToAddress: { string sAddress = request.QueryString["TO"]; int iStartRevision = 0; if (request.QueryString.AllKeys.Contains("StartRevision")) { iStartRevision = Convert.ToInt32(request.QueryString["StartRevision"]); } sResponseMessage = HandleGetPostToAddress(sAddress, iStartRevision); } break; case ezBuildRequestMessageType.GETPause: { sResponseMessage = HandleGetPause(true); } break; case ezBuildRequestMessageType.GETResume: { sResponseMessage = HandleGetPause(false); } break; case ezBuildRequestMessageType.GETEnableHibernateOnIdle: { sResponseMessage = HandleGetHibernate(true); } break; case ezBuildRequestMessageType.GETDisableHibernateOnIdle: { sResponseMessage = HandleGetHibernate(false); } break; case ezBuildRequestMessageType.GETCleanBuild: { string sID = request.QueryString["ID"]; sResponseMessage = HandleGetCleanBuild(sID); } break; default: Console.WriteLine("HandleRequest: invalid message type: '{0}'!", eType); break; } } // Send response if (sResponseMessage == null) { context.Response.StatusCode = 400; // Bad Request context.Response.OutputStream.Close(); } else { context.Response.StatusCode = 200; // OK context.Response.SendChunked = true; var bytes = Encoding.UTF8.GetBytes(sResponseMessage); context.Response.OutputStream.Write(bytes, 0, bytes.Length); context.Response.OutputStream.Close(); } } catch (Exception ex) { Console.WriteLine("HandleRequest Failed: {0}", ex.Message); context.Response.StatusCode = 400; // Bad Request context.Response.OutputStream.Close(); } }
public bool Init(BuildMachineSettings settings) { _Settings = settings; return(true); }
public abstract ezTest.TestTargetResult BuildTarget(ezCMake.TestTarget target, BuildMachineSettings settings);
public BuildProcessResult() { Settings = new BuildMachineSettings(); }
public BuildMake(BuildMachineSettings settings) { _settings = settings; }
protected string GetOutputFileName(ezCMake.TestTarget target, BuildMachineSettings settings) { return(string.Format("{0}_{1}_{2}.json", settings.Configuration, settings.Revision, target.Name)); }