OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <vector> |
| 6 |
| 7 #include "base/basictypes.h" |
| 8 #include "chrome/test/logging/win/mof_data_parser.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 |
| 11 // A test fixture for Mof parser tests. |
| 12 class MofDataParserTest : public ::testing::Test { |
| 13 protected: |
| 14 EVENT_TRACE* MakeEventWithDataOfSize(size_t size); |
| 15 template<typename T> EVENT_TRACE* MakeEventWithBlittedValue(T value) { |
| 16 EVENT_TRACE* event = MakeEventWithDataOfSize(sizeof(value)); |
| 17 *reinterpret_cast<T*>(event->MofData) = value; |
| 18 return event; |
| 19 } |
| 20 EVENT_TRACE* MakeEventWithDWORD(DWORD value); |
| 21 EVENT_TRACE* MakeEventWithPointerArray(const void* const* pointers, |
| 22 DWORD size); |
| 23 EVENT_TRACE* MakeEventWithString(const char* a_string, size_t length); |
| 24 |
| 25 std::vector<uint8> buffer_; |
| 26 }; |
| 27 |
| 28 EVENT_TRACE* MofDataParserTest::MakeEventWithDataOfSize(size_t size) { |
| 29 buffer_.assign(sizeof(EVENT_TRACE) + size, 0); |
| 30 EVENT_TRACE* event = reinterpret_cast<EVENT_TRACE*>(&buffer_[0]); |
| 31 event->MofLength = size; |
| 32 event->MofData = &buffer_[sizeof(EVENT_TRACE)]; |
| 33 return event; |
| 34 } |
| 35 |
| 36 EVENT_TRACE* MofDataParserTest::MakeEventWithDWORD(DWORD value) { |
| 37 return MakeEventWithBlittedValue(value); |
| 38 } |
| 39 |
| 40 EVENT_TRACE* MofDataParserTest::MakeEventWithPointerArray( |
| 41 const void* const* pointers, |
| 42 DWORD size) { |
| 43 EVENT_TRACE* event = |
| 44 MakeEventWithDataOfSize(sizeof(DWORD) + sizeof(*pointers) * size); |
| 45 *reinterpret_cast<DWORD*>(event->MofData) = size; |
| 46 ::memcpy(reinterpret_cast<DWORD*>(event->MofData) + 1, pointers, |
| 47 sizeof(*pointers) * size); |
| 48 return event; |
| 49 } |
| 50 |
| 51 // |length| is the number of bytes to put in (i.e., include the terminator if |
| 52 // you want one). |
| 53 EVENT_TRACE* MofDataParserTest::MakeEventWithString(const char* a_string, |
| 54 size_t length) { |
| 55 EVENT_TRACE* event = MakeEventWithDataOfSize(length); |
| 56 ::memcpy(event->MofData, a_string, length); |
| 57 return event; |
| 58 } |
| 59 |
| 60 // Tests reading a primitive value. ReadDWORD, ReadInt, and ReadPointer share |
| 61 // the same implementation, so this test covers all three. |
| 62 TEST_F(MofDataParserTest, ReadPrimitive) { |
| 63 |
| 64 // Read a valid DWORD. |
| 65 EVENT_TRACE* event = MakeEventWithDWORD(5); |
| 66 { |
| 67 DWORD value = 0; |
| 68 logging_win::MofDataParser parser(event); |
| 69 EXPECT_FALSE(parser.empty()); |
| 70 EXPECT_TRUE(parser.ReadDWORD(&value)); |
| 71 EXPECT_EQ(5UL, value); |
| 72 EXPECT_TRUE(parser.empty()); |
| 73 } |
| 74 |
| 75 // Try again if there's insufficient data. |
| 76 --(event->MofLength); |
| 77 { |
| 78 DWORD value = 0; |
| 79 logging_win::MofDataParser parser(event); |
| 80 EXPECT_FALSE(parser.empty()); |
| 81 EXPECT_FALSE(parser.ReadDWORD(&value)); |
| 82 EXPECT_EQ(0UL, value); |
| 83 } |
| 84 } |
| 85 |
| 86 // Tests reading an array of pointer-sized values. These arrays are encoded by |
| 87 // writing a DWORD item count followed by the items. |
| 88 TEST_F(MofDataParserTest, ReadPointerArray) { |
| 89 const void* const pointers[] = { this, &buffer_ }; |
| 90 const DWORD array_size = arraysize(pointers); |
| 91 |
| 92 // Read a valid array of two pointers. |
| 93 EVENT_TRACE* event = MakeEventWithPointerArray(&pointers[0], array_size); |
| 94 { |
| 95 DWORD size = 0; |
| 96 const intptr_t* values = NULL; |
| 97 |
| 98 logging_win::MofDataParser parser(event); |
| 99 EXPECT_FALSE(parser.empty()); |
| 100 EXPECT_TRUE(parser.ReadDWORD(&size)); |
| 101 EXPECT_EQ(array_size, size); |
| 102 EXPECT_TRUE(parser.ReadPointerArray(size, &values)); |
| 103 EXPECT_EQ(0, ::memcmp(&pointers[0], values, sizeof(*values) * size)); |
| 104 EXPECT_TRUE(parser.empty()); |
| 105 } |
| 106 |
| 107 // Try again if there's insufficient data. |
| 108 --(event->MofLength); |
| 109 { |
| 110 DWORD size = 0; |
| 111 const intptr_t* values = NULL; |
| 112 |
| 113 logging_win::MofDataParser parser(event); |
| 114 EXPECT_FALSE(parser.empty()); |
| 115 EXPECT_TRUE(parser.ReadDWORD(&size)); |
| 116 EXPECT_EQ(array_size, size); |
| 117 EXPECT_FALSE(parser.ReadPointerArray(size, &values)); |
| 118 EXPECT_FALSE(parser.empty()); |
| 119 } |
| 120 } |
| 121 |
| 122 // Tests reading a structure. |
| 123 TEST_F(MofDataParserTest, ReadStructure) { |
| 124 struct Spam { |
| 125 int blorf; |
| 126 char spiffy; |
| 127 }; |
| 128 const Spam canned_meat = { 47, 'Y' }; |
| 129 |
| 130 // Read a pointer to a structure. |
| 131 EVENT_TRACE* event = MakeEventWithBlittedValue(canned_meat); |
| 132 { |
| 133 const Spam* value = NULL; |
| 134 logging_win::MofDataParser parser(event); |
| 135 EXPECT_FALSE(parser.empty()); |
| 136 EXPECT_TRUE(parser.ReadStructure(&value)); |
| 137 EXPECT_EQ(canned_meat.blorf, value->blorf); |
| 138 EXPECT_EQ(canned_meat.spiffy, value->spiffy); |
| 139 EXPECT_TRUE(parser.empty()); |
| 140 } |
| 141 |
| 142 // Try again if there's insufficient data. |
| 143 --(event->MofLength); |
| 144 { |
| 145 const Spam* value = NULL; |
| 146 logging_win::MofDataParser parser(event); |
| 147 EXPECT_FALSE(parser.empty()); |
| 148 EXPECT_FALSE(parser.ReadStructure(&value)); |
| 149 EXPECT_FALSE(parser.empty()); |
| 150 } |
| 151 } |
| 152 |
| 153 // Tests reading null-terminated string. |
| 154 TEST_F(MofDataParserTest, ReadString) { |
| 155 const char a_string_nl[] = "sometimes i get lost in my own thoughts.\n"; |
| 156 const char a_string[] = "sometimes i get lost in my own thoughts."; |
| 157 |
| 158 // Read a string with a trailing newline. |
| 159 EVENT_TRACE* event = |
| 160 MakeEventWithString(a_string_nl, arraysize(a_string_nl)); |
| 161 { |
| 162 base::StringPiece value; |
| 163 logging_win::MofDataParser parser(event); |
| 164 EXPECT_FALSE(parser.empty()); |
| 165 EXPECT_TRUE(parser.ReadString(&value)); |
| 166 EXPECT_EQ(base::StringPiece(&a_string_nl[0], arraysize(a_string_nl) - 2), |
| 167 value); |
| 168 EXPECT_TRUE(parser.empty()); |
| 169 } |
| 170 |
| 171 // Read a string without a trailing newline. |
| 172 event = MakeEventWithString(a_string, arraysize(a_string)); |
| 173 { |
| 174 base::StringPiece value; |
| 175 logging_win::MofDataParser parser(event); |
| 176 EXPECT_FALSE(parser.empty()); |
| 177 EXPECT_TRUE(parser.ReadString(&value)); |
| 178 EXPECT_EQ(base::StringPiece(&a_string[0], arraysize(a_string) - 1), value); |
| 179 EXPECT_TRUE(parser.empty()); |
| 180 } |
| 181 |
| 182 // Try a string that isn't terminated. |
| 183 event = MakeEventWithString(a_string, arraysize(a_string) - 1); |
| 184 { |
| 185 base::StringPiece value; |
| 186 logging_win::MofDataParser parser(event); |
| 187 EXPECT_FALSE(parser.empty()); |
| 188 EXPECT_FALSE(parser.ReadString(&value)); |
| 189 EXPECT_FALSE(parser.empty()); |
| 190 } |
| 191 } |
OLD | NEW |