1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require_relative "spec_helper"
SimpleCov.command_name "Service Tests" if Object.const_defined? "SimpleCov"
# find the library without external help
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
require "dbus"
PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties".freeze
class Test < DBus::Object
INTERFACE = "org.ruby.SampleInterface".freeze
def initialize(path)
super path
@read_me = "READ ME"
@read_or_write_me = "READ OR WRITE ME"
end
# Create an interface aggregating all upcoming dbus_method defines.
dbus_interface INTERFACE do
dbus_method :hello, "in name:s, in name2:s" do |name, name2|
puts "hello(#{name}, #{name2})"
end
dbus_method :test_variant, "in stuff:v" do |variant|
DBus.logger.debug variant.inspect
end
dbus_method :bounce_variant, "in stuff:v, out chaff:v" do |variant|
[variant]
end
dbus_method :variant_size, "in stuff:v, out size:u" do |variant|
[variant.size]
end
dbus_method :the_answer, "out answer:i" do
42
end
dbus_method :will_raise, "" do
raise "Handle this"
end
dbus_method :will_raise_error_failed, "" do
raise DBus.error, "failed as designed"
end
dbus_method :will_raise_name_error, "" do
"foo".frobnicate
end
dbus_method :Error, "in name:s, in description:s" do |name, description|
raise DBus.error(name), description
end
dbus_method :mirror_byte_array, "in bytes:ay, out mirrored:ay" do |bytes|
[bytes]
end
end
# closing and reopening the same interface
dbus_interface INTERFACE do
dbus_method :multibyte_string, "out string:s" do
"あいうえお"
end
dbus_method :i16_plus, "in a:n, in b:n, out result:n" do |a, b|
a + b
end
dbus_signal :SomethingJustHappened, "toto:s, tutu:u"
end
dbus_interface "org.ruby.AnotherInterface" do
dbus_method :ThatsALongMethodNameIThink do
puts "ThatsALongMethodNameIThink"
end
dbus_method :Reverse, "in instr:s, out outstr:s" do |instr|
outstr = instr.split(//).reverse.join
[outstr]
end
end
dbus_interface "org.ruby.Ticket30" do
dbus_method :Sybilla, "in choices:av, out advice:s" do |choices|
["Do #{choices[0]}"]
end
end
dbus_interface "org.ruby.Duplicates" do
dbus_method :the_answer, "out answer:i" do
[0]
end
dbus_method :interfaces, "out answer:i" do
raise "This DBus method is currently shadowed by ProxyObject#interfaces"
end
end
dbus_interface "org.ruby.Loop" do
# starts doing something long, but returns immediately
# and sends a signal when done
dbus_method :LongTaskBegin, "in delay:i" do |delay|
# FIXME: did not complain about mismatch between signature and block args
self.LongTaskStart
DBus.logger.debug "Long task began"
task = Thread.new do
DBus.logger.debug "Long task thread started (#{delay}s)"
sleep delay
DBus.logger.debug "Long task will signal end"
self.LongTaskEnd
end
task.abort_on_exception = true # protect from test case bugs
end
dbus_signal :LongTaskStart
dbus_signal :LongTaskEnd
end
# Properties:
# ReadMe:string, returns "READ ME" at first, then what WriteMe received
# WriteMe:string
# ReadOrWriteMe:string, returns "READ OR WRITE ME" at first
dbus_interface PROPERTY_INTERFACE do
dbus_method :Get, "in interface:s, in propname:s, out value:v" do |interface, propname|
unless interface == INTERFACE
raise DBus.error("org.freedesktop.DBus.Error.UnknownInterface"),
"Interface '#{interface}' not found on object '#{@path}'"
end
case propname
when "ReadMe"
[@read_me]
when "ReadOrWriteMe"
[@read_or_write_me]
when "WriteMe"
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Property '#{interface}.#{propname}' (on object '#{@path}') is not readable"
else
# what should happen for unknown properties
# plasma: InvalidArgs (propname), UnknownInterface (interface)
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Property '#{interface}.#{propname}' not found on object '#{@path}'"
end
end
dbus_method :Set, "in interface:s, in propname:s, in value:v" do |interface, propname, value|
unless interface == INTERFACE
raise DBus.error("org.freedesktop.DBus.Error.UnknownInterface"),
"Interface '#{interface}' not found on object '#{@path}'"
end
case propname
when "ReadMe"
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Property '#{interface}.#{propname}' (on object '#{@path}') is not writable"
when "ReadOrWriteMe"
@read_or_write_me = value
self.PropertiesChanged(interface, { propname => value }, [])
when "WriteMe"
@read_me = value
self.PropertiesChanged(interface, { "ReadMe" => value }, [])
else
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Property '#{interface}.#{propname}' not found on object '#{@path}'"
end
end
dbus_method :GetAll, "in interface:s, out value:a{sv}" do |interface|
unless interface == INTERFACE
raise DBus.error("org.freedesktop.DBus.Error.UnknownInterface"),
"Interface '#{interface}' not found on object '#{@path}'"
end
[
{
"ReadMe" => @read_me,
"ReadOrWriteMe" => @read_or_write_me
}
]
end
dbus_signal :PropertiesChanged, "interface:s, changed_properties:a{sv}, invalidated_properties:as"
end
end
class Derived < Test
end
class Test2 < DBus::Object
dbus_interface "org.ruby.Test2" do
dbus_method :hi, "in name:s, out greeting:s" do |name|
"Hi, #{name}!"
end
end
end
bus = DBus::SessionBus.instance
service = bus.request_service("org.ruby.service")
myobj = Test.new("/org/ruby/MyInstance")
service.export(myobj)
derived = Derived.new "/org/ruby/MyDerivedInstance"
service.export derived
test2 = Test2.new "/org/ruby/MyInstance2"
service.export test2
# introspect every other connection, Ticket #34
# (except the one that activates us - it has already emitted
# NOC by the time we run this. Therefore the test for #34 will not work
# by running t2.rb alone, one has to run t1 before it; 'rake' does it)
mr = DBus::MatchRule.new.from_s "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'"
bus.add_match(mr) do |msg|
new_unique_name = msg.params[2]
unless new_unique_name.empty?
DBus.logger.debug "RRRING #{new_unique_name}"
bus.introspect_data(new_unique_name, "/") do
# ignore the result
end
end
end
puts "listening, with ruby-#{RUBY_VERSION}"
main = DBus::Main.new
main << bus
begin
main.run
rescue SystemCallError
# the test driver will kill the bus, that's OK
end
|