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