ruby-dbus 0.22.1 → 0.23.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
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