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_definition::{ErrCode, Extension, Value};
24
25 use crate::{
26 database::Database,
27 table::Table,
28 types::{column, DbMap, QueryOptions, TABLE_NAME},
29 };
30
31 const DB_DATA: [(&str, Value); 9] = [
32 (column::OWNER_TYPE, Value::Number(1)),
33 (column::SYNC_TYPE, Value::Number(1)),
34 (column::ACCESSIBILITY, Value::Number(1)),
35 (column::AUTH_TYPE, Value::Number(1)),
36 (column::IS_PERSISTENT, Value::Bool(true)),
37 (column::VERSION, Value::Number(2)),
38 (column::REQUIRE_PASSWORD_SET, Value::Bool(false)),
39 (column::LOCAL_STATUS, Value::Number(0)),
40 (column::SYNC_STATUS, Value::Number(0)),
41 ];
42
43 const TEST_FILE: &str = "/data/asset_test/0";
44
create_dir()45 fn create_dir() {
46 let path = Path::new(TEST_FILE);
47 if !path.exists() {
48 fs::create_dir_all(path).unwrap();
49 }
50 }
51
remove_dir()52 fn remove_dir() {
53 let path = Path::new(TEST_FILE);
54 if path.exists() {
55 fs::remove_dir_all(path).unwrap();
56 }
57 }
58
open_db_and_insert_data() -> Database59 fn open_db_and_insert_data() -> Database {
60 create_dir();
61 let mut def = DbMap::from(DB_DATA);
62 add_bytes_column(&mut def);
63 let mut db = Database::build(0).unwrap();
64 let count = db.insert_datas(&def).unwrap();
65 assert_eq!(count, 1);
66 db
67 }
68
add_bytes_column(db_data: &mut DbMap)69 fn add_bytes_column(db_data: &mut DbMap) {
70 db_data.insert(column::SECRET, Value::Bytes(column::SECRET.as_bytes().to_vec()));
71 db_data.insert(column::ALIAS, Value::Bytes(column::ALIAS.as_bytes().to_vec()));
72 db_data.insert(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()));
73 db_data.insert(column::CREATE_TIME, Value::Bytes(column::CREATE_TIME.as_bytes().to_vec()));
74 db_data.insert(column::UPDATE_TIME, Value::Bytes(column::UPDATE_TIME.as_bytes().to_vec()));
75 }
76
backup_db(db: &Database)77 fn backup_db(db: &Database) {
78 fs::copy(&db.path, &db.backup_path).unwrap();
79 }
80
81 #[test]
create_and_drop_database()82 fn create_and_drop_database() {
83 fs::create_dir_all("/data/asset_test/0").unwrap();
84 let mut db = Database::build(0).unwrap();
85 backup_db(&db);
86 db.close_db();
87 assert!(Database::delete(0).is_ok());
88 }
89
90 #[test]
database_version()91 fn database_version() {
92 fs::create_dir_all("/data/asset_test/0").unwrap();
93 let calling_info = CallingInfo::new_self();
94 let db = Database::build(calling_info.user_id(), calling_info.owner_type_enum(), calling_info.owner_info(), false)
95 .unwrap();
96 assert_eq!(3, db.get_version().unwrap());
97 assert!(db.set_version(2).is_ok());
98 assert_eq!(2, db.get_version().unwrap());
99 let _ = Database::delete(0, &db.db_name);
100 }
101
102 #[test]
error_sql()103 fn error_sql() {
104 fs::create_dir_all("/data/asset_test/0").unwrap();
105 let db = Database::build(0).unwrap();
106 let sql = "pragma zzz user_version = {} mmm";
107 assert!(db.exec(sql).is_err());
108 let _ = Database::delete(0);
109 }
110
111 #[test]
create_delete_asset_table()112 fn create_delete_asset_table() {
113 fs::create_dir_all("/data/asset_test/0").unwrap();
114 let mut db = Database::build(0).unwrap();
115 let table = Table::new(TABLE_NAME, &db);
116 assert!(table.exist().unwrap());
117 assert!(table.delete().is_ok());
118 assert!(!table.exist().unwrap());
119 db.close_db();
120 let _ = Database::delete(0);
121 }
122
123 #[test]
insert_data_with_different_alias()124 fn insert_data_with_different_alias() {
125 create_dir();
126 let mut def = DbMap::from(DB_DATA);
127 add_bytes_column(&mut def);
128
129 let mut db = Database::build(0).unwrap();
130 let count = db.insert_datas(&def).unwrap();
131 assert_eq!(count, 1);
132
133 def.insert(column::ALIAS, Value::Bytes(b"Alias2".to_vec()));
134 let count = db.insert_datas(&def).unwrap();
135 assert_eq!(count, 1);
136
137 let ret = db
138 .query_datas(
139 &vec![],
140 &DbMap::from([(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()))]),
141 None,
142 false,
143 )
144 .unwrap();
145 assert_eq!(ret.len(), 2);
146 remove_dir();
147 }
148
149 #[test]
delete_data()150 fn delete_data() {
151 let mut db = open_db_and_insert_data();
152
153 let mut datas = DbMap::new();
154 datas.insert(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()));
155 datas.insert(column::ALIAS, Value::Bytes(column::ALIAS.as_bytes().to_vec()));
156
157 let ret = db.is_data_exists(&datas, false).unwrap();
158 assert!(ret);
159
160 let count = db.delete_datas(&datas, None, false).unwrap();
161 assert_eq!(count, 1);
162
163 let ret = db.is_data_exists(&datas, false).unwrap();
164 assert!(!ret);
165
166 remove_dir();
167 }
168
169 #[test]
update_data()170 fn update_data() {
171 let mut db = open_db_and_insert_data();
172
173 let mut datas = DbMap::new();
174 datas.insert(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()));
175 datas.insert(column::ALIAS, Value::Bytes(column::ALIAS.as_bytes().to_vec()));
176 let update_time: Vec<u8> = vec![2];
177 let count = db
178 .update_datas(&datas, true, &DbMap::from([(column::UPDATE_TIME, Value::Bytes(update_time.clone()))]))
179 .unwrap();
180 assert_eq!(count, 1);
181
182 let res = db.query_datas(&vec![], &datas, None, false).unwrap();
183 assert_eq!(res.len(), 1);
184 let query_update_time = res[0].get_bytes_attr(&column::UPDATE_TIME).unwrap();
185 assert_eq!(update_time.len(), query_update_time.len());
186 for (ins, qy) in update_time.iter().zip(query_update_time.iter()) {
187 assert_eq!(*ins, *qy);
188 }
189
190 remove_dir();
191 }
192
193 #[test]
query_ordered_data()194 fn query_ordered_data() {
195 // insert two data
196 create_dir();
197 let mut def = DbMap::from(DB_DATA);
198 add_bytes_column(&mut def);
199
200 let mut db = Database::build(0).unwrap();
201 let count = db.insert_datas(&def).unwrap();
202 assert_eq!(count, 1);
203
204 def.insert(column::ALIAS, Value::Bytes(b"AAA".to_vec()));
205 let count = db.insert_datas(&def).unwrap();
206 assert_eq!(count, 1);
207
208 // query data by order
209 let query = QueryOptions {
210 limit: Some(100),
211 offset: Some(0),
212 order: Some(Ordering::Greater),
213 order_by: Some(vec![column::ALIAS]),
214 };
215 let res = db
216 .query_datas(
217 &vec![column::ID, column::ALIAS],
218 &DbMap::from([(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()))]),
219 Some(&query),
220 false,
221 )
222 .unwrap();
223 assert_eq!(res.len(), 2);
224 assert_eq!(&(b"AAA".to_vec()), res[0].get_bytes_attr(&column::ALIAS).unwrap());
225
226 remove_dir();
227 }
228
229 #[test]
insert_error_data()230 fn insert_error_data() {
231 create_dir();
232 let mut datas = DbMap::new();
233 datas.insert(column::OWNER, Value::Bytes(column::OWNER.as_bytes().to_vec()));
234 let mut db = Database::build(0).unwrap();
235 assert!(db.insert_datas(&datas).is_err());
236 remove_dir();
237 }
238
239 #[test]
backup_and_restore()240 fn backup_and_restore() {
241 let db = open_db_and_insert_data();
242 backup_db(&db);
243 drop(db);
244
245 // Destroy the main database.
246 let mut db_file = OpenOptions::new().read(true).write(true).open("/data/asset_test/0/asset.db").unwrap();
247 let _ = db_file.write(b"buffer buffer buffer").unwrap();
248
249 // Recovery the main database.
250 let mut db = Database::build(0).unwrap();
251 let mut def = DbMap::from(DB_DATA);
252 add_bytes_column(&mut def);
253
254 db.query_datas(&vec![], &def, None, false).unwrap();
255 drop(db);
256 remove_dir();
257 }
258
259 #[test]
insert_duplicated_data()260 fn insert_duplicated_data() {
261 let mut db = open_db_and_insert_data();
262
263 let mut def = DbMap::from(DB_DATA);
264 add_bytes_column(&mut def);
265 assert_eq!(ErrCode::Duplicated, db.insert_datas(&def).unwrap_err().code);
266
267 drop(db);
268 remove_dir();
269 }
270
271 #[test]
query_mismatch_type_data()272 fn query_mismatch_type_data() {
273 create_dir();
274 let mut data = DbMap::from(DB_DATA);
275 add_bytes_column(&mut data);
276 data.insert(column::CREATE_TIME, Value::Number(1));
277 let mut db = Database::build(0).unwrap();
278 db.insert_datas(&data).unwrap();
279
280 assert_eq!(ErrCode::FileOperationError, db.query_datas(&vec![], &data, None, false).unwrap_err().code);
281 drop(db);
282 remove_dir();
283 }
284