rbus 0.1.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.
Files changed (59) hide show
  1. data/CHANGELOG.txt +9 -0
  2. data/COPYING.txt +341 -0
  3. data/HACKING.txt +104 -0
  4. data/Manifest.txt +58 -0
  5. data/README.txt +17 -0
  6. data/Rakefile +97 -0
  7. data/TUTORIAL.txt +303 -0
  8. data/bin/rbus-send +165 -0
  9. data/examples/async_rb_and_notify.rb +56 -0
  10. data/examples/async_rb_loop.rb +52 -0
  11. data/examples/glib_async_rb_loop.rb +57 -0
  12. data/examples/glib_rhythmbox.rb +54 -0
  13. data/examples/hal_device_info.rb +54 -0
  14. data/examples/listnames.rb +37 -0
  15. data/examples/network_manager_get_properties.rb +50 -0
  16. data/examples/notification_bubble.rb +46 -0
  17. data/examples/rhythmbox_print_playing_uri.rb +41 -0
  18. data/examples/rhythmbox_signal_print_playing.rb +54 -0
  19. data/examples/rhythmbox_start_service.rb +39 -0
  20. data/examples/rhythmbox_toggle_playing.rb +46 -0
  21. data/lib/rbus.rb +25 -0
  22. data/lib/rbus/auth/auth.rb +53 -0
  23. data/lib/rbus/auth/dbus_cookie_sha1.rb +66 -0
  24. data/lib/rbus/auth/dummy.rb +37 -0
  25. data/lib/rbus/auth/external.rb +34 -0
  26. data/lib/rbus/auth/state_machine.rb +168 -0
  27. data/lib/rbus/bus/bus.rb +101 -0
  28. data/lib/rbus/bus/proxy.rb +137 -0
  29. data/lib/rbus/bus/transport.rb +125 -0
  30. data/lib/rbus/default.rb +29 -0
  31. data/lib/rbus/etc/exception.rb +44 -0
  32. data/lib/rbus/etc/log.rb +100 -0
  33. data/lib/rbus/etc/types.rb +56 -0
  34. data/lib/rbus/etc/version.rb +34 -0
  35. data/lib/rbus/glib.rb +29 -0
  36. data/lib/rbus/mainloop/glib.rb +77 -0
  37. data/lib/rbus/mainloop/mainloop.rb +84 -0
  38. data/lib/rbus/mainloop/observers.rb +149 -0
  39. data/lib/rbus/mainloop/thread.rb +78 -0
  40. data/lib/rbus/message/constants.rb +51 -0
  41. data/lib/rbus/message/marshal.rb +139 -0
  42. data/lib/rbus/message/message.rb +110 -0
  43. data/lib/rbus/message/reader.rb +108 -0
  44. data/lib/rbus/message/serial_generator.rb +48 -0
  45. data/lib/rbus/message/unmarshal.rb +171 -0
  46. data/lib/rbus/message/writer.rb +69 -0
  47. data/setup.rb +1608 -0
  48. data/spec/auth_spec.rb +123 -0
  49. data/spec/bus_spec.rb +178 -0
  50. data/spec/helpers/bus_mocks.rb +64 -0
  51. data/spec/helpers/spec_helper.rb +24 -0
  52. data/spec/mainloop_spec.rb +74 -0
  53. data/spec/marshal_spec.rb +91 -0
  54. data/spec/message_spec.rb +61 -0
  55. data/spec/observers_spec.rb +28 -0
  56. data/spec/proxy_spec.rb +120 -0
  57. data/spec/transport_spec.rb +187 -0
  58. data/spec/unmarshal_spec.rb +186 -0
  59. metadata +118 -0
