Coverage for /Syzygy/refinery/process_state/process_state_unittest.cc

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

Line-by-line coverage:

   1    :  // Copyright 2015 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/refinery/process_state/process_state.h"
  16    :  
  17    :  #include <limits>
  18    :  #include <string>
  19    :  
  20    :  #include "base/memory/scoped_ptr.h"
  21    :  #include "base/strings/string_piece.h"
  22    :  #include "gtest/gtest.h"
  23    :  #include "syzygy/refinery/process_state/process_state_util.h"
  24    :  #include "syzygy/refinery/process_state/refinery.pb.h"
  25    :  
  26    :  namespace refinery {
  27    :  
  28    :  namespace {
  29    :  
  30    :  void ValidateSingleRecordMatch(
  31    :      AddressRange range,
  32    :      const std::vector<BytesRecordPtr>& matching_records,
  33  E :      base::StringPiece testcase) {
  34  E :    ASSERT_EQ(1, matching_records.size()) << testcase;
  35  E :    ASSERT_EQ(range, matching_records[0]->range()) << testcase;
  36  E :  }
  37    :  
  38    :  // Adds a stack record to a process state.
  39    :  void AddStackRecord(const AddressRange& range,
  40    :                      const size_t thread_id,
  41    :                      ProcessState* process_state,
  42  E :                      StackRecordPtr* stack_record) {
  43  E :    StackLayerPtr stack_layer;
  44  E :    process_state->FindOrCreateLayer(&stack_layer);
  45  E :    stack_layer->CreateRecord(range, stack_record);
  46    :    (*stack_record)
  47    :        ->mutable_data()
  48    :        ->mutable_thread_info()
  49  E :        ->set_thread_id(thread_id);
  50  E :  }
  51    :  
  52    :  }  // namespace
  53    :  
  54  E :  TEST(ProcessStateTest, FindOrCreateLayer) {
  55  E :    ProcessState report;
  56    :  
  57  E :    scoped_refptr<ProcessState::Layer<Bytes>> bytes_layer;
  58  E :    EXPECT_FALSE(report.FindLayer(&bytes_layer));
  59  E :    EXPECT_TRUE(bytes_layer == nullptr);
  60    :  
  61  E :    scoped_refptr<ProcessState::Layer<TypedBlock>> typed_layer;
  62  E :    EXPECT_FALSE(report.FindLayer(&typed_layer));
  63    :  
  64  E :    report.FindOrCreateLayer(&bytes_layer);
  65  E :    EXPECT_TRUE(bytes_layer != nullptr);
  66    :  
  67  E :    scoped_refptr<ProcessState::Layer<Bytes>> test_layer;
  68  E :    EXPECT_TRUE(report.FindLayer(&test_layer));
  69  E :    EXPECT_EQ(bytes_layer.get(), test_layer.get());
  70    :  
  71  E :    EXPECT_FALSE(report.FindLayer(&typed_layer));
  72  E :  }
  73    :  
  74  E :  TEST(ProcessStateTest, FindSingleRecord) {
  75  E :    const size_t kThreadId = 42;
  76  E :    const AddressRange kRecordAddressRange(80ULL, 10U);
  77  E :    ProcessState report;
  78  E :    StackRecordPtr retrieved;
  79    :  
  80    :    // Empty report: returns false.
  81  E :    ASSERT_FALSE(report.FindSingleRecord(84ULL, &retrieved));
  82    :  
  83    :    // Add a stack record to the report.
  84  E :    StackRecordPtr created;
  85  E :    AddStackRecord(kRecordAddressRange, kThreadId, &report, &created);
  86    :  
  87    :    // Search for address outside record's range.
  88  E :    ASSERT_FALSE(report.FindSingleRecord(79ULL, &retrieved));
  89  E :    ASSERT_FALSE(report.FindSingleRecord(90ULL, &retrieved));
  90    :  
  91    :    // Search for address within record's range.
  92  E :    ASSERT_TRUE(report.FindSingleRecord(84ULL, &retrieved));
  93  E :    ASSERT_EQ(created.get(), retrieved.get());
  94  E :  }
  95    :  
  96  E :  TEST(ProcessStateTest, FindStackRecord) {
  97  E :    const size_t kThreadId = 42;
  98  E :    ProcessState report;
  99  E :    StackRecordPtr retrieved;
 100    :  
 101    :    // Report doesn't have a stack layer.
 102  E :    ASSERT_FALSE(report.FindStackRecord(kThreadId, &retrieved));
 103    :  
 104    :    // Report has an empty stack layer.
 105  E :    StackLayerPtr stack_layer;
 106  E :    report.FindOrCreateLayer(&stack_layer);
 107  E :    ASSERT_FALSE(report.FindStackRecord(kThreadId, &retrieved));
 108    :  
 109    :    // Add a stack record to the report.
 110  E :    StackRecordPtr created;
 111  E :    AddStackRecord(AddressRange(8000ULL, 80U), kThreadId, &report, &created);
 112    :  
 113    :    // Search for a non-existing thread id.
 114  E :    ASSERT_FALSE(report.FindStackRecord(kThreadId + 1, &retrieved));
 115    :  
 116    :    // Search for the existing thread id.
 117  E :    ASSERT_TRUE(report.FindStackRecord(kThreadId, &retrieved));
 118  E :    ASSERT_EQ(created.get(), retrieved.get());
 119  E :  }
 120    :  
 121  E :  TEST(ProcessStateTest, ExceptionBasics) {
 122  E :    const int kExceptingThreadId = 1;
 123  E :    const int kExceptionCode = 2;
 124  E :    Exception exception;
 125  E :    exception.set_thread_id(kExceptingThreadId);
 126  E :    exception.set_exception_code(kExceptionCode);
 127    :  
 128  E :    ProcessState state;
 129  E :    size_t retrieved_thread_id = 0;
 130    :  
 131    :    // Retrieving excepting thread id on an empty state fails.
 132  E :    ASSERT_FALSE(state.GetExceptingThreadId(&retrieved_thread_id));
 133  E :    retrieved_thread_id = 0;
 134    :  
 135    :    // Setting an exception fails when thread isn't in the state.
 136  E :    ASSERT_FALSE(state.SetException(exception));
 137    :  
 138    :    // Add a stack record to the report.
 139  E :    StackRecordPtr stack_record;
 140    :    AddStackRecord(AddressRange(8000ULL, 80U), kExceptingThreadId, &state,
 141  E :                   &stack_record);
 142    :  
 143    :    // Setting an exception succeeds.
 144  E :    ASSERT_TRUE(state.SetException(exception));
 145  E :    ASSERT_TRUE(stack_record->data().thread_info().has_exception());
 146    :    const Exception& retrieved_exception =
 147  E :        stack_record->data().thread_info().exception();
 148  E :    ASSERT_EQ(kExceptingThreadId, retrieved_exception.thread_id());
 149  E :    ASSERT_EQ(kExceptionCode, retrieved_exception.exception_code());
 150    :  
 151    :    // Retrieving the excepting thread id succeeds.
 152  E :    ASSERT_TRUE(state.GetExceptingThreadId(&retrieved_thread_id));
 153  E :    ASSERT_EQ(kExceptingThreadId, retrieved_thread_id);
 154    :  
 155    :    // Setting a second exception fails.
 156  E :    ASSERT_FALSE(state.SetException(exception));
 157  E :  }
 158    :  
 159  E :  TEST(ProcessStateTest, AddressRangeBasics) {
 160  E :    const Address kAddr = 0xCAFE0000ULL;
 161  E :    const Size kSize = 0xBABEU;
 162    :  
 163  E :    AddressRange valid_range(kAddr, kSize);
 164  E :    ASSERT_TRUE(valid_range.IsValid());
 165  E :    ASSERT_EQ(kAddr, valid_range.start());
 166  E :    ASSERT_EQ(kSize, valid_range.size());
 167  E :    ASSERT_EQ(kAddr, valid_range.start());
 168  E :    ASSERT_EQ(kAddr, valid_range.start());
 169  E :    ASSERT_EQ(0xCAFEBABEULL, valid_range.end());
 170    :  
 171  E :    AddressRange zero_range(kAddr, 0U);
 172  E :    ASSERT_FALSE(zero_range.IsValid());
 173    :  
 174  E :    AddressRange overflow_range(std::numeric_limits<Address>::max(), 1U);
 175  E :    ASSERT_FALSE(overflow_range.IsValid());
 176  E :  }
 177    :  
 178  E :  TEST(ProcessStateTest, CreateRecord) {
 179  E :    ProcessState report;
 180    :  
 181  E :    scoped_refptr<ProcessState::Layer<Bytes>> bytes_layer;
 182  E :    report.FindOrCreateLayer(&bytes_layer);
 183  E :    EXPECT_TRUE(bytes_layer != nullptr);
 184  E :    ASSERT_EQ(0, bytes_layer->size());
 185    :  
 186    :    // Add a record for a range of memory.
 187  E :    const Address kAddr = 0xCAFEBABEULL;
 188  E :    const Size kSize = 0xBABE;
 189  E :    scoped_refptr<ProcessState::Record<Bytes>> first_record;
 190  E :    bytes_layer->CreateRecord(AddressRange(kAddr, kSize), &first_record);
 191    :  
 192  E :    ASSERT_EQ(AddressRange(kAddr, kSize), first_record->range());
 193  E :    ASSERT_EQ(1, bytes_layer->size());
 194    :  
 195    :    // Add a second record for the same range.
 196  E :    scoped_refptr<ProcessState::Record<Bytes>> second_record;
 197  E :    bytes_layer->CreateRecord(AddressRange(kAddr, kSize), &second_record);
 198    :  
 199  E :    ASSERT_EQ(AddressRange(kAddr, kSize), second_record->range());
 200  E :    ASSERT_EQ(2, bytes_layer->size());
 201    :  
 202    :    // Verify that this produced two distinct objects.
 203  E :    ASSERT_NE(first_record.get(), second_record.get());
 204  E :  }
 205    :  
 206  E :  TEST(ProcessStateTest, GetRecordsAt) {
 207    :    // Create a report with a Bytes layer.
 208  E :    ProcessState report;
 209  E :    BytesLayerPtr bytes_layer;
 210  E :    report.FindOrCreateLayer(&bytes_layer);
 211  E :    EXPECT_TRUE(bytes_layer != nullptr);
 212  E :    ASSERT_EQ(0, bytes_layer->size());
 213    :  
 214    :    // Add a single record for basic testing.
 215  E :    BytesRecordPtr record;
 216  E :    bytes_layer->CreateRecord(AddressRange(80ULL, 16U), &record);
 217    :  
 218    :    // Get right before and right after - no match.
 219  E :    std::vector<BytesRecordPtr> matching_records;
 220  E :    bytes_layer->GetRecordsAt(79ULL, &matching_records);
 221  E :    ASSERT_EQ(0, matching_records.size());
 222  E :    bytes_layer->GetRecordsAt(81ULL, &matching_records);
 223  E :    ASSERT_EQ(0, matching_records.size());
 224    :  
 225    :    // Match.
 226  E :    bytes_layer->GetRecordsAt(80ULL, &matching_records);
 227  E :    ASSERT_EQ(1, matching_records.size());
 228  E :    ASSERT_EQ(record.get(), matching_records[0].get());
 229    :  
 230    :    // Add a second record. Match both.
 231  E :    matching_records.clear();
 232  E :    bytes_layer->CreateRecord(AddressRange(80ULL, 4U), &record);
 233  E :    bytes_layer->GetRecordsAt(80ULL, &matching_records);
 234  E :    ASSERT_EQ(2, matching_records.size());
 235  E :  }
 236    :  
 237  E :  TEST(ProcessStateTest, GetRecordsSpanningSingleRecord) {
 238    :    // Create a report with a Bytes layer.
 239  E :    ProcessState report;
 240  E :    BytesLayerPtr bytes_layer;
 241  E :    report.FindOrCreateLayer(&bytes_layer);
 242  E :    EXPECT_TRUE(bytes_layer != nullptr);
 243  E :    ASSERT_EQ(0, bytes_layer->size());
 244    :  
 245    :    // Add a single record for basic testing.
 246  E :    const Address kAddress = 80ULL;
 247  E :    const Size kSize = 16U;
 248  E :    BytesRecordPtr record;
 249  E :    bytes_layer->CreateRecord(AddressRange(kAddress, kSize), &record);
 250    :  
 251    :    // No match: requested region is outside.
 252  E :    std::vector<BytesRecordPtr> matching_records;
 253    :    bytes_layer->GetRecordsSpanning(AddressRange(73ULL, 5U),
 254  E :                                    &matching_records);
 255  E :    ASSERT_EQ(0, matching_records.size());
 256    :    bytes_layer->GetRecordsSpanning(AddressRange(96ULL, 3U),
 257  E :                                    &matching_records);
 258  E :    ASSERT_EQ(0, matching_records.size());
 259    :  
 260    :    // No match: requested region straddles.
 261    :    bytes_layer->GetRecordsSpanning(AddressRange(75ULL, 10U),
 262  E :                                    &matching_records);
 263  E :    ASSERT_EQ(0, matching_records.size());
 264    :  
 265    :    // No match: requested region is a superset.
 266    :    bytes_layer->GetRecordsSpanning(AddressRange(75ULL, 32U),
 267  E :                                    &matching_records);
 268  E :    ASSERT_EQ(0, matching_records.size());
 269    :  
 270    :    // Match: requested region is a subset.
 271    :    bytes_layer->GetRecordsSpanning(AddressRange(84ULL, 4U),
 272  E :                                    &matching_records);
 273    :    ValidateSingleRecordMatch(AddressRange(kAddress, kSize), matching_records,
 274  E :                              "Case: Requested region is a subset");
 275  E :    matching_records.clear();
 276    :  
 277    :    // Match: region is exact match.
 278    :    bytes_layer->GetRecordsSpanning(AddressRange(kAddress, kSize),
 279  E :                                    &matching_records);
 280    :    ValidateSingleRecordMatch(AddressRange(kAddress, kSize), matching_records,
 281  E :                              "Case: Requested region is exact match");
 282  E :  }
 283    :  
 284  E :  TEST(ProcessStateTest, GetRecordsSpanningMultipleRecords) {
 285    :    // Create a report with a Bytes layer.
 286  E :    ProcessState report;
 287  E :    BytesLayerPtr bytes_layer;
 288  E :    report.FindOrCreateLayer(&bytes_layer);
 289  E :    ASSERT_TRUE(bytes_layer != nullptr);
 290    :  
 291    :    // Add a few records (note the 2 records at the same address).
 292  E :    BytesRecordPtr record;
 293  E :    bytes_layer->CreateRecord(AddressRange(80ULL, 16U), &record);
 294  E :    bytes_layer->CreateRecord(AddressRange(75ULL, 25U), &record);
 295  E :    bytes_layer->CreateRecord(AddressRange(80ULL, 16U), &record);
 296    :  
 297    :    // Match a subset.
 298  E :    std::vector<BytesRecordPtr> matching_records;
 299    :    bytes_layer->GetRecordsSpanning(AddressRange(82ULL, 4U),
 300  E :                                    &matching_records);
 301  E :    ASSERT_EQ(3, matching_records.size());
 302  E :  }
 303    :  
 304  E :  TEST(ProcessStateTest, GetRecordsIntersectingSingleRecord) {
 305    :    // Create a report with a Bytes layer.
 306  E :    ProcessState report;
 307  E :    BytesLayerPtr bytes_layer;
 308  E :    report.FindOrCreateLayer(&bytes_layer);
 309  E :    EXPECT_TRUE(bytes_layer != nullptr);
 310  E :    ASSERT_EQ(0, bytes_layer->size());
 311    :  
 312    :    // Add a single record for basic testing.
 313  E :    const Address kAddress = 80ULL;
 314  E :    const Size kSize = 16U;
 315  E :    BytesRecordPtr record;
 316  E :    bytes_layer->CreateRecord(AddressRange(kAddress, kSize), &record);
 317    :  
 318    :    // No match: requested region is outside.
 319  E :    std::vector<BytesRecordPtr> matching_records;
 320    :    bytes_layer->GetRecordsIntersecting(AddressRange(73ULL, 5U),
 321  E :                                        &matching_records);
 322  E :    ASSERT_EQ(0, matching_records.size());
 323    :    bytes_layer->GetRecordsIntersecting(AddressRange(96ULL, 3U),
 324  E :                                        &matching_records);
 325  E :    ASSERT_EQ(0, matching_records.size());
 326    :  
 327    :    // No match: requested region is contiguous.
 328    :    bytes_layer->GetRecordsIntersecting(AddressRange(75ULL, 5U),
 329  E :                                        &matching_records);
 330  E :    ASSERT_EQ(0, matching_records.size());
 331    :    bytes_layer->GetRecordsIntersecting(AddressRange(96ULL, 3U),
 332  E :                                        &matching_records);
 333  E :    ASSERT_EQ(0, matching_records.size());
 334    :  
 335    :    // Match: requested region straddles.
 336    :    bytes_layer->GetRecordsIntersecting(AddressRange(75ULL, 10U),
 337  E :                                        &matching_records);
 338    :    ValidateSingleRecordMatch(AddressRange(kAddress, kSize), matching_records,
 339  E :                              "Case: Requested region straddles");
 340  E :    matching_records.clear();
 341    :  
 342    :    // Match: requested region is a superset.
 343    :    bytes_layer->GetRecordsIntersecting(AddressRange(75ULL, 32U),
 344  E :                                        &matching_records);
 345    :    ValidateSingleRecordMatch(AddressRange(kAddress, kSize), matching_records,
 346  E :                              "Case: Requested region is a superset");
 347  E :    matching_records.clear();
 348    :  
 349    :    // Match: requested region is a subset.
 350    :    bytes_layer->GetRecordsIntersecting(AddressRange(84ULL, 4U),
 351  E :                                        &matching_records);
 352    :    ValidateSingleRecordMatch(AddressRange(kAddress, kSize), matching_records,
 353  E :                              "Case: Requested region is a subset");
 354  E :    matching_records.clear();
 355    :  
 356    :    // Match: region is exact match.
 357    :    bytes_layer->GetRecordsIntersecting(AddressRange(kAddress, kSize),
 358  E :                                        &matching_records);
 359    :    ValidateSingleRecordMatch(AddressRange(kAddress, kSize), matching_records,
 360  E :                              "Case: Requested region is an exact match");
 361  E :    matching_records.clear();
 362  E :  }
 363    :  
 364  E :  TEST(ProcessStateTest, GetRecordsIntersectingMultipleRecords) {
 365    :    // Create a report with a Bytes layer.
 366  E :    ProcessState report;
 367  E :    BytesLayerPtr bytes_layer;
 368  E :    report.FindOrCreateLayer(&bytes_layer);
 369  E :    ASSERT_TRUE(bytes_layer != nullptr);
 370    :  
 371    :    // Add a few records.
 372  E :    BytesRecordPtr record;
 373  E :    bytes_layer->CreateRecord(AddressRange(80ULL, 16U), &record);
 374  E :    bytes_layer->CreateRecord(AddressRange(75ULL, 25U), &record);
 375    :    bytes_layer->CreateRecord(AddressRange(80ULL, 16U),
 376  E :                              &record);  // Second record at location.
 377    :  
 378    :    // Match a subset straddling region.
 379  E :    std::vector<BytesRecordPtr> matching_records;
 380    :    bytes_layer->GetRecordsIntersecting(AddressRange(78ULL, 4U),
 381  E :                                        &matching_records);
 382  E :    ASSERT_EQ(3, matching_records.size());
 383  E :  }
 384    :  
 385  E :  TEST(ProcessStateTest, RemoveRecord) {
 386    :    // Create a report that has a Bytes layer with a single record.
 387  E :    ProcessState report;
 388  E :    BytesLayerPtr bytes_layer;
 389  E :    report.FindOrCreateLayer(&bytes_layer);
 390  E :    ASSERT_TRUE(bytes_layer != nullptr);
 391    :  
 392  E :    const Address kAddress = 80ULL;
 393  E :    const Size kSize = 16U;
 394  E :    BytesRecordPtr record;
 395  E :    bytes_layer->CreateRecord(AddressRange(kAddress, kSize), &record);
 396  E :    ASSERT_EQ(1, bytes_layer->size());
 397    :  
 398    :    // Remove record.
 399  E :    ASSERT_TRUE(bytes_layer->RemoveRecord(record));
 400  E :    ASSERT_EQ(0, bytes_layer->size());
 401    :  
 402    :    // Removing a second time fails.
 403  E :    ASSERT_FALSE(bytes_layer->RemoveRecord(record));
 404  E :  }
 405    :  
 406  E :  TEST(ProcessStateTest, LayerIteration) {
 407    :    // Create a report that has a Bytes layer with few records.
 408  E :    ProcessState report;
 409  E :    BytesLayerPtr bytes_layer;
 410  E :    report.FindOrCreateLayer(&bytes_layer);
 411  E :    ASSERT_TRUE(bytes_layer != nullptr);
 412    :  
 413  E :    BytesRecordPtr record;
 414  E :    bytes_layer->CreateRecord(AddressRange(80ULL, 4U), &record);
 415  E :    bytes_layer->CreateRecord(AddressRange(84ULL, 4U), &record);
 416  E :    bytes_layer->CreateRecord(AddressRange(88ULL, 4U), &record);
 417    :  
 418    :    // Manual iteration.
 419    :    // Note: for ease of testing, this test relies on the iterator returning
 420    :    // records by ascending address. However, this is not in the contract.
 421  E :    ProcessState::Layer<Bytes>::Iterator it = bytes_layer->begin();
 422  E :    ASSERT_EQ(80ULL, (*it)->range().start());
 423  E :    ++it;
 424  E :    ASSERT_EQ(84ULL, (*it)->range().start());
 425  E :    ++it;
 426  E :    ASSERT_EQ(88ULL, (*it)->range().start());
 427  E :    ++it;
 428  E :    ASSERT_EQ(bytes_layer->end(), it);
 429    :  
 430    :    // Range based for loop.
 431  E :    int record_count = 0;
 432  E :    for (BytesRecordPtr rec : *bytes_layer) {
 433  E :      ++record_count;
 434  E :    }
 435  E :    ASSERT_EQ(3, record_count);
 436  E :  }
 437    :  
 438    :  class ProcessStateBitSourceTest : public testing::Test {
 439    :   protected:
 440  E :    void SetUp() override {
 441    :      // Populate the process state with a single Bytes record at address_,
 442    :      // containing data_.
 443    :  
 444  E :      address_ = 80ULL;
 445  E :      data_ = "0123456789";
 446    :  
 447    :      // Note: range doesn't include trailing '\0'.
 448  E :      AddressRange record_range(address_, data_.size());
 449    :  
 450  E :      BytesLayerPtr bytes_layer;
 451  E :      process_state_.FindOrCreateLayer(&bytes_layer);
 452  E :      BytesRecordPtr bytes_record;
 453  E :      bytes_layer->CreateRecord(record_range, &bytes_record);
 454  E :      *bytes_record->mutable_data()->mutable_data() = data_;
 455  E :    }
 456    :  
 457  E :    Address address() { return address_; }
 458  E :    const std::string& data() { return data_; }
 459    :  
 460    :    void PerformGetFromTest(AddressRange requested,
 461    :                            size_t expected_cnt,
 462    :                            bool bytes_requested,
 463  E :                            const std::string& expected_bytes) {
 464  E :      size_t retrieved_cnt = 0U;
 465  E :      scoped_ptr<char> buffer(new char[data().size()]);
 466  E :      memset(buffer.get(), 0, data().size());
 467    :  
 468  E :      ASSERT_TRUE(
 469    :          process_state_.GetFrom(requested, &retrieved_cnt, buffer.get()));
 470    :  
 471  E :      ASSERT_EQ(expected_cnt, retrieved_cnt);
 472  E :      if (bytes_requested)
 473  E :        ASSERT_EQ(expected_bytes, std::string(buffer.get(), retrieved_cnt));
 474  E :    }
 475    :  
 476    :    ProcessState process_state_;
 477    :  
 478    :   private:
 479    :    Address address_;
 480    :    std::string data_;
 481    :  };
 482    :  
 483  E :  TEST_F(ProcessStateBitSourceTest, GetAll) {
 484  E :    char retrieved = '-';
 485    :  
 486    :    // Fail to retrieve data that is not fully in the process state.
 487  E :    AddressRange desired_range = AddressRange(address() - 1, data().size());
 488  E :    ASSERT_FALSE(process_state_.GetAll(desired_range, &retrieved));
 489    :  
 490    :    // Successfully retrieve data that is in the process state.
 491  E :    retrieved = '-';
 492  E :    ASSERT_TRUE(process_state_.GetAll(AddressRange(address(), 1U), &retrieved));
 493  E :    ASSERT_EQ(data()[0], retrieved);
 494  E :  }
 495    :  
 496  E :  TEST_F(ProcessStateBitSourceTest, GetFrom) {
 497  E :    size_t retrieved_cnt = 0U;
 498  E :    scoped_ptr<char> buffer(new char[data().size()]);
 499    :  
 500    :    // Fail to retrieve when the head is outside existing data.
 501  E :    AddressRange desired(address() - 1U, data().size());
 502  E :    ASSERT_FALSE(process_state_.GetFrom(desired, &retrieved_cnt, nullptr));
 503  E :    desired = AddressRange(address() + data().size(), 1U);
 504  E :    ASSERT_FALSE(process_state_.GetFrom(desired, &retrieved_cnt, buffer.get()));
 505    :  
 506    :    // Successful full retrieval - not asking for data.
 507  E :    desired = AddressRange(address() + 1, data().size() - 1);
 508  E :    PerformGetFromTest(desired, data().size() - 1, false, "");
 509    :  
 510    :    // Successful partial retrieval - not asking for data.
 511  E :    desired = AddressRange(address() + 1, data().size());
 512  E :    PerformGetFromTest(desired, data().size() - 1, false, "");
 513    :  
 514    :    // Successful full retrieval - asking for data.
 515  E :    std::string expected_bytes = data().substr(1, data().size() - 1);
 516  E :    desired = AddressRange(address() + 1, data().size() - 1);
 517  E :    PerformGetFromTest(desired, data().size() - 1, true, expected_bytes);
 518    :  
 519    :    // Successful partial retrieval - asking for data.
 520  E :    desired = AddressRange(address() + 1, data().size());
 521  E :    PerformGetFromTest(desired, data().size() - 1, true, expected_bytes);
 522  E :  }
 523    :  
 524    :  }  // namespace refinery

Coverage information generated Thu Jan 14 17:40:38 2016.