1 /* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 #include "my_config.h"
24
25 #include <gmock/gmock.h>
26 #include <gtest/gtest.h>
27
28 #include "plugin/x/src/account_verification_handler.h"
29 #include "plugin/x/src/capabilities/handler_auth_mech.h"
30 #include "plugin/x/src/capabilities/handler_client_interactive.h"
31 #include "plugin/x/src/capabilities/handler_connection_attributes.h"
32 #include "plugin/x/src/capabilities/handler_tls.h"
33 #include "plugin/x/src/sql_user_require.h"
34 #include "unittest/gunit/xplugin/xpl/assert_error_code.h"
35 #include "unittest/gunit/xplugin/xpl/mock/capabilities.h"
36 #include "unittest/gunit/xplugin/xpl/mock/ngs_general.h"
37 #include "unittest/gunit/xplugin/xpl/mock/session.h"
38 #include "unittest/gunit/xplugin/xpl/mysqlx_pb_wrapper.h"
39
40 namespace xpl {
41
42 namespace test {
43
44 using ::testing::_;
45 using ::testing::Return;
46 using ::testing::ReturnRef;
47 using ::testing::SetArgPointee;
48 using ::testing::StrictMock;
49 using ::testing::Test;
50 using ::testing::WithParamInterface;
51 using xpl::test::Mock_authentication_container;
52
53 class CapabilityHanderTlsTestSuite : public Test {
54 public:
CapabilityHanderTlsTestSuite()55 CapabilityHanderTlsTestSuite() : sut(mock_client) {
56 EXPECT_CALL(mock_client, connection())
57 .WillRepeatedly(ReturnRef(mock_connection));
58 EXPECT_CALL(mock_client, server()).WillRepeatedly(ReturnRef(mock_server));
59 EXPECT_CALL(mock_server, ssl_context())
60 .WillRepeatedly(Return(&mock_ssl_context));
61 }
62
63 StrictMock<Mock_vio> mock_connection;
64 StrictMock<Mock_client> mock_client;
65 StrictMock<Mock_ssl_context> mock_ssl_context;
66 StrictMock<Mock_server> mock_server;
67
68 Capability_tls sut;
69 };
70
TEST_F(CapabilityHanderTlsTestSuite,isSupported_returnsCurrentConnectionOption_on_supported_connection_type)71 TEST_F(
72 CapabilityHanderTlsTestSuite,
73 isSupported_returnsCurrentConnectionOption_on_supported_connection_type) {
74 EXPECT_CALL(mock_ssl_context, has_ssl())
75 .WillOnce(Return(true))
76 .WillOnce(Return(false));
77 EXPECT_CALL(mock_connection, get_type())
78 .WillOnce(Return(xpl::Connection_tcpip))
79 .WillOnce(Return(xpl::Connection_tcpip));
80
81 ASSERT_TRUE(sut.is_supported());
82 ASSERT_FALSE(sut.is_supported());
83 }
84
TEST_F(CapabilityHanderTlsTestSuite,isSupported_returnsFailure_on_unsupported_connection_type)85 TEST_F(CapabilityHanderTlsTestSuite,
86 isSupported_returnsFailure_on_unsupported_connection_type) {
87 EXPECT_CALL(mock_ssl_context, has_ssl())
88 .WillOnce(Return(true))
89 .WillOnce(Return(false));
90 EXPECT_CALL(mock_connection, get_type())
91 .WillOnce(Return(xpl::Connection_namedpipe))
92 .WillOnce(Return(xpl::Connection_namedpipe));
93
94 ASSERT_FALSE(sut.is_supported());
95 ASSERT_FALSE(sut.is_supported());
96 }
97
TEST_F(CapabilityHanderTlsTestSuite,name_returnsTls_always)98 TEST_F(CapabilityHanderTlsTestSuite, name_returnsTls_always) {
99 ASSERT_STREQ("tls", sut.name().c_str());
100 }
101
TEST_F(CapabilityHanderTlsTestSuite,get_returnsCurrentConnectionOption_always)102 TEST_F(CapabilityHanderTlsTestSuite,
103 get_returnsCurrentConnectionOption_always) {
104 const bool expected_result = true;
105 ::Mysqlx::Datatypes::Any any;
106
107 EXPECT_CALL(mock_connection, get_type())
108 .WillOnce(Return(xpl::Connection_type::Connection_tls));
109
110 sut.get(&any);
111
112 ASSERT_EQ(::Mysqlx::Datatypes::Any::SCALAR, any.type());
113 ASSERT_EQ(::Mysqlx::Datatypes::Scalar::V_BOOL, any.scalar().type());
114 ASSERT_EQ(expected_result, any.scalar().v_bool());
115 }
116
117 class Set_params {
118 public:
119 template <typename T>
Set_params(T any,bool tls)120 Set_params(T any, bool tls) : m_tls_active(tls) {
121 m_any = Any{Scalar{any}};
122
123 m_tls_active = tls;
124 }
125
126 Any m_any;
127 bool m_tls_active;
128 };
129
operator <<(::std::ostream & os,const Set_params & set_param)130 ::std::ostream &operator<<(::std::ostream &os, const Set_params &set_param) {
131 return os << "tls-active:" << set_param.m_tls_active << std::endl;
132 }
133
134 class SuccessSetCapabilityHanderTlsTestSuite
135 : public CapabilityHanderTlsTestSuite,
136 public WithParamInterface<Set_params> {
137 public:
138 };
139
TEST_P(SuccessSetCapabilityHanderTlsTestSuite,get_success_forValidParametersAndTlsSupportedOnTcpip)140 TEST_P(SuccessSetCapabilityHanderTlsTestSuite,
141 get_success_forValidParametersAndTlsSupportedOnTcpip) {
142 auto s = GetParam();
143
144 EXPECT_CALL(mock_ssl_context, has_ssl()).WillOnce(Return(true));
145 EXPECT_CALL(mock_connection, get_type())
146 .WillRepeatedly(Return(xpl::Connection_tcpip));
147
148 ASSERT_EQ(ER_X_SUCCESS, sut.set(s.m_any).error);
149
150 EXPECT_CALL(mock_client, activate_tls_void());
151
152 sut.commit();
153 }
154
TEST_P(SuccessSetCapabilityHanderTlsTestSuite,get_failure_forValidParametersAndTlsSupportedOnNamedPipe)155 TEST_P(SuccessSetCapabilityHanderTlsTestSuite,
156 get_failure_forValidParametersAndTlsSupportedOnNamedPipe) {
157 Set_params s = GetParam();
158
159 EXPECT_CALL(mock_ssl_context, has_ssl()).WillOnce(Return(true));
160 EXPECT_CALL(mock_connection, get_type())
161 .WillRepeatedly(Return(xpl::Connection_namedpipe));
162
163 ASSERT_EQ(ER_X_CAPABILITIES_PREPARE_FAILED, sut.set(s.m_any).error);
164 }
165
TEST_P(SuccessSetCapabilityHanderTlsTestSuite,get_failure_forValidParametersAndTlsIsntSupported)166 TEST_P(SuccessSetCapabilityHanderTlsTestSuite,
167 get_failure_forValidParametersAndTlsIsntSupported) {
168 Set_params s = GetParam();
169
170 EXPECT_CALL(mock_ssl_context, has_ssl()).WillOnce(Return(false));
171 EXPECT_CALL(mock_connection, get_type())
172 .WillRepeatedly(Return(xpl::Connection_tcpip));
173
174 ASSERT_EQ(ER_X_CAPABILITIES_PREPARE_FAILED, sut.set(s.m_any).error);
175 }
176
177 INSTANTIATE_TEST_CASE_P(
178 SuccessInstantiation, SuccessSetCapabilityHanderTlsTestSuite,
179 ::testing::Values(Set_params(true, false), Set_params(1, false),
180 Set_params(2, false), Set_params(3u, false),
181 Set_params(1.0, false)));
182
183 class FaildSetCapabilityHanderTlsTestSuite
184 : public SuccessSetCapabilityHanderTlsTestSuite {};
185
TEST_P(FaildSetCapabilityHanderTlsTestSuite,get_failure_forValidParameters)186 TEST_P(FaildSetCapabilityHanderTlsTestSuite, get_failure_forValidParameters) {
187 Set_params s = GetParam();
188
189 EXPECT_CALL(mock_connection, get_type())
190 .WillRepeatedly(
191 Return(s.m_tls_active ? xpl::Connection_tls : xpl::Connection_tcpip));
192
193 ASSERT_EQ(ER_X_CAPABILITIES_PREPARE_FAILED, sut.set(s.m_any).error);
194
195 sut.commit();
196 }
197
198 INSTANTIATE_TEST_CASE_P(
199 FaildInstantiationAlreadySet, FaildSetCapabilityHanderTlsTestSuite,
200 ::testing::Values(Set_params(true, true), Set_params(1, true),
201 Set_params(2, true), Set_params(3u, true),
202 Set_params(1.0, true)));
203
204 INSTANTIATE_TEST_CASE_P(
205 FaildInstantiationCantDisable, FaildSetCapabilityHanderTlsTestSuite,
206 ::testing::Values(Set_params(false, true), Set_params(0, true),
207 Set_params(0u, true), Set_params(0.0, true)));
208
209 INSTANTIATE_TEST_CASE_P(FaildInstantiationAlreadyDisabled,
210 FaildSetCapabilityHanderTlsTestSuite,
211 ::testing::Values(Set_params(0, false),
212 Set_params(false, false)));
213
214 class CapabilityHanderAuthMechTestSuite : public Test {
215 public:
CapabilityHanderAuthMechTestSuite()216 CapabilityHanderAuthMechTestSuite() : sut(mock_client) {
217 mock_server = std::make_shared<StrictMock<Mock_server>>();
218
219 EXPECT_CALL(mock_client, connection())
220 .WillRepeatedly(ReturnRef(mock_connection));
221 EXPECT_CALL(mock_client, server()).WillRepeatedly(ReturnRef(*mock_server));
222 }
223
224 std::shared_ptr<StrictMock<Mock_server>> mock_server;
225
226 StrictMock<Mock_vio> mock_connection;
227 StrictMock<Mock_client> mock_client;
228
229 Capability_auth_mech sut;
230 };
231
TEST_F(CapabilityHanderAuthMechTestSuite,isSupported_returnsTrue_always)232 TEST_F(CapabilityHanderAuthMechTestSuite, isSupported_returnsTrue_always) {
233 ASSERT_TRUE(sut.is_supported());
234 }
235
TEST_F(CapabilityHanderAuthMechTestSuite,set_returnsFalse_always)236 TEST_F(CapabilityHanderAuthMechTestSuite, set_returnsFalse_always) {
237 Set_params set(1, false);
238
239 ASSERT_EQ(ER_X_CAPABILITIES_PREPARE_FAILED, sut.set(set.m_any).error);
240 }
241
TEST_F(CapabilityHanderAuthMechTestSuite,commit_doesNothing_always)242 TEST_F(CapabilityHanderAuthMechTestSuite, commit_doesNothing_always) {
243 sut.commit();
244 }
245
TEST_F(CapabilityHanderAuthMechTestSuite,name)246 TEST_F(CapabilityHanderAuthMechTestSuite, name) {
247 ASSERT_STREQ("authentication.mechanisms", sut.name().c_str());
248 }
249
TEST_F(CapabilityHanderAuthMechTestSuite,get_doesNothing_whenEmptySetReceive)250 TEST_F(CapabilityHanderAuthMechTestSuite, get_doesNothing_whenEmptySetReceive) {
251 std::vector<std::string> names{};
252 ::Mysqlx::Datatypes::Any any;
253 Mock_authentication_container mock_auth;
254
255 EXPECT_CALL(*mock_server, get_authentications())
256 .WillOnce(ReturnRef(mock_auth));
257
258 EXPECT_CALL(mock_auth, get_authentication_mechanisms(&mock_client))
259 .WillOnce(Return(names));
260 sut.get(&any);
261
262 ASSERT_EQ(::Mysqlx::Datatypes::Any::ARRAY, any.type());
263 EXPECT_EQ(0, any.array().value_size());
264 }
265
TEST_F(CapabilityHanderAuthMechTestSuite,get_returnAuthMethodsFromServer_always)266 TEST_F(CapabilityHanderAuthMechTestSuite,
267 get_returnAuthMethodsFromServer_always) {
268 std::vector<std::string> names{"first", "second"};
269 ::Mysqlx::Datatypes::Any any;
270
271 StrictMock<Mock_authentication_container> mock_auth;
272
273 EXPECT_CALL(*mock_server, get_authentications())
274 .WillOnce(ReturnRef(mock_auth));
275
276 EXPECT_CALL(mock_auth, get_authentication_mechanisms(_))
277 .WillOnce(Return(names));
278
279 sut.get(&any);
280
281 ASSERT_EQ(::Mysqlx::Datatypes::Any::ARRAY, any.type());
282 ASSERT_EQ(static_cast<int>(names.size()), any.array().value_size());
283
284 for (std::size_t i = 0; i < names.size(); ++i) {
285 const auto &a = any.array().value(static_cast<int>(i));
286
287 ASSERT_EQ(::Mysqlx::Datatypes::Any::SCALAR, a.type());
288 ASSERT_EQ(::Mysqlx::Datatypes::Scalar::V_STRING, a.scalar().type());
289 ASSERT_STREQ(names[i].c_str(), a.scalar().v_string().value().c_str());
290 }
291 }
292
293 class Capability_hander_client_interactive_test_suite : public Test {
294 public:
295 Capability_hander_client_interactive_test_suite() = default;
296
SetUp()297 void SetUp() {
298 EXPECT_CALL(mock_client, is_interactive()).WillOnce(Return(false));
299 sut.reset(new Capability_client_interactive(mock_client));
300 }
301
302 std::unique_ptr<Capability_client_interactive> sut;
303 StrictMock<Mock_client> mock_client;
304 };
305
TEST_F(Capability_hander_client_interactive_test_suite,is_supported_returns_true_always)306 TEST_F(Capability_hander_client_interactive_test_suite,
307 is_supported_returns_true_always) {
308 ASSERT_TRUE(sut->is_supported());
309 }
310
TEST_F(Capability_hander_client_interactive_test_suite,name_returns_client_interactive_always)311 TEST_F(Capability_hander_client_interactive_test_suite,
312 name_returns_client_interactive_always) {
313 ASSERT_STREQ("client.interactive", sut->name().c_str());
314 }
315
TEST_F(Capability_hander_client_interactive_test_suite,get_when_client_is_interactive)316 TEST_F(Capability_hander_client_interactive_test_suite,
317 get_when_client_is_interactive) {
318 EXPECT_CALL(mock_client, is_interactive()).WillOnce(Return(true));
319 sut.reset(new Capability_client_interactive(mock_client));
320
321 const bool expected_result = true;
322 ::Mysqlx::Datatypes::Any any;
323
324 sut->get(&any);
325
326 ASSERT_EQ(::Mysqlx::Datatypes::Any::SCALAR, any.type());
327 ASSERT_EQ(::Mysqlx::Datatypes::Scalar::V_BOOL, any.scalar().type());
328 ASSERT_EQ(expected_result, any.scalar().v_bool());
329 }
330
TEST_F(Capability_hander_client_interactive_test_suite,get_when_client_is_not_interactive)331 TEST_F(Capability_hander_client_interactive_test_suite,
332 get_when_client_is_not_interactive) {
333 EXPECT_CALL(mock_client, is_interactive()).WillOnce(Return(false));
334 sut.reset(new Capability_client_interactive(mock_client));
335
336 const bool expected_result = false;
337 ::Mysqlx::Datatypes::Any any;
338
339 sut->get(&any);
340
341 ASSERT_EQ(::Mysqlx::Datatypes::Any::SCALAR, any.type());
342 ASSERT_EQ(::Mysqlx::Datatypes::Scalar::V_BOOL, any.scalar().type());
343 ASSERT_EQ(expected_result, any.scalar().v_bool());
344 }
345
TEST_F(Capability_hander_client_interactive_test_suite,set_and_commit_valid_type)346 TEST_F(Capability_hander_client_interactive_test_suite,
347 set_and_commit_valid_type) {
348 Any any{Scalar{true}};
349
350 ASSERT_EQ(ER_X_SUCCESS, sut->set(any).error);
351
352 EXPECT_CALL(mock_client, set_is_interactive(true));
353
354 sut->commit();
355 }
356
TEST_F(Capability_hander_client_interactive_test_suite,set_and_commit_invalid_type)357 TEST_F(Capability_hander_client_interactive_test_suite,
358 set_and_commit_invalid_type) {
359 Any any{Scalar{"invalid"}};
360
361 ASSERT_EQ(ER_X_CAPABILITIES_PREPARE_FAILED, sut->set(any).error);
362
363 EXPECT_CALL(mock_client, set_is_interactive(false));
364
365 sut->commit();
366 }
367
368 class Capability_handler_connection_attributes : public Test {
369 public:
SetUp()370 void SetUp() override {
371 ASSERT_EQ(ER_X_CAPABILITIES_PREPARE_FAILED, m_sut.set(m_any).error);
372 }
373
374 Any m_any;
375 Capability_connection_attributes m_sut;
376 };
377
TEST_F(Capability_handler_connection_attributes,is_supported)378 TEST_F(Capability_handler_connection_attributes, is_supported) {
379 ASSERT_TRUE(m_sut.is_supported());
380 }
381
TEST_F(Capability_handler_connection_attributes,set_invalid_capability_empty_object)382 TEST_F(Capability_handler_connection_attributes,
383 set_invalid_capability_empty_object) {
384 const auto empty_obj = Any::Object{};
385 m_any = Any{empty_obj};
386 ASSERT_EQ(ER_X_CAPABILITIES_PREPARE_FAILED, m_sut.set(m_any).error);
387 }
TEST_F(Capability_handler_connection_attributes,set_invalid_capability_empty_field)388 TEST_F(Capability_handler_connection_attributes,
389 set_invalid_capability_empty_field) {
390 const Any::Object::Fld field{};
391 const Any::Object obj{field};
392 m_any = Any{obj};
393 ASSERT_EQ(ER_X_CAPABILITIES_PREPARE_FAILED, m_sut.set(m_any).error);
394 }
395
TEST_F(Capability_handler_connection_attributes,set_invalid_capability_field_with_empty_value)396 TEST_F(Capability_handler_connection_attributes,
397 set_invalid_capability_field_with_empty_value) {
398 const Any::Object::Fld field{"some_key", {}};
399 const Any::Object obj{field};
400 m_any = Any{obj};
401 ASSERT_EQ(ER_X_CAPABILITIES_PREPARE_FAILED, m_sut.set(m_any).error);
402 }
403
TEST_F(Capability_handler_connection_attributes,set_invalid_capability_field_with_empty_scalar)404 TEST_F(Capability_handler_connection_attributes,
405 set_invalid_capability_field_with_empty_scalar) {
406 Scalar empty_scalar;
407 Any value{empty_scalar};
408 const Any::Object::Fld field{"some_key", value};
409 const Any::Object obj{field};
410 m_any = Any{obj};
411 ASSERT_EQ(ER_X_BAD_CONNECTION_SESSION_ATTRIBUTE_TYPE, m_sut.set(m_any).error);
412 }
413
TEST_F(Capability_handler_connection_attributes,set_invalid_capability_field_with_scalar_other_than_string)414 TEST_F(Capability_handler_connection_attributes,
415 set_invalid_capability_field_with_scalar_other_than_string) {
416 Scalar scalar{true};
417 Any value{scalar};
418 const Any::Object::Fld field{"some_key", value};
419 const Any::Object obj{field};
420 m_any = Any{obj};
421 ASSERT_EQ(ER_X_BAD_CONNECTION_SESSION_ATTRIBUTE_TYPE, m_sut.set(m_any).error);
422 }
423
TEST_F(Capability_handler_connection_attributes,set_invalid_capability_field_with_empty_string_scalar)424 TEST_F(Capability_handler_connection_attributes,
425 set_invalid_capability_field_with_empty_string_scalar) {
426 ::Mysqlx::Datatypes::Object obj;
427 ::Mysqlx::Datatypes::Any value;
428 ::Mysqlx::Datatypes::Scalar scalar;
429 ::Mysqlx::Datatypes::Scalar_String empty_scalar_string;
430 scalar.mutable_v_string()->CopyFrom(empty_scalar_string);
431 value.mutable_scalar()->CopyFrom(scalar);
432 auto field = obj.add_fld();
433 field->set_key("some_key");
434 field->mutable_value()->CopyFrom(value);
435 ::Mysqlx::Datatypes::Any any;
436 any.mutable_obj()->CopyFrom(obj);
437 ASSERT_EQ(ER_X_BAD_CONNECTION_SESSION_ATTRIBUTE_TYPE, m_sut.set(any).error);
438 }
439
TEST_F(Capability_handler_connection_attributes,set_invalid_capability_field_without_a_key)440 TEST_F(Capability_handler_connection_attributes,
441 set_invalid_capability_field_without_a_key) {
442 ::Mysqlx::Datatypes::Object obj;
443 ::Mysqlx::Datatypes::Any value;
444 ::Mysqlx::Datatypes::Scalar scalar;
445 ::Mysqlx::Datatypes::Scalar_String scalar_string;
446 scalar_string.set_value("some value");
447 scalar.mutable_v_string()->CopyFrom(scalar_string);
448 value.mutable_scalar()->CopyFrom(scalar);
449 auto field = obj.add_fld();
450 field->mutable_value()->CopyFrom(value);
451 ::Mysqlx::Datatypes::Any any;
452 any.mutable_obj()->CopyFrom(obj);
453 ASSERT_EQ(ER_X_CAPABILITIES_PREPARE_FAILED, m_sut.set(any).error);
454 }
455
TEST_F(Capability_handler_connection_attributes,key_max_size_exceeded)456 TEST_F(Capability_handler_connection_attributes, key_max_size_exceeded) {
457 Scalar::String scalar_string{"some value"};
458 Scalar scalar{scalar_string};
459 Any value{scalar};
460 std::string long_string(128, 'x');
461 const Any::Object::Fld field{long_string, value};
462 const Any::Object obj{field};
463 m_any = Any{obj};
464 ASSERT_EQ(ER_X_BAD_CONNECTION_SESSION_ATTRIBUTE_KEY_LENGTH,
465 m_sut.set(m_any).error);
466 }
467
TEST_F(Capability_handler_connection_attributes,empty_key)468 TEST_F(Capability_handler_connection_attributes, empty_key) {
469 Scalar::String scalar_string{"some value"};
470 Scalar scalar{scalar_string};
471 Any value{scalar};
472 const Any::Object::Fld field{"", value};
473 const Any::Object obj{field};
474 m_any = Any{obj};
475 ASSERT_EQ(ER_X_BAD_CONNECTION_SESSION_ATTRIBUTE_EMPTY_KEY,
476 m_sut.set(m_any).error);
477 }
478
TEST_F(Capability_handler_connection_attributes,value_max_size_exceeded)479 TEST_F(Capability_handler_connection_attributes, value_max_size_exceeded) {
480 std::string long_string(2048, 'x');
481 Scalar::String long_scalar_string{long_string};
482 Scalar scalar{long_scalar_string};
483 Any value{scalar};
484 const Any::Object::Fld field{"some key", value};
485 const Any::Object obj{field};
486 m_any = Any{obj};
487 ASSERT_EQ(ER_X_BAD_CONNECTION_SESSION_ATTRIBUTE_VALUE_LENGTH,
488 m_sut.set(m_any).error);
489 }
490
TEST_F(Capability_handler_connection_attributes,set_one_key_value_pair)491 TEST_F(Capability_handler_connection_attributes, set_one_key_value_pair) {
492 Scalar::String scalar_string{"some value"};
493 Scalar scalar{scalar_string};
494 Any value{scalar};
495 const Any::Object::Fld field{"some key", value};
496 const Any::Object obj{field};
497 m_any = Any{obj};
498 ASSERT_EQ(ER_X_SUCCESS, m_sut.set(m_any).error);
499 }
500
TEST_F(Capability_handler_connection_attributes,set_two_key_value_pairs)501 TEST_F(Capability_handler_connection_attributes, set_two_key_value_pairs) {
502 Scalar::String scalar_string1{"some value"};
503 Scalar::String scalar_string2{"other value"};
504 Scalar scalar1{scalar_string1};
505 Scalar scalar2{scalar_string1};
506 Any value1{scalar1};
507 Any value2{scalar2};
508 const Any::Object::Fld field1{"some key", value1};
509 const Any::Object::Fld field2{"other key", value2};
510 const Any::Object obj{{field1, field2}};
511 m_any = Any{obj};
512 ASSERT_EQ(ER_X_SUCCESS, m_sut.set(m_any).error);
513 }
514
515 } // namespace test
516
517 } // namespace xpl
518