ruby-dbus 0.22.1 → 0.23.0.beta2

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +38 -0
  3. data/VERSION +1 -1
  4. data/doc/Reference.md +5 -5
  5. data/examples/no-bus/pulseaudio.rb +50 -0
  6. data/examples/service/complex-property.rb +2 -2
  7. data/examples/service/service_newapi.rb +2 -2
  8. data/lib/dbus/bus.rb +48 -694
  9. data/lib/dbus/connection.rb +350 -0
  10. data/lib/dbus/logger.rb +3 -2
  11. data/lib/dbus/main.rb +66 -0
  12. data/lib/dbus/message.rb +6 -8
  13. data/lib/dbus/node_tree.rb +105 -0
  14. data/lib/dbus/object.rb +28 -9
  15. data/lib/dbus/object_manager.rb +6 -3
  16. data/lib/dbus/object_server.rb +149 -0
  17. data/lib/dbus/org.freedesktop.DBus.xml +97 -0
  18. data/lib/dbus/proxy_object.rb +4 -4
  19. data/lib/dbus/proxy_service.rb +107 -0
  20. data/lib/dbus.rb +10 -8
  21. data/ruby-dbus.gemspec +1 -1
  22. data/spec/bus_connection_spec.rb +80 -0
  23. data/spec/connection_spec.rb +37 -0
  24. data/spec/coverage_helper.rb +39 -0
  25. data/spec/dbus_spec.rb +22 -0
  26. data/spec/main_loop_spec.rb +14 -0
  27. data/spec/message_spec.rb +21 -0
  28. data/spec/mock-service/cockpit-dbustests.rb +29 -0
  29. data/spec/mock-service/com.redhat.Cockpit.DBusTests.xml +180 -0
  30. data/spec/mock-service/org.ruby.service.service +4 -0
  31. data/spec/mock-service/org.rubygems.ruby_dbus.DBusTests.service +4 -0
  32. data/spec/{service_newapi.rb → mock-service/spaghetti-monster.rb} +21 -10
  33. data/spec/node_spec.rb +1 -5
  34. data/spec/object_server_spec.rb +138 -0
  35. data/spec/object_spec.rb +46 -0
  36. data/spec/{bus_driver_spec.rb → proxy_service_spec.rb} +13 -8
  37. data/spec/spec_helper.rb +9 -45
  38. data/spec/thread_safety_spec.rb +9 -11
  39. data/spec/tools/dbus-launch-simple +4 -1
  40. data/spec/tools/dbus-limited-session.conf +3 -0
  41. data/spec/tools/test_env +26 -6
  42. metadata +24 -10
  43. data/spec/server_spec.rb +0 -55
  44. data/spec/service_spec.rb +0 -18
  45. data/spec/tools/test_server +0 -39
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../coverage_helper"
5
+ SimpleCov.command_name "Cockpit Tests (#{Process.pid})" if Object.const_defined? "SimpleCov"
6
+
7
+ # find the library without external help
8
+ $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
9
+ require "dbus"
10
+
11
+ SERVICE_NAME = "org.rubygems.ruby_dbus.DBusTests"
12
+ ROOT_OPATH = "/otree/frobber"
13
+
14
+ class DBusTests < DBus::Object
15
+ FROBBER_INTERFACE = "com.redhat.Cockpit.DBusTests.Frobber"
16
+
17
+ dbus_interface FROBBER_INTERFACE do
18
+ dbus_method :HelloWorld, "in greeting:s, out response:s" do |greeting|
19
+ # TODO: return the same thing as the original implementation
20
+ # and try substituting it?
21
+ [format("Word! You said `%s'. I'm Skeleton, btw!", greeting)]
22
+ end
23
+ end
24
+ end
25
+
26
+ bus = DBus::SessionBus.instance
27
+ bus.object_server.export(DBusTests.new(ROOT_OPATH))
28
+ bus.request_name(SERVICE_NAME)
29
+ DBus::Main.new.tap { |m| m << bus }.run
@@ -0,0 +1,180 @@
1
+ <node>
2
+ <!--
3
+ This file is part of Cockpit.
4
+
5
+ Copyright (C) 2013 Red Hat, Inc.
6
+
7
+ Cockpit is free software; you can redistribute it and/or modify it
8
+ under the terms of the GNU Lesser General Public License as published by
9
+ the Free Software Foundation; either version 2.1 of the License, or
10
+ (at your option) any later version.
11
+
12
+ Cockpit is distributed in the hope that it will be useful, but
13
+ WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General Public License
18
+ along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
19
+ -->
20
+
21
+ <interface name="com.redhat.Cockpit.DBusTests.Alpha">
22
+ </interface>
23
+
24
+ <interface name="com.redhat.Cockpit.DBusTests.Frobber">
25
+ <method name="HelloWorld">
26
+ <arg name="greeting" direction="in" type="s"/>
27
+ <arg name="response" direction="out" type="s"/>
28
+ </method>
29
+
30
+ <method name="NeverReturn">
31
+ </method>
32
+
33
+ <method name="TestPrimitiveTypes">
34
+ <arg direction="in" type="y" name="val_byte" />
35
+ <arg direction="in" type="b" name="val_boolean" />
36
+ <arg direction="in" type="n" name="val_int16" />
37
+ <arg direction="in" type="q" name="val_uint16" />
38
+ <arg direction="in" type="i" name="val_int32" />
39
+ <arg direction="in" type="u" name="val_uint32" />
40
+ <arg direction="in" type="x" name="val_int64" />
41
+ <arg direction="in" type="t" name="val_uint64" />
42
+ <arg direction="in" type="d" name="val_double" />
43
+ <arg direction="in" type="s" name="val_string" />
44
+ <arg direction="in" type="o" name="val_objpath" />
45
+ <arg direction="in" type="g" name="val_signature" />
46
+ <arg direction="in" type="ay" name="val_bytestring" />
47
+ <arg direction="out" type="y" name="ret_byte" />
48
+ <arg direction="out" type="b" name="ret_boolean" />
49
+ <arg direction="out" type="n" name="ret_int16" />
50
+ <arg direction="out" type="q" name="ret_uint16" />
51
+ <arg direction="out" type="i" name="ret_int32" />
52
+ <arg direction="out" type="u" name="ret_uint32" />
53
+ <arg direction="out" type="x" name="ret_int64" />
54
+ <arg direction="out" type="t" name="ret_uint64" />
55
+ <arg direction="out" type="d" name="ret_double" />
56
+ <arg direction="out" type="s" name="ret_string" />
57
+ <arg direction="out" type="o" name="ret_objpath" />
58
+ <arg direction="out" type="g" name="ret_signature" />
59
+ <arg direction="out" type="ay" name="ret_bytestring" />
60
+ </method>
61
+
62
+ <method name="TestNonPrimitiveTypes">
63
+ <arg direction="in" type="a{ss}" name="dict_s_to_s" />
64
+ <arg direction="in" type="a{s(ii)}" name="dict_s_to_pairs" />
65
+ <arg direction="in" type="(iss)" name="a_struct" />
66
+ <arg direction="in" type="as" name="array_of_strings" />
67
+ <arg direction="in" type="ao" name="array_of_objpaths" />
68
+ <arg direction="in" type="ag" name="array_of_signatures" />
69
+ <arg direction="in" type="aay" name="array_of_bytestrings" />
70
+ <arg direction="out" type="s" name="result" />
71
+ </method>
72
+
73
+ <method name="TestAsv">
74
+ <arg direction="in" type="a{sv}" name="asv" />
75
+ <arg direction="out" type="s" name="result" />
76
+ </method>
77
+
78
+ <method name="TestVariant">
79
+ <arg direction="in" type="v" name="v" />
80
+ </method>
81
+
82
+ <method name="RequestSignalEmission">
83
+ <arg direction="in" type="i" name="which_one" />
84
+ </method>
85
+
86
+ <method name="RequestPropertyMods"/>
87
+
88
+ <method name="RequestMultiPropertyMods"/>
89
+
90
+ <method name="UnimplementedMethod"/>
91
+
92
+ <method name="PropertyCancellation"/>
93
+
94
+ <signal name="TestSignal">
95
+ <arg type="i" name="val_int32"/>
96
+ <arg type="as" name="array_of_strings" />
97
+ <arg type="ao" name="array_of_objpaths" />
98
+ <arg type="a{s(ii)}" name="dict_s_to_pairs" />
99
+ </signal>
100
+
101
+ <signal name="AnotherSignal">
102
+ <arg type="s" name="word" />
103
+ </signal>
104
+
105
+ <method name="DeleteAllObjects"/>
106
+
107
+ <method name="CreateObject">
108
+ <arg direction="in" type="o" name="at_path" />
109
+ </method>
110
+
111
+ <method name="DeleteObject">
112
+ <arg direction="in" type="o" name="path" />
113
+ </method>
114
+
115
+ <method name="AddAlpha"/>
116
+ <method name="RemoveAlpha"/>
117
+
118
+ <method name="CreateClique">
119
+ <arg direction="in" type="s" name="name" />
120
+ <arg direction="out" type="o" name="member" />
121
+ </method>
122
+
123
+ <method name="EmitHidden">
124
+ <arg direction="in" type="s" name="name" />
125
+ </method>
126
+
127
+ <method name="ClaimOtherName">
128
+ <arg name="name" direction="in" type="s"/>
129
+ </method>
130
+
131
+ <method name="ReleaseOtherName">
132
+ <arg name="name" direction="in" type="s"/>
133
+ </method>
134
+
135
+ <method name="TellMeYourName">
136
+ <arg direction="out" name="name" type="s"/>
137
+ </method>
138
+
139
+ <method name="MakeTestFd">
140
+ <arg direction="in" name="type" type="s"/>
141
+ <arg direction="out" name="fd" type="h"/>
142
+ </method>
143
+
144
+ <property name="y" type="y" access="readwrite"/>
145
+ <property name="b" type="b" access="readwrite"/>
146
+ <property name="n" type="n" access="readwrite"/>
147
+ <property name="q" type="q" access="readwrite"/>
148
+ <property name="i" type="i" access="readwrite"/>
149
+ <property name="u" type="u" access="readwrite"/>
150
+ <property name="x" type="x" access="readwrite"/>
151
+ <property name="t" type="t" access="readwrite"/>
152
+ <property name="d" type="d" access="readwrite"/>
153
+ <property name="s" type="s" access="readwrite"/>
154
+ <property name="o" type="o" access="readwrite"/>
155
+ <property name="g" type="g" access="readwrite"/>
156
+ <property name="ay" type="ay" access="readwrite"/>
157
+ <property name="as" type="as" access="readwrite"/>
158
+ <property name="aay" type="aay" access="readwrite"/>
159
+ <property name="ao" type="ao" access="readwrite"/>
160
+ <property name="ag" type="ag" access="readwrite"/>
161
+ <property name="FinallyNormalName" type="s" access="readwrite"/>
162
+ <property name="ReadonlyProperty" type="s" access="read"/>
163
+ <property name="WriteonlyProperty" type="s" access="write"/>
164
+ </interface>
165
+
166
+ <interface name="com.redhat.Cockpit.DBusTests.Clique">
167
+ <property name="Friend" type="o" access="read"/>
168
+ </interface>
169
+
170
+ <interface name="com.redhat.Cockpit.DBusTests.Hidden">
171
+ <property name="Name" type="s" access="read"/>
172
+ </interface>
173
+
174
+ </node>
175
+
176
+ <!--
177
+ Local Variables:
178
+ indent-tabs-mode: nil
179
+ End:
180
+ -->
@@ -0,0 +1,4 @@
1
+ [D-BUS Service]
2
+ Name=org.ruby.service
3
+ # ... will replace the directory with the current one
4
+ Exec=/usr/bin/spaghetti-monster.rb
@@ -0,0 +1,4 @@
1
+ [D-BUS Service]
2
+ Name=org.rubygems.ruby_dbus.DBusTests
3
+ # ... will replace the directory with the current one
4
+ Exec=/usr/bin/cockpit-dbustests.rb
@@ -1,14 +1,20 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative "spec_helper"
5
- SimpleCov.command_name "Service Tests" if Object.const_defined? "SimpleCov"
4
+ # This file was formerly named spec/service_newapi.rb, after the example
5
+ # which it mutated from.
6
+ # Spaghetti monster is a better name,
7
+ # reflecting on its evolution and current nature :'-)
8
+
9
+ require_relative "../coverage_helper"
10
+ SimpleCov.command_name "Service Tests (#{Process.pid})" if Object.const_defined? "SimpleCov"
11
+
6
12
  # find the library without external help
