ruby-dbus 0.18.1 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/NEWS.md +17 -0
- data/VERSION +1 -1
- data/lib/dbus/bus.rb +57 -15
- data/lib/dbus/introspect.rb +2 -1
- data/lib/dbus/marshall.rb +1 -1
- data/lib/dbus/object.rb +31 -3
- data/lib/dbus/object_manager.rb +58 -0
- data/lib/dbus.rb +1 -0
- data/spec/node_spec.rb +46 -0
- data/spec/object_manager_spec.rb +33 -0
- data/spec/object_spec.rb +10 -0
- data/spec/server_robustness_spec.rb +18 -6
- data/spec/service_newapi.rb +28 -0
- data/spec/service_spec.rb +18 -0
- data/spec/tools/dbus-limited-session.conf +1 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7261c5ad0fb4e067da97b31298e6a79023e54743f69563b22c9a751101df2f85
|
4
|
+
data.tar.gz: 38075d862b0407889bf0a0e25eff450d18c8e225012a028545700fc1be15c342
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 700dc07af8d28f7a7537be292dd6313268032f169102c3581d2f5c7a13ba8b9b7c864b23d3b8bdb66e3760a147a7edf7d835098f450625ffade7f748e101f987
|
7
|
+
data.tar.gz: 2637cb7cad666a415c6e4a83a158b116507e5d6db3e70a53f5384d1a9240f191e6e2b540950076ae76397b7581c891e71b9f59e84346647394fe0bd7833e49c1
|
data/NEWS.md
CHANGED
@@ -2,6 +2,23 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## Ruby D-Bus 0.19.0 - 2023-01-18
|
6
|
+
|
7
|
+
API:
|
8
|
+
* Added a ObjectManager mix-in to implement the service-side
|
9
|
+
[ObjectManager][objmgr] interface.
|
10
|
+
|
11
|
+
Bug fixes:
|
12
|
+
* dbus_attr_accessor and friends validate the signature ([#120][]).
|
13
|
+
* Declare the Introspectable interface in exported objects([#99][]).
|
14
|
+
* Do reply with an error when calling a nonexisting object
|
15
|
+
with an existing path prefix([#121][]).
|
16
|
+
|
17
|
+
[#120]: https://github.com/mvidner/ruby-dbus/issues/120
|
18
|
+
[#99]: https://github.com/mvidner/ruby-dbus/issues/99
|
19
|
+
[#121]: https://github.com/mvidner/ruby-dbus/issues/121
|
20
|
+
[objmgr]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager
|
21
|
+
|
5
22
|
## Ruby D-Bus 0.18.1 - 2022-07-13
|
6
23
|
|
7
24
|
No changes since 0.18.0.beta8.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.19.0
|
data/lib/dbus/bus.rb
CHANGED
@@ -76,6 +76,7 @@ module DBus
|
|
76
76
|
def export(obj)
|
77
77
|
obj.service = self
|
78
78
|
get_node(obj.path, create: true).object = obj
|
79
|
+
object_manager_for(obj)&.object_added(obj)
|
79
80
|
end
|
80
81
|
|
81
82
|
# Undo exporting an object _obj_.
|
@@ -93,6 +94,7 @@ module DBus
|
|
93
94
|
parent_node = get_node(parent_path, create: false)
|
94
95
|
return false unless parent_node
|
95
96
|
|
97
|
+
object_manager_for(obj)&.object_removed(obj)
|
96
98
|
obj.service = nil
|
97
99
|
parent_node.delete(node_name).object
|
98
100
|
end
|
@@ -112,18 +114,51 @@ module DBus
|
|
112
114
|
end
|
113
115
|
n = n[elem]
|
114
116
|
end
|
115
|
-
if n.nil?
|
116
|
-
DBus.logger.debug "Warning, unknown object #{path}"
|
117
|
-
end
|
118
117
|
n
|
119
118
|
end
|
120
119
|
|
120
|
+
# Find the (closest) parent of *object*
|
121
|
+
# implementing the ObjectManager interface, or nil
|
122
|
+
# @return [DBus::Object,nil]
|
123
|
+
def object_manager_for(object)
|
124
|
+
path = object.path
|
125
|
+
node_chain = get_node_chain(path)
|
126
|
+
om_node = node_chain.reverse_each.find do |node|
|
127
|
+
node.object&.is_a? DBus::ObjectManager
|
128
|
+
end
|
129
|
+
om_node&.object
|
130
|
+
end
|
131
|
+
|
132
|
+
# All objects (not paths) under this path (except itself).
|
133
|
+
# @param path [ObjectPath]
|
134
|
+
# @return [Array<DBus::Object>]
|
135
|
+
# @raise ArgumentError if the *path* does not exist
|
136
|
+
def descendants_for(path)
|
137
|
+
node = get_node(path, create: false)
|
138
|
+
raise ArgumentError, "Object path #{path} doesn't exist" if node.nil?
|
139
|
+
|
140
|
+
node.descendant_objects
|
141
|
+
end
|
142
|
+
|
121
143
|
#########
|
122
144
|
|
123
145
|
private
|
124
146
|
|
125
147
|
#########
|
126
148
|
|
149
|
+
# @raise ArgumentError if the *path* does not exist
|
150
|
+
def get_node_chain(path)
|
151
|
+
n = @root
|
152
|
+
result = [n]
|
153
|
+
path.sub(%r{^/}, "").split("/").each do |elem|
|
154
|
+
n = n[elem]
|
155
|
+
raise ArgumentError, "Object path #{path} doesn't exist" if n.nil?
|
156
|
+
|
157
|
+
result.push(n)
|
158
|
+
end
|
159
|
+
result
|
160
|
+
end
|
161
|
+
|
127
162
|
# Perform a recursive retrospection on the given current _node_
|
128
163
|
# on the given _path_.
|
129
164
|
def rec_introspect(node, path)
|
@@ -198,6 +233,15 @@ module DBus
|
|
198
233
|
.join(",")
|
199
234
|
"#{s}{#{contents_sub_inspect}}"
|
200
235
|
end
|
236
|
+
|
237
|
+
# All objects (not paths) under this path (except itself).
|
238
|
+
# @return [Array<DBus::Object>]
|
239
|
+
def descendant_objects
|
240
|
+
children_objects = values.map(&:object).compact
|
241
|
+
descendants = values.map(&:descendant_objects)
|
242
|
+
flat_descendants = descendants.reduce([], &:+)
|
243
|
+
children_objects + flat_descendants
|
244
|
+
end
|
201
245
|
end
|
202
246
|
|
203
247
|
# FIXME: rename Connection to Bus?
|
@@ -233,7 +277,6 @@ module DBus
|
|
233
277
|
@method_call_msgs = {}
|
234
278
|
@signal_matchrules = {}
|
235
279
|
@proxy = nil
|
236
|
-
@object_root = Node.new("/")
|
237
280
|
end
|
238
281
|
|
239
282
|
# Dispatch all messages that are available in the queue,
|
@@ -561,23 +604,22 @@ module DBus
|
|
561
604
|
DBus.logger.debug "Got method call on /org/freedesktop/DBus"
|
562
605
|
end
|
563
606
|
node = @service.get_node(msg.path, create: false)
|
564
|
-
if
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
# handle introspectable as an exception:
|
569
|
-
elsif msg.interface == "org.freedesktop.DBus.Introspectable" &&
|
570
|
-
msg.member == "Introspect"
|
607
|
+
# introspect a known path even if there is no object on it
|
608
|
+
if node &&
|
609
|
+
msg.interface == "org.freedesktop.DBus.Introspectable" &&
|
610
|
+
msg.member == "Introspect"
|
571
611
|
reply = Message.new(Message::METHOD_RETURN).reply_to(msg)
|
572
612
|
reply.sender = @unique_name
|
573
613
|
xml = node.to_xml(msg.path)
|
574
614
|
reply.add_param(Type::STRING, xml)
|
575
615
|
@message_queue.push(reply)
|
616
|
+
# dispatch for an object
|
617
|
+
elsif node&.object
|
618
|
+
node.object.dispatch(msg)
|
576
619
|
else
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
obj&.dispatch(msg)
|
620
|
+
reply = Message.error(msg, "org.freedesktop.DBus.Error.UnknownObject",
|
621
|
+
"Object #{msg.path} doesn't exist")
|
622
|
+
@message_queue.push(reply)
|
581
623
|
end
|
582
624
|
when DBus::Message::SIGNAL
|
583
625
|
# the signal can match multiple different rules
|
data/lib/dbus/introspect.rb
CHANGED
@@ -270,7 +270,7 @@ module DBus
|
|
270
270
|
class Property
|
271
271
|
# @return [Symbol] The name of the property, for example FooBar.
|
272
272
|
attr_reader :name
|
273
|
-
# @return [
|
273
|
+
# @return [Type]
|
274
274
|
attr_reader :type
|
275
275
|
# @return [Symbol] :read :write or :readwrite
|
276
276
|
attr_reader :access
|
@@ -282,6 +282,7 @@ module DBus
|
|
282
282
|
|
283
283
|
def initialize(name, type, access, ruby_name:)
|
284
284
|
@name = name.to_sym
|
285
|
+
type = DBus.type(type) unless type.is_a?(Type)
|
285
286
|
@type = type
|
286
287
|
@access = access
|
287
288
|
@ruby_name = ruby_name
|
data/lib/dbus/marshall.rb
CHANGED
@@ -327,7 +327,7 @@ module DBus
|
|
327
327
|
# Damn ruby rocks here
|
328
328
|
val = val.to_a
|
329
329
|
end
|
330
|
-
# If string is
|
330
|
+
# If string is received and ay is expected, explode the string
|
331
331
|
if val.is_a?(String) && child_type.sigtype == Type::BYTE
|
332
332
|
val = val.bytes
|
333
333
|
end
|
data/lib/dbus/object.rb
CHANGED
@@ -89,8 +89,11 @@ module DBus
|
|
89
89
|
# while the superclass keeps the old one.
|
90
90
|
self.intfs = intfs.merge(name => @@cur_intf)
|
91
91
|
end
|
92
|
-
|
93
|
-
|
92
|
+
begin
|
93
|
+
yield
|
94
|
+
ensure
|
95
|
+
@@cur_intf = nil
|
96
|
+
end
|
94
97
|
end
|
95
98
|
end
|
96
99
|
|
@@ -122,7 +125,8 @@ module DBus
|
|
122
125
|
#
|
123
126
|
# @param ruby_name [Symbol] :foo_bar is exposed as FooBar;
|
124
127
|
# use dbus_name to override
|
125
|
-
# @param type
|
128
|
+
# @param type [Type,SingleCompleteType]
|
129
|
+
# a signature like "s" or "a(uus)" or Type::STRING
|
126
130
|
# @param dbus_name [String] if not given it is made
|
127
131
|
# by CamelCasing the ruby_name. foo_bar becomes FooBar
|
128
132
|
# to convert the Ruby convention to the DBus convention.
|
@@ -387,6 +391,23 @@ module DBus
|
|
387
391
|
property
|
388
392
|
end
|
389
393
|
|
394
|
+
# Generates information about interfaces and properties of the object
|
395
|
+
#
|
396
|
+
# Returns a hash containing interfaces names as keys. Each value is the
|
397
|
+
# same hash that would be returned by the
|
398
|
+
# org.freedesktop.DBus.Properties.GetAll() method for that combination of
|
399
|
+
# object path and interface. If an interface has no properties, the empty
|
400
|
+
# hash is returned.
|
401
|
+
#
|
402
|
+
# @return [Hash{String => Hash{String => Data::Base}}] interface -> property -> value
|
403
|
+
def interfaces_and_properties
|
404
|
+
get_all_method = self.class.make_method_name("org.freedesktop.DBus.Properties", :GetAll)
|
405
|
+
|
406
|
+
intfs.keys.each_with_object({}) do |interface, hash|
|
407
|
+
hash[interface] = public_send(get_all_method, interface).first
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
390
411
|
####################################################################
|
391
412
|
|
392
413
|
# use the above defined methods to declare the property-handling
|
@@ -459,5 +480,12 @@ module DBus
|
|
459
480
|
|
460
481
|
dbus_signal :PropertiesChanged, "interface:s, changed_properties:a{sv}, invalidated_properties:as"
|
461
482
|
end
|
483
|
+
|
484
|
+
dbus_interface "org.freedesktop.DBus.Introspectable" do
|
485
|
+
dbus_method :Introspect, "out xml_data:s" do
|
486
|
+
# The body is not used, Connection#process handles it instead
|
487
|
+
# which is more efficient and handles paths without objects.
|
488
|
+
end
|
489
|
+
end
|
462
490
|
end
|
463
491
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is part of the ruby-dbus project
|
4
|
+
# Copyright (C) 2022 José Iván López González
|
5
|
+
# Copyright (C) 2022 Martin Vidner
|
6
|
+
#
|
7
|
+
# This library is free software; you can redistribute it and/or
|
8
|
+
# modify it under the terms of the GNU Lesser General Public
|
9
|
+
# License, version 2.1 as published by the Free Software Foundation.
|
10
|
+
# See the file "COPYING" for the exact licensing terms.
|
11
|
+
|
12
|
+
module DBus
|
13
|
+
# A mixin for {DBus::Object} implementing
|
14
|
+
# {https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager
|
15
|
+
# org.freedesktop.DBus.ObjectManager}.
|
16
|
+
#
|
17
|
+
# {Service#export} and {Service#unexport} will look for an ObjectManager
|
18
|
+
# parent in the path hierarchy. If found, it will emit InterfacesAdded
|
19
|
+
# or InterfacesRemoved, as appropriate.
|
20
|
+
module ObjectManager
|
21
|
+
OBJECT_MANAGER_INTERFACE = "org.freedesktop.DBus.ObjectManager"
|
22
|
+
|
23
|
+
# @return [Hash{ObjectPath => Hash{String => Hash{String => Data::Base}}}]
|
24
|
+
# object -> interface -> property -> value
|
25
|
+
def managed_objects
|
26
|
+
# FIXME: also fix the "service" concept
|
27
|
+
descendant_objects = @service.descendants_for(path)
|
28
|
+
descendant_objects.each_with_object({}) do |obj, hash|
|
29
|
+
hash[obj.path] = obj.interfaces_and_properties
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param object [DBus::Object]
|
34
|
+
# @return [void]
|
35
|
+
def object_added(object)
|
36
|
+
InterfacesAdded(object.path, object.interfaces_and_properties)
|
37
|
+
end
|
38
|
+
|
39
|
+
# @param object [DBus::Object]
|
40
|
+
# @return [void]
|
41
|
+
def object_removed(object)
|
42
|
+
InterfacesRemoved(object.path, object.intfs.keys)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.included(base)
|
46
|
+
base.class_eval do
|
47
|
+
dbus_interface OBJECT_MANAGER_INTERFACE do
|
48
|
+
dbus_method :GetManagedObjects, "out res:a{oa{sa{sv}}}" do
|
49
|
+
[managed_objects]
|
50
|
+
end
|
51
|
+
|
52
|
+
dbus_signal :InterfacesAdded, "object:o, interfaces_and_properties:a{sa{sv}}"
|
53
|
+
dbus_signal :InterfacesRemoved, "object:o, interfaces:as"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/dbus.rb
CHANGED
@@ -24,6 +24,7 @@ require_relative "dbus/matchrule"
|
|
24
24
|
require_relative "dbus/message"
|
25
25
|
require_relative "dbus/message_queue"
|
26
26
|
require_relative "dbus/object"
|
27
|
+
require_relative "dbus/object_manager"
|
27
28
|
require_relative "dbus/object_path"
|
28
29
|
require_relative "dbus/proxy_object"
|
29
30
|
require_relative "dbus/proxy_object_factory"
|
data/spec/node_spec.rb
CHANGED
@@ -20,4 +20,50 @@ describe DBus::Node do
|
|
20
20
|
expect(parent.inspect).to match(/<DBus::Node [0-9a-f]+ {child0 => {},child1 => {},child2 => {}}>/)
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
describe "#descendant_objects" do
|
25
|
+
let(:manager_path) { "/org/example/FooManager" }
|
26
|
+
let(:child_paths) do
|
27
|
+
[
|
28
|
+
# note that "/org/example/FooManager/good"
|
29
|
+
# is a path under a managed object but there is no object there
|
30
|
+
"/org/example/FooManager/good/1",
|
31
|
+
"/org/example/FooManager/good/2",
|
32
|
+
"/org/example/FooManager/good/3",
|
33
|
+
"/org/example/FooManager/bad/1",
|
34
|
+
"/org/example/FooManager/bad/2"
|
35
|
+
]
|
36
|
+
end
|
37
|
+
|
38
|
+
let(:non_child_paths) do
|
39
|
+
[
|
40
|
+
"/org/example/BarManager/good/1",
|
41
|
+
"/org/example/BarManager/good/2"
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
context "on the bus" do
|
46
|
+
let(:bus) { DBus::ASessionBus.new }
|
47
|
+
let(:service) do
|
48
|
+
# if we used org.ruby.service it would be a name collision
|
49
|
+
# ... which would not break the test for lucky reasons
|
50
|
+
bus.request_service("org.ruby.service.scratch")
|
51
|
+
end
|
52
|
+
|
53
|
+
before do
|
54
|
+
service.export(DBus::Object.new(manager_path))
|
55
|
+
non_child_paths.each do |p|
|
56
|
+
service.export(DBus::Object.new(p))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns just the descendants of the specified objects" do
|
61
|
+
child_exported_objects = child_paths.map { |p| DBus::Object.new(p) }
|
62
|
+
child_exported_objects.each { |obj| service.export(obj) }
|
63
|
+
|
64
|
+
node = service.get_node(manager_path, create: false)
|
65
|
+
expect(node.descendant_objects).to eq child_exported_objects
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
23
69
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "spec_helper"
|
5
|
+
require "dbus"
|
6
|
+
|
7
|
+
describe DBus::ObjectManager do
|
8
|
+
describe "GetManagedObjects" do
|
9
|
+
let(:bus) { DBus::ASessionBus.new }
|
10
|
+
let(:service) { bus["org.ruby.service"] }
|
11
|
+
let(:obj) { service["/org/ruby/MyInstance"] }
|
12
|
+
let(:parent_iface) { obj["org.ruby.TestParent"] }
|
13
|
+
let(:om_iface) { obj["org.freedesktop.DBus.ObjectManager"] }
|
14
|
+
|
15
|
+
it "returns the interfaces and properties of currently managed objects" do
|
16
|
+
c1_opath = parent_iface.New("child1")
|
17
|
+
c2_opath = parent_iface.New("child2")
|
18
|
+
|
19
|
+
parent_iface.Delete(c1_opath)
|
20
|
+
expected_gmo = {
|
21
|
+
"/org/ruby/MyInstance/child2" => {
|
22
|
+
"org.freedesktop.DBus.Introspectable" => {},
|
23
|
+
"org.freedesktop.DBus.Properties" => {},
|
24
|
+
"org.ruby.TestChild" => { "Name" => "Child2" }
|
25
|
+
}
|
26
|
+
}
|
27
|
+
expect(om_iface.GetManagedObjects).to eq(expected_gmo)
|
28
|
+
|
29
|
+
parent_iface.Delete(c2_opath)
|
30
|
+
expect(om_iface.GetManagedObjects).to eq({})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/object_spec.rb
CHANGED
@@ -61,6 +61,16 @@ describe DBus::Object do
|
|
61
61
|
end
|
62
62
|
end.to raise_error(DBus::Object::UndefinedInterface)
|
63
63
|
end
|
64
|
+
|
65
|
+
it "fails when the signature is invalid" do
|
66
|
+
expect do
|
67
|
+
ObjectTest.instance_exec do
|
68
|
+
dbus_interface "org.ruby.ServerTest" do
|
69
|
+
dbus_reader :foo2, "!"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end.to raise_error(DBus::Type::SignatureException)
|
73
|
+
end
|
64
74
|
end
|
65
75
|
|
66
76
|
describe ".dbus_reader, when paired with attr_accessor" do
|
@@ -16,7 +16,7 @@ describe "ServerRobustnessTest" do
|
|
16
16
|
it "tests no such path with introspection" do
|
17
17
|
obj = @svc.object "/org/ruby/NotMyInstance"
|
18
18
|
expect { obj.introspect }.to raise_error(DBus::Error) do |e|
|
19
|
-
expect(e).to_not match(/timeout/)
|
19
|
+
expect(e.message).to_not match(/timeout/)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -25,7 +25,19 @@ describe "ServerRobustnessTest" do
|
|
25
25
|
ifc = DBus::ProxyObjectInterface.new(obj, "org.ruby.SampleInterface")
|
26
26
|
ifc.define_method("the_answer", "out n:i")
|
27
27
|
expect { ifc.the_answer }.to raise_error(DBus::Error) do |e|
|
28
|
-
expect(e).to_not match(/timeout/)
|
28
|
+
expect(e.message).to_not match(/timeout/)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "an existing path without an object" do
|
33
|
+
let(:obj) { @svc.object "/org" }
|
34
|
+
|
35
|
+
it "errors without a timeout" do
|
36
|
+
ifc = DBus::ProxyObjectInterface.new(obj, "org.ruby.SampleInterface")
|
37
|
+
ifc.define_method("the_answer", "out n:i")
|
38
|
+
expect { ifc.the_answer }.to raise_error(DBus::Error) do |e|
|
39
|
+
expect(e.message).to_not match(/timeout/)
|
40
|
+
end
|
29
41
|
end
|
30
42
|
end
|
31
43
|
|
@@ -33,7 +45,7 @@ describe "ServerRobustnessTest" do
|
|
33
45
|
obj = @svc.object "/org/ruby/MyInstance"
|
34
46
|
obj.default_iface = "org.ruby.SampleInterface"
|
35
47
|
expect { obj.will_raise }.to raise_error(DBus::Error) do |e|
|
36
|
-
expect(e).to_not match(/timeout/)
|
48
|
+
expect(e.message).to_not match(/timeout/)
|
37
49
|
end
|
38
50
|
end
|
39
51
|
|
@@ -41,7 +53,7 @@ describe "ServerRobustnessTest" do
|
|
41
53
|
obj = @svc.object "/org/ruby/MyInstance"
|
42
54
|
obj.default_iface = "org.ruby.SampleInterface"
|
43
55
|
expect { obj.will_raise_name_error }.to raise_error(DBus::Error) do |e|
|
44
|
-
expect(e).to_not match(/timeout/)
|
56
|
+
expect(e.message).to_not match(/timeout/)
|
45
57
|
end
|
46
58
|
end
|
47
59
|
|
@@ -51,7 +63,7 @@ describe "ServerRobustnessTest" do
|
|
51
63
|
ifc = DBus::ProxyObjectInterface.new(obj, "org.ruby.SampleInterface")
|
52
64
|
ifc.define_method("not_the_answer", "out n:i")
|
53
65
|
expect { ifc.not_the_answer }.to raise_error(DBus::Error) do |e|
|
54
|
-
expect(e).to_not match(/timeout/)
|
66
|
+
expect(e.message).to_not match(/timeout/)
|
55
67
|
end
|
56
68
|
end
|
57
69
|
|
@@ -60,7 +72,7 @@ describe "ServerRobustnessTest" do
|
|
60
72
|
ifc = DBus::ProxyObjectInterface.new(obj, "org.ruby.NoSuchInterface")
|
61
73
|
ifc.define_method("the_answer", "out n:i")
|
62
74
|
expect { ifc.the_answer }.to raise_error(DBus::Error) do |e|
|
63
|
-
expect(e).to_not match(/timeout/)
|
75
|
+
expect(e.message).to_not match(/timeout/)
|
64
76
|
end
|
65
77
|
end
|
66
78
|
end
|
data/spec/service_newapi.rb
CHANGED
@@ -10,11 +10,24 @@ require "dbus"
|
|
10
10
|
|
11
11
|
PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
|
12
12
|
|
13
|
+
class TestChild < DBus::Object
|
14
|
+
def initialize(opath)
|
15
|
+
@name = opath.split("/").last.capitalize
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
dbus_interface "org.ruby.TestChild" do
|
20
|
+
dbus_attr_reader :name, "s"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
13
24
|
class Test < DBus::Object
|
14
25
|
Point2D = Struct.new(:x, :y)
|
15
26
|
|
16
27
|
attr_writer :main_loop
|
17
28
|
|
29
|
+
include DBus::ObjectManager
|
30
|
+
|
18
31
|
INTERFACE = "org.ruby.SampleInterface"
|
19
32
|
def initialize(path)
|
20
33
|
super path
|
@@ -155,6 +168,21 @@ class Test < DBus::Object
|
|
155
168
|
end
|
156
169
|
end
|
157
170
|
|
171
|
+
dbus_interface "org.ruby.TestParent" do
|
172
|
+
dbus_method :New, "in name:s, out opath:o" do |name|
|
173
|
+
child = TestChild.new("#{path}/#{name}")
|
174
|
+
@service.export(child)
|
175
|
+
[child.path]
|
176
|
+
end
|
177
|
+
|
178
|
+
dbus_method :Delete, "in opath:o" do |opath|
|
179
|
+
raise ArgumentError unless opath.start_with?(path)
|
180
|
+
|
181
|
+
obj = @service.get_node(opath)&.object
|
182
|
+
@service.unexport(obj)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
158
186
|
dbus_interface "org.ruby.Duplicates" do
|
159
187
|
dbus_method :the_answer, "out answer:i" do
|
160
188
|
[0]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "spec_helper"
|
5
|
+
require "dbus"
|
6
|
+
|
7
|
+
describe "DBus::Service (server role)" do
|
8
|
+
let(:bus) { DBus::ASessionBus.new }
|
9
|
+
# This is the client role, but the server role API is bad
|
10
|
+
# and for the one test there is no difference
|
11
|
+
let(:service) { bus["org.ruby.service"] }
|
12
|
+
|
13
|
+
describe "#descendants_for" do
|
14
|
+
it "raises for not existing path" do
|
15
|
+
expect { service.descendants_for("/notthere") }.to raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -24,6 +24,7 @@
|
|
24
24
|
<!-- Do not increase the limits.
|
25
25
|
Instead, lower some so that we can test resource leaks. -->
|
26
26
|
<limit name="max_match_rules_per_connection">50</limit><!-- was 512 -->
|
27
|
+
<limit name="reply_timeout">5000</limit><!-- 5 seconds -->
|
27
28
|
|
28
29
|
<!--
|
29
30
|
dbus-daemon[1700]: [session uid=1001 pid=1700] Unable to set up new connection: Failed to get AppArmor confinement information of socket peer: Protocol not available
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-dbus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ruby DBus Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rexml
|
@@ -155,6 +155,7 @@ files:
|
|
155
155
|
- lib/dbus/message.rb
|
156
156
|
- lib/dbus/message_queue.rb
|
157
157
|
- lib/dbus/object.rb
|
158
|
+
- lib/dbus/object_manager.rb
|
158
159
|
- lib/dbus/object_path.rb
|
159
160
|
- lib/dbus/proxy_object.rb
|
160
161
|
- lib/dbus/proxy_object_factory.rb
|
@@ -179,6 +180,7 @@ files:
|
|
179
180
|
- spec/introspection_spec.rb
|
180
181
|
- spec/main_loop_spec.rb
|
181
182
|
- spec/node_spec.rb
|
183
|
+
- spec/object_manager_spec.rb
|
182
184
|
- spec/object_path_spec.rb
|
183
185
|
- spec/object_spec.rb
|
184
186
|
- spec/packet_marshaller_spec.rb
|
@@ -188,6 +190,7 @@ files:
|
|
188
190
|
- spec/server_robustness_spec.rb
|
189
191
|
- spec/server_spec.rb
|
190
192
|
- spec/service_newapi.rb
|
193
|
+
- spec/service_spec.rb
|
191
194
|
- spec/session_bus_spec.rb
|
192
195
|
- spec/session_bus_spec_manual.rb
|
193
196
|
- spec/signal_spec.rb
|