blob: 7bb1ab9b2c8a958ebbcf52076d126d25dae04b14 [file] [log] [blame]
Paul Stewart1dce1ae2014-10-01 05:30:18 -07001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chromeos-dbus-bindings/proxy_generator.h"
6
7#include <string>
8#include <vector>
9
10#include <base/file_util.h>
11#include <base/files/file_path.h>
12#include <base/files/scoped_temp_dir.h>
13#include <gtest/gtest.h>
14
15#include "chromeos-dbus-bindings/interface.h"
16
17using std::string;
18using std::vector;
19using testing::Test;
20
21namespace chromeos_dbus_bindings {
22
23namespace {
24
25const char kInterfaceName[] = "org.chromium.TestInterface";
Alex Vakulenkofafef132014-11-03 14:52:09 -080026const char kInterfaceName2[] = "org.chromium.TestInterface2";
Paul Stewart1dce1ae2014-10-01 05:30:18 -070027const char kMethod1Name[] = "Elements";
28const char kMethod1Return[] = "s";
29const char kMethod1Argument1[] = "s";
30const char kMethod1ArgumentName1[] = "space_walk";
31const char kMethod1Argument2[] = "ao";
32const char kMethod1ArgumentName2[] = "ramblin_man";
33const char kMethod2Name[] = "ReturnToPatagonia";
34const char kMethod2Return[] = "x";
35const char kMethod3Name[] = "NiceWeatherForDucks";
36const char kMethod3Argument1[] = "b";
37const char kMethod4Name[] = "ExperimentNumberSix";
Alex Vakulenkofafef132014-11-03 14:52:09 -080038const char kMethod5Name[] = "GetPersonInfo";
39const char kMethod5Argument1[] = "s";
40const char kMethod5ArgumentName1[] = "name";
41const char kMethod5Argument2[] = "i";
42const char kMethod5ArgumentName2[] = "age";
Paul Stewart1dce1ae2014-10-01 05:30:18 -070043const char kSignal1Name[] = "Closer";
44const char kSignal2Name[] = "TheCurseOfKaZar";
45const char kSignal2Argument1[] = "as";
46const char kSignal2Argument2[] = "y";
47const char kExpectedContent[] = R"literal_string(
48#include <string>
49#include <vector>
50
51#include <base/bind.h>
52#include <base/callback.h>
53#include <base/logging.h>
54#include <base/macros.h>
55#include <base/memory/ref_counted.h>
56#include <chromeos/any.h>
57#include <chromeos/dbus/dbus_method_invoker.h>
58#include <chromeos/dbus/dbus_signal_handler.h>
59#include <chromeos/errors/error.h>
60#include <dbus/bus.h>
61#include <dbus/message.h>
62#include <dbus/object_path.h>
63#include <dbus/object_proxy.h>
64
65namespace org {
66namespace chromium {
67
68class TestInterfaceProxy {
69 public:
70 class SignalReceiver {
71 public:
72 virtual void OnCloserSignal() {}
73 virtual void OnTheCurseOfKaZarSignal(
74 const std::vector<std::string>&,
75 uint8_t) {}
76 };
77 TestInterfaceProxy(
78 const scoped_refptr<dbus::Bus>& bus,
79 const std::string& service_name,
80 const std::string& object_path,
81 SignalReceiver* signal_receiver)
82 : bus_(bus),
83 service_name_(service_name),
84 object_path_(object_path),
85 dbus_object_proxy_(
86 bus_->GetObjectProxy(service_name_, object_path_)) {
87 chromeos::dbus_utils::ConnectToSignal(
88 dbus_object_proxy_,
89 "org.chromium.TestInterface",
90 "Closer",
91 base::Bind(
92 &SignalReceiver::OnCloserSignal,
93 base::Unretained(signal_receiver)),
94 base::Bind(
95 &TestInterfaceProxy::OnDBusSignalConnected,
96 base::Unretained(this)));
97 chromeos::dbus_utils::ConnectToSignal(
98 dbus_object_proxy_,
99 "org.chromium.TestInterface",
100 "TheCurseOfKaZar",
101 base::Bind(
102 &SignalReceiver::OnTheCurseOfKaZarSignal,
103 base::Unretained(signal_receiver)),
104 base::Bind(
105 &TestInterfaceProxy::OnDBusSignalConnected,
106 base::Unretained(this)));
107 }
108 virtual ~TestInterfaceProxy() {
109 dbus_object_proxy_->Detach();
110 bus_->RemoveObjectProxy(service_name_, object_path_, base::Closure());
111 }
112 void OnDBusSignalConnected(
113 const std::string& interface,
114 const std::string& signal,
115 bool success) {
116 if (!success) {
117 LOG(ERROR)
118 << "Failed to connect to " << interface << "." << signal
119 << " for " << service_name_ << " at "
120 << object_path_.value();
121 }
122 }
Alex Vakulenkofafef132014-11-03 14:52:09 -0800123 virtual bool Elements(
124 const std::string& in_space_walk,
125 const std::vector<dbus::ObjectPath>& in_ramblin_man,
126 std::string* out_3,
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700127 chromeos::ErrorPtr* error) {
128 auto response = chromeos::dbus_utils::CallMethodAndBlock(
129 dbus_object_proxy_,
130 "org.chromium.TestInterface",
131 "Elements",
132 error,
Alex Vakulenkofafef132014-11-03 14:52:09 -0800133 in_space_walk,
134 in_ramblin_man);
135 return response && chromeos::dbus_utils::ExtractMethodCallResults(
136 response.get(), error, out_3);
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700137 }
Alex Vakulenkofafef132014-11-03 14:52:09 -0800138 virtual bool ReturnToPatagonia(
139 int64_t* out_1,
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700140 chromeos::ErrorPtr* error) {
141 auto response = chromeos::dbus_utils::CallMethodAndBlock(
142 dbus_object_proxy_,
143 "org.chromium.TestInterface",
144 "ReturnToPatagonia",
145 error);
Alex Vakulenkofafef132014-11-03 14:52:09 -0800146 return response && chromeos::dbus_utils::ExtractMethodCallResults(
147 response.get(), error, out_1);
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700148 }
Alex Vakulenkofafef132014-11-03 14:52:09 -0800149 virtual bool NiceWeatherForDucks(
150 bool in_1,
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700151 chromeos::ErrorPtr* error) {
152 auto response = chromeos::dbus_utils::CallMethodAndBlock(
153 dbus_object_proxy_,
154 "org.chromium.TestInterface",
155 "NiceWeatherForDucks",
156 error,
Alex Vakulenkofafef132014-11-03 14:52:09 -0800157 in_1);
158 return response && chromeos::dbus_utils::ExtractMethodCallResults(
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700159 response.get(), error);
160 }
Alex Vakulenkofafef132014-11-03 14:52:09 -0800161 virtual bool ExperimentNumberSix(
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700162 chromeos::ErrorPtr* error) {
163 auto response = chromeos::dbus_utils::CallMethodAndBlock(
164 dbus_object_proxy_,
165 "org.chromium.TestInterface",
166 "ExperimentNumberSix",
167 error);
Alex Vakulenkofafef132014-11-03 14:52:09 -0800168 return response && chromeos::dbus_utils::ExtractMethodCallResults(
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700169 response.get(), error);
170 }
Alex Vakulenkofafef132014-11-03 14:52:09 -0800171 virtual bool GetPersonInfo(
172 std::string* out_name,
173 int32_t* out_age,
174 chromeos::ErrorPtr* error) {
175 auto response = chromeos::dbus_utils::CallMethodAndBlock(
176 dbus_object_proxy_,
177 "org.chromium.TestInterface2",
178 "GetPersonInfo",
179 error);
180 return response && chromeos::dbus_utils::ExtractMethodCallResults(
181 response.get(), error, out_name, out_age);
182 }
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700183
184 private:
185 scoped_refptr<dbus::Bus> bus_;
186 std::string service_name_;
187 dbus::ObjectPath object_path_;
188 dbus::ObjectProxy* dbus_object_proxy_;
189
190 DISALLOW_COPY_AND_ASSIGN(TestInterfaceProxy);
191};
192
193} // namespace chromium
194} // namespace org
195)literal_string";
196
197} // namespace
198
199class ProxyGeneratorTest : public Test {
200 public:
201 void SetUp() override {
202 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
203 }
204
205 protected:
206 base::FilePath CreateInputFile(const string& contents) {
207 base::FilePath path;
208 EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &path));
209 EXPECT_EQ(contents.size(),
210 base::WriteFile(path, contents.c_str(), contents.size()));
211 return path;
212 }
213
214 base::ScopedTempDir temp_dir_;
215};
216
217TEST_F(ProxyGeneratorTest, GenerateAdaptors) {
218 Interface interface;
219 interface.name = kInterfaceName;
220 interface.methods.emplace_back(
221 kMethod1Name,
222 vector<Interface::Argument>{
223 {kMethod1ArgumentName1, kMethod1Argument1},
224 {kMethod1ArgumentName2, kMethod1Argument2}},
225 vector<Interface::Argument>{{"", kMethod1Return}});
226 interface.methods.emplace_back(
227 kMethod2Name,
228 vector<Interface::Argument>{},
229 vector<Interface::Argument>{{"", kMethod2Return}});
230 interface.methods.emplace_back(
231 kMethod3Name,
232 vector<Interface::Argument>{{"", kMethod3Argument1}},
233 vector<Interface::Argument>{});
234 interface.methods.emplace_back(kMethod4Name);
235 interface.signals.emplace_back(kSignal1Name);
236 interface.signals.emplace_back(
237 kSignal2Name,
238 vector<Interface::Argument>{
239 {"", kSignal2Argument1},
240 {"", kSignal2Argument2}});
Alex Vakulenkofafef132014-11-03 14:52:09 -0800241 Interface interface2;
242 interface2.name = kInterfaceName2;
243 interface2.methods.emplace_back(
244 kMethod5Name,
245 vector<Interface::Argument>{},
246 vector<Interface::Argument>{
247 {kMethod5ArgumentName1, kMethod5Argument1},
248 {kMethod5ArgumentName2, kMethod5Argument2}});
249 vector<Interface> interfaces{interface, interface2};
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700250 base::FilePath output_path = temp_dir_.path().Append("output.h");
Alex Vakulenkofafef132014-11-03 14:52:09 -0800251 EXPECT_TRUE(ProxyGenerator::GenerateProxy(interfaces, output_path));
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700252 string contents;
253 EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
254 // The header guards contain the (temporary) filename, so we search for
255 // the content we need within the string.
256 EXPECT_NE(string::npos, contents.find(kExpectedContent))
257 << "Expected to find the following content...\n"
258 << kExpectedContent << "...within content...\n" << contents;
259}
260
261} // namespace chromeos_dbus_bindings