7
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
13
+ $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
8
14
 
9
15
  require "dbus"
10
16
 
11
- PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
17
+ SERVICE_NAME = "org.ruby.service"
12
18
 
13
19
  class TestChild < DBus::Object
14
20
  def initialize(opath)
@@ -177,15 +183,14 @@ class Test < DBus::Object
177
183
  dbus_interface "org.ruby.TestParent" do
178
184
  dbus_method :New, "in name:s, out opath:o" do |name|
179
185
  child = TestChild.new("#{path}/#{name}")
180
- @service.export(child)
186
+ object_server.export(child)
181
187
  [child.path]
182
188
  end
183
189
 
184
190
  dbus_method :Delete, "in opath:o" do |opath|
185
191
  raise ArgumentError unless opath.start_with?(path)
186
192
 
187
- obj = @service.get_node(opath)&.object
188
- @service.unexport(obj)
193
+ object_server.unexport(opath)
189
194
  end
190
195
  end
191
196
 
@@ -193,7 +198,11 @@ class Test < DBus::Object
193
198
  dbus_method :the_answer, "out answer:i" do
194
199
  [0]
195
200
  end
201
+
196
202
  dbus_method :interfaces, "out answer:i" do
203
+ # 'Shadowed' from the Ruby side, meaning ProxyObject#interfaces
204
+ # will return the list of interfaces rather than calling this method.
205
+ # Calling it with busctl will work just fine.
197
206
  raise "This DBus method is currently shadowed by ProxyObject#interfaces"
