2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Kyungwook Tak <k.tak@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
19 * @author Maciej Karpiuk (m.karpiuk2@samsung.com)
23 #include <boost/test/unit_test.hpp>
24 #include <db-crypto.h>
25 #include <ckm/ckm-error.h>
26 #include <DBFixture.h>
30 using namespace std::chrono;
33 DBFixture::DBFixture()
35 BOOST_CHECK(unlink(m_crypto_db_fname) == 0 || errno == ENOENT);
38 DBFixture::DBFixture(const char *db_fname)
40 BOOST_CHECK(unlink(m_crypto_db_fname) == 0 || errno == ENOENT);
43 std::ifstream f1(db_fname, std::fstream::binary);
44 std::ofstream f2(m_crypto_db_fname, std::fstream::trunc | std::fstream::binary);
52 void DBFixture::init()
54 high_resolution_clock::time_point srand_feed = high_resolution_clock::now();
55 srand(srand_feed.time_since_epoch().count());
57 BOOST_REQUIRE_NO_THROW(m_db = DB::Crypto(m_crypto_db_fname, defaultPass));
60 double DBFixture::performance_get_time_elapsed_ms()
62 return duration_cast<milliseconds>(m_end_time - m_start_time).count();
65 void DBFixture::performance_start(const char *operation_name)
67 m_operation = std::string(operation_name ? operation_name : "unknown");
68 BOOST_TEST_MESSAGE("\t<performance> running " << m_operation <<
69 " performance test...");
70 m_start_time = high_resolution_clock::now();
73 void DBFixture::performance_stop(long num_operations_performed)
75 m_end_time = high_resolution_clock::now();
76 double time_elapsed_ms = performance_get_time_elapsed_ms();
77 BOOST_TEST_MESSAGE("\t<performance> time elapsed: " << time_elapsed_ms <<
78 "[ms], number of " << m_operation << ": " << num_operations_performed);
80 if (num_operations_performed > 0)
81 BOOST_TEST_MESSAGE("\t<performance> average time per " << m_operation << ": " <<
82 time_elapsed_ms / num_operations_performed << "[ms]");
85 void DBFixture::generate_name(unsigned int id, Name &output)
88 ss << "name_no_" << id;
92 void DBFixture::generate_owner(unsigned int id, ClientId &output)
95 ss << "owner_no_" << id;
99 void DBFixture::generate_perf_DB(unsigned int num_name,
100 unsigned int names_per_owner)
102 // to speed up data creation - cache the row
103 DB::Row rowPattern = create_default_row(DataType::BINARY_DATA);
104 rowPattern.data = RawBuffer(100, 20);
105 rowPattern.dataSize = rowPattern.data.size();
106 rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
108 for (unsigned int i = 0; i < num_name; i++) {
109 generate_name(i, rowPattern.name);
110 generate_owner(i / names_per_owner, rowPattern.owner);
112 BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
116 long DBFixture::add_full_access_rights(unsigned int num_name,
117 unsigned int num_name_per_owner)
120 unsigned int num_owners = num_name / num_name_per_owner;
122 ClientId owner, accessor;
124 for (unsigned int a = 0; a < num_name; a++) {
125 generate_name(a, name);
126 generate_owner(a / num_name_per_owner, owner);
128 for (unsigned int l = 0; l < num_owners; l++) {
130 if (l == (a / num_name_per_owner))
134 generate_owner(l, accessor);
135 add_permission(name, owner, accessor);
143 DB::Row DBFixture::create_default_row(DataType type)
145 return create_default_row(m_default_name, m_default_owner, type);
148 DB::Row DBFixture::create_default_row(const Name &name,
149 const ClientId &owner,
156 row.algorithmType = DBCMAlgType::AES_GCM_256;
158 row.iv = createDefaultPass();
159 row.encryptionScheme = 0;
161 row.backendId = CryptoBackend::OpenSSL;
166 void DBFixture::compare_row(const DB::Row &lhs, const DB::Row &rhs)
168 BOOST_CHECK_MESSAGE(lhs.name == rhs.name,
169 "namees didn't match! Got: " << rhs.name
170 << " , expected : " << lhs.name);
172 BOOST_CHECK_MESSAGE(lhs.owner == rhs.owner,
173 "owner didn't match! Got: " << rhs.owner
174 << " , expected : " << lhs.owner);
176 BOOST_CHECK_MESSAGE(lhs.exportable == rhs.exportable,
177 "exportable didn't match! Got: " << rhs.exportable
178 << " , expected : " << lhs.exportable);
180 BOOST_CHECK_MESSAGE(lhs.iv == rhs.iv,
181 "iv didn't match! Got: " << rhs.iv.size()
182 << " , expected : " << lhs.iv.size());
184 BOOST_CHECK_MESSAGE(lhs.data == rhs.data,
185 "data didn't match! Got: " << rhs.data.size()
186 << " , expected : " << lhs.data.size());
188 BOOST_CHECK_MESSAGE(lhs.backendId == rhs.backendId,
189 "backendId didn't match! Got: " << static_cast<int>(rhs.backendId)
190 << " , expected : " << static_cast<int>(lhs.backendId));
193 void DBFixture::check_DB_integrity(const DB::Row &rowPattern)
195 BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
197 DB::Crypto::RowOptional optional_row;
198 BOOST_REQUIRE_NO_THROW(optional_row = m_db.getRow("name", "owner",
199 DataType::BINARY_DATA));
200 BOOST_REQUIRE_MESSAGE(optional_row, "Select didn't return any row");
202 compare_row(*optional_row, rowPattern);
203 DB::Row name_duplicate = rowPattern;
204 name_duplicate.data = createDefaultPass();
205 name_duplicate.dataSize = name_duplicate.data.size();
208 BOOST_REQUIRE_NO_THROW(erased = m_db.deleteRow("name", "owner"));
209 BOOST_REQUIRE_MESSAGE(erased > 0, "Inserted row didn't exist in db");
211 DB::Crypto::RowOptional row_optional;
212 BOOST_REQUIRE_NO_THROW(row_optional = m_db.getRow("name", "owner",
213 DataType::BINARY_DATA));
214 BOOST_REQUIRE_MESSAGE(!row_optional,
215 "Select should not return row after deletion");
218 void DBFixture::insert_row()
220 insert_row(m_default_name, m_default_owner);
223 void DBFixture::insert_row(const Name &name, const ClientId &owner)
225 DB::Row rowPattern = create_default_row(name, owner,
226 DataType::BINARY_DATA);
227 rowPattern.data = RawBuffer(100, 20);
228 rowPattern.dataSize = rowPattern.data.size();
229 rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1);
230 BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern));
233 void DBFixture::delete_row(const Name &name, const ClientId &owner)
236 BOOST_REQUIRE_NO_THROW(exit_flag = m_db.deleteRow(name, owner));
237 BOOST_REQUIRE_MESSAGE(true == exit_flag, "remove name failed: no rows removed");
240 void DBFixture::add_permission(const Name &name, const ClientId &owner,
241 const ClientId &accessor)
243 BOOST_REQUIRE_NO_THROW(m_db.setPermission(name,
246 CKM::Permission::READ | CKM::Permission::REMOVE));
249 void DBFixture::read_row_expect_success(const Name &name,
250 const ClientId &owner)
252 DB::Crypto::RowOptional row;
253 BOOST_REQUIRE_NO_THROW(row = m_db.getRow(name, owner,
254 DataType::BINARY_DATA));
255 BOOST_REQUIRE_MESSAGE(row, "row is empty");
256 BOOST_REQUIRE_MESSAGE(row->name == name, "name is not valid");