1 // Copyright 2015 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 #include "media/midi/midi_manager_alsa.h"
7 #include "testing/gtest/include/gtest/gtest.h"
12 class MidiManagerAlsaTest
: public ::testing::Test
{
14 void SetUp() override
{
15 // Pre-instantiate typical MidiPort instances that are often used in
18 // Inputs. port_input_0_ == port_input_1_.
19 port_input_0_
.reset(new MidiManagerAlsa::MidiPort(
20 "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
21 "interface", "serial"),
22 1, 2, 5, "client_name", "port_name", "manufacturer", "version",
23 MidiManagerAlsa::MidiPort::Type::kInput
));
24 port_input_1_
.reset(new MidiManagerAlsa::MidiPort(
25 "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
26 "interface", "serial"),
27 1, 2, 5, "client_name", "port_name", "manufacturer", "version",
28 MidiManagerAlsa::MidiPort::Type::kInput
));
29 port_input_minimal_
.reset(new MidiManagerAlsa::MidiPort(
30 "", MidiManagerAlsa::MidiPort::Id(), 0, 0, 0, "", "", "", "",
31 MidiManagerAlsa::MidiPort::Type::kInput
));
32 // Outputs. port_output_0_ == port_output_1_.
33 port_output_0_
.reset(new MidiManagerAlsa::MidiPort(
34 "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
35 "interface", "serial"),
36 1, 2, 5, "client_name", "port_name", "manufacturer", "version",
37 MidiManagerAlsa::MidiPort::Type::kOutput
));
38 port_output_1_
.reset(new MidiManagerAlsa::MidiPort(
39 "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
40 "interface", "serial"),
41 1, 2, 5, "client_name", "port_name", "manufacturer", "version",
42 MidiManagerAlsa::MidiPort::Type::kOutput
));
44 // MidiPort fields that differ from port_input_0_ in a single way each time.
45 // Used for testing the Match* and Find* methods.
46 port_input_0_alt_path_
.reset(new MidiManagerAlsa::MidiPort(
47 "path2", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
48 "interface", "serial"),
49 1, 2, 5, "client_name", "port_name", "manufacturer", "version",
50 MidiManagerAlsa::MidiPort::Type::kInput
));
51 port_input_0_alt_id_
.reset(new MidiManagerAlsa::MidiPort(
52 "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
53 "interface", "serial2"),
54 1, 2, 5, "client_name", "port_name", "manufacturer", "version",
55 MidiManagerAlsa::MidiPort::Type::kInput
));
56 port_input_0_alt_client_name_
.reset(new MidiManagerAlsa::MidiPort(
57 "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
58 "interface", "serial"),
59 1, 2, 5, "client_name2", "port_name", "manufacturer", "version",
60 MidiManagerAlsa::MidiPort::Type::kInput
));
61 port_input_0_alt_port_name_
.reset(new MidiManagerAlsa::MidiPort(
62 "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
63 "interface", "serial"),
64 1, 2, 5, "client_name", "port_name2", "manufacturer", "version",
65 MidiManagerAlsa::MidiPort::Type::kInput
));
66 port_input_0_alt_client_id_
.reset(new MidiManagerAlsa::MidiPort(
67 "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
68 "interface", "serial"),
69 2, 2, 5, "client_name", "port_name", "manufacturer", "version",
70 MidiManagerAlsa::MidiPort::Type::kInput
));
71 port_input_0_alt_port_id_
.reset(new MidiManagerAlsa::MidiPort(
72 "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
73 "interface", "serial"),
74 1, 3, 5, "client_name", "port_name", "manufacturer", "version",
75 MidiManagerAlsa::MidiPort::Type::kInput
));
76 port_input_0_alt_midi_device_
.reset(new MidiManagerAlsa::MidiPort(
77 "path", MidiManagerAlsa::MidiPort::Id("bus", "vendor", "model",
78 "interface", "serial"),
79 1, 2, 6, "client_name", "port_name", "manufacturer", "version",
80 MidiManagerAlsa::MidiPort::Type::kInput
));
82 // "No card" variants of above. For testing FindDisconnected.
83 port_input_0_no_card_
.reset(new MidiManagerAlsa::MidiPort(
84 "", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name",
85 "port_name", "manufacturer", "version",
86 MidiManagerAlsa::MidiPort::Type::kInput
));
87 port_input_1_no_card_
.reset(new MidiManagerAlsa::MidiPort(
88 "", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name",
89 "port_name", "manufacturer", "version",
90 MidiManagerAlsa::MidiPort::Type::kInput
));
91 port_output_0_no_card_
.reset(new MidiManagerAlsa::MidiPort(
92 "", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name",
93 "port_name", "manufacturer", "version",
94 MidiManagerAlsa::MidiPort::Type::kOutput
));
96 // No card variants of the alt variants from above. For more testing
97 // of Match* and Find*.
98 port_input_0_no_card_alt_client_name_
.reset(new MidiManagerAlsa::MidiPort(
99 "", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name2",
100 "port_name", "manufacturer", "version",
101 MidiManagerAlsa::MidiPort::Type::kInput
));
102 port_input_0_no_card_alt_port_name_
.reset(new MidiManagerAlsa::MidiPort(
103 "", MidiManagerAlsa::MidiPort::Id(), 1, 2, -1, "client_name",
104 "port_name2", "manufacturer", "version",
105 MidiManagerAlsa::MidiPort::Type::kInput
));
106 port_input_0_no_card_alt_client_id_
.reset(new MidiManagerAlsa::MidiPort(
107 "", MidiManagerAlsa::MidiPort::Id(), 2, 2, -1, "client_name",
108 "port_name", "manufacturer", "version",
109 MidiManagerAlsa::MidiPort::Type::kInput
));
110 port_input_0_no_card_alt_port_id_
.reset(new MidiManagerAlsa::MidiPort(
111 "", MidiManagerAlsa::MidiPort::Id(), 1, 3, -1, "client_name",
112 "port_name", "manufacturer", "version",
113 MidiManagerAlsa::MidiPort::Type::kInput
));
116 // Counts ports for help with testing ToMidiPortState().
117 int CountPorts(MidiManagerAlsa::TemporaryMidiPortState
& state
) {
119 for (auto it
= state
.begin(); it
!= state
.end(); ++it
)
124 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_
;
125 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_1_
;
126 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_minimal_
;
127 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_output_0_
;
128 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_output_1_
;
130 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_alt_path_
;
131 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_alt_id_
;
132 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_alt_client_name_
;
133 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_alt_port_name_
;
134 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_alt_client_id_
;
135 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_alt_port_id_
;
136 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_alt_midi_device_
;
138 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_no_card_
;
139 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_1_no_card_
;
140 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_output_0_no_card_
;
142 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_no_card_alt_client_name_
;
143 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_no_card_alt_port_name_
;
144 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_no_card_alt_client_id_
;
145 scoped_ptr
<MidiManagerAlsa::MidiPort
> port_input_0_no_card_alt_port_id_
;
147 // State fields to avoid declaring in test fixtures below.
148 MidiManagerAlsa::MidiPortState midi_port_state_0_
;
149 MidiManagerAlsa::MidiPortState midi_port_state_1_
;
150 MidiManagerAlsa::TemporaryMidiPortState temporary_midi_port_state_0_
;
151 MidiManagerAlsa::AlsaSeqState alsa_seq_state_0_
;
152 MidiManagerAlsa::AlsaCardMap alsa_cards_
;
155 // Tests that ExtractManufacturerString works as expected.
156 TEST_F(MidiManagerAlsaTest
, ExtractManufacturer
) {
157 EXPECT_EQ("My\\x20Vendor",
158 MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
159 "My\\x20Vendor", "1234", "My Vendor, Inc.", "Card",
160 "My Vendor Inc Card at bus"));
161 EXPECT_EQ("My Vendor", MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
162 "My Vendor", "1234", "My Vendor, Inc.", "Card",
163 "My Vendor Inc Card at bus"));
164 EXPECT_EQ("My Vendor, Inc.",
165 MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
166 "1234", "1234", "My Vendor, Inc.", "Card",
167 "My Vendor Inc Card at bus"));
168 EXPECT_EQ("My Vendor Inc",
169 MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
170 "1234", "1234", "", "Card", "My Vendor Inc Card at bus"));
171 EXPECT_EQ("My Vendor Inc",
172 MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
173 "", "", "", "Card", "My Vendor Inc Card at bus"));
174 EXPECT_EQ("", MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
175 "1234", "1234", "", "Card", "Longname"));
176 EXPECT_EQ("Keystation\\x20Mini\\x2032",
177 MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
178 "Keystation\\x20Mini\\x2032", "129d",
179 "Evolution Electronics, Ltd", "Keystation Mini 32",
180 "Keystation Mini 32 Keystation Mini 32 at"
181 " usb-0000:00:14.0-2.4.4, full speed"));
182 EXPECT_EQ("Keystation Mini 32",
183 MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
184 "Keystation Mini 32", "129d", "Evolution Electronics, Ltd",
185 "Keystation Mini 32",
186 "Keystation Mini 32 Keystation Mini 32 at"
187 " usb-0000:00:14.0-2.4.4, full speed"));
188 EXPECT_EQ("Keystation Mini 32",
189 MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
190 "", "", "", "Keystation Mini 32",
191 "Keystation Mini 32 Keystation Mini 32 at"
192 " usb-0000:00:14.0-2.4.4, full speed"));
193 EXPECT_EQ("", MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
194 "", "", "", "Serial MIDI (UART16550A)",
195 "Serial MIDI (UART16550A) [Soundcanvas] at 0x3f8, irq 4"));
196 EXPECT_EQ("", MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
197 "", "", "", "VirMIDI", "Virtual MIDI Card 1"));
198 EXPECT_EQ("C-Media Electronics Inc",
199 MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
200 "", "0x13f6", "C-Media Electronics Inc", "C-Media CMI8738 MIDI",
201 "C-Media CMI8738 (model 55) at 0xd000, irq 19"));
202 EXPECT_EQ("C-Media Electronics Inc",
203 MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
204 "", "0x13f6", "C-Media Electronics Inc", "C-Media CMI8738 FM",
205 "C-Media CMI8738 (model 55) at 0xd000, irq 19"));
208 // Tests that verify proper serialization and generation of opaque key for
210 TEST_F(MidiManagerAlsaTest
, JSONPortMetadata
) {
212 "{\"bus\":\"bus\",\"clientId\":1,\"clientName\":\"client_name\","
213 "\"midiDevice\":5,\"modelId\":\"model\",\"path\":\"path\",\"portId\":2,"
214 "\"portName\":\"port_name\",\"serial\":\"serial\",\"type\":\"input\","
215 "\"usbInterfaceNum\":\"interface\",\"vendorId\":\"vendor\"}",
216 port_input_0_
->JSONValue());
218 EXPECT_EQ("810194DAF713B32FC9BE40EC822E21682635B48C242D09EA95DBA4A184A95877",
219 port_input_0_
->OpaqueKey());
222 "{\"bus\":\"bus\",\"clientId\":1,\"clientName\":\"client_name\","
223 "\"midiDevice\":5,\"modelId\":\"model\",\"path\":\"path\",\"portId\":2,"
224 "\"portName\":\"port_name\",\"serial\":\"serial\",\"type\":\"output\","
225 "\"usbInterfaceNum\":\"interface\",\"vendorId\":\"vendor\"}",
226 port_output_0_
->JSONValue());
227 EXPECT_EQ("C32552FC772A0CA453A675CED05EFB3BDEF749EB58ED9522475206F111BC01E2",
228 port_output_0_
->OpaqueKey());
230 EXPECT_EQ("{\"clientId\":0,\"midiDevice\":0,\"portId\":0,\"type\":\"input\"}",
231 port_input_minimal_
->JSONValue());
232 EXPECT_EQ("3BC2A85598E5026D01DBCB022016C8A3362A9C7F912B88E303BF619C56D0C111",
233 port_input_minimal_
->OpaqueKey());
236 // Tests Match* methods.
237 TEST_F(MidiManagerAlsaTest
, MatchConnected
) {
238 // The query can be disconnected or connected, but the target
239 // must be connected.
240 port_input_1_
->set_connected(false);
241 EXPECT_TRUE(port_input_0_
->MatchConnected(*port_input_1_
.get()));
242 EXPECT_FALSE(port_input_1_
->MatchConnected(*port_input_0_
.get()));
245 EXPECT_FALSE(port_input_0_
->MatchConnected(*port_output_0_
.get()));
247 // Differing in 1 field. None should succeed.
248 EXPECT_FALSE(port_input_0_
->MatchConnected(*port_input_0_alt_path_
.get()));
249 EXPECT_FALSE(port_input_0_
->MatchConnected(*port_input_0_alt_id_
.get()));
251 port_input_0_
->MatchConnected(*port_input_0_alt_client_name_
.get()));
253 port_input_0_
->MatchConnected(*port_input_0_alt_port_name_
.get()));
255 port_input_0_
->MatchConnected(*port_input_0_alt_client_id_
.get()));
256 EXPECT_FALSE(port_input_0_
->MatchConnected(*port_input_0_alt_port_id_
.get()));
258 port_input_0_
->MatchConnected(*port_input_0_alt_midi_device_
.get()));
261 TEST_F(MidiManagerAlsaTest
, MatchCard1
) {
262 // The query can be disconnected or connected, but the target
263 // must be disonnected.
264 EXPECT_FALSE(port_input_0_
->MatchCardPass1(*port_input_1_
.get()));
265 port_input_0_
->set_connected(false);
266 EXPECT_TRUE(port_input_0_
->MatchCardPass1(*port_input_1_
.get()));
269 EXPECT_FALSE(port_input_0_
->MatchCardPass1(*port_output_0_
.get()));
271 // Tests matches differing in 1 field.
272 // client_name, port_name, client_id are ok to differ.
273 EXPECT_FALSE(port_input_0_
->MatchCardPass1(*port_input_0_alt_path_
.get()));
274 EXPECT_FALSE(port_input_0_
->MatchCardPass1(*port_input_0_alt_id_
.get()));
276 port_input_0_
->MatchCardPass1(*port_input_0_alt_client_name_
.get()));
278 port_input_0_
->MatchCardPass1(*port_input_0_alt_port_name_
.get()));
280 port_input_0_
->MatchCardPass1(*port_input_0_alt_client_id_
.get()));
281 EXPECT_FALSE(port_input_0_
->MatchCardPass1(*port_input_0_alt_port_id_
.get()));
283 port_input_0_
->MatchCardPass1(*port_input_0_alt_midi_device_
.get()));
286 TEST_F(MidiManagerAlsaTest
, MatchCard2
) {
287 // The query can be disconnected or connected, but the target
288 // must be disonnected.
289 EXPECT_FALSE(port_input_0_
->MatchCardPass2(*port_input_1_
.get()));
290 port_input_0_
->set_connected(false);
291 EXPECT_TRUE(port_input_0_
->MatchCardPass2(*port_input_1_
.get()));
294 EXPECT_FALSE(port_input_0_
->MatchCardPass2(*port_output_0_
.get()));
296 // Tests matches differing in 1 field.
297 // client_name, port_name, path, client_id are ok to differ.
298 EXPECT_TRUE(port_input_0_
->MatchCardPass2(*port_input_0_alt_path_
.get()));
299 EXPECT_FALSE(port_input_0_
->MatchCardPass2(*port_input_0_alt_id_
.get()));
301 port_input_0_
->MatchCardPass2(*port_input_0_alt_client_name_
.get()));
303 port_input_0_
->MatchCardPass2(*port_input_0_alt_port_name_
.get()));
305 port_input_0_
->MatchCardPass2(*port_input_0_alt_client_id_
.get()));
306 EXPECT_FALSE(port_input_0_
->MatchCardPass2(*port_input_0_alt_port_id_
.get()));
308 port_input_0_
->MatchCardPass2(*port_input_0_alt_midi_device_
.get()));
311 TEST_F(MidiManagerAlsaTest
, MatchNoCard1
) {
312 // The query can be disconnected or connected, but the target
313 // must be disonnected.
314 // path and id must be empty. midi_device must be -1.
315 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass1(*port_input_1_
.get()));
316 port_input_0_no_card_
->set_connected(false);
317 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass1(*port_input_1_
.get()));
319 port_input_0_no_card_
->MatchNoCardPass1(*port_input_1_no_card_
.get()));
323 port_input_0_no_card_
->MatchNoCardPass1(*port_output_0_no_card_
.get()));
325 // Tests matches differing in 1 field.
326 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass1(
327 *port_input_0_no_card_alt_client_name_
.get()));
328 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass1(
329 *port_input_0_no_card_alt_port_name_
.get()));
330 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass1(
331 *port_input_0_no_card_alt_client_id_
.get()));
332 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass1(
333 *port_input_0_no_card_alt_port_id_
.get()));
336 TEST_F(MidiManagerAlsaTest
, MatchNoCard2
) {
337 // The query can be disconnected or connected, but the target
338 // must be disonnected.
339 // path and id must be empty. midi_device must be -1.
340 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass2(*port_input_1_
.get()));
341 port_input_0_no_card_
->set_connected(false);
342 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass2(*port_input_1_
.get()));
344 port_input_0_no_card_
->MatchNoCardPass2(*port_input_1_no_card_
.get()));
348 port_input_0_no_card_
->MatchNoCardPass2(*port_output_0_no_card_
.get()));
350 // Tests matches differing in 1 field.
351 // client_id ok to differ.
352 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass2(
353 *port_input_0_no_card_alt_client_name_
.get()));
354 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass2(
355 *port_input_0_no_card_alt_port_name_
.get()));
356 EXPECT_TRUE(port_input_0_no_card_
->MatchNoCardPass2(
357 *port_input_0_no_card_alt_client_id_
.get()));
358 EXPECT_FALSE(port_input_0_no_card_
->MatchNoCardPass2(
359 *port_input_0_no_card_alt_port_id_
.get()));
362 // Tests that MidiPorts start connected.
363 TEST_F(MidiManagerAlsaTest
, PortStartsConnected
) {
364 EXPECT_TRUE(port_output_0_
->connected());
365 EXPECT_TRUE(port_input_0_
->connected());
368 // Tests that the web_port_index gets updated by MidiPortState.
369 TEST_F(MidiManagerAlsaTest
, PortIndexSet
) {
370 auto* port_input_0_tracking_pointer
= port_input_0_
.get();
371 auto* port_output_0_tracking_pointer
= port_output_0_
.get();
372 auto* port_input_1_tracking_pointer
= port_input_1_
.get();
373 auto* port_output_1_tracking_pointer
= port_input_1_
.get();
375 // Explicitly initialize web_port_index.
376 port_input_1_
->set_web_port_index(5000);
377 port_output_1_
->set_web_port_index(5000);
379 midi_port_state_0_
.Insert(port_input_0_
.Pass());
380 midi_port_state_0_
.Insert(port_output_0_
.Pass());
381 midi_port_state_0_
.Insert(port_input_1_
.Pass());
382 midi_port_state_0_
.Insert(port_output_1_
.Pass());
384 // First port of each type has index of 0.
385 EXPECT_EQ(0U, port_input_0_tracking_pointer
->web_port_index());
386 EXPECT_EQ(0U, port_output_0_tracking_pointer
->web_port_index());
387 // Second port of each type has index of 1.
388 EXPECT_EQ(1U, port_input_1_tracking_pointer
->web_port_index());
389 EXPECT_EQ(1U, port_output_1_tracking_pointer
->web_port_index());
392 // Tests that the web_port_index is not updated by TemporaryMidiPortState.
393 TEST_F(MidiManagerAlsaTest
, PortIndexNotSet
) {
394 auto* port_input_0_tracking_pointer
= port_input_0_
.get();
395 auto* port_output_0_tracking_pointer
= port_output_0_
.get();
396 auto* port_input_1_tracking_pointer
= port_input_1_
.get();
397 auto* port_output_1_tracking_pointer
= port_input_1_
.get();
399 // Explicitly initialize web_port_index.
400 port_input_1_
->set_web_port_index(5000);
401 port_output_1_
->set_web_port_index(5000);
403 temporary_midi_port_state_0_
.Insert(port_input_0_
.Pass());
404 temporary_midi_port_state_0_
.Insert(port_output_0_
.Pass());
405 temporary_midi_port_state_0_
.Insert(port_input_1_
.Pass());
406 temporary_midi_port_state_0_
.Insert(port_output_1_
.Pass());
408 // web_port_index is untouched.
409 EXPECT_EQ(0U, port_input_0_tracking_pointer
->web_port_index());
410 EXPECT_EQ(0U, port_output_0_tracking_pointer
->web_port_index());
411 EXPECT_EQ(5000U, port_input_1_tracking_pointer
->web_port_index());
412 EXPECT_EQ(5000U, port_output_1_tracking_pointer
->web_port_index());
415 // Tests that inputs and outputs stay separate in MidiPortState.
416 TEST_F(MidiManagerAlsaTest
, SeparateInputOutput
) {
417 auto* port_input_0_tracking_pointer
= port_input_0_
.get();
418 auto* port_output_0_tracking_pointer
= port_output_0_
.get();
419 auto* port_input_1_tracking_pointer
= port_input_1_
.get();
420 auto* port_output_1_tracking_pointer
= port_input_1_
.get();
422 // First port of each type has index of 0.
423 EXPECT_EQ(0U, midi_port_state_0_
.Insert(port_input_0_
.Pass()));
424 EXPECT_EQ(0U, midi_port_state_0_
.Insert(port_output_0_
.Pass()));
426 // Second port of each type has index of 1.
427 EXPECT_EQ(1U, midi_port_state_0_
.Insert(port_input_1_
.Pass()));
428 EXPECT_EQ(1U, midi_port_state_0_
.Insert(port_output_1_
.Pass()));
430 // Check again that the field matches what was returned.
431 EXPECT_EQ(0U, port_input_0_tracking_pointer
->web_port_index());
432 EXPECT_EQ(0U, port_output_0_tracking_pointer
->web_port_index());
433 EXPECT_EQ(1U, port_input_1_tracking_pointer
->web_port_index());
434 EXPECT_EQ(1U, port_output_1_tracking_pointer
->web_port_index());
437 // Tests FindConnected.
438 TEST_F(MidiManagerAlsaTest
, FindConnected
) {
439 auto* port_input_0_tracking_pointer
= port_input_0_
.get();
440 auto* port_input_1_tracking_pointer
= port_input_1_
.get();
442 // Insert port_input_0.
443 midi_port_state_0_
.Insert(port_input_0_
.Pass());
444 // Look for port_input_1 (every field matches port_input_0).
445 auto it
= midi_port_state_0_
.FindConnected(*port_input_1_tracking_pointer
);
446 EXPECT_EQ(port_input_0_tracking_pointer
, *it
);
447 // Look for something else that we won't find.
448 EXPECT_EQ(midi_port_state_0_
.end(),
449 midi_port_state_0_
.FindConnected(*port_input_0_alt_path_
));
452 TEST_F(MidiManagerAlsaTest
, FindConnected2
) {
453 auto* port_input_0_tracking_pointer
= port_input_0_
.get();
454 auto* port_input_1_tracking_pointer
= port_input_1_
.get();
456 // Insert some stuff.
457 midi_port_state_0_
.Insert(port_input_0_alt_path_
.Pass());
458 midi_port_state_0_
.Insert(port_input_0_alt_id_
.Pass());
459 midi_port_state_0_
.Insert(port_input_0_alt_client_name_
.Pass());
460 // Insert port_input_0.
461 midi_port_state_0_
.Insert(port_input_0_
.Pass());
462 // Insert some more stuff.
463 midi_port_state_0_
.Insert(port_input_0_alt_port_id_
.Pass());
464 // Look for port_input_1 (matches to port_input_0).
465 auto it
= midi_port_state_0_
.FindConnected(*port_input_1_tracking_pointer
);
466 EXPECT_EQ(port_input_0_tracking_pointer
, *it
);
467 // Look for something else that we won't find.
468 EXPECT_EQ(midi_port_state_0_
.end(),
469 midi_port_state_0_
.FindConnected(*port_input_minimal_
));
472 TEST_F(MidiManagerAlsaTest
, FindConnected3
) {
473 // midi_port_state_0_ is empty to start.
474 EXPECT_EQ(midi_port_state_0_
.end(),
475 midi_port_state_0_
.FindConnected(*port_input_minimal_
));
478 // Tests FindDisconnected.
479 TEST_F(MidiManagerAlsaTest
, FindDisconnected
) {
480 // midi_port_state_0_ is empty to start.
481 EXPECT_EQ(midi_port_state_0_
.end(),
482 midi_port_state_0_
.FindDisconnected(*port_input_minimal_
));
485 TEST_F(MidiManagerAlsaTest
, FindDisconnected2
) {
486 auto* port_input_0_tracking_pointer
= port_input_0_
.get();
487 auto* port_input_1_tracking_pointer
= port_input_1_
.get();
488 auto* port_input_1_no_card_tracking_pointer
= port_input_1_no_card_
.get();
490 // Ports need to be disconnected to find them.
491 port_input_0_alt_id_
->set_connected(false);
492 port_input_0_alt_path_
->set_connected(false);
493 port_input_0_
->set_connected(false);
495 // Insert some stuff.
496 midi_port_state_0_
.Insert(port_input_0_alt_id_
.Pass());
497 midi_port_state_0_
.Insert(port_input_0_alt_path_
.Pass());
498 // Insert port_input_0.
499 midi_port_state_0_
.Insert(port_input_0_
.Pass());
501 // Add "no card" stuff.
502 port_input_1_no_card_
->set_connected(false);
503 midi_port_state_0_
.Insert(port_input_1_no_card_
.Pass());
505 // Insert some more stuff.
506 midi_port_state_0_
.Insert(port_input_0_alt_port_id_
.Pass());
508 // Look for port_input_1, should trigger exact match.
509 EXPECT_EQ(port_input_0_tracking_pointer
, *midi_port_state_0_
.FindDisconnected(
510 *port_input_1_tracking_pointer
));
512 // Look for no card exact match.
513 EXPECT_EQ(port_input_1_no_card_tracking_pointer
,
514 *midi_port_state_0_
.FindDisconnected(*port_input_0_no_card_
.get()));
516 // Look for something else that we won't find.
517 EXPECT_EQ(midi_port_state_0_
.end(),
518 midi_port_state_0_
.FindDisconnected(*port_input_minimal_
));
521 TEST_F(MidiManagerAlsaTest
, FindDisconnected3
) {
522 auto* port_input_0_tracking_pointer
= port_input_0_
.get();
523 auto* port_input_0_alt_path_tracking_pointer
= port_input_0_alt_path_
.get();
524 auto* port_input_1_no_card_tracking_pointer
= port_input_1_no_card_
.get();
526 // Ports need to be disconnected to find them.
527 port_input_0_alt_path_
->set_connected(false);
528 port_input_0_
->set_connected(false);
530 // Insert some stuff.
531 midi_port_state_0_
.Insert(port_input_0_alt_path_
.Pass());
532 midi_port_state_0_
.Insert(port_input_0_alt_id_
.Pass());
534 // Add no card stuff.
535 port_input_1_no_card_
->set_connected(false);
536 midi_port_state_0_
.Insert(port_input_1_no_card_
.Pass());
538 // Look for port_input_0, should find port_input_0_alt_path.
540 port_input_0_alt_path_tracking_pointer
,
541 *midi_port_state_0_
.FindDisconnected(*port_input_0_tracking_pointer
));
543 // Look for no card partial match.
544 EXPECT_EQ(port_input_1_no_card_tracking_pointer
,
545 *midi_port_state_0_
.FindDisconnected(
546 *port_input_0_no_card_alt_client_id_
.get()));
549 EXPECT_EQ(midi_port_state_0_
.end(),
550 midi_port_state_0_
.FindDisconnected(
551 *port_input_0_no_card_alt_port_id_
.get()));
553 // Look for something else that we won't find.
554 EXPECT_EQ(midi_port_state_0_
.end(),
555 midi_port_state_0_
.FindDisconnected(*port_input_minimal_
));
558 // Tests AlsaSeqState -> MidiPortState.
559 TEST_F(MidiManagerAlsaTest
, ToMidiPortState
) {
562 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
564 // Still empty, because there are no ports yet.
565 alsa_seq_state_0_
.ClientStart(0, "0", SND_SEQ_KERNEL_CLIENT
);
567 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
569 // Add a port, now it has 1 item when converted.
570 alsa_seq_state_0_
.PortStart(
571 0, 0, "0:0", MidiManagerAlsa::AlsaSeqState::PortDirection::kInput
, true);
573 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
575 // Close client. This closes its ports and returns count to 0.
576 alsa_seq_state_0_
.ClientExit(0);
578 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
580 // Add another port, without client. This does nothing.
581 alsa_seq_state_0_
.PortStart(
582 0, 0, "0:0", MidiManagerAlsa::AlsaSeqState::PortDirection::kInput
, true);
584 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
586 // Close client again. This does nothing.
587 alsa_seq_state_0_
.ClientExit(0);
589 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
591 // Add duplex port. This will add 2 ports when converted.
592 alsa_seq_state_0_
.ClientStart(0, "0", SND_SEQ_KERNEL_CLIENT
);
593 alsa_seq_state_0_
.PortStart(
594 0, 0, "0:0", MidiManagerAlsa::AlsaSeqState::PortDirection::kDuplex
, true);
596 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
598 // Add an output port. Now we are at 3.
599 alsa_seq_state_0_
.PortStart(
600 0, 1, "0:1", MidiManagerAlsa::AlsaSeqState::PortDirection::kOutput
, true);
602 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
604 // Add another client. Still at 3.
605 alsa_seq_state_0_
.ClientStart(1, "1", SND_SEQ_KERNEL_CLIENT
);
607 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
609 // Add a port. Now at 4.
610 alsa_seq_state_0_
.PortStart(
611 1, 0, "1:0", MidiManagerAlsa::AlsaSeqState::PortDirection::kInput
, true);
613 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
615 // Add a duplicate port. Still at 4.
616 alsa_seq_state_0_
.PortStart(
617 1, 0, "1:0", MidiManagerAlsa::AlsaSeqState::PortDirection::kInput
, true);
619 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
621 // Add a duplicate client. This will close the ports from the previous client.
622 alsa_seq_state_0_
.ClientStart(1, "1", SND_SEQ_KERNEL_CLIENT
);
624 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
626 // Remove a duplex port. This reduces count by 2.
627 alsa_seq_state_0_
.PortExit(0, 0);
629 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
631 // Remove a non-existent port. No change.
632 alsa_seq_state_0_
.PortExit(0, 0);
634 CountPorts(*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
).get()));
636 // Verify the last entry.
637 EXPECT_TRUE((*alsa_seq_state_0_
.ToMidiPortState(alsa_cards_
)->begin())
638 ->MatchConnected(MidiManagerAlsa::MidiPort(
639 "", MidiManagerAlsa::MidiPort::Id(), 0, 1, -1, "0", "0:1",
640 "", "", MidiManagerAlsa::MidiPort::Type::kOutput
)));
643 // Tests card_client_count of AlsaSeqState.
644 TEST_F(MidiManagerAlsaTest
, CardClientCount
) {
645 EXPECT_EQ(0, alsa_seq_state_0_
.card_client_count());
647 // Add a kernel client.
648 alsa_seq_state_0_
.ClientStart(16, "16", SND_SEQ_KERNEL_CLIENT
);
649 EXPECT_EQ(1, alsa_seq_state_0_
.card_client_count());
651 // Add a duplicate kernel client.
652 alsa_seq_state_0_
.ClientStart(16, "16", SND_SEQ_KERNEL_CLIENT
);
653 EXPECT_EQ(1, alsa_seq_state_0_
.card_client_count());
655 // Add a duplicate user client.
656 alsa_seq_state_0_
.ClientStart(16, "16", SND_SEQ_USER_CLIENT
);
657 EXPECT_EQ(0, alsa_seq_state_0_
.card_client_count());
659 // Add 2 more kernel clients.
660 alsa_seq_state_0_
.ClientStart(17, "17", SND_SEQ_KERNEL_CLIENT
);
661 alsa_seq_state_0_
.ClientStart(18, "18", SND_SEQ_KERNEL_CLIENT
);
662 EXPECT_EQ(2, alsa_seq_state_0_
.card_client_count());
664 // Add another user client.
665 alsa_seq_state_0_
.ClientStart(101, "101", SND_SEQ_USER_CLIENT
);
666 EXPECT_EQ(2, alsa_seq_state_0_
.card_client_count());
668 // Remove kernel client.
669 alsa_seq_state_0_
.ClientExit(17);
670 EXPECT_EQ(1, alsa_seq_state_0_
.card_client_count());
672 // Remove user client.
673 alsa_seq_state_0_
.ClientExit(16);
674 EXPECT_EQ(1, alsa_seq_state_0_
.card_client_count());
676 // Remove kernel client.
677 alsa_seq_state_0_
.ClientExit(18);
678 EXPECT_EQ(0, alsa_seq_state_0_
.card_client_count());
680 // Add a duplicate kernel client.
681 alsa_seq_state_0_
.ClientStart(101, "101", SND_SEQ_KERNEL_CLIENT
);
682 EXPECT_EQ(1, alsa_seq_state_0_
.card_client_count());
684 // Add a low kernel client.
685 alsa_seq_state_0_
.ClientStart(1, "1", SND_SEQ_KERNEL_CLIENT
);
686 EXPECT_EQ(1, alsa_seq_state_0_
.card_client_count());
688 // Remove low kernel client.
689 alsa_seq_state_0_
.ClientExit(1);
690 EXPECT_EQ(1, alsa_seq_state_0_
.card_client_count());
693 TEST_F(MidiManagerAlsaTest
, AlsaCards
) {
694 // TODO(agoode): test add/remove of alsa cards.
697 // TODO(agoode): Test old -> new state event generation, using mocks.