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