Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: net/spdy/spdy_test_util.cc

Issue 2881001: Cleaning up SPDY unit tests (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Undo mode changes Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/spdy/spdy_test_util.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 "net/spdy/spdy_test_util.h"
6
7 #include "base/basictypes.h"
8 #include "base/string_util.h"
9
10 namespace net {
11
12 // Chop a frame into an array of MockWrites.
13 // |data| is the frame to chop.
14 // |length| is the length of the frame to chop.
15 // |num_chunks| is the number of chunks to create.
16 MockWrite* ChopFrame(const char* data, int length, int num_chunks) {
17 MockWrite* chunks = new MockWrite[num_chunks];
18 int chunk_size = length / num_chunks;
19 for (int index = 0; index < num_chunks; index++) {
20 const char* ptr = data + (index * chunk_size);
21 if (index == num_chunks - 1)
22 chunk_size += length % chunk_size; // The last chunk takes the remainder.
23 chunks[index] = MockWrite(true, ptr, chunk_size);
24 }
25 return chunks;
26 }
27
28 // Chop a SpdyFrame into an array of MockWrites.
29 // |frame| is the frame to chop.
30 // |num_chunks| is the number of chunks to create.
31 MockWrite* ChopFrame(const spdy::SpdyFrame* frame, int num_chunks) {
32 return ChopFrame(frame->data(),
33 frame->length() + spdy::SpdyFrame::size(),
34 num_chunks);
35 }
36
37 // Adds headers and values to a map.
38 // |extra_headers| is an array of { name, value } pairs, arranged as strings
39 // where the even entries are the header names, and the odd entries are the
40 // header values.
41 // |headers| gets filled in from |extra_headers|.
42 void AppendHeadersToSpdyFrame(const char* const extra_headers[],
43 int extra_header_count,
44 spdy::SpdyHeaderBlock* headers) {
45 std::string this_header;
46 std::string this_value;
47
48 if (!extra_header_count)
49 return;
50
51 // Sanity check: Non-NULL header list.
52 DCHECK(NULL != extra_headers) << "NULL header value pair list";
53 // Sanity check: Non-NULL header map.
54 DCHECK(NULL != headers) << "NULL header map";
55 // Copy in the headers.
56 for (int i = 0; i < extra_header_count; i++) {
57 // Sanity check: Non-empty header.
58 DCHECK_NE('\0', *extra_headers[i * 2]) << "Empty header value pair";
59 this_header = extra_headers[i * 2];
60 std::string::size_type header_len = this_header.length();
61 if (!header_len)
62 continue;
63 this_value = extra_headers[1 + (i * 2)];
64 std::string new_value;
65 if (headers->find(this_header) != headers->end()) {
66 // More than one entry in the header.
67 // Don't add the header again, just the append to the value,
68 // separated by a NULL character.
69
70 // Adjust the value.
71 new_value = (*headers)[this_header];
72 // Put in a NULL separator.
73 new_value.append(1, '\0');
74 // Append the new value.
75 new_value += this_value;
76 } else {
77 // Not a duplicate, just write the value.
78 new_value = this_value;
79 }
80 (*headers)[this_header] = new_value;
81 }
82 }
83
84 // Writes |val| to a location of size |len|, in big-endian format.
85 // in the buffer pointed to by |buffer_handle|.
86 // Updates the |*buffer_handle| pointer by |len|
87 // Returns the number of bytes written
88 int AppendToBuffer(int val,
89 int len,
90 unsigned char** buffer_handle,
91 int* buffer_len_remaining) {
92 if (len <= 0)
93 return 0;
94 DCHECK((size_t) len <= sizeof(len)) << "Data length too long for data type";
95 DCHECK(NULL != buffer_handle) << "NULL buffer handle";
96 DCHECK(NULL != *buffer_handle) << "NULL pointer";
97 DCHECK(NULL != buffer_len_remaining)
98 << "NULL buffer remainder length pointer";
99 DCHECK_GE(*buffer_len_remaining, len) << "Insufficient buffer size";
100 for (int i = 0; i < len; i++) {
101 int shift = (8 * (len - (i + 1)));
102 unsigned char val_chunk = (val >> shift) & 0x0FF;
103 *(*buffer_handle)++ = val_chunk;
104 *buffer_len_remaining += 1;
105 }
106 return len;
107 }
108
109 // Construct a SPDY packet.
110 // |head| is the start of the packet, up to but not including
111 // the header value pairs.
112 // |extra_headers| are the extra header-value pairs, which typically
113 // will vary the most between calls.
114 // |tail| is any (relatively constant) header-value pairs to add.
115 // |buffer| is the buffer we're filling in.
116 // Returns a SpdyFrame.
117 spdy::SpdyFrame* ConstructSpdyPacket(const SpdyHeaderInfo* header_info,
118 const char* const extra_headers[],
119 int extra_header_count,
120 const char* const tail[],
121 int tail_header_count) {
122 spdy::SpdyFramer framer;
123 spdy::SpdyHeaderBlock headers;
124 // Copy in the extra headers to our map.
125 AppendHeadersToSpdyFrame(extra_headers, extra_header_count, &headers);
126 // Copy in the tail headers to our map.
127 if (tail && tail_header_count)
128 AppendHeadersToSpdyFrame(tail, tail_header_count, &headers);
129 spdy::SpdyFrame* frame = NULL;
130 switch (header_info->kind) {
131 case spdy::SYN_STREAM:
132 frame = framer.CreateSynStream(header_info->id, header_info->assoc_id,
133 header_info->priority,
134 header_info->control_flags,
135 header_info->compressed, &headers);
136 break;
137 case spdy::SYN_REPLY:
138 frame = framer.CreateSynReply(header_info->id, header_info->control_flags,
139 header_info->compressed, &headers);
140 break;
141 case spdy::RST_STREAM:
142 frame = framer.CreateRstStream(header_info->id, header_info->status);
143 break;
144 default:
145 frame = framer.CreateDataFrame(header_info->id, header_info->data,
146 header_info->data_length,
147 header_info->data_flags);
148 break;
149 }
150 return frame;
151 }
152
153 // Construct an expected SPDY SETTINGS frame.
154 // |settings| are the settings to set.
155 // Returns the constructed frame. The caller takes ownership of the frame.
156 spdy::SpdyFrame* ConstructSpdySettings(spdy::SpdySettings settings) {
157 spdy::SpdyFramer framer;
158 return framer.CreateSettings(settings);
159 }
160
161 // Construct a single SPDY header entry, for validation.
162 // |extra_headers| are the extra header-value pairs.
163 // |buffer| is the buffer we're filling in.
164 // |index| is the index of the header we want.
165 // Returns the number of bytes written into |buffer|.
166 int ConstructSpdyHeader(const char* const extra_headers[],
167 int extra_header_count,
168 char* buffer,
169 int buffer_length,
170 int index) {
171 const char* this_header = NULL;
172 const char* this_value = NULL;
173 if (!buffer || !buffer_length)
174 return 0;
175 *buffer = '\0';
176 // Sanity check: Non-empty header list.
177 DCHECK(NULL != extra_headers) << "NULL extra headers pointer";
178 // Sanity check: Index out of range.
179 DCHECK((index >= 0) && (index < extra_header_count))
180 << "Index " << index
181 << " out of range [0, " << extra_header_count << ")";
182 this_header = extra_headers[index * 2];
183 // Sanity check: Non-empty header.
184 if (!*this_header)
185 return 0;
186 std::string::size_type header_len = strlen(this_header);
187 if (!header_len)
188 return 0;
189 this_value = extra_headers[1 + (index * 2)];
190 // Sanity check: Non-empty value.
191 if (!*this_value)
192 this_value = "";
193 int n = base::snprintf(buffer,
194 buffer_length,
195 "%s: %s\r\n",
196 this_header,
197 this_value);
198 return n;
199 }
200
201 // Constructs a standard SPDY GET packet.
202 // |extra_headers| are the extra header-value pairs, which typically
203 // will vary the most between calls.
204 // Returns a SpdyFrame.
205 spdy::SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
206 int extra_header_count) {
207 SpdyHeaderInfo SynStartHeader = {
208 spdy::SYN_STREAM, // Kind = Syn
209 1, // Stream ID
210 0, // Associated stream ID
211 SPDY_PRIORITY_LOWEST, // Priority
212 spdy::CONTROL_FLAG_FIN, // Control Flags
213 false, // Compressed
214 spdy::INVALID, // Status
215 NULL, // Data
216 0, // Length
217 spdy::DATA_FLAG_NONE // Data Flags
218 };
219 static const char* const kStandardGetHeaders[] = {
220 "method",
221 "GET",
222 "url",
223 "http://www.google.com/",
224 "version",
225 "HTTP/1.1"
226 };
227 return ConstructSpdyPacket(
228 &SynStartHeader,
229 extra_headers,
230 extra_header_count,
231 kStandardGetHeaders,
232 arraysize(kStandardGetHeaders) / 2);
233 }
234
235 // Constructs a standard SPDY SYN_REPLY packet to match the SPDY GET.
236 // |extra_headers| are the extra header-value pairs, which typically
237 // will vary the most between calls.
238 // Returns a SpdyFrame.
239 spdy::SpdyFrame* ConstructSpdyGetSynReply(const char* const extra_headers[],
240 int extra_header_count) {
241 SpdyHeaderInfo SynStartHeader = {
242 spdy::SYN_REPLY, // Kind = SynReply
243 1, // Stream ID
244 0, // Associated stream ID
245 SPDY_PRIORITY_LOWEST, // Priority
246 spdy::CONTROL_FLAG_NONE, // Control Flags
247 false, // Compressed
248 spdy::INVALID, // Status
249 NULL, // Data
250 0, // Length
251 spdy::DATA_FLAG_NONE // Data Flags
252 };
253 static const char* const kStandardGetHeaders[] = {
254 "hello",
255 "bye",
256 "status",
257 "200",
258 "url",
259 "/index.php",
260 "version",
261 "HTTP/1.1"
262 };
263 return ConstructSpdyPacket(
264 &SynStartHeader,
265 extra_headers,
266 extra_header_count,
267 kStandardGetHeaders,
268 arraysize(kStandardGetHeaders) / 2);
269 }
270
271 // Construct an expected SPDY reply string.
272 // |extra_headers| are the extra header-value pairs, which typically
273 // will vary the most between calls.
274 // |buffer| is the buffer we're filling in.
275 // Returns the number of bytes written into |buffer|.
276 int ConstructSpdyReplyString(const char* const extra_headers[],
277 int extra_header_count,
278 char* buffer,
279 int buffer_length) {
280 int packet_size = 0;
281 int header_count = 0;
282 char* buffer_write = buffer;
283 int buffer_left = buffer_length;
284 spdy::SpdyHeaderBlock headers;
285 if (!buffer || !buffer_length)
286 return 0;
287 // Copy in the extra headers.
288 AppendHeadersToSpdyFrame(extra_headers, extra_header_count, &headers);
289 header_count = headers.size();
290 // The iterator gets us the list of header/value pairs in sorted order.
291 spdy::SpdyHeaderBlock::iterator next = headers.begin();
292 spdy::SpdyHeaderBlock::iterator last = headers.end();
293 for ( ; next != last; ++next) {
294 // Write the header.
295 int value_len, current_len, offset;
296 const char* header_string = next->first.c_str();
297 packet_size += AppendToBuffer(header_string,
298 next->first.length(),
299 &buffer_write,
300 &buffer_left);
301 packet_size += AppendToBuffer(": ",
302 strlen(": "),
303 &buffer_write,
304 &buffer_left);
305 // Write the value(s).
306 const char* value_string = next->second.c_str();
307 // Check if it's split among two or more values.
308 value_len = next->second.length();
309 current_len = strlen(value_string);
310 offset = 0;
311 // Handle the first N-1 values.
312 while (current_len < value_len) {
313 // Finish this line -- write the current value.
314 packet_size += AppendToBuffer(value_string + offset,
315 current_len - offset,
316 &buffer_write,
317 &buffer_left);
318 packet_size += AppendToBuffer("\n",
319 strlen("\n"),
320 &buffer_write,
321 &buffer_left);
322 // Advance to next value.
323 offset = current_len + 1;
324 current_len += 1 + strlen(value_string + offset);
325 // Start another line -- add the header again.
326 packet_size += AppendToBuffer(header_string,
327 next->first.length(),
328 &buffer_write,
329 &buffer_left);
330 packet_size += AppendToBuffer(": ",
331 strlen(": "),
332 &buffer_write,
333 &buffer_left);
334 }
335 EXPECT_EQ(value_len, current_len);
336 // Copy the last (or only) value.
337 packet_size += AppendToBuffer(value_string + offset,
338 value_len - offset,
339 &buffer_write,
340 &buffer_left);
341 packet_size += AppendToBuffer("\n",
342 strlen("\n"),
343 &buffer_write,
344 &buffer_left);
345 }
346 return packet_size;
347 }
348
349 // Create a MockWrite from the given SpdyFrame.
350 MockWrite CreateMockWrite(spdy::SpdyFrame* req) {
351 return MockWrite(
352 true, req->data(), req->length() + spdy::SpdyFrame::size());
353 }
354
355 // Create a MockRead from the given SpdyFrame.
356 MockRead CreateMockRead(spdy::SpdyFrame* resp) {
357 return MockRead(
358 true, resp->data(), resp->length() + spdy::SpdyFrame::size());
359 }
360
361 // Create a MockRead from the given SpdyFrame and sequence number.
362 MockRead CreateMockRead(spdy::SpdyFrame* resp, int seq) {
363 return MockRead(
364 true, resp->data(), resp->length() + spdy::SpdyFrame::size(), seq);
365 }
366
367 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_test_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698