right_develop 1.2.0 → 1.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.
@@ -1,96 +0,0 @@
1
- Given /^a serializer named '(.+)'$/ do |klass|
2
- @serializer = klass.to_const
3
- end
4
-
5
- Given /^a stateful Ruby class named '(.*)'$/ do |name|
6
- name = name.to_sym
7
- ivars = 1 + rand(10)
8
-
9
-
10
- Kernel.__send__(:remove_const, name) if Kernel.const_defined?(name)
11
-
12
- @stateful_ruby_class = Class.new(Object)
13
- Kernel.__send__(:const_set, name, @stateful_ruby_class)
14
-
15
- @stateful_ruby_class.instance_eval do
16
- define_method(:initialize) do
17
- ivars.times do
18
- self.instance_variable_set("@instance_variable_#{random_value(Integer)}", random_value(nil, [String]))
19
- end
20
- end
21
-
22
- define_method(:==) do |other|
23
- result = (Set.new(self.instance_variables) == Set.new(other.instance_variables))
24
-
25
- self.instance_variables.each do |ivar|
26
- result &&= (self.instance_variable_get(ivar) == other.instance_variable_get(ivar))
27
- end
28
-
29
- result
30
- end
31
- end
32
- end
33
-
34
- When /^I serialize the Ruby value: (.*)$/ do |expression|
35
- @ruby_value = eval(expression)
36
- @serialized_value = @serializer.dump(@ruby_value)
37
- end
38
-
39
- When /^I serialize a complex random data structure$/ do
40
- @ruby_value = random_value(nil, [String])
41
- @serialized_value = @serializer.dump(@ruby_value)
42
- end
43
-
44
- When /^an eldritch force deletes a key from the serialized value$/ do
45
- hash = RightDevelop::Data::Serializer::Encoder.load(@serialized_value)
46
- hash.delete(hash.keys[rand(hash.keys.size)])
47
- @serialized_value = @serializer.dump(hash)
48
- end
49
-
50
- Then /^the serialized value should be: (.*)$/ do |expression|
51
- if (@serialized_value =~ /^\{/) || (expression =~ /^\{/)
52
- # Hash: ordering of JSON representation is unimportant; load as pure JSON and compare values
53
- RightDevelop::Data::Serializer::Encoder.load(@serialized_value).should ==
54
- RightDevelop::Data::Serializer::Encoder.load(expression)
55
- else
56
- # Any other data: exact comparison
57
- @serialized_value.should == expression
58
- end
59
- end
60
-
61
- Then /^the serialized value should round-trip cleanly$/ do
62
- case @ruby_value
63
- when Float
64
- # Floating-point numbers lose some precision due to truncation
65
- @serializer.load(@serialized_value).should be_within(0.000001).of(@ruby_value)
66
- when Time
67
- # Times are stored with accuracy ~ 1 sec
68
- @serializer.load(@serialized_value).to_i.should == @ruby_value.to_i
69
- else
70
- # Everything else should compare identical
71
- @serializer.load(@serialized_value).should == @ruby_value
72
- end
73
- end
74
-
75
- When /^the serialized value should fail to round\-trip$/ do
76
- @serializer.load(@serialized_value).should_not == @ruby_value
77
- end
78
-
79
- Then /^the serialized value should be a JSON (.*)$/ do |json_type|
80
- case json_type
81
- when 'object'
82
- @serialized_value.should =~ /^\{.*\}$/
83
- when 'string'
84
- @serialized_value.should =~ /^".*"$/
85
- when 'number'
86
- @serialized_value.should =~ /^".*"$/
87
- when 'true', 'false', 'null'
88
- @serialized_value.should == json_type
89
- else
90
- raise NotImplementedError, "Unknown JSON type"
91
- end
92
- end
93
-
94
- Then /^the serialized value should have a suitable _ruby_class/ do
95
- @serialized_value.should =~ /"_ruby_class":"#{Regexp.escape(@ruby_value.class.name)}"/
96
- end
@@ -1,134 +0,0 @@
1
- #-- -*- mode: ruby; encoding: utf-8 -*-
2
- # Copyright: Copyright (c) 2011 RightScale, Inc.
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # 'Software'), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
- # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
- # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
- # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
- # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
-
24
- require 'webrick'
25
- require 'webrick/httpservlet'
26
-
27
- # Mimic a generic HTTP server with various configurable behaviors
28
- class MockServer < WEBrick::HTTPServer
29
- attr_accessor :thread, :port, :url
30
-
31
- # Overridden factory method that will tolerate Errno::EADDRINUSE in case a certain
32
- # TCP port is already used
33
- def self.new(*args)
34
- tries ||= 0
35
- super
36
- rescue Errno::EADDRINUSE => e
37
- tries += 1
38
- if tries > 5
39
- raise
40
- else
41
- retry
42
- end
43
- end
44
-
45
- def initialize(options={})
46
- @port = options[:port] || (4096 + rand(32768-4096))
47
- @url = "http://localhost:#{@port}"
48
-
49
- logger = WEBrick::Log.new(STDERR, WEBrick::Log::FATAL)
50
- super(options.merge(:Port => @port, :AccessLog => [], :Logger=>logger))
51
-
52
- # mount servlets via callback
53
- yield(self)
54
-
55
- #Start listening for HTTP in a separate thread
56
- @thread = Thread.new do
57
- self.start()
58
- end
59
- end
60
- end
61
-
62
- # Mimic a server that exists but hangs without providing any response, not even
63
- # ICMP signals e.g. host unreachable or network unreachable. We simulate this
64
- # by pointing at a port of the RightScale (my) load balancer that is not allowed
65
- # by the security group, which causes the TCP SYN packets to be dropped with no
66
- # acknowledgement.
67
- class BlackholedServer
68
- attr_accessor :port, :url
69
-
70
- def initialize(options={})
71
- @port = options[:port] || (4096 + rand(4096))
72
- @url = "my.rightscale.com:#{@port}"
73
- end
74
- end
75
-
76
- Before do
77
- @mock_servers = []
78
- end
79
-
80
- # Kill running reposes after test finishes.
81
- After do
82
- @mock_servers.each do |server|
83
- if server.is_a?(MockServer)
84
- server.thread.kill
85
- end
86
- end
87
- end
88
-
89
- Given /^(an?|\d+)? (overloaded|blackholed) servers?$/ do |number, behavior|
90
- number = 0 if number =~ /no/
91
- number = 1 if number =~ /an?/
92
- number = number.to_i
93
-
94
- number.times do
95
- case behavior
96
- when 'overloaded'
97
- proc = Proc.new do
98
- sleep(10)
99
- 'Hi there! I am overloaded.'
100
- end
101
- server = MockServer.new do |s|
102
- s.mount('/', WEBrick::HTTPServlet::ProcHandler.new(proc))
103
- end
104
- when 'blackholed'
105
- server = BlackholedServer.new()
106
- else
107
- raise ArgumentError, "Unknown server behavior #{behavior}"
108
- end
109
-
110
- @mock_servers << server
111
- end
112
- end
113
-
114
- Given /^(an?|\d+)? servers? that responds? with ([0-9]+)$/ do |number, status_code|
115
- number = 0 if number =~ /no/
116
- number = 1 if number =~ /an?/
117
- number = number.to_i
118
-
119
- status_code = status_code.to_i
120
-
121
- proc = Proc.new do
122
- klass = WEBrick::HTTPStatus::CodeToError[status_code]
123
- klass.should_not be_nil
124
- raise klass, "Simulated #{status_code} response"
125
- end
126
-
127
- number.times do
128
- server = MockServer.new do |s|
129
- s.mount('/', WEBrick::HTTPServlet::ProcHandler.new(proc))
130
- end
131
-
132
- @mock_servers << server
133
- end
134
- end
@@ -1,84 +0,0 @@
1
- #--
2
- # Copyright: Copyright (c) 2010- RightScale, Inc.
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # 'Software'), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
- # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
- # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
- # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
- # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
-
24
- require 'tmpdir'
25
-
26
- require 'rubygems'
27
- require 'bundler/setup'
28
-
29
- require 'right_develop'
30
-
31
- module RubyAppHelper
32
- def ruby_app_root
33
- @ruby_app_root ||= Dir.mktmpdir('right_develop_cucumber_ruby')
34
- end
35
-
36
- def ruby_app_path(*args)
37
- path = ruby_app_root
38
- until args.empty?
39
- item = args.shift
40
- path = File.join(path, item)
41
- end
42
- path
43
- end
44
-
45
- # Run a shell command in app_dir, e.g. a rake task
46
- def ruby_app_shell(cmd, options={})
47
- ignore_errors = options[:ignore_errors] || false
48
- log = !!(Cucumber.logger)
49
-
50
- all_output = ''
51
- Dir.chdir(ruby_app_root) do
52
- Cucumber.logger.debug("bash> #{cmd}\n") if log
53
- Bundler.with_clean_env do
54
- IO.popen("#{cmd} 2>&1", 'r') do |output|
55
- output.sync = true
56
- done = false
57
- until done
58
- begin
59
- line = output.readline + "\n"
60
- all_output << line
61
- Cucumber.logger.debug(line) if log
62
- rescue EOFError
63
- done = true
64
- end
65
- end
66
- end
67
- end
68
- end
69
-
70
- $?.success?.should(be_true) unless ignore_errors
71
- all_output
72
- end
73
- end
74
-
75
- module RightDevelopWorld
76
- include RubyAppHelper
77
- end
78
-
79
- # The Cucumber world
80
- World(RightDevelopWorld)
81
-
82
- After do
83
- FileUtils.rm_rf(ruby_app_root) if File.directory?(ruby_app_root)
84
- end
@@ -1,45 +0,0 @@
1
- # Copyright (c) 2012- RightScale Inc
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining
4
- # a copy of this software and associated documentation files (the
5
- # "Software"), to deal in the Software without restriction, including
6
- # without limitation the rights to use, copy, modify, merge, publish,
7
- # distribute, sublicense, and/or sell copies of the Software, and to
8
- # permit persons to whom the Software is furnished to do so, subject to
9
- # the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be
12
- # included in all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
-
22
- # Magic hooks that is necessary due to Bundler/RVM craziness interfering with
23
- # our own Cucumbers. This is necessary because our Cucumber scenarios need to create a
24
- # Ruby app that has a distinct, separate bundle from right_develop's own Gemfile, e.g. we
25
- # need to test what happens when RSpec or Cucumber isn't available. Therefore the subprocesses
26
- # that RightDevelop's Cucumber suite launches, should not inherit our bundle.
27
- module FileUtilsBundlerMixin
28
- def self.included(base)
29
- if base.respond_to?(:sh) && !base.respond_to?(:sh_without_bundler_taint)
30
- base.instance_eval {
31
- alias_method :sh_without_bundler_taint, :sh
32
- alias_method :sh, :sh_with_bundler_taint
33
- }
34
- end
35
- end
36
-
37
- def sh_with_bundler_taint(*params)
38
- Bundler.with_clean_env do
39
- sh_without_bundler_taint(*params)
40
- end
41
- end
42
- end
43
-
44
- # Install the magic hook.
45
- Kernel.instance_eval { include(::FileUtilsBundlerMixin) }
@@ -1,202 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper.rb')
2
-
3
- describe "xml parser" do
4
- it "BaseHelper.xml_post_process_1_5 for root hash formatted xml" do
5
- expected_hash = {
6
- "farms"=>nil,
7
- "animals"=>[
8
- {"species"=>"chicken", "type"=>'bird'},
9
- {"species"=>"chicken", "type"=>'bird'},
10
- {"species"=>"horse", "type"=>'mammal'},
11
- {"species"=>"cow", "type"=>'mammal'},
12
- {"species"=>"bull", "type"=>'mammal'},
13
- {"species"=>"rooster", "type"=>'bird'},
14
- {"species"=>"camel","type"=>'mammal'},
15
- {"species"=>"sheep", "type"=>'mammal'},
16
- {"species"=>"wolf", "type"=>'mammal'},
17
- ]
18
- }
19
- session_index_1_5_xml = %@<?xml version="1.0" encoding="UTF-8"?>
20
- <session>
21
- <farms></farms>
22
- <animals>
23
- <animal species="chicken" type='bird'/>
24
- <animal species="chicken" type='bird'/>
25
- <animal species="horse" type='mammal'/>
26
- <animal species="cow" type='mammal'/>
27
- <animal species="bull" type='mammal'/>
28
- <animal species="rooster" type='bird'/>
29
- <animal species="camel" type='mammal'/>
30
- <animal species="sheep" type='mammal'/>
31
- <animal species="wolf" type='mammal'/>
32
- </animals>
33
- </session>
34
- @
35
- RightDevelop::Parsers::SaxParser.parse(session_index_1_5_xml,
36
- :post_parser => lambda { |xml| RightDevelop::Parsers::XmlPostParser.remove_nesting(xml) } ).should == expected_hash
37
- end
38
-
39
- it "BaseHelper.xml_post_process_1_5 for root array formatted xml" do
40
- expected_array = [
41
- {
42
- 'farms'=>[{'name'=>'chicken farm'}],
43
- 'farmers'=>[
44
- {'name'=>'John', 'specialty'=>'harvesting'},
45
- {'name'=>'Bill', 'specialty'=>'eggs'},
46
- {'name'=>'Bob', 'specialty'=>'milk'},
47
- {'name'=>'Joe', 'specialty'=>'butchering'}
48
- ],
49
- 'description'=>'animal farms',
50
- },
51
- {
52
- 'farms'=>[{'name'=>'wheat farm'},{'name'=>'corn farm'}],
53
- 'farmers'=>[
54
- {'name'=>'May', 'specialty'=>'milling'},
55
- {'name'=>'Mike', 'specialty'=>'corn'},
56
- {'name'=>'Will', 'specialty'=>'harvesting'},
57
- {'name'=>'Moe', 'specialty'=>'sowing'}
58
- ],
59
- 'description'=>'vegetable farms',
60
- }
61
- ]
62
- servers_index_1_5_xml = %@<?xml version='1.0' encoding='UTF-8'?>
63
- <farm_clusters>
64
- <farm_cluster>
65
- <farms>
66
- <farm name='chicken farm'/>
67
- </farms>
68
- <farmers>
69
- <farmer name='John' specialty='harvesting'/>
70
- <farmer name='Bill' specialty='eggs'/>
71
- <farmer name='Bob' specialty='milk'/>
72
- <farmer name='Joe' specialty='butchering'/>
73
- </farmers>
74
- <description>animal farms</description>
75
- </farm_cluster>
76
- <farm_cluster>
77
- <farms>
78
- <farm name='wheat farm'/>
79
- <farm name='corn farm'/>
80
- </farms>
81
- <farmers>
82
- <farmer name='May' specialty='milling'/>
83
- <farmer name='Mike' specialty='corn'/>
84
- <farmer name='Will' specialty='harvesting'/>
85
- <farmer name='Moe' specialty='sowing'/>
86
- </farmers>
87
- <description>vegetable farms</description>
88
- </farm_cluster>
89
- </farm_clusters>
90
- @
91
- RightDevelop::Parsers::SaxParser.parse(servers_index_1_5_xml,
92
- :post_parser => lambda { |xml| RightDevelop::Parsers::XmlPostParser.remove_nesting(xml) } ).should == expected_array
93
- end
94
-
95
- it "BaseHelper.xml_post_process_1_5 for node with empty text string" do
96
- expected_array = [
97
- {
98
- 'farms'=>[{'name'=>'server farm'}],
99
- 'description'=>'big time computing'
100
- },
101
- {
102
- 'farms'=>[{'name'=>'unlisted farm'}],
103
- 'description'=>nil
104
- }
105
- ]
106
- servers_index_1_5_xml = %@<?xml version='1.0' encoding='UTF-8'?>
107
- <farm_clusters>
108
- <farm_cluster>
109
- <farms>
110
- <farm name='server farm'/>
111
- </farms>
112
- <description>big time computing</description>
113
- </farm_cluster>
114
- <farm_cluster>
115
- <farms>
116
- <farm name='unlisted farm'/>
117
- </farms>
118
- <description></description>
119
- </farm_cluster>
120
- </farm_clusters>
121
- @
122
- RightDevelop::Parsers::SaxParser.parse(servers_index_1_5_xml,
123
- :post_parser => lambda { |xml| RightDevelop::Parsers::XmlPostParser.remove_nesting(xml) } ).should == expected_array
124
- end
125
-
126
- it "BaseHelper.xml_post_process_1_5 custom multiple nested xml" do
127
-
128
- expected_array = [{
129
- "parents"=>[{
130
- "children"=> ["Bob", "Mike"]
131
- }, {
132
- "children"=> ["Bob", "Mike"]
133
- }, {
134
- "children"=> ["Bob", "Mike"]
135
- }
136
- ]
137
- }, {
138
- "parents"=>[{
139
- "children"=> ["Bob", "Mike"]
140
- }, {
141
- "children"=> ["Bob", "Mike"]
142
- }, {
143
- "children"=> ["Bob", "Mike"]
144
- }
145
- ]
146
- }
147
- ]
148
-
149
- custom_nested_xml = %@<?xml version="1.0" encoding="UTF-8"?>
150
- <ancestors>
151
- <ancestor>
152
- <parents>
153
- <parent>
154
- <children>
155
- <child>Bob</child>
156
- <child>Mike</child>
157
- </children>
158
- </parent>
159
- <parent>
160
- <children>
161
- <child>Bob</child>
162
- <child>Mike</child>
163
- </children>
164
- </parent>
165
- <parent>
166
- <children>
167
- <child>Bob</child>
168
- <child>Mike</child>
169
- </children>
170
- </parent>
171
- </parents>
172
- </ancestor>
173
- <ancestor>
174
- <parents>
175
- <parent>
176
- <children>
177
- <child>Bob</child>
178
- <child>Mike</child>
179
- </children>
180
- </parent>
181
- <parent>
182
- <children>
183
- <child>Bob</child>
184
- <child>Mike</child>
185
- </children>
186
- </parent>
187
- <parent>
188
- <children>
189
- <child>Bob</child>
190
- <child>Mike</child>
191
- </children>
192
- </parent>
193
- </parents>
194
- </ancestor>
195
- </ancestors>
196
- @
197
-
198
- RightDevelop::Parsers::SaxParser.parse(custom_nested_xml,
199
- :post_parser => lambda { |xml| RightDevelop::Parsers::XmlPostParser.remove_nesting(xml) } ).should == expected_array
200
- end
201
-
202
- end
data/spec/spec_helper.rb DELETED
@@ -1,28 +0,0 @@
1
- # Copyright (c) 2012- RightScale Inc
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining
4
- # a copy of this software and associated documentation files (the
5
- # "Software"), to deal in the Software without restriction, including
6
- # without limitation the rights to use, copy, modify, merge, publish,
7
- # distribute, sublicense, and/or sell copies of the Software, and to
8
- # permit persons to whom the Software is furnished to do so, subject to
9
- # the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be
12
- # included in all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
-
22
- require 'rubygems'
23
- require 'bundler/setup'
24
- require 'flexmock'
25
- require 'ruby-debug'
26
- require 'syntax'
27
-
28
- require 'right_develop'