spqr 0.2.0 → 0.2.2
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.
- data/CHANGES +19 -1
- data/Rakefile +59 -3
- data/VERSION +1 -1
- data/bin/spqr-gen.rb +1 -1
- data/lib/spqr/app.rb +36 -16
- data/lib/spqr/codegen.rb +1 -2
- data/lib/spqr/constants.rb +1 -1
- data/lib/spqr/manageable.rb +43 -1
- data/lib/spqr/spqr.rb +1 -1
- data/lib/spqr/utils.rb +1 -1
- data/ruby-spqr.spec.in +81 -0
- data/test/example-apps.rb +74 -0
- data/test/generic-agent.rb +20 -0
- data/test/helper.rb +29 -17
- data/test/test_failbot.rb +19 -0
- data/test/test_spqr_boolprop.rb +31 -0
- metadata +9 -2
data/CHANGES
CHANGED
@@ -1,4 +1,22 @@
|
|
1
|
-
version 0.2.
|
1
|
+
version 0.2.2
|
2
|
+
|
3
|
+
* Methods on manageable objects now can call fail(status, message) to
|
4
|
+
signal failure in the QMF method response.
|
5
|
+
|
6
|
+
version 0.2.1 (f29e675e71445f63fae7e988707f07fc705c63bd)
|
7
|
+
|
8
|
+
* SPQR apps now log much less verbosely by default and allow specifying
|
9
|
+
additional log options.
|
10
|
+
|
11
|
+
* Bug fix related to boolean-valued properties and statistics.
|
12
|
+
|
13
|
+
* Changed default application (and queue) name to include the process ID.
|
14
|
+
|
15
|
+
* Manageable classes can now refer to the app object in which they
|
16
|
+
are running via the app member function. This functionality should
|
17
|
+
be considered experimental and may disappear in a future release.
|
18
|
+
|
19
|
+
version 0.2.0 (b519a04fbc148ef10e11e3b62aba15b656900278)
|
2
20
|
|
3
21
|
* SPQR and Rhubarb are now separate projects.
|
4
22
|
|
data/Rakefile
CHANGED
@@ -23,14 +23,70 @@ def pkg_version
|
|
23
23
|
return version.chomp
|
24
24
|
end
|
25
25
|
|
26
|
+
def name
|
27
|
+
return "spqr"
|
28
|
+
end
|
29
|
+
|
30
|
+
def pkg_name
|
31
|
+
return "ruby-" + name()
|
32
|
+
end
|
33
|
+
|
34
|
+
def pkg_spec
|
35
|
+
return pkg_name() + ".spec"
|
36
|
+
end
|
37
|
+
|
38
|
+
def pkg_rel
|
39
|
+
return `grep -i 'define rel' #{pkg_spec} | awk '{print $3}'`.chomp()
|
40
|
+
end
|
41
|
+
|
42
|
+
def pkg_source
|
43
|
+
return pkg_name() + "-" + pkg_version() + "-" + pkg_rel() + ".tar.gz"
|
44
|
+
end
|
45
|
+
|
46
|
+
def pkg_dir
|
47
|
+
return pkg_name() + "-" + pkg_version()
|
48
|
+
end
|
49
|
+
|
50
|
+
def rpm_dirs
|
51
|
+
return %w{BUILD BUILDROOT RPMS SOURCES SPECS SRPMS}
|
52
|
+
end
|
53
|
+
|
26
54
|
desc "create an RPM spec file"
|
27
55
|
task :rpmspec => :build do
|
28
56
|
sh "gem2rpm -t spqr.spec.in -o spqr.spec pkg/spqr-#{pkg_version}.gem"
|
29
57
|
end
|
30
58
|
|
31
|
-
desc "create
|
32
|
-
task :
|
33
|
-
|
59
|
+
desc "create RPMs"
|
60
|
+
task :rpms => [:build, :tarball, :gen_spec] do
|
61
|
+
FileUtils.cp pkg_spec(), 'SPECS'
|
62
|
+
sh "rpmbuild --define=\"_topdir \${PWD}\" -ba SPECS/#{pkg_spec}"
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Generate the specfile"
|
66
|
+
task :gen_spec do
|
67
|
+
sh "cat #{pkg_spec}" + ".in" + "| sed 's/SPQR_VERSION/#{pkg_version}/' > #{pkg_spec}"
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "Create a tarball"
|
71
|
+
task :tarball => [:make_rpmdirs, :gen_spec] do
|
72
|
+
FileUtils.cp_r 'bin', pkg_dir()
|
73
|
+
FileUtils.cp_r 'lib', pkg_dir()
|
74
|
+
FileUtils.cp_r 'examples', pkg_dir()
|
75
|
+
FileUtils.cp ['LICENSE', 'README.rdoc', 'CHANGES', 'TODO', 'VERSION'], pkg_dir()
|
76
|
+
sh "tar -cf #{pkg_source} #{pkg_dir}"
|
77
|
+
FileUtils.mv pkg_source(), 'SOURCES'
|
78
|
+
end
|
79
|
+
|
80
|
+
desc "Make dirs for building RPM"
|
81
|
+
task :make_rpmdirs => :clean do
|
82
|
+
FileUtils.mkdir pkg_dir()
|
83
|
+
FileUtils.mkdir rpm_dirs()
|
84
|
+
end
|
85
|
+
|
86
|
+
desc "Cleanup after an RPM build"
|
87
|
+
task :clean do
|
88
|
+
require 'fileutils'
|
89
|
+
FileUtils.rm_r [pkg_dir(), rpm_dirs(), pkg_spec(), 'pkg', name() + ".gemspec"], :force => true
|
34
90
|
end
|
35
91
|
|
36
92
|
require 'spec/rake/spectask'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.2
|
data/bin/spqr-gen.rb
CHANGED
data/lib/spqr/app.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Application skeleton class
|
4
4
|
#
|
5
|
-
# Copyright (c) 2009 Red Hat, Inc.
|
5
|
+
# Copyright (c) 2009--2010 Red Hat, Inc.
|
6
6
|
#
|
7
7
|
# Author: William Benton (willb@redhat.com)
|
8
8
|
#
|
@@ -20,6 +20,8 @@ module SPQR
|
|
20
20
|
class App < Qmf::AgentHandler
|
21
21
|
class ClassMeta < Struct.new(:object_class, :schema_class) ; end
|
22
22
|
|
23
|
+
attr_reader :agent
|
24
|
+
|
23
25
|
def initialize(options=nil)
|
24
26
|
defaults = {:logfile=>STDERR, :loglevel=>Logger::WARN, :notifier=>nil, :server=>"localhost", :port=>5672}
|
25
27
|
|
@@ -36,7 +38,9 @@ module SPQR
|
|
36
38
|
# fix up shorthands
|
37
39
|
options[:loglevel] = loglevels[options[:loglevel]] if loglevels[options[:loglevel]]
|
38
40
|
|
39
|
-
|
41
|
+
logger_opts = ([options[:logfile]] + [options[:logoptions]]).flatten.compact
|
42
|
+
|
43
|
+
@log = Logger.new(*logger_opts)
|
40
44
|
@log.level = options[:loglevel]
|
41
45
|
|
42
46
|
@log.info("initializing SPQR app....")
|
@@ -44,13 +48,13 @@ module SPQR
|
|
44
48
|
@classes_by_name = {}
|
45
49
|
@classes_by_id = {}
|
46
50
|
@pipe = options[:notifier]
|
47
|
-
@app_name = (options[:appname] or "SPQR application")
|
51
|
+
@app_name = (options[:appname] or "SPQR application [#{Process.pid}]")
|
48
52
|
@qmf_host = options[:server]
|
49
53
|
@qmf_port = options[:port]
|
50
54
|
@qmf_sendUserId = if options.has_key?(:send_user_id)
|
51
55
|
options[:send_user_id]
|
52
56
|
else
|
53
|
-
(options.has_key?(:user)
|
57
|
+
(options.has_key?(:user) || options.has_key?(:password))
|
54
58
|
end
|
55
59
|
|
56
60
|
@qmf_user = options[:user]
|
@@ -66,7 +70,10 @@ module SPQR
|
|
66
70
|
schemaclass = schematize(klass)
|
67
71
|
|
68
72
|
klass.log = @log
|
69
|
-
|
73
|
+
|
74
|
+
@log.info("SETTING #{klass.spqr_meta.classname}.app to #{self.inspect}")
|
75
|
+
klass.app = self
|
76
|
+
|
70
77
|
@classes_by_id[klass.class_id] = klass
|
71
78
|
@classes_by_name[klass.spqr_meta.classname.to_s] = ClassMeta.new(klass, schemaclass)
|
72
79
|
end
|
@@ -79,10 +86,12 @@ module SPQR
|
|
79
86
|
|
80
87
|
def method_call(context, name, obj_id, args, user_id)
|
81
88
|
begin
|
89
|
+
status = 0
|
90
|
+
message = "OK"
|
82
91
|
class_id = obj_id.object_num_high
|
83
92
|
obj_id = obj_id.object_num_low
|
84
93
|
|
85
|
-
@log.debug "calling method: context=#{context} method=#{name} object_id=#{obj_id},
|
94
|
+
@log.debug "calling method: context=#{context} method=#{name} object_id=#{obj_id}, user=#{user_id}"
|
86
95
|
|
87
96
|
managed_object = find_object(context, class_id, obj_id)
|
88
97
|
@log.debug("managed object is #{managed_object}")
|
@@ -100,13 +109,24 @@ module SPQR
|
|
100
109
|
@log.debug("formals: #{managed_method.formals_in.inspect}")
|
101
110
|
@log.debug("actuals: #{actuals_in.inspect}")
|
102
111
|
|
103
|
-
actuals_out =
|
104
|
-
when 0 then managed_object.send(name.to_sym)
|
105
|
-
when 1 then managed_object.send(name.to_sym, actuals_in[0])
|
106
|
-
else managed_object.send(name.to_sym, *actuals_in)
|
107
|
-
end
|
112
|
+
actuals_out = []
|
108
113
|
|
109
|
-
|
114
|
+
begin
|
115
|
+
actuals_out = case actual_count
|
116
|
+
when 0 then managed_object.send(name.to_sym)
|
117
|
+
when 1 then managed_object.send(name.to_sym, actuals_in[0])
|
118
|
+
else managed_object.send(name.to_sym, *actuals_in)
|
119
|
+
end
|
120
|
+
|
121
|
+
raise RuntimeError.new("#{managed_object.class} did not return the appropriate number of return values; got '#{actuals_out.inspect}', but expected #{managed_method.types_out.inspect}") unless result_valid(actuals_out, managed_method)
|
122
|
+
|
123
|
+
rescue ::SPQR::ManageableObjectError => failure
|
124
|
+
@log.info "#{name} called SPQR::Manageable#fail: #{failure}"
|
125
|
+
status = failure.status
|
126
|
+
message = failure.message || "ERROR"
|
127
|
+
# XXX: failure.result is currently ignored by QMF
|
128
|
+
actuals_out = failure.result || managed_method.formals_out.inject([]) {|acc, val| acc << args[val]; acc}
|
129
|
+
end
|
110
130
|
|
111
131
|
if managed_method.formals_out.size == 0
|
112
132
|
actuals_out = [] # ignore return value in this case
|
@@ -125,7 +145,7 @@ module SPQR
|
|
125
145
|
args[k] = encoded_val
|
126
146
|
end
|
127
147
|
|
128
|
-
@agent.method_response(context,
|
148
|
+
@agent.method_response(context, status, message, args)
|
129
149
|
rescue Exception => ex
|
130
150
|
@log.error "Error calling #{name}: #{ex}"
|
131
151
|
@log.error " " + ex.backtrace.join("\n ")
|
@@ -136,8 +156,6 @@ module SPQR
|
|
136
156
|
def get_query(context, query, user_id)
|
137
157
|
@log.debug "query: user=#{user_id} context=#{context} class=#{query.class_name} object_num=#{query.object_id.object_num_low if query.object_id} details=#{query} haveSelect=#{query.impl and query.impl.haveSelect} getSelect=#{query.impl and query.impl.getSelect} (#{query.impl and query.impl.getSelect and query.impl.getSelect.methods.inspect})"
|
138
158
|
|
139
|
-
@log.debug "classes_by_name is #{@classes_by_name.inspect}"
|
140
|
-
|
141
159
|
cmeta = @classes_by_name[query.class_name]
|
142
160
|
objs = []
|
143
161
|
|
@@ -336,12 +354,14 @@ module SPQR
|
|
336
354
|
getter = a.name.to_s
|
337
355
|
@log.debug("setting property/statistic #{getter} to its value from #{o}: #{o.send(getter) if o.respond_to?(getter)}")
|
338
356
|
value = o.send(getter) if o.respond_to?(getter)
|
339
|
-
|
357
|
+
|
358
|
+
if value || a.kind == :bool
|
340
359
|
# XXX: remove this line when/if Manageable includes an
|
341
360
|
# appropriate impl method
|
342
361
|
value = encode_object(value) if value.kind_of?(::SPQR::Manageable)
|
343
362
|
qo[getter] = value
|
344
363
|
end
|
364
|
+
|
345
365
|
end
|
346
366
|
end
|
347
367
|
end
|
data/lib/spqr/codegen.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Code generation for SPQR
|
2
2
|
#
|
3
|
-
# Copyright (c) 2009 Red Hat, Inc.
|
3
|
+
# Copyright (c) 2009--2010 Red Hat, Inc.
|
4
4
|
#
|
5
5
|
# Author: William Benton (willb@redhat.com)
|
6
6
|
#
|
@@ -371,7 +371,6 @@ module SPQR
|
|
371
371
|
# cc is the name of the variable that will hold a collection of schema classes
|
372
372
|
def gen
|
373
373
|
with_output_to @fn do
|
374
|
-
pp "require 'rubygems'"
|
375
374
|
pp "require 'spqr/spqr'"
|
376
375
|
pp "require 'spqr/app'"
|
377
376
|
|
data/lib/spqr/constants.rb
CHANGED
data/lib/spqr/manageable.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Manageable object mixin and support classes.
|
4
4
|
#
|
5
|
-
# Copyright (c) 2009 Red Hat, Inc.
|
5
|
+
# Copyright (c) 2009--2010 Red Hat, Inc.
|
6
6
|
#
|
7
7
|
# Author: William Benton (willb@redhat.com)
|
8
8
|
#
|
@@ -13,6 +13,16 @@
|
|
13
13
|
# http://www.apache.org/licenses/LICENSE-2.0
|
14
14
|
|
15
15
|
module SPQR
|
16
|
+
class ManageableObjectError < RuntimeError
|
17
|
+
attr_accessor :status, :result
|
18
|
+
|
19
|
+
def initialize(status, message=nil, rval=nil)
|
20
|
+
super(message)
|
21
|
+
@status = status
|
22
|
+
@result = rval
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
16
26
|
class ManageableMeta < Struct.new(:classname, :package, :description, :mmethods, :options, :statistics, :properties)
|
17
27
|
def initialize(*a)
|
18
28
|
super *a
|
@@ -136,6 +146,14 @@ module SPQR
|
|
136
146
|
@spqr_log || ::SPQR::Sink.new
|
137
147
|
end
|
138
148
|
|
149
|
+
def app=(app)
|
150
|
+
@spqr_app = app
|
151
|
+
end
|
152
|
+
|
153
|
+
def app
|
154
|
+
@spqr_app
|
155
|
+
end
|
156
|
+
|
139
157
|
# Exposes a method to QMF
|
140
158
|
def expose(name, description=nil, options=nil, &blk)
|
141
159
|
spqr_meta.declare_method(name, description, options, blk)
|
@@ -203,6 +221,30 @@ module SPQR
|
|
203
221
|
end
|
204
222
|
|
205
223
|
module Manageable
|
224
|
+
# fail takes either (up to) three arguments or a hash
|
225
|
+
# the three arguments are:
|
226
|
+
# * =status= (an integer failure code)
|
227
|
+
# * =message= (a descriptive failure message, defaults to nil)
|
228
|
+
# * =result= (a value to return, defaults to nil; currently ignored by QMF)
|
229
|
+
# the hash simply maps from keys =:status=, =:message=, and =:result= to their respective values. Only =:status= is required.
|
230
|
+
def fail(*args)
|
231
|
+
unless args.size <= 3 && args.size >= 1
|
232
|
+
raise RuntimeError.new("SPQR::Manageable#fail takes at least one parameter but not more than three; received #{args.inspect}")
|
233
|
+
end
|
234
|
+
|
235
|
+
if args.size == 1 and args[0].class = Hash
|
236
|
+
failhash = args[0]
|
237
|
+
|
238
|
+
unless failhash[:status] && failhash[:status].is_a?(Fixnum)
|
239
|
+
raise RuntimeError.new("SPQR::Manageable#fail requires a Fixnum-valued :status parameter when called with keyword arguments; received #{failhash[:status].inspect}")
|
240
|
+
end
|
241
|
+
|
242
|
+
raise ManageableObjectError.new(failhash[:status], failhash[:message], failhash[:result])
|
243
|
+
end
|
244
|
+
|
245
|
+
raise ManageableObjectError.new(*args)
|
246
|
+
end
|
247
|
+
|
206
248
|
def qmf_oid
|
207
249
|
result = 0
|
208
250
|
if self.respond_to? :spqr_object_id
|
data/lib/spqr/spqr.rb
CHANGED
data/lib/spqr/utils.rb
CHANGED
data/ruby-spqr.spec.in
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
%{!?ruby_sitelib: %global ruby_sitelib %(ruby -rrbconfig -e 'puts Config::CONFIG["sitelibdir"] ')}
|
2
|
+
%define rel 1.0
|
3
|
+
|
4
|
+
Summary: SPQR: {Schema Processor|Straightforward Publishing} for QMF agents in Ruby
|
5
|
+
Name: ruby-spqr
|
6
|
+
Version: SPQR_VERSION
|
7
|
+
Release: %{rel}%{?dist}
|
8
|
+
Group: Applications/System
|
9
|
+
License: ASL 2.0
|
10
|
+
URL: http://git.fedorahosted.org/git/grid/spqr.git
|
11
|
+
Source0: %{name}-%{version}-%{rel}.tar.gz
|
12
|
+
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
13
|
+
Requires: ruby(abi) = 1.8
|
14
|
+
Requires: ruby
|
15
|
+
Requires: ruby-qmf
|
16
|
+
BuildRequires: ruby
|
17
|
+
BuildArch: noarch
|
18
|
+
|
19
|
+
%description
|
20
|
+
SPQR makes it very simple to expose methods on Ruby objects over QMF.
|
21
|
+
|
22
|
+
%package -n spqr-gen
|
23
|
+
Summary: Generates an spqr app from an xml schema
|
24
|
+
Group: Applications/System
|
25
|
+
Requires: ruby-spqr
|
26
|
+
Requires: ruby(abi) = 1.8
|
27
|
+
Requires: ruby
|
28
|
+
|
29
|
+
%description -n spqr-gen
|
30
|
+
A tool that will generate an spqr application from an xml schema file
|
31
|
+
|
32
|
+
%prep
|
33
|
+
%setup -q
|
34
|
+
|
35
|
+
%build
|
36
|
+
|
37
|
+
%install
|
38
|
+
rm -rf %{buildroot}
|
39
|
+
mkdir -p %{buildroot}/%{_bindir}
|
40
|
+
mkdir -p %{buildroot}/%{ruby_sitelib}/spqr
|
41
|
+
cp -f lib/spqr/app.rb %{buildroot}/%{ruby_sitelib}/spqr
|
42
|
+
cp -f lib/spqr/codegen.rb %{buildroot}/%{ruby_sitelib}/spqr
|
43
|
+
cp -f lib/spqr/constants.rb %{buildroot}/%{ruby_sitelib}/spqr
|
44
|
+
cp -f lib/spqr/manageable.rb %{buildroot}/%{ruby_sitelib}/spqr
|
45
|
+
cp -f lib/spqr/spqr.rb %{buildroot}/%{ruby_sitelib}/spqr
|
46
|
+
cp -f lib/spqr/utils.rb %{buildroot}/%{ruby_sitelib}/spqr
|
47
|
+
cp -f bin/spqr-gen.rb %{buildroot}/%{_bindir}
|
48
|
+
|
49
|
+
%clean
|
50
|
+
rm -rf %{buildroot}
|
51
|
+
|
52
|
+
%files
|
53
|
+
%defattr(-, root, root, -)
|
54
|
+
%doc LICENSE README.rdoc CHANGES TODO VERSION
|
55
|
+
%doc examples
|
56
|
+
%{ruby_sitelib}/spqr/app.rb
|
57
|
+
%{ruby_sitelib}/spqr/codegen.rb
|
58
|
+
%{ruby_sitelib}/spqr/constants.rb
|
59
|
+
%{ruby_sitelib}/spqr/manageable.rb
|
60
|
+
%{ruby_sitelib}/spqr/spqr.rb
|
61
|
+
%{ruby_sitelib}/spqr/utils.rb
|
62
|
+
|
63
|
+
%files -n spqr-gen
|
64
|
+
%defattr(-, root, root, -)
|
65
|
+
%doc LICENSE
|
66
|
+
%defattr(755, root, root, -)
|
67
|
+
%{_bindir}/spqr-gen.rb
|
68
|
+
|
69
|
+
%changelog
|
70
|
+
|
71
|
+
* Tue Feb 24 2010 <willb@redhat> - 0.2.1-1.0
|
72
|
+
- updated to version 0.2.1 (which is not released as a gem at the moment)
|
73
|
+
|
74
|
+
* Fri Feb 19 2010 <willb@redhat> - 0.2.0-0.3
|
75
|
+
- The SPQR application object is now exposed to managed classes
|
76
|
+
|
77
|
+
* Fri Feb 5 2010 <rrati@redhat> - 0.2.0-0.2
|
78
|
+
- Fixed packaging issues
|
79
|
+
|
80
|
+
* Tue Feb 2 2010 <rrati@redhat> - 0.2.0-0.1
|
81
|
+
- Initial package
|
data/test/example-apps.rb
CHANGED
@@ -123,4 +123,78 @@ class QmfIntegerProp
|
|
123
123
|
qmf_package_name :example
|
124
124
|
end
|
125
125
|
|
126
|
+
class QmfBoolProp
|
127
|
+
include ::SPQR::Manageable
|
128
|
+
|
129
|
+
SIZE = 7
|
130
|
+
|
131
|
+
def initialize(oid)
|
132
|
+
@int_id = oid
|
133
|
+
end
|
126
134
|
|
135
|
+
def spqr_object_id
|
136
|
+
@int_id
|
137
|
+
end
|
138
|
+
|
139
|
+
def QmfBoolProp.gen_objects(ct)
|
140
|
+
objs = []
|
141
|
+
ct.times do |x|
|
142
|
+
objs << (new(x))
|
143
|
+
end
|
144
|
+
objs
|
145
|
+
end
|
146
|
+
|
147
|
+
def QmfBoolProp.find_by_id(oid)
|
148
|
+
puts "calling QBP::find_by_id"
|
149
|
+
@qmf_bps ||= gen_objects(SIZE)
|
150
|
+
@qmf_bps[oid]
|
151
|
+
end
|
152
|
+
|
153
|
+
def QmfBoolProp.find_all
|
154
|
+
puts "calling QBP::find_all"
|
155
|
+
@qmf_bps ||= gen_objects(SIZE)
|
156
|
+
@qmf_bps
|
157
|
+
end
|
158
|
+
|
159
|
+
def is_id_even
|
160
|
+
@int_id % 2 == 0
|
161
|
+
end
|
162
|
+
|
163
|
+
qmf_property :int_id, :int, :index=>true
|
164
|
+
qmf_property :is_id_even, :bool
|
165
|
+
|
166
|
+
qmf_class_name :QmfBoolProp
|
167
|
+
qmf_package_name :example
|
168
|
+
end
|
169
|
+
|
170
|
+
class Failbot
|
171
|
+
include ::SPQR::Manageable
|
172
|
+
|
173
|
+
def Failbot.find_by_id(oid)
|
174
|
+
@failbots ||= [Failbot.new]
|
175
|
+
@failbots[0]
|
176
|
+
end
|
177
|
+
|
178
|
+
def Failbot.find_all
|
179
|
+
@failbots ||= [Failbot.new]
|
180
|
+
@failbots
|
181
|
+
end
|
182
|
+
|
183
|
+
def fail_with_no_result
|
184
|
+
fail 42, "This method should not succeed, with failure code 42"
|
185
|
+
end
|
186
|
+
|
187
|
+
expose :fail_with_no_result do |args|
|
188
|
+
end
|
189
|
+
|
190
|
+
def fail_without_expected_result
|
191
|
+
fail 17, "This method should not succeed, with failure code 17, and should return some garbage value"
|
192
|
+
end
|
193
|
+
|
194
|
+
expose :fail_without_expected_result do |args|
|
195
|
+
args.declare :result, :uint64, :out
|
196
|
+
end
|
197
|
+
|
198
|
+
qmf_package_name :example
|
199
|
+
qmf_class_name :Failbot
|
200
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
|
6
|
+
require 'spqr/spqr'
|
7
|
+
require 'spqr/app'
|
8
|
+
require 'example-apps'
|
9
|
+
|
10
|
+
klasses = ARGV.map {|klass| Kernel.const_get(klass)}
|
11
|
+
|
12
|
+
DEBUG = (::ENV["SPQR_TESTS_DEBUG"] and ::ENV["SPQR_TESTS_DEBUG"].downcase == "yes")
|
13
|
+
|
14
|
+
app = SPQR::App.new(:loglevel => (DEBUG ? :debug : :fatal), :appname=>"#{klasses.join("")}[#{Process.pid}]")
|
15
|
+
app.register *klasses
|
16
|
+
while true
|
17
|
+
app.main rescue nil
|
18
|
+
end
|
19
|
+
|
20
|
+
sleep
|
data/test/helper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'rubygems'
|
1
|
+
require 'rubygems' rescue nil
|
2
2
|
require 'test/unit'
|
3
3
|
require 'qmf'
|
4
4
|
require 'timeout'
|
@@ -23,7 +23,7 @@ module QmfTestHelpers
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def agent_added(agent)
|
26
|
-
puts "GOT AN AGENT: #{agent}" if DEBUG
|
26
|
+
puts "GOT AN AGENT: #{agent} at #{Time.now.utc}" if DEBUG
|
27
27
|
@q << agent
|
28
28
|
end
|
29
29
|
end
|
@@ -35,33 +35,45 @@ module QmfTestHelpers
|
|
35
35
|
$console = Qmf::Console.new($notify_handler)
|
36
36
|
$broker = $console.add_connection($connection)
|
37
37
|
end
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
|
39
|
+
sleep 0.5
|
40
|
+
$broker.wait_for_stable
|
41
|
+
|
41
42
|
@child_pid = fork do
|
43
|
+
sleep 0.5
|
42
44
|
unless DEBUG
|
43
45
|
# replace stdin/stdout/stderr
|
44
46
|
$stdin.reopen("/dev/null", "r")
|
45
47
|
$stdout.reopen("/dev/null", "w")
|
46
48
|
$stderr.reopen("/dev/null", "w")
|
49
|
+
else
|
50
|
+
ENV['QPID_TRACE'] = "1"
|
47
51
|
end
|
48
52
|
|
53
|
+
exec("#{File.dirname(__FILE__)}/generic-agent.rb", *classes.map {|cl| cl.to_s})
|
54
|
+
exit! 127
|
55
|
+
|
56
|
+
@app = SPQR::App.new(:loglevel => (DEBUG ? :debug : :fatal), :appname=>"#{classes.join("")}[#{Process.pid}]")
|
57
|
+
@app.register *classes
|
58
|
+
|
49
59
|
@app.main
|
50
60
|
end
|
51
61
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end until k != "1.0"
|
62
|
+
begin
|
63
|
+
Timeout.timeout(12) do
|
64
|
+
k = ""
|
65
|
+
begin
|
66
|
+
@ag = $notify_handler.queue.pop
|
67
|
+
k = @ag.key
|
68
|
+
puts "GOT A KEY: #{k} at #{Time.now.utc}" if DEBUG
|
69
|
+
end until k != "1.0"
|
61
70
|
|
62
|
-
|
63
|
-
|
64
|
-
|
71
|
+
# XXX
|
72
|
+
puts "ESCAPING FROM TIMEOUT at #{Time.now.utc}" if DEBUG
|
73
|
+
end
|
74
|
+
rescue Timeout::Error
|
75
|
+
puts "QUEUE SIZE WAS #{$notify_handler.queue.size} at #{Time.now.utc}" if DEBUG
|
76
|
+
raise
|
65
77
|
end
|
66
78
|
|
67
79
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'set'
|
3
|
+
require 'example-apps'
|
4
|
+
|
5
|
+
class TestFailbot < Test::Unit::TestCase
|
6
|
+
include QmfTestHelpers
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@child_pid = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_basic_failure
|
13
|
+
app_setup Failbot
|
14
|
+
failbot = $console.object(:class=>"Failbot", :agent=>@ag)
|
15
|
+
method_response = failbot.fail_with_no_result
|
16
|
+
assert_equal 42, method_response.status
|
17
|
+
assert_match /This method should not succeed/, method_response.text
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'set'
|
3
|
+
require 'example-apps'
|
4
|
+
|
5
|
+
class TestBoolProp < Test::Unit::TestCase
|
6
|
+
include QmfTestHelpers
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@child_pid = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_property_identities
|
13
|
+
app_setup QmfBoolProp
|
14
|
+
|
15
|
+
objs = $console.objects(:class=>"QmfBoolProp")
|
16
|
+
ids = Set.new
|
17
|
+
|
18
|
+
assert_equal QmfBoolProp::SIZE, objs.size
|
19
|
+
|
20
|
+
objs.each do |obj|
|
21
|
+
assert_equal((obj.int_id % 2 == 0), obj.is_id_even)
|
22
|
+
ids << obj[:int_id]
|
23
|
+
end
|
24
|
+
|
25
|
+
assert_equal objs.size, ids.size
|
26
|
+
|
27
|
+
objs.size.times do |x|
|
28
|
+
assert ids.include?(x), "ids should include #{x}, which is less than #{objs.size}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spqr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Benton
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-03-04 00:00:00 -06:00
|
13
13
|
default_executable: spqr-gen.rb
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -51,12 +51,16 @@ files:
|
|
51
51
|
- lib/spqr/manageable.rb
|
52
52
|
- lib/spqr/spqr.rb
|
53
53
|
- lib/spqr/utils.rb
|
54
|
+
- ruby-spqr.spec.in
|
54
55
|
- spec/spec.opts
|
55
56
|
- spec/spec_helper.rb
|
56
57
|
- spec/spqr_spec.rb
|
57
58
|
- spqr.spec.in
|
58
59
|
- test/example-apps.rb
|
60
|
+
- test/generic-agent.rb
|
59
61
|
- test/helper.rb
|
62
|
+
- test/test_failbot.rb
|
63
|
+
- test/test_spqr_boolprop.rb
|
60
64
|
- test/test_spqr_clicker.rb
|
61
65
|
- test/test_spqr_dummyprop.rb
|
62
66
|
- test/test_spqr_hello.rb
|
@@ -94,7 +98,10 @@ test_files:
|
|
94
98
|
- spec/spec_helper.rb
|
95
99
|
- test/example-apps.rb
|
96
100
|
- test/test_spqr_dummyprop.rb
|
101
|
+
- test/generic-agent.rb
|
97
102
|
- test/helper.rb
|
103
|
+
- test/test_failbot.rb
|
104
|
+
- test/test_spqr_boolprop.rb
|
98
105
|
- test/test_spqr_clicker.rb
|
99
106
|
- test/test_spqr_integerprop.rb
|
100
107
|
- test/test_spqr_hello.rb
|