public void RenameSessionLogFile() { Log.Flush(); var currentName = SessionLogs.GetSessionLogFilePath(); SessionLogs.Rename("Log1.txt"); SessionLogs.Rename("LogTest/Log2.txt"); string inlog = "This is written to log2"; log.Debug(inlog); Log.Flush(); SessionLogs.Flush(); var file = File.Open("LogTest/Log2.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using (var reader = new StreamReader(file)) { var part = reader.ReadToEnd(); StringAssert.Contains(inlog, part); } Assert.AreEqual(Path.GetFullPath(SessionLogs.GetSessionLogFilePath()), Path.GetFullPath("LogTest/Log2.txt")); SessionLogs.Rename(currentName); Assert.AreEqual(currentName, SessionLogs.GetSessionLogFilePath()); Assert.IsFalse(File.Exists("Log1.txt")); Assert.IsFalse(File.Exists("LogTest/Log2.txt")); Assert.IsTrue(Directory.Exists("LogTest")); }
// This example loads and runs a predefined test plan using the TAP API, the same interface the TAP GUI uses. // Use this to create custom GUIs or Operator interfaces. If no GUI is needed, the CLI may be a better alternative. // To run this example you must specify a path to a .TapPlan file. private static void Main(string[] args) { Console.WriteLine("\nThis example shows using the TAP API to control loading and running a TestPlan."); try { // If you have plugins in directories different from the location of your TAP_PATH, then add those directories here. // PluginManager.DirectoriesToSearch.Add(@"C:\SomeOtherDirectory"); // Start finding plugins. PluginManager.SearchAsync(); // Point to log file to be used. SessionLogs.Initialize("console_log.txt"); // Determine path to .TapPlan file. string absoluteTestPlanPath; if (args.Length == 1 && File.Exists(args[0])) { absoluteTestPlanPath = args[0]; } else { Console.WriteLine("Please specify an absolute path to a .TapPlan file."); return; } // ResultsListeners are configured by settings files, using the TAP GUI. // If settings files do not exist, then a default set of settings files, // including a default "Text Log" listener will be used. // Alternately, RestultListeners can be configured via TAP API. See the BuildTestPlan.Api example. // Load the Test Plan. TestPlan myTestPlan = TestPlan.Load(absoluteTestPlanPath); // Execute the Test Plan. TestPlanRun myTestPlanRun = myTestPlan.Execute(); Console.WriteLine("Loaded and ran \n{0}", absoluteTestPlanPath); // Test Plan properties are accessible. Console.WriteLine("TestPlan verdict={0}", myTestPlanRun.Verdict); // After the Test Plan has been run Macros, if used, can be expanded. SessionLogs.Rename(EngineSettings.Current.SessionLogPath.Expand(date: DateTime.Now)); } catch (Exception ex) { Console.WriteLine("Exception: {0}", ex.Message); } finally { Console.WriteLine("Press any key to continue."); Console.ReadLine(); } }
static void Main() { // If you have plugins in directories different from the location of your TAP_PATH, then add those directories here. // PluginManager.DirectoriesToSearch.Add(@"C:\SomeOtherDirectory"); // Start finding plugins. PluginManager.SearchAsync(); // Point to log file to be used. SessionLogs.Initialize("console_log.txt"); // Create a new Test Plan. TestPlan myTestPlan = new TestPlan(); // All Test Plan steps are added as child steps. myTestPlan.ChildTestSteps.Add(new DelayStep { DelaySecs = .1, Name = "Delay1" }); // Sequences can be created and added to TestPlan. SequenceStep mySequenceStep = new SequenceStep(); mySequenceStep.ChildTestSteps.Add(new DelayStep { DelaySecs = .2, Name = "Delay2" }); LogStep logStep = new LogStep { Name = "SomeName", LogMessage = "Hello from myTestPlan at " + DateTime.Now.ToLongTimeString(), Severity = LogSeverity.Info }; mySequenceStep.ChildTestSteps.Add(logStep); // Sequences are added to the Test Plan like any other step. myTestPlan.ChildTestSteps.Add(mySequenceStep); // The Test Plan can be saved for later reuse. string myFilePath = Path.Combine(AssemblyDirectory, myTestPlan.Name + ".TapPlan"); myTestPlan.Save(myFilePath); // Add any ResultListeners that should be used. // If not specified, a list of ResultListeners with a single LogResultListener will be created. // Alternatively, the ResultListeners could be defined in settings files. List <ResultListener> resultListeners = new List <ResultListener>(); resultListeners.Add(new LogResultListener()); //resultListeners.Add(new Keysight.OpenTap.Plugins.Csv.CsvResultListener()); // Execute the TestPlan. This is the equivalent of the Run button in the TAP GUI. myTestPlan.Execute(resultListeners); // After the TestPlan has been run Macros, if used, can be expanded. SessionLogs.Rename(EngineSettings.Current.SessionLogPath.Expand(date: DateTime.Now)); Console.WriteLine("This example builds a TestPlan programmatically."); Console.WriteLine("Press any key to exit."); Console.ReadLine(); }
public static int Execute(params string[] args) { // Trigger plugin manager before anything else. if (ExecutorClient.IsRunningIsolated) { // TODO: This is not needed right now, but might be again when we fix the TODO in tap.exe //PluginManager.DirectoriesToSearch.Clear(); //PluginManager.DirectoriesToSearch.Add(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)); using (var tpmClient = new ExecutorClient()) { tpmClient.MessageServer("delete " + Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)); } } // Set TapMutex to ensure any installers know about running OpenTAP processes. ReflectionHelper.SetTapMutex(); try { // Turn off the default system behavior when CTRL+C is pressed. // When Console.TreatControlCAsInput is false, CTRL+C is treated as an interrupt instead of as input. Console.TreatControlCAsInput = false; } catch { } try { var execThread = TapThread.Current; Console.CancelKeyPress += (s, e) => { e.Cancel = true; execThread.Abort(); }; } catch { } CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; // Find the called action if (!TypeData.GetDerivedTypes <ICliAction>().Any()) { Console.WriteLine("No commands found. Please try reinstalling OpenTAP."); return(1); } try { // setup logging to be relative to the executing assembly. // at this point SessionLogs.Initialize has already been called (PluginManager.Load). // so the log is already being saved at a different location. var logpath = EngineSettings.Current.SessionLogPath.Expand(date: Process.GetCurrentProcess().StartTime); bool isPathRooted = Path.IsPathRooted(logpath); if (isPathRooted == false) { var dir = Path.GetDirectoryName(typeof(SessionLogs).Assembly.Location); if (ExecutorClient.IsRunningIsolated) { // redirect the isolated log path to the non-isolated path. dir = ExecutorClient.ExeDir; } logpath = Path.Combine(dir, logpath); } SessionLogs.Rename(logpath); } catch (Exception e) { log.Error("Path defined in Engine settings contains invalid characters: {0}", EngineSettings.Current.SessionLogPath); log.Debug(e); } ITypeData selectedCommand = null; // Find selected command var actionTree = new CliActionTree(); var selectedcmd = actionTree.GetSubCommand(args); if (selectedcmd?.Type != null && selectedcmd?.SubCommands.Any() != true) { selectedCommand = selectedcmd.Type; } void print_command(CliActionTree cmd, int level, int descriptionStart) { if (cmd.IsBrowsable) { int relativePadding = descriptionStart - (level * LevelPadding); // Calculate amount of characters to pad right before description start to ensure description alignments. Console.Write($"{"".PadRight(level * LevelPadding)}{cmd.Name.PadRight(relativePadding)}"); if (cmd.Type?.IsBrowsable() ?? false) { Console.WriteLine($"{cmd.Type.GetDisplayAttribute().Description}"); } else { Console.WriteLine(); } if (cmd.IsGroup) { foreach (var subCmd in cmd.SubCommands) { print_command(subCmd, level + 1, descriptionStart); } } } } // Print default info if (selectedCommand == null) { Console.WriteLine("OpenTAP Command Line Interface ({0})", Assembly.GetExecutingAssembly().GetSemanticVersion().ToString(4)); Console.WriteLine("Usage: tap <command> [<subcommand(s)>] [<args>]\n"); if (selectedcmd == null) { Console.WriteLine("Valid commands are:"); foreach (var cmd in actionTree.SubCommands) { print_command(cmd, 0, actionTree.GetMaxCommandTreeLength(LevelPadding) + LevelPadding); } } else { Console.Write("Valid subcommands of "); print_command(selectedcmd, 0, actionTree.GetMaxCommandTreeLength(LevelPadding) + LevelPadding); } Console.WriteLine($"\nRun \"{(OperatingSystem.Current == OperatingSystem.Windows ? "tap.exe" : "tap")} " + "<command> [<subcommand>] -h\" to get additional help for a specific command.\n"); if (args.Length == 0 || args.Any(s => s.ToLower() == "--help" || s.ToLower() == "-h")) { return(0); } else { return(-1); } } if (selectedCommand != TypeData.FromType(typeof(RunCliAction)) && UserInput.Interface == null) // RunCliAction has --non-interactive flag and custom platform interaction handling. { CliUserInputInterface.Load(); } ICliAction packageAction = null; try{ packageAction = (ICliAction)selectedCommand.CreateInstance(); }catch (TargetInvocationException e1) when(e1.InnerException is System.ComponentModel.LicenseException e) { Console.Error.WriteLine("Unable to load CLI Action '{0}'", selectedCommand.GetDisplayAttribute().GetFullName()); Console.Error.WriteLine(e.Message); return(-4); } if (packageAction == null) { Console.WriteLine("Error instantiating command {0}", selectedCommand.Name); return(-3); } try { int skip = selectedCommand.GetDisplayAttribute().Group.Length + 1; // If the selected command has a group, it takes two arguments to use the command. E.g. "package create". If not, it only takes 1 argument, E.g. "restapi". return(packageAction.Execute(args.Skip(skip).ToArray())); } catch (ExitCodeException ec) { log.Error(ec.Message); return(ec.ExitCode); } catch (ArgumentException ae) { // ArgumentException usually contains several lines. // Only print the first line as an error message. // Example message: // "Directory is not a git repository. // Parameter name: repositoryDir" var lines = ae.Message.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); log.Error(lines.First()); for (int i = 1; i < lines.Length; i++) { log.Debug(lines[i]); } return(-1); } catch (OperationCanceledException ex) { log.Error(ex.Message); return(1); } catch (Exception ex) { log.Error(ex.Message); log.Debug(ex); return(-1); } finally { Log.Flush(); } }