1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 use std::{
17 cmp::Ordering,
18 fs::{self, OpenOptions},
19 io::Write,
20 path::Path,
21 };
22
23 use asset_common::CallingInfo;
24 use asset_definition::{ErrCode, Extension, Value};
25
26 use crate::{
27 database::Database,
28 table::Table,
29 types::{column, DbMap, QueryOptions, TABLE_NAME},
30 };
31
32 const DB_DATA: [(&str, Value); 9] = [
33 (column::OWNER_TYPE, Value::Number(1)),
34 (column::SYNC_TYPE, Value::Number(1)),
35 (column::ACCESSIBILITY, Value::Number(1)),
36 (column::AUTH_TYPE, Value::Number(1)),
37 (column::IS_PERSISTENT, Value::Bool(true)),
38 (column::VERSION, Value::Number(2)),
39 (column::REQUIRE_PASSWORD_SET, Value::Bool(false)),
40 (column::LOCAL_STATUS, Value::Number(0)),
41 (column::SYNC_STATUS, Value::Number(0)),
42 ];
43
44 const TEST_FILE: &str = "/data/asset_test/0";
45
create_dir()46 fn create_dir() {
47 let path = Path::new(TEST_FILE);
48 if !path.exists() {
49 fs::create_dir_all(path).unwrap();
50 }
51 }
52
remove_dir()53 fn remove_dir() {
54 let path = Path::new(TEST_FILE);
55 if path.exists() {
56 fs::remove_dir_all(path).unwrap();
57 }
58 }
59
open_db_and_insert_data() -> Database60 fn open_db_and_insert_data() -> Database {
61 create_dir();
62 let mut def = DbMap::from(DB_DATA);
63 add_bytes_column(&mut def);
64 let calling_info = CallingInfo::new_self();
65 let mut db = Database::build(&calling_info, false).unwrap();
66 let count = db.insert_datas(&def).unwrap();
67 assert_eq!(count, 1);
68 db
69 }
70
add_bytes_column(db_data: &mut DbMap)71 fn add_bytes_column(db_data: &mut DbMap) {
72 db_data.insert(column::SECRET, Value::Bytes(column::SECRET.as_bytes().to_vec()));
73 db_data.insert(column::ALIAS, Value::Bytes(column::ALIAS.as_bytes().to_vec()));
74 db_data.insert(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()));
75 db_data.insert(column::CREATE_TIME, Value::Bytes(column::CREATE_TIME.as_bytes().to_vec()));
76 db_data.insert(column::UPDATE_TIME, Value::Bytes(column::UPDATE_TIME.as_bytes().to_vec()));
77 }
78
backup_db(db: &Database)79 fn backup_db(db: &Database) {
80 fs::copy(&db.path, &db.backup_path).unwrap();
81 }
82
83 #[test]
create_and_drop_database()84 fn create_and_drop_database() {
85 fs::create_dir_all("/data/asset_test/0").unwrap();
86 let calling_info = CallingInfo::new_self();
87 let mut db = Database::build(&calling_info, false).unwrap();
88 backup_db(&db);
89 db.close_db();
90 assert!(Database::delete(0, &db.db_name).is_ok());
91 }
92
93 #[test]
database_version()94 fn database_version() {
95 fs::create_dir_all("/data/asset_test/0").unwrap();
96 let calling_info = CallingInfo::new_self();
97 let db = Database::build(&calling_info, false).unwrap();
98 assert_eq!(3, db.get_version().unwrap());
99 assert!(db.set_version(2).is_ok());
100 assert_eq!(2, db.get_version().unwrap());
101 let _ = Database::delete(0, &db.db_name);
102 }
103
104 #[test]
error_sql()105 fn error_sql() {
106 fs::create_dir_all("/data/asset_test/0").unwrap();
107 let calling_info = CallingInfo::new_self();
108 let db = Database::build(&calling_info, false).unwrap();
109 let sql = "pragma zzz user_version = {} mmm";
110 assert!(db.exec(sql).is_err());
111 let _ = Database::delete(0, &db.db_name);
112 }
113
114 #[test]
create_delete_asset_table()115 fn create_delete_asset_table() {
116 fs::create_dir_all("/data/asset_test/0").unwrap();
117 let calling_info = CallingInfo::new_self();
118 let mut db = Database::build(&calling_info, false).unwrap();
119 let table = Table::new(TABLE_NAME, &db);
120 assert!(table.exist().unwrap());
121 assert!(table.delete().is_ok());
122 assert!(!table.exist().unwrap());
123 db.close_db();
124 let _ = Database::delete(0, &db.db_name);
125 }
126
127 #[test]
insert_data_with_different_alias()128 fn insert_data_with_different_alias() {
129 create_dir();
130 let mut def = DbMap::from(DB_DATA);
131 add_bytes_column(&mut def);
132
133 let calling_info = CallingInfo::new_self();
134 let mut db = Database::build(&calling_info, false).unwrap();
135 let count = db.insert_datas(&def).unwrap();
136 assert_eq!(count, 1);
137
138 def.insert(column::ALIAS, Value::Bytes(b"Alias2".to_vec()));
139 let count = db.insert_datas(&def).unwrap();
140 assert_eq!(count, 1);
141
142 let ret = db
143 .query_datas(
144 &vec![],
145 &DbMap::from([(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()))]),
146 None,
147 false,
148 )
149 .unwrap();
150 assert_eq!(ret.len(), 2);
151 remove_dir();
152 }
153
154 #[test]
delete_data()155 fn delete_data() {
156 let mut db = open_db_and_insert_data();
157
158 let mut datas = DbMap::new();
159 datas.insert(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()));
160 datas.insert(column::ALIAS, Value::Bytes(column::ALIAS.as_bytes().to_vec()));
161
162 let ret = db.is_data_exists(&datas, false).unwrap();
163 assert!(ret);
164
165 let count = db.delete_datas(&datas, None, false).unwrap();
166 assert_eq!(count, 1);
167
168 let ret = db.is_data_exists(&datas, false).unwrap();
169 assert!(!ret);
170
171 remove_dir();
172 }
173
174 #[test]
update_data()175 fn update_data() {
176 let mut db = open_db_and_insert_data();
177
178 let mut datas = DbMap::new();
179 datas.insert(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()));
180 datas.insert(column::ALIAS, Value::Bytes(column::ALIAS.as_bytes().to_vec()));
181 let update_time: Vec<u8> = vec![2];
182 let count = db
183 .update_datas(&datas, true, &DbMap::from([(column::UPDATE_TIME, Value::Bytes(update_time.clone()))]))
184 .unwrap();
185 assert_eq!(count, 1);
186
187 let res = db.query_datas(&vec![], &datas, None, false).unwrap();
188 assert_eq!(res.len(), 1);
189 let query_update_time = res[0].get_bytes_attr(&column::UPDATE_TIME).unwrap();
190 assert_eq!(update_time.len(), query_update_time.len());
191 for (ins, qy) in update_time.iter().zip(query_update_time.iter()) {
192 assert_eq!(*ins, *qy);
193 }
194
195 remove_dir();
196 }
197
198 #[test]
query_ordered_data()199 fn query_ordered_data() {
200 // insert two data
201 create_dir();
202 let mut def = DbMap::from(DB_DATA);
203 add_bytes_column(&mut def);
204
205 let calling_info = CallingInfo::new_self();
206 let mut db = Database::build(&calling_info, false).unwrap();
207 let count = db.insert_datas(&def).unwrap();
208 assert_eq!(count, 1);
209
210 def.insert(column::ALIAS, Value::Bytes(b"AAA".to_vec()));
211 let count = db.insert_datas(&def).unwrap();
212 assert_eq!(count, 1);
213
214 // query data by order
215 let query = QueryOptions {
216 limit: Some(100),
217 offset: Some(0),
218 order: Some(Ordering::Greater),
219 order_by: Some(vec![column::ALIAS]),
220 amend: None,
221 };
222 let res = db
223 .query_datas(
224 &vec![column::ID, column::ALIAS],
225 &DbMap::from([(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()))]),
226 Some(&query),
227 false,
228 )
229 .unwrap();
230 assert_eq!(res.len(), 2);
231 assert_eq!(&(b"AAA".to_vec()), res[0].get_bytes_attr(&column::ALIAS).unwrap());
232
233 remove_dir();
234 }
235
236 #[test]
insert_error_data()237 fn insert_error_data() {
238 create_dir();
239 let mut datas = DbMap::new();
240 datas.insert(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()));
241 let calling_info = CallingInfo::new_self();
242 let mut db = Database::build(&calling_info, false).unwrap();
243 assert!(db.insert_datas(&datas).is_err());
244 remove_dir();
245 }
246
247 #[test]
backup_and_restore()248 fn backup_and_restore() {
249 let db = open_db_and_insert_data();
250 backup_db(&db);
251 drop(db);
252
253 // Destroy the main database.
254 let mut db_file =
255 OpenOptions::new().read(true).write(true).open("/data/asset_test/0/Native_asset_service_8100.db").unwrap();
256 let _ = db_file.write(b"buffer buffer buffer").unwrap();
257
258 // Recovery the main database.
259 let calling_info = CallingInfo::new_self();
260 let mut db = Database::build(&calling_info, false).unwrap();
261 let mut def = DbMap::from(DB_DATA);
262 add_bytes_column(&mut def);
263
264 db.query_datas(&vec![], &def, None, false).unwrap();
265 drop(db);
266 remove_dir();
267 }
268
269 #[test]
insert_duplicated_data()270 fn insert_duplicated_data() {
271 let mut db = open_db_and_insert_data();
272
273 let mut def = DbMap::from(DB_DATA);
274 add_bytes_column(&mut def);
275 assert_eq!(ErrCode::Duplicated, db.insert_datas(&def).unwrap_err().code);
276
277 drop(db);
278 remove_dir();
279 }
280
281 #[test]
query_mismatch_type_data()282 fn query_mismatch_type_data() {
283 create_dir();
284 let mut data = DbMap::from(DB_DATA);
285 add_bytes_column(&mut data);
286 data.insert(column::CREATE_TIME, Value::Number(1));
287 let calling_info = CallingInfo::new_self();
288 let mut db = Database::build(&calling_info, false).unwrap();
289 db.insert_datas(&data).unwrap();
290
291 assert_eq!(ErrCode::FileOperationError, db.query_datas(&vec![], &data, None, false).unwrap_err().code);
292 drop(db);
293 remove_dir();
294 }
295