!1087 预加载回调调整,增加测试

Merge pull request !1087 from fqwert/predownload
This commit is contained in:
openharmony_ci 2024-11-21 01:56:50 +00:00 committed by Gitee
commit 40a4e0910c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
11 changed files with 582 additions and 151 deletions

View File

@ -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"

View File

@ -18,6 +18,7 @@ edition = "2021"
[features]
default = [
"ohos",
]
ohos = [

View File

@ -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<RamCache>,
finish: Arc<AtomicBool>,
state: Arc<AtomicUsize>,
callbacks: Arc<Mutex<Vec<Box<dyn CustomCallback>>>>,
processed: u64,
callbacks: Arc<Mutex<VecDeque<Box<dyn CustomCallback>>>>,
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<AtomicBool>,
callbacks: Arc<Mutex<Vec<Box<dyn CustomCallback>>>>,
callbacks: Arc<Mutex<VecDeque<Box<dyn CustomCallback>>>>,
state: Arc<AtomicUsize>,
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<CancelHandle>,
state: Arc<AtomicUsize>,
finish: Arc<AtomicBool>,
callbacks: Arc<Mutex<Vec<Box<dyn CustomCallback>>>>,
callbacks: Arc<Mutex<VecDeque<Box<dyn CustomCallback>>>>,
}
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<Mutex<Vec<Box<dyn CustomCallback>>>> {
fn callbacks(&self) -> Arc<Mutex<VecDeque<Box<dyn CustomCallback>>>> {
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(

View File

@ -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",
]

View File

@ -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.
*/
*/
#ifndef REQUEST_PRELOAD_TEST_COMMON_H
#define REQUEST_PRELOAD_TEST_COMMON_H
#include <atomic>
#include <memory>
#include "request_preload.h"
struct TestCallback {
TestCallback();
std::shared_ptr<std::atomic_bool> flagS;
std::shared_ptr<std::atomic_bool> flagF;
std::shared_ptr<std::atomic_bool> flagC;
std::shared_ptr<std::atomic_bool> flagP;
OHOS::Request::PreloadCallback callback;
};
#endif

View File

@ -31,20 +31,26 @@
#include <unordered_map>
#include <vector>
#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 stepsetup 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<PreloadCallback>(callback));
EXPECT_NE(handle, nullptr);
}
}
/**
* @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> &&data, const std::string &taskId) {
std::this_thread::sleep_for(std::chrono::hours(ABNORMAL_INTERVAL));
},
};
auto handle = Preload::GetInstance()->load(url, std::make_unique<PreloadCallback>(abnormal_callback));
TestCallback test;
auto &[flagS, flagF, flagC, flagP, callback] = test;
Preload::GetInstance()->load(url, std::make_unique<PreloadCallback>(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<PreloadCallback>(abnormal_callback));
TestCallback test;
auto &[flagS, flagF, flagC, flagP, callback] = test;
Preload::GetInstance()->load(url, std::make_unique<PreloadCallback>(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<PreloadCallback>(abnormal_callback));
TestCallback test;
auto &[flagS, flagF, flagC, flagP, callback] = test;
auto handle_1 = Preload::GetInstance()->load(url, std::make_unique<PreloadCallback>(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);
}

View File

@ -27,22 +27,21 @@
#include <cstdint>
#include <memory>
#include <thread>
#include <tuple>
#include <unordered_map>
#include <vector>
#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 stepsetup 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<std::atomic_bool>(false);
auto flagF = std::make_shared<std::atomic_bool>(false);
auto flagC = std::make_shared<std::atomic_bool>(false);
auto flagP = std::make_shared<std::atomic_int64_t>(0);
auto callback = PreloadCallback{
.OnSuccess = [flagS](const std::shared_ptr<Data> &&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<PreloadCallback>(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<PreloadCallback>(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<PreloadCallback>(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<PreloadCallback>(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<PreloadCallback>(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<PreloadCallback>(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<PreloadCallback>(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);
}

View File

@ -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<std::atomic_bool>(false);
auto flagF = std::make_shared<std::atomic_bool>(false);
auto flagC = std::make_shared<std::atomic_bool>(false);
auto flagP = std::make_shared<std::atomic_bool>(false);
this->callback = PreloadCallback{
.OnSuccess = [flagS](const std::shared_ptr<Data> &&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;
}

View File

@ -31,18 +31,20 @@
#include <unordered_map>
#include <vector>
#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 stepsetup 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<std::atomic_bool>(false);
auto flagF = std::make_shared<std::atomic_bool>(false);
auto flagC = std::make_shared<std::atomic_bool>(false);
auto flagP = std::make_shared<std::atomic_int64_t>(0);
TestCallback test;
auto &[flagS, flagF, flagC, flagP, callback] = test;
auto callback = PreloadCallback{
.OnSuccess = [flagS](const std::shared_ptr<Data> &&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<PreloadCallback>(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<std::atomic_uint64_t>(0);
auto callback = PreloadCallback{
.OnSuccess = [](const std::shared_ptr<Data> &&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<PreloadCallback>(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<PreloadCallback>(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<PreloadCallback>(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);
}

View File

@ -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.
*/
*/
/**
* @tc.name: WrapperCStringTest_001
* @tc.desc: Test WrapperCString interface base function
* @tc.type: FUNC
* @tc.require: Issue Number
*/
#include <gtest/gtest.h>
#include <atomic>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <thread>
#include <tuple>
#include <unordered_map>
#include <vector>
#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 stepsetup 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<std::atomic_bool>(false);
auto flagF = std::make_shared<std::atomic_bool>(false);
auto flagC = std::make_shared<std::atomic_bool>(false);
auto flagTot = std::make_shared<std::atomic_uint64_t>(0);
auto flagCur = std::make_shared<std::atomic_uint64_t>(0);
auto flagP = std::make_shared<std::atomic_bool>(true);
auto callback = PreloadCallback{
.OnSuccess = [flagS](const std::shared_ptr<Data> &&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<PreloadCallback>(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);
}

View File

@ -31,6 +31,7 @@
#include <unordered_map>
#include <vector>
#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 stepsetup 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<std::atomic_uint64_t>(0);
auto flagF = std::make_shared<std::atomic_bool>(false);
auto flagC = std::make_shared<std::atomic_bool>(false);
auto flagP = std::make_shared<std::atomic_int64_t>(0);
auto callback = PreloadCallback{
.OnSuccess = [flagS](const std::shared_ptr<Data> &&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<PreloadCallback>(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<std::atomic_bool>(false);
auto flagF = std::make_shared<std::atomic_bool>(false);
auto flagC = std::make_shared<std::atomic_bool>(false);
auto flagP = std::make_shared<std::atomic_int64_t>(0);
auto callback = PreloadCallback{
.OnSuccess = [flagS](const std::shared_ptr<Data> &&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<PreloadCallback>(callback));
auto flagS_1 = std::make_shared<std::atomic_bool>(false);
auto flagF_1 = std::make_shared<std::atomic_bool>(false);
auto flagC_1 = std::make_shared<std::atomic_bool>(false);
auto flagP_1 = std::make_shared<std::atomic_int64_t>(0);
auto callback_1 = PreloadCallback{
.OnSuccess = [flagS_1](const std::shared_ptr<Data> &&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<PreloadCallback>(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<std::atomic_bool>(false);
auto flagF = std::make_shared<std::atomic_bool>(false);
auto flagC = std::make_shared<std::atomic_bool>(false);
auto flagP = std::make_shared<std::atomic_int64_t>(0);
auto callback = PreloadCallback{
.OnSuccess = [flagS](const std::shared_ptr<Data> &&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<PreloadCallback>(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<std::atomic_bool>(false);
auto flagF_1 = std::make_shared<std::atomic_bool>(false);
auto flagC_1 = std::make_shared<std::atomic_bool>(false);
auto flagP_1 = std::make_shared<std::atomic_int64_t>(0);
auto callback_1 = PreloadCallback{
.OnSuccess = [flagS_1](const std::shared_ptr<Data> &&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<PreloadCallback>(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);