caa72bea40e78276cd4dcc0cd2e7e6e91ed4588d
[profile/ivi/smartdevicelink.git] / src / components / policy / test / policy / src / test_sql_pt_representation.cc
1 /* Copyright (c) 2013, Ford Motor Company
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following
12  * disclaimer in the documentation and/or other materials provided with the
13  * distribution.
14  *
15  * Neither the name of the Ford Motor Company nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include <gtest/gtest.h>
33 #ifdef __QNX__
34 #  include <qdb/qdb.h>
35 #else  // __QNX__
36 #  include <sqlite3.h>
37 #endif  // __QNX__
38 #include <vector>
39 #include "json/value.h"
40 #include "policy/sql_pt_representation.h"
41 #include "policy/policy_types.h"
42 #include "policy_table_interface_base/types.h"
43 #include "policy_table_interface_base/enums.h"
44
45 using policy::SQLPTRepresentation;
46 using policy::CheckPermissionResult;
47 using policy::EndpointUrls;
48
49 namespace test {
50 namespace components {
51 namespace policy {
52
53 #ifdef __QNX__
54 class DBMS {
55  public:
56   bool Open() {
57     conn_ = qdb_connect(kDatabaseName_.c_str(), 0);
58     return conn_ != NULL;
59   }
60   void Close() {
61     qdb_disconnect(conn_);
62   }
63   bool Exec(const char* query) {
64     return -1 != qdb_statement(conn_, query);
65   }
66  private:
67   static qdb_hdl_t* conn_;
68   static const std::string kDatabaseName_;
69 };
70 qdb_hdl_t* DBMS::conn_ = 0;
71 const std::string DBMS::kDatabaseName_ = "policy";
72 #else  // __QNX__
73 class DBMS {
74  public:
75   bool Open() {
76     return SQLITE_OK == sqlite3_open(kFileName_.c_str(), &conn_);
77   }
78   void Close() {
79     sqlite3_close(conn_);
80     remove(kFileName_.c_str());
81   }
82   bool Exec(const char* query) {
83     return SQLITE_OK == sqlite3_exec(conn_, query, NULL, NULL, NULL);
84   }
85  private:
86   static sqlite3* conn_;
87   static const std::string kFileName_;
88 };
89 sqlite3* DBMS::conn_ = 0;
90 const std::string DBMS::kFileName_ = "policy.sqlite";
91 #endif  // __QNX__
92
93 class SQLPTRepresentationTest : public ::testing::Test {
94  protected:
95   static DBMS* dbms;
96   static SQLPTRepresentation* reps;
97
98   static void SetUpTestCase() {
99     reps = new SQLPTRepresentation;
100     dbms = new DBMS;
101     EXPECT_EQ(::policy::SUCCESS, reps->Init());
102     EXPECT_TRUE(dbms->Open());
103   }
104
105   static void TearDownTestCase() {
106     EXPECT_TRUE(reps->Clear());
107     EXPECT_TRUE(reps->Close());
108     delete reps;
109     dbms->Close();
110   }
111 };
112
113 DBMS* SQLPTRepresentationTest::dbms = 0;
114 SQLPTRepresentation* SQLPTRepresentationTest::reps = 0;
115
116 ::testing::AssertionResult IsValid(const policy_table::Table &table) {
117   if (table.is_valid()) {
118     return ::testing::AssertionSuccess();
119   } else {
120     ::rpc::ValidationReport report(" - table");
121     table.ReportErrors(&report);
122     return ::testing::AssertionFailure() << ::rpc::PrettyFormat(report);
123   }
124 }
125
126 TEST_F(SQLPTRepresentationTest, CheckPermissionsAllowed) {
127   const char* query = "INSERT OR REPLACE INTO `application` (`id`, `memory_kb`,"
128       " `watchdog_timer_ms`) VALUES ('12345', 5, 10); "
129       "INSERT OR REPLACE INTO functional_group (`id`, `name`)"
130       "  VALUES (1, 'Base-4'); "
131       "INSERT OR REPLACE INTO `app_group` (`application_id`,"
132       " `functional_group_id`) VALUES ('12345', 1); "
133       "INSERT OR REPLACE INTO `rpc` (`name`, `parameter`, `hmi_level_value`,"
134       " `functional_group_id`) VALUES ('Update', 'gps', 'FULL', 1); "
135       "INSERT OR REPLACE INTO `rpc` (`name`, `parameter`, `hmi_level_value`,"
136       " `functional_group_id`) VALUES ('Update', 'speed', 'FULL', 1);";
137   ASSERT_TRUE(dbms->Exec(query));
138
139   CheckPermissionResult ret;
140   ret = reps->CheckPermissions("12345", "FULL", "Update");
141   EXPECT_TRUE(ret.hmi_level_permitted == ::policy::kRpcAllowed);
142   ASSERT_EQ(2, ret.list_of_allowed_params->size());
143   EXPECT_EQ("gps", (*ret.list_of_allowed_params)[0]);
144   EXPECT_EQ("speed", (*ret.list_of_allowed_params)[1]);
145 }
146
147 TEST_F(SQLPTRepresentationTest, CheckPermissionsAllowedWithoutParameters) {
148   const char* query = "INSERT OR REPLACE INTO `application` (`id`, `memory_kb`,"
149       " `watchdog_timer_ms`) VALUES ('12345', 5, 10); "
150       "INSERT OR REPLACE INTO functional_group (`id`, `name`)"
151       "  VALUES (1, 'Base-4'); "
152       "INSERT OR REPLACE INTO `app_group` (`application_id`,"
153       " `functional_group_id`) VALUES ('12345', 1); "
154       "DELETE FROM `rpc`; "
155       "INSERT OR REPLACE INTO `rpc` (`name`, `hmi_level_value`,"
156       " `functional_group_id`) VALUES ('Update', 'LIMITED', 1);";
157   ASSERT_TRUE(dbms->Exec(query));
158
159   CheckPermissionResult ret;
160   ret = reps->CheckPermissions("12345", "LIMITED", "Update");
161   EXPECT_TRUE(ret.hmi_level_permitted == ::policy::kRpcAllowed);
162   EXPECT_TRUE(!ret.list_of_allowed_params);
163 }
164
165 TEST_F(SQLPTRepresentationTest, CheckPermissionsDisallowed) {
166   const char* query = "DELETE FROM `app_group`";
167   ASSERT_TRUE(dbms->Exec(query));
168
169   CheckPermissionResult ret;
170   ret = reps->CheckPermissions("12345", "FULL", "Update");
171   EXPECT_EQ(::policy::kRpcDisallowed, ret.hmi_level_permitted);
172   EXPECT_TRUE(!ret.list_of_allowed_params);
173 }
174
175 TEST_F(SQLPTRepresentationTest, IsPTPReloaded) {
176   const char* query = "UPDATE `module_config` SET `preloaded_pt` = 1";
177   ASSERT_TRUE(dbms->Exec(query));
178   EXPECT_TRUE(reps->IsPTPreloaded());
179 }
180
181 TEST_F(SQLPTRepresentationTest, GetUpdateUrls) {
182   const char* query_delete = "DELETE FROM `endpoint`; ";
183   ASSERT_TRUE(dbms->Exec(query_delete));
184   EndpointUrls ret = reps->GetUpdateUrls(7);
185   EXPECT_TRUE(ret.empty());
186
187   const char* query_insert =
188       "INSERT INTO `endpoint` (`application_id`, `url`, `service`) "
189           "  VALUES ('12345', 'http://ford.com/cloud/1', '0x07');"
190           "INSERT INTO `endpoint` (`application_id`, `url`, `service`) "
191           "  VALUES ('12345', 'http://ford.com/cloud/2', '0x07');";
192
193   ASSERT_TRUE(dbms->Exec(query_insert));
194   ret = reps->GetUpdateUrls(7);
195   ASSERT_EQ(2, ret.size());
196   EXPECT_EQ("http://ford.com/cloud/1", ret[0].url);
197   EXPECT_EQ("http://ford.com/cloud/2", ret[1].url);
198
199   ret = reps->GetUpdateUrls(0);
200   EXPECT_TRUE(ret.empty());
201 }
202
203 TEST_F(SQLPTRepresentationTest, IgnitionCyclesBeforeExchangeAndIncrement) {
204   const char* query_zeros = "UPDATE `module_meta` SET "
205       "  `ignition_cycles_since_last_exchange` = 0; "
206       "  UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = 0";
207   ASSERT_TRUE(dbms->Exec(query_zeros));
208   EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
209   reps->IncrementIgnitionCycles();
210   EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
211
212   const char* query_less_limit = "UPDATE `module_meta` SET "
213       "  `ignition_cycles_since_last_exchange` = 5; "
214       "  UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = 10";
215   ASSERT_TRUE(dbms->Exec(query_less_limit));
216   EXPECT_EQ(5, reps->IgnitionCyclesBeforeExchange());
217   reps->IncrementIgnitionCycles();
218   EXPECT_EQ(4, reps->IgnitionCyclesBeforeExchange());
219
220   const char* query_limit = "UPDATE `module_meta` SET "
221       "  `ignition_cycles_since_last_exchange` = 9; "
222       "  UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = 10";
223   ASSERT_TRUE(dbms->Exec(query_limit));
224   EXPECT_EQ(1, reps->IgnitionCyclesBeforeExchange());
225   reps->IncrementIgnitionCycles();
226   EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
227
228   const char* query_more_limit = "UPDATE `module_meta` SET "
229       "  `ignition_cycles_since_last_exchange` = 12; "
230       "  UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = 10";
231   ASSERT_TRUE(dbms->Exec(query_more_limit));
232   EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
233
234   const char* query_negative_limit = "UPDATE `module_meta` SET "
235       "  `ignition_cycles_since_last_exchange` = 3; "
236       "  UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = -1";
237   ASSERT_TRUE(dbms->Exec(query_negative_limit));
238   EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
239
240   const char* query_negative_current = "UPDATE `module_meta` SET "
241       "  `ignition_cycles_since_last_exchange` = -1; "
242       "  UPDATE `module_config` SET `exchange_after_x_ignition_cycles` = 2";
243   ASSERT_TRUE(dbms->Exec(query_negative_current));
244   EXPECT_EQ(0, reps->IgnitionCyclesBeforeExchange());
245 }
246
247 TEST_F(SQLPTRepresentationTest, KilometersBeforeExchange) {
248   const char* query_zeros = "UPDATE `module_meta` SET "
249       "  `pt_exchanged_at_odometer_x` = 0; "
250       "  UPDATE `module_config` SET `exchange_after_x_kilometers` = 0";
251   ASSERT_TRUE(dbms->Exec(query_zeros));
252   EXPECT_EQ(0, reps->KilometersBeforeExchange(0));
253   EXPECT_EQ(0, reps->KilometersBeforeExchange(-10));
254   EXPECT_EQ(0, reps->KilometersBeforeExchange(10));
255
256   const char* query_negative_limit = "UPDATE `module_meta` SET "
257       "  `pt_exchanged_at_odometer_x` = 10; "
258       "  UPDATE `module_config` SET `exchange_after_x_kilometers` = -10";
259   ASSERT_TRUE(dbms->Exec(query_negative_limit));
260   EXPECT_EQ(0, reps->KilometersBeforeExchange(0));
261   EXPECT_EQ(0, reps->KilometersBeforeExchange(10));
262
263   const char* query_negative_last = "UPDATE `module_meta` SET "
264       "  `pt_exchanged_at_odometer_x` = -10; "
265       "  UPDATE `module_config` SET `exchange_after_x_kilometers` = 20";
266   ASSERT_TRUE(dbms->Exec(query_negative_last));
267   EXPECT_EQ(0, reps->KilometersBeforeExchange(0));
268   EXPECT_EQ(0, reps->KilometersBeforeExchange(10));
269
270   const char* query_limit = "UPDATE `module_meta` SET "
271       "  `pt_exchanged_at_odometer_x` = 10; "
272       "  UPDATE `module_config` SET `exchange_after_x_kilometers` = 100";
273   ASSERT_TRUE(dbms->Exec(query_limit));
274   EXPECT_EQ(0, reps->KilometersBeforeExchange(120));
275   EXPECT_EQ(60, reps->KilometersBeforeExchange(50));
276   EXPECT_EQ(0, reps->KilometersBeforeExchange(5));
277 }
278
279 TEST_F(SQLPTRepresentationTest, DaysBeforeExchange) {
280   const char* query_zeros = "UPDATE `module_meta` SET "
281       "  `pt_exchanged_x_days_after_epoch` = 0; "
282       "  UPDATE `module_config` SET `exchange_after_x_days` = 0";
283   ASSERT_TRUE(dbms->Exec(query_zeros));
284   EXPECT_EQ(0, reps->DaysBeforeExchange(0));
285   EXPECT_EQ(0, reps->DaysBeforeExchange(-10));
286   EXPECT_EQ(0, reps->DaysBeforeExchange(10));
287
288   const char* query_negative_limit = "UPDATE `module_meta` SET "
289       "  `pt_exchanged_x_days_after_epoch` = 10; "
290       "  UPDATE `module_config` SET `exchange_after_x_days` = -10";
291   ASSERT_TRUE(dbms->Exec(query_negative_limit));
292   EXPECT_EQ(0, reps->DaysBeforeExchange(0));
293   EXPECT_EQ(0, reps->DaysBeforeExchange(10));
294
295   const char* query_negative_last = "UPDATE `module_meta` SET "
296       "  `pt_exchanged_x_days_after_epoch` = -10; "
297       "  UPDATE `module_config` SET `exchange_after_x_days` = 20";
298   ASSERT_TRUE(dbms->Exec(query_negative_last));
299   EXPECT_EQ(0, reps->DaysBeforeExchange(0));
300   EXPECT_EQ(0, reps->DaysBeforeExchange(10));
301
302   const char* query_limit = "UPDATE `module_meta` SET "
303       "  `pt_exchanged_x_days_after_epoch` = 10; "
304       "  UPDATE `module_config` SET `exchange_after_x_days` = 100";
305   ASSERT_TRUE(dbms->Exec(query_limit));
306   EXPECT_EQ(0, reps->DaysBeforeExchange(120));
307   EXPECT_EQ(60, reps->DaysBeforeExchange(50));
308   EXPECT_EQ(0, reps->DaysBeforeExchange(5));
309 }
310
311 TEST_F(SQLPTRepresentationTest, SecondsBetweenRetries) {
312   std::vector<int> seconds;
313
314   const char* query_delete = "DELETE FROM `seconds_between_retry`; ";
315   ASSERT_TRUE(dbms->Exec(query_delete));
316   ASSERT_TRUE(reps->SecondsBetweenRetries(&seconds));
317   EXPECT_EQ(0, seconds.size());
318
319   const char* query_insert =
320       "INSERT INTO `seconds_between_retry` (`index`, `value`) "
321           "  VALUES (0, 10); "
322           "INSERT INTO `seconds_between_retry` (`index`, `value`) "
323           "  VALUES (1, 20); ";
324   ASSERT_TRUE(dbms->Exec(query_insert));
325   ASSERT_TRUE(reps->SecondsBetweenRetries(&seconds));
326   ASSERT_EQ(2, seconds.size());
327   EXPECT_EQ(10, seconds[0]);
328   EXPECT_EQ(20, seconds[1]);
329 }
330
331 TEST_F(SQLPTRepresentationTest, TimeoutResponse) {
332   const char* query =
333       "UPDATE `module_config` SET `timeout_after_x_seconds` = 60";
334   ASSERT_TRUE(dbms->Exec(query));
335   EXPECT_EQ(60, reps->TimeoutResponse());
336 }
337
338 #ifndef EXTENDED_POLICY
339 TEST_F(SQLPTRepresentationTest, SaveGenerateSnapshot) {
340   Json::Value expect(Json::objectValue);
341   expect["policy_table"] = Json::Value(Json::objectValue);
342
343   Json::Value& policy_table = expect["policy_table"];
344   policy_table["module_meta"] = Json::Value(Json::objectValue);
345   policy_table["module_config"] = Json::Value(Json::objectValue);
346   policy_table["usage_and_error_counts"] = Json::Value(Json::objectValue);
347   policy_table["device_data"] = Json::Value(Json::objectValue);
348   policy_table["functional_groupings"] = Json::Value(Json::objectValue);
349   policy_table["consumer_friendly_messages"] = Json::Value(Json::objectValue);
350   policy_table["app_policies"] = Json::Value(Json::objectValue);
351
352   Json::Value& module_config = policy_table["module_config"];
353   module_config["preloaded_pt"] = Json::Value(true);
354   module_config["exchange_after_x_ignition_cycles"] = Json::Value(10);
355   module_config["exchange_after_x_kilometers"] = Json::Value(100);
356   module_config["exchange_after_x_days"] = Json::Value(5);
357   module_config["timeout_after_x_seconds"] = Json::Value(500);
358   module_config["seconds_between_retries"] = Json::Value(Json::arrayValue);
359   module_config["seconds_between_retries"][0] = Json::Value(10);
360   module_config["seconds_between_retries"][1] = Json::Value(20);
361   module_config["seconds_between_retries"][2] = Json::Value(30);
362   module_config["endpoints"] = Json::Value(Json::objectValue);
363   module_config["endpoints"]["0x00"] = Json::Value(Json::objectValue);
364   module_config["endpoints"]["0x00"]["default"] = Json::Value(Json::arrayValue);
365   module_config["endpoints"]["0x00"]["default"][0] = Json::Value(
366       "http://ford.com/cloud/default");
367   module_config["notifications_per_minute_by_priority"] = Json::Value(
368       Json::objectValue);
369   module_config["notifications_per_minute_by_priority"]["emergency"] =
370       Json::Value(1);
371   module_config["notifications_per_minute_by_priority"]["navigation"] =
372       Json::Value(2);
373   module_config["notifications_per_minute_by_priority"]["voiceCommunication"] =
374       Json::Value(3);
375   module_config["notifications_per_minute_by_priority"]["communication"] =
376       Json::Value(4);
377   module_config["notifications_per_minute_by_priority"]["normal"] = Json::Value(
378       5);
379   module_config["notifications_per_minute_by_priority"]["none"] = Json::Value(
380       6);
381   module_config["vehicle_make"] = Json::Value("MakeT");
382   module_config["vehicle_model"] = Json::Value("ModelT");
383   module_config["vehicle_year"] = Json::Value(2014);
384
385   Json::Value& usage_and_error_counts = policy_table["usage_and_error_counts"];
386   usage_and_error_counts["app_level"] = Json::Value(Json::objectValue);
387   usage_and_error_counts["app_level"]["12345"] = Json::Value(Json::objectValue);
388
389   Json::Value& device_data = policy_table["device_data"];
390   device_data["user_consent_records"] = Json::Value(Json::objectValue);
391
392   Json::Value& functional_groupings = policy_table["functional_groupings"];
393   functional_groupings["default"] = Json::Value(Json::objectValue);
394   Json::Value& default_group = functional_groupings["default"];
395   default_group["rpcs"] = Json::Value(Json::objectValue);
396   default_group["rpcs"]["Update"] = Json::Value(Json::objectValue);
397   default_group["rpcs"]["Update"]["hmi_levels"] = Json::Value(Json::arrayValue);
398   default_group["rpcs"]["Update"]["hmi_levels"][0] = Json::Value("FULL");
399   default_group["rpcs"]["Update"]["parameters"] = Json::Value(Json::arrayValue);
400   default_group["rpcs"]["Update"]["parameters"][0] = Json::Value("speed");
401
402   Json::Value& consumer_friendly_messages =
403       policy_table["consumer_friendly_messages"];
404   consumer_friendly_messages["version"] = Json::Value("1.2");
405
406   Json::Value& app12345counters = usage_and_error_counts["app_level"]["12345"];
407   app12345counters["app_registration_language_gui"] = "";
408   app12345counters["app_registration_language_vui"] = "";
409   app12345counters["count_of_rejected_rpc_calls"] = 0;
410   app12345counters["count_of_rejections_duplicate_name"] = 0;
411   app12345counters["count_of_rejections_nickname_mismatch"] = 0;
412   app12345counters["count_of_rejections_sync_out_of_memory"] = 0;
413   app12345counters["count_of_removals_for_bad_behavior"] = 0;
414   app12345counters["count_of_rfcom_limit_reached"] = 0;
415   app12345counters["count_of_rpcs_sent_in_hmi_none"] = 0;
416   app12345counters["count_of_run_attempts_while_revoked"] = 0;
417   app12345counters["count_of_user_selections"] = 0;
418   app12345counters["minutes_in_hmi_background"] = 0;
419   app12345counters["minutes_in_hmi_full"] = 0;
420   app12345counters["minutes_in_hmi_limited"] = 0;
421   app12345counters["minutes_in_hmi_none"] = 0;
422
423   Json::Value& app_policies = policy_table["app_policies"];
424   app_policies["default"] = Json::Value(Json::objectValue);
425   app_policies["default"]["memory_kb"] = Json::Value(50);
426   app_policies["default"]["watchdog_timer_ms"] = Json::Value(100);
427   app_policies["default"]["groups"] = Json::Value(Json::arrayValue);
428   app_policies["default"]["groups"][0] = Json::Value("default");
429
430   policy_table::Table table(&expect);
431
432   ASSERT_TRUE(IsValid(table));
433   ASSERT_TRUE(reps->Save(table));
434   utils::SharedPtr<policy_table::Table> snapshot = reps->GenerateSnapshot();
435   EXPECT_TRUE(IsValid(*snapshot));
436   EXPECT_EQ(table.ToJsonValue().toStyledString(),
437             snapshot->ToJsonValue().toStyledString());
438 }
439 #endif  // EXTENDED_POLICY
440
441 }  // namespace policy
442 }  // namespace components
443 }  // namespace test
444
445 int main(int argc, char** argv) {
446   testing::InitGoogleTest(&argc, argv);
447   return RUN_ALL_TESTS();
448 }