Handle account removal correctly on all platforms.
[chromium-blink-merge.git] / gpu / command_buffer / service / cmd_parser_test.cc
blobd880830f661c23edc4f3bf10001c14fa7f5d16ed
1 // Copyright (c) 2011 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.
5 // Tests for the command parser.
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "gpu/command_buffer/service/cmd_parser.h"
10 #include "gpu/command_buffer/service/mocks.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 namespace gpu {
15 using testing::_;
16 using testing::Invoke;
17 using testing::Mock;
18 using testing::Return;
19 using testing::Sequence;
20 using testing::SetArgPointee;
21 using testing::Truly;
23 // Test fixture for CommandParser test - Creates a mock AsyncAPIInterface, and
24 // a fixed size memory buffer. Also provides a simple API to create a
25 // CommandParser.
26 class CommandParserTest : public testing::Test {
27 protected:
28 virtual void SetUp() {
29 api_mock_.reset(new AsyncAPIMock(false));
30 buffer_entry_count_ = 20;
31 buffer_.reset(new CommandBufferEntry[buffer_entry_count_]);
33 virtual void TearDown() {}
35 void AddDoCommandsExpect(error::Error _return,
36 unsigned int num_commands,
37 int num_entries,
38 int num_processed) {
39 EXPECT_CALL(*api_mock_, DoCommands(num_commands, _, num_entries, _))
40 .InSequence(sequence_)
41 .WillOnce(DoAll(SetArgPointee<3>(num_processed), Return(_return)));
44 // Creates a parser, with a buffer of the specified size (in entries).
45 CommandParser *MakeParser(unsigned int entry_count) {
46 size_t shm_size = buffer_entry_count_ *
47 sizeof(CommandBufferEntry); // NOLINT
48 size_t command_buffer_size = entry_count *
49 sizeof(CommandBufferEntry); // NOLINT
50 DCHECK_LE(command_buffer_size, shm_size);
51 CommandParser* parser = new CommandParser(api_mock());
53 parser->SetBuffer(buffer(), shm_size, 0, command_buffer_size);
54 return parser;
57 unsigned int buffer_entry_count() { return 20; }
58 AsyncAPIMock *api_mock() { return api_mock_.get(); }
59 CommandBufferEntry *buffer() { return buffer_.get(); }
60 private:
61 unsigned int buffer_entry_count_;
62 scoped_ptr<AsyncAPIMock> api_mock_;
63 scoped_ptr<CommandBufferEntry[]> buffer_;
64 Sequence sequence_;
67 // Tests initialization conditions.
68 TEST_F(CommandParserTest, TestInit) {
69 scoped_ptr<CommandParser> parser(MakeParser(10));
70 EXPECT_EQ(0, parser->get());
71 EXPECT_EQ(0, parser->put());
72 EXPECT_TRUE(parser->IsEmpty());
75 // Tests simple commands.
76 TEST_F(CommandParserTest, TestSimple) {
77 scoped_ptr<CommandParser> parser(MakeParser(10));
78 CommandBufferOffset put = parser->put();
79 CommandHeader header;
81 // add a single command, no args
82 header.size = 1;
83 header.command = 123;
84 buffer()[put++].value_header = header;
85 parser->set_put(put);
86 EXPECT_EQ(put, parser->put());
88 AddDoCommandsExpect(error::kNoError, 1, 1, 1);
89 EXPECT_EQ(error::kNoError, parser->ProcessCommands(1));
90 EXPECT_EQ(put, parser->get());
91 Mock::VerifyAndClearExpectations(api_mock());
93 // add a single command, 2 args
94 header.size = 3;
95 header.command = 456;
96 buffer()[put++].value_header = header;
97 buffer()[put++].value_int32 = 2134;
98 buffer()[put++].value_float = 1.f;
99 parser->set_put(put);
100 EXPECT_EQ(put, parser->put());
102 AddDoCommandsExpect(error::kNoError, 1, 3, 3);
103 EXPECT_EQ(error::kNoError, parser->ProcessCommands(1));
104 EXPECT_EQ(put, parser->get());
105 Mock::VerifyAndClearExpectations(api_mock());
108 // Tests having multiple commands in the buffer.
109 TEST_F(CommandParserTest, TestMultipleCommands) {
110 scoped_ptr<CommandParser> parser(MakeParser(10));
111 CommandBufferOffset put = parser->put();
112 CommandHeader header;
114 // add 2 commands, test with single ProcessCommands()
115 header.size = 2;
116 header.command = 789;
117 buffer()[put++].value_header = header;
118 buffer()[put++].value_int32 = 5151;
120 CommandBufferOffset put_cmd2 = put;
121 header.size = 2;
122 header.command = 876;
123 buffer()[put++].value_header = header;
124 buffer()[put++].value_int32 = 3434;
125 parser->set_put(put);
126 EXPECT_EQ(put, parser->put());
128 // Process up to 1 command. 4 entries remaining.
129 AddDoCommandsExpect(error::kNoError, 1, 4, 2);
130 EXPECT_EQ(error::kNoError, parser->ProcessCommands(1));
131 EXPECT_EQ(put_cmd2, parser->get());
133 // Process up to 1 command. 2 entries remaining.
134 AddDoCommandsExpect(error::kNoError, 1, 2, 2);
135 EXPECT_EQ(error::kNoError, parser->ProcessCommands(1));
136 EXPECT_EQ(put, parser->get());
137 Mock::VerifyAndClearExpectations(api_mock());
139 // add 2 commands again, test with ProcessAllCommands()
140 header.size = 2;
141 header.command = 123;
142 buffer()[put++].value_header = header;
143 buffer()[put++].value_int32 = 5656;
145 header.size = 2;
146 header.command = 321;
147 buffer()[put++].value_header = header;
148 buffer()[put++].value_int32 = 7878;
149 parser->set_put(put);
150 EXPECT_EQ(put, parser->put());
152 // 4 entries remaining.
153 AddDoCommandsExpect(
154 error::kNoError, CommandParser::kParseCommandsSlice, 4, 4);
155 EXPECT_EQ(error::kNoError, parser->ProcessAllCommands());
156 EXPECT_EQ(put, parser->get());
157 Mock::VerifyAndClearExpectations(api_mock());
160 // Tests that the parser will wrap correctly at the end of the buffer.
161 TEST_F(CommandParserTest, TestWrap) {
162 scoped_ptr<CommandParser> parser(MakeParser(5));
163 CommandBufferOffset put = parser->put();
164 CommandHeader header;
166 // add 3 commands with no args (1 word each)
167 for (unsigned int i = 0; i < 3; ++i) {
168 header.size = 1;
169 header.command = i;
170 buffer()[put++].value_header = header;
172 parser->set_put(put);
173 EXPECT_EQ(put, parser->put());
175 // Process up to 10 commands. 3 entries remaining to put.
176 AddDoCommandsExpect(error::kNoError, 10, 3, 3);
177 EXPECT_EQ(error::kNoError, parser->ProcessCommands(10));
178 EXPECT_EQ(put, parser->get());
179 Mock::VerifyAndClearExpectations(api_mock());
181 // add 1 command with 1 arg (2 words). That should put us at the end of the
182 // buffer.
183 header.size = 2;
184 header.command = 3;
185 buffer()[put++].value_header = header;
186 buffer()[put++].value_int32 = 5;
188 DCHECK_EQ(5, put);
189 put = 0;
191 // add 1 command with 1 arg (2 words).
192 header.size = 2;
193 header.command = 4;
194 buffer()[put++].value_header = header;
195 buffer()[put++].value_int32 = 6;
197 // 2 entries remaining to end of buffer.
198 AddDoCommandsExpect(
199 error::kNoError, CommandParser::kParseCommandsSlice, 2, 2);
200 // 2 entries remaining to put.
201 AddDoCommandsExpect(
202 error::kNoError, CommandParser::kParseCommandsSlice, 2, 2);
203 parser->set_put(put);
204 EXPECT_EQ(put, parser->put());
206 EXPECT_EQ(error::kNoError, parser->ProcessAllCommands());
207 EXPECT_EQ(put, parser->get());
208 Mock::VerifyAndClearExpectations(api_mock());
211 // Tests error conditions.
212 TEST_F(CommandParserTest, TestError) {
213 const unsigned int kNumEntries = 5;
214 scoped_ptr<CommandParser> parser(MakeParser(kNumEntries));
215 CommandBufferOffset put = parser->put();
216 CommandHeader header;
218 EXPECT_FALSE(parser->set_get(-1));
219 EXPECT_FALSE(parser->set_get(kNumEntries));
221 // Generate a command with size 0.
222 header.size = 0;
223 header.command = 3;
224 buffer()[put++].value_header = header;
226 parser->set_put(put);
227 EXPECT_EQ(put, parser->put());
229 AddDoCommandsExpect(
230 error::kInvalidSize, CommandParser::kParseCommandsSlice, 1, 0);
231 EXPECT_EQ(error::kInvalidSize,
232 parser->ProcessAllCommands());
233 // check that no DoCommand call was made.
234 Mock::VerifyAndClearExpectations(api_mock());
236 parser.reset(MakeParser(5));
237 put = parser->put();
239 // Generate a command with size 6, extends beyond the end of the buffer.
240 header.size = 6;
241 header.command = 3;
242 buffer()[put++].value_header = header;
244 parser->set_put(put);
245 EXPECT_EQ(put, parser->put());
247 AddDoCommandsExpect(
248 error::kOutOfBounds, CommandParser::kParseCommandsSlice, 1, 0);
249 EXPECT_EQ(error::kOutOfBounds,
250 parser->ProcessAllCommands());
251 // check that no DoCommand call was made.
252 Mock::VerifyAndClearExpectations(api_mock());
254 parser.reset(MakeParser(5));
255 put = parser->put();
257 // Generates 2 commands.
258 header.size = 1;
259 header.command = 3;
260 buffer()[put++].value_header = header;
261 CommandBufferOffset put_post_fail = put;
262 header.size = 1;
263 header.command = 4;
264 buffer()[put++].value_header = header;
266 parser->set_put(put);
267 EXPECT_EQ(put, parser->put());
268 // have the first command fail to parse.
269 AddDoCommandsExpect(
270 error::kUnknownCommand, CommandParser::kParseCommandsSlice, 2, 1);
271 EXPECT_EQ(error::kUnknownCommand,
272 parser->ProcessAllCommands());
273 // check that only one command was executed, and that get reflects that
274 // correctly.
275 EXPECT_EQ(put_post_fail, parser->get());
276 Mock::VerifyAndClearExpectations(api_mock());
277 // make the second one succeed, and check that the parser recovered fine.
278 AddDoCommandsExpect(
279 error::kNoError, CommandParser::kParseCommandsSlice, 1, 1);
280 EXPECT_EQ(error::kNoError, parser->ProcessAllCommands());
281 EXPECT_EQ(put, parser->get());
282 Mock::VerifyAndClearExpectations(api_mock());
285 TEST_F(CommandParserTest, SetBuffer) {
286 scoped_ptr<CommandParser> parser(MakeParser(3));
287 CommandBufferOffset put = parser->put();
288 CommandHeader header;
290 // add a single command, no args
291 header.size = 2;
292 header.command = 123;
293 buffer()[put++].value_header = header;
294 buffer()[put++].value_int32 = 456;
295 parser->set_put(put);
297 AddDoCommandsExpect(
298 error::kNoError, CommandParser::kParseCommandsSlice, 2, 2);
299 EXPECT_EQ(error::kNoError, parser->ProcessAllCommands());
300 // We should have advanced 2 entries
301 EXPECT_EQ(2, parser->get());
302 Mock::VerifyAndClearExpectations(api_mock());
304 scoped_ptr<CommandBufferEntry[]> buffer2(new CommandBufferEntry[2]);
305 parser->SetBuffer(
306 buffer2.get(), sizeof(CommandBufferEntry) * 2, 0,
307 sizeof(CommandBufferEntry) * 2);
308 // The put and get should have reset to 0.
309 EXPECT_EQ(0, parser->get());
310 EXPECT_EQ(0, parser->put());
313 } // namespace gpu