1 // Copyright (C) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 cfg_oh! { 15 pub(crate) mod config; 16 pub(crate) use config::{SystemConfig, SystemConfigManager}; 17 } 18 19 pub(crate) mod account; 20 pub(crate) mod app_state; 21 pub(crate) mod database; 22 pub(crate) mod events; 23 pub(crate) mod query; 24 pub(crate) use task_manager::TaskManager; 25 pub(crate) mod network; 26 pub(crate) mod network_manager; 27 pub(crate) mod notifier; 28 pub(crate) mod scheduler; 29 pub(crate) mod task_manager; 30 31 #[cfg(test)] 32 mod test { 33 use std::fs::File; 34 use std::time::Duration; 35 36 use ylong_runtime::sync::mpsc::unbounded_channel; 37 38 use super::database::RequestDb; 39 use super::network::{NetworkInfo, NetworkInner, NetworkType}; 40 use super::TaskManager; 41 use crate::config::{Action, ConfigBuilder, Mode}; 42 use crate::error::ErrorCode; 43 use crate::info::{State, TaskInfo}; 44 use crate::manage::events::{TaskEvent, TaskManagerEvent}; 45 use crate::manage::task_manager::{TaskManagerRx, TaskManagerTx}; 46 use crate::service::client::ClientManagerEntry; 47 use crate::service::run_count::RunCountManagerEntry; 48 use crate::task::reason::Reason; 49 use crate::tests::{lock_database, test_init}; 50 51 const GITEE_FILE_LEN: u64 = 1042003; 52 task_manager() -> TaskManager53 fn task_manager() -> TaskManager { 54 let (tx, rx) = unbounded_channel(); 55 let task_manager_tx = TaskManagerTx::new(tx); 56 let rx = TaskManagerRx::new(rx); 57 let inner = NetworkInner::new(); 58 inner.notify_online(NetworkInfo { 59 network_type: NetworkType::Wifi, 60 is_metered: false, 61 is_roaming: false, 62 }); 63 let (tx, _rx) = unbounded_channel(); 64 let run_count = RunCountManagerEntry::new(tx); 65 let (tx, _rx) = unbounded_channel(); 66 let client = ClientManagerEntry::new(tx); 67 TaskManager::new(task_manager_tx, rx, run_count, client) 68 } 69 task_into(task_id: u32) -> TaskInfo70 fn task_into(task_id: u32) -> TaskInfo { 71 let db = RequestDb::get_instance(); 72 db.get_task_info(task_id).unwrap() 73 } 74 75 #[test] ut_manager_task_state_and_reason()76 fn ut_manager_task_state_and_reason() { 77 test_init(); 78 let _lock = lock_database(); 79 let mut manager = task_manager(); 80 let file_path = "test_files/ut_manager_task_state_and_reason.txt"; 81 82 let file = File::create(file_path).unwrap(); 83 let config = ConfigBuilder::new() 84 .action(Action::Download) 85 .retry(true) 86 .mode(Mode::BackGround) 87 .file_spec(file) 88 .url("https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/test.txt") 89 .redirect(true) 90 .build(); 91 let uid = config.common_data.uid; 92 let task_id = manager.create(config).unwrap(); 93 assert_eq!( 94 task_into(task_id).progress.common_data.state, 95 State::Initialized.repr 96 ); 97 98 assert_eq!(task_into(task_id).common_data.reason, Reason::Default.repr); 99 100 manager.start(uid, task_id); 101 assert_eq!( 102 task_into(task_id).progress.common_data.state, 103 State::Waiting.repr 104 ); 105 assert_eq!( 106 task_into(task_id).common_data.reason, 107 Reason::RunningTaskMeetLimits.repr 108 ); 109 110 manager.pause(uid, task_id); 111 assert_eq!( 112 task_into(task_id).progress.common_data.state, 113 State::Paused.repr 114 ); 115 assert_eq!( 116 task_into(task_id).common_data.reason, 117 Reason::UserOperation.repr 118 ); 119 120 manager.resume(uid, task_id); 121 assert_eq!( 122 task_into(task_id).progress.common_data.state, 123 State::Waiting.repr 124 ); 125 assert_eq!( 126 task_into(task_id).common_data.reason, 127 Reason::RunningTaskMeetLimits.repr 128 ); 129 130 manager.pause(uid, task_id); 131 assert_eq!( 132 task_into(task_id).progress.common_data.state, 133 State::Paused.repr 134 ); 135 assert_eq!( 136 task_into(task_id).common_data.reason, 137 Reason::UserOperation.repr 138 ); 139 140 manager.resume(uid, task_id); 141 assert_eq!( 142 task_into(task_id).progress.common_data.state, 143 State::Waiting.repr 144 ); 145 assert_eq!( 146 task_into(task_id).common_data.reason, 147 Reason::RunningTaskMeetLimits.repr 148 ); 149 150 manager.stop(uid, task_id); 151 assert_eq!( 152 task_into(task_id).progress.common_data.state, 153 State::Stopped.repr 154 ); 155 assert_eq!( 156 task_into(task_id).common_data.reason, 157 Reason::UserOperation.repr 158 ); 159 160 manager.start(uid, task_id); 161 assert_eq!( 162 task_into(task_id).progress.common_data.state, 163 State::Waiting.repr 164 ); 165 assert_eq!( 166 task_into(task_id).common_data.reason, 167 Reason::RunningTaskMeetLimits.repr 168 ); 169 170 manager.scheduler.reschedule(); 171 172 ylong_runtime::block_on(async move { 173 ylong_runtime::time::sleep(Duration::from_millis(500)).await; 174 assert_eq!( 175 task_into(task_id).progress.common_data.state, 176 State::Running.repr 177 ); 178 assert_eq!(task_into(task_id).common_data.reason, Reason::Default.repr); 179 ylong_runtime::time::sleep(Duration::from_secs(10)).await; 180 let msg = manager.rx.recv().await.unwrap(); 181 assert!(matches!(msg, TaskManagerEvent::Reschedule)); 182 let msg = manager.rx.recv().await.unwrap(); 183 assert!(matches!( 184 msg, 185 TaskManagerEvent::Task(TaskEvent::Completed(info_task_id, info_uid,Mode::BackGround)) if uid == info_uid && task_id == info_task_id 186 )); 187 let file = File::open(file_path).unwrap(); 188 assert_eq!(file.metadata().unwrap().len(), GITEE_FILE_LEN); 189 }); 190 } 191 192 #[test] ut_manager_state_change_error()193 fn ut_manager_state_change_error() { 194 test_init(); 195 let _lock = lock_database(); 196 let mut manager = task_manager(); 197 let file_path = "test_files/ut_manager_state_change_error.txt"; 198 199 let file = File::create(file_path).unwrap(); 200 let config = ConfigBuilder::new() 201 .action(Action::Download) 202 .retry(true) 203 .mode(Mode::BackGround) 204 .file_spec(file) 205 .url("https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/test.txt") 206 .redirect(true) 207 .build(); 208 let uid = config.common_data.uid; 209 210 // initialized 211 let task_id = manager.create(config.clone()).unwrap(); 212 assert_eq!( 213 task_into(task_id).progress.common_data.state, 214 State::Initialized.repr 215 ); 216 assert_eq!(manager.pause(uid, task_id), ErrorCode::TaskStateErr); 217 assert_eq!(manager.resume(uid, task_id), ErrorCode::TaskStateErr); 218 assert_eq!(manager.stop(uid, task_id), ErrorCode::TaskStateErr); 219 assert_eq!(manager.remove(uid, task_id), ErrorCode::ErrOk); 220 assert_eq!( 221 task_into(task_id).progress.common_data.state, 222 State::Removed.repr 223 ); 224 225 // started 226 let task_id = manager.create(config.clone()).unwrap(); 227 assert_eq!(manager.start(uid, task_id), ErrorCode::ErrOk); 228 assert_eq!(manager.resume(uid, task_id), ErrorCode::TaskStateErr); 229 assert_eq!(manager.start(uid, task_id), ErrorCode::TaskStateErr); 230 assert_eq!(manager.remove(uid, task_id), ErrorCode::ErrOk); 231 assert_eq!( 232 task_into(task_id).progress.common_data.state, 233 State::Removed.repr 234 ); 235 236 // paused 237 let task_id = manager.create(config.clone()).unwrap(); 238 assert_eq!(manager.start(uid, task_id), ErrorCode::ErrOk); 239 assert_eq!(manager.pause(uid, task_id), ErrorCode::ErrOk); 240 assert_eq!(manager.pause(uid, task_id), ErrorCode::TaskStateErr); 241 assert_eq!(manager.stop(uid, task_id), ErrorCode::TaskStateErr); 242 assert_eq!(manager.start(uid, task_id), ErrorCode::TaskStateErr); 243 assert_eq!(manager.remove(uid, task_id), ErrorCode::ErrOk); 244 assert_eq!( 245 task_into(task_id).progress.common_data.state, 246 State::Removed.repr 247 ); 248 249 // stopped 250 let task_id = manager.create(config.clone()).unwrap(); 251 assert_eq!(manager.start(uid, task_id), ErrorCode::ErrOk); 252 assert_eq!(manager.stop(uid, task_id), ErrorCode::ErrOk); 253 assert_eq!(manager.pause(uid, task_id), ErrorCode::TaskStateErr); 254 assert_eq!(manager.stop(uid, task_id), ErrorCode::TaskStateErr); 255 assert_eq!(manager.resume(uid, task_id), ErrorCode::TaskStateErr); 256 assert_eq!(manager.start(uid, task_id), ErrorCode::ErrOk); 257 assert_eq!(manager.stop(uid, task_id), ErrorCode::ErrOk); 258 assert_eq!(manager.remove(uid, task_id), ErrorCode::ErrOk); 259 assert_eq!( 260 task_into(task_id).progress.common_data.state, 261 State::Removed.repr 262 ); 263 264 // resumed 265 let task_id = manager.create(config.clone()).unwrap(); 266 assert_eq!(manager.start(uid, task_id), ErrorCode::ErrOk); 267 assert_eq!(manager.pause(uid, task_id), ErrorCode::ErrOk); 268 assert_eq!(manager.resume(uid, task_id), ErrorCode::ErrOk); 269 assert_eq!(manager.resume(uid, task_id), ErrorCode::TaskStateErr); 270 assert_eq!(manager.start(uid, task_id), ErrorCode::TaskStateErr); 271 assert_eq!(manager.pause(uid, task_id), ErrorCode::ErrOk); 272 assert_eq!(manager.resume(uid, task_id), ErrorCode::ErrOk); 273 assert_eq!(manager.remove(uid, task_id), ErrorCode::ErrOk); 274 assert_eq!( 275 task_into(task_id).progress.common_data.state, 276 State::Removed.repr 277 ); 278 } 279 280 #[test] ut_manager_reschedule()281 fn ut_manager_reschedule() { 282 test_init(); 283 let _lock = lock_database(); 284 let mut manager = task_manager(); 285 let file_path = "test_files/ut_manager_reschedule.txt"; 286 287 let file = File::create(file_path).unwrap(); 288 let config = ConfigBuilder::new() 289 .action(Action::Download) 290 .retry(true) 291 .mode(Mode::BackGround) 292 .file_spec(file) 293 .url("https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/test.txt") 294 .redirect(true) 295 .build(); 296 let uid = config.common_data.uid; 297 let task_id = manager.create(config.clone()).unwrap(); 298 manager.rx.try_recv().unwrap_err(); 299 manager.start(uid, task_id); 300 assert!(matches!( 301 manager.rx.try_recv().unwrap(), 302 TaskManagerEvent::Reschedule 303 )); 304 manager.scheduler.resort_scheduled = false; 305 manager.stop(uid, task_id); 306 assert!(matches!( 307 manager.rx.try_recv().unwrap(), 308 TaskManagerEvent::Reschedule 309 )); 310 manager.scheduler.resort_scheduled = false; 311 manager.start(uid, task_id); 312 assert!(matches!( 313 manager.rx.try_recv().unwrap(), 314 TaskManagerEvent::Reschedule 315 )); 316 manager.stop(uid, task_id); 317 manager.rx.try_recv().unwrap_err(); 318 manager.scheduler.resort_scheduled = false; 319 manager.start(uid, task_id); 320 assert!(matches!( 321 manager.rx.try_recv().unwrap(), 322 TaskManagerEvent::Reschedule 323 )); 324 manager.scheduler.resort_scheduled = false; 325 manager.pause(uid, task_id); 326 assert!(matches!( 327 manager.rx.try_recv().unwrap(), 328 TaskManagerEvent::Reschedule 329 )); 330 manager.scheduler.resort_scheduled = false; 331 manager.resume(uid, task_id); 332 assert!(matches!( 333 manager.rx.try_recv().unwrap(), 334 TaskManagerEvent::Reschedule 335 )); 336 } 337 } 338