(file) Return to Globals.h CVS log (file) (dir) Up to [OMI] / omi / nits / base

  1 krisbash 1.1 //*****************************************************************************
  2              //  Copyright (C) 2008 Microsoft Corporation
  3              //  All rights reserved.
  4              //*****************************************************************************
  5              
  6              #ifndef __GLOBALS_H__
  7              #define __GLOBALS_H__
  8              
  9              #ifndef TEST_BUILD
 10              #define TEST_BUILD
 11              #endif
 12              
 13              #ifdef _MSC_VER
 14                  #include <windows.h>
 15              #else
 16                  #include <signal.h>
 17              #endif
 18              #include <vector>
 19              #include <sstream>
 20              
 21              #include <pal/palcommon.h>
 22 krisbash 1.1 
 23              #ifndef NITS_EXPORT
 24              # define NITS_EXPORT PAL_EXTERN_C PAL_EXPORT_API
 25              #endif
 26              
 27              #include "nits.h"
 28              #include "Frame.h"
 29              
 30              #include <pal/atomic.h>
 31              #include <pal/sleep.h>
 32              #include <pal/sem.h>
 33              #include <pal/cpu.h>
 34              #include <pal/shmem.h>
 35              #include <pal/shlib.h>
 36              #include <pal/thread.h>
 37              #include <pal/format.h>
 38              
 39              #define NITS_TRACING_LOCATION L"Microsoft\\NITS"
 40              
 41              #define WPP_USE_NTDLL_FUNCTIONS
 42              #define WPP_CONTROL_GUIDS \
 43 krisbash 1.1     WPP_DEFINE_CONTROL_GUID(NITS,(95bef1fc,d949,42d0,951a,ff1af27a6549), \
 44                      WPP_DEFINE_BIT(TestLifetime)     \
 45                      )
 46              
 47              PAL_INLINE void Atomic_Lock(
 48                  _Inout_ volatile ptrdiff_t* dest)
 49              {
 50                  while (Atomic_Swap(dest, 1) == 1)
 51                      while (*dest)
 52                          ;
 53              }
 54              
 55              PAL_INLINE void Atomic_Unlock(
 56                  _Inout_ volatile ptrdiff_t* dest)
 57              {
 58                  Atomic_Swap(dest, 0);
 59              }
 60              
 61              
 62              enum NitsTraceLevel
 63              {
 64 krisbash 1.1     NitsTraceFailedTests = 1,   //Shows nothing except failed test cases.
 65                  NitsTraceWarnedTests = 2,   //Shows test cases with warnings.
 66                  NitsTraceAllTests    = 3,   //Shows all test cases.
 67                  NitsTraceAsserts     = 3,   //Shows individual asserts.
 68                  NitsTraceWarnings    = 4,   //Shows individual asserts/warnings.
 69                  NitsTraceIterations  = 5,   //Shows fault injection iterations.
 70                  NitsTraceVerbose     = 6    //Shows product and other traces.
 71              };
 72              
 73              enum {
 74                  CallSite_NONE = -1,   //Anonymous call site.
 75                  CallSite_ALL = -2     //Automatic fault loops.
 76              };
 77              
 78              struct Configuration
 79              {
 80                  NitsTraceLevel traces;
 81                  NitsTestMode mode;
 82                  //NitsIsolationMode isolation;
 83                  //NitsResourceScope scope;
 84                  bool breakAssert;
 85 krisbash 1.1     bool breakFault;
 86                  bool skipFlakyTests;
 87              };
 88              
 89              struct Statistics
 90              {
 91                  unsigned faultIterations;
 92                  unsigned shouldFaults;
 93                  unsigned currentTestProcess;
 94                  unsigned frameLookups;
 95                  unsigned frameInsertions;
 96                  unsigned frameHashHits;
 97                  unsigned frameHits[16];
 98                  unsigned stackLookups;
 99                  unsigned stackTicks;
100              };
101              
102              namespace TestSystem
103              {
104              
105              using namespace std;
106 krisbash 1.1 
107              bool StartsWith(_In_z_ const PAL_Char * str, _In_z_ const PAL_Char * prefix);
108              bool Equals(_In_z_ const PAL_Char * str, _In_z_ const PAL_Char * target);
109              bool EqualsCI(_In_z_ const PAL_Char * str, _In_z_ const PAL_Char * target);
110              
111              PAL_Char *Copy(_In_opt_z_ const PAL_Char * str);
112              
113              class Exception
114              {
115              public:
116                  Exception(_In_ const PAL_Char * message = PAL_T("")) : m_message(message) {}
117              
118                  const PAL_Char * GetMessage() const {return m_message;}
119              private:
120                  const PAL_Char * m_message;
121              };
122              
123              inline void FatalError() {throw Exception();}
124              
125              //Used for defining wostringstream objects in nits.h.
126              //Avoids public header file dependency on STL.
127 krisbash 1.1 class Buffer
128              {
129              public:
130                  Buffer(wostringstream &data) : m_data(data) {}
131              
132                  operator wostringstream &() {return m_data;}
133              
134                  wostringstream &m_data;
135              
136                  Buffer(const Buffer&);
137                  Buffer& operator=( const Buffer& );
138              };
139              
140              //Used for defining vector objects in nits.h.
141              //Avoids public header file dependency on STL.
142              class ChildList
143              {
144              public:
145                  operator vector<Switch *> const &() const {return m_list;}
146                  operator vector<Switch *> &() {return m_list;}
147              
148 krisbash 1.1     vector<Switch *> m_list;
149              };
150              
151              enum SharedStatus
152              {
153                  Unloaded = 0,
154                  Loading,
155                  Loaded
156              };
157              
158              struct Mapping
159              {
160                  PAL_Char *m_name;
161              
162                  Shmem *m_mapping;
163                  ptrdiff_t volatile *m_status; //Initialization spinlock.
164              
165                  void *m_data;            //Shared data section.
166                  long m_bytes;            //Length of data section.
167              
168                  void *m_copy;            //Initial data values.
169 krisbash 1.1 
170                  DWORD Initialize(_In_reads_bytes_(bytes) void const *context, long bytes);
171              
172                  void Reset();
173              };
174              
175              class Fault
176              {
177              public:
178                  enum {
179                      FileSize = 256
180                  };
181              
182                  Fault();
183              
184                  void Reset(int site, int iteration, bool breakOnFault);
185                  bool ShouldFault(CallSite const &site);
186                  bool DidFault() const {return m_faulted;}
187                  void Toggle(bool enabled); 
188                  CallSite GetFaultedSite() const;
189              
190 krisbash 1.1     int m_site;
191                  int m_iteration;
192                  volatile ptrdiff_t m_attempt;
193                  volatile ptrdiff_t m_lock;
194              
195                  bool m_break;
196                  bool volatile m_faulted;
197                  bool volatile m_filtered;
198                  int m_hit;
199                  int m_line;
200                  char m_file[FileSize];
201              
202                  //Used for filtering causal anomalies.
203                  ThreadID m_mainThread;
204                  ptrdiff_t m_minimumAttemptDifferentThread;
205                  ptrdiff_t m_firstAttemptDifferentThread;
206                  ptrdiff_t m_faultedAttempt;
207              };
208              
209              struct InjectorTarget
210              {
211 krisbash 1.1     void *signalSemaphore;
212                  void *waitSemaphore;
213                  void *lockSemaphore;
214                  ptrdiff_t process;
215              };
216              
217              static const int InjectorListSize = 1024;
218              static const int SharedMemoryVersion = 3; //Increment after each change to Globals.
219              
220              enum PipeOutputType
221              {
222                  NoMessage,
223                  InfoMessage,
224                  WttLogTestStart,
225                  WttLogTestEnd
226              };
227              
228              //Internal self-relative data structure.
229              //Propagates test commands and state across processes.
230              class Globals
231              {
232 krisbash 1.1 public:
233                  int m_version; //Used to match against SharedMemoryVersion.
234                  int m_unload;  //Triggers the injector to self-unload everywhere.
235              
236                  enum {
237                      PipeSize = 1024,
238                      StringSize = 256
239                  };
240              
241                  Globals();
242                  ~Globals();
243              
244                  bool IsUnittestRunning();
245                  bool StartRun(bool force = false);
246                  void StopRun();
247                  void CheckRun();                    //Makes sure the test process is alive.
248              
249                  void Reset();                       //Erases test status.
250                  void AttachDebugger();
251                  void CheckDebugger();
252                  void SetFault(int site,
253 krisbash 1.1                   int attempt,
254                                HRESULT error,
255                                _In_z_ const PAL_Char * event);
256                  Fault &GetAutoFault() {return m_simAuto;}
257              
258                  NitsResult TestExpression(bool test, NitsFaultMode mode);
259                  NitsResult ShouldFault(CallSite const &site, NitsFaultMode mode);
260                  NitsResult DidFault();
261              
262                  void StopReportingIgnoredErrors()
263                  {
264                      //This function has no effect if the fault already happened.
265                      //The purpose is to indicate that *future* faults are purposefully ignored.
266                      if (!DidFault())
267                          m_stopReportingIgnoredErrors = true;
268                  }
269                  bool ShouldReportIgnoredErrors() {return !m_stopReportingIgnoredErrors;}
270                  void ResetIgnoredErrorReporting() {m_stopReportingIgnoredErrors = false;}
271              
272                  HRESULT GetFaultError() const {return m_faultError;}
273                  Result GetResult() const {return m_result;}
274 krisbash 1.1     Configuration const &GetConfiguration() const {return m_config;}
275                  void SetConfiguration(Configuration const &config) {m_config = config;}
276                  Statistics &GetStats() {return m_stats;}
277                  int *GetStatistics() {return m_statistics;}
278              
279                  void SetResult(Result result) {m_result = result;}
280                  void SetDebugger(_In_z_ const PAL_Char * debugger);
281              
282                  void **GetStackTrace() {return m_stackTrace;}
283              
284                  void SetRunTime(double seconds) {m_runTimeInSeconds = seconds;}
285                  double GetRunTime() {return m_runTimeInSeconds;}
286              
287              #if defined(CONFIG_HAVE_BACKTRACE)
288                  FrameCache m_frames;
289              #endif
290              
291              public:
292                  void PostPipe(_In_z_ const PAL_Char * text, PipeOutputType outputType = InfoMessage);    //Adds text to out-of-proc buffer.
293                  void DumpPipe();                    //Dumps pipe to stderr.
294                  bool IsPipeEmpty();
295 krisbash 1.1     void LockPipe();
296                  void UnlockPipe();
297                  void EmptyPipe();
298                  PAL_Char *GetPipe() { return m_pipe; }
299                  PipeOutputType GetPipeOutputType() { return m_pipeOutputType; }
300                  ptrdiff_t volatile m_runLock;    //PID of test run in progress.    
301              private:
302                  ptrdiff_t volatile m_attachLock; //PID of process being attached to debugger.
303                  ptrdiff_t volatile m_pipeLock;   //Pipe synchronization.
304                  long m_pipeChars;           //Buffer size used.    
305              
306                  bool m_stopReportingIgnoredErrors;
307              
308                  Configuration m_config;
309                  Statistics m_stats;
310              
311                  Result m_result;            //Current test result.
312              
313              public:
314                  Fault m_simAuto;
315                  Fault m_simManual;
316 krisbash 1.1 
317                  PAL_Char m_binaryFilter[1024];
318                  PAL_Char m_binaryTarget[1024];
319                  InjectorTarget m_injectors[InjectorListSize];
320              private:
321              
322                  int m_statistics[ResultCount];
323              
324                  HRESULT m_faultError;
325                  PAL_Char m_faultEvent[Event::MaxName];
326                  PAL_Char m_pipe[PipeSize];
327                  PAL_Char m_debugger[1024];   //Used for automatic debugger attaching.
328              
329                  void *m_stackTrace[50];
330                  double m_runTimeInSeconds;
331                  PipeOutputType m_pipeOutputType;
332              };
333              
334              class System
335              {
336              public:
337 krisbash 1.1     static System &GetInstance() {return s_system;}
338              
339                  System();
340                  ~System();
341              
342                  NamedSem *GetPipeEvent() const {return (NamedSem *)&m_pipeEvent;}
343                  Globals const &GetGlobals() const;
344                  Globals &GetGlobals();
345                  Mapping &GetMapping(_In_z_ const PAL_Char * name);
346                  void ResetClientMappings();
347              private:
348                  NamedSem m_pipeEvent;
349                  Globals *m_globals;
350                  vector<Mapping> m_mappings;
351                  static System s_system;
352              };
353              
354              inline Globals &GetGlobals() {return System::GetInstance().GetGlobals();}
355              
356              }; //namespace TestSystem
357              
358 krisbash 1.1 /*
359              **==============================================================================
360              **
361              ** Conversion functions between Ansi/WideChar/PAL_Char strings
362              **
363              **==============================================================================
364              */
365              PWSTR ConvertStringToW(_In_opt_z_ const char *buf);
366              PSTR ConvertStringToA(_In_opt_z_ const wchar_t *buf);
367              PAL_Char *ConvertStringAToPalChar(_In_opt_z_ const char *buf);
368              PAL_Char *ConvertStringWToPalChar(_In_opt_z_ const wchar_t *buf);
369              char *ConvertPalCharToStringA(_In_opt_z_ const PAL_Char *buf);
370              
371              #ifdef _MSC_VER
372              #define MyDebugBreak DebugBreak()
373              #else
374              #define MyDebugBreak raise(SIGTRAP)
375              #endif
376              
377              #endif // ndef __GLOBALS_H__

ViewCVS 0.9.2