ruby-dbus 0.18.0.beta8 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d6ace164222b10bbf03ab5ac9e2ec3799c8847c4a8f94e1d7f509944bf3e806
4
- data.tar.gz: 9e8a61b9fa885b36ef21d04f4eb03d4d5a5ab8ec78d5ae258e2433a9e4e5cabe
3
+ metadata.gz: 7261c5ad0fb4e067da97b31298e6a79023e54743f69563b22c9a751101df2f85
4
+ data.tar.gz: 38075d862b0407889bf0a0e25eff450d18c8e225012a028545700fc1be15c342
5
5
  SHA512:
6
- metadata.gz: a6f4e56b35c43975202769d8085cd690c95f345b09e5c78cd2e89f373105ee0e7edc0d9954ac3c647678a41c18ffb06dbaa806f9bed269b832ad6052a9449afe
7
- data.tar.gz: 986c96e6a2f74668cd70e111c9fd57c4dd1c30a2e1b2ed66252406bc8fc67a6ec56bc663bae111b0e331e0f8544419d7fb4facabec1a14e1407ca903695d43c9
6
+ metadata.gz: 700dc07af8d28f7a7537be292dd6313268032f169102c3581d2f5c7a13ba8b9b7c864b23d3b8bdb66e3760a147a7edf7d835098f450625ffade7f748e101f987
7
+ data.tar.gz: 2637cb7cad666a415c6e4a83a158b116507e5d6db3e70a53f5384d1a9240f191e6e2b540950076ae76397b7581c891e71b9f59e84346647394fe0bd7833e49c1
data/NEWS.md CHANGED
@@ -2,6 +2,59 @@
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
+
22
+ ## Ruby D-Bus 0.18.1 - 2022-07-13
23
+
24
+ No changes since 0.18.0.beta8.
25
+ Repeating the most important changes since 0.17.0:
26
+
27
+ API:
28
+ * Introduced DBus::Data classes, use them in Properties.Get,
29
+ Properties.GetAll to return correct types as declared ([#97][]).
30
+ * Introduced Object#dbus_properties_changed to send correctly typed property
31
+ values ([#115][]). Avoid calling PropertiesChanged directly as it will
32
+ guess the types.
33
+ * Service side `emits_changed_signal` to control emission of
34
+ PropertiesChanged: can be assigned within `dbus_interface` or as an option
35
+ when declaring properties ([#117][]).
36
+ * DBus.variant(type, value) is deprecated in favor of
37
+ Data::Variant.new(value, member_type:)
38
+ * Added type factories
39
+ * Type::Array[type]
40
+ * Type::Hash[key_type, value_type]
41
+ * Type::Struct[type1, type2...]
42
+
43
+ Bug fixes:
44
+ * Fix Object.dbus_reader to work with attr_accessor and automatically produce
45
+ dbus_properties_changed for properties that are read-write at
46
+ implementation side and read-only at D-Bus side ([#96][])
47
+ * Service-side properties: Fix Properties.Get, Properties.GetAll
48
+ to use the specific property signature, not the generic
49
+ Variant ([#97][], [#105][], [#109][]).
50
+ * Client-side properties: When calling Properties.Set in
51
+ ProxyObjectInterface#[]=, use the correct type ([#108][]).
52
+ * Added thorough tests (`spec/data/marshall.yaml`) to detect nearly all
53
+ invalid data at unmarshalling time.
54
+
55
+ Requirements:
56
+ * Require Ruby 2.4, because of RuboCop 1.0.
57
+
5
58
  ## Ruby D-Bus 0.18.0.beta8 - 2022-06-21
6
59
 
7
60
  Bug fixes:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.18.0.beta8
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 !node
565
- reply = Message.error(msg, "org.freedesktop.DBus.Error.UnknownObject",
566
- "Object #{msg.path} doesn't exist")
567
- @message_queue.push(reply)
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
- obj = node.object
578
- return if obj.nil? # FIXME, pushes no reply
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
@@ -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 [SingleCompleteType]
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 recieved and ay is expected, explode the string
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
- yield
93
- @@cur_intf = nil
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 a signature like "s" or "a(uus)" or Type::STRING
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
@@ -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.18.0.beta8
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: 2022-06-21 00:00:00.000000000 Z
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
@@ -216,9 +219,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
216
219
  version: 2.4.0
217
220
  required_rubygems_version: !ruby/object:Gem::Requirement
218
221
  requirements:
219
- - - ">"
222
+ - - ">="
220
223
  - !ruby/object:Gem::Version
221
- version: 1.3.1
224
+ version: '0'
222
225
  requirements: []
223
226
  rubyforge_project:
224
227
  rubygems_version: 2.7.6.3