198
207
  end
199
208
  end
@@ -231,13 +240,14 @@ class Test2 < DBus::Object
231
240
  end
232
241
 
233
242
  bus = DBus::SessionBus.instance
234
- service = bus.request_service("org.ruby.service")
243
+ service = bus.object_server
235
244
  myobj = Test.new("/org/ruby/MyInstance")
236
245
  service.export(myobj)
237
246
  derived = Derived.new "/org/ruby/MyDerivedInstance"
238
247
  service.export derived
239
248
  test2 = Test2.new "/org/ruby/MyInstance2"
240
249
  service.export test2
250
+ bus.request_name(SERVICE_NAME)
241
251
 
242
252
  # introspect every other connection, Ticket #34
243
253
  # (except the one that activates us - it has already emitted
@@ -254,12 +264,13 @@ bus.add_match(mr) do |msg|
254
264
  end
255
265
  end
256
266
 
257
- puts "listening, with ruby-#{RUBY_VERSION}"
267
+ DBus.logger.info "Service #{SERVICE_NAME} listening, with ruby-#{RUBY_VERSION}"
258
268
  main = DBus::Main.new
259
269
  main << bus
260
270
  myobj.main_loop = main
261
271
  begin
262
272
  main.run
263
- rescue SystemCallError
273
+ rescue SystemCallError, SignalException => e
274
+ DBus.logger.info "Service #{SERVICE_NAME} got #{e.inspect}, exiting"
264
275
  # the test driver will kill the bus, that's OK
