right_develop 1.2.0 → 1.2.2

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