@@ -0,0 +1,91 @@
1
+ #--
2
+ #
3
+ # R-Bus is a native Ruby implementation of the D-Bus protocol.
4
+ # Copyright (C) 2007 Kristoffer Lundén (kristoffer.lunden@gmail.com)
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
20
+ # also available at http://www.gnu.org/copyleft/gpl.html.
21
+ #
22
+ #++
23
+ #
24
+ require File.dirname(__FILE__) + '/helpers/spec_helper'
25
+
26
+ class Array
27
+ include(RBus::MarshalMixin)
28
+ end
29
+
30
+ module RBus
31
+
32
+ context "Boolean" do
33
+ setup do
34
+ @true = [1].pack('I')
35
+ @false = [0].pack('I')
36
+ end
37
+
38
+ specify "should encode false" do
39
+ [false].dbus_marshal('b').should == @false
40
+ end
41
+ specify "should encode 0" do
42
+ [0].dbus_marshal('b').should == @false
43
+ end
44
+ specify "should encode true" do
45
+ [true].dbus_marshal('b').should == @true
46
+ end
47
+ specify "should encode 1" do
48
+ [1].dbus_marshal('b').should == @true
49
+ end
50
+ specify "should encode most anything 'true' as per Ruby rules" do
51
+ [rand(255), 'string'].each do |val|
52
+ [val].dbus_marshal('b').should == @true
53
+ end
54
+ end
55
+ specify "should encode nil as false as per Ruby rules" do
56
+ [nil].dbus_marshal('b').should == @false
57
+ end
58
+ end
59
+
60
+ context "Byte" do
61
+ specify "should encode byte" do
62
+ num = rand(255)
63
+ [num].dbus_marshal('y').should == [num].pack('C')
64
+ end
65
+ specify "should encode byte series" do
66
+ [1,2,3,4,5].dbus_marshal('yyyyy').should == [1,2,3,4,5].pack('C*')
67
+ end
68
+ end
69
+
70
+ context "Numbers" do
71
+ setup do
72
+ @uint16 = rand(2**16-1)
73
+ @int16 = rand(2**15-1) * [-1,1][rand(2)]
74
+ @uint32 = rand(2**32-1)
75
+ @int32 = rand(2**31-1) * [-1,1][rand(2)]
76
+ @double = rand(2**1023-1) * [-1,1][rand(2)]
77
+ end
78
+ specify "should encode uint16" do
79
+ [@uint16].dbus_marshal('q').should == [@uint16].pack('S')
80
+ end
81
+ end
82
+
83
+ context "Mixed basic types" do
84
+ setup do
85
+
86
+ end
87
+ specify "should encode bool, byte, uint32" do
88
+ [1,2,3].dbus_marshal('byu').should == [1,2,3].pack('ICxxxI')
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,61 @@
1
+ #--
2
+ #
3
+ # R-Bus is a native Ruby implementation of the D-Bus protocol.
4
+ # Copyright (C) 2007 Kristoffer Lundén (kristoffer.lunden@gmail.com)
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
20
+ # also available at http://www.gnu.org/copyleft/gpl.html.
21
+ #
22
+ #++
23
+ #
24
+ require File.dirname(__FILE__) + '/helpers/spec_helper'
25
+
26
+ module RBus
27
+ context "Message::Base" do
28
+ setup do
29
+ Message::SerialGenerator.stub!(:get_unique).and_return(1)
30
+ @message = Message::Base.new
31
+ end
32
+
33
+ specify "should be a Message object" do
34
+ @message.should_be_instance_of(Message::Base)
35
+ end
36
+ end
37
+
38
+ context "Message::SerialGenerator" do
39
+ setup do
40
+ @serials = Array.new(42).map!{Message::SerialGenerator.get_unique}
41
+ end
42
+ specify "single-threaded should give an ordered series" do
43
+ @serials.sort.should == @serials
44
+ end
45
+ specify "single-threaded should give unique values" do
46
+ @serials.uniq.should == @serials
47
+ end
48
+ specify "multi-threaded should still give all unique values" do
49
+ threads = []
50
+ serials = []
51
+ 1337.times do
52
+ threads << Thread.new do
53
+ select(nil,nil,nil,rand)
54
+ serials << Message::SerialGenerator.get_unique
55
+ end
56
+ end
57
+ threads.each {|thr| thr.join }
58
+ serials.uniq.should == serials
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,28 @@
1
+ #--
2
+ #
3
+ # R-Bus is a native Ruby implementation of the D-Bus protocol.
4
+ # Copyright (C) 2007 Kristoffer Lundén (kristoffer.lunden@gmail.com)
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
20
+ # also available at http://www.gnu.org/copyleft/gpl.html.
21
+ #
22
+ #++
23
+ #
24
+ module RBus
25
+ module Message
26
+
27
+ end
28
+ end
@@ -0,0 +1,120 @@
1
+ #--
2
+ #
3
+ # R-Bus is a native Ruby implementation of the D-Bus protocol.
4
+ # Copyright (C) 2007 Kristoffer Lundén (kristoffer.lunden@gmail.com)
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
20
+ # also available at http://www.gnu.org/copyleft/gpl.html.
21
+ #
22
+ #++
23
+ #
24
+ require File.dirname(__FILE__) + '/helpers/spec_helper'
25
+
26
+ module RBus
27
+
28
+ context "Proxy" do
29
+ setup do
30
+ @well_known_name = 'org.rubyforge.rbus'
31
+ @object_path = '/org/rubyforge/rbus'
32
+ @message_loop = mock('MessageLoop')
33
+ @message_loop.stub!(:send_message)
34
+ @bus = mock('Bus')
35
+ @bus.stub!(:message_loop).and_return(@message_loop)
36
+ @proxy = Proxy.new(@bus, @well_known_name, @object_path)
37
+ end
38
+
39
+ specify "should send Hello message" do
40
+ @message_loop.should_receive(:send_message) {|m,b|
41
+ m.should_be_an_instance_of(MethodCall)
42
+ m.member.should == 'Hello'
43
+ b.should == nil
44
+ }
45
+ @proxy.Hello()
46
+ end
47
+
48
+ specify "should send message with arg == string" do
49
+ @message_loop.should_receive(:send_message) {|m,b|
50
+ m.should_be_an_instance_of(MethodCall)
51
+ m.member.should == 'Hola'
52
+ m.arguments.should == ['a string']
53
+ b.should == nil
54
+ }
55
+ @proxy.Hola('a string')
56
+ end
57
+
58
+ specify "should send message with multiple args" do
59
+ @message_loop.should_receive(:send_message) {|m,b|
60
+ m.should_be_an_instance_of(MethodCall)
61
+ m.member.should == 'Hola'
62
+ m.arguments.should == ['a string',2,3,[2,3]]
63
+ b.should == nil
64
+ }
65
+ @proxy.Hola('a string', 2,3,[2,3])
66
+ end
67
+
68
+ specify "should send Hello message with async block" do
69
+ @message_loop.should_receive(:send_message) {|m,b|
70
+ m.should_be_an_instance_of(MethodCall)
71
+ m.member.should == 'Hello'
72
+ b.call('Reverse').should == 'esreveR'
73
+ }
74
+ @proxy.Hello() {|v|v.reverse}
75
+ end
76
+
77
+ specify "should send message with arg == string and async block" do
78
+ @message_loop.should_receive(:send_message) {|m,b|
79
+ m.should_be_an_instance_of(MethodCall)
80
+ m.member.should == 'Hola'
81
+ m.arguments.should == ['a string']
82
+ b.call('Reverse').should == 'esreveR'
83
+ }
84
+ @proxy.Hola('a string') {|v|v.reverse}
85
+ end
86
+
87
+ specify "should send Hello message with interface" do
88
+ @message_loop.should_receive(:send_message) {|m,b|
89
+ m.should_be_an_instance_of(MethodCall)
90
+ m.member.should == 'Hello'
91
+ m.interface.should == 'org.freedesktop.dbus.Hello'
92
+ b.should == nil
93
+ }
94
+ @proxy.interface!('org.freedesktop.dbus.Hello').Hello()
95
+ end
96
+
97
+ specify "should send Hello message with interface and async block" do
98
+ @message_loop.should_receive(:send_message) {|m,b|
99
+ m.should_be_an_instance_of(MethodCall)
100
+ m.member.should == 'Hello'
101
+ m.interface.should == 'org.freedesktop.dbus.Hello'
102
+ b.call('Reverse').should == 'esreveR'
103
+ }
104
+ @proxy.interface!('org.freedesktop.dbus.Hello').Hello() {|v|v.reverse}
105
+ end
106
+
107
+ specify "should raise on illegal method name (?)" do
108
+ lambda{@proxy.illegal?}.should_raise(InvalidNameException)
109
+ end
110
+
111
+ specify "should raise on illegal method name (!)" do
112
+ lambda{@proxy.illegal!}.should_raise(InvalidNameException)
113
+ end
114
+
115
+ specify "should raise on too long name (>255)" do
116
+ lambda{@proxy.abcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijkabcdefghijk}.should_raise(InvalidNameException)
117
+ end
118
+
119
+ end
120
+ end
@@ -0,0 +1,187 @@
1
+ #--
2
+ #
3
+ # R-Bus is a native Ruby implementation of the D-Bus protocol.
4
+ # Copyright (C) 2007 Kristoffer Lundén (kristoffer.lunden@gmail.com)
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
20
+ # also available at http://www.gnu.org/copyleft/gpl.html.
21
+ #
22
+ #++
23
+ #
24
+ require File.dirname(__FILE__) + '/helpers/spec_helper'
25
+
26
+ module RBus
27
+
28
+ context "Transport.connect" do
29
+ specify "should raise on illegal transport" do
30
+ lambda{Transport.connect('illegal:and=bad')}.should_raise InvalidTransportException
31
+ end
32
+ end
33
+
34
+ context "Transport.parse_address" do
35
+ specify "should raise on address without :" do
36
+ lambda{Transport.parse_address('unix')}.should_raise InvalidAddressException
37
+ end
38
+
39
+ specify "should raise on transport without content" do
40
+ lambda{Transport.parse_address('unix:')}.should_raise InvalidAddressException
41
+ end
42
+ end
43
+
44
+ context "Transport.parse_address unix:path" do
45
+ setup do
46
+ @connection_info = Transport.parse_address('unix:path=/var/run/dbus/system_bus_socket')
47
+ end
48
+
49
+ specify "should have transport unix" do
50
+ @connection_info['transport'].should == 'unix'
51
+ end
52
+
53
+ specify "should have path" do
54
+ @connection_info['path'].should == '/var/run/dbus/system_bus_socket'
55
+ end
56
+ end
57
+
58
+ context "Transport.parse_address unix:abstract with guid" do
59
+ setup do
60
+ @connection_info =
61
+ Transport.parse_address('unix:abstract=/tmp/dbus-lafi7lJhll,guid=a190e4459a37da0c62586ac4de5fa400')
62
+ end
63
+
64
+ specify "should have transport unix" do
65
+ @connection_info['transport'].should == 'unix'
66
+ end
67
+
68
+ specify "should have abstract path" do
69
+ @connection_info['abstract'].should == '/tmp/dbus-lafi7lJhll'
70
+ end
71
+
72
+ specify "should have guid" do
73
+ @connection_info['guid'].should == 'a190e4459a37da0c62586ac4de5fa400'
74
+ end
75
+
76
+ end
77
+
78
+ context "Transport.parse_address tcp with host=ip" do
79
+ setup do
80
+ @connection_info = Transport.parse_address('tcp:host=192.168.0.1,port=6666')
81
+ end
82
+
83
+ specify "should have transport tcp" do
84
+ @connection_info['transport'].should == 'tcp'
85
+ end
86
+
87
+ specify "should have host" do
88
+ @connection_info['host'].should == '192.168.0.1'
89
+ end
90
+
91
+ specify "should have port" do
92
+ @connection_info['port'].should == '6666'
93
+ end
94
+ end
95
+
96
+ context "Transport.parse_address tcp with host=url" do
97
+ setup do
98
+ @connection_info = Transport.parse_address('tcp:host=example.com,port=8073')
99
+ end
100
+
101
+ specify "should have transport tcp" do
102
+ @connection_info['transport'].should == 'tcp'
103
+ end
104
+
105
+ specify "should have host" do
106
+ @connection_info['host'].should == 'example.com'
107
+ end
108
+
109
+ specify "should have port" do
110
+ @connection_info['port'].should == '8073'
111
+ end
112
+
113
+ end
114
+
115
+ context "Transport.unescape" do
116
+ specify "should leave non-escaped alone" do
117
+ Transport.unescape('example.com').should == 'example.com'
118
+ end
119
+
120
+ specify "should properly unescape" do
121
+ test_string = 'example.com/?test=this&key=value#anchor'
122
+ escaped = test_string.split('').map{|c|sprintf("%%%X", c[0])}.join
123
+ Transport.unescape(escaped).should == test_string
124
+ end
125
+ end
126
+
127
+ context "Abstract UNIX socket" do
128
+ setup do
129
+ @abstract_path = '/tmp/test'
130
+ @socket = mock('Socket')
131
+ @socket.stub!(:connect)
132
+ Socket.should_receive(:new).any_number_of_times.and_return(@socket)
133
+ @transport = Transport.connect("unix:abstract=#{@abstract_path}")
134
+ end
135
+
136
+ specify "should receive connect with abstract path" do
137
+ @socket.should_receive(:connect).with("\1\0\0#{@abstract_path}")
138
+ Transport.connect("unix:abstract=#{@abstract_path}")
139
+ end
140
+
141
+ specify "should take send()" do
142
+ @transport.should_receive(:send).with("\0")
143
+ @transport.send("\0")
144
+ end
145
+
146
+ specify "should take read()" do
147
+ @transport.should_receive(:read)
148
+ @transport.read
149
+ end
150
+
151
+ specify "should take sendline()" do
152
+ @transport.should_receive(:sendline).with(:string)
153
+ @transport.sendline('AUTH EXTERNAL')
154
+ end
155
+
156
+ specify "should take readline()" do
157
+ @transport.should_receive(:readline)
158
+ @transport.readline
159
+ end
160
+ end
161
+
162
+ context "Regular UNIX socket" do
163
+ setup do
164
+ @path = '/tmp/test'
165
+ @socket = mock('UNIXSocket')
166
+ end
167
+
168
+ specify "should receive connect with path" do
169
+ UNIXSocket.should_receive(:open).with(@path).and_return(@socket)
170
+ Transport.connect("unix:path=#{@path}")
171
+ end
172
+ end
173
+
174
+ context "TCP socket" do
175
+ setup do
176
+ @host = 'example.com'
177
+ @port = '6666'
178
+ @socket = mock('TCPSocket')
179
+ end
180
+
181
+ specify "should receive connect with host and port" do
182
+ TCPSocket.should_receive(:new).with(@host, @port).and_return(@socket)
183
+ Transport.connect("tcp:host=#{@host},port=#{@port}")
184
+ end
185
+ end
186
+
187
+ end