和什么细什么| 小孩用脚尖走路是什么原因| 彬字五行属什么| plt是什么意思| 幻觉幻听是什么症状| 经常打嗝放屁是什么原因| vca是什么牌子| 半夜猫叫有什么预兆| 令瓦念什么| 常吃阿司匹林有什么副作用| 胎儿缺氧孕妇会有什么反应| 什么的海洋| 什么是力量训练| 一直咳嗽不见好是什么原因| 到底什么是爱| 经常做噩梦的原因是什么| 肚子疼呕吐是什么原因引起的| 十二指肠球部溃疡吃什么药| 咽炎吃什么好| 观音菩萨的坐骑是什么| 小囊性灶是什么意思| 鲁迅为什么弃医从文| 皮肤瘙痒是什么原因| 乳腺结节有什么危害| 老鼠最怕什么气味驱赶| 开荤是什么意思| 中元节是什么意思| 牙槽骨吸收是什么意思| 女方起诉离婚需要什么证件| 星期一右眼皮跳是什么预兆| 羊膜是什么| 现象是什么意思| 木字旁的字与什么有关| 刽子手是什么意思| 情非得已是什么生肖| 14年属什么生肖| 白腊金是什么意思| buffalo是什么牌子| ricoh什么牌子| lsp是什么| 扁桃体肿大是什么原因引起的| 冬瓜和什么不能一起吃| ACS什么意思| 什么是胃溃疡| 压迫感是什么意思| 乳房皮肤痒是什么原因| 胆结石吃什么比较好| 腰椎间盘突出适合什么运动| 胃反流吃什么药效果好| 眼干眼涩眼疲劳用什么眼药水| 憋尿憋不住是什么原因| 开山鼻祖是什么意思| 身体缺钾会有什么症状| 18度穿什么衣服合适| 结婚六十年是什么婚| 为什么会有黑头| 长脓包是什么原因| 胃炎是什么原因引起的| 孟买血型是什么意思| 礼五行属什么| 八哥鸟吃什么饲料最好| 7月31日是什么星座| 琬字五行属什么| 萘是什么| pa代表什么意思| 低烧是什么原因引起的| 永恒是什么意思| 脾胃不和吃什么药| 吃虾不能吃什么水果| 阳虚水泛是什么症状| 什么叫低钾血症| 玫瑰花泡水喝有什么功效| 葡萄像什么比喻句| 一天什么时候最热| 77年属什么生肖| 血糖30多有什么危险| 门特是什么| 脚痒脱皮是什么原因| 三教九流代表什么生肖| 体寒的女人吃什么能调理好身体| 暴饮暴食是什么意思| 锦鲤什么意思| 尿常规能查出什么| 回奶吃什么快最有效的| 氮肥是什么肥料| 割伤用什么药愈合伤口| 中国的国粹是什么| 吃饭出虚汗是什么原因| 冷暖自知的前一句是什么| 胆囊是干什么用的| 口干口苦是什么原因引起的| 什么水果消炎| 吃什么变聪明| 五光十色是什么意思| 这厮是什么意思| 天高云淡是什么季节| 静推是什么意思| 九天揽月是什么意思| 什么是公职人员| 肠炎可以吃什么水果| 七宗罪都是什么| 愿君多采撷是什么意思| 中暑是什么症状| hcg是检查什么的| 吃什么都吐是什么原因| 漫游什么意思| 调节是什么意思| cmc是什么| 一饿就胃疼是什么原因| 长期便秘吃什么药好| 衣原体感染吃什么药| 又什么又什么| 鬼冢虎为什么很少人穿| 腿困是什么原因引起的| 妆前乳是什么| 怀孕初期应该注意什么| 非萎缩性胃炎是什么意思| 芈月和秦始皇什么关系| 丑是什么意思| 欧诗漫是个什么档次| 专项变应原筛查是什么| 脚底痛是什么原因| 客套是什么意思| 困觉是什么意思| 什么冰冰| 禁的拼音是什么| 狗狗胰腺炎有什么症状| 末次月经是什么意思| 七月二十二什么日子| 肚子疼拉稀吃什么药| 二月什么座| 男人左眼跳是什么预兆| 什么是低血糖| 肥胖纹什么样子| 前来是什么意思| 篱笆是什么意思| 智商是什么意思| 公务员是什么职业| 什么情况下会猝死| 耸肩是什么意思| 烟雾病是什么| 减肥晚上适合吃什么水果| 炸东西用什么淀粉| 接触隔离什么意思| 什么地端详| roa是什么| 睡觉多梦是什么原因引起的| 氨基丁酸是什么| 奢靡是什么意思| 什么的笋| 什么蛇不咬人| 亨廷顿舞蹈症是什么病| 八月二号是什么星座| 奇异是什么意思| 底妆是什么意思| 什么是ct| 最小的一位数是什么| 人为什么会突然晕倒| 我国的国球是什么球| 脑管瘤的症状是什么| 怀疑甲亢需要做什么检查| 无极调光是什么意思| 泰安有什么大学| 利郎男装是什么档次的| 胺碘酮又叫什么名字| 大便蛋花状是什么原因| 隐血十一是什么意思| 大便有血是什么原因男性| 视力模糊用什么眼药水| 梦见老公不理我是什么意思| 打鼾是什么意思| 开心果是什么树的果实| 天伦之乐什么意思| 入木三分什么意思| 五年存活率是什么意思| 11月份生日是什么星座| 外痔用什么药| 看病人送什么鲜花好| 汉武帝属什么生肖| 纳气是什么意思| 五月七日是什么星座| m k是什么牌子| 俄狄浦斯情结是什么意思| 十月二十八是什么星座| 牛肉馅配什么菜包饺子好吃| 什么东西有助于睡眠| 真菌感染皮肤病用什么药最好| 四大神兽是什么动物| 京东什么时候优惠最大| 骨折用什么药恢复快| 什么是调和油| 为什么插不进去| rna是什么| 中元节出什么生肖| 虾与什么食物相克| 什么气味能驱赶猫| 天蝎座和什么星座不合| 开塞露擦脸有什么效果| 婴儿吃什么奶粉好吸收| 什么鱼适合清蒸| 七月三号是什么日子| 破军星是什么意思| 1992年属什么生肖年| ims是什么意思| 戾气重是什么意思| 身份证借给别人有什么危害性| 思维是什么| 孕妇吃猕猴桃对胎儿有什么好处| 元旦吃什么| 大雄宝殿是什么意思| 皮肤过敏用什么药最好| 吃什么对肝最好| 膀胱钙化是什么意思| 娃娃鱼吃什么| 小便尿道刺痛吃什么药| AMY医学上是什么意思| 什么微风| 梦见火车脱轨什么预兆| 男女更年期分别在什么年龄| 大力念什么| 灵芝搭配什么煲汤最好| 参军是什么官职| 丙型肝炎病毒抗体阴性什么意思| 结婚一年是什么婚| 2006年属什么生肖| ken是什么意思| 脂肪肝什么意思| 吃什么可以补黑色素| 双肾钙化灶是什么意思| 胃肠彩超能检查出什么| 乳腺增生乳腺结节吃什么药| 1933年属什么| 早泄要吃什么药| 花非花雾非雾什么意思| 全身疼痛是什么原因| 硫酸是什么| 肝癌早期有什么症状| 活水是什么意思| 脚后跟开裂是什么原因| 囊变是什么意思| 梦到小鸟是什么意思| 减肥吃什么药| 丰盈是什么意思| 肠梗阻挂什么科| 什么的积雪| 唱反调是什么意思| 绿色加什么颜色是蓝色| 吃什么对心脏好| 三元及第是什么意思| 蛇属于什么类动物| pd999是什么金| 精液是什么味| 欲生欲死是什么意思| 前列腺增生有什么症状| 梦见假牙掉了是什么意思| 音爆是什么| 流金铄石是什么意思| 肩宽适合穿什么样的衣服| 嘴唇起小水泡是什么原因| 2023年是属什么生肖| 梦见野猪是什么预兆| 坐久了脚肿是什么原因| 人情世故什么意思| 镁低了是什么原因| 百度
blob: 41e5e7dcf2291a929a9aef484fcbcd4263f6c768 [file] [log] [blame] [edit]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <algorithm>
#include <memory>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/test/task_environment.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/test_service.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace dbus {
namespace {
// See comments in ObjectProxy::RunResponseCallback() for why the number was
// chosen.
const int kHugePayloadSize = 64 << 20; // 64 MB
} // namespace
// The end-to-end test exercises the asynchronous APIs in ObjectProxy and
// ExportedObject.
class EndToEndAsyncTest : public testing::Test {
public:
void SetUp() override {
// Make the main thread not to allow IO.
base::ThreadRestrictions::SetIOAllowed(false);
// Start the D-Bus thread.
dbus_thread_ = std::make_unique<base::Thread>("D-Bus Thread");
base::Thread::Options thread_options;
thread_options.message_pump_type = base::MessagePumpType::IO;
ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options));
// Start the test service, using the D-Bus thread.
TestService::Options options;
options.dbus_task_runner = dbus_thread_->task_runner();
test_service_ = std::make_unique<TestService>(options);
ASSERT_TRUE(test_service_->StartService());
test_service_->WaitUntilServiceIsStarted();
ASSERT_TRUE(test_service_->HasDBusThread());
// Create the client, using the D-Bus thread.
Bus::Options bus_options;
bus_options.bus_type = Bus::SESSION;
bus_options.connection_type = Bus::PRIVATE;
bus_options.dbus_task_runner = dbus_thread_->task_runner();
bus_ = new Bus(bus_options);
object_proxy_ = bus_->GetObjectProxy(
test_service_->service_name(),
ObjectPath("/org/chromium/TestObject"));
ASSERT_TRUE(bus_->HasDBusThread());
// Connect to the "Test" signal of "org.chromium.TestInterface" from
// the remote object.
object_proxy_->ConnectToSignal(
"org.chromium.TestInterface", "Test",
base::BindRepeating(&EndToEndAsyncTest::OnTestSignal,
base::Unretained(this)),
base::BindOnce(&EndToEndAsyncTest::OnConnected,
base::Unretained(this)));
// Wait until the object proxy is connected to the signal.
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
// Connect to the "Test2" signal of "org.chromium.TestInterface" from
// the remote object. There was a bug where we were emitting error
// messages like "Requested to remove an unknown match rule: ..." at
// the shutdown of Bus when an object proxy is connected to more than
// one signal of the same interface. See crosbug.com/23382 for details.
object_proxy_->ConnectToSignal(
"org.chromium.TestInterface", "Test2",
base::BindRepeating(&EndToEndAsyncTest::OnTest2Signal,
base::Unretained(this)),
base::BindOnce(&EndToEndAsyncTest::OnConnected,
base::Unretained(this)));
// Wait until the object proxy is connected to the signal.
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
// Create a second object proxy for the root object.
root_object_proxy_ = bus_->GetObjectProxy(test_service_->service_name(),
ObjectPath("/"));
ASSERT_TRUE(bus_->HasDBusThread());
// Connect to the "Test" signal of "org.chromium.TestInterface" from
// the root remote object too.
root_object_proxy_->ConnectToSignal(
"org.chromium.TestInterface", "Test",
base::BindRepeating(&EndToEndAsyncTest::OnRootTestSignal,
base::Unretained(this)),
base::BindOnce(&EndToEndAsyncTest::OnConnected,
base::Unretained(this)));
// Wait until the root object proxy is connected to the signal.
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
void TearDown() override {
bus_->ShutdownOnDBusThreadAndBlock();
// Shut down the service.
test_service_->ShutdownAndBlock();
// Reset to the default.
base::ThreadRestrictions::SetIOAllowed(true);
// Stopping a thread is considered an IO operation, so do this after
// allowing IO.
test_service_->Stop();
}
protected:
// Replaces the bus with a broken one.
void SetUpBrokenBus() {
// Shut down the existing bus.
bus_->ShutdownOnDBusThreadAndBlock();
// Create new bus with invalid address.
const char kInvalidAddress[] = "";
Bus::Options bus_options;
bus_options.bus_type = Bus::CUSTOM_ADDRESS;
bus_options.address = kInvalidAddress;
bus_options.connection_type = Bus::PRIVATE;
bus_options.dbus_task_runner = dbus_thread_->task_runner();
bus_ = new Bus(bus_options);
ASSERT_TRUE(bus_->HasDBusThread());
// Create new object proxy.
object_proxy_ = bus_->GetObjectProxy(
test_service_->service_name(),
ObjectPath("/org/chromium/TestObject"));
}
// Calls the method asynchronously. OnResponse() will be called once the
// response is received.
void CallMethod(MethodCall* method_call,
int timeout_ms) {
object_proxy_->CallMethod(
method_call, timeout_ms,
base::BindOnce(&EndToEndAsyncTest::OnResponse, base::Unretained(this)));
}
// Calls the method asynchronously. OnResponse() will be called once the
// response is received without error, otherwise OnError() will be called.
void CallMethodWithErrorCallback(MethodCall* method_call,
int timeout_ms) {
object_proxy_->CallMethodWithErrorCallback(
method_call, timeout_ms,
base::BindOnce(&EndToEndAsyncTest::OnResponse, base::Unretained(this)),
base::BindOnce(&EndToEndAsyncTest::OnError, base::Unretained(this)));
}
// Wait for the give number of responses.
void WaitForResponses(size_t num_responses) {
while (response_strings_.size() < num_responses) {
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
}
// Called when the response is received.
void OnResponse(Response* response) {
// |response| will be deleted on exit of the function. Copy the
// payload to |response_strings_|.
if (response) {
MessageReader reader(response);
std::string response_string;
ASSERT_TRUE(reader.PopString(&response_string));
response_strings_.push_back(response_string);
} else {
response_strings_.push_back(std::string());
}
run_loop_->Quit();
}
// Wait for the given number of errors.
void WaitForErrors(size_t num_errors) {
while (error_names_.size() < num_errors) {
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
}
// Called when an error is received.
void OnError(ErrorResponse* error) {
// |error| will be deleted on exit of the function. Copy the payload to
// |error_names_|.
if (error) {
ASSERT_NE("", error->GetErrorName());
error_names_.push_back(error->GetErrorName());
} else {
error_names_.push_back(std::string());
}
run_loop_->Quit();
}
// Called when the "Test" signal is received, in the main thread.
// Copy the string payload to |test_signal_string_|.
void OnTestSignal(Signal* signal) {
MessageReader reader(signal);
ASSERT_TRUE(reader.PopString(&test_signal_string_));
run_loop_->Quit();
}
// Called when the "Test" signal is received, in the main thread, by
// the root object proxy. Copy the string payload to
// |root_test_signal_string_|.
void OnRootTestSignal(Signal* signal) {
MessageReader reader(signal);
ASSERT_TRUE(reader.PopString(&root_test_signal_string_));
run_loop_->Quit();
}
// Called when the "Test2" signal is received, in the main thread.
void OnTest2Signal(Signal* signal) {
MessageReader reader(signal);
run_loop_->Quit();
}
// Called when connected to the signal.
void OnConnected(const std::string& interface_name,
const std::string& signal_name,
bool success) {
ASSERT_TRUE(success);
run_loop_->Quit();
}
// Wait for the hey signal to be received.
void WaitForTestSignal() {
// OnTestSignal() will quit the message loop.
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
base::test::SingleThreadTaskEnvironment task_environment_;
std::unique_ptr<base::RunLoop> run_loop_;
std::vector<std::string> response_strings_;
std::vector<std::string> error_names_;
std::unique_ptr<base::Thread> dbus_thread_;
scoped_refptr<Bus> bus_;
ObjectProxy* object_proxy_;
ObjectProxy* root_object_proxy_;
std::unique_ptr<TestService> test_service_;
// Text message from "Test" signal.
std::string test_signal_string_;
// Text message from "Test" signal delivered to root.
std::string root_test_signal_string_;
};
TEST_F(EndToEndAsyncTest, Echo) {
const char* kHello = "hello";
// Create the method call.
MethodCall method_call("org.chromium.TestInterface", "Echo");
MessageWriter writer(&method_call);
writer.AppendString(kHello);
// Call the method.
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethod(&method_call, timeout_ms);
// Check the response.
WaitForResponses(1);
EXPECT_EQ(kHello, response_strings_[0]);
}
TEST_F(EndToEndAsyncTest, EchoWithErrorCallback) {
const char* kHello = "hello";
// Create the method call.
MethodCall method_call("org.chromium.TestInterface", "Echo");
MessageWriter writer(&method_call);
writer.AppendString(kHello);
// Call the method.
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethodWithErrorCallback(&method_call, timeout_ms);
// Check the response.
WaitForResponses(1);
EXPECT_EQ(kHello, response_strings_[0]);
EXPECT_TRUE(error_names_.empty());
}
// Call Echo method three times.
TEST_F(EndToEndAsyncTest, EchoThreeTimes) {
const char* kMessages[] = { "foo", "bar", "baz" };
for (size_t i = 0; i < base::size(kMessages); ++i) {
// Create the method call.
MethodCall method_call("org.chromium.TestInterface", "Echo");
MessageWriter writer(&method_call);
writer.AppendString(kMessages[i]);
// Call the method.
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethod(&method_call, timeout_ms);
}
// Check the responses.
WaitForResponses(3);
// Sort as the order of the returned messages is not deterministic.
std::sort(response_strings_.begin(), response_strings_.end());
EXPECT_EQ("bar", response_strings_[0]);
EXPECT_EQ("baz", response_strings_[1]);
EXPECT_EQ("foo", response_strings_[2]);
}
TEST_F(EndToEndAsyncTest, Echo_HugePayload) {
const std::string kHugePayload(kHugePayloadSize, 'o');
// Create the method call with a huge payload.
MethodCall method_call("org.chromium.TestInterface", "Echo");
MessageWriter writer(&method_call);
writer.AppendString(kHugePayload);
// Call the method.
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethod(&method_call, timeout_ms);
// This caused a DCHECK failure before. Ensure that the issue is fixed.
WaitForResponses(1);
EXPECT_EQ(kHugePayload, response_strings_[0]);
}
TEST_F(EndToEndAsyncTest, BrokenBus) {
const char* kHello = "hello";
// Set up a broken bus.
SetUpBrokenBus();
// Create the method call.
MethodCall method_call("org.chromium.TestInterface", "Echo");
MessageWriter writer(&method_call);
writer.AppendString(kHello);
// Call the method.
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethod(&method_call, timeout_ms);
WaitForResponses(1);
// Should fail because of the broken bus.
ASSERT_EQ("", response_strings_[0]);
}
TEST_F(EndToEndAsyncTest, BrokenBusWithErrorCallback) {
const char* kHello = "hello";
// Set up a broken bus.
SetUpBrokenBus();
// Create the method call.
MethodCall method_call("org.chromium.TestInterface", "Echo");
MessageWriter writer(&method_call);
writer.AppendString(kHello);
// Call the method.
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethodWithErrorCallback(&method_call, timeout_ms);
WaitForErrors(1);
// Should fail because of the broken bus.
ASSERT_TRUE(response_strings_.empty());
ASSERT_EQ("", error_names_[0]);
}
TEST_F(EndToEndAsyncTest, Timeout) {
const char* kHello = "hello";
// Create the method call.
MethodCall method_call("org.chromium.TestInterface", "SlowEcho");
MessageWriter writer(&method_call);
writer.AppendString(kHello);
// Call the method with timeout of 0ms.
const int timeout_ms = 0;
CallMethod(&method_call, timeout_ms);
WaitForResponses(1);
// Should fail because of timeout.
ASSERT_EQ("", response_strings_[0]);
}
TEST_F(EndToEndAsyncTest, TimeoutWithErrorCallback) {
const char* kHello = "hello";
// Create the method call.
MethodCall method_call("org.chromium.TestInterface", "SlowEcho");
MessageWriter writer(&method_call);
writer.AppendString(kHello);
// Call the method with timeout of 0ms.
const int timeout_ms = 0;
CallMethodWithErrorCallback(&method_call, timeout_ms);
WaitForErrors(1);
// Should fail because of timeout.
ASSERT_TRUE(response_strings_.empty());
ASSERT_EQ(DBUS_ERROR_NO_REPLY, error_names_[0]);
}
TEST_F(EndToEndAsyncTest, CancelPendingCalls) {
const char* kHello = "hello";
// Create the method call.
MethodCall method_call("org.chromium.TestInterface", "Echo");
MessageWriter writer(&method_call);
writer.AppendString(kHello);
// Call the method.
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethod(&method_call, timeout_ms);
// Remove the object proxy before receiving the result.
// This results in cancelling the pending method call.
bus_->RemoveObjectProxy(test_service_->service_name(),
ObjectPath("/org/chromium/TestObject"),
base::DoNothing());
// We shouldn't receive any responses. Wait for a while just to make sure.
run_loop_ = std::make_unique<base::RunLoop>();
task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
FROM_HERE, run_loop_->QuitClosure(), TestTimeouts::tiny_timeout());
run_loop_->Run();
EXPECT_TRUE(response_strings_.empty());
}
// Tests calling a method that sends its reply asynchronously.
TEST_F(EndToEndAsyncTest, AsyncEcho) {
const char* kHello = "hello";
// Create the method call.
MethodCall method_call("org.chromium.TestInterface", "AsyncEcho");
MessageWriter writer(&method_call);
writer.AppendString(kHello);
// Call the method.
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethod(&method_call, timeout_ms);
// Check the response.
WaitForResponses(1);
EXPECT_EQ(kHello, response_strings_[0]);
}
TEST_F(EndToEndAsyncTest, NonexistentMethod) {
MethodCall method_call("org.chromium.TestInterface", "Nonexistent");
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethod(&method_call, timeout_ms);
WaitForResponses(1);
// Should fail because the method is nonexistent.
ASSERT_EQ("", response_strings_[0]);
}
TEST_F(EndToEndAsyncTest, NonexistentMethodWithErrorCallback) {
MethodCall method_call("org.chromium.TestInterface", "Nonexistent");
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethodWithErrorCallback(&method_call, timeout_ms);
WaitForErrors(1);
// Should fail because the method is nonexistent.
ASSERT_TRUE(response_strings_.empty());
ASSERT_EQ(DBUS_ERROR_UNKNOWN_METHOD, error_names_[0]);
}
TEST_F(EndToEndAsyncTest, BrokenMethod) {
MethodCall method_call("org.chromium.TestInterface", "BrokenMethod");
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethod(&method_call, timeout_ms);
WaitForResponses(1);
// Should fail because the method is broken.
ASSERT_EQ("", response_strings_[0]);
}
TEST_F(EndToEndAsyncTest, BrokenMethodWithErrorCallback) {
MethodCall method_call("org.chromium.TestInterface", "BrokenMethod");
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethodWithErrorCallback(&method_call, timeout_ms);
WaitForErrors(1);
// Should fail because the method is broken.
ASSERT_TRUE(response_strings_.empty());
ASSERT_EQ(DBUS_ERROR_FAILED, error_names_[0]);
}
TEST_F(EndToEndAsyncTest, InvalidServiceName) {
// Bus name cannot contain '/'.
const std::string invalid_service_name = ":1/2";
// Replace object proxy with new one.
object_proxy_ = bus_->GetObjectProxy(invalid_service_name,
ObjectPath("/org/chromium/TestObject"));
MethodCall method_call("org.chromium.TestInterface", "Echo");
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
CallMethodWithErrorCallback(&method_call, timeout_ms);
WaitForErrors(1);
// Should fail because of the invalid bus name.
ASSERT_TRUE(response_strings_.empty());
ASSERT_EQ("", error_names_[0]);
}
TEST_F(EndToEndAsyncTest, EmptyResponseCallback) {
const char* kHello = "hello";
// Create the method call.
MethodCall method_call("org.chromium.TestInterface", "Echo");
MessageWriter writer(&method_call);
writer.AppendString(kHello);
// Call the method with an empty callback.
const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
object_proxy_->CallMethod(&method_call, timeout_ms, base::DoNothing());
// Post a delayed task to quit the RunLoop.
run_loop_ = std::make_unique<base::RunLoop>();
task_environment_.GetMainThreadTaskRunner()->PostDelayedTask(
FROM_HERE, run_loop_->QuitClosure(), TestTimeouts::tiny_timeout());
run_loop_->Run();
// We cannot tell if the empty callback is called, but at least we can
// check if the test does not crash.
}
TEST_F(EndToEndAsyncTest, TestSignal) {
const char kMessage[] = "hello, world";
// Send the test signal from the exported object.
test_service_->SendTestSignal(kMessage);
// Receive the signal with the object proxy. The signal is handled in
// EndToEndAsyncTest::OnTestSignal() in the main thread.
WaitForTestSignal();
ASSERT_EQ(kMessage, test_signal_string_);
}
TEST_F(EndToEndAsyncTest, TestSignalFromRoot) {
const char kMessage[] = "hello, world";
// Object proxies are tied to a particular object path, if a signal
// arrives from a different object path like "/" the first object proxy
// |object_proxy_| should not handle it, and should leave it for the root
// object proxy |root_object_proxy_|.
test_service_->SendTestSignalFromRoot(kMessage);
WaitForTestSignal();
// Verify the signal was not received by the specific proxy.
ASSERT_TRUE(test_signal_string_.empty());
// Verify the string WAS received by the root proxy.
ASSERT_EQ(kMessage, root_test_signal_string_);
}
TEST_F(EndToEndAsyncTest, TestHugeSignal) {
const std::string kHugeMessage(kHugePayloadSize, 'o');
// Send the huge signal from the exported object.
test_service_->SendTestSignal(kHugeMessage);
// This caused a DCHECK failure before. Ensure that the issue is fixed.
WaitForTestSignal();
ASSERT_EQ(kHugeMessage, test_signal_string_);
}
class SignalMultipleHandlerTest : public EndToEndAsyncTest {
public:
SignalMultipleHandlerTest() = default;
void SetUp() override {
// Set up base class.
EndToEndAsyncTest::SetUp();
// Connect the root object proxy's signal handler to a new handler
// so that we can verify that a second call to ConnectSignal() delivers
// to both our new handler and the old.
object_proxy_->ConnectToSignal(
"org.chromium.TestInterface", "Test",
base::BindRepeating(&SignalMultipleHandlerTest::OnAdditionalTestSignal,
base::Unretained(this)),
base::BindOnce(&SignalMultipleHandlerTest::OnAdditionalConnected,
base::Unretained(this)));
// Wait until the object proxy is connected to the signal.
run_loop_ = std::make_unique<base::RunLoop>();
run_loop_->Run();
}
protected:
// Called when the "Test" signal is received, in the main thread.
// Copy the string payload to |additional_test_signal_string_|.
void OnAdditionalTestSignal(Signal* signal) {
MessageReader reader(signal);
ASSERT_TRUE(reader.PopString(&additional_test_signal_string_));
run_loop_->Quit();
}
// Called when connected to the signal.
void OnAdditionalConnected(const std::string& interface_name,
const std::string& signal_name,
bool success) {
ASSERT_TRUE(success);
run_loop_->Quit();
}
// Text message from "Test" signal delivered to additional handler.
std::string additional_test_signal_string_;
};
TEST_F(SignalMultipleHandlerTest, TestMultipleHandlers) {
const char kMessage[] = "hello, world";
// Send the test signal from the exported object.
test_service_->SendTestSignal(kMessage);
// Receive the signal with the object proxy.
WaitForTestSignal();
// Verify the string WAS received by the original handler.
ASSERT_EQ(kMessage, test_signal_string_);
// Verify the signal WAS ALSO received by the additional handler.
ASSERT_EQ(kMessage, additional_test_signal_string_);
}
} // namespace dbus
正念是什么 梦见老鼠是什么意思 私奔是什么意思 芊芊学子什么意思 神经元是什么
乳房突然疼痛什么原因 日加华念什么 六月二十九日是什么星座 嬛嬛一袅楚宫腰什么意思 知己什么意思
作息时间是什么意思 减肥期间可以吃什么水果 9月三号是什么日子 什么是抗凝药物 乙酰氨基酚片是什么药
60岁男人喜欢什么样的女人 孕妇吃什么水果比较好 花枝招展什么意思 鼻炎不能吃什么食物 2003是什么年
肝病吃什么药hcv8jop3ns8r.cn 什么是会车hcv8jop6ns9r.cn 流水席是什么意思hcv8jop0ns3r.cn 小猫咪吃什么hcv8jop6ns3r.cn 蛇脱皮在家有什么预兆imcecn.com
寿眉属于什么茶hcv8jop3ns8r.cn 鹅吃什么草520myf.com 三国是什么朝代imcecn.com 什么是引流hcv8jop1ns9r.cn s和m什么意思sanhestory.com
穿山甲用什么中药代替hcv9jop1ns2r.cn mrd是什么意思hcv9jop2ns8r.cn 下面痛是什么原因hcv8jop1ns7r.cn 子宫内膜不均匀是什么意思hcv7jop9ns3r.cn 烽烟是什么意思hcv8jop2ns0r.cn
头一直摇晃是什么病hcv9jop8ns1r.cn 金的部首是什么gysmod.com 家里来狗是什么征兆hcv8jop4ns9r.cn 啰嗦是什么意思hcv9jop4ns1r.cn rad是什么单位hcv8jop2ns4r.cn
百度