Coverage for /Syzygy/trace/service/mapped_buffer_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
91.3%941030.C++test

Line-by-line coverage:

   1    :  // Copyright 2013 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/trace/service/mapped_buffer.h"
  16    :  
  17    :  #include "gtest/gtest.h"
  18    :  #include "syzygy/trace/service/buffer_consumer.h"
  19    :  #include "syzygy/trace/service/buffer_pool.h"
  20    :  #include "syzygy/trace/service/service.h"
  21    :  #include "syzygy/trace/service/session.h"
  22    :  
  23    :  namespace trace {
  24    :  namespace service {
  25    :  
  26    :  namespace {
  27    :  
  28    :  // A dummy buffer consumer for use with our dummy session.
  29    :  class DummyBufferConsumer : public BufferConsumer {
  30    :   public:
  31  i :    virtual ~DummyBufferConsumer() { }
  32  i :    virtual bool Open(Session* session) OVERRIDE { return true; }
  33  i :    virtual bool Close(Session* session) OVERRIDE { return true; }
  34  i :    virtual bool ConsumeBuffer(Buffer* buffer) OVERRIDE { return true; }
  35  i :    virtual size_t block_size() const OVERRIDE { return 1024; }
  36    :  };
  37    :  
  38    :  // A factory for producing DummyBufferConsumer instances.
  39    :  class DummyBufferConsumerFactory : public BufferConsumerFactory {
  40    :   public:
  41    :    virtual bool CreateConsumer(
  42  i :        scoped_refptr<BufferConsumer>* consumer) OVERRIDE {
  43  i :      *consumer = new DummyBufferConsumer();
  44  i :      return true;
  45  i :    }
  46    :  };
  47    :  
  48    :  class MappedBufferTest : public testing::Test {
  49    :   public:
  50    :    // This needs to be <= the system allocation granularity (which is 64kb).
  51    :    static const size_t kBufferSize = 4096;
  52    :  
  53  E :    MappedBufferTest() : b1(NULL), b2(NULL) {
  54  E :      SYSTEM_INFO sys_info = {};
  55  E :      ::GetSystemInfo(&sys_info);
  56  E :      DCHECK_LT(kBufferSize, sys_info.dwAllocationGranularity);
  57  E :    }
  58    :  
  59  E :    virtual void SetUp() OVERRIDE {
  60  E :      service.reset(new Service(&dummy_buffer_consumer_factory));
  61  E :      session = new Session(service.get());
  62    :  
  63  E :      pool.reset(new BufferPool());
  64  E :      ASSERT_TRUE(pool->Init(session.get(), 2, kBufferSize));
  65    :  
  66  E :      b1 = pool->begin();
  67  E :      b2 = b1 + 1;
  68  E :      ASSERT_EQ(2, pool->end() - pool->begin());
  69  E :    }
  70    :  
  71  E :    virtual void TearDown() OVERRIDE {
  72  E :      b1 = NULL;
  73  E :      b2 = NULL;
  74    :  
  75  E :      pool.reset();
  76  E :      session = NULL;
  77  E :      service.reset();
  78  E :    }
  79    :  
  80    :    // These are needed because they are all injected dependencies of each other,
  81    :    // and ultimately a session is an injected dependency of a BufferPool.
  82    :    // However, I don't need them to be actually running as MappedBuffer
  83    :    // interaction with BufferPool is limited to the memory mapped file handle.
  84    :    DummyBufferConsumerFactory dummy_buffer_consumer_factory;
  85    :    scoped_ptr<Service> service;
  86    :    scoped_refptr<Session> session;
  87    :    scoped_ptr<BufferPool> pool;
  88    :    Buffer* b1;
  89    :    Buffer* b2;
  90    :  };
  91    :  
  92    :  // A simple wrapper that exposes the innards of a mapped buffer.
  93    :  class TestMappedBuffer : public MappedBuffer {
  94    :   public:
  95  E :    explicit TestMappedBuffer(Buffer* buffer) : MappedBuffer(buffer) { }
  96  E :    Buffer* buffer() const { return buffer_; }
  97  E :    uint8* base() const { return base_; }
  98    :  };
  99    :  
 100    :  }  // namespace
 101    :  
 102  E :  TEST_F(MappedBufferTest, MapAndUnmap) {
 103  E :    TestMappedBuffer mb(b1);
 104  E :    EXPECT_EQ(b1, mb.buffer());
 105  E :    EXPECT_TRUE(mb.base() == NULL);
 106  E :    EXPECT_TRUE(mb.data() == NULL);
 107  E :    EXPECT_FALSE(mb.IsMapped());
 108    :  
 109    :    // Do a no-op unmap.
 110  E :    EXPECT_TRUE(mb.Unmap());
 111  E :    EXPECT_EQ(b1, mb.buffer());
 112  E :    EXPECT_TRUE(mb.base() == NULL);
 113  E :    EXPECT_TRUE(mb.data() == NULL);
 114  E :    EXPECT_FALSE(mb.IsMapped());
 115    :  
 116    :    // Map the buffer.
 117  E :    EXPECT_TRUE(mb.Map());
 118  E :    EXPECT_EQ(b1, mb.buffer());
 119  E :    EXPECT_TRUE(mb.base() != NULL);
 120  E :    EXPECT_TRUE(mb.data() != NULL);
 121  E :    EXPECT_EQ(mb.base(), mb.data());
 122  E :    EXPECT_TRUE(mb.IsMapped());
 123  E :    uint8* base = mb.base();
 124  E :    uint8* data = mb.data();
 125    :  
 126    :    // Do a no-op map.
 127  E :    EXPECT_TRUE(mb.Map());
 128  E :    EXPECT_EQ(b1, mb.buffer());
 129  E :    EXPECT_TRUE(mb.base() != NULL);
 130  E :    EXPECT_TRUE(mb.data() != NULL);
 131  E :    EXPECT_EQ(mb.base(), mb.data());
 132  E :    EXPECT_EQ(base, mb.base());
 133  E :    EXPECT_EQ(data, mb.data());
 134  E :    EXPECT_TRUE(mb.IsMapped());
 135    :  
 136    :    // Unmap the buffer.
 137  E :    EXPECT_TRUE(mb.Unmap());
 138  E :    EXPECT_EQ(b1, mb.buffer());
 139  E :    EXPECT_TRUE(mb.base() == NULL);
 140  E :    EXPECT_TRUE(mb.data() == NULL);
 141  E :    EXPECT_FALSE(mb.IsMapped());
 142  E :  }
 143    :  
 144  E :  TEST_F(MappedBufferTest, AlignmentCalculationIsCorrect) {
 145  E :    TestMappedBuffer mb(b2);
 146    :  
 147    :    // Map the buffer.
 148  E :    EXPECT_TRUE(mb.Map());
 149  E :    EXPECT_TRUE(mb.base() != NULL);
 150  E :    EXPECT_TRUE(mb.data() != NULL);
 151  E :    EXPECT_EQ(mb.data(), mb.base() + kBufferSize);
 152  E :  }
 153    :  
 154  E :  TEST_F(MappedBufferTest, MappedViewIsReaped) {
 155  E :    MEMORY_BASIC_INFORMATION info = {};
 156  E :    SIZE_T ret = 0;
 157  E :    uint8* base = NULL;
 158    :  
 159    :    {
 160  E :      TestMappedBuffer mb(b1);
 161  E :      mb.Map();
 162  E :      base = mb.base();
 163  E :      EXPECT_TRUE(base != NULL);
 164  E :      ret = ::VirtualQuery(base, &info, sizeof(info));
 165  E :      EXPECT_EQ(sizeof(info), ret);
 166  E :      EXPECT_EQ(base, info.BaseAddress);
 167  E :      EXPECT_LE(kBufferSize, info.RegionSize);
 168  E :      EXPECT_EQ(MEM_MAPPED, info.Type);
 169    :  
 170    :      // Test that the mapping is reaped when unmap is explicitly called.
 171  E :      mb.Unmap();
 172  E :      ret = ::VirtualQuery(base, &info, sizeof(info));
 173  E :      EXPECT_EQ(sizeof(info), ret);
 174  E :      EXPECT_EQ(MEM_FREE, info.State);
 175    :  
 176  E :      mb.Map();
 177  E :      base = mb.base();
 178  E :      EXPECT_TRUE(base != NULL);
 179  E :      ret = ::VirtualQuery(base, &info, sizeof(info));
 180  E :      EXPECT_EQ(sizeof(info), ret);
 181  E :      EXPECT_EQ(base, info.BaseAddress);
 182  E :      EXPECT_LE(kBufferSize, info.RegionSize);
 183  E :      EXPECT_EQ(MEM_MAPPED, info.Type);
 184  E :    }
 185    :  
 186    :    // And also make sure it is reaped when the object goes out of scope.
 187  E :    ret = ::VirtualQuery(base, &info, sizeof(info));
 188  E :    EXPECT_EQ(sizeof(info), ret);
 189  E :    EXPECT_EQ(MEM_FREE, info.State);
 190  E :  }
 191    :  
 192    :  }  // namespace service
 193    :  }  // namespace trace

Coverage information generated Thu Mar 26 16:15:41 2015.