rbus 0.1.0

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