265
276
  end
data/spec/node_spec.rb CHANGED
@@ -44,11 +44,7 @@ describe DBus::Node do
44
44
 
45
45
  context "on the bus" do
46
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
47
+ let(:service) { bus.object_server }
52
48
 
53
49
  before do
54
50
  service.export(DBus::Object.new(manager_path))
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env rspec
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "spec_helper"
5
+ require "dbus"
6
+
7
+ describe DBus::ObjectServer do
8
+ let(:bus) { DBus::ASessionBus.new }
9
+ let(:server) { bus.object_server }
10
+
11
+ describe "#descendants_for" do
12
+ it "raises for not existing path" do
13
+ expect { server.descendants_for("/notthere") }.to raise_error(ArgumentError, /notthere doesn't exist/)
14
+ end
15
+ end
16
+
17
+ # tag_bus MEANS that the test needs a session bus
18
+ # tag_service MEANS that it needs a session bus with our testing services
19
+
20
+ describe "#export, #object, #[]", tag_bus: true do
21
+ it "object and [] return the object if it was exported" do
22
+ path = "/org/ruby/Foo"
23
+ obj = DBus::Object.new(path)
24
+ server.export(obj)
25
+ expect(server.object(path)).to be_equal(obj)
26
+ expect(server[path]).to be_equal(obj)
27
+ end
28
+
29
+ it "object and [] return nil if the path was not found or has no object" do
30
+ path = "/org/ruby/Bar"
31
+ obj = DBus::Object.new(path)
32
+ server.export(obj)
33
+
34
+ path2 = "/org/ruby/nosuch"
35
+ expect(server.object(path2)).to be_nil
36
+ expect(server[path2]).to be_nil
37
+
38
+ path3 = "/org"
39
+ expect(server.object(path3)).to be_nil
40
+ expect(server[path3]).to be_nil
41
+ end
42
+ end
43
+
44
+ describe "#export", tag_bus: true do
45
+ context "when exporting at a path where an object exists already" do
46
+ let(:path) { "/org/ruby/Same" }
47
+ let(:obj1) do
48
+ o = DBus::Object.new(path)
49
+ o.define_singleton_method(:which) { 1 }
50
+ o
51
+ end
52
+ let(:obj2) do
53
+ o = DBus::Object.new(path)
54
+ o.define_singleton_method(:which) { 2 }
55
+ o
56
+ end
57
+
58
+ it "raises an error" do
59
+ server.export(obj1)
60
+ expect { server.export(obj2) }.to raise_error(RuntimeError, /there is already an object/)
61
+ end
62
+ end
63
+ end
64
+
65
+ describe "#unexport", tag_bus: true do
66
+ before(:each) do
67
+ bus = DBus::ASessionBus.new
68
+ @svc = bus.object_server
69
+ end
70
+
71
+ it "returns the unexported leaf object" do
72
+ obj = DBus::Object.new "/org/ruby/Foo"
73
+ @svc.export obj
74
+ expect(@svc.unexport(obj)).to be_equal(obj)
75
+ end
76
+
77
+ it "returns the unexported leaf object, if specified by its path" do
78
+ obj = DBus::Object.new "/org/ruby/Foo"
79
+ @svc.export obj
80
+ expect(@svc.unexport(obj.path)).to be_equal(obj)
81
+
82
+ obj = DBus::Object.new "/org/ruby/Foo"
83
+ @svc.export obj
84
+ expect(@svc.unexport(DBus::ObjectPath.new(obj.path))).to be_equal(obj)
85
+ end
86
+
87
+ it "returns false if the object was never exported" do
88
+ obj = DBus::Object.new "/org/ruby/Foo"
89
+ expect(@svc.unexport(obj)).to be false
90
+ end
91
+
92
+ it "raises false if the path has no node" do
93
+ obj = DBus::Object.new "/org/ruby/Foo"
94
+ @svc.export obj
95
+ expect { @svc.unexport("/org/ruby/NotFoo") }.to raise_error(ArgumentError)
96
+ @svc.unexport obj
97
+ end
98
+
99
+ it "raises false if the path has no object" do
100
+ obj = DBus::Object.new "/org/ruby/Foo"
101
+ @svc.export obj
102
+ expect { @svc.unexport("/org/ruby") }.to raise_error(ArgumentError)
103
+ @svc.unexport obj
104
+ end
105
+
106
+ it "raises when argument is not usable" do
107
+ expect { @svc.unexport(:foo) }.to raise_error(ArgumentError)
108
+ end
109
+
110
+ context "/child_of_root" do
111
+ it "returns the unexported object" do
112
+ obj = DBus::Object.new "/child_of_root"
113
+ @svc.export obj
114
+ expect(@svc.unexport(obj)).to be_equal(obj)
115
+ end
116
+ end
117
+
118
+ context "/ (root)" do
119
+ it "returns the unexported object" do
120
+ obj = DBus::Object.new "/"
121
+ @svc.export obj
122
+ expect(@svc.unexport(obj)).to be_equal(obj)
123
+ end
124
+ end
125
+
126
+ context "not a leaf object" do
127
+ it "maintains objects on child paths" do
128
+ obj = DBus::Object.new "/org/ruby"
129
+ @svc.export obj
130
+ obj2 = DBus::Object.new "/org/ruby/Foo"
131
+ @svc.export obj2
132
+
133
+ @svc.unexport(obj)
134
+ expect(@svc.object("/org/ruby/Foo")).to be_a DBus::Object
135
+ end
136
+ end
137
+ end
138
+ end
data/spec/object_spec.rb CHANGED
@@ -118,6 +118,27 @@ describe DBus::Object do
118
118
  end
119
119
  end
120
120
 
121
+ describe ".dbus_signal" do
122
+ it "can only be used within a dbus_interface" do
123
+ expect do
124
+ ObjectTest.instance_exec do
125
+ dbus_signal :signal_without_interface
126
+ end
127
+ end.to raise_error(DBus::Object::UndefinedInterface)
128
+ end
129
+
130
+ it "cannot be named with a bang" do
131
+ expect do
132
+ ObjectTest.instance_exec do
133
+ dbus_interface "org.ruby.ServerTest" do
134
+ # a valid Ruby symbol but an invalid DBus name; Ticket#38
135
+ dbus_signal :signal_with_a_bang!
136
+ end
137
+ end
138
+ end.to raise_error(DBus::InvalidMethodName)
139
+ end
140
+ end
141
+
121
142
  describe ".emits_changed_signal" do
122
143
  it "raises UndefinedInterface when so" do
123
144
  expect { ObjectTest.emits_changed_signal = false }
@@ -145,4 +166,29 @@ describe DBus::Object do
145
166
  end.to raise_error(RuntimeError, /assigned more than once/)
146
167
  end
147
168
  end
169
+
170
+ # coverage obsession
171
+ describe "#dispatch" do
172
+ it "survives being called with a non-METHOD_CALL, doing nothing" do
173
+ obj = ObjectTest.new("/test")
174
+ msg = DBus::MethodReturnMessage.new
175
+ expect { obj.dispatch(msg) }.to_not raise_error
176
+ end
177
+ end
178
+
179
+ describe "#emit" do
180
+ context "before the object has been exported" do
181
+ it "raises an explanatory error" do
182
+ obj = ObjectTest.new("/test")
183
+
184
+ intf = DBus::Interface.new("org.example.Test")
185
+ signal = DBus::Signal.new("Ring")
186
+ expect { obj.emit(intf, signal) }
187
+ .to raise_error(
188
+ RuntimeError,
189
+ %r{Cannot emit signal org.example.Test.Ring before /test is exported}
190
+ )
191
+ end
192
+ end
193
+ end
148
194
  end
@@ -4,14 +4,8 @@
4
4
  require_relative "spec_helper"
5
5
  require "dbus"
6
6
 
7
- describe DBus::Service do
8
- context "when a private bus is set up" do
9
- around(:each) do |example|
10
- with_private_bus do
11
- with_service_by_activation(&example)
12
- end
13
- end
14
-
7
+ describe DBus::ProxyService do
8
+ context "when a private bus is set up", tag_service: true do
15
9
  let(:bus) { DBus::ASessionBus.new }
16
10
 
17
11
  describe "#exists?" do
@@ -26,5 +20,16 @@ describe DBus::Service do
26
20
  expect(svc.exists?).to be false
27
21
  end
28
22
  end
23
+
24
+ # This method is used by dbus-gui-gtk.
25
+ # Deprecate it? In favor of introspecting the tree gradually
26
+ # or move it to the application code?
27
+ describe "#introspect" do
28
+ it "creates the whole node tree" do
29
+ svc = bus.service("org.ruby.service")
30
+ expect { svc.introspect }.to_not raise_error
31
+ expect(svc.root.dig("org", "ruby", "MyInstance")).to be_a DBus::Node
32
+ end
33
+ end
29
34
  end
30
35
  end
data/spec/spec_helper.rb CHANGED
@@ -1,51 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- coverage = if ENV["COVERAGE"]
4
- ENV["COVERAGE"] == "true"
5
- else
6
- # heuristics: enable for interactive builds (but not in OBS)
7
- ENV["DISPLAY"]
8
- end
9
-
10
- if coverage
11
- require "simplecov"
12
- SimpleCov.root File.expand_path("..", __dir__)
13
-
14
- # do not cover specs
15
- SimpleCov.add_filter "_spec.rb"
16
- # do not cover the activesupport helpers
17
- SimpleCov.add_filter "/core_ext/"
18
- # measure all if/else branches on a line
19
- SimpleCov.enable_coverage :branch
20
-
21
- SimpleCov.start
22
-
23
- # additionally use the LCOV format for on-line code coverage reporting at CI
24
- if ENV["COVERAGE_LCOV"] == "true"
25
- require "simplecov-lcov"
26
-
27
- SimpleCov::Formatter::LcovFormatter.config do |c|
28
- c.report_with_single_file = true
29
- # this is the default Coveralls GitHub Action location
30
- # https://github.com/marketplace/actions/coveralls-github-action
31
- c.single_report_path = "coverage/lcov.info"
32
- end
33
-
34
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new [
35
- SimpleCov::Formatter::HTMLFormatter,
36
- SimpleCov::Formatter::LcovFormatter
37
- ]
38
- end
39
- end
3
+ require_relative "coverage_helper"
40
4
 
41
5
  $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
42
6
 
43
- if Object.const_defined? "RSpec"
44
- # http://betterspecs.org/#expect
45
- RSpec.configure do |config|
46
- config.expect_with :rspec do |c|
47
- c.syntax = :expect
48
- end
7
+ # http://betterspecs.org/#expect
8
+ RSpec.configure do |config|
9
+ config.expect_with :rspec do |c|
10
+ c.syntax = :expect
49
11
  end
50
12
  end
51
13
 
@@ -102,7 +64,7 @@ end
102
64
 
103
65
  def with_service_by_activation(&block)
104
66
  name = "org.ruby.service"
105
- exec = "#{TOPDIR}/spec/service_newapi.rb"
67
+ exec = "#{TOPDIR}/spec/mock-service/spaghetti-monster.rb"
106
68
 
107
69
  service_dir = "#{ENV["XDG_DATA_DIRS"]}/dbus-1/services"
108
70
  FileUtils.mkdir_p service_dir
@@ -118,7 +80,9 @@ def with_service_by_activation(&block)
118
80
 
119
81
  block.call
120
82
 
121
- system "pkill -f #{exec}"
83
+ # This would kill also other instances,
84
+ # namely on the bus set up by test_env.
85
+ ## system "pkill -f #{exec}"
122
86
  end
123
87
 
124
88
  # Make a binary string from readable YAML pieces; see data/marshall.yaml
@@ -53,22 +53,20 @@ describe "thread safety" do
53
53
  end
54
54
 
55
55
  context "W/O: when the threads only send signals" do
56
- it "it works with a shared separate bus connection" do
57
- race_threads(5) do |j|
58
- # shared connection
59
- bus = DBus::SessionBus.instance
60
- # hackish: we do not actually request the name
61
- svc = DBus::Service.new("org.ruby.server-test#{j}", bus)
62
-
63
- obj = TestSignalRace.new "/org/ruby/Foo"
64
- svc.export obj
56
+ it "it works with a shared bus connection" do
57
+ # shared connection
58
+ bus = DBus::SessionBus.instance
59
+ svc = bus.object_server
60
+ obj = TestSignalRace.new "/org/ruby/Foo"
61
+ svc.export obj
65
62
 
63
+ race_threads(5) do |_j|
66
64
  repeat_with_jitter(10) do
67
65
  obj.signal_without_arguments
68
66
  end
69
-
70
- svc.unexport(obj)
71
67
  end
68
+
69
+ svc.unexport(obj)
72
70
  puts
73
71
  end
74
72
  end
@@ -12,7 +12,10 @@ my_dbus_launch () {
12
12
  AF=`mktemp dbus.addr.XXXXXX` || exit
13
13
  RM_FILES="$RM_FILES $PF $AF"
14
14
 
15
- dbus-daemon --config-file=$(dirname $0)/dbus-limited-session.conf --print-address=3 3>$AF --print-pid=4 4>$PF &
15
+ # For debugging:
16
+ # DBUS_DAEMON=~/svn/dbus/bus/dbus-daemon DBUS_VERBOSE=1 ./spec/tools/test_env env PS1="TEST $PS1" bash
17
+ : ${DBUS_DAEMON=dbus-daemon}
18
+ $DBUS_DAEMON --config-file=$(dirname $0)/dbus-limited-session.conf --print-address=3 3>$AF --print-pid=4 4>$PF &
16
19
  # wait for the daemon to print the info
17
20
  TRIES=0
18
21
  while [ ! -s $AF -o ! -s $PF ]; do