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;
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
65 #[cfg(all(not(feature = "oh"), test))]
66 mod test {
67 use rusqlite::Connection;
68
69 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)";
70 use super::{pause_task, start_task, stop_task};
71 use crate::info::State;
72 use crate::task::reason::Reason;
73
init()74 fn init() {
75 let _ = env_logger::builder().is_test(true).try_init();
76 }
77
78 #[test]
ut_start_pause_start()79 fn ut_start_pause_start() {
80 init();
81
82 let db = Connection::open_in_memory().unwrap();
83 db.execute(
84 &CREATE,
85 (), // empty list of parameters.
86 )
87 .unwrap();
88
89 let task_id: u32 = rand::random();
90 db.execute(
91 &format!(
92 "INSERT INTO request_task (task_id, state) VALUES ({}, {})",
93 task_id,
94 State::Initialized.repr,
95 ),
96 (),
97 )
98 .unwrap();
99 db.execute(&start_task(task_id), ()).unwrap();
100 let mut stmt = db
101 .prepare(&format!(
102 "SELECT state from request_task where task_id = {}",
103 task_id,
104 ))
105 .unwrap();
106 let mut row = stmt
107 .query_map([], |row| Ok(row.get::<_, u8>(0).unwrap()))
108 .unwrap();
109 let state = row.next().unwrap().unwrap();
110 assert_eq!(state, State::Running.repr);
111 db.execute(&pause_task(task_id), ()).unwrap();
112
113 let mut stmt = db
114 .prepare(&format!(
115 "SELECT state from request_task where task_id = {}",
116 task_id,
117 ))
118 .unwrap();
119 let mut row = stmt
120 .query_map([], |row| Ok(row.get::<_, u8>(0).unwrap()))
121 .unwrap();
122 let state = row.next().unwrap().unwrap();
123 assert_eq!(state, State::Paused.repr);
124
125 db.execute(&start_task(task_id), ()).unwrap();
126
127 let mut stmt = db
128 .prepare(&format!(
129 "SELECT state from request_task where task_id = {}",
130 task_id,
131 ))
132 .unwrap();
133 let mut row = stmt
134 .query_map([], |row| Ok(row.get::<_, u8>(0).unwrap()))
135 .unwrap();
136 let state = row.next().unwrap().unwrap();
137 assert_eq!(state, State::Paused.repr);
138 }
139
140 #[test]
ut_pause()141 fn ut_pause() {
142 init();
143
144 let db = Connection::open_in_memory().unwrap();
145 db.execute(
146 &CREATE,
147 (), // empty list of parameters.
148 )
149 .unwrap();
150 let states = [State::Running, State::Retrying, State::Waiting];
151 let mut tasks = vec![];
152 for state in states.iter() {
153 let task_id: u32 = rand::random();
154 tasks.push(task_id);
155 db.execute(
156 &format!(
157 "INSERT INTO request_task (task_id, state) VALUES ({}, {})",
158 task_id, state.repr,
159 ),
160 (),
161 )
162 .unwrap();
163 }
164 for task_id in tasks.iter() {
165 db.execute(&pause_task(*task_id), ()).unwrap();
166 }
167 let mut stmt = db
168 .prepare(&format!(
169 "SELECT task_id from request_task where state = {} AND reason = {}",
170 State::Paused.repr,
171 Reason::UserOperation.repr
172 ))
173 .unwrap();
174 let rows = stmt.query_map([], |row| Ok(row.get(0).unwrap())).unwrap();
175 let mut res: Vec<u32> = rows.map(|r| r.unwrap()).collect();
176 res.sort();
177 tasks.sort();
178 assert_eq!(tasks, res);
179 }
180
181 #[test]
ut_stop()182 fn ut_stop() {
183 init();
184
185 let db = Connection::open_in_memory().unwrap();
186 db.execute(
187 &CREATE,
188 (), // empty list of parameters.
189 )
190 .unwrap();
191 let states = [State::Running, State::Retrying, State::Waiting];
192 let mut tasks = vec![];
193 for state in states.iter() {
194 let task_id: u32 = rand::random();
195 tasks.push(task_id);
196 db.execute(
197 &format!(
198 "INSERT INTO request_task (task_id, state) VALUES ({}, {})",
199 task_id, state.repr,
200 ),
201 (),
202 )
203 .unwrap();
204 }
205 for task_id in tasks.iter() {
206 db.execute(&&stop_task(*task_id), ()).unwrap();
207 }
208 let mut stmt = db
209 .prepare(&format!(
210 "SELECT task_id from request_task where state = {} AND reason = {}",
211 State::Stopped.repr,
212 Reason::UserOperation.repr
213 ))
214 .unwrap();
215 let rows = stmt.query_map([], |row| Ok(row.get(0).unwrap())).unwrap();
216 let mut res: Vec<u32> = rows.map(|r| r.unwrap()).collect();
217 res.sort();
218 tasks.sort();
219 assert_eq!(tasks, res);
220 }
221 }
222