OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Crashpad Authors. 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 "util/net/http_body.h" |
| 16 |
| 17 #include "base/memory/scoped_ptr.h" |
| 18 #include "gtest/gtest.h" |
| 19 |
| 20 namespace crashpad { |
| 21 namespace test { |
| 22 namespace { |
| 23 |
| 24 void ExpectBufferSet(const uint8_t* actual, |
| 25 uint8_t expected_byte, |
| 26 size_t num_expected_bytes) { |
| 27 for (size_t i = 0; i < num_expected_bytes; ++i) { |
| 28 EXPECT_EQ(expected_byte, actual[i]) << i; |
| 29 } |
| 30 } |
| 31 |
| 32 TEST(StringHTTPBodyStream, EmptyString) { |
| 33 uint8_t buf[32]; |
| 34 memset(buf, '!', sizeof(buf)); |
| 35 |
| 36 std::string empty_string; |
| 37 StringHTTPBodyStream stream(empty_string); |
| 38 EXPECT_EQ(0, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 39 ExpectBufferSet(buf, '!', sizeof(buf)); |
| 40 } |
| 41 |
| 42 TEST(StringHTTPBodyStream, SmallString) { |
| 43 uint8_t buf[32]; |
| 44 memset(buf, '!', sizeof(buf)); |
| 45 |
| 46 std::string string("Hello, world"); |
| 47 StringHTTPBodyStream stream(string); |
| 48 EXPECT_EQ(static_cast<ssize_t>(string.length()), |
| 49 stream.GetBytesBuffer(buf, sizeof(buf))); |
| 50 |
| 51 std::string actual(reinterpret_cast<const char*>(buf), string.length()); |
| 52 EXPECT_EQ(string, actual); |
| 53 ExpectBufferSet(buf + string.length(), '!', sizeof(buf) - string.length()); |
| 54 |
| 55 EXPECT_EQ(0, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 56 } |
| 57 |
| 58 TEST(StringHTTPBodyStream, MultipleReads) { |
| 59 uint8_t buf[2]; |
| 60 memset(buf, '!', sizeof(buf)); |
| 61 |
| 62 { |
| 63 std::string string("test"); |
| 64 SCOPED_TRACE("aligned buffer boundary"); |
| 65 |
| 66 StringHTTPBodyStream stream(string); |
| 67 EXPECT_EQ(2, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 68 EXPECT_EQ('t', buf[0]); |
| 69 EXPECT_EQ('e', buf[1]); |
| 70 EXPECT_EQ(2, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 71 EXPECT_EQ('s', buf[0]); |
| 72 EXPECT_EQ('t', buf[1]); |
| 73 EXPECT_EQ(0, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 74 EXPECT_EQ('s', buf[0]); |
| 75 EXPECT_EQ('t', buf[1]); |
| 76 } |
| 77 |
| 78 { |
| 79 std::string string("abc"); |
| 80 SCOPED_TRACE("unaligned buffer boundary"); |
| 81 |
| 82 StringHTTPBodyStream stream(string); |
| 83 EXPECT_EQ(2, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 84 EXPECT_EQ('a', buf[0]); |
| 85 EXPECT_EQ('b', buf[1]); |
| 86 EXPECT_EQ(1, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 87 EXPECT_EQ('c', buf[0]); |
| 88 EXPECT_EQ('b', buf[1]); // Unmodified from last read. |
| 89 EXPECT_EQ(0, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 90 EXPECT_EQ('c', buf[0]); |
| 91 EXPECT_EQ('b', buf[1]); |
| 92 } |
| 93 } |
| 94 |
| 95 std::string ReadStreamToString(HTTPBodyStream* stream, size_t buffer_size) { |
| 96 scoped_ptr<uint8_t[]> buf(new uint8_t[buffer_size]); |
| 97 std::string result; |
| 98 |
| 99 ssize_t bytes_read; |
| 100 while ((bytes_read = stream->GetBytesBuffer(buf.get(), buffer_size)) != 0) { |
| 101 if (bytes_read < 0) { |
| 102 ADD_FAILURE() << "Failed to read from stream: " << bytes_read; |
| 103 return std::string(); |
| 104 } |
| 105 |
| 106 result.append(reinterpret_cast<char*>(buf.get()), bytes_read); |
| 107 } |
| 108 |
| 109 return result; |
| 110 } |
| 111 |
| 112 TEST(FileHTTPBodyStream, ReadASCIIFile) { |
| 113 // TODO(rsesek): Use a more robust mechanism to locate testdata |
| 114 // <https://code.google.com/p/crashpad/issues/detail?id=4>. |
| 115 base::FilePath path = base::FilePath("util/net/testdata/ascii_http_body.txt"); |
| 116 FileHTTPBodyStream stream(path); |
| 117 std::string contents = ReadStreamToString(&stream, 32); |
| 118 EXPECT_EQ("This is a test.\n", contents); |
| 119 |
| 120 // Make sure that the file is not read again after it has been read to |
| 121 // completion. |
| 122 uint8_t buf[8]; |
| 123 memset(buf, '!', sizeof(buf)); |
| 124 EXPECT_EQ(0, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 125 ExpectBufferSet(buf, '!', sizeof(buf)); |
| 126 EXPECT_EQ(0, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 127 ExpectBufferSet(buf, '!', sizeof(buf)); |
| 128 } |
| 129 |
| 130 TEST(FileHTTPBodyStream, ReadBinaryFile) { |
| 131 // HEX contents of file: |FEEDFACE A11A15|. |
| 132 // TODO(rsesek): Use a more robust mechanism to locate testdata |
| 133 // <https://code.google.com/p/crashpad/issues/detail?id=4>. |
| 134 base::FilePath path = |
| 135 base::FilePath("util/net/testdata/binary_http_body.dat"); |
| 136 // This buffer size was chosen so that reading the file takes multiple reads. |
| 137 uint8_t buf[4]; |
| 138 |
| 139 FileHTTPBodyStream stream(path); |
| 140 |
| 141 memset(buf, '!', sizeof(buf)); |
| 142 EXPECT_EQ(4, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 143 EXPECT_EQ(0xfe, buf[0]); |
| 144 EXPECT_EQ(0xed, buf[1]); |
| 145 EXPECT_EQ(0xfa, buf[2]); |
| 146 EXPECT_EQ(0xce, buf[3]); |
| 147 |
| 148 memset(buf, '!', sizeof(buf)); |
| 149 EXPECT_EQ(3, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 150 EXPECT_EQ(0xa1, buf[0]); |
| 151 EXPECT_EQ(0x1a, buf[1]); |
| 152 EXPECT_EQ(0x15, buf[2]); |
| 153 EXPECT_EQ('!', buf[3]); |
| 154 |
| 155 memset(buf, '!', sizeof(buf)); |
| 156 EXPECT_EQ(0, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 157 ExpectBufferSet(buf, '!', sizeof(buf)); |
| 158 EXPECT_EQ(0, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 159 ExpectBufferSet(buf, '!', sizeof(buf)); |
| 160 } |
| 161 |
| 162 TEST(FileHTTPBodyStream, NonExistentFile) { |
| 163 base::FilePath path = |
| 164 base::FilePath("/var/empty/crashpad/util/net/http_body/null"); |
| 165 FileHTTPBodyStream stream(path); |
| 166 |
| 167 uint8_t buf = 0xff; |
| 168 EXPECT_LT(stream.GetBytesBuffer(&buf, 1), 0); |
| 169 EXPECT_EQ(0xff, buf); |
| 170 EXPECT_LT(stream.GetBytesBuffer(&buf, 1), 0); |
| 171 EXPECT_EQ(0xff, buf); |
| 172 } |
| 173 |
| 174 TEST(CompositeHTTPBodyStream, TwoEmptyStrings) { |
| 175 std::vector<HTTPBodyStream*> parts; |
| 176 parts.push_back(new StringHTTPBodyStream(std::string())); |
| 177 parts.push_back(new StringHTTPBodyStream(std::string())); |
| 178 |
| 179 CompositeHTTPBodyStream stream(parts); |
| 180 |
| 181 uint8_t buf[5]; |
| 182 memset(buf, '!', sizeof(buf)); |
| 183 EXPECT_EQ(0, stream.GetBytesBuffer(buf, sizeof(buf))); |
| 184 ExpectBufferSet(buf, '!', sizeof(buf)); |
| 185 } |
| 186 |
| 187 class CompositeHTTPBodyStreamBufferSize |
| 188 : public testing::TestWithParam<size_t> { |
| 189 }; |
| 190 |
| 191 TEST_P(CompositeHTTPBodyStreamBufferSize, ThreeStringParts) { |
| 192 std::string string1("crashpad"); |
| 193 std::string string2("test"); |
| 194 std::string string3("foobar"); |
| 195 const size_t all_strings_length = string1.length() + string2.length() + |
| 196 string3.length(); |
| 197 uint8_t buf[all_strings_length + 3]; |
| 198 memset(buf, '!', sizeof(buf)); |
| 199 |
| 200 std::vector<HTTPBodyStream*> parts; |
| 201 parts.push_back(new StringHTTPBodyStream(string1)); |
| 202 parts.push_back(new StringHTTPBodyStream(string2)); |
| 203 parts.push_back(new StringHTTPBodyStream(string3)); |
| 204 |
| 205 CompositeHTTPBodyStream stream(parts); |
| 206 |
| 207 std::string actual_string = ReadStreamToString(&stream, GetParam()); |
| 208 EXPECT_EQ(string1 + string2 + string3, actual_string); |
| 209 |
| 210 ExpectBufferSet(buf + all_strings_length, '!', |
| 211 sizeof(buf) - all_strings_length); |
| 212 } |
| 213 |
| 214 TEST_P(CompositeHTTPBodyStreamBufferSize, StringsAndFile) { |
| 215 std::string string1("Hello! "); |
| 216 std::string string2(" Goodbye :)"); |
| 217 |
| 218 std::vector<HTTPBodyStream*> parts; |
| 219 parts.push_back(new StringHTTPBodyStream(string1)); |
| 220 parts.push_back(new FileHTTPBodyStream( |
| 221 base::FilePath("util/net/testdata/ascii_http_body.txt"))); |
| 222 parts.push_back(new StringHTTPBodyStream(string2)); |
| 223 |
| 224 CompositeHTTPBodyStream stream(parts); |
| 225 |
| 226 std::string expected_string = string1 + "This is a test.\n" + string2; |
| 227 std::string actual_string = ReadStreamToString(&stream, GetParam()); |
| 228 EXPECT_EQ(expected_string, actual_string); |
| 229 } |
| 230 |
| 231 INSTANTIATE_TEST_CASE_P(VariableBufferSize, |
| 232 CompositeHTTPBodyStreamBufferSize, |
| 233 testing::Values(1, 2, 9, 16, 31, 128)); |
| 234 |
| 235 } // namespace |
| 236 } // namespace test |
| 237 } // namespace crashpad |
OLD | NEW |