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

Side by Side Diff: media/midi/midi_manager_unittest.cc

Issue 662853003: Manage MIDI related objects and sessions' lifecycles correctly (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: unittest Created 6 years, 2 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/midi/midi_manager.h" 5 #include "media/midi/midi_manager.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 } 47 }
48 48
49 bool start_initialization_is_called_; 49 bool start_initialization_is_called_;
50 50
51 private: 51 private:
52 DISALLOW_COPY_AND_ASSIGN(FakeMidiManager); 52 DISALLOW_COPY_AND_ASSIGN(FakeMidiManager);
53 }; 53 };
54 54
55 class FakeMidiManagerClient : public MidiManagerClient { 55 class FakeMidiManagerClient : public MidiManagerClient {
56 public: 56 public:
57 explicit FakeMidiManagerClient(int client_id) 57 FakeMidiManagerClient()
58 : client_id_(client_id), 58 : result_(MIDI_NOT_SUPPORTED),
59 result_(MIDI_NOT_SUPPORTED),
60 wait_for_result_(true) {} 59 wait_for_result_(true) {}
61 virtual ~FakeMidiManagerClient() {} 60 virtual ~FakeMidiManagerClient() {}
62 61
63 // MidiManagerClient implementation. 62 // MidiManagerClient implementation.
64 virtual void CompleteStartSession(int client_id, MidiResult result) override { 63 virtual void CompleteStartSession(MidiResult result) override {
65 EXPECT_TRUE(wait_for_result_); 64 EXPECT_TRUE(wait_for_result_);
66 CHECK_EQ(client_id_, client_id);
67 result_ = result; 65 result_ = result;
68 wait_for_result_ = false; 66 wait_for_result_ = false;
69 } 67 }
70 68
71 virtual void ReceiveMidiData(uint32 port_index, const uint8* data, 69 virtual void ReceiveMidiData(uint32 port_index, const uint8* data,
72 size_t size, double timestamp) override {} 70 size_t size, double timestamp) override {}
73 virtual void AccumulateMidiBytesSent(size_t size) override {} 71 virtual void AccumulateMidiBytesSent(size_t size) override {}
74 72
75 int client_id() const { return client_id_; }
76 MidiResult result() const { return result_; } 73 MidiResult result() const { return result_; }
77 74
78 void HandleContinuationMessage() { 75 void HandleContinuationMessage() {
79 // Stop posting a dummy message once CompleteStartSession() is invoked. 76 // Stop posting a dummy message once CompleteStartSession() is invoked.
80 if (!wait_for_result_) 77 if (!wait_for_result_)
81 return; 78 return;
82 base::MessageLoop::current()->PostTask( 79 base::MessageLoop::current()->PostTask(
83 FROM_HERE, 80 FROM_HERE,
84 base::Bind(&FakeMidiManagerClient::HandleContinuationMessage, 81 base::Bind(&FakeMidiManagerClient::HandleContinuationMessage,
85 base::Unretained(this))); 82 base::Unretained(this)));
86 } 83 }
87 84
88 85
89 MidiResult WaitForResult() { 86 MidiResult WaitForResult() {
90 base::RunLoop run_loop; 87 base::RunLoop run_loop;
91 // Post a dummy task not to stop the following event loop. 88 // Post a dummy task not to stop the following event loop.
92 HandleContinuationMessage(); 89 HandleContinuationMessage();
93 // CompleteStartSession() is called inside the message loop on the same 90 // CompleteStartSession() is called inside the message loop on the same
94 // thread. Protection for |wait_for_result_| is not needed. 91 // thread. Protection for |wait_for_result_| is not needed.
95 run_loop.RunUntilIdle(); 92 run_loop.RunUntilIdle();
96 return result(); 93 return result();
97 } 94 }
98 95
99 private: 96 private:
100 int client_id_;
101 MidiResult result_; 97 MidiResult result_;
102 bool wait_for_result_; 98 bool wait_for_result_;
103 99
104 DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient); 100 DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient);
105 }; 101 };
106 102
107 class MidiManagerTest : public ::testing::Test { 103 class MidiManagerTest : public ::testing::Test {
108 public: 104 public:
109 MidiManagerTest() 105 MidiManagerTest()
110 : manager_(new FakeMidiManager), 106 : manager_(new FakeMidiManager),
111 message_loop_(new base::MessageLoop) {} 107 message_loop_(new base::MessageLoop) {}
112 virtual ~MidiManagerTest() {} 108 virtual ~MidiManagerTest() {}
113 109
114 protected: 110 protected:
115 void StartTheFirstSession(FakeMidiManagerClient* client) { 111 void StartTheFirstSession(FakeMidiManagerClient* client) {
116 EXPECT_FALSE(manager_->start_initialization_is_called_); 112 EXPECT_FALSE(manager_->start_initialization_is_called_);
117 EXPECT_EQ(0U, manager_->GetClientCount()); 113 EXPECT_EQ(0U, manager_->GetClientCount());
118 EXPECT_EQ(0U, manager_->GetPendingClientCount()); 114 EXPECT_EQ(0U, manager_->GetPendingClientCount());
119 manager_->StartSession(client, client->client_id()); 115 manager_->StartSession(client);
120 EXPECT_EQ(0U, manager_->GetClientCount()); 116 EXPECT_EQ(0U, manager_->GetClientCount());
121 EXPECT_EQ(1U, manager_->GetPendingClientCount()); 117 EXPECT_EQ(1U, manager_->GetPendingClientCount());
122 EXPECT_TRUE(manager_->start_initialization_is_called_); 118 EXPECT_TRUE(manager_->start_initialization_is_called_);
123 EXPECT_EQ(0U, manager_->GetClientCount()); 119 EXPECT_EQ(0U, manager_->GetClientCount());
124 EXPECT_EQ(1U, manager_->GetPendingClientCount()); 120 EXPECT_EQ(1U, manager_->GetPendingClientCount());
125 EXPECT_TRUE(manager_->start_initialization_is_called_); 121 EXPECT_TRUE(manager_->start_initialization_is_called_);
126 } 122 }
127 123
128 void StartTheNthSession(FakeMidiManagerClient* client, size_t nth) { 124 void StartTheNthSession(FakeMidiManagerClient* client, size_t nth) {
129 EXPECT_EQ(nth != 1, manager_->start_initialization_is_called_); 125 EXPECT_EQ(nth != 1, manager_->start_initialization_is_called_);
130 EXPECT_EQ(0U, manager_->GetClientCount()); 126 EXPECT_EQ(0U, manager_->GetClientCount());
131 EXPECT_EQ(nth - 1, manager_->GetPendingClientCount()); 127 EXPECT_EQ(nth - 1, manager_->GetPendingClientCount());
132 128
133 // StartInitialization() should not be called for the second and later 129 // StartInitialization() should not be called for the second and later
134 // sessions. 130 // sessions.
135 manager_->start_initialization_is_called_ = false; 131 manager_->start_initialization_is_called_ = false;
136 manager_->StartSession(client, client->client_id()); 132 manager_->StartSession(client);
137 EXPECT_EQ(nth == 1, manager_->start_initialization_is_called_); 133 EXPECT_EQ(nth == 1, manager_->start_initialization_is_called_);
138 manager_->start_initialization_is_called_ = true; 134 manager_->start_initialization_is_called_ = true;
139 } 135 }
140 136
141 void EndSession(FakeMidiManagerClient* client, size_t before, size_t after) { 137 void EndSession(FakeMidiManagerClient* client, size_t before, size_t after) {
142 EXPECT_EQ(before, manager_->GetClientCount()); 138 EXPECT_EQ(before, manager_->GetClientCount());
143 manager_->EndSession(client); 139 manager_->EndSession(client);
144 EXPECT_EQ(after, manager_->GetClientCount()); 140 EXPECT_EQ(after, manager_->GetClientCount());
145 } 141 }
146 142
(...skipping 10 matching lines...) Expand all
157 scoped_ptr<FakeMidiManager> manager_; 153 scoped_ptr<FakeMidiManager> manager_;
158 154
159 private: 155 private:
160 scoped_ptr<base::MessageLoop> message_loop_; 156 scoped_ptr<base::MessageLoop> message_loop_;
161 157
162 DISALLOW_COPY_AND_ASSIGN(MidiManagerTest); 158 DISALLOW_COPY_AND_ASSIGN(MidiManagerTest);
163 }; 159 };
164 160
165 TEST_F(MidiManagerTest, StartAndEndSession) { 161 TEST_F(MidiManagerTest, StartAndEndSession) {
166 scoped_ptr<FakeMidiManagerClient> client; 162 scoped_ptr<FakeMidiManagerClient> client;
167 client.reset(new FakeMidiManagerClient(0)); 163 client.reset(new FakeMidiManagerClient);
168 164
169 StartTheFirstSession(client.get()); 165 StartTheFirstSession(client.get());
170 CompleteInitialization(MIDI_OK); 166 CompleteInitialization(MIDI_OK);
171 EXPECT_EQ(MIDI_OK, client->WaitForResult()); 167 EXPECT_EQ(MIDI_OK, client->WaitForResult());
172 EndSession(client.get(), 1U, 0U); 168 EndSession(client.get(), 1U, 0U);
173 } 169 }
174 170
175 TEST_F(MidiManagerTest, StartAndEndSessionWithError) { 171 TEST_F(MidiManagerTest, StartAndEndSessionWithError) {
176 scoped_ptr<FakeMidiManagerClient> client; 172 scoped_ptr<FakeMidiManagerClient> client;
177 client.reset(new FakeMidiManagerClient(1)); 173 client.reset(new FakeMidiManagerClient);
178 174
179 StartTheFirstSession(client.get()); 175 StartTheFirstSession(client.get());
180 CompleteInitialization(MIDI_INITIALIZATION_ERROR); 176 CompleteInitialization(MIDI_INITIALIZATION_ERROR);
181 EXPECT_EQ(MIDI_INITIALIZATION_ERROR, client->WaitForResult()); 177 EXPECT_EQ(MIDI_INITIALIZATION_ERROR, client->WaitForResult());
182 EndSession(client.get(), 0U, 0U); 178 EndSession(client.get(), 0U, 0U);
183 } 179 }
184 180
185 TEST_F(MidiManagerTest, StartMultipleSessions) { 181 TEST_F(MidiManagerTest, StartMultipleSessions) {
186 scoped_ptr<FakeMidiManagerClient> client1; 182 scoped_ptr<FakeMidiManagerClient> client1;
187 scoped_ptr<FakeMidiManagerClient> client2; 183 scoped_ptr<FakeMidiManagerClient> client2;
188 scoped_ptr<FakeMidiManagerClient> client3; 184 scoped_ptr<FakeMidiManagerClient> client3;
189 client1.reset(new FakeMidiManagerClient(0)); 185 client1.reset(new FakeMidiManagerClient);
190 client2.reset(new FakeMidiManagerClient(1)); 186 client2.reset(new FakeMidiManagerClient);
191 client3.reset(new FakeMidiManagerClient(1)); 187 client3.reset(new FakeMidiManagerClient);
192 188
193 StartTheFirstSession(client1.get()); 189 StartTheFirstSession(client1.get());
194 StartTheNthSession(client2.get(), 2); 190 StartTheNthSession(client2.get(), 2);
195 StartTheNthSession(client3.get(), 3); 191 StartTheNthSession(client3.get(), 3);
196 CompleteInitialization(MIDI_OK); 192 CompleteInitialization(MIDI_OK);
197 EXPECT_EQ(MIDI_OK, client1->WaitForResult()); 193 EXPECT_EQ(MIDI_OK, client1->WaitForResult());
198 EXPECT_EQ(MIDI_OK, client2->WaitForResult()); 194 EXPECT_EQ(MIDI_OK, client2->WaitForResult());
199 EXPECT_EQ(MIDI_OK, client3->WaitForResult()); 195 EXPECT_EQ(MIDI_OK, client3->WaitForResult());
200 EndSession(client1.get(), 3U, 2U); 196 EndSession(client1.get(), 3U, 2U);
201 EndSession(client2.get(), 2U, 1U); 197 EndSession(client2.get(), 2U, 1U);
202 EndSession(client3.get(), 1U, 0U); 198 EndSession(client3.get(), 1U, 0U);
203 } 199 }
204 200
205 // TODO(toyoshim): Add a test for a MidiManagerClient that has multiple 201 // TODO(toyoshim): Add a test for a MidiManagerClient that has multiple
206 // sessions with multiple client_id. 202 // sessions with multiple client_id.
207 203
208 TEST_F(MidiManagerTest, TooManyPendingSessions) { 204 TEST_F(MidiManagerTest, TooManyPendingSessions) {
209 // Push as many client requests for starting session as possible. 205 // Push as many client requests for starting session as possible.
210 ScopedVector<FakeMidiManagerClient> many_existing_clients; 206 ScopedVector<FakeMidiManagerClient> many_existing_clients;
211 many_existing_clients.resize(MidiManager::kMaxPendingClientCount); 207 many_existing_clients.resize(MidiManager::kMaxPendingClientCount);
212 for (size_t i = 0; i < MidiManager::kMaxPendingClientCount; ++i) { 208 for (size_t i = 0; i < MidiManager::kMaxPendingClientCount; ++i) {
213 many_existing_clients[i] = new FakeMidiManagerClient(i); 209 many_existing_clients[i] = new FakeMidiManagerClient;
214 StartTheNthSession(many_existing_clients[i], i + 1); 210 StartTheNthSession(many_existing_clients[i], i + 1);
215 } 211 }
216 212
217 // Push the last client that should be rejected for too many pending requests. 213 // Push the last client that should be rejected for too many pending requests.
218 scoped_ptr<FakeMidiManagerClient> additional_client( 214 scoped_ptr<FakeMidiManagerClient> additional_client(
219 new FakeMidiManagerClient(MidiManager::kMaxPendingClientCount)); 215 new FakeMidiManagerClient);
220 manager_->start_initialization_is_called_ = false; 216 manager_->start_initialization_is_called_ = false;
221 manager_->StartSession(additional_client.get(), 217 manager_->StartSession(additional_client.get());
222 additional_client->client_id());
223 EXPECT_FALSE(manager_->start_initialization_is_called_); 218 EXPECT_FALSE(manager_->start_initialization_is_called_);
224 EXPECT_EQ(MIDI_INITIALIZATION_ERROR, additional_client->result()); 219 EXPECT_EQ(MIDI_INITIALIZATION_ERROR, additional_client->result());
225 220
226 // Other clients still should not receive a result. 221 // Other clients still should not receive a result.
227 RunLoopUntilIdle(); 222 RunLoopUntilIdle();
228 for (size_t i = 0; i < many_existing_clients.size(); ++i) 223 for (size_t i = 0; i < many_existing_clients.size(); ++i)
229 EXPECT_EQ(MIDI_NOT_SUPPORTED, many_existing_clients[i]->result()); 224 EXPECT_EQ(MIDI_NOT_SUPPORTED, many_existing_clients[i]->result());
230 225
231 // The result MIDI_OK should be distributed to other clients. 226 // The result MIDI_OK should be distributed to other clients.
232 CompleteInitialization(MIDI_OK); 227 CompleteInitialization(MIDI_OK);
233 for (size_t i = 0; i < many_existing_clients.size(); ++i) 228 for (size_t i = 0; i < many_existing_clients.size(); ++i)
234 EXPECT_EQ(MIDI_OK, many_existing_clients[i]->WaitForResult()); 229 EXPECT_EQ(MIDI_OK, many_existing_clients[i]->WaitForResult());
235 230
236 // Close all successful sessions in FIFO order. 231 // Close all successful sessions in FIFO order.
237 size_t sessions = many_existing_clients.size(); 232 size_t sessions = many_existing_clients.size();
238 for (size_t i = 0; i < many_existing_clients.size(); ++i, --sessions) 233 for (size_t i = 0; i < many_existing_clients.size(); ++i, --sessions)
239 EndSession(many_existing_clients[i], sessions, sessions - 1); 234 EndSession(many_existing_clients[i], sessions, sessions - 1);
240 } 235 }
241 236
242 TEST_F(MidiManagerTest, AbortSession) { 237 TEST_F(MidiManagerTest, AbortSession) {
243 // A client starting a session can be destructed while an asynchronous 238 // A client starting a session can be destructed while an asynchronous
244 // initialization is performed. 239 // initialization is performed.
245 scoped_ptr<FakeMidiManagerClient> client; 240 scoped_ptr<FakeMidiManagerClient> client;
246 client.reset(new FakeMidiManagerClient(0)); 241 client.reset(new FakeMidiManagerClient);
247 242
248 StartTheFirstSession(client.get()); 243 StartTheFirstSession(client.get());
249 EndSession(client.get(), 0, 0); 244 EndSession(client.get(), 0, 0);
250 client.reset(); 245 client.reset();
251 246
252 // Following function should not call the destructed |client| function. 247 // Following function should not call the destructed |client| function.
253 CompleteInitialization(MIDI_OK); 248 CompleteInitialization(MIDI_OK);
254 base::RunLoop run_loop; 249 base::RunLoop run_loop;
255 run_loop.RunUntilIdle(); 250 run_loop.RunUntilIdle();
256 } 251 }
257 252
258 TEST_F(MidiManagerTest, CreateMidiManager) { 253 TEST_F(MidiManagerTest, CreateMidiManager) {
259 scoped_ptr<FakeMidiManagerClient> client; 254 scoped_ptr<FakeMidiManagerClient> client;
260 client.reset(new FakeMidiManagerClient(0)); 255 client.reset(new FakeMidiManagerClient);
261 256
262 scoped_ptr<MidiManager> manager(MidiManager::Create()); 257 scoped_ptr<MidiManager> manager(MidiManager::Create());
263 manager->StartSession(client.get(), client->client_id()); 258 manager->StartSession(client.get());
264 259
265 MidiResult result = client->WaitForResult(); 260 MidiResult result = client->WaitForResult();
266 // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc. 261 // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc.
267 // Do not change the condition for disabling this test. 262 // Do not change the condition for disabling this test.
268 #if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(USE_ALSA) && \ 263 #if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(USE_ALSA) && \
269 !defined(OS_ANDROID) && !defined(OS_CHROMEOS) 264 !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
270 EXPECT_EQ(MIDI_NOT_SUPPORTED, result); 265 EXPECT_EQ(MIDI_NOT_SUPPORTED, result);
271 #elif defined(USE_ALSA) 266 #elif defined(USE_ALSA)
272 // Temporary until http://crbug.com/371230 is resolved. 267 // Temporary until http://crbug.com/371230 is resolved.
273 EXPECT_TRUE((result == MIDI_OK) || (result == MIDI_INITIALIZATION_ERROR)); 268 EXPECT_TRUE((result == MIDI_OK) || (result == MIDI_INITIALIZATION_ERROR));
274 #else 269 #else
275 EXPECT_EQ(MIDI_OK, result); 270 EXPECT_EQ(MIDI_OK, result);
276 #endif 271 #endif
277 } 272 }
278 273
279 } // namespace 274 } // namespace
280 275
281 } // namespace media 276 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698