diff --git a/preload/native/BUILD.gn b/preload/native/BUILD.gn index c95aaf8e..5affe7d5 100644 --- a/preload/native/BUILD.gn +++ b/preload/native/BUILD.gn @@ -36,7 +36,6 @@ ohos_rust_shared_ffi("preload_native_rust") { "../netstack_rs:netstack_rs", "//third_party/rust/crates/cxx:lib", ] - external_deps = [ "ability_runtime:app_context" ] subsystem_name = "request" part_name = "request" diff --git a/preload/native/Cargo.toml b/preload/native/Cargo.toml index 1bb1bb64..c67c02c0 100644 --- a/preload/native/Cargo.toml +++ b/preload/native/Cargo.toml @@ -18,6 +18,7 @@ edition = "2021" [features] default = [ + "ohos", ] ohos = [ diff --git a/preload/native/src/download/common.rs b/preload/native/src/download/common.rs index db66d1c7..f30c60f6 100644 --- a/preload/native/src/download/common.rs +++ b/preload/native/src/download/common.rs @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::collections::VecDeque; use std::io::Write; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; @@ -30,21 +31,39 @@ const SUCCESS: usize = 2; const FAIL: usize = 3; const CANCEL: usize = 4; +const PROGRESS_INTERVAL: usize = 8; + pub(crate) struct DownloadCallback { task_id: TaskId, cache: Option, finish: Arc, state: Arc, - callbacks: Arc>>>, - processed: u64, + callbacks: Arc>>>, + progress_restriction: ProgressRestriction, seq: usize, } +struct ProgressRestriction { + processed: u64, + count: usize, + data_receive: bool, +} + +impl ProgressRestriction { + fn new() -> Self { + Self { + processed: 0, + count: 0, + data_receive: false, + } + } +} + impl DownloadCallback { pub(crate) fn new( task_id: TaskId, finish: Arc, - callbacks: Arc>>>, + callbacks: Arc>>>, state: Arc, seq: usize, ) -> Self { @@ -54,7 +73,7 @@ impl DownloadCallback { cache: None, finish, callbacks, - processed: 0, + progress_restriction: ProgressRestriction::new(), seq, } } @@ -79,9 +98,23 @@ impl DownloadCallback { self.state.store(SUCCESS, Ordering::Release); self.finish.store(true, Ordering::Release); let mut callbacks = self.callbacks.lock().unwrap(); - while let Some(mut callback) = callbacks.pop() { - callback.on_success(cache.clone(), self.task_id.brief()); + + if callbacks.len() <= 1 { + if let Some(mut callback) = callbacks.pop_front() { + callback.on_progress(cache.size() as u64, cache.size() as u64); + callback.on_success(cache.clone(), self.task_id.brief()); + } + } else { + while let Some(mut callback) = callbacks.pop_front() { + let clone_cache = cache.clone(); + let task_id = self.task_id.brief().to_string(); + crate::spawn(move || { + callback.on_progress(clone_cache.size() as u64, clone_cache.size() as u64); + callback.on_success(clone_cache, &task_id) + }); + } } + drop(callbacks); self.notify_agent_finish(); } @@ -91,9 +124,19 @@ impl DownloadCallback { self.state.store(FAIL, Ordering::Release); self.finish.store(true, Ordering::Release); let mut callbacks = self.callbacks.lock().unwrap(); - while let Some(mut callback) = callbacks.pop() { - callback.on_fail(DownloadError::from(&error), self.task_id.brief()); + + if callbacks.len() <= 1 { + if let Some(mut callback) = callbacks.pop_front() { + callback.on_fail(DownloadError::from(&error), self.task_id.brief()); + } + } else { + while let Some(mut callback) = callbacks.pop_front() { + let task_id = self.task_id.brief().to_string(); + let error = DownloadError::from(&error); + crate::spawn(move || callback.on_fail(error, &task_id)); + } } + drop(callbacks); self.notify_agent_finish(); } @@ -133,9 +176,17 @@ impl RequestCallback for DownloadCallback { self.finish.store(true, Ordering::Release); let mut callbacks = self.callbacks.lock().unwrap(); - while let Some(mut callback) = callbacks.pop() { - callback.on_cancel(); + + if callbacks.len() <= 1 { + if let Some(mut callback) = callbacks.pop_front() { + callback.on_cancel(); + } + } else { + while let Some(mut callback) = callbacks.pop_front() { + crate::spawn(move || callback.on_cancel()); + } } + drop(callbacks); self.notify_agent_finish(); } @@ -143,6 +194,7 @@ impl RequestCallback for DownloadCallback { #[allow(unused_mut)] fn on_data_receive(&mut self, data: &[u8], mut task: RequestTask) { if self.cache.is_none() { + self.progress_restriction.data_receive = true; let headers = task.headers(); let is_chunked = headers .get("transfer-encoding") @@ -167,11 +219,21 @@ impl RequestCallback for DownloadCallback { } fn on_progress(&mut self, dl_total: u64, dl_now: u64, _ul_total: u64, _ul_now: u64) { - if dl_now > self.processed { - self.processed = dl_now; - } else { + if !self.progress_restriction.data_receive + || dl_now == self.progress_restriction.processed + || dl_now == dl_total + { return; } + self.progress_restriction.processed = dl_now; + + let count = self.progress_restriction.count; + self.progress_restriction.count += 1; + if count % PROGRESS_INTERVAL != 0 { + return; + } + self.progress_restriction.count = 1; + let mut callbacks = self.callbacks.lock().unwrap(); for callback in callbacks.iter_mut() { callback.on_progress(dl_now, dl_total); @@ -185,7 +247,7 @@ pub struct TaskHandle { cancel_handle: Option, state: Arc, finish: Arc, - callbacks: Arc>>>, + callbacks: Arc>>>, } impl TaskHandle { @@ -195,7 +257,7 @@ impl TaskHandle { task_id, cancel_handle: None, finish: Arc::new(AtomicBool::new(false)), - callbacks: Arc::new(Mutex::new(vec![])), + callbacks: Arc::new(Mutex::new(VecDeque::with_capacity(1))), } } pub(crate) fn cancel(&mut self) { @@ -240,7 +302,7 @@ impl TaskHandle { let mut callbacks = self.callbacks.lock().unwrap(); if !self.finish.load(Ordering::Acquire) { info!("add callback to task {}", self.task_id.brief()); - callbacks.push(callback); + callbacks.push_back(callback); if let Some(handle) = self.cancel_handle.as_ref() { handle.add_count(); } @@ -261,7 +323,7 @@ impl TaskHandle { } #[inline] - fn callbacks(&self) -> Arc>>> { + fn callbacks(&self) -> Arc>>> { self.callbacks.clone() } @@ -279,7 +341,7 @@ pub(crate) fn download( ) -> TaskHandle { let mut handle = TaskHandle::new(task_id.clone()); if let Some(callback) = callback { - handle.callbacks.lock().unwrap().push(callback); + handle.callbacks.lock().unwrap().push_back(callback); } let callback = DownloadCallback::new( diff --git a/test/unittest/cpp_test/preload/BUILD.gn b/test/unittest/cpp_test/preload/BUILD.gn index 998ef92d..86312278 100644 --- a/test/unittest/cpp_test/preload/BUILD.gn +++ b/test/unittest/cpp_test/preload/BUILD.gn @@ -18,6 +18,7 @@ ohos_unittest("preload_test") { module_out_path = module_output_path include_dirs = [ + "include", "../../../../interfaces/inner_kits/predownload/include", "../../../../common/include", ] @@ -25,8 +26,8 @@ ohos_unittest("preload_test") { sources = [ "src/abnormal.cpp", "src/cancel.cpp", + "src/common.cpp", "src/fail.cpp", - "src/info.cpp", "src/progress.cpp", "src/success.cpp", ] diff --git a/test/unittest/cpp_test/preload/src/info.cpp b/test/unittest/cpp_test/preload/include/common.h similarity index 58% rename from test/unittest/cpp_test/preload/src/info.cpp rename to test/unittest/cpp_test/preload/include/common.h index b49308a9..4cb9309f 100644 --- a/test/unittest/cpp_test/preload/src/info.cpp +++ b/test/unittest/cpp_test/preload/include/common.h @@ -11,4 +11,22 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ \ No newline at end of file + */ + +#ifndef REQUEST_PRELOAD_TEST_COMMON_H +#define REQUEST_PRELOAD_TEST_COMMON_H + +#include +#include + +#include "request_preload.h" +struct TestCallback { + TestCallback(); + std::shared_ptr flagS; + std::shared_ptr flagF; + std::shared_ptr flagC; + std::shared_ptr flagP; + OHOS::Request::PreloadCallback callback; +}; + +#endif \ No newline at end of file diff --git a/test/unittest/cpp_test/preload/src/abnormal.cpp b/test/unittest/cpp_test/preload/src/abnormal.cpp index 02a95b2b..1bbcf603 100644 --- a/test/unittest/cpp_test/preload/src/abnormal.cpp +++ b/test/unittest/cpp_test/preload/src/abnormal.cpp @@ -31,20 +31,26 @@ #include #include +#include "common.h" #include "gmock/gmock.h" #include "log.h" #include "request_preload.h" using namespace testing::ext; using namespace OHOS::Request; -static std::string TEST_URL_0 = "https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/test.txt"; +static std::string TEST_URL_0 = "https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/" + "test.txt"; +static std::string TEST_URL_1 = "https://www.gitee.com/fqwert/aaaaaa"; -class PreloadAbnormalTest : public testing::Test { +constexpr size_t SLEEP_INTERVAL = 100; +constexpr size_t ABNORMAL_INTERVAL = 24; + +class PreloadAbnormal : public testing::Test { public: void SetUp(); }; -void PreloadAbnormalTest::SetUp(void) +void PreloadAbnormal::SetUp(void) { // input testcase setup step,setup invoked before each testcases testing::UnitTest *test = testing::UnitTest::GetInstance(); @@ -57,12 +63,12 @@ void PreloadAbnormalTest::SetUp(void) } /** - * @tc.name: PreloadAbnormalTest - * @tc.desc: Test PreloadAbnormalTest interface base function - nullCallback + * @tc.name: NullptrTest + * @tc.desc: Test nullptr callback * @tc.type: FUNC * @tc.require: Issue Number */ -HWTEST_F(PreloadAbnormalTest, PreloadAbnormalTest, TestSize.Level1) +HWTEST_F(PreloadAbnormal, NullptrTest, TestSize.Level1) { auto callback = PreloadCallback{ .OnSuccess = nullptr, @@ -72,4 +78,106 @@ HWTEST_F(PreloadAbnormalTest, PreloadAbnormalTest, TestSize.Level1) }; auto handle = Preload::GetInstance()->load(TEST_URL_0, std::make_unique(callback)); EXPECT_NE(handle, nullptr); -} \ No newline at end of file +} + +/** + * @tc.name: SuccessBlockCallbackTest + * @tc.desc: Test block callback not affect other callback + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(PreloadAbnormal, SuccessBlockCallbackTest, TestSize.Level1) +{ + auto url = TEST_URL_0; + Preload::GetInstance()->Remove(url); + auto abnormal_callback = PreloadCallback{ + .OnSuccess = + [](const std::shared_ptr &&data, const std::string &taskId) { + std::this_thread::sleep_for(std::chrono::hours(ABNORMAL_INTERVAL)); + }, + }; + auto handle = Preload::GetInstance()->load(url, std::make_unique(abnormal_callback)); + + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; + Preload::GetInstance()->load(url, std::make_unique(callback)); + + while (!handle->IsFinish()) { + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); + } + + EXPECT_FALSE(flagF->load()); + EXPECT_FALSE(flagC->load()); + EXPECT_TRUE(flagP->load()); + EXPECT_TRUE(flagS->load()); + EXPECT_EQ(handle->GetState(), PreloadState::SUCCESS); + Preload::GetInstance()->Remove(url); +} + +/** + * @tc.name: FailBlockCallbackTest + * @tc.desc: Test block callback not affect other callback + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(PreloadAbnormal, FailBlockCallbackTest, TestSize.Level1) +{ + auto url = TEST_URL_1; + Preload::GetInstance()->Remove(url); + auto abnormal_callback = PreloadCallback{ + .OnFail = + [](const PreloadError &error, const std::string &taskId) { + std::this_thread::sleep_for(std::chrono::hours(ABNORMAL_INTERVAL)); + }, + }; + auto handle = Preload::GetInstance()->load(url, std::make_unique(abnormal_callback)); + + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; + Preload::GetInstance()->load(url, std::make_unique(callback)); + + while (!handle->IsFinish()) { + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); + } + + EXPECT_TRUE(flagF->load()); + EXPECT_TRUE(flagP->load()); + EXPECT_FALSE(flagC->load()); + EXPECT_FALSE(flagS->load()); + EXPECT_EQ(handle->GetState(), PreloadState::FAIL); + Preload::GetInstance()->Remove(url); +} + +/** + * @tc.name: CancelBlockCallbackTest + * @tc.desc: Test block callback not affect other callback + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(PreloadAbnormal, CancelBlockCallbackTest, TestSize.Level1) +{ + auto url = TEST_URL_1; + Preload::GetInstance()->Remove(url); + auto abnormal_callback = PreloadCallback{ + .OnCancel = []() { std::this_thread::sleep_for(std::chrono::hours(ABNORMAL_INTERVAL)); }, + }; + auto handle = Preload::GetInstance()->load(url, std::make_unique(abnormal_callback)); + + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; + auto handle_1 = Preload::GetInstance()->load(url, std::make_unique(callback)); + handle->Cancel(); + handle_1->Cancel(); + + while (!handle->IsFinish()) { + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); + } + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); + + EXPECT_FALSE(flagF->load()); + EXPECT_TRUE(flagC->load()); + EXPECT_FALSE(flagP->load()); + EXPECT_FALSE(flagS->load()); + EXPECT_EQ(handle->GetState(), PreloadState::CANCEL); + Preload::GetInstance()->Remove(url); +} diff --git a/test/unittest/cpp_test/preload/src/cancel.cpp b/test/unittest/cpp_test/preload/src/cancel.cpp index 14b0571e..8f1344d8 100644 --- a/test/unittest/cpp_test/preload/src/cancel.cpp +++ b/test/unittest/cpp_test/preload/src/cancel.cpp @@ -27,22 +27,21 @@ #include #include #include -#include -#include #include +#include "common.h" #include "gmock/gmock.h" #include "log.h" #include "request_preload.h" using namespace testing::ext; using namespace OHOS::Request; - -class PreloadCancelTest : public testing::Test { +using namespace std; +class PreloadCancel : public testing::Test { public: void SetUp(); }; -void PreloadCancelTest::SetUp(void) +void PreloadCancel::SetUp(void) { // input testcase setup step,setup invoked before each testcases testing::UnitTest *test = testing::UnitTest::GetInstance(); @@ -54,10 +53,12 @@ void PreloadCancelTest::SetUp(void) GTEST_LOG_(INFO) << testCaseName.append(" start"); } -static std::string TEST_URL_0 = "https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/test.txt"; +static std::string TEST_URL_0 = "https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/" + "test.txt"; static std::string TEST_URL_1 = "https://www.w3cschool.cn/statics/demosource/movie.mp4"; static std::string TEST_URL_2 = "https://www.baidu.com"; -static std::string TEST_URL_3 = "https://vd4.bdstatic.com/mda-pm7bte3t6fs50rsh/sc/cae_h264/1702057792414494257/" +static std::string TEST_URL_3 = "https://vd4.bdstatic.com/mda-pm7bte3t6fs50rsh/sc/cae_h264/" + "1702057792414494257/" "mda-pm7bte3t6fs50rsh.mp4?v_from_s=bdapp-author-nanjing"; constexpr size_t SLEEP_INTERVAL = 100; @@ -65,19 +66,13 @@ constexpr size_t SLEEP_INTERVAL = 100; void DownloadCancelTest(std::string url) { Preload::GetInstance()->Remove(url); - auto flagS = std::make_shared(false); - auto flagF = std::make_shared(false); - auto flagC = std::make_shared(false); - auto flagP = std::make_shared(0); - auto callback = PreloadCallback{ - .OnSuccess = [flagS](const std::shared_ptr &&data, const std::string &taskId) { flagS->store(true); }, - .OnCancel = [flagC]() { flagC->store(true); }, - .OnFail = [flagF](const PreloadError &error, const std::string &taskId) { flagF->store(true); }, - .OnProgress = [flagP](uint64_t current, uint64_t total) { flagP->fetch_add(1); }, - }; + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; + auto handle = Preload::GetInstance()->load(url, std::make_unique(callback)); EXPECT_FALSE(handle->IsFinish()); + EXPECT_EQ(handle->GetState(), PreloadState::RUNNING); handle->Cancel(); while (!handle->IsFinish()) { @@ -88,16 +83,17 @@ void DownloadCancelTest(std::string url) EXPECT_FALSE(flagS->load()); EXPECT_TRUE(flagC->load()); EXPECT_EQ(flagP->load(), 0); + EXPECT_EQ(handle->GetState(), PreloadState::CANCEL); Preload::GetInstance()->Remove(url); } /** - * @tc.name: PreloadTest_002 - * @tc.desc: Test PreloadTest_002 interface base function - OnCancel + * @tc.name: OnCancelTest + * @tc.desc: Test PreloadCancel interface base function - OnCancel * @tc.type: FUNC * @tc.require: Issue Number */ -HWTEST_F(PreloadCancelTest, PreloadCancel, TestSize.Level1) +HWTEST_F(PreloadCancel, OnCancelTest, TestSize.Level1) { // chunk DownloadCancelTest(TEST_URL_0); @@ -105,4 +101,122 @@ HWTEST_F(PreloadCancelTest, PreloadCancel, TestSize.Level1) DownloadCancelTest(TEST_URL_1); DownloadCancelTest(TEST_URL_2); DownloadCancelTest(TEST_URL_3); +} + +/** + * @tc.name: OnCancelAddCallback_0 + * @tc.desc: Test Add callback for same url on cancel + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(PreloadCancel, OnCancelAddCallback_0, TestSize.Level1) +{ + auto url = TEST_URL_0; + Preload::GetInstance()->Remove(url); + + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; + + auto handle = Preload::GetInstance()->load(url, std::make_unique(callback)); + + TestCallback test1; + auto &[flagS_1, flagF_1, flagC_1, flagP_1, callback_1] = test1; + + auto handle_1 = Preload::GetInstance()->load(url, std::make_unique(callback_1)); + handle->Cancel(); + while (!handle->IsFinish()) { + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); + } + + EXPECT_FALSE(flagF->load()); + EXPECT_FALSE(flagF_1->load()); + EXPECT_FALSE(flagC->load()); + EXPECT_FALSE(flagC_1->load()); + + EXPECT_TRUE(flagP->load()); + EXPECT_TRUE(flagP_1->load()); + EXPECT_TRUE(flagS->load()); + EXPECT_TRUE(flagS_1->load()); + Preload::GetInstance()->Remove(url); +} + +/** + * @tc.name: PreloadCancel + * @tc.desc: Test Add callback for same url on cancel + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(PreloadCancel, OnCancelAddCallback_1, TestSize.Level1) +{ + auto url = TEST_URL_0; + Preload::GetInstance()->Remove(url); + + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; + + auto handle = Preload::GetInstance()->load(url, std::make_unique(callback)); + + TestCallback test1; + auto &[flagS_1, flagF_1, flagC_1, flagP_1, callback_1] = test1; + + auto handle_1 = Preload::GetInstance()->load(url, std::make_unique(callback_1)); + handle->Cancel(); + handle_1->Cancel(); + + while (!handle->IsFinish()) { + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); + } + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); + + EXPECT_FALSE(flagF->load()); + EXPECT_FALSE(flagF_1->load()); + EXPECT_FALSE(flagP->load()); + EXPECT_FALSE(flagP_1->load()); + EXPECT_FALSE(flagS->load()); + EXPECT_FALSE(flagS_1->load()); + + EXPECT_TRUE(flagC->load()); + EXPECT_TRUE(flagC_1->load()); + Preload::GetInstance()->Remove(url); +} + +/** + * @tc.name: PreloadCancel + * @tc.desc: Test Add callback for same url on cancel + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(PreloadCancel, OnCancelAddCallback_2, TestSize.Level1) +{ + auto url = TEST_URL_0; + Preload::GetInstance()->Remove(url); + + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; + + auto handle = Preload::GetInstance()->load(url, std::make_unique(callback)); + + handle->Cancel(); + + TestCallback test1; + auto &[flagS_1, flagF_1, flagC_1, flagP_1, callback_1] = test1; + + auto handle_1 = Preload::GetInstance()->load(url, std::make_unique(callback_1)); + + while (!handle_1->IsFinish()) { + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); + } + + EXPECT_FALSE(flagF->load()); + EXPECT_FALSE(flagF_1->load()); + + EXPECT_FALSE(flagP->load()); + EXPECT_TRUE(flagP_1->load()); + + EXPECT_FALSE(flagS->load()); + EXPECT_TRUE(flagS_1->load()); + + EXPECT_TRUE(flagC->load()); + EXPECT_FALSE(flagC_1->load()); + Preload::GetInstance()->Remove(url); } \ No newline at end of file diff --git a/test/unittest/cpp_test/preload/src/common.cpp b/test/unittest/cpp_test/preload/src/common.cpp new file mode 100644 index 00000000..5ec1e817 --- /dev/null +++ b/test/unittest/cpp_test/preload/src/common.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" + +#include "request_preload.h" +using namespace OHOS::Request; +TestCallback::TestCallback() +{ + auto flagS = std::make_shared(false); + auto flagF = std::make_shared(false); + auto flagC = std::make_shared(false); + auto flagP = std::make_shared(false); + this->callback = PreloadCallback{ + .OnSuccess = [flagS](const std::shared_ptr &&data, const std::string &taskId) { flagS->store(true); }, + .OnCancel = [flagC]() { flagC->store(true); }, + .OnFail = [flagF](const PreloadError &error, const std::string &taskId) { flagF->store(true); }, + .OnProgress = [flagP](uint64_t current, uint64_t total) { flagP->store(true); }, + }; + this->flagS = flagS; + this->flagF = flagF; + this->flagC = flagC; + this->flagP = flagP; +} \ No newline at end of file diff --git a/test/unittest/cpp_test/preload/src/fail.cpp b/test/unittest/cpp_test/preload/src/fail.cpp index 7b048dd7..f0075d74 100644 --- a/test/unittest/cpp_test/preload/src/fail.cpp +++ b/test/unittest/cpp_test/preload/src/fail.cpp @@ -31,18 +31,20 @@ #include #include +#include "common.h" #include "gmock/gmock.h" #include "log.h" #include "request_preload.h" + using namespace testing::ext; using namespace OHOS::Request; -class PreloadFailTest : public testing::Test { +class PreloadFail : public testing::Test { public: void SetUp(); }; -void PreloadFailTest::SetUp(void) +void PreloadFail::SetUp(void) { // input testcase setup step,setup invoked before each testcases testing::UnitTest *test = testing::UnitTest::GetInstance(); @@ -54,25 +56,19 @@ void PreloadFailTest::SetUp(void) GTEST_LOG_(INFO) << testCaseName.append(" start"); } -static std::string TEST_URL_2 = "https://127.3.1.123"; +static std::string TEST_URL_0 = "https://127.3.1.123"; +static std::string TEST_URL_1 = "https://www.gitee.com/fqwert/aaaaa"; constexpr size_t SLEEP_INTERVAL = 100; void DownloadFailTest(std::string url) { Preload::GetInstance()->Remove(url); - auto flagS = std::make_shared(false); - auto flagF = std::make_shared(false); - auto flagC = std::make_shared(false); - auto flagP = std::make_shared(0); + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; - auto callback = PreloadCallback{ - .OnSuccess = [flagS](const std::shared_ptr &&data, const std::string &taskId) { flagS->store(true); }, - .OnCancel = [flagC]() { flagC->store(true); }, - .OnFail = [flagF](const PreloadError &error, const std::string &taskId) { flagF->store(true); }, - .OnProgress = [flagP](uint64_t current, uint64_t total) { flagP->fetch_add(1); }, - }; auto handle = Preload::GetInstance()->load(url, std::make_unique(callback)); EXPECT_FALSE(handle->IsFinish()); + EXPECT_EQ(handle->GetState(), PreloadState::RUNNING); while (!handle->IsFinish()) { std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); @@ -81,28 +77,54 @@ void DownloadFailTest(std::string url) EXPECT_FALSE(flagS->load()); EXPECT_FALSE(flagC->load()); EXPECT_EQ(flagP->load(), 0); + EXPECT_EQ(handle->GetState(), PreloadState::FAIL); Preload::GetInstance()->Remove(url); } /** - * @tc.name: PreloadFailTest - * @tc.desc: Test PreloadFailTest interface base function - OnFail + * @tc.name: OnFailTest + * @tc.desc: Test PreloadCancel interface base function - OnCancel * @tc.type: FUNC * @tc.require: Issue Number */ -HWTEST_F(PreloadFailTest, PreloadFailTest, TestSize.Level1) +HWTEST_F(PreloadFail, OnFailTest, TestSize.Level1) { - auto flag = std::make_shared(0); - auto callback = PreloadCallback{ - .OnSuccess = [](const std::shared_ptr &&data, const std::string &taskId) {}, - .OnCancel = []() {}, - .OnFail = [flag](const PreloadError &error, const std::string &taskId) { flag->fetch_add(1); }, - .OnProgress = [](uint64_t current, uint64_t total) {}, - }; + DownloadFailTest(TEST_URL_0); +} - auto handle = Preload::GetInstance()->load(TEST_URL_2, std::make_unique(callback)); - std::this_thread::sleep_for(std::chrono::seconds(1)); - EXPECT_EQ(flag->load(), 1); - EXPECT_TRUE(handle->IsFinish()); - EXPECT_EQ(handle->GetState(), PreloadState::FAIL); +/** + * @tc.name: PreloadFailTest + * @tc.desc: Test Add callback for same url on fail + * @tc.type: FUNC + * @tc.require: Issue Number + */ +HWTEST_F(PreloadFail, OnFailAddCallback, TestSize.Level1) +{ + auto url = TEST_URL_1; + Preload::GetInstance()->Remove(url); + + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; + + auto handle = Preload::GetInstance()->load(url, std::make_unique(callback)); + + TestCallback test1; + auto &[flagS_1, flagF_1, flagC_1, flagP_1, callback_1] = test1; + + auto handle_1 = Preload::GetInstance()->load(url, std::make_unique(callback_1)); + + while (!handle->IsFinish()) { + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); + } + + EXPECT_TRUE(flagF->load()); + EXPECT_TRUE(flagF_1->load()); + EXPECT_FALSE(flagC->load()); + EXPECT_FALSE(flagC_1->load()); + + EXPECT_TRUE(flagP->load()); + EXPECT_TRUE(flagP_1->load()); + EXPECT_FALSE(flagS->load()); + EXPECT_FALSE(flagS_1->load()); + Preload::GetInstance()->Remove(url); } \ No newline at end of file diff --git a/test/unittest/cpp_test/preload/src/progress.cpp b/test/unittest/cpp_test/preload/src/progress.cpp index b49308a9..ad9c8bf1 100644 --- a/test/unittest/cpp_test/preload/src/progress.cpp +++ b/test/unittest/cpp_test/preload/src/progress.cpp @@ -11,4 +11,111 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ \ No newline at end of file + */ + +/** + * @tc.name: WrapperCStringTest_001 + * @tc.desc: Test WrapperCString interface base function + * @tc.type: FUNC + * @tc.require: Issue Number + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "gmock/gmock.h" +#include "log.h" +#include "request_preload.h" + +using namespace testing::ext; +using namespace OHOS::Request; + +class PreloadProgress : public testing::Test { +public: + void SetUp(); +}; + +void PreloadProgress::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases + testing::UnitTest *test = testing::UnitTest::GetInstance(); + ASSERT_NE(test, nullptr); + const testing::TestInfo *testInfo = test->current_test_info(); + ASSERT_NE(testInfo, nullptr); + string testCaseName = string(testInfo->name()); + REQUEST_HILOGI("[SetUp] %{public}s start", testCaseName.c_str()); + GTEST_LOG_(INFO) << testCaseName.append(" start"); +} + +static std::string TEST_URL_0 = "https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/" + "test.txt"; +static std::string TEST_URL_1 = "https://www.w3cschool.cn/statics/demosource/movie.mp4"; +static std::string TEST_URL_2 = "https://www.baidu.com"; +static std::string TEST_URL_3 = "https://vd4.bdstatic.com/mda-pm7bte3t6fs50rsh/sc/cae_h264/" + "1702057792414494257/" + "mda-pm7bte3t6fs50rsh.mp4?v_from_s=bdapp-author-nanjing"; + +constexpr size_t SLEEP_INTERVAL = 100; + +void DownloadProgressTest(std::string url) +{ + Preload::GetInstance()->Remove(url); + auto flagS = std::make_shared(false); + auto flagF = std::make_shared(false); + auto flagC = std::make_shared(false); + auto flagTot = std::make_shared(0); + auto flagCur = std::make_shared(0); + auto flagP = std::make_shared(true); + auto callback = PreloadCallback{ + .OnSuccess = [flagS](const std::shared_ptr &&data, const std::string &taskId) { flagS->store(true); }, + .OnCancel = [flagC]() { flagC->store(true); }, + .OnFail = [flagF](const PreloadError &error, const std::string &taskId) { flagF->store(true); }, + .OnProgress = + [flagCur, flagTot, flagP](uint64_t current, uint64_t total) { + if (flagCur->load() > current) { + flagP->store(false); + } + if (flagTot->load() > total) { + flagP->store(false); + } + flagCur->store(current); + flagTot->store(total); + }, + }; + auto handle = Preload::GetInstance()->load(url, std::make_unique(callback)); + while (!handle->IsFinish()) { + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); + } + EXPECT_FALSE(flagF->load()); + EXPECT_FALSE(flagC->load()); + + EXPECT_TRUE(flagP->load()); + EXPECT_TRUE(flagS->load()); + + EXPECT_EQ(flagCur->load(), flagTot->load()); + Preload::GetInstance()->Remove(url); +} + +/** + * @tc.name: OnProgressTest + * @tc.desc: Test PreloadSuccessCache interface base function - OnSuccess + * @tc.type: FUNC + * @tc.require: Issue Number + */ + +HWTEST_F(PreloadProgress, OnProgressTest, TestSize.Level1) +{ + DownloadProgressTest(TEST_URL_0); + DownloadProgressTest(TEST_URL_1); + DownloadProgressTest(TEST_URL_2); + DownloadProgressTest(TEST_URL_3); +} diff --git a/test/unittest/cpp_test/preload/src/success.cpp b/test/unittest/cpp_test/preload/src/success.cpp index ea4b69dc..bf4512d5 100644 --- a/test/unittest/cpp_test/preload/src/success.cpp +++ b/test/unittest/cpp_test/preload/src/success.cpp @@ -31,6 +31,7 @@ #include #include +#include "common.h" #include "gmock/gmock.h" #include "log.h" #include "request_preload.h" @@ -39,21 +40,23 @@ using namespace OHOS::Request; constexpr size_t SLEEP_INTERVAL = 100; constexpr size_t FETCH_INTERVAL = 5; -static std::string TEST_URL_0 = "https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/test.txt"; +static std::string TEST_URL_0 = "https://www.gitee.com/tiga-ultraman/downloadTests/releases/download/v1.01/" + "test.txt"; static std::string TEST_URL_1 = "https://www.w3cschool.cn/statics/demosource/movie.mp4"; static std::string TEST_URL_2 = "https://www.baidu.com"; -static std::string TEST_URL_3 = "https://vd4.bdstatic.com/mda-pm7bte3t6fs50rsh/sc/cae_h264/1702057792414494257/" +static std::string TEST_URL_3 = "https://vd4.bdstatic.com/mda-pm7bte3t6fs50rsh/sc/cae_h264/" + "1702057792414494257/" "mda-pm7bte3t6fs50rsh.mp4?v_from_s=bdapp-author-nanjing"; constexpr uint64_t TEST_SIZE_0 = 1042003; constexpr uint64_t TEST_SIZE_1 = 318465; -class PreloadSuccessTest : public testing::Test { +class PreloadSuccess : public testing::Test { public: void SetUp(); }; -void PreloadSuccessTest::SetUp(void) +void PreloadSuccess::SetUp(void) { // input testcase setup step,setup invoked before each testcases testing::UnitTest *test = testing::UnitTest::GetInstance(); @@ -68,38 +71,32 @@ void PreloadSuccessTest::SetUp(void) void DownloadSuccessTest(std::string url, uint64_t size) { Preload::GetInstance()->Remove(url); - auto flagS = std::make_shared(0); - auto flagF = std::make_shared(false); - auto flagC = std::make_shared(false); - auto flagP = std::make_shared(0); - auto callback = PreloadCallback{ - .OnSuccess = [flagS](const std::shared_ptr &&data, - const std::string &taskId) { flagS->store(data->bytes().size()); }, - .OnCancel = [flagC]() { flagC->store(true); }, - .OnFail = [flagF](const PreloadError &error, const std::string &taskId) { flagF->store(true); }, - .OnProgress = [flagP](uint64_t current, uint64_t total) { flagP->fetch_add(1); }, - }; + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; + auto handle = Preload::GetInstance()->load(url, std::make_unique(callback)); EXPECT_FALSE(handle->IsFinish()); + EXPECT_EQ(handle->GetState(), PreloadState::RUNNING); while (!handle->IsFinish()) { std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); } EXPECT_FALSE(flagF->load()); EXPECT_FALSE(flagC->load()); - EXPECT_TRUE(flagP->load() > 0); - EXPECT_EQ(flagS->load(), size); + EXPECT_TRUE(flagP->load()); + EXPECT_TRUE(flagS->load()); + EXPECT_EQ(handle->GetState(), PreloadState::SUCCESS); Preload::GetInstance()->Remove(url); } /** - * @tc.name: PreloadSuccessTest_001 - * @tc.desc: Test PreloadSuccessTest_001 interface base function - OnSuccess + * @tc.name: OnSuccessTest + * @tc.desc: Test OnSuccessTest interface base function - OnSuccess * @tc.type: FUNC * @tc.require: Issue Number */ -HWTEST_F(PreloadSuccessTest, PreloadSuccessCallback, TestSize.Level1) +HWTEST_F(PreloadSuccess, OnSuccessTest, TestSize.Level1) { // chunk DownloadSuccessTest(TEST_URL_0, TEST_SIZE_0); @@ -108,42 +105,24 @@ HWTEST_F(PreloadSuccessTest, PreloadSuccessCallback, TestSize.Level1) } /** - * @tc.name: PreloadSuccessAddCallback - * @tc.desc: Test PreloadSuccessAddCallback interface base function - OnSuccess + * @tc.name: OnSuccessAddCallback + * @tc.desc: Test Add callback for same url on cancel * @tc.type: FUNC * @tc.require: Issue Number */ -HWTEST_F(PreloadSuccessTest, PreloadSuccessAddCallback, TestSize.Level1) +HWTEST_F(PreloadSuccess, OnSuccessAddCallback, TestSize.Level1) { auto url = TEST_URL_2; Preload::GetInstance()->Remove(url); - auto flagS = std::make_shared(false); - auto flagF = std::make_shared(false); - auto flagC = std::make_shared(false); - auto flagP = std::make_shared(0); - - auto callback = PreloadCallback{ - .OnSuccess = [flagS](const std::shared_ptr &&data, const std::string &taskId) { flagS->store(true); }, - .OnCancel = [flagC]() { flagC->store(true); }, - .OnFail = [flagF](const PreloadError &error, const std::string &taskId) { flagF->store(true); }, - .OnProgress = [flagP](uint64_t current, uint64_t total) { flagP->fetch_add(1); }, - }; + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; auto handle = Preload::GetInstance()->load(url, std::make_unique(callback)); - auto flagS_1 = std::make_shared(false); - auto flagF_1 = std::make_shared(false); - auto flagC_1 = std::make_shared(false); - auto flagP_1 = std::make_shared(0); - - auto callback_1 = PreloadCallback{ - .OnSuccess = [flagS_1](const std::shared_ptr &&data, const std::string &taskId) { flagS_1->store(true); }, - .OnCancel = [flagC_1]() { flagC_1->store(true); }, - .OnFail = [flagF_1](const PreloadError &error, const std::string &taskId) { flagF_1->store(true); }, - .OnProgress = [flagP_1](uint64_t current, uint64_t total) { flagP_1->fetch_add(1); }, - }; + TestCallback test1; + auto &[flagS_1, flagF_1, flagC_1, flagP_1, callback_1] = test1; auto handle_1 = Preload::GetInstance()->load(url, std::make_unique(callback_1)); @@ -155,36 +134,28 @@ HWTEST_F(PreloadSuccessTest, PreloadSuccessAddCallback, TestSize.Level1) EXPECT_FALSE(flagF_1->load()); EXPECT_FALSE(flagC->load()); EXPECT_FALSE(flagC_1->load()); - EXPECT_TRUE(flagP->load() > 0); - EXPECT_TRUE(flagP_1->load() > 0); + + EXPECT_TRUE(flagP->load()); + EXPECT_TRUE(flagP_1->load()); EXPECT_TRUE(flagS->load()); EXPECT_TRUE(flagS_1->load()); Preload::GetInstance()->Remove(url); } /** - * @tc.name: PreloadSuccessCache - * @tc.desc: Test PreloadSuccessCache interface base function - OnSuccess + * @tc.name: OnSuccessCache + * @tc.desc: Test cached data * @tc.type: FUNC * @tc.require: Issue Number */ -HWTEST_F(PreloadSuccessTest, PreloadSuccessCache, TestSize.Level1) +HWTEST_F(PreloadSuccess, OnSuccessCache, TestSize.Level1) { auto url = TEST_URL_3; Preload::GetInstance()->Remove(url); - auto flagS = std::make_shared(false); - auto flagF = std::make_shared(false); - auto flagC = std::make_shared(false); - auto flagP = std::make_shared(0); - - auto callback = PreloadCallback{ - .OnSuccess = [flagS](const std::shared_ptr &&data, const std::string &taskId) { flagS->store(true); }, - .OnCancel = [flagC]() { flagC->store(true); }, - .OnFail = [flagF](const PreloadError &error, const std::string &taskId) { flagF->store(true); }, - .OnProgress = [flagP](uint64_t current, uint64_t total) { flagP->fetch_add(1); }, - }; + TestCallback test; + auto &[flagS, flagF, flagC, flagP, callback] = test; auto handle = Preload::GetInstance()->load(url, std::make_unique(callback)); @@ -192,17 +163,8 @@ HWTEST_F(PreloadSuccessTest, PreloadSuccessCache, TestSize.Level1) std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL)); } - auto flagS_1 = std::make_shared(false); - auto flagF_1 = std::make_shared(false); - auto flagC_1 = std::make_shared(false); - auto flagP_1 = std::make_shared(0); - - auto callback_1 = PreloadCallback{ - .OnSuccess = [flagS_1](const std::shared_ptr &&data, const std::string &taskId) { flagS_1->store(true); }, - .OnCancel = [flagC_1]() { flagC_1->store(true); }, - .OnFail = [flagF_1](const PreloadError &error, const std::string &taskId) { flagF_1->store(true); }, - .OnProgress = [flagP_1](uint64_t current, uint64_t total) { flagP_1->fetch_add(1); }, - }; + TestCallback test1; + auto &[flagS_1, flagF_1, flagC_1, flagP_1, callback_1] = test1; auto handle_1 = Preload::GetInstance()->load(url, std::make_unique(callback_1)); std::this_thread::sleep_for(std::chrono::milliseconds(FETCH_INTERVAL)); @@ -211,8 +173,9 @@ HWTEST_F(PreloadSuccessTest, PreloadSuccessCache, TestSize.Level1) EXPECT_FALSE(flagF_1->load()); EXPECT_FALSE(flagC->load()); EXPECT_FALSE(flagC_1->load()); - EXPECT_TRUE(flagP->load() > 0); - EXPECT_EQ(flagP_1->load(), 0); + EXPECT_FALSE(flagP_1->load()); + + EXPECT_TRUE(flagP->load()); EXPECT_TRUE(flagS->load()); EXPECT_TRUE(flagS_1->load()); Preload::GetInstance()->Remove(url);