ruby-dbus-openplacos 0.6.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.
- data/COPYING +504 -0
- data/NEWS +146 -0
- data/README +42 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/doc/tutorial/index.markdown +480 -0
- data/examples/gdbus/gdbus +255 -0
- data/examples/gdbus/gdbus.glade +184 -0
- data/examples/gdbus/launch.sh +4 -0
- data/examples/no-introspect/nm-test.rb +21 -0
- data/examples/no-introspect/tracker-test.rb +16 -0
- data/examples/rhythmbox/playpause.rb +25 -0
- data/examples/service/call_service.rb +25 -0
- data/examples/service/service_newapi.rb +51 -0
- data/examples/simple/call_introspect.rb +34 -0
- data/examples/simple/properties.rb +19 -0
- data/examples/utils/listnames.rb +11 -0
- data/examples/utils/notify.rb +19 -0
- data/lib/dbus/auth.rb +258 -0
- data/lib/dbus/bus.rb +947 -0
- data/lib/dbus/core_ext/class/attribute.rb +91 -0
- data/lib/dbus/core_ext/kernel/singleton_class.rb +14 -0
- data/lib/dbus/core_ext/module/remove_method.rb +12 -0
- data/lib/dbus/error.rb +44 -0
- data/lib/dbus/export.rb +124 -0
- data/lib/dbus/introspect.rb +570 -0
- data/lib/dbus/marshall.rb +443 -0
- data/lib/dbus/matchrule.rb +100 -0
- data/lib/dbus/message.rb +310 -0
- data/lib/dbus/type.rb +222 -0
- data/lib/dbus.rb +83 -0
- data/ruby-dbus-openplacos.gemspec +17 -0
- data/test/binding_test.rb +56 -0
- data/test/bus_driver_test.rb +22 -0
- data/test/dbus-launch-simple +35 -0
- data/test/dbus-limited-session.conf +28 -0
- data/test/property_test.rb +55 -0
- data/test/server_robustness_test.rb +72 -0
- data/test/server_test.rb +53 -0
- data/test/service_newapi.rb +197 -0
- data/test/session_bus_test_manual.rb +20 -0
- data/test/signal_test.rb +64 -0
- data/test/t1 +4 -0
- data/test/t2.rb +66 -0
- data/test/t3-ticket27.rb +18 -0
- data/test/t5-report-dbus-interface.rb +58 -0
- data/test/t6-loop.rb +82 -0
- data/test/test_env +13 -0
- data/test/test_server +39 -0
- data/test/variant_test.rb +66 -0
- metadata +118 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
#! /bin/sh
|
2
|
+
# A wrapper for DBus tests
|
3
|
+
# Reimplementing dbus-launch because it is in dbus-1-x11.rpm
|
4
|
+
# Sets up a private session bus and call the specified program
|
5
|
+
set -o errexit
|
6
|
+
|
7
|
+
# This launches the bus daemon,
|
8
|
+
# exports DBUS_SESSION_BUS_ADDRESS and sets DBUS_SESSION_BUS_PID
|
9
|
+
my_dbus_launch () {
|
10
|
+
# reimplementing dbus-launch because it is in dbus-1-x11.rpm
|
11
|
+
PF=`mktemp dbus.pid.XXXXXX` || exit
|
12
|
+
AF=`mktemp dbus.addr.XXXXXX` || exit
|
13
|
+
RM_FILES="$RM_FILES $PF $AF"
|
14
|
+
|
15
|
+
dbus-daemon --config-file=dbus-limited-session.conf --print-address=3 3>$AF --print-pid=4 4>$PF &
|
16
|
+
# wait for the daemon to print the info
|
17
|
+
TRIES=0
|
18
|
+
while [ ! -s $AF -o ! -s $PF ]; do
|
19
|
+
sleep 0.1
|
20
|
+
TRIES=`expr $TRIES + 1`
|
21
|
+
if [ $TRIES -gt 100 ]; then echo "dbus-daemon failed?"; exit 1; fi
|
22
|
+
done
|
23
|
+
DBUS_SESSION_BUS_PID=$(cat $PF)
|
24
|
+
export DBUS_SESSION_BUS_ADDRESS=$(cat $AF)
|
25
|
+
KILLS="$KILLS $DBUS_SESSION_BUS_PID"
|
26
|
+
# dbus-monitor &
|
27
|
+
}
|
28
|
+
|
29
|
+
my_dbus_launch
|
30
|
+
|
31
|
+
# Clean up at exit.
|
32
|
+
trap "kill \$KILLS; rm -rf \$RM_FILES" EXIT TERM INT
|
33
|
+
|
34
|
+
# run the payload; the return value is passed on
|
35
|
+
"$@"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<!-- This configuration file controls the testing message bus.
|
2
|
+
It is based on a session bus config. -->
|
3
|
+
|
4
|
+
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
|
5
|
+
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
6
|
+
<busconfig>
|
7
|
+
<!-- Our well-known bus type, don't change this -->
|
8
|
+
<type>session</type>
|
9
|
+
|
10
|
+
<listen>unix:tmpdir=/tmp</listen>
|
11
|
+
<listen>tcp:host=localhost,port=0,family=ipv4</listen>
|
12
|
+
|
13
|
+
<standard_session_servicedirs />
|
14
|
+
|
15
|
+
<policy context="default">
|
16
|
+
<!-- Allow everything to be sent -->
|
17
|
+
<allow send_destination="*" eavesdrop="true"/>
|
18
|
+
<!-- Allow everything to be received -->
|
19
|
+
<allow eavesdrop="true"/>
|
20
|
+
<!-- Allow anyone to own anything -->
|
21
|
+
<allow own="*"/>
|
22
|
+
</policy>
|
23
|
+
|
24
|
+
<!-- Do not increase the limits.
|
25
|
+
Instead, lower some so that we can test resource leaks. -->
|
26
|
+
<limit name="max_match_rules_per_connection">50</limit><!-- was 512 -->
|
27
|
+
|
28
|
+
</busconfig>
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "test/unit"
|
3
|
+
require "dbus"
|
4
|
+
|
5
|
+
class PropertyTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
session_bus = DBus::ASessionBus.new
|
8
|
+
svc = session_bus.service("org.ruby.service")
|
9
|
+
@obj = svc.object("/org/ruby/MyInstance")
|
10
|
+
@obj.introspect
|
11
|
+
@iface = @obj["org.ruby.SampleInterface"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_property_reading
|
15
|
+
assert_equal "READ ME", @iface["ReadMe"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_property_nonreading
|
19
|
+
e = assert_raises DBus::Error do
|
20
|
+
@iface["WriteMe"]
|
21
|
+
end
|
22
|
+
assert_match(/not readable/, e.to_s)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_property_writing
|
26
|
+
@iface["ReadOrWriteMe"] = "VALUE"
|
27
|
+
assert_equal "VALUE", @iface["ReadOrWriteMe"]
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_property_nonwriting
|
31
|
+
e = assert_raises DBus::Error do
|
32
|
+
@iface["ReadMe"] = "WROTE"
|
33
|
+
end
|
34
|
+
assert_match(/not writable/, e.to_s)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_get_all
|
38
|
+
all = @iface.all_properties
|
39
|
+
assert_equal ["ReadMe", "ReadOrWriteMe"], all.keys.sort
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_unknown_property_reading
|
43
|
+
e = assert_raises DBus::Error do
|
44
|
+
@iface["Spoon"]
|
45
|
+
end
|
46
|
+
assert_match(/not found/, e.to_s)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_unknown_property_writing
|
50
|
+
e = assert_raises DBus::Error do
|
51
|
+
@iface["Spoon"] = "FORK"
|
52
|
+
end
|
53
|
+
assert_match(/not found/, e.to_s)
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test that a server survives various error cases
|
3
|
+
require "test/unit"
|
4
|
+
require "dbus"
|
5
|
+
|
6
|
+
class ServerRobustnessTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@bus = DBus::ASessionBus.new
|
9
|
+
@svc = @bus.service("org.ruby.service")
|
10
|
+
end
|
11
|
+
|
12
|
+
# https://trac.luon.net/ruby-dbus/ticket/31
|
13
|
+
# the server should not crash
|
14
|
+
def test_no_such_path_with_introspection
|
15
|
+
obj = @svc.object "/org/ruby/NotMyInstance"
|
16
|
+
obj.introspect
|
17
|
+
assert false, "should have raised"
|
18
|
+
rescue DBus::Error => e
|
19
|
+
assert_no_match(/timeout/, e.to_s)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_no_such_path_without_introspection
|
23
|
+
obj = @svc.object "/org/ruby/NotMyInstance"
|
24
|
+
ifc = DBus::ProxyObjectInterface.new(obj, "org.ruby.SampleInterface")
|
25
|
+
ifc.define_method("the_answer", "out n:i")
|
26
|
+
ifc.the_answer
|
27
|
+
assert false, "should have raised"
|
28
|
+
rescue DBus::Error => e
|
29
|
+
assert_no_match(/timeout/, e.to_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_a_method_that_raises
|
33
|
+
obj = @svc.object "/org/ruby/MyInstance"
|
34
|
+
obj.introspect
|
35
|
+
obj.default_iface = "org.ruby.SampleInterface"
|
36
|
+
obj.will_raise
|
37
|
+
assert false, "should have raised"
|
38
|
+
rescue DBus::Error => e
|
39
|
+
assert_no_match(/timeout/, e.to_s)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_a_method_that_raises_name_error
|
43
|
+
obj = @svc.object "/org/ruby/MyInstance"
|
44
|
+
obj.introspect
|
45
|
+
obj.default_iface = "org.ruby.SampleInterface"
|
46
|
+
obj.will_raise_name_error
|
47
|
+
assert false, "should have raised"
|
48
|
+
rescue DBus::Error => e
|
49
|
+
assert_no_match(/timeout/, e.to_s)
|
50
|
+
end
|
51
|
+
|
52
|
+
# https://trac.luon.net/ruby-dbus/ticket/31#comment:3
|
53
|
+
def test_no_such_method_without_introspection
|
54
|
+
obj = @svc.object "/org/ruby/MyInstance"
|
55
|
+
ifc = DBus::ProxyObjectInterface.new(obj, "org.ruby.SampleInterface")
|
56
|
+
ifc.define_method("not_the_answer", "out n:i")
|
57
|
+
ifc.not_the_answer
|
58
|
+
assert false, "should have raised"
|
59
|
+
rescue DBus::Error => e
|
60
|
+
assert_no_match(/timeout/, e)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_no_such_interface_without_introspection
|
64
|
+
obj = @svc.object "/org/ruby/MyInstance"
|
65
|
+
ifc = DBus::ProxyObjectInterface.new(obj, "org.ruby.NoSuchInterface")
|
66
|
+
ifc.define_method("the_answer", "out n:i")
|
67
|
+
ifc.the_answer
|
68
|
+
assert false, "should have raised"
|
69
|
+
rescue DBus::Error => e
|
70
|
+
assert_no_match(/timeout/, e)
|
71
|
+
end
|
72
|
+
end
|
data/test/server_test.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test that a server survives various error cases
|
3
|
+
require "test/unit"
|
4
|
+
require "dbus"
|
5
|
+
|
6
|
+
class Foo < DBus::Object
|
7
|
+
dbus_interface "org.ruby.ServerTest" do
|
8
|
+
dbus_signal :signal_without_arguments
|
9
|
+
dbus_signal :signal_with_argument, "epsilon:d"
|
10
|
+
end
|
11
|
+
|
12
|
+
dbus_signal :signal_without_interface
|
13
|
+
rescue DBus::Object::UndefinedInterface => e
|
14
|
+
# raised by the preceding signal declaration
|
15
|
+
end
|
16
|
+
|
17
|
+
class Bar < DBus::Object
|
18
|
+
dbus_interface "org.ruby.ServerTest" do
|
19
|
+
# a valid Ruby symbol but an invalid DBus name; Ticket#38
|
20
|
+
dbus_signal :signal_with_a_bang!
|
21
|
+
end
|
22
|
+
rescue DBus::InvalidMethodName
|
23
|
+
# raised by the preceding signal declaration
|
24
|
+
end
|
25
|
+
|
26
|
+
class ServerTest < Test::Unit::TestCase
|
27
|
+
def setup
|
28
|
+
@bus = DBus::ASessionBus.new
|
29
|
+
@svc = @bus.request_service "org.ruby.server-test"
|
30
|
+
end
|
31
|
+
|
32
|
+
def teardown
|
33
|
+
@bus.proxy.ReleaseName "org.ruby.server-test"
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_unexporting_an_object
|
37
|
+
obj = Foo.new "/org/ruby/Foo"
|
38
|
+
@svc.export obj
|
39
|
+
assert @svc.unexport(obj)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_unexporting_an_object_not_exported
|
43
|
+
obj = Foo.new "/org/ruby/Foo"
|
44
|
+
assert !@svc.unexport(obj)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_emiting_signals
|
48
|
+
obj = Foo.new "/org/ruby/Foo"
|
49
|
+
@svc.export obj
|
50
|
+
obj.signal_without_arguments
|
51
|
+
obj.signal_with_argument(-0.1)
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# find the library without external help
|
4
|
+
$:.unshift File.expand_path("../../lib", __FILE__)
|
5
|
+
|
6
|
+
require 'dbus'
|
7
|
+
|
8
|
+
def d(msg)
|
9
|
+
puts "#{$$} #{msg}" if $DEBUG
|
10
|
+
end
|
11
|
+
|
12
|
+
PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
|
13
|
+
|
14
|
+
class Test < DBus::Object
|
15
|
+
INTERFACE = "org.ruby.SampleInterface"
|
16
|
+
def initialize(path)
|
17
|
+
super path
|
18
|
+
@read_me = "READ ME"
|
19
|
+
@read_or_write_me = "READ OR WRITE ME"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Create an interface aggregating all upcoming dbus_method defines.
|
23
|
+
dbus_interface INTERFACE do
|
24
|
+
dbus_method :hello, "in name:s, in name2:s" do |name, name2|
|
25
|
+
puts "hello(#{name}, #{name2})"
|
26
|
+
end
|
27
|
+
|
28
|
+
dbus_method :test_variant, "in stuff:v" do |variant|
|
29
|
+
p variant
|
30
|
+
end
|
31
|
+
|
32
|
+
dbus_method :bounce_variant, "in stuff:v, out chaff:v" do |variant|
|
33
|
+
[variant]
|
34
|
+
end
|
35
|
+
|
36
|
+
dbus_method :variant_size, "in stuff:v, out size:u" do |variant|
|
37
|
+
[variant.size]
|
38
|
+
end
|
39
|
+
|
40
|
+
dbus_method :the_answer, "out answer:i" do
|
41
|
+
42
|
42
|
+
end
|
43
|
+
|
44
|
+
dbus_method :will_raise, "" do
|
45
|
+
raise "Handle this"
|
46
|
+
end
|
47
|
+
|
48
|
+
dbus_method :will_raise_error_failed, "" do
|
49
|
+
raise DBus.error, "failed as designed"
|
50
|
+
end
|
51
|
+
|
52
|
+
dbus_method :will_raise_name_error, "" do
|
53
|
+
"foo".frobnicate
|
54
|
+
end
|
55
|
+
|
56
|
+
dbus_method :Error, "in name:s, in description:s" do |name, description|
|
57
|
+
raise DBus.error(name), description
|
58
|
+
end
|
59
|
+
|
60
|
+
dbus_signal :SomethingJustHappened, "toto:s, tutu:u"
|
61
|
+
end
|
62
|
+
|
63
|
+
dbus_interface "org.ruby.AnotherInterface" do
|
64
|
+
dbus_method :ThatsALongMethodNameIThink do
|
65
|
+
puts "ThatsALongMethodNameIThink"
|
66
|
+
end
|
67
|
+
dbus_method :Reverse, "in instr:s, out outstr:s" do |instr|
|
68
|
+
outstr = instr.split(//).reverse.join
|
69
|
+
puts "got: #{instr}, replying: #{outstr}"
|
70
|
+
[outstr]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
dbus_interface "org.ruby.Ticket30" do
|
75
|
+
dbus_method :Sybilla, 'in choices:av, out advice:s' do |choices|
|
76
|
+
["Do #{choices[0]}"]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
dbus_interface "org.ruby.Loop" do
|
81
|
+
# starts doing something long, but returns immediately
|
82
|
+
# and sends a signal when done
|
83
|
+
dbus_method :LongTaskBegin, 'in delay:i' do |delay|
|
84
|
+
# FIXME did not complain about mismatch between signature and block args
|
85
|
+
d "Long task began"
|
86
|
+
task = Thread.new do
|
87
|
+
d "Long task thread started (#{delay}s)"
|
88
|
+
sleep delay
|
89
|
+
d "Long task will signal end"
|
90
|
+
self.LongTaskEnd
|
91
|
+
end
|
92
|
+
task.abort_on_exception = true # protect from test case bugs
|
93
|
+
end
|
94
|
+
|
95
|
+
dbus_signal :LongTaskEnd
|
96
|
+
end
|
97
|
+
|
98
|
+
# Properties:
|
99
|
+
# ReadMe:string, returns "READ ME" at first, then what WriteMe received
|
100
|
+
# WriteMe:string
|
101
|
+
# ReadOrWriteMe:string, returns "READ OR WRITE ME" at first
|
102
|
+
dbus_interface PROPERTY_INTERFACE do
|
103
|
+
dbus_method :Get, "in interface:s, in propname:s, out value:v" do |interface, propname|
|
104
|
+
if interface == INTERFACE
|
105
|
+
if propname == "ReadMe"
|
106
|
+
[@read_me]
|
107
|
+
elsif propname == "ReadOrWriteMe"
|
108
|
+
[@read_or_write_me]
|
109
|
+
elsif propname == "WriteMe"
|
110
|
+
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"), "Property '#{interface}.#{propname}' (on object '#{@path}') is not readable"
|
111
|
+
else
|
112
|
+
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"), "Property '#{interface}.#{propname}' not found on object '#{@path}'"
|
113
|
+
end
|
114
|
+
else
|
115
|
+
raise DBus.error("org.freedesktop.DBus.Error.UnknownInterface"), "Interface '#{interface}' not found on object '#{@path}'"
|
116
|
+
end
|
117
|
+
# what should happen for unknown properties
|
118
|
+
# plasma: InvalidArgs (propname), UnknownInterface (interface)
|
119
|
+
end
|
120
|
+
|
121
|
+
dbus_method :Set, "in interface:s, in propname:s, in value:v" do |interface, propname, value|
|
122
|
+
if interface == INTERFACE
|
123
|
+
if propname == "ReadMe"
|
124
|
+
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"), "Property '#{interface}.#{propname}' (on object '#{@path}') is not writable"
|
125
|
+
elsif propname == "ReadOrWriteMe"
|
126
|
+
@read_or_write_me = value
|
127
|
+
self.PropertiesChanged(interface, {propname => value}, [])
|
128
|
+
elsif propname == "WriteMe"
|
129
|
+
@read_me = value
|
130
|
+
self.PropertiesChanged(interface, {"ReadMe" => value}, [])
|
131
|
+
else
|
132
|
+
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"), "Property '#{interface}.#{propname}' not found on object '#{@path}'"
|
133
|
+
end
|
134
|
+
else
|
135
|
+
raise DBus.error("org.freedesktop.DBus.Error.UnknownInterface"), "Interface '#{interface}' not found on object '#{@path}'"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
dbus_method :GetAll, "in interface:s, out value:a{sv}" do |interface|
|
140
|
+
if interface == INTERFACE
|
141
|
+
[ {
|
142
|
+
"ReadMe" => @read_me,
|
143
|
+
"ReadOrWriteMe" =>@read_or_write_me,
|
144
|
+
} ]
|
145
|
+
else
|
146
|
+
raise DBus.error("org.freedesktop.DBus.Error.UnknownInterface"), "Interface '#{interface}' not found on object '#{@path}'"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
dbus_signal :PropertiesChanged, "interface:s, changed_properties:a{sv}, invalidated_properties:as"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class Derived < Test
|
155
|
+
end
|
156
|
+
|
157
|
+
class Test2 < DBus::Object
|
158
|
+
dbus_interface "org.ruby.Test2" do
|
159
|
+
dbus_method :hi, "in name:s, out greeting:s" do |name|
|
160
|
+
"Hi, #{name}!"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
bus = DBus::SessionBus.instance
|
166
|
+
service = bus.request_service("org.ruby.service")
|
167
|
+
myobj = Test.new("/org/ruby/MyInstance")
|
168
|
+
service.export(myobj)
|
169
|
+
derived = Derived.new "/org/ruby/MyDerivedInstance"
|
170
|
+
service.export derived
|
171
|
+
test2 = Test2.new "/org/ruby/MyInstance2"
|
172
|
+
service.export test2
|
173
|
+
|
174
|
+
# introspect every other connection, Ticket #34
|
175
|
+
# (except the one that activates us - it has already emitted
|
176
|
+
# NOC by the time we run this. Therefore the test for #34 will not work
|
177
|
+
# by running t2.rb alone, one has to run t1 before it; 'rake' does it)
|
178
|
+
mr = DBus::MatchRule.new.from_s "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'"
|
179
|
+
bus.add_match(mr) do |msg|
|
180
|
+
new_unique_name = msg.params[2]
|
181
|
+
unless new_unique_name.empty?
|
182
|
+
d "RRRING #{new_unique_name}"
|
183
|
+
bus.introspect_data(new_unique_name, "/") do
|
184
|
+
# ignore the result
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
puts "listening"
|
190
|
+
main = DBus::Main.new
|
191
|
+
main << bus
|
192
|
+
begin
|
193
|
+
main.run
|
194
|
+
rescue SystemCallError
|
195
|
+
# the test driver will kill the bus, that's OK
|
196
|
+
end
|
197
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "test/unit"
|
3
|
+
require "dbus"
|
4
|
+
|
5
|
+
def d(msg)
|
6
|
+
puts msg if $DEBUG
|
7
|
+
end
|
8
|
+
|
9
|
+
class SessionBusAddressTest < Test::Unit::TestCase
|
10
|
+
def setup
|
11
|
+
# test getting the session bus address even if unset in ENV (Issue#4)
|
12
|
+
ENV.delete "DBUS_SESSION_BUS_ADDRESS"
|
13
|
+
@bus = DBus::ASessionBus.new
|
14
|
+
@svc = @bus.service("org.freedesktop.DBus")
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_connection
|
18
|
+
assert @svc.exists?
|
19
|
+
end
|
20
|
+
end
|
data/test/signal_test.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test the signal handlers
|
3
|
+
require "test/unit"
|
4
|
+
require "dbus"
|
5
|
+
|
6
|
+
def d(msg)
|
7
|
+
puts "#{$$} #{msg}" if $DEBUG
|
8
|
+
end
|
9
|
+
|
10
|
+
class SignalHandlerTest < Test::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
@session_bus = DBus::ASessionBus.new
|
13
|
+
svc = @session_bus.service("org.ruby.service")
|
14
|
+
@obj = svc.object("/org/ruby/MyInstance")
|
15
|
+
@obj.introspect # necessary
|
16
|
+
@obj.default_iface = "org.ruby.Loop"
|
17
|
+
|
18
|
+
@loop = DBus::Main.new
|
19
|
+
@loop << @session_bus
|
20
|
+
end
|
21
|
+
|
22
|
+
# testing for commit 017c83 (kkaempf)
|
23
|
+
def test_overriding_a_handler
|
24
|
+
counter = 0
|
25
|
+
|
26
|
+
@obj.on_signal "LongTaskEnd" do
|
27
|
+
d "+10"
|
28
|
+
counter += 10
|
29
|
+
end
|
30
|
+
@obj.on_signal "LongTaskEnd" do
|
31
|
+
d "+1"
|
32
|
+
counter += 1
|
33
|
+
end
|
34
|
+
|
35
|
+
d "will begin"
|
36
|
+
@obj.LongTaskBegin 3
|
37
|
+
|
38
|
+
quitter = Thread.new do
|
39
|
+
d "sleep before quit"
|
40
|
+
# FIXME if we sleep for too long
|
41
|
+
# the socket will be drained and we deadlock in a select.
|
42
|
+
# It could be worked around by sending ourselves a Unix signal
|
43
|
+
# (with a dummy handler) to interrupt the select
|
44
|
+
sleep 1
|
45
|
+
d "will quit"
|
46
|
+
@loop.quit
|
47
|
+
end
|
48
|
+
@loop.run
|
49
|
+
|
50
|
+
assert_equal 1, counter
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_too_many_rules
|
54
|
+
100.times do
|
55
|
+
@obj.on_signal "Whichever" do
|
56
|
+
puts "not called"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_removing_a_nonexistent_rule
|
62
|
+
@obj.on_signal "DoesNotExist"
|
63
|
+
end
|
64
|
+
end
|
data/test/t1
ADDED
data/test/t2.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "test/unit"
|
3
|
+
require "dbus"
|
4
|
+
|
5
|
+
class ValueTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
session_bus = DBus::ASessionBus.new
|
8
|
+
svc = session_bus.service("org.ruby.service")
|
9
|
+
@obj = svc.object("/org/ruby/MyInstance")
|
10
|
+
@obj.introspect # necessary
|
11
|
+
@obj.default_iface = "org.ruby.SampleInterface"
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_passing_an_array_through_a_variant
|
15
|
+
# old explicit typing
|
16
|
+
@obj.test_variant(["as", ["coucou", "kuku"]])
|
17
|
+
# automatic typing
|
18
|
+
@obj.test_variant(["coucou", "kuku"])
|
19
|
+
@obj.test_variant(["saint", "was that a word or a signature?"])
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_bouncing_a_variant
|
23
|
+
assert_equal "cuckoo", @obj.bounce_variant("cuckoo")[0]
|
24
|
+
assert_equal ["coucou", "kuku"], @obj.bounce_variant(["coucou", "kuku"])[0]
|
25
|
+
assert_equal [], @obj.bounce_variant([])[0]
|
26
|
+
empty_hash = {}
|
27
|
+
assert_equal empty_hash, @obj.bounce_variant(empty_hash)[0]
|
28
|
+
end
|
29
|
+
|
30
|
+
# these are ambiguous
|
31
|
+
def test_pairs_with_a_string
|
32
|
+
|
33
|
+
# deprecated
|
34
|
+
assert_equal "foo", @obj.bounce_variant(["s", "foo"])[0]
|
35
|
+
|
36
|
+
assert_equal "foo", @obj.bounce_variant(DBus.variant("s", "foo"))[0]
|
37
|
+
assert_equal "foo", @obj.bounce_variant([DBus.type("s"), "foo"])[0]
|
38
|
+
|
39
|
+
# does not work, because the server side forgets the explicit typing
|
40
|
+
# assert_equal ["s", "foo"], @obj.bounce_variant(["av", ["s", "foo"]])[0]
|
41
|
+
# assert_equal ["s", "foo"], @obj.bounce_variant(["as", ["s", "foo"]])[0]
|
42
|
+
|
43
|
+
# instead, use this to demonstrate that the variant is passed as expected
|
44
|
+
assert_equal 4, @obj.variant_size(["s", "four"])[0]
|
45
|
+
# "av" is the simplest thing that will work,
|
46
|
+
# shifting the heuristic from a pair to the individual items
|
47
|
+
assert_equal 2, @obj.variant_size(["av", ["s", "four"]])[0]
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_marshalling_an_array_of_variants
|
51
|
+
# https://trac.luon.net/ruby-dbus/ticket/30
|
52
|
+
@obj.default_iface = "org.ruby.Ticket30"
|
53
|
+
choices = []
|
54
|
+
choices << ['s', 'Plan A']
|
55
|
+
choices << ['s', 'Plan B']
|
56
|
+
# old explicit typing
|
57
|
+
assert_equal "Do Plan A", @obj.Sybilla(choices)[0]
|
58
|
+
# automatic typing
|
59
|
+
assert_equal "Do Plan A", @obj.Sybilla(["Plan A", "Plan B"])[0]
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_service_returning_nonarray
|
63
|
+
# "warning: default `to_a' will be obsolete"
|
64
|
+
@obj.the_answer
|
65
|
+
end
|
66
|
+
end
|
data/test/t3-ticket27.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Test passing a particular struct array through a variant
|
3
|
+
# https://trac.luon.net/ruby-dbus/ticket/27
|
4
|
+
require "dbus"
|
5
|
+
session_bus = DBus::ASessionBus.new
|
6
|
+
svc = session_bus.service("org.ruby.service")
|
7
|
+
obj = svc.object("/org/ruby/MyInstance")
|
8
|
+
obj.introspect # necessary
|
9
|
+
obj.default_iface = "org.ruby.SampleInterface"
|
10
|
+
# The bug is probably alignment related so whether it triggers
|
11
|
+
# depends also on the combined length of service, interface,
|
12
|
+
# and method names. Luckily here it works out.
|
13
|
+
triple = ['a(uuu)', []]
|
14
|
+
obj.test_variant(triple)
|
15
|
+
quadruple = ['a(uuuu)', []] # a(uuu) works fine
|
16
|
+
# The bus disconnects us because of malformed message,
|
17
|
+
# code 12: DBUS_INVALID_TOO_MUCH_DATA
|
18
|
+
obj.test_variant(quadruple)
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# should report it missing on org.ruby.SampleInterface
|
3
|
+
# (on object...) instead of on DBus::Proxy::ObjectInterface
|
4
|
+
require "test/unit"
|
5
|
+
require "dbus"
|
6
|
+
|
7
|
+
class ErrMsgTest < Test::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
session_bus = DBus::ASessionBus.new
|
10
|
+
svc = session_bus.service("org.ruby.service")
|
11
|
+
@obj = svc.object("/org/ruby/MyInstance")
|
12
|
+
@obj.introspect # necessary
|
13
|
+
@obj.default_iface = "org.ruby.SampleInterface"
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_report_dbus_interface
|
17
|
+
begin
|
18
|
+
@obj.NoSuchMethod
|
19
|
+
# a specific exception...
|
20
|
+
rescue NameError => e
|
21
|
+
# mentioning DBus and the interface
|
22
|
+
assert_match(/DBus interface.*#{@obj.default_iface}/, e.to_s)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_report_short_struct
|
27
|
+
begin
|
28
|
+
@obj.test_variant ["(ss)", ["too few"] ]
|
29
|
+
rescue DBus::TypeException => e
|
30
|
+
assert_match(/1 elements but type info for 2/, e.to_s)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_report_long_struct
|
35
|
+
begin
|
36
|
+
@obj.test_variant ["(ss)", ["a", "b", "too many"] ]
|
37
|
+
rescue DBus::TypeException => e
|
38
|
+
assert_match(/3 elements but type info for 2/, e.to_s)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_report_nil
|
43
|
+
nils = [
|
44
|
+
["(s)", [nil] ], # would get disconnected
|
45
|
+
["i", nil ],
|
46
|
+
["a{ss}", {"foo" => nil} ],
|
47
|
+
]
|
48
|
+
nils.each do |has_nil|
|
49
|
+
begin
|
50
|
+
@obj.test_variant has_nil
|
51
|
+
rescue DBus::TypeException => e
|
52
|
+
# TODO want backtrace from the perspective of the caller:
|
53
|
+
# rescue/reraise in send_sync?
|
54
|
+
assert_match(/Cannot send nil/, e.to_s)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|