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 use crate::config::{Action, Mode};
15 use crate::info::State;
16 use crate::task::reason::Reason;
17
start_task(task_id: u32) -> String18 pub(super) fn start_task(task_id: u32) -> String {
19 format!(
20 "UPDATE request_task SET state = {}, reason = {} where task_id = {} AND (state = {} OR state = {} OR (action = {} AND (state = {} OR state = {} )))",
21 State::Waiting.repr,
22 Reason::RunningTaskMeetLimits.repr,
23 task_id,
24 State::Initialized.repr,
25 State::Paused.repr,
26 Action::Download.repr,
27 State::Failed.repr,
28 State::Stopped.repr,
29 )
30 }
31
pause_task(task_id: u32) -> String32 pub(super) fn pause_task(task_id: u32) -> String {
33 format!(
34 "UPDATE request_task SET state = {}, reason = {} where task_id = {} AND (state = {} OR state = {} OR state = {})",
35 State::Paused.repr,
36 Reason::UserOperation.repr,
37 task_id,
38 State::Running.repr,
39 State::Retrying.repr,
40 State::Waiting.repr,
41 )
42 }
43
stop_task(task_id: u32) -> String44 pub(super) fn stop_task(task_id: u32) -> String {
45 format!(
46 "UPDATE request_task SET state = {}, reason = {} where task_id = {} AND (state = {} OR state = {} OR state = {})",
47 State::Stopped.repr,
48 Reason::UserOperation.repr,
49 task_id,
50 State::Running.repr,
51 State::Retrying.repr,
52 State::Waiting.repr,
53 )
54 }
55
remove_task(task_id: u32) -> String56 pub(super) fn remove_task(task_id: u32) -> String {
57 format!(
58 "UPDATE request_task SET state = {}, reason = {} where task_id = {}",
59 State::Removed.repr,
60 Reason::UserOperation.repr,
61 task_id,
62 )
63 }
64
task_set_mode(task_id: u32, mode: Mode) -> String65 pub(super) fn task_set_mode(task_id: u32, mode: Mode) -> String {
66 format!(
67 "UPDATE request_task SET mode = {} where task_id = {}",
68 mode.repr, task_id,
69 )
70 }
71
72 #[cfg(all(not(feature = "oh"), test))]
73 mod test {
74 use rusqlite::Connection;
75
76 const CREATE: &'static str = "CREATE TABLE IF NOT EXISTS request_task (task_id INTEGER PRIMARY KEY, uid INTEGER, token_id INTEGER, action INTEGER, mode INTEGER, cover INTEGER, network INTEGER, metered INTEGER, roaming INTEGER, ctime INTEGER, mtime INTEGER, reason INTEGER, gauge INTEGER, retry INTEGER, redirect INTEGER, tries INTEGER, version INTEGER, config_idx INTEGER, begins INTEGER, ends INTEGER, precise INTEGER, priority INTEGER, background INTEGER, bundle TEXT, url TEXT, data TEXT, token TEXT, title TEXT, description TEXT, method TEXT, headers TEXT, config_extras TEXT, mime_type TEXT, state INTEGER, idx INTEGER, total_processed INTEGER, sizes TEXT, processed TEXT, extras TEXT, form_items BLOB, file_specs BLOB, each_file_status BLOB, body_file_names BLOB, certs_paths BLOB)";
77 use super::{pause_task, start_task, stop_task};
78 use crate::info::State;
79 use crate::task::reason::Reason;
80
init()81 fn init() {
82 let _ = env_logger::builder().is_test(true).try_init();
83 }
84
85 #[test]
ut_start_pause_start()86 fn ut_start_pause_start() {
87 init();
88
89 let db = Connection::open_in_memory().unwrap();
90 db.execute(
91 &CREATE,
92 (), // empty list of parameters.
93 )
94 .unwrap();
95
96 let task_id: u32 = rand::random();
97 db.execute(
98 &format!(
99 "INSERT INTO request_task (task_id, state) VALUES ({}, {})",
100 task_id,
101 State::Initialized.repr,
102 ),
103 (),
104 )
105 .unwrap();
106 db.execute(&start_task(task_id), ()).unwrap();
107 let mut stmt = db
108 .prepare(&format!(
109 "SELECT state from request_task where task_id = {}",
110 task_id,
111 ))
112 .unwrap();
113 let mut row = stmt
114 .query_map([], |row| Ok(row.get::<_, u8>(0).unwrap()))
115 .unwrap();
116 let state = row.next().unwrap().unwrap();
117 assert_eq!(state, State::Running.repr);
118 db.execute(&pause_task(task_id), ()).unwrap();
119
120 let mut stmt = db
121 .prepare(&format!(
122 "SELECT state from request_task where task_id = {}",
123 task_id,
124 ))
125 .unwrap();
126 let mut row = stmt
127 .query_map([], |row| Ok(row.get::<_, u8>(0).unwrap()))
128 .unwrap();
129 let state = row.next().unwrap().unwrap();
130 assert_eq!(state, State::Paused.repr);
131
132 db.execute(&start_task(task_id), ()).unwrap();
133
134 let mut stmt = db
135 .prepare(&format!(
136 "SELECT state from request_task where task_id = {}",
137 task_id,
138 ))
139 .unwrap();
140 let mut row = stmt
141 .query_map([], |row| Ok(row.get::<_, u8>(0).unwrap()))
142 .unwrap();
143 let state = row.next().unwrap().unwrap();
144 assert_eq!(state, State::Paused.repr);
145 }
146
147 #[test]
ut_pause()148 fn ut_pause() {
149 init();
150
151 let db = Connection::open_in_memory().unwrap();
152 db.execute(
153 &CREATE,
154 (), // empty list of parameters.
155 )
156 .unwrap();
157 let states = [State::Running, State::Retrying, State::Waiting];
158 let mut tasks = vec![];
159 for state in states.iter() {
160 let task_id: u32 = rand::random();
161 tasks.push(task_id);
162 db.execute(
163 &format!(
164 "INSERT INTO request_task (task_id, state) VALUES ({}, {})",
165 task_id, state.repr,
166 ),
167 (),
168 )
169 .unwrap();
170 }
171 for task_id in tasks.iter() {
172 db.execute(&pause_task(*task_id), ()).unwrap();
173 }
174 let mut stmt = db
175 .prepare(&format!(
176 "SELECT task_id from request_task where state = {} AND reason = {}",
177 State::Paused.repr,
178 Reason::UserOperation.repr
179 ))
180 .unwrap();
181 let rows = stmt.query_map([], |row| Ok(row.get(0).unwrap())).unwrap();
182 let mut res: Vec<u32> = rows.map(|r| r.unwrap()).collect();
183 res.sort();
184 tasks.sort();
185 assert_eq!(tasks, res);
186 }
187
188 #[test]
ut_stop()189 fn ut_stop() {
190 init();
191
192 let db = Connection::open_in_memory().unwrap();
193 db.execute(
194 &CREATE,
195 (), // empty list of parameters.
196 )
197 .unwrap();
198 let states = [State::Running, State::Retrying, State::Waiting];
199 let mut tasks = vec![];
200 for state in states.iter() {
201 let task_id: u32 = rand::random();
202 tasks.push(task_id);
203 db.execute(
204 &format!(
205 "INSERT INTO request_task (task_id, state) VALUES ({}, {})",
206 task_id, state.repr,
207 ),
208 (),
209 )
210 .unwrap();
211 }
212 for task_id in tasks.iter() {
213 db.execute(&&stop_task(*task_id), ()).unwrap();
214 }
215 let mut stmt = db
216 .prepare(&format!(
217 "SELECT task_id from request_task where state = {} AND reason = {}",
218 State::Stopped.repr,
219 Reason::UserOperation.repr
220 ))
221 .unwrap();
222 let rows = stmt.query_map([], |row| Ok(row.get(0).unwrap())).unwrap();
223 let mut res: Vec<u32> = rows.map(|r| r.unwrap()).collect();
224 res.sort();
225 tasks.sort();
226 assert_eq!(tasks, res);
227 }
228 }
229