PageRenderTime 68ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/IronPython_Main/Runtime/Tests/SiteTest/SiteLog.cs

#
C# | 334 lines | 160 code | 31 blank | 143 comment | 13 complexity | fae0eed5a5dabfb239eb34208553edb9 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, CPL-1.0, CC-BY-SA-3.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1, Apache-2.0
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Apache License, Version 2.0, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Apache License, Version 2.0.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if !CLR2
  16. using System.Linq.Expressions;
  17. #else
  18. using Microsoft.Scripting.Ast;
  19. #endif
  20. using System;
  21. using System.Collections.Generic;
  22. using System.Diagnostics;
  23. using System.Text;
  24. using System.Threading;
  25. namespace SiteTest {
  26. /// <summary>
  27. /// SiteLog logs the various events of a dyn site scenario.
  28. ///
  29. /// This class is still being designed. It should be thread-safe.
  30. /// Need to better handle performance metrics
  31. /// </summary>
  32. public class SiteLog {
  33. public delegate void Func();
  34. List<Event> _log = new List<Event>();
  35. Stopwatch logtimer = new Stopwatch();
  36. Stopwatch scenarioTimer = new Stopwatch();
  37. string scenarioDescription = null;
  38. public SiteLog() {
  39. logtimer.Start();
  40. }
  41. /// <summary>
  42. /// Removes all recorded events from the log
  43. /// and resets the timer to 0. This invalidates
  44. /// all pre-existing event ids.
  45. /// </summary>
  46. public void Reset() {
  47. lock (_log) {
  48. _log.Clear();
  49. logtimer.Reset();
  50. logtimer.Start();
  51. }
  52. }
  53. /// <summary>
  54. /// Retrieves the log event matching
  55. /// the given event id.
  56. /// </summary>
  57. /// <param name="index"></param>
  58. /// <returns></returns>
  59. public Event this[int index] {
  60. get {
  61. return _log[index];
  62. }
  63. }
  64. /// <summary>
  65. /// Returns the number of entries currently in the log.
  66. /// </summary>
  67. public int Length {
  68. get {
  69. return _log.Count;
  70. }
  71. }
  72. /// <summary>
  73. /// Delegate to be used by sites to Target the Log call
  74. /// </summary>
  75. /// <param name="site"></param>
  76. /// <param name="eType"></param>
  77. /// <param name="text"></param>
  78. /// <returns></returns>
  79. public delegate int LogDel(System.Runtime.CompilerServices.CallSite site, EventType eType, string text);
  80. /// <summary>
  81. /// Adds a new event to the log with the given
  82. /// description using the current time and thread
  83. /// information.
  84. /// </summary>
  85. /// <param name="eType">The type of this event</param>
  86. /// <param name="text">Description of the new event</param>
  87. /// <returns></returns>
  88. public int Log(EventType eType, string text) {
  89. Event ev = new Event();
  90. ev.Time = logtimer.ElapsedMilliseconds;
  91. ev.EType = eType;
  92. ev.ThreadId = Thread.CurrentThread.ManagedThreadId;
  93. ev.Description = text;
  94. lock (_log) {
  95. _log.Add(ev);
  96. return _log.Count - 1 ;
  97. }
  98. }
  99. /// <summary>
  100. /// Adds a new event with the given type and
  101. /// an empty description.
  102. /// </summary>
  103. /// <param name="eType">The type of this event</param>
  104. /// <returns></returns>
  105. public int Log(EventType eType) {
  106. return Log(eType, null);
  107. }
  108. /// <summary>
  109. /// Logs a ScenarioBegin event, invokes f,
  110. /// logs a ScenarioEnd event and returns
  111. /// the elapsed time in milliseconds.
  112. /// </summary>
  113. /// <param name="text">Description of the event</param>
  114. /// <param name="f"></param>
  115. /// <returns></returns>
  116. public long TimeScenario(string text, Func f) {
  117. StartTimer(text);
  118. f();
  119. return StopTimer();
  120. }
  121. /// <summary>
  122. /// Logs a ScenarioBegin event, invokes f,
  123. /// logs a ScenarioEnd event and returns
  124. /// the elapsed time in milliseconds.
  125. /// </summary>
  126. /// <param name="f"></param>
  127. /// <returns></returns>
  128. public long TimeScenario(Func f) {
  129. return TimeScenario(null, f);
  130. }
  131. /// <summary>
  132. /// Logs a ScenarioBegin event and starts
  133. /// a separate stopwatch timer. The given
  134. /// text is used as the event's long description.
  135. /// </summary>
  136. /// <param name="text"></param>
  137. public void StartTimer(string text) {
  138. if(scenarioTimer.IsRunning)
  139. throw new ApplicationException("The scenario timer is already running");
  140. scenarioDescription = text;
  141. scenarioTimer.Reset();
  142. Log(EventType.ScenarioBegin, text);
  143. scenarioTimer.Start();
  144. }
  145. /// <summary>
  146. /// Logs a ScenarioBegin event and starts
  147. /// a separate stopwatch timer.
  148. /// </summary>
  149. public void StartTimer() {
  150. StartTimer(null);
  151. }
  152. /// <summary>
  153. /// Stops a running scenario stopwatch timer
  154. /// logs an event and returns the number of
  155. /// milliseconds elapsed since the timer was
  156. /// started.
  157. /// </summary>
  158. /// <returns>Elapsed time in milliseconds</returns>
  159. public long StopTimer() {
  160. if (!scenarioTimer.IsRunning)
  161. throw new ApplicationException("The scenario timer is not running");
  162. Log(EventType.ScenarioEnd, scenarioDescription);
  163. scenarioTimer.Stop();
  164. scenarioDescription = null;
  165. return scenarioTimer.ElapsedMilliseconds;
  166. }
  167. /// <summary>
  168. /// Returns a pretty-printable view of the log contents
  169. ///
  170. /// Don't want to override ToString because it impacts how
  171. /// -X:ShowRules works.
  172. /// </summary>
  173. /// <returns></returns>
  174. public string ToPrintableString() {
  175. lock (_log) {
  176. return ToPrintableString(_log.ToArray());
  177. }
  178. }
  179. /// <summary>
  180. /// Returns a pretty-printable view of a given list of events
  181. /// </summary>
  182. /// <param name="events"></param>
  183. /// <returns></returns>
  184. private string ToPrintableString(Event[] events) {
  185. StringBuilder repr = new StringBuilder();
  186. repr.AppendLine("TID\tTime\tEvent Type\t\tDescription");
  187. foreach (Event e in events) {
  188. repr.AppendLine(e.ToString());
  189. }
  190. return repr.ToString();
  191. }
  192. /// <summary>
  193. /// Generates an Expression tree that, when invoked,
  194. /// will append a new event to this log with the
  195. /// given description and the current (at invocation time)
  196. /// time and thread information.
  197. /// </summary>
  198. /// <param name="textExp">An Expression that returns a string that describes the new event</param>
  199. /// <param name="eType"></param>
  200. /// <returns></returns>
  201. public Expression GenLog(EventType eType, Expression textExp) {
  202. return GenLog(Expression.Constant(eType), textExp);
  203. }
  204. /// <summary>
  205. /// Generates an Expression tree that, when invoked,
  206. /// will append a new event to this log with the
  207. /// given description and the current (at invocation time)
  208. /// time and thread information.
  209. /// </summary>
  210. /// <param name="text">Description of the new event</param>
  211. /// <param name="eType"></param>
  212. /// <returns></returns>
  213. public Expression GenLog(EventType eType, string text) {
  214. return GenLog(eType, Expression.Constant(text, typeof(string)));
  215. }
  216. /// <summary>
  217. /// Generates an Expression tree that, when invoked,
  218. /// will append a new event to this log with the
  219. /// given description and the current (at invocation time)
  220. /// time and thread information.
  221. /// </summary>
  222. /// <param name="eTypeExp"></param>
  223. /// <param name="textExp"></param>
  224. /// <returns></returns>
  225. public Expression GenLog(Expression eTypeExp, Expression textExp) {
  226. return Expression.Call(Expression.Constant(this),
  227. typeof(SiteLog).GetMethod("Log", new Type[] { typeof(EventType), typeof(string) }),
  228. eTypeExp,
  229. textExp);
  230. }
  231. /// <summary>
  232. /// Compares the current log against the given
  233. /// sequence of events, ignoring all extended information
  234. /// (long description, threadid, timings).
  235. /// </summary>
  236. /// <param name="args"></param>
  237. /// <returns></returns>
  238. public bool MatchesEventSequence(params Event[] args) {
  239. bool result = true;
  240. lock (_log) {
  241. if (args.Length != _log.Count)
  242. result = false;
  243. else {
  244. for (int i = 0; i < _log.Count; i++) {
  245. if (args[i].EType != _log[i].EType) {
  246. result = false;
  247. break;
  248. }
  249. //If the baseline sequence didn't give an event description then don't compare
  250. if (args[i].Description != null) {
  251. if (args[i].Description != _log[i].Description) {
  252. result = false;
  253. break;
  254. }
  255. }
  256. }
  257. }
  258. if (!result) {
  259. Console.WriteLine("Expected:\n{0}", ToPrintableString(args));
  260. Console.WriteLine("Actual:\n{0}", ToPrintableString());
  261. }
  262. return result;
  263. }
  264. }
  265. public Event CreateEvent(EventType eType) {
  266. return CreateEvent(eType, null);
  267. }
  268. public Event CreateEvent(EventType eType, string descr) {
  269. Event e = new Event();
  270. e.EType = eType;
  271. e.Description = descr;
  272. return e;
  273. }
  274. /// <summary>
  275. /// Represents a single log event
  276. /// </summary>
  277. public struct Event {
  278. public int ThreadId;
  279. public long Time;
  280. public string Description;
  281. public EventType EType;
  282. public override string ToString() {
  283. return String.Format("{0}\t{1}\t{2}\t\t{3}", ThreadId, Time, EType, Description);
  284. }
  285. }
  286. /// <summary>
  287. /// Enumeration of the different types of dyn site
  288. /// events we care to track. This makes it easier
  289. /// to compare against an expected baseline.
  290. /// </summary>
  291. public enum EventType {
  292. MakeRule,
  293. ValidatorInvocation,
  294. TestInvocation,
  295. TargetInvocation,
  296. CachePrune_L2,
  297. CacheOverflow_L1,
  298. ScenarioBegin,
  299. ScenarioEnd,
  300. //@TODO - Add any others...
  301. }
  302. }
  303. }