(file) Return to Switch.cpp.bkp CVS log (file) (dir) Up to [OMI] / omi / nits / base

   1 krisbash 1.1 //*****************************************************************************
   2              //  Copyright (C) 2007 Microsoft Corporation
   3              //  All rights reserved.
   4              //*****************************************************************************
   5              
   6              #include "Run.h"
   7              #include <iostream>
   8              #ifdef _MSC_VER
   9                  #include <Switch.tmh>
  10              #endif
  11              #include <pal/palcommon.h>
  12              #include <pal/strings.h>
  13              
  14              using namespace std;
  15              using namespace TestSystem;
  16              
  17              #define IsSetupFixture(fixtureType) ((fixtureType == SetupFixture) || (fixtureType == SplitFixture))
  18              
  19              NITS_EXPORT void NITS_CALL NitsSwitchCreate(
  20                  _Inout_ Switch *test,
  21                  _In_ const PAL_Char * name,
  22 krisbash 1.1     _In_ void (NITS_CALL *setup)(Switch &),
  23                  bool group)
  24              {
  25                  test->m_name = name;
  26                  test->m_setup = setup;
  27                  test->m_cleanup = NULL;
  28                  test->m_choice = group ? Switch::AllChildren : 0;
  29                  test->m_index = 0;
  30                  test->m_refs = 0;
  31                  test->m_children = new ChildList;
  32                  test->m_registration = NULL;
  33                  test->m_prevLayerContinuation = NULL;
  34                  test->m_sameLayerContinuation = NULL;
  35                  test->m_prevSwitchOnSelectedTestStack = NULL;
  36                  test->m_rootSwitch = NULL;
  37                  test->m_dryRunToFindChildren = 0;
  38                  test->m_someoneCalledOmit = 0;
  39                  test->m_filteredOutByUser = 0;
  40                  test->m_notRunInCurrentTestChoice = 0;
  41                  test->m_switchState = TestSystem::Switch::NotRunYet;
  42                  
  43 krisbash 1.1     if (test->m_children == NULL)
  44                  {
  45                      FatalError();
  46                  }
  47              }
  48              
  49              NITS_EXPORT void NITS_CALL NitsSwitchDelete(
  50                  _Inout_ Switch *test)
  51              {
  52                  struct RegistrationInfo *r = (struct RegistrationInfo *) (test->m_registration);
  53                  int count = 0;
  54                  delete test->m_children;
  55                  if(r)
  56                  {
  57                      if(r->arrayOfInitializers)
  58                      {
  59                          while(count < r->numberOfParents)
  60                          {
  61                              free(r->arrayOfInitializers[count]);
  62                              count++;
  63                          }
  64 krisbash 1.1             free(r->arrayOfInitializers);
  65                      }
  66              
  67                      if(r->parentArray)
  68                      {
  69                          free(r->parentArray);
  70                      }
  71                      
  72                      free(r);
  73                  }
  74              }
  75              
  76              NITS_EXPORT void NITS_CALL NitsSetTeardownSwitch(_Inout_ Switch *test, Switch *teardownSwitch, int isCleanup)
  77              {
  78                  if(test->m_registration)
  79                  {
  80                      struct RegistrationInfo *r = (struct RegistrationInfo *) (test->m_registration);
  81                      if(isCleanup)
  82                      {
  83                          r->cleanupSwitch = teardownSwitch;
  84                      }
  85 krisbash 1.1         else
  86                      {
  87                          r->crashSwitch = teardownSwitch;
  88                      }
  89                  }
  90              }
  91              
  92              NITS_EXPORT void ** NITS_CALL NitsGetInitArray(_Inout_ Switch *test)
  93              {
  94                  if(!test->IsNewInterfaceTest())
  95                      return NULL;
  96                  
  97                  struct RegistrationInfo *r = (struct RegistrationInfo *) (test->m_registration);
  98              
  99                  return r->arrayOfInitializers;
 100              }
 101              
 102              NITS_EXPORT int NITS_CALL NitsIsSplitFixture(_In_ Switch *test)
 103              {
 104                  if(!test->IsNewInterfaceTest())
 105                      return 0;
 106 krisbash 1.1     
 107                  struct RegistrationInfo *r = (struct RegistrationInfo *) (test->m_registration);    
 108              
 109                  return (r->fixtureType == SplitFixture);
 110              }
 111              
 112              PAL_Boolean Switch::IsBodyFixture()
 113              {
 114                  if(!IsNewInterfaceTest())
 115                      return PAL_FALSE;
 116              
 117                  struct RegistrationInfo *r = (struct RegistrationInfo *) (m_registration);
 118              
 119                  return ((r->fixtureType == BodyFixture) || (r->fixtureType == ModuleSetupFixture));
 120              }
 121              
 122              bool Switch::IsChildSelected(int index) const
 123              {
 124                  return IsGroup() || index == m_choice;
 125              }
 126              
 127 krisbash 1.1 //Registers and runs child switches from setup().
 128              //Caller must not change the child sequence when repeating its own variations.
 129              NITS_EXPORT void NITS_CALL NitsSwitchChild(
 130                  _Inout_ Switch *test,
 131                  _In_ Switch &child)
 132              {
 133                  vector<Switch *> &list = *test->m_children;
 134              
 135                  if (test->m_index == list.size())
 136                  {
 137                      //Register a new child.
 138                      list.push_back(&child);
 139                  }
 140                  else if (list[test->m_index] != &child)
 141                  {
 142                      //Caller previously registered children in a different order!
 143                      FatalError();
 144                  }
 145              
 146                  if (test->IsChildSelected(test->m_index++))
 147                  {
 148 krisbash 1.1         child.RunSetup();
 149                  }
 150              }
 151              
 152              NITS_EXPORT bool NITS_CALL NitsSwitchGetEnabled(
 153                  _Inout_ Switch const *test)
 154              {
 155                  PAL_UNUSED(test);
 156                  return Run::GetInstance().GetEnabled();
 157              }
 158              
 159              NITS_EXPORT void NITS_CALL NitsSwitchSetFaultMode(
 160                  _Inout_ Switch *test,
 161                  NitsFaultMode mode)
 162              {
 163                  PAL_UNUSED(test);
 164              
 165                  Run::GetInstance().SetFaultMode(mode);
 166              }
 167              
 168              NITS_EXPORT void NITS_CALL NitsSwitchSetEnabled(
 169 krisbash 1.1     _Inout_ Switch *test,
 170                  bool enabled)
 171              {
 172                  PAL_UNUSED(test);
 173              
 174                  Run::GetInstance().SetEnabled(enabled);
 175              }
 176              
 177              NITS_EXPORT void NITS_CALL NitsSwitchSetFlaky(
 178                  _Inout_ Switch *test,
 179                  bool flaky)
 180              {
 181                  PAL_UNUSED(test);
 182              
 183                  Run::GetInstance().SetFlaky(flaky);
 184              }
 185              
 186              NITS_EXPORT void NITS_CALL NitsSwitchFaultExclude(
 187                  _Inout_ Switch *test,
 188                  _In_reads_opt_(count) int sites[],
 189                  int count)
 190 krisbash 1.1 {
 191                  PAL_UNUSED(test);
 192              
 193                  Run::GetInstance().SetExclusions(sites, count);
 194              }
 195              
 196              NITS_EXPORT void NITS_CALL NitsSwitchFaultOff(
 197                  _Inout_ Switch *test)
 198              {
 199                  PAL_UNUSED(test);
 200              
 201                  GetGlobals().SetFault(CallSite_NONE, 0, S_OK, PAL_T(""));
 202              }
 203              
 204              NITS_EXPORT void NITS_CALL NitsSwitchFaultHresult(
 205                  _Inout_ Switch *test,
 206                  int site,
 207                  HRESULT error,
 208                  int attempt)
 209              {
 210                  PAL_UNUSED(test);
 211 krisbash 1.1 
 212                  GetGlobals().SetFault(site, attempt, error, PAL_T(""));
 213              }
 214              
 215              NITS_EXPORT void NITS_CALL NitsSwitchFaultError(
 216                  _Inout_ Switch *test,
 217                  int site,
 218                  DWORD error,
 219                  int attempt)
 220              {
 221                  PAL_UNUSED(test);
 222              
 223                  GetGlobals().SetFault(site, attempt, HRESULT_FROM_WIN32(error), PAL_T(""));
 224              }
 225              
 226              NITS_EXPORT void NITS_CALL NitsSwitchFaultWait(
 227                  _Inout_ Switch *test,
 228                  int site,
 229                  _In_ Event const &event,
 230                  int attempt)
 231              {
 232 krisbash 1.1     PAL_UNUSED(test);
 233              
 234                  GetGlobals().SetFault(site, attempt, S_OK, event);
 235              }
 236              
 237              NITS_EXPORT const PAL_Char *NITS_CALL NitsTestGetParam(_In_z_ const PAL_Char *paramName)
 238              {
 239                  return Run::GetInstance().GetParam(paramName);
 240              }
 241              
 242              void Switch::RunSetup()
 243              {
 244                  if (++m_refs > 1)
 245                  {
 246                      if (IsChoice())
 247                      {
 248                          //Sanity check: choices must NOT have multiple parents.
 249                          //This causes confusion when choosing children.
 250                          throw Exception();
 251                      }
 252              
 253 krisbash 1.1         return;
 254                  }
 255              
 256                  //The setup call registers and calls children through Child().
 257                  //Child call order is determined by setup.
 258                  m_setup(*this);
 259              }
 260              
 261              void Switch::RunCleanup()
 262              {
 263                  if (m_refs <= 0)
 264                  {
 265                      throw Exception();
 266                  }
 267              
 268                  if (--m_refs > 0)
 269                  {
 270                      return;
 271                  }
 272                  
 273                  //Shut down the parent first.
 274 krisbash 1.1     //Then shut down children that called setup, in reverse order.
 275                  if (m_cleanup)
 276                  {
 277                      m_cleanup(*this);
 278                  }
 279              
 280                  while (m_index > 0)
 281                  {
 282                      vector<Switch *> &list = *m_children;
 283                      Switch &child = *list[--m_index];
 284                      if (IsChildSelected(m_index))
 285                      {
 286                          child.RunCleanup();
 287                      }
 288                  }
 289              }
 290              
 291              Switch *Switch::GetFirstSelectedChild()
 292              {
 293                  vector<Switch *> &list = *m_children;
 294                  int index = 0;
 295 krisbash 1.1     int sizeOfChildrenList = (int)list.size();
 296                  
 297                  while (index < sizeOfChildrenList)
 298                  {
 299                      if (IsChildSelected(index))
 300                      {
 301                          return list[index];
 302                      }
 303                      index++;
 304                  }
 305              
 306                  return NULL;
 307              }
 308              
 309              void Switch::Reset()
 310              {
 311                  if (IsChoice())
 312                  {
 313                      m_choice = 0;
 314                  }
 315              
 316 krisbash 1.1     if (m_index != 0 || m_refs > 0)
 317                  {
 318                      throw Exception();
 319                  }
 320              
 321                  //TODO: Is this really necessary?
 322                  vector<Switch *> &list = *m_children;
 323                  for (DWORD i = 0; i < list.size(); i++)
 324                  {
 325                      list[i]->Reset();
 326                  }
 327              
 328                  m_prevLayerContinuation = NULL;
 329                  m_sameLayerContinuation = NULL;
 330                  m_prevSwitchOnSelectedTestStack = NULL;
 331                  m_rootSwitch = NULL;
 332                  m_switchState = TestSystem::Switch::NotRunYet;
 333              
 334                  list.clear(); //Allows a later test to declare different children.
 335              }
 336              
 337 krisbash 1.1 bool Switch::Next()
 338              {
 339                  vector<Switch *> &list = *m_children;
 340                  if (IsGroup())
 341                  {
 342                      //Lexicographic search.
 343                      //Start with the lowest-order "digit" and increment.
 344                      //If that is done, reset and move to the next-order "digit".
 345                      for (int i = (int)list.size() - 1; i >= 0; i--)
 346                      {
 347                          Switch &child = *list[i];
 348                          if (child.Next())
 349                          {
 350                              return true;
 351                          }
 352                          
 353                          child.Reset();
 354                      }
 355              
 356                      return false;
 357                  }
 358 krisbash 1.1     else
 359                  {
 360                      if (list.size() == 0)
 361                      {
 362                          //Choice nodes with no children run like a group node.
 363                          return false;
 364                      }
 365              
 366                      //Iterative search.
 367                      //Each child contains at least one position.
 368                      Switch &child = *list[m_choice];
 369                      if (child.Next())
 370                      {
 371                          return true;
 372                      }
 373              
 374                      child.Reset();
 375                      return ((unsigned long)(++m_choice)) < list.size();
 376                  }
 377              }
 378              
 379 krisbash 1.1 void Switch::PrintChoices(Buffer &data)
 380              {
 381                  wostringstream &buf = data;
 382                  vector<Switch *> &list = *m_children;
 383                  if (IsChoice())
 384                  {
 385                      if (list.size() > 0)
 386                      {
 387                          buf << L"/" << list[m_choice]->GetName();
 388                          list[m_choice]->PrintChoices(data);
 389                      }
 390                  }
 391                  else for (DWORD i = 0; i < list.size(); i++)
 392                  {
 393                      list[i]->PrintChoices(data);
 394                  }
 395              }
 396              
 397              bool Switch::SelectChoices(_Inout_z_ PAL_Char * &choices)
 398              {
 399                  vector<Switch *> &list = *m_children;
 400 krisbash 1.1 
 401                  //NOTE: Have to run setup at least once to discover children.
 402                  if (list.size() == 0)
 403                  {
 404                      RunSetup();
 405                      RunCleanup();
 406                  }
 407              
 408                  //Recursively traverse the choices and groups.
 409                  if (IsChoice())
 410                  {
 411                      PAL_Char *item = choices;
 412                      PAL_Char *slash = Tcschr(choices, PAL_T('/'));
 413                      if (slash)
 414                      {
 415                          //Advance to next choice.
 416                          *slash = PAL_T('\0');
 417                          choices = slash + 1;
 418                      }
 419                      else
 420                      {
 421 krisbash 1.1             //No more choices. Just advance to the end.
 422                          choices += Tcslen(choices);
 423                      }
 424              
 425                      for (DWORD i = 0; i < list.size(); i++)
 426                      {
 427                          if (Equals(list[i]->GetName(), item))
 428                          {
 429                              m_choice = i;
 430                              return list[i]->SelectChoices(choices);
 431                          }
 432                      }
 433              
 434                      //Choice was not found.
 435                      return false;
 436                  }
 437                  else
 438                  {
 439                      for (DWORD i = 0; i < list.size(); i++)
 440                      {
 441                          if (!list[i]->SelectChoices(choices))
 442 krisbash 1.1             {
 443                              return false;
 444                          }
 445                      }
 446              
 447                      return true;
 448                  }
 449              }
 450              
 451              NITS_EXPORT void NITS_CALL NitsTestCreate(
 452                  _Inout_ Test *test,
 453                  _In_ const PAL_Char * name,
 454                  _In_ void (NITS_CALL *setup)(Switch &),
 455                  _In_ void (NITS_CALL *body)(Switch &),
 456                  bool deleteMeAfterRun /* = false */)
 457              {
 458                  PAL_UNUSED(name);
 459                  PAL_UNUSED(setup);
 460                  PAL_UNUSED(body);
 461              
 462                  test->m_body = body;
 463 krisbash 1.1     test->m_deleteMeAfterRun = deleteMeAfterRun;
 464                  
 465                  if (!Run::IsValid())
 466                  {
 467                      return;
 468                  }
 469              
 470                  Module &module = Run::GetInstance().GetCurrentModule();
 471                  if (&module == NULL)
 472                  {
 473                      return;
 474                  }
 475              
 476                  test->m_module = module.GetName();
 477                  module.AddTest(test);
 478              
 479                  test->m_timeout = test->s_nextTimeout;
 480                  test->m_isolation = test->s_nextIsolation;
 481              
 482                  test->s_nextTimeout = 60;
 483                  test->s_nextIsolation = false;
 484 krisbash 1.1     test->m_startTicks = 0;
 485                  test->m_testRunState = TestSystem::Test::BodyYetToRun;
 486                  test->m_cleanupMode = TestSystem::Test::ImmediateCleanup;
 487              }
 488              
 489              void Test::PrintName(Buffer &data, bool choices)
 490              {
 491                  wostringstream &buf = data;    
 492                  buf << GetModule() 
 493              #ifdef _MSC_VER
 494                      << L"!" 
 495              #else
 496                      << L":" 
 497              #endif
 498                      << GetName();
 499                  if (choices)
 500                  {
 501                      PrintChoices(data);
 502                  }
 503              }
 504              
 505 krisbash 1.1 void Test::RunDeferredCleanup()
 506              {
 507                  RunCleanup();
 508                  struct RegistrationInfo *myRegistration = (struct RegistrationInfo *)(m_registration);
 509                  myRegistration->cleanupFunc(myRegistration->selfContext);
 510              }
 511              
 512              void Test::Execute(_In_opt_z_ const PAL_Char * choices)
 513              {
 514                  Reset();
 515                  Run &run = Run::GetInstance();
 516                  run.SetDefaultOptions();
 517                  
 518                  
 519                  if(!IsNewInterfaceTest() && (m_cleanupMode == DeferredCleanup))
 520                  {
 521                      NitsErr << PAL_T("ERROR: Only new interface tests can run deferred cleanup");
 522                      throw Exception();        
 523                  }    
 524              
 525                  if (choices == NULL)
 526 krisbash 1.1     {
 527                      do {            
 528                          RunVariation();
 529                      }
 530                      while (Next());
 531                  }
 532                  else
 533                  {
 534                  	PAL_Char *temp = Copy(choices);
 535                  	PAL_Char *temp2 = temp;
 536                      SetDryRun(1);
 537                      bool success = SelectChoices(temp2) && temp2[0] == L'\0';
 538                      SetDryRun(0);
 539                      delete [] temp;
 540              
 541                      if (!success)
 542                      {
 543                          NitsErr << PAL_T("ERROR: Invalid test variation '") << choices << PAL_T("'\n");
 544                          return;
 545                      }
 546              
 547 krisbash 1.1         RunVariation();
 548                  }
 549              }
 550              
 551              void Test::ContinueProcessingAfterBody()
 552              {
 553                  if(m_testRunState == PartAfterBodyRan)
 554                      return;
 555              
 556                  m_testRunState = PartAfterBodyRan;
 557              
 558              
 559                  Globals &globals = GetGlobals();
 560                  Run &run = Run::GetInstance();
 561              
 562                  Fault &fault = globals.GetAutoFault();
 563                  bool failTest = false;
 564              
 565                  if (globals.GetResult() == Error)
 566                  {
 567                      //Asserts attempted to fail fault sim.
 568 krisbash 1.1         //During the regular body this is an ordinary failure.
 569                      globals.SetResult(Failed);
 570                  }
 571                  else if (globals.GetResult() == Skipped && Run::GetInstance().GetEnabled())
 572                  {
 573                      if(!NitsNotRunInCurrentTestChoice())
 574                      {
 575                          //No asserts were attempted and the test wasn't disabled.
 576                          globals.SetResult(Error);
 577                          NitsAssert(0, PAL_T("The test case contains no assertions!"));
 578                      }
 579                      else
 580                      {            
 581                          globals.SetResult((m_filteredOutByUser) ? Skipped : Omitted);
 582                      }
 583                  }
 584              
 585                  int tempSwitchState = m_switchState;
 586                  
 587                  bool runFaultInjection = Run::GetInstance().GetFaultMode() == Automatic &&
 588                      globals.GetConfiguration().mode >= NitsTestIterativeFault;
 589 krisbash 1.1 
 590                  Configuration const &config = Run::GetInstance().GetConfiguration();
 591              
 592                  bool filteringDetected = false;
 593              	ptrdiff_t limit = 0;
 594              
 595                  if (!runFaultInjection || 
 596                      globals.GetResult() != Passed)
 597                  {
 598                      goto NoFaultSim;
 599                  }
 600              
 601                  enum
 602                  {
 603                      MainThreadOnly,
 604                      IncreasingAttemptOnly,
 605                      Delayed
 606                  } state;
 607              
 608                  state = MainThreadOnly;
 609                  globals.m_simAuto.m_minimumAttemptDifferentThread = INT_MAX;
 610 krisbash 1.1 
 611              #if defined(_MSC_VER)
 612              # pragma warning(disable : 4127)
 613              #endif
 614              
 615                  //Automatic fault simulation loop.
 616                  for (int i = 1; true; i++)
 617                  {
 618                      globals.ResetIgnoredErrorReporting();
 619                      if (state == Delayed)
 620                      {
 621                          //When filtering is disabled, threads from previous iterations
 622                          //  might interfere with us. Wait some time for them to go away.
 623                          Sleep_Milliseconds(10);
 624                      }
 625              
 626                      //Do NOT reset globals here, or information from setup will be erased.
 627                      //Set automatic fault sim parameters.
 628                      bool faultBP = false;
 629              
 630                      if (config.breakFault)
 631 krisbash 1.1         {
 632                          vector<int> const &list = Run::GetInstance().GetFaultBreakpointList();
 633                          for (unsigned j = 0; j < list.size(); j++)
 634                          {
 635                              if (list[j] == i)
 636                              {
 637                                  faultBP = true;
 638                                  break;
 639                              }
 640                          }
 641                      }
 642                      globals.SetResult(Passed);
 643                      fault.Reset(CallSite_ALL, i, faultBP);
 644              
 645                      wostringstream buf;
 646                      buf << L"Starting fault simulation iteration #" << i << L"...";
 647                      NitsTraceExW(buf.str().c_str(), TLINE, NitsAutomatic);
 648              #ifdef _MSC_VER
 649                      DoTraceMessage(TestLifetime, L"Starting fault simulation iteration #%d...", i);
 650              #endif
 651                      globals.GetStats().faultIterations++;
 652 krisbash 1.1 
 653                      // making switch state NotRunYet so that running the body does not skip the body
 654                      m_switchState = NotRunYet;
 655              
 656                      m_body(*this);
 657              
 658                      // putting the state back to what it was before we started fault sim so that further code path continues from the place where fault sim started
 659                      m_switchState = tempSwitchState;
 660                          
 661                      if (globals.m_simAuto.m_filtered)
 662                      {
 663                          filteringDetected = true;
 664                      }
 665              
 666                      if (state == MainThreadOnly)
 667                      {
 668                          limit = max(limit, globals.m_simAuto.m_firstAttemptDifferentThread);
 669                          globals.m_simAuto.m_firstAttemptDifferentThread = 0;
 670                      }
 671                      else if (state == IncreasingAttemptOnly)
 672                      {
 673 krisbash 1.1             limit = max(limit, globals.m_simAuto.m_faultedAttempt + 1);
 674                          globals.m_simAuto.m_minimumAttemptDifferentThread = limit;
 675                          globals.m_simAuto.m_firstAttemptDifferentThread = 0;
 676                      }
 677              
 678                      if (globals.GetResult() == Failed)
 679                      {
 680                          if (fault.DidFault())
 681                          {
 682                              //Expected behavior.
 683                              //Proceed to the next iteration.
 684                              continue;
 685                          }
 686              
 687                          //The test hit asserts before the fault was simulated.
 688                          //Stop here and report failure.
 689                          failTest = true;
 690                          NitsTraceEx(PAL_T("UNEXPECTED FAULT SIM FAILURE"), NitsHere(), NitsManual);
 691              #ifdef _MSC_VER
 692                          DoTraceMessage(TestLifetime, L"UNEXPECTED FAULT SIM FAILURE");
 693              #endif
 694 krisbash 1.1         }
 695                      else if (globals.GetResult() == Error)
 696                      {
 697                          //Asserts attempted to fail fault sim.
 698                          //Don't abort the test.
 699                          failTest = true;
 700                          continue;
 701                      }
 702                      else if (globals.GetResult() != Passed)
 703                      {
 704                          throw Exception();
 705                      }
 706              
 707                      //The test body passed.
 708                      //This may or may not be expected.
 709                      if (!fault.DidFault())
 710                      {
 711                          if (filteringDetected)
 712                          {
 713                              if (state == MainThreadOnly)
 714                              {
 715 krisbash 1.1                     //Rerun with all threads, using the calculated limit.
 716                                  globals.m_simAuto.m_minimumAttemptDifferentThread = limit;
 717                                  state = IncreasingAttemptOnly;
 718                              }
 719                              else if (state == IncreasingAttemptOnly)
 720                              {
 721                                  //Need to rerun with delays and without filtering.
 722                                  globals.m_simAuto.m_minimumAttemptDifferentThread = 0;
 723                                  state = Delayed;
 724                              }
 725                              filteringDetected = false;
 726                              continue;
 727                          }
 728              
 729                          //Loop complete.
 730                          fault.Reset(CallSite_NONE, 0, false);
 731                          globals.SetResult(failTest ? Failed : Faulted);
 732              #ifdef _MSC_VER
 733                          DoTraceMessage(TestLifetime, L"Fault simulation loop completed");
 734              #endif
 735                          goto NoFaultSim;
 736 krisbash 1.1         }
 737              
 738                      if (Run::GetInstance().IsSiteExcluded(fault.m_hit) ||
 739                          !globals.ShouldReportIgnoredErrors())
 740                      {
 741                          //The test expected faults not to propagate properly here.
 742                          continue;
 743                      }
 744              
 745                      //This iteration should not have succeeded.
 746                      //Report the problem and continue running the test.
 747                      failTest = true;
 748                      if (GetGlobals().GetConfiguration().traces >= NitsTraceAsserts)
 749                      {
 750                          NitsTraceEx(PAL_T("UNEXPECTED FAULT SIM SUCCESS"),
 751                                  fault.GetFaultedSite(), NitsManual);
 752                      }
 753              #ifdef _MSC_VER
 754                      DoTraceMessage(TestLifetime, L"UNEXPECTED FAULT SIM SUCCESS");
 755              #endif
 756                      if (config.breakAssert)
 757 krisbash 1.1         {
 758                          MyDebugBreak;
 759                      }
 760                  }
 761              
 762              NoFaultSim:
 763              
 764              	wostringstream testName;
 765              
 766              	Buffer wrappedTestName(testName);
 767                  PrintName(wrappedTestName, true);
 768              
 769                  if(m_cleanupMode == TestSystem::Test::ImmediateCleanup)
 770                  {
 771              #ifdef _MSC_VER
 772                      DoTraceMessage(TestLifetime, "Running test cleanup: %S", testName.str().c_str());
 773              #endif
 774              
 775                      RunCleanup();
 776                  }
 777              
 778 krisbash 1.1     Result temp = globals.GetResult();
 779                  globals.SetResult(Skipped);
 780              
 781                  if(NitsNotRunInCurrentTestChoice())
 782                  {
 783              #ifdef _MSC_VER
 784                      DoTraceMessage(TestLifetime, "Test choice ommited: %S", testName.str().c_str());
 785              #endif
 786                  }
 787                  else
 788                  {
 789              #ifdef _MSC_VER
 790                      DoTraceMessage(TestLifetime, "Test completed: %S", testName.str().c_str());
 791              #endif
 792                  }
 793                  
 794              #ifdef _MSC_VER
 795                  //Reset all shared memory helpers except the NITS shared memory.
 796                  //This prevents badly-behaved tests from interfering with future tests.
 797                  System::GetInstance().ResetClientMappings();
 798              #endif
 799 krisbash 1.1 
 800                  if (globals.GetResult() == Failed)
 801                  {
 802                      globals.SetResult(Error);
 803                  }
 804                  else
 805                  {
 806                      globals.SetResult(temp);
 807                  }
 808              
 809                  ptrdiff_t stopTicks = CPU_GetTimeStamp();
 810                  double seconds = float(stopTicks - m_startTicks) / 1000000.0;
 811                  globals.SetRunTime(seconds);
 812              
 813                  run.ReportResult();    
 814              }
 815              
 816              static void FilterOutTestIfRequired()
 817              {    
 818                  Run &run = Run::GetInstance();
 819                  if(!(run.CurrentTestMatchesTestFilter()))
 820 krisbash 1.1     {        
 821                      run.GetCurrentTest().m_filteredOutByUser = 1; 
 822                      GetGlobals().SetResult(Skipped);
 823                  }
 824              }
 825              
 826              void Test::ContinueProcessingAfterSetup()
 827              {
 828                  if(m_testRunState == BodyRan)
 829                      return;
 830              
 831                  m_testRunState = BodyRan;
 832                  
 833                  Globals &globals = GetGlobals();
 834                  Run &run = Run::GetInstance();
 835                  wostringstream testName;
 836              
 837                  Buffer wrappedTestName(testName);
 838                  PrintName(wrappedTestName, true);
 839              #ifdef _MSC_VER
 840                  DoTraceMessage(TestLifetime, "Running test setup: %S", testName.str().c_str());
 841 krisbash 1.1 #endif
 842                  
 843                  FilterOutTestIfRequired();    
 844              
 845                  if ((globals.GetConfiguration().traces >= NitsTraceAllTests) && 
 846                      (!m_filteredOutByUser))
 847                  {        
 848                      wostringstream buf;
 849                      buf << L"\t          " << testName.str().c_str() << L"...\n";
 850              
 851                      PAL_Char *postPipeStr = ConvertStringWToPalChar(buf.str().c_str());
 852                      globals.PostPipe(postPipeStr);
 853                      delete [] postPipeStr;
 854                  }
 855              
 856                  if (globals.GetResult() == Failed)
 857                  {
 858                      globals.SetResult(Error);
 859                  }
 860                  else if (globals.GetResult() == Passed)
 861                  {
 862 krisbash 1.1         globals.SetResult(Skipped);
 863                  }
 864              
 865                  BOOL testEnabled = TRUE;
 866                  if (!run.GetEnabled())
 867                  {
 868                      testEnabled = FALSE;
 869                  }
 870                  if (globals.GetConfiguration().skipFlakyTests)
 871                  {
 872                      if (run.GetFlaky())
 873                      {
 874                          testEnabled = FALSE;
 875                      }
 876                  }
 877              
 878                  if (testEnabled &&
 879                          globals.GetResult() == Skipped)
 880                  {
 881              #ifdef _MSC_VER
 882                      DoTraceMessage(TestLifetime, "Running test: %S", testName.str().c_str());
 883 krisbash 1.1 #endif
 884                      RunBody();
 885                      
 886                      if(m_testRunState == BodyRan)
 887                      {
 888                          if(!IsNewInterfaceTest())
 889                          {
 890                              ContinueProcessingAfterBody();
 891                          }
 892                          else
 893                          {
 894                              // we do not want test writers to use "return;" to exit the test fixtures, we want them to use "NitsReturn;"
 895                              // if they use "return;" then we hit this code path where the Setup is not followed by a continuation function call leading to the body and so on.
 896                              // so if we hit this code path when running new interface tests, we should error out
 897                              throw Exception();
 898                          }            
 899                      }
 900                  }
 901                  else
 902                  {
 903              #ifdef _MSC_VER
 904 krisbash 1.1         DoTraceMessage(TestLifetime, "Skipping test body: %S", testName.str().c_str());
 905              #endif
 906                      ContinueProcessingAfterBody();
 907                  }
 908              }
 909              
 910              void Test::RunVariation()
 911              {
 912                  Run &run = Run::GetInstance();
 913              
 914                  run.ClearTestVaritionNodes();
 915              
 916                  //Copy settings from command line options.
 917                  run.SetDefaultOptions();
 918              
 919                  m_startTicks = CPU_GetTimeStamp();
 920              
 921                  m_testRunState = BodyYetToRun;
 922                  m_prevLayerContinuation = NULL;
 923                  m_sameLayerContinuation = NULL;
 924                  m_prevSwitchOnSelectedTestStack = NULL;
 925 krisbash 1.1     m_someoneCalledOmit = 0;
 926                  m_filteredOutByUser = 0;
 927                  m_switchState = TestSystem::Switch::NotRunYet;
 928                  
 929                  //Status is 'Skipped'.
 930                  RunSetup();
 931              
 932                  if(m_testRunState == BodyYetToRun)
 933                  {    
 934                      vector<Switch *> &list = *(m_children);
 935                      // if it is not new interface test or there were no children registered then we will continue from here since setup would not have ran continuation
 936                      if(!IsNewInterfaceTest() || (list.size() == 0))
 937                      {            
 938                          ContinueProcessingAfterSetup();
 939                      }
 940                      else
 941                      {
 942                          // we do not want test writers to use "return;" to exit the test fixtures, we want them to use "NitsReturn;"
 943                          // if they use "return;" then we hit this code path where the Setup is not followed by a continuation function call leading to the body and so on.
 944                          // so if we hit this code path when running new interface tests, we should error out
 945                          throw Exception();
 946 krisbash 1.1         }
 947                  }
 948              }
 949              
 950              
 951              void Test::RunBody()
 952              {
 953                  Globals &globals = GetGlobals();
 954                  
 955                  //N.B. When nits.exe is running tests in-proc, we need to bootstrap
 956                  //  the debugger before the test. Otherwise, the test could call
 957                  //  LoadLibrary, and CheckDebugger() could get called inside the
 958                  //  loader lock of our process, which can prevent us from actually
 959                  //  creating the debugger process indefinitely.
 960                  globals.CheckDebugger();
 961              
 962                  globals.m_simAuto.m_firstAttemptDifferentThread = 0;
 963                  globals.m_simAuto.m_minimumAttemptDifferentThread = 0;
 964                  globals.m_simAuto.m_mainThread = Thread_ID();
 965                  globals.m_simAuto.m_faultedAttempt = 0;
 966              
 967 krisbash 1.1     //Run the regular test body.
 968                  m_body(*this);
 969              }
 970              
 971              int Test::s_nextTimeout = 60;
 972              bool Test::s_nextIsolation = false;
 973              
 974              NITS_EXPORT void NITS_CALL NitsTestSetIsolationHelper(_In_ Test &test)
 975              {
 976                  PAL_UNUSED(test);
 977              
 978                  Test::s_nextIsolation = true;
 979              }
 980              
 981              NITS_EXPORT void NITS_CALL NitsTestSetTimeoutHelper(_In_ Test &test, int seconds)
 982              {
 983                  PAL_UNUSED(test);
 984              
 985                  Test::s_nextTimeout = seconds;
 986              }
 987              
 988 krisbash 1.1 NITS_EXPORT void NITS_CALL NitsSetRegistrationInfo(struct RegistrationInfo *r, 
 989                                      int selfContextSize, 
 990                                      int selfStructSize,                         
 991              						int numberOfParents,
 992              						Switch **parentArray, 
 993              						void *(*creationFunc)(), 
 994              						void (*initFunc)(void *, void *), 
 995              						void (*bodyFunc)(void *),
 996              						void (*cleanupFunc)(void *),
 997              						enum TestFixtureType fixtureType, 
 998              						void **arrayOfInitializers)
 999              {
1000              	r->selfContext = 0;
1001              	r->selfStruct = 0;    
1002                  r->countOfLinks = 0;
1003              	r->selfContextSize = selfContextSize;
1004              	r->selfStructSize = selfStructSize;    
1005              	r->numberOfParents = numberOfParents;
1006              	r->parentArray = parentArray;
1007              	r->creationFunc = creationFunc;
1008              	r->initFunc = initFunc;
1009 krisbash 1.1 	r->bodyFunc = bodyFunc;
1010              	r->cleanupFunc = cleanupFunc;
1011              	r->fixtureType = fixtureType;
1012              	r->arrayOfInitializers = arrayOfInitializers;		
1013              	r->cleanupSwitch = 0;
1014              	r->crashSwitch = 0;
1015              }
1016              
1017              NITS_EXPORT void NITS_CALL NitsCreateStruct(TestSystem::Switch &myFixture, void **selfContext, void **selfStruct)
1018              {
1019              	struct RegistrationInfo *myFixtureRegistration = (struct RegistrationInfo *) (myFixture.m_registration);
1020              
1021                  // this should not happen
1022                  if(!selfContext || !selfStruct)
1023                      return;
1024              
1025                  // this is for virtual inheritance kind of semantics; if there is already a structure allocated through one route in inheritance, we will not allocate it again but use the same one
1026                  if(myFixtureRegistration->countOfLinks > 0)
1027                  {
1028                      *selfContext = myFixtureRegistration->selfContext;
1029                      *selfStruct = myFixtureRegistration->selfStruct;
1030 krisbash 1.1     }
1031                  else
1032                  {
1033                      int isSplitFixture = (myFixtureRegistration->fixtureType == SplitFixture);
1034                      // for splitfixtures, the context comes from their parents; they do not have a context; 
1035                      // pointer adjustment is done during the call of the splitfixture by walking back the call chain
1036                      *selfContext = malloc(myFixtureRegistration->selfContextSize);
1037                      *selfStruct = (isSplitFixture ? 0 : malloc(myFixtureRegistration->selfStructSize));
1038                      myFixtureRegistration->selfContext = *selfContext;
1039                      myFixtureRegistration->selfStruct = *selfStruct;
1040                  }
1041                  (myFixtureRegistration->countOfLinks)++;
1042              }
1043              
1044              NITS_EXPORT void NITS_CALL NitsDestroyStruct(TestSystem::Switch &myFixture)
1045              {
1046              	struct RegistrationInfo *myFixtureRegistration = (struct RegistrationInfo *) (myFixture.m_registration);
1047                  (myFixtureRegistration->countOfLinks)--;
1048              
1049                  if(myFixtureRegistration->countOfLinks == 0)
1050                  {
1051 krisbash 1.1         free(myFixtureRegistration->selfContext);
1052              
1053                      if(myFixtureRegistration->fixtureType != SplitFixture)
1054                      {
1055                          free(myFixtureRegistration->selfStruct);
1056                      }
1057                      myFixtureRegistration->selfContext = 0;
1058                      myFixtureRegistration->selfStruct = 0;
1059                  }
1060              }
1061              
1062              NITS_EXPORT void * NITS_CALL NitsGetSelfStruct(TestSystem::Switch &myFixture)
1063              {
1064              	struct RegistrationInfo *myFixtureRegistration = (struct RegistrationInfo *) (myFixture.m_registration);
1065              
1066                  return myFixtureRegistration->selfStruct;
1067              }
1068              
1069              NITS_EXPORT void NITS_CALL NitsBody_NewInterfaceTest(TestSystem::Switch &test)
1070              {
1071              	struct RegistrationInfo *testRegistration = (struct RegistrationInfo *) (test.m_registration);
1072 krisbash 1.1 
1073                  FilterOutTestIfRequired();
1074              
1075                  if(test.m_switchState == TestSystem::Switch::NotRunYet)
1076                  {
1077                      test.m_switchState = TestSystem::Switch::RunOnce;
1078                  	testRegistration->bodyFunc(testRegistration->selfContext);
1079                  }
1080                  else
1081                  {
1082                      NitsRunContinuation(test);
1083                  }
1084              }
1085              
1086              NITS_EXPORT void NITS_CALL NitsSetup_NewInterfaceTest(TestSystem::Switch &test)
1087              {
1088              	struct RegistrationInfo *testRegistration = (struct RegistrationInfo *) (test.m_registration);
1089              	int parentCount = 0;
1090              	Switch *currentParent = 0;
1091                  // when doing dryRun, it is needed only to make engine aware of children; so skip all other steps.
1092                  int isDryRun = Run::GetInstance().GetCurrentTest().IsDryRunToIdentifyChildren();// test.IsDryRunToIdentifyChildren();
1093 krisbash 1.1     
1094                  if(test.IsBodyFixture() ||
1095              		IsSetupFixture(testRegistration->fixtureType))
1096              	{	
1097                      if(!isDryRun)
1098                      {
1099                          Run::GetInstance().AddTestVariationNode(&test);
1100                      }
1101              
1102              		if(test.IsBodyFixture() && !isDryRun)
1103              		{
1104              			if(testRegistration->selfContext == 0)
1105              			{
1106              				// this creationFunc will recurse through the entire test structure and create selfContext for each node following the virtual inheritance way of creating common node only once
1107              				// TODO: implement multiple inheritance; will the common nodes need to register switches multiple times; who will create those switches?
1108              				testRegistration->creationFunc();
1109              			}
1110              			// the initFunc is passed in the created context and a NULL for the initValues since the test itself does not provide any init values; the initFunc is supposed zero out its structure if init values are not provided.
1111              			testRegistration->initFunc(testRegistration->selfContext, 0);
1112              
1113                          test.m_sameLayerContinuation = 0;
1114 krisbash 1.1 
1115                          test.m_prevLayerContinuation = &test;
1116              		}
1117              
1118              		if(testRegistration->parentArray != 0)
1119              		{
1120              			while(parentCount < testRegistration->numberOfParents)
1121              			{
1122              				// register the child by calling Test.Child; this helps the test engine identify children/pick up the current chain of children to be run in this iteration
1123              				currentParent = testRegistration->parentArray[parentCount];
1124                                              
1125                              // in both test setup and body cases, you need continuation switch set to your currentParent; 
1126                              // but in SetupFixture case the continuation is the body of this current testRegistration whereas in 
1127                              // in BodyFixture case continuation is the ContinueProcessingAfterSetup
1128                              if(!isDryRun)
1129                              {
1130                                  currentParent->m_sameLayerContinuation = 0;
1131                                      
1132                                  if(test.IsGroup() && (parentCount >= 1))
1133                                  {
1134                                      Switch *prevParent = testRegistration->parentArray[parentCount - 1];
1135 krisbash 1.1                         prevParent->m_sameLayerContinuation = currentParent;
1136                                  }
1137              
1138                                  // this helps with multiple inheritance; if some other fixture already put the prevLayerContiuationLink into current parent, that is sufficient; the second link is not required
1139                                  if(currentParent->m_prevLayerContinuation == 0)
1140                                  {
1141                                      currentParent->m_prevLayerContinuation = &test;
1142                                  }
1143                              }
1144                                  
1145                  			test.Child(*currentParent);	            
1146                              
1147              				parentCount++;
1148              			}
1149              
1150                          // once we found what is the root node in current iteration; invoke its body; that will keep calling continuation till we run the test body and cleanup by nesting them on the same stack
1151                          if(!isDryRun && test.IsBodyFixture() && (test.m_rootSwitch != 0))
1152                          {
1153                              (test.m_rootSwitch)->m_prevSwitchOnSelectedTestStack = 0;
1154                  			NitsBody_NewInterfaceTest(*(test.m_rootSwitch));
1155                              test.m_rootSwitch = 0;                
1156 krisbash 1.1             }
1157              		}
1158                      else
1159                      {
1160                          if(!isDryRun)
1161                          {
1162                              // when we reach the root of the tree; run the body of the fixture
1163                      		if(IsSetupFixture(testRegistration->fixtureType))
1164                      		{
1165                          		Switch *continuationSwitch = test.m_prevLayerContinuation;
1166                          		while(continuationSwitch)
1167                                  {
1168                                      if(continuationSwitch->m_prevLayerContinuation == 0 || (continuationSwitch->m_prevLayerContinuation == continuationSwitch))
1169                                      {
1170                                          break;
1171                                      }
1172                                      continuationSwitch = continuationSwitch->m_prevLayerContinuation;
1173                                  }
1174              
1175                                  if (continuationSwitch == NULL)
1176                                  {
1177 krisbash 1.1                         FatalError();
1178                                      return;
1179                                  }
1180              
1181                                  // only first root node i.e. when m_rootSwitch = 0 does this assignment; others do not since the first one will continue to run others
1182                                  if(continuationSwitch->m_rootSwitch == 0)
1183                                  {
1184                                      continuationSwitch->m_rootSwitch = &test;
1185                                  }
1186                      		}
1187                          }
1188                      }
1189              	}
1190              }
1191              
1192              NITS_EXPORT void NITS_CALL NitsCleanup_NewInterfaceTest(TestSystem::Switch &test)
1193              {
1194              	struct RegistrationInfo *testRegistration = (struct RegistrationInfo *) (test.m_registration);
1195              
1196                  if(Run::GetInstance().GetCurrentTest().IsDryRunToIdentifyChildren())
1197                      return;
1198 krisbash 1.1     
1199                  struct RegistrationInfo *cleanupRegistration = (struct RegistrationInfo *) ((testRegistration->cleanupSwitch) ? testRegistration->cleanupSwitch->m_registration : 0);
1200                  
1201                  if(cleanupRegistration && !(test.m_notRunInCurrentTestChoice))
1202                  {
1203                      if(test.m_switchState == TestSystem::Switch::RunOnce)
1204                      {
1205                          test.m_switchState = TestSystem::Switch::CleanupRun;
1206                          cleanupRegistration->bodyFunc(testRegistration->selfContext);
1207                      }
1208                  }
1209              
1210                  test.m_switchState = TestSystem::Switch::NotRunYet;
1211                  test.m_notRunInCurrentTestChoice = 0;
1212              }
1213              
1214              NITS_EXPORT void NITS_CALL NitsRunContinuation(TestSystem::Switch &test)
1215              {
1216                  // start psuedo code
1217                  TestSystem::Switch *continuationSwitch = test.m_sameLayerContinuation;
1218                  struct RegistrationInfo *continuationRegistration = 0;
1219 krisbash 1.1     
1220                  // this will get run now or it will go to its parent; so we should reset it to avoid infinite loop if any
1221                  test.m_sameLayerContinuation = NULL;
1222              
1223                  while(continuationSwitch)
1224                  {
1225                      continuationRegistration = (struct RegistrationInfo *) (continuationSwitch->m_registration);
1226                      
1227                      if(continuationRegistration->parentArray == 0)
1228                      {
1229                          continuationSwitch->m_prevSwitchOnSelectedTestStack = &test;
1230                          continuationSwitch->m_notRunInCurrentTestChoice = NitsNotRunInCurrentTestChoice();
1231                          if(continuationRegistration->fixtureType == SplitFixture)
1232                          {
1233                              continuationRegistration->selfStruct = NitsGetSelfStruct(test);
1234                          }
1235                          NitsBody_NewInterfaceTest(*continuationSwitch);
1236                          // continuationRegistration->bodyFunc(continuationRegistration->selfContext);
1237                          return;
1238                      }
1239                      else
1240 krisbash 1.1         {
1241                          Switch *tempSwitch = continuationSwitch;
1242                          continuationSwitch = continuationSwitch->GetFirstSelectedChild();
1243                          if(continuationSwitch && (continuationSwitch->m_prevLayerContinuation != tempSwitch))
1244                          {
1245                              // this helps with multiple inheritance; before going to the next parent; 
1246                              // you set the prevLayerContinuation to yourself so that when it comes down, it does not go the current prevLayer instead comes back to you
1247                              continuationSwitch->m_prevLayerContinuation = tempSwitch;
1248                          }
1249                      }
1250                  }
1251              
1252                  continuationSwitch = test.m_prevLayerContinuation;
1253              
1254                  if(continuationSwitch)
1255                  {
1256                      continuationRegistration = (struct RegistrationInfo *) (continuationSwitch->m_registration);
1257              
1258                      if(IsSetupFixture(continuationRegistration->fixtureType))
1259                      {
1260                          continuationSwitch->m_prevSwitchOnSelectedTestStack = &test;
1261 krisbash 1.1             continuationSwitch->m_notRunInCurrentTestChoice = NitsNotRunInCurrentTestChoice();
1262                          if(continuationRegistration->fixtureType == SplitFixture)
1263                          {
1264                              continuationRegistration->selfStruct = NitsGetSelfStruct(test);
1265                          }            
1266                          NitsBody_NewInterfaceTest(*continuationSwitch);
1267                          // continuationRegistration->bodyFunc(continuationRegistration->selfContext);
1268                      }
1269                      else if(continuationSwitch->IsBodyFixture())
1270                      {
1271                          TestSystem::Test *continuationTest = (TestSystem::Test *)continuationSwitch;
1272                          
1273                          if(continuationTest->m_testRunState == TestSystem::Test::BodyYetToRun)
1274                          {
1275                              continuationSwitch->m_prevSwitchOnSelectedTestStack = &test;
1276                              continuationSwitch->m_notRunInCurrentTestChoice = NitsNotRunInCurrentTestChoice();
1277                              continuationTest->ContinueProcessingAfterSetup();
1278                          }
1279                          else if(continuationTest->m_testRunState == TestSystem::Test::BodyRan)
1280                          {
1281                              continuationTest->ContinueProcessingAfterBody();
1282 krisbash 1.1 
1283                              if(continuationTest->m_cleanupMode == TestSystem::Test::ImmediateCleanup)
1284                              {
1285                                  // the main thread which was running body and possibly faultsim will then call clean up on the test related context objects
1286                                  // this is separate from the cleanup functions explicitly defined by the user to clean up the stuff the user wants to.
1287                                  continuationRegistration->cleanupFunc(continuationRegistration->selfContext);
1288                              }
1289                          }            
1290                      }
1291                  }
1292              }
1293              
1294              NITS_EXPORT int NITS_CALL NitsIsFixtureSelectedSoFar(TestSystem::Switch &currentSwitch, TestSystem::Switch &searchSwitch)
1295              {
1296                  Switch *currentNode = &currentSwitch;
1297                  
1298                  while(currentNode->m_prevSwitchOnSelectedTestStack)
1299                  {
1300                      if(currentNode->m_prevSwitchOnSelectedTestStack == &searchSwitch)
1301                          return 1;
1302              
1303 krisbash 1.1         currentNode = currentNode->m_prevSwitchOnSelectedTestStack;
1304                  }
1305              
1306                  return 0;
1307              }
1308              
1309              #define FIXTURE_STRING PAL_T("Fixture ")
1310              #define OMITTED_MESSAGE PAL_T(" omitted the test choice\n")
1311              
1312              NITS_EXPORT void NITS_CALL NitsOmit(TestSystem::Switch &currentSwitch)
1313              {
1314                  Run::GetInstance().GetCurrentTest().m_someoneCalledOmit = 1;
1315                  GetGlobals().SetResult(Skipped);
1316              
1317                  int totalLen = (int)(Tcslen(FIXTURE_STRING) + Tcslen(currentSwitch.GetName()) + Tcslen(OMITTED_MESSAGE)) + 1;
1318                  PAL_Char *outString = (PAL_Char *)(malloc(totalLen*sizeof(PAL_Char)));
1319                  if(outString)
1320                  {
1321                  	Tcslcpy(outString, FIXTURE_STRING, totalLen);
1322                  	Tcscat(outString, totalLen, currentSwitch.GetName());
1323                  	Tcscat(outString, totalLen, OMITTED_MESSAGE);
1324 krisbash 1.1     	GetGlobals().PostPipe(outString);
1325                      free(outString);
1326                  }
1327                  else
1328                  {
1329                  	GetGlobals().PostPipe(PAL_T("Some Fixture omitted the test choice"));
1330                  }    
1331              }
1332              
1333              NITS_EXPORT int NITS_CALL NitsAreWeInOmitMode()
1334              {    
1335                  return (Run::GetInstance().GetCurrentTest().m_someoneCalledOmit);
1336              }
1337              
1338              NITS_EXPORT int NITS_CALL NitsIsTestFiltered()
1339              {
1340                  return (Run::GetInstance().GetCurrentTest().m_filteredOutByUser);
1341              }
1342              
1343              NITS_EXPORT_DEF struct EmptyStruct sEmptyStruct = {0};
1344              

ViewCVS 0.9.2