1// Copyright (c) 2009 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 "flip_protocol.h"
6
7#include "base/scoped_ptr.h"
8#include "net/flip/flip_bitmasks.h"
9#include "net/flip/flip_framer.h"
10#include "testing/platform_test.h"
11
12using flip::FlipDataFrame;
13using flip::FlipFrame;
14using flip::FlipControlFrame;
15using flip::FlipSynStreamControlFrame;
16using flip::FlipSynReplyControlFrame;
17using flip::FlipFinStreamControlFrame;
18using flip::FlipFramer;
19using flip::FlipHeaderBlock;
20using flip::FlagsAndLength;
21using flip::kLengthMask;
22using flip::kStreamIdMask;
23using flip::kFlipProtocolVersion;
24using flip::SYN_STREAM;
25using flip::SYN_REPLY;
26using flip::FIN_STREAM;
27using flip::CONTROL_FLAG_FIN;
28using flip::CONTROL_FLAG_NONE;
29
30namespace {
31
32// Test our protocol constants
33TEST(FlipProtocolTest, ProtocolConstants) {
34  EXPECT_EQ(8u, FlipFrame::size());
35  EXPECT_EQ(8u, FlipDataFrame::size());
36  EXPECT_EQ(12u, FlipControlFrame::size());
37  EXPECT_EQ(14u, FlipSynStreamControlFrame::size());
38  EXPECT_EQ(14u, FlipSynReplyControlFrame::size());
39  EXPECT_EQ(16u, FlipFinStreamControlFrame::size());
40  EXPECT_EQ(4u, sizeof(FlagsAndLength));
41  EXPECT_EQ(1, SYN_STREAM);
42  EXPECT_EQ(2, SYN_REPLY);
43  EXPECT_EQ(3, FIN_STREAM);
44}
45
46// Test some of the protocol helper functions
47TEST(FlipProtocolTest, FrameStructs) {
48  FlipFrame frame(FlipFrame::size());
49  frame.set_length(12345);
50  frame.set_flags(10);
51  EXPECT_EQ(12345u, frame.length());
52  EXPECT_EQ(10u, frame.flags());
53  EXPECT_EQ(false, frame.is_control_frame());
54
55  frame.set_length(0);
56  frame.set_flags(10);
57  EXPECT_EQ(0u, frame.length());
58  EXPECT_EQ(10u, frame.flags());
59  EXPECT_EQ(false, frame.is_control_frame());
60}
61
62TEST(FlipProtocolTest, DataFrameStructs) {
63  FlipDataFrame data_frame;
64  data_frame.set_stream_id(12345);
65  EXPECT_EQ(12345u, data_frame.stream_id());
66}
67
68TEST(FlipProtocolTest, ControlFrameStructs) {
69  FlipFramer framer;
70  FlipHeaderBlock headers;
71
72  scoped_ptr<FlipSynStreamControlFrame> syn_frame(
73      framer.CreateSynStream(123, 2, CONTROL_FLAG_FIN, false, &headers));
74  EXPECT_EQ(kFlipProtocolVersion, syn_frame->version());
75  EXPECT_EQ(true, syn_frame->is_control_frame());
76  EXPECT_EQ(SYN_STREAM, syn_frame->type());
77  EXPECT_EQ(123u, syn_frame->stream_id());
78  EXPECT_EQ(2u, syn_frame->priority());
79  EXPECT_EQ(2, syn_frame->header_block_len());
80  EXPECT_EQ(1u, syn_frame->flags());
81
82  scoped_ptr<FlipSynReplyControlFrame> syn_reply(
83      framer.CreateSynReply(123, CONTROL_FLAG_NONE, false, &headers));
84  EXPECT_EQ(kFlipProtocolVersion, syn_reply->version());
85  EXPECT_EQ(true, syn_reply->is_control_frame());
86  EXPECT_EQ(SYN_REPLY, syn_reply->type());
87  EXPECT_EQ(123u, syn_reply->stream_id());
88  EXPECT_EQ(2, syn_reply->header_block_len());
89  EXPECT_EQ(0, syn_reply->flags());
90
91  scoped_ptr<FlipFinStreamControlFrame> fin_frame(
92      framer.CreateFinStream(123, 444));
93  EXPECT_EQ(kFlipProtocolVersion, fin_frame->version());
94  EXPECT_EQ(true, fin_frame->is_control_frame());
95  EXPECT_EQ(FIN_STREAM, fin_frame->type());
96  EXPECT_EQ(123u, fin_frame->stream_id());
97  EXPECT_EQ(444u, fin_frame->status());
98  fin_frame->set_status(555);
99  EXPECT_EQ(555u, fin_frame->status());
100  EXPECT_EQ(0, fin_frame->flags());
101}
102
103TEST(FlipProtocolTest, TestDataFrame) {
104  FlipDataFrame frame;
105
106  // Set the stream ID to various values.
107  frame.set_stream_id(0);
108  EXPECT_EQ(0u, frame.stream_id());
109  EXPECT_FALSE(frame.is_control_frame());
110  frame.set_stream_id(~0 & kStreamIdMask);
111  EXPECT_EQ(~0 & kStreamIdMask, frame.stream_id());
112  EXPECT_FALSE(frame.is_control_frame());
113
114  // Set length to various values.  Make sure that when you set_length(x),
115  // length() == x.  Also make sure the flags are unaltered.
116  memset(frame.data(), '1', FlipDataFrame::size());
117  int8 flags = frame.flags();
118  frame.set_length(0);
119  EXPECT_EQ(0u, frame.length());
120  EXPECT_EQ(flags, frame.flags());
121  frame.set_length(kLengthMask);
122  EXPECT_EQ(kLengthMask, frame.length());
123  EXPECT_EQ(flags, frame.flags());
124  frame.set_length(5u);
125  EXPECT_EQ(5u, frame.length());
126  EXPECT_EQ(flags, frame.flags());
127
128  // Set flags to various values.  Make sure that when you set_flags(x),
129  // flags() == x.  Also make sure the length is unaltered.
130  memset(frame.data(), '1', FlipDataFrame::size());
131  uint32 length = frame.length();
132  frame.set_flags(0);
133  EXPECT_EQ(0u, frame.flags());
134  EXPECT_EQ(length, frame.length());
135  int8 all_flags = ~0;
136  frame.set_flags(all_flags);
137  flags = frame.flags();
138  EXPECT_EQ(all_flags, flags);
139  EXPECT_EQ(length, frame.length());
140  frame.set_flags(5u);
141  EXPECT_EQ(5u, frame.flags());
142  EXPECT_EQ(length, frame.length());
143}
144
145// Make sure that overflows both die in debug mode, and do not cause problems
146// in opt mode.  Note:  Chrome doesn't die on DCHECK failures, so the
147// EXPECT_DEBUG_DEATH doesn't work.
148TEST(FlipProtocolDeathTest, TestDataFrame) {
149  FlipDataFrame frame;
150
151  frame.set_stream_id(0);
152#ifndef WIN32
153  EXPECT_DEBUG_DEATH(frame.set_stream_id(~0), "");
154#endif
155  EXPECT_FALSE(frame.is_control_frame());
156
157  frame.set_flags(0);
158#ifndef WIN32
159  EXPECT_DEBUG_DEATH(frame.set_length(~0), "");
160#endif
161  EXPECT_EQ(0, frame.flags());
162}
163
164TEST(FlipProtocolDeathTest, TestFlipControlFrame) {
165  FlipControlFrame frame(FlipControlFrame::size());
166  memset(frame.data(), '1', FlipControlFrame::size());
167
168  // Set the stream ID to various values.
169  frame.set_stream_id(0);
170  EXPECT_EQ(0u, frame.stream_id());
171  EXPECT_FALSE(frame.is_control_frame());
172  frame.set_stream_id(~0 & kStreamIdMask);
173  EXPECT_EQ(~0 & kStreamIdMask, frame.stream_id());
174  EXPECT_FALSE(frame.is_control_frame());
175}
176
177}  // namespace
178
179