root/chrome/test/logging/win/mof_data_parser_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. MakeEventWithBlittedValue
  2. MakeEventWithDataOfSize
  3. MakeEventWithDWORD
  4. MakeEventWithPointerArray
  5. MakeEventWithString
  6. TEST_F
  7. TEST_F
  8. TEST_F
  9. TEST_F

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <vector>

#include "base/basictypes.h"
#include "chrome/test/logging/win/mof_data_parser.h"
#include "testing/gtest/include/gtest/gtest.h"

// A test fixture for Mof parser tests.
class MofDataParserTest : public ::testing::Test {
 protected:
  EVENT_TRACE* MakeEventWithDataOfSize(size_t size);
  template<typename T> EVENT_TRACE* MakeEventWithBlittedValue(T value) {
    EVENT_TRACE* event = MakeEventWithDataOfSize(sizeof(value));
    *reinterpret_cast<T*>(event->MofData) = value;
    return event;
  }
  EVENT_TRACE* MakeEventWithDWORD(DWORD value);
  EVENT_TRACE* MakeEventWithPointerArray(const void* const* pointers,
                                         DWORD size);
  EVENT_TRACE* MakeEventWithString(const char* a_string, size_t length);

  std::vector<uint8> buffer_;
};

EVENT_TRACE* MofDataParserTest::MakeEventWithDataOfSize(size_t size) {
  buffer_.assign(sizeof(EVENT_TRACE) + size, 0);
  EVENT_TRACE* event = reinterpret_cast<EVENT_TRACE*>(&buffer_[0]);
  event->MofLength = size;
  event->MofData = &buffer_[sizeof(EVENT_TRACE)];
  return event;
}

EVENT_TRACE* MofDataParserTest::MakeEventWithDWORD(DWORD value) {
  return MakeEventWithBlittedValue(value);
}

EVENT_TRACE* MofDataParserTest::MakeEventWithPointerArray(
    const void* const* pointers,
    DWORD size) {
  EVENT_TRACE* event =
      MakeEventWithDataOfSize(sizeof(DWORD) + sizeof(*pointers) * size);
  *reinterpret_cast<DWORD*>(event->MofData) = size;
  ::memcpy(reinterpret_cast<DWORD*>(event->MofData) + 1, pointers,
           sizeof(*pointers) * size);
  return event;
}

// |length| is the number of bytes to put in (i.e., include the terminator if
// you want one).
EVENT_TRACE* MofDataParserTest::MakeEventWithString(const char* a_string,
                                                    size_t length) {
  EVENT_TRACE* event = MakeEventWithDataOfSize(length);
  ::memcpy(event->MofData, a_string, length);
  return event;
}

// Tests reading a primitive value.  ReadDWORD, ReadInt, and ReadPointer share
// the same implementation, so this test covers all three.
TEST_F(MofDataParserTest, ReadPrimitive) {

  // Read a valid DWORD.
  EVENT_TRACE* event = MakeEventWithDWORD(5);
  {
    DWORD value = 0;
    logging_win::MofDataParser parser(event);
    EXPECT_FALSE(parser.empty());
    EXPECT_TRUE(parser.ReadDWORD(&value));
    EXPECT_EQ(5UL, value);
    EXPECT_TRUE(parser.empty());
  }

  // Try again if there's insufficient data.
  --(event->MofLength);
  {
    DWORD value = 0;
    logging_win::MofDataParser parser(event);
    EXPECT_FALSE(parser.empty());
    EXPECT_FALSE(parser.ReadDWORD(&value));
    EXPECT_EQ(0UL, value);
  }
}

// Tests reading an array of pointer-sized values.  These arrays are encoded by
// writing a DWORD item count followed by the items.
TEST_F(MofDataParserTest, ReadPointerArray) {
  const void* const pointers[] = { this, &buffer_ };
  const DWORD array_size = arraysize(pointers);

  // Read a valid array of two pointers.
  EVENT_TRACE* event = MakeEventWithPointerArray(&pointers[0], array_size);
  {
    DWORD size = 0;
    const intptr_t* values = NULL;

    logging_win::MofDataParser parser(event);
    EXPECT_FALSE(parser.empty());
    EXPECT_TRUE(parser.ReadDWORD(&size));
    EXPECT_EQ(array_size, size);
    EXPECT_TRUE(parser.ReadPointerArray(size, &values));
    EXPECT_EQ(0, ::memcmp(&pointers[0], values, sizeof(*values) * size));
    EXPECT_TRUE(parser.empty());
  }

  // Try again if there's insufficient data.
  --(event->MofLength);
  {
    DWORD size = 0;
    const intptr_t* values = NULL;

    logging_win::MofDataParser parser(event);
    EXPECT_FALSE(parser.empty());
    EXPECT_TRUE(parser.ReadDWORD(&size));
    EXPECT_EQ(array_size, size);
    EXPECT_FALSE(parser.ReadPointerArray(size, &values));
    EXPECT_FALSE(parser.empty());
  }
}

// Tests reading a structure.
TEST_F(MofDataParserTest, ReadStructure) {
  struct Spam {
    int blorf;
    char spiffy;
  };
  const Spam canned_meat = { 47, 'Y' };

  // Read a pointer to a structure.
  EVENT_TRACE* event = MakeEventWithBlittedValue(canned_meat);
  {
    const Spam* value = NULL;
    logging_win::MofDataParser parser(event);
    EXPECT_FALSE(parser.empty());
    EXPECT_TRUE(parser.ReadStructure(&value));
    EXPECT_EQ(canned_meat.blorf, value->blorf);
    EXPECT_EQ(canned_meat.spiffy, value->spiffy);
    EXPECT_TRUE(parser.empty());
  }

  // Try again if there's insufficient data.
  --(event->MofLength);
  {
    const Spam* value = NULL;
    logging_win::MofDataParser parser(event);
    EXPECT_FALSE(parser.empty());
    EXPECT_FALSE(parser.ReadStructure(&value));
    EXPECT_FALSE(parser.empty());
  }
}

// Tests reading null-terminated string.
TEST_F(MofDataParserTest, ReadString) {
  const char a_string_nl[] = "sometimes i get lost in my own thoughts.\n";
  const char a_string[] = "sometimes i get lost in my own thoughts.";

  // Read a string with a trailing newline.
  EVENT_TRACE* event =
      MakeEventWithString(a_string_nl, arraysize(a_string_nl));
  {
    base::StringPiece value;
    logging_win::MofDataParser parser(event);
    EXPECT_FALSE(parser.empty());
    EXPECT_TRUE(parser.ReadString(&value));
    EXPECT_EQ(base::StringPiece(&a_string_nl[0], arraysize(a_string_nl) - 2),
              value);
    EXPECT_TRUE(parser.empty());
  }

  // Read a string without a trailing newline.
  event = MakeEventWithString(a_string, arraysize(a_string));
  {
    base::StringPiece value;
    logging_win::MofDataParser parser(event);
    EXPECT_FALSE(parser.empty());
    EXPECT_TRUE(parser.ReadString(&value));
    EXPECT_EQ(base::StringPiece(&a_string[0], arraysize(a_string) - 1), value);
    EXPECT_TRUE(parser.empty());
  }

  // Try a string that isn't terminated.
  event = MakeEventWithString(a_string, arraysize(a_string) - 1);
  {
    base::StringPiece value;
    logging_win::MofDataParser parser(event);
    EXPECT_FALSE(parser.empty());
    EXPECT_FALSE(parser.ReadString(&value));
    EXPECT_FALSE(parser.empty());
  }
}

/* [<][>][^][v][top][bottom][index][help] */