]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | ||
20 | #include <boost/test/auto_unit_test.hpp> | |
21 | #include <iostream> | |
22 | #include <climits> | |
23 | #include <vector> | |
24 | #include <thrift/protocol/TBinaryProtocol.h> | |
25 | #include <memory> | |
26 | #include <thrift/transport/TBufferTransports.h> | |
27 | #include "gen-cpp/ThriftTest_types.h" | |
28 | ||
29 | BOOST_AUTO_TEST_SUITE(TMemoryBufferTest) | |
30 | ||
31 | using apache::thrift::protocol::TBinaryProtocol; | |
32 | using apache::thrift::transport::TMemoryBuffer; | |
33 | using apache::thrift::transport::TTransportException; | |
34 | using std::shared_ptr; | |
35 | using std::cout; | |
36 | using std::endl; | |
37 | using std::string; | |
38 | ||
39 | BOOST_AUTO_TEST_CASE(test_read_write_grow) { | |
40 | // Added to test the fix for THRIFT-1248 | |
41 | TMemoryBuffer uut; | |
42 | const int maxSize = 65536; | |
43 | uint8_t verify[maxSize]; | |
44 | std::vector<uint8_t> buf; | |
45 | buf.resize(maxSize); | |
46 | ||
47 | for (uint32_t i = 0; i < maxSize; ++i) { | |
48 | buf[i] = static_cast<uint8_t>(i); | |
49 | } | |
50 | ||
51 | for (uint32_t i = 1; i < maxSize; i *= 2) { | |
52 | uut.write(&buf[0], i); | |
53 | } | |
54 | ||
55 | for (uint32_t i = 1; i < maxSize; i *= 2) { | |
56 | uut.read(verify, i); | |
57 | BOOST_CHECK_EQUAL(0, ::memcmp(verify, &buf[0], i)); | |
58 | } | |
59 | } | |
60 | ||
61 | BOOST_AUTO_TEST_CASE(test_roundtrip) { | |
62 | shared_ptr<TMemoryBuffer> strBuffer(new TMemoryBuffer()); | |
63 | shared_ptr<TBinaryProtocol> binaryProtcol(new TBinaryProtocol(strBuffer)); | |
64 | ||
65 | thrift::test::Xtruct a; | |
66 | a.i32_thing = 10; | |
67 | a.i64_thing = 30; | |
68 | a.string_thing = "holla back a"; | |
69 | ||
70 | a.write(binaryProtcol.get()); | |
71 | std::string serialized = strBuffer->getBufferAsString(); | |
72 | ||
73 | shared_ptr<TMemoryBuffer> strBuffer2(new TMemoryBuffer()); | |
74 | shared_ptr<TBinaryProtocol> binaryProtcol2(new TBinaryProtocol(strBuffer2)); | |
75 | ||
76 | strBuffer2->resetBuffer((uint8_t*)serialized.data(), static_cast<uint32_t>(serialized.length())); | |
77 | thrift::test::Xtruct a2; | |
78 | a2.read(binaryProtcol2.get()); | |
79 | ||
80 | BOOST_CHECK(a == a2); | |
81 | } | |
82 | ||
83 | BOOST_AUTO_TEST_CASE(test_readAppendToString) { | |
84 | string str1 = "abcd1234"; | |
85 | TMemoryBuffer buf((uint8_t*)str1.data(), | |
86 | static_cast<uint32_t>(str1.length()), | |
87 | TMemoryBuffer::COPY); | |
88 | ||
89 | string str3 = "wxyz", str4 = "6789"; | |
90 | buf.readAppendToString(str3, 4); | |
91 | buf.readAppendToString(str4, INT_MAX); | |
92 | ||
93 | BOOST_CHECK(str3 == "wxyzabcd"); | |
94 | BOOST_CHECK(str4 == "67891234"); | |
95 | } | |
96 | ||
97 | BOOST_AUTO_TEST_CASE(test_exceptions) { | |
98 | char data[] = "foo\0bar"; | |
99 | ||
100 | TMemoryBuffer buf1((uint8_t*)data, 7, TMemoryBuffer::OBSERVE); | |
101 | string str = buf1.getBufferAsString(); | |
102 | BOOST_CHECK(str.length() == 7); | |
103 | ||
104 | buf1.resetBuffer(); | |
105 | ||
106 | BOOST_CHECK_THROW(buf1.write((const uint8_t*)"foo", 3), TTransportException); | |
107 | ||
108 | TMemoryBuffer buf2((uint8_t*)data, 7, TMemoryBuffer::COPY); | |
109 | BOOST_CHECK_NO_THROW(buf2.write((const uint8_t*)"bar", 3)); | |
110 | } | |
111 | ||
112 | BOOST_AUTO_TEST_CASE(test_default_maximum_buffer_size) | |
113 | { | |
114 | BOOST_CHECK_EQUAL((std::numeric_limits<uint32_t>::max)(), TMemoryBuffer().getMaxBufferSize()); | |
115 | } | |
116 | ||
117 | BOOST_AUTO_TEST_CASE(test_default_buffer_size) | |
118 | { | |
119 | BOOST_CHECK_EQUAL(1024, TMemoryBuffer().getBufferSize()); | |
120 | } | |
121 | ||
122 | BOOST_AUTO_TEST_CASE(test_error_set_max_buffer_size_too_small) | |
123 | { | |
124 | TMemoryBuffer buf; | |
125 | BOOST_CHECK_THROW(buf.setMaxBufferSize(buf.getBufferSize() - 1), TTransportException); | |
126 | } | |
127 | ||
128 | BOOST_AUTO_TEST_CASE(test_maximum_buffer_size) | |
129 | { | |
130 | TMemoryBuffer buf; | |
131 | buf.setMaxBufferSize(8192); | |
132 | std::vector<uint8_t> small_buff(1); | |
133 | ||
134 | for (size_t i = 0; i < 8192; ++i) | |
135 | { | |
136 | buf.write(&small_buff[0], 1); | |
137 | } | |
138 | ||
139 | BOOST_CHECK_THROW(buf.write(&small_buff[0], 1), TTransportException); | |
140 | } | |
141 | ||
142 | BOOST_AUTO_TEST_CASE(test_memory_buffer_to_get_sizeof_objects) | |
143 | { | |
144 | // This is a demonstration of how to use TMemoryBuffer to determine | |
145 | // the serialized size of a thrift object in the Binary protocol. | |
146 | // See THRIFT-3480 | |
147 | ||
148 | shared_ptr<TMemoryBuffer> memBuffer(new TMemoryBuffer()); | |
149 | shared_ptr<TBinaryProtocol> binaryProtcol(new TBinaryProtocol(memBuffer)); | |
150 | ||
151 | thrift::test::Xtruct object; | |
152 | object.i32_thing = 10; | |
153 | object.i64_thing = 30; | |
154 | object.string_thing = "who's your daddy?"; | |
155 | ||
156 | uint32_t size = object.write(binaryProtcol.get()); | |
157 | BOOST_CHECK_EQUAL(47, size); | |
158 | } | |
159 | ||
160 | BOOST_AUTO_TEST_SUITE_END() |