Coverage for /Syzygy/bard/events/play_util_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%46460.C++test

Line-by-line coverage:

   1    :  // Copyright 2016 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/bard/events/play_util.h"
  16    :  
  17    :  #include <windows.h>
  18    :  
  19    :  #include "base/macros.h"
  20    :  #include "gtest/gtest.h"
  21    :  
  22    :  namespace bard {
  23    :  
  24    :  namespace {
  25    :  
  26    :  struct StackTrace {
  27    :    // One frame for each nibble of the stack ID.
  28    :    void* frames[8];
  29    :  };
  30    :  
  31    :  template <uint32_t kInvokeValue>
  32    :  using InvokeHelper =
  33    :      detail::InvokeFunctionWithStackIdHelper<kInvokeValue,
  34    :                                              bool(bool, StackTrace*),
  35    :                                              bool,
  36    :                                              bool,
  37    :                                              StackTrace*>;
  38    :  
  39  E :  bool ParrotImpl(bool input, StackTrace* stack_trace) {
  40    :    // Capture the current stack trace, but ignore the current frame. This should
  41    :    // only grab the InvokeFunctionWithStackIdHelper frames.
  42  E :    CaptureStackBackTrace(1, arraysize(stack_trace->frames), stack_trace->frames,
  43    :                          nullptr);
  44  E :    return input;
  45  E :  }
  46    :  
  47    :  // Does nothing.
  48  E :  bool Dummy(bool input, StackTrace* stack_trace) {
  49  E :    return false;
  50  E :  }
  51    :  
  52    :  // Wraps a call to ParrotImpl via InvokeFunctionWithStackId.
  53  E :  bool Parrot(uint32_t stack_id, bool input, StackTrace* stack_trace) {
  54  E :    return InvokeFunctionWithStackId(stack_id, ParrotImpl, input, stack_trace);
  55  E :  }
  56    :  
  57    :  // Gets the extents of the associated InvokeHelper function.
  58    :  template <uint32_t kInvokeValue>
  59    :  struct GetInvokeFunctionExtents {
  60    :    static void Do(void const** invoke_helper_begins,
  61  E :                   void const** invoke_helper_ends) {
  62  E :      InvokeHelper<kInvokeValue>::Do(detail::kGetFunctionExtentsDepth, 0, Dummy,
  63    :                                     false, nullptr);
  64  E :      invoke_helper_begins[kInvokeValue] = detail::kInvokeFunctionBegin;
  65  E :      invoke_helper_ends[kInvokeValue] = detail::kInvokeFunctionEnd;
  66  E :    }
  67    :  };
  68    :  
  69    :  }  // namespace
  70    :  
  71  E :  TEST(InvokeFunctionWithStackIdTest, ExpectedStackId) {
  72    :    // Get the extents of the various invoke helper functions.
  73  E :    void const* invoke_helper_begins[16] = {};
  74  E :    void const* invoke_helper_ends[16] = {};
  75  E :    GetInvokeFunctionExtents<0x0>::Do(invoke_helper_begins, invoke_helper_ends);
  76  E :    GetInvokeFunctionExtents<0x1>::Do(invoke_helper_begins, invoke_helper_ends);
  77  E :    GetInvokeFunctionExtents<0x2>::Do(invoke_helper_begins, invoke_helper_ends);
  78  E :    GetInvokeFunctionExtents<0x3>::Do(invoke_helper_begins, invoke_helper_ends);
  79  E :    GetInvokeFunctionExtents<0x4>::Do(invoke_helper_begins, invoke_helper_ends);
  80  E :    GetInvokeFunctionExtents<0x5>::Do(invoke_helper_begins, invoke_helper_ends);
  81  E :    GetInvokeFunctionExtents<0x6>::Do(invoke_helper_begins, invoke_helper_ends);
  82  E :    GetInvokeFunctionExtents<0x7>::Do(invoke_helper_begins, invoke_helper_ends);
  83  E :    GetInvokeFunctionExtents<0x8>::Do(invoke_helper_begins, invoke_helper_ends);
  84  E :    GetInvokeFunctionExtents<0x9>::Do(invoke_helper_begins, invoke_helper_ends);
  85  E :    GetInvokeFunctionExtents<0xA>::Do(invoke_helper_begins, invoke_helper_ends);
  86  E :    GetInvokeFunctionExtents<0xB>::Do(invoke_helper_begins, invoke_helper_ends);
  87  E :    GetInvokeFunctionExtents<0xC>::Do(invoke_helper_begins, invoke_helper_ends);
  88  E :    GetInvokeFunctionExtents<0xD>::Do(invoke_helper_begins, invoke_helper_ends);
  89  E :    GetInvokeFunctionExtents<0xE>::Do(invoke_helper_begins, invoke_helper_ends);
  90  E :    GetInvokeFunctionExtents<0xF>::Do(invoke_helper_begins, invoke_helper_ends);
  91    :  
  92    :    // Generate a handful of random stack IDs and ensure they are dispatched via
  93    :    // the expected functions.
  94  E :    StackTrace stack_trace = {};
  95  E :    for (size_t i = 0; i < 100; ++i) {
  96  E :      uint32_t stack_id = ::rand();
  97  E :      bool value = ::rand() % 2;
  98  E :      EXPECT_EQ(value, Parrot(stack_id, value, &stack_trace));
  99    :  
 100  E :      for (size_t j = 0; j < 8; ++j) {
 101  E :        uint32_t nibble = (stack_id >> (28 - 4 * j)) & 0xF;
 102  E :        EXPECT_LT(invoke_helper_begins[nibble], stack_trace.frames[j]);
 103  E :        EXPECT_GE(invoke_helper_ends[nibble], stack_trace.frames[j]);
 104  E :      }
 105  E :    }
 106  E :  }
 107    :  
 108    :  }  // namespace bard

Coverage information generated Fri Jul 29 11:00:21 2016.