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,123 @@
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
+ require 'etc'
26
+ require 'digest/sha1'
27
+
28
+ module RBus
29
+ context "Auth" do
30
+ setup do
31
+ @transport = mock('Transport')
32
+ @transport.stub!(:sendline)
33
+ @transport.stub!(:send)
34
+ @state_machine = mock('StateMachine')
35
+ Auth::StateMachine.stub!(:new).and_return(@state_machine)
36
+ @state_machine.stub!(:authorize).and_raise(AuthException)
37
+ end
38
+ specify "should raise on nil transport" do
39
+ lambda{Auth.authorize(nil)}.should_raise AuthException
40
+ end
41
+
42
+ specify "should close socket on exception" do
43
+ @transport.should_receive(:close)
44
+ begin
45
+ Auth.authorize(@transport)
46
+ rescue AuthException
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ context "Dummy" do
53
+ setup do
54
+ @dummy = Auth::Dummy.new
55
+ end
56
+ specify "auth should reply nil, nil, :REJECTED" do
57
+ @dummy.auth.should == [nil, nil, :REJECTED]
58
+ end
59
+ specify "should not have data" do
60
+ @dummy.should_not_respond_to :data
61
+ end
62
+ end
63
+
64
+ context "EXTERNAL" do
65
+ setup do
66
+ @ex = Auth::External.new
67
+ end
68
+ specify "auth should reply EXTERNAL, UID, :OK" do
69
+ @ex.auth.should == ['EXTERNAL', Process.uid, :OK]
70
+ end
71
+ specify "should not have data" do
72
+ @ex.should_not_respond_to :data
73
+ end
74
+ end
75
+
76
+ context "DBUS_COOKIE_SHA1" do
77
+ setup do
78
+ @dbs = Auth::DBusCookieSHA1.new
79
+ end
80
+ specify "auth should reply DBUS_COOKIE_SHA1, username, :DATA" do
81
+ @dbs.auth.should == ['DBUS_COOKIE_SHA1', Etc.getlogin, :DATA]
82
+ end
83
+
84
+ specify "should respond to data" do
85
+ @dbs.should_respond_to :data
86
+ end
87
+
88
+ specify "should read cookie file and return proper digest + :OK" do
89
+ seed = rand(255) # for extra fun
90
+ id = '1157262198'
91
+ timestamp = '1173310572'
92
+ cookie = '173d01b6f806051f36daee8336a08d5754ac021ac3309e19'
93
+
94
+ File.stub!(:foreach).and_yield("#{id} #{timestamp} #{cookie}")
95
+
96
+ s_challenge = Array.new(16).map{|obj|obj=rand(255).to_s}.join
97
+ data = "org_freedesktop_general 1157262198 #{s_challenge}"
98
+
99
+ srand(seed)
100
+ c_challenge = Array.new(s_challenge.length/2).map{|obj|obj=rand(255).to_s}.join
101
+ sha = Digest::SHA1.hexdigest("#{s_challenge}:#{c_challenge}:#{cookie}")
102
+
103
+ srand(seed)
104
+ @dbs.data(data).should == ["#{c_challenge} #{sha}", :OK]
105
+ end
106
+ end
107
+
108
+ context "Auth::Command" do
109
+ specify "should decode DATA" do
110
+ data = 'Some test data'
111
+ encoded = data.unpack('H*')[0]
112
+ Auth::Command.new("DATA #{encoded}").data.should == data
113
+ end
114
+
115
+ specify "should not decode REJECTED data" do
116
+ Auth::Command.new('REJECTED EXTERNAL').data.should == 'EXTERNAL'
117
+ end
118
+
119
+ specify "should not decode OK data" do
120
+ Auth::Command.new('OK 7300ef45753074d050c8465c31cb2700').data.should == '7300ef45753074d050c8465c31cb2700'
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,178 @@
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
+ require File.dirname(__FILE__) + '/helpers/bus_mocks'
26
+
27
+ module RBus
28
+
29
+ module BusSpecHelper
30
+ def setup_mocks
31
+ @transport = mock('Transport')
32
+ @transport.stub!(:send)
33
+ @transport.stub!(:read)
34
+
35
+ @message_reader = mock('Message::Reader')
36
+ @message_reader.stub!(:read_message)
37
+ Message::Reader.stub!(:new).and_return(@message_reader)
38
+
39
+ message_loop = mock('Mainloop', :null_object => true)
40
+ #message_loop.stub!(:run).and_return(message_loop)
41
+ message_loop.stub!(:send_message)
42
+ Mainloop.stub!(:new).and_return(message_loop)
43
+
44
+ @proxy = mock('Proxy')
45
+ Bus.stub!(:get_object).and_return(@proxy)
46
+
47
+ Transport.stub!(:connect).and_return(@transport)
48
+ Auth.stub!(:authorize).and_return(fake_guid)
49
+ end
50
+
51
+ def fake_guid
52
+ "deadbeef" * 4
53
+ end
54
+ end
55
+
56
+ context "Bus" do
57
+ include BusSpecHelper
58
+ setup do
59
+ setup_mocks
60
+ @bus = Bus.new('unix:')
61
+ end
62
+
63
+ specify "should be a Bus object" do
64
+ @bus.should_be_an_instance_of(Bus)
65
+ end
66
+
67
+ specify "should respond to get_object" do
68
+ @bus.should_respond_to :get_object
69
+ end
70
+
71
+ specify "should barf on empty address" do
72
+ lambda{Bus.new('')}.should_raise InvalidAddressException
73
+ end
74
+
75
+ end
76
+
77
+ context "Bus address splitting" do
78
+ include BusSpecHelper
79
+ setup do
80
+ setup_mocks
81
+ end
82
+
83
+ specify "should handle multiple separated by ;" do
84
+ Transport.should_receive(:connect).twice.with(/test/).and_return(@transport)
85
+ @bus = MockBus.new('test;test2')
86
+ end
87
+ end
88
+
89
+ context "Session bus" do
90
+ include BusSpecHelper
91
+ setup do
92
+ setup_mocks
93
+ @bus = RBus.session_bus
94
+ end
95
+
96
+ specify "should be a Bus object" do
97
+ @bus.should_be_a_kind_of(Bus)
98
+ end
99
+
100
+ specify "should be a singleton" do
101
+ @bus.should == (RBus.session_bus)
102
+ end
103
+
104
+ specify "should be a SessionBus object" do
105
+ @bus.should_be_an_instance_of(SessionBus)
106
+ end
107
+
108
+ end
109
+
110
+ context "Session bus when instanciated" do
111
+ include BusSpecHelper
112
+
113
+ setup do
114
+ setup_mocks
115
+ end
116
+
117
+ specify "should use ENV variable if exists" do
118
+ ENV['DBUS_SESSION_BUS_ADDRESS'] = 'test'
119
+ Transport.should_receive(:connect).once.with('test').and_return(@transport)
120
+ @bus = MockSessionBus.new
121
+ end
122
+
123
+ =begin TODO
124
+ The address of the login session message bus is given in the DBUS_SESSION_BUS_ADDRESS environment variable. If that
125
+ variable is not set, applications may also try to read the address from the X Window System root window property
126
+ _DBUS_SESSION_BUS_ADDRESS. The root window property must have type STRING. The environment variable should have
127
+ precedence over the root window property.
128
+
129
+ $ xprop -root _DBUS_SESSION_BUS_ADDRESS
130
+ --> _DBUS_SESSION_BUS_ADDRESS(STRING) = "somethingsomething"
131
+ =end
132
+
133
+ end
134
+
135
+
136
+
137
+ context "System bus" do
138
+ include BusSpecHelper
139
+ setup do
140
+ setup_mocks
141
+ @bus = RBus.system_bus
142
+ end
143
+
144
+ specify "should be a Bus object" do
145
+ @bus.should_be_a_kind_of(Bus)
146
+ end
147
+
148
+ specify "should be a singleton" do
149
+ @bus.should == (RBus.system_bus)
150
+ end
151
+
152
+ specify "should be a SystemBus object" do
153
+ @bus.should_be_an_instance_of(SystemBus)
154
+ end
155
+
156
+ end
157
+
158
+ context "System bus when instanciated" do
159
+ include BusSpecHelper
160
+
161
+ setup do
162
+ setup_mocks
163
+ end
164
+
165
+ specify "should use ENV variable if exists" do
166
+ ENV['DBUS_SYSTEM_BUS_ADDRESS'] = 'test'
167
+ Transport.should_receive(:connect).once.with('test').and_return(@transport)
168
+ @bus = MockSystemBus.new
169
+ end
170
+
171
+ specify "should use well-known address if no ENV" do
172
+ ENV.delete('DBUS_SYSTEM_BUS_ADDRESS')
173
+ Transport.should_receive(:connect).once.with('unix:path=/var/run/dbus/system_bus_socket').and_return(@transport)
174
+ @bus = MockSystemBus.new
175
+ end
176
+
177
+ end
178
+ end
@@ -0,0 +1,64 @@
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
+ # Mock object of the generic Bus to test parsing
25
+ class MockBus < RBus::Bus
26
+ attr_reader :addresses
27
+
28
+ def initialize(server_address)
29
+ @addresses = []
30
+ super
31
+ end
32
+
33
+ def parse_address(address)
34
+ @addresses << address
35
+ end
36
+ end
37
+
38
+ # Mock objects of the system and session buses in order
39
+ # to be able to test Singletons
40
+
41
+ class MockSystemBus < RBus::SystemBus
42
+
43
+ def self.new
44
+ new_object = self.allocate
45
+ new_object.initialize
46
+ new_object
47
+ end
48
+ public_class_method :allocate
49
+ public :initialize
50
+
51
+ end
52
+
53
+ class MockSessionBus < RBus::SessionBus
54
+
55
+ def self.new
56
+ new_object = self.allocate
57
+ new_object.initialize
58
+ new_object
59
+ end
60
+ public_class_method :allocate
61
+ public :initialize
62
+
63
+ end
64
+
@@ -0,0 +1,24 @@
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.join(File.dirname(__FILE__), '..', '..', 'lib', 'rbus')
@@ -0,0 +1,74 @@
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
+ module Message
28
+ context "MainlLoop" do
29
+ setup do
30
+ @transport = mock('Transport')
31
+ @transport.stub!(:send)
32
+ @transport.stub!(:read)
33
+
34
+ @message = mock('Message', :null_object => true)
35
+ @message.stub!(:serial).and_return(1)
36
+ @message.stub!(:message).and_return("string")
37
+
38
+ @message.stub!(:destination).and_return(":1.31")
39
+ Bus::NAMES[0] = ':1.31'
40
+
41
+ @message_reader = mock('Message::Reader', :null_object => true)
42
+ @message_reader.stub!(:read_message).and_return(@message)
43
+ Reader.stub!(:new).and_return(@message_reader)
44
+
45
+ @message_writer = mock('Message::Writer')
46
+ @message_writer.stub!(:send_message)
47
+ Writer::stub!(:new).and_return(@message_writer)
48
+
49
+ @message_loop = Mainloop.new(@transport)
50
+
51
+ Thread.abort_on_exception = true
52
+ end
53
+
54
+ specify "should be instance of Mainloop" do
55
+ @message_loop.should_be_an_instance_of(Mainloop)
56
+ end
57
+
58
+ specify "should receive reply in sync" do
59
+ @message_loop.send_message(@message).should == @message
60
+ end
61
+
62
+ specify "should receive reply in async" do
63
+ callback = mock('Proc')
64
+ callback.should_receive(:call).with(@message)
65
+ @message_loop.send_message(@message, callback)
66
+ end
67
+
68
+ teardown do
69
+ Thread.abort_on_exception = false
70
+ end
71
+ end
72
+
73
+ end
74
+ end