openshift-origin-controller 1.3.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of openshift-origin-controller might be problematic. Click here for more details.

Files changed (180) hide show
  1. data/COPYRIGHT +1 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +12 -0
  4. data/README.md +3 -0
  5. data/Rakefile +9 -0
  6. data/app/controllers/app_events_controller.rb +115 -0
  7. data/app/controllers/application_templates_controller.rb +19 -0
  8. data/app/controllers/applications_controller.rb +214 -0
  9. data/app/controllers/base_controller.rb +367 -0
  10. data/app/controllers/cartridges_controller.rb +48 -0
  11. data/app/controllers/descriptors_controller.rb +23 -0
  12. data/app/controllers/dns_resolvable_controller.rb +35 -0
  13. data/app/controllers/domains_controller.rb +156 -0
  14. data/app/controllers/emb_cart_controller.rb +276 -0
  15. data/app/controllers/emb_cart_events_controller.rb +52 -0
  16. data/app/controllers/environment_controller.rb +11 -0
  17. data/app/controllers/estimates_controller.rb +71 -0
  18. data/app/controllers/gear_groups_controller.rb +53 -0
  19. data/app/controllers/gears_controller.rb +70 -0
  20. data/app/controllers/keys_controller.rb +96 -0
  21. data/app/controllers/legacy_broker_controller.rb +510 -0
  22. data/app/controllers/quickstarts_controller.rb +29 -0
  23. data/app/controllers/user_controller.rb +38 -0
  24. data/app/helpers/cartridge_helper.rb +25 -0
  25. data/app/helpers/legacy_broker_helper.rb +21 -0
  26. data/app/helpers/user_action_logger.rb +38 -0
  27. data/app/models/application.rb +1718 -0
  28. data/app/models/application_template.rb +27 -0
  29. data/app/models/cartridge_cache.rb +51 -0
  30. data/app/models/cloud_user.rb +334 -0
  31. data/app/models/component_instance.rb +228 -0
  32. data/app/models/connection_endpoint.rb +10 -0
  33. data/app/models/district.rb +210 -0
  34. data/app/models/domain.rb +234 -0
  35. data/app/models/gear.rb +376 -0
  36. data/app/models/group_instance.rb +306 -0
  37. data/app/models/key.rb +20 -0
  38. data/app/models/legacy_reply.rb +15 -0
  39. data/app/models/legacy_request.rb +126 -0
  40. data/app/models/link.rb +11 -0
  41. data/app/models/message.rb +10 -0
  42. data/app/models/name_server_cache.rb +46 -0
  43. data/app/models/optional_param.rb +12 -0
  44. data/app/models/param.rb +13 -0
  45. data/app/models/remote_job.rb +57 -0
  46. data/app/models/rest_application.rb +126 -0
  47. data/app/models/rest_application10.rb +106 -0
  48. data/app/models/rest_application12.rb +124 -0
  49. data/app/models/rest_application_estimate.rb +12 -0
  50. data/app/models/rest_application_template.rb +20 -0
  51. data/app/models/rest_cartridge10.rb +41 -0
  52. data/app/models/rest_cartridge11.rb +151 -0
  53. data/app/models/rest_domain.rb +43 -0
  54. data/app/models/rest_domain10.rb +42 -0
  55. data/app/models/rest_estimates.rb +16 -0
  56. data/app/models/rest_gear.rb +14 -0
  57. data/app/models/rest_gear_group.rb +26 -0
  58. data/app/models/rest_key.rb +24 -0
  59. data/app/models/rest_reply.rb +31 -0
  60. data/app/models/rest_user.rb +43 -0
  61. data/app/models/result_io.rb +67 -0
  62. data/app/models/usage_record.rb +37 -0
  63. data/app/models/validators/app_validator.rb +30 -0
  64. data/app/models/validators/key_validator.rb +30 -0
  65. data/app/models/validators/namespace_validator.rb +18 -0
  66. data/config/routes.rb +36 -0
  67. data/lib/controller_engine.rb +7 -0
  68. data/lib/openshift-origin-controller.rb +14 -0
  69. data/lib/openshift/application_container_proxy.rb +241 -0
  70. data/lib/openshift/auth_service.rb +101 -0
  71. data/lib/openshift/data_store.rb +33 -0
  72. data/lib/openshift/dns_service.rb +41 -0
  73. data/lib/openshift/mongo_data_store.rb +671 -0
  74. data/openshift-origin-controller.gemspec +42 -0
  75. data/rubygem-openshift-origin-controller.spec +274 -0
  76. data/test/cucumber/application-estimate.feature +25 -0
  77. data/test/cucumber/cartridge-10gen-mms-agent.feature +28 -0
  78. data/test/cucumber/cartridge-cron.feature +32 -0
  79. data/test/cucumber/cartridge-haproxy.feature +31 -0
  80. data/test/cucumber/cartridge-jenkins-build.feature +12 -0
  81. data/test/cucumber/cartridge-jenkins-client.feature +10 -0
  82. data/test/cucumber/cartridge-lifecycle-diy.feature +21 -0
  83. data/test/cucumber/cartridge-lifecycle-jbossas.feature +61 -0
  84. data/test/cucumber/cartridge-lifecycle-jbosseap.feature +61 -0
  85. data/test/cucumber/cartridge-lifecycle-jbossews10.feature +61 -0
  86. data/test/cucumber/cartridge-lifecycle-jenkins.feature +41 -0
  87. data/test/cucumber/cartridge-lifecycle-nodejs.feature +59 -0
  88. data/test/cucumber/cartridge-lifecycle-perl.feature +40 -0
  89. data/test/cucumber/cartridge-lifecycle-php.feature +106 -0
  90. data/test/cucumber/cartridge-lifecycle-python.feature +40 -0
  91. data/test/cucumber/cartridge-lifecycle-ruby18.feature +49 -0
  92. data/test/cucumber/cartridge-lifecycle-ruby19.feature +41 -0
  93. data/test/cucumber/cartridge-mongodb.feature +31 -0
  94. data/test/cucumber/cartridge-mysql.feature +30 -0
  95. data/test/cucumber/cartridge-php.feature +14 -0
  96. data/test/cucumber/cartridge-phpmyadmin.feature +32 -0
  97. data/test/cucumber/cartridge-postgresql.feature +32 -0
  98. data/test/cucumber/cartridge-runtime-extended-db.feature +64 -0
  99. data/test/cucumber/cartridge-runtime-extended-jboss.feature +24 -0
  100. data/test/cucumber/cartridge-runtime-extended-nodejs.feature +21 -0
  101. data/test/cucumber/cartridge-runtime-extended-perl.feature +18 -0
  102. data/test/cucumber/cartridge-runtime-extended-php.feature +19 -0
  103. data/test/cucumber/cartridge-runtime-extended-python.feature +18 -0
  104. data/test/cucumber/cartridge-runtime-extended-ruby.feature +22 -0
  105. data/test/cucumber/cartridge-runtime-standard-diy.feature +6 -0
  106. data/test/cucumber/cartridge-runtime-standard-jbossas.feature +7 -0
  107. data/test/cucumber/cartridge-runtime-standard-jbosseap.feature +7 -0
  108. data/test/cucumber/cartridge-runtime-standard-jbossews10.feature +7 -0
  109. data/test/cucumber/cartridge-runtime-standard-jenkins.feature +8 -0
  110. data/test/cucumber/cartridge-runtime-standard-nodejs.feature +7 -0
  111. data/test/cucumber/cartridge-runtime-standard-perl.feature +6 -0
  112. data/test/cucumber/cartridge-runtime-standard-php.feature +6 -0
  113. data/test/cucumber/cartridge-runtime-standard-python.feature +6 -0
  114. data/test/cucumber/cartridge-runtime-standard-ruby.feature +19 -0
  115. data/test/cucumber/cartridge-switchyard.feature +36 -0
  116. data/test/cucumber/descriptor.feature +40 -0
  117. data/test/cucumber/embedded.feature +44 -0
  118. data/test/cucumber/idler.feature +75 -0
  119. data/test/cucumber/misc/descriptor/manifest.yml +22 -0
  120. data/test/cucumber/misc/php/db_test.php +21 -0
  121. data/test/cucumber/openshift-node.feature +21 -0
  122. data/test/cucumber/rest-application-templates.feature +31 -0
  123. data/test/cucumber/rest-applications.feature +431 -0
  124. data/test/cucumber/rest-cartridge-types.feature +16 -0
  125. data/test/cucumber/rest-domains.feature +276 -0
  126. data/test/cucumber/rest-gears.feature +38 -0
  127. data/test/cucumber/rest-keys.feature +247 -0
  128. data/test/cucumber/rest-quickstarts.feature +27 -0
  129. data/test/cucumber/rest-workflow.feature +64 -0
  130. data/test/cucumber/step_definitions/api_steps.rb +369 -0
  131. data/test/cucumber/step_definitions/application-estimate-steps.rb +51 -0
  132. data/test/cucumber/step_definitions/application_steps.rb +215 -0
  133. data/test/cucumber/step_definitions/cartridge-10gen-mms-agent_steps.rb +11 -0
  134. data/test/cucumber/step_definitions/cartridge-cron_steps.rb +51 -0
  135. data/test/cucumber/step_definitions/cartridge-haproxy_steps.rb +30 -0
  136. data/test/cucumber/step_definitions/cartridge-jenkins_steps.rb +93 -0
  137. data/test/cucumber/step_definitions/cartridge-lifecycle-nodejs_steps.rb +30 -0
  138. data/test/cucumber/step_definitions/cartridge-mongodb_steps.rb +60 -0
  139. data/test/cucumber/step_definitions/cartridge-mysql_steps.rb +56 -0
  140. data/test/cucumber/step_definitions/cartridge-php_steps.rb +72 -0
  141. data/test/cucumber/step_definitions/cartridge-postgresql_steps.rb +59 -0
  142. data/test/cucumber/step_definitions/cartridge-switchyard_steps.rb +29 -0
  143. data/test/cucumber/step_definitions/client_steps.rb +12 -0
  144. data/test/cucumber/step_definitions/descriptor_step.rb +32 -0
  145. data/test/cucumber/step_definitions/idler_steps.rb +37 -0
  146. data/test/cucumber/step_definitions/node_steps.rb +203 -0
  147. data/test/cucumber/step_definitions/runtime_steps.rb +547 -0
  148. data/test/cucumber/step_definitions/runtime_url_steps.rb +46 -0
  149. data/test/cucumber/step_definitions/trap-user-extended_steps.rb +14 -0
  150. data/test/cucumber/step_definitions/trap-user_steps.rb +58 -0
  151. data/test/cucumber/support/00_setup_helper.rb +106 -0
  152. data/test/cucumber/support/app_helper.rb +243 -0
  153. data/test/cucumber/support/assertions.rb +52 -0
  154. data/test/cucumber/support/command_helper.rb +453 -0
  155. data/test/cucumber/support/dns_helper.rb +54 -0
  156. data/test/cucumber/support/env.rb +5 -0
  157. data/test/cucumber/support/process_helper.rb +44 -0
  158. data/test/cucumber/support/runtime_support.rb +440 -0
  159. data/test/cucumber/support/unused.rb +27 -0
  160. data/test/cucumber/support/user_helper.rb +37 -0
  161. data/test/cucumber/trap-user-extended.feature +53 -0
  162. data/test/cucumber/trap-user.feature +34 -0
  163. data/test/ddns/1.168.192-rev.db.init +13 -0
  164. data/test/ddns/HOWTO.txt +207 -0
  165. data/test/ddns/Kexample.com.+157+06142.key +1 -0
  166. data/test/ddns/Kexample.com.+157+06142.private +7 -0
  167. data/test/ddns/authconfig.rb +14 -0
  168. data/test/ddns/example.com.db.init +23 -0
  169. data/test/ddns/example.com.key +4 -0
  170. data/test/ddns/named.ca +52 -0
  171. data/test/ddns/named.conf +48 -0
  172. data/test/ddns/named.empty +10 -0
  173. data/test/ddns/named.localhost +10 -0
  174. data/test/ddns/named.loopback +11 -0
  175. data/test/ddns/named.rfc1912.zones +42 -0
  176. data/test/ddns/named.root.key +5 -0
  177. data/test/ddns/named_service.rb +127 -0
  178. data/test/unit/bind_dns_service_test.rb +167 -0
  179. data/test/unit/broker_auth_test.rb +28 -0
  180. metadata +545 -0
@@ -0,0 +1,27 @@
1
+ @broker_api
2
+ @broker_api1
3
+ Feature: quickstarts
4
+ As an API client
5
+ In order to do things with quickstarts
6
+ I want to List and Show quickstarts without authenticating
7
+
8
+ Scenario: List quickstarts
9
+ Given I accept "JSON"
10
+ When I send an unauthenticated GET request to "/quickstarts"
11
+ Then the response should be "200"
12
+ And the response should be a list of "quickstarts"
13
+
14
+ Scenario: Get a specific quickstart
15
+ Given I accept "JSON"
16
+ And a quickstart UUID
17
+ When I send an unauthenticated GET request to "/quickstarts/<uuid>"
18
+ Then the response should be "200"
19
+ And the response should be a "quickstart"
20
+
21
+ Scenario: Get community quickstart URLs
22
+ Given I accept "JSON"
23
+ #And the Rails openshift configuration key community_base_url is "/community/"
24
+ When I send an unauthenticated GET request to "/api"
25
+ Then the response should be "200"
26
+ And the response should have the links "LIST_QUICKSTARTS, SHOW_QUICKSTART"
27
+
@@ -0,0 +1,64 @@
1
+ @broker
2
+ Feature: Rest Quick tests
3
+ As an developer I want to make sure I didn't break anything that is going to prevent others from working
4
+
5
+ Scenario Outline: Typical Workflow
6
+ Given a new user
7
+ And I accept "<format>"
8
+ When I send a POST request to "/user/keys" with the following:"name=api&type=ssh-rsa&content=XYZ123567"
9
+ Then the response should be "201"
10
+ And the response should be a "key" with attributes "name=api&type=ssh-rsa&content=XYZ123567"
11
+ When I send a GET request to "/user/keys/api"
12
+ Then the response should be "200"
13
+ And the response should be a "key" with attributes "name=api&type=ssh-rsa&content=XYZ123567"
14
+ When I send a POST request to "/domains" with the following:"id=api<random>"
15
+ Then the response should be "201"
16
+ When I send a POST request to "/domains/api<random>/applications" with the following:"name=app&cartridge=php-5.3"
17
+ Then the response should be "201"
18
+ And the response should be a "application" with attributes "name=app&framework=php-5.3"
19
+ When I send a GET request to "/domains/api<random>/applications/app"
20
+ Then the response should be "200"
21
+ And the response should be a "application" with attributes "name=app&framework=php-5.3"
22
+ When I send a GET request to "/domains/api<random>/applications"
23
+ Then the response should be "200"
24
+ When I send a POST request to "/domains/api<random>/applications/app/events" with the following:"event=stop"
25
+ Then the response should be "200"
26
+ When I send a POST request to "/domains/api<random>/applications/app/events" with the following:"event=start"
27
+ Then the response should be "200"
28
+ When I send a POST request to "/domains/api<random>/applications/app/events" with the following:"event=start"
29
+ Then the response should be "200"
30
+ When I send a POST request to "/domains/api<random>/applications/app/events" with the following:"event=force-stop"
31
+ Then the response should be "200"
32
+ When I send a POST request to "/domains/api<random>/applications/app/events" with the following:"event=add-alias&alias=app-api.foobar.com"
33
+ Then the response should be "200"
34
+ When I send a POST request to "/domains/api<random>/applications/app/events" with the following:"event=remove-alias&alias=app-api.foobar.com"
35
+ Then the response should be "200"
36
+ When I send a POST request to "/domains/api<random>/applications/app/cartridges" with the following:"cartridge=mysql-5.1"
37
+ Then the response should be "201"
38
+ When I send a GET request to "/domains/api<random>/applications/app/descriptor"
39
+ Then the response descriptor should have "php-5.3,mysql-5.1" as dependencies
40
+ When I send a POST request to "/domains/api<random>/applications/app/cartridges/mysql-5.1/events" with the following:"event=stop"
41
+ Then the response should be "200"
42
+ When I send a POST request to "/domains/api<random>/applications/app/cartridges/mysql-5.1/events" with the following:"event=start"
43
+ Then the response should be "200"
44
+ When I send a POST request to "/domains/api<random>/applications/app/cartridges/mysql-5.1/events" with the following:"event=restart"
45
+ Then the response should be "200"
46
+ When I send a DELETE request to "/domains/api<random>/applications/app/cartridges/mysql-5.1"
47
+ Then the response should be "200"
48
+ When I send a PUT request to "/domains/api<random>" with the following:"id=apiX<random>"
49
+ Then the response should be "200"
50
+ And the response should be a "domain" with attributes "id=apiX<random>"
51
+ When I send a DELETE request to "/domains/apiX<random>/applications/app"
52
+ Then the response should be "204"
53
+ When I send a GET request to "/domains/apiX<random>/applications/app"
54
+ Then the response should be "404"
55
+ When I send a DELETE request to "/domains/apiX<random>"
56
+ Then the response should be "204"
57
+ When I send a DELETE request to "/user/keys/api"
58
+ Then the response should be "204"
59
+
60
+ Scenarios:
61
+ | format |
62
+ | JSON |
63
+ | XML |
64
+
@@ -0,0 +1,369 @@
1
+ require 'rubygems'
2
+ require 'rest_client'
3
+ require 'nokogiri'
4
+ #require '/var/www/openshift/broker/config/environment'
5
+ require 'logger'
6
+
7
+ @random = nil
8
+ Before do
9
+ @base_url = "https://localhost/broker/rest"
10
+ end
11
+
12
+ After do |scenario|
13
+ domains = ["api#{@random}", "apiX#{@random}", "apiY#{@random}", "app-api#{@random}"]
14
+ remove_dns_entries(domains)
15
+ @random = nil
16
+ (@undo_config || []).each do |(main, secondary, value)|
17
+ Rails.configuration[main.to_sym][secondary.to_sym] = value
18
+ end
19
+ end
20
+
21
+ Given /^a new user$/ do
22
+ @random = rand(99999999)
23
+ @username = "rest-test-#{@random}"
24
+ @password = "xyz123"
25
+
26
+ register_user(@username, @password) if $registration_required
27
+
28
+ #TODO authenticate user
29
+
30
+ end
31
+
32
+ Given /^the Rails ([^\s]+) configuration key ([^\s]+) is "([^\"]*)"$/ do |main, secondary, value|
33
+ (@undo_config ||= []) << [main, secondary, Rails.configuration.config[main.to_sym][secondary.to_sym]]
34
+ Rails.configuration.config[main.to_sym][secondary.to_sym] = value
35
+ end
36
+
37
+ Given /^I send and accept "([^\"]*)"$/ do |type|
38
+ @headers = {:accept => type, :content_type => type}
39
+ end
40
+
41
+ Given /^I accept "([^\"]*)"$/ do |type|
42
+ @accept_type = type
43
+ @headers = {:accept => type.to_s.downcase}
44
+ end
45
+
46
+ Given /^an application template UUID$/ do
47
+ path = sub_random('/application_templates')
48
+ url = @base_url + path.to_s
49
+ @request = RestClient::Request.new(:method => :get, :url => url, :headers => @headers)
50
+ begin
51
+ @response = @request.execute()
52
+ rescue => e
53
+ @response = e.response
54
+ end
55
+
56
+ # Get a normalized list of templates
57
+ application_templates = unpacked_data(@response.body)
58
+
59
+ @uuid = application_templates[0]['uuid']
60
+ end
61
+
62
+ Given /^a quickstart UUID$/ do
63
+ path = sub_random('/quickstarts')
64
+ url = @base_url + path.to_s
65
+ @request = RestClient::Request.new(:method => :get, :url => url, :headers => @headers)
66
+ begin
67
+ @response = @request.execute()
68
+ rescue => e
69
+ @response = e.response
70
+ end
71
+
72
+ # Get a normalized list of quickstarts
73
+ quickstarts = unpacked_data(@response.body)
74
+
75
+ @uuid = quickstarts[0]['quickstart']['id']
76
+ end
77
+
78
+ When /^I send a GET request to "([^\"]*)"$/ do |path|
79
+ path = sub_random(path)
80
+ url = @base_url + path.to_s
81
+ @request = RestClient::Request.new(:method => :get, :url => url,
82
+ :user => @username, :password => @password, :headers => @headers)
83
+ begin
84
+ @response = @request.execute()
85
+ rescue => e
86
+ @response = e.response
87
+ end
88
+ end
89
+
90
+ When /^I send an unauthenticated GET request to "([^\"]*)"$/ do |path|
91
+ path = sub_random(sub_uuid(path))
92
+ url = @base_url + path.to_s
93
+ @request = RestClient::Request.new(:method => :get, :url => url, :headers => @headers)
94
+ begin
95
+ @response = @request.execute()
96
+ rescue => e
97
+ @response = e.response
98
+ end
99
+ end
100
+
101
+ When /^I send a POST request to "([^\"]*)" with the following:"([^\"]*)"$/ do |path, body|
102
+ path = sub_random(path)
103
+ body = sub_random(body)
104
+ #puts "path #{path}"
105
+ #puts "body #{body}"
106
+ payload = {}
107
+ params = body.split("&")
108
+ params.each do |param|
109
+ key, value = param.split("=", 2)
110
+ if payload[key].nil?
111
+ payload[key] = value
112
+ else
113
+ values = [payload[key], value]
114
+ payload[key] = values.flatten
115
+ end
116
+ end
117
+ url = @base_url + path.to_s
118
+ @request = RestClient::Request.new(:method => :post, :url => url,
119
+ :user => @username, :password => @password, :headers => @headers,
120
+ :payload => payload)
121
+ begin
122
+ @response = @request.execute()
123
+ rescue => e
124
+ @response = e.response
125
+ end
126
+ end
127
+
128
+ When /^I send a PUT request to "([^\"]*)" with the following:"([^\"]*)"$/ do |path, body|
129
+ path = sub_random(path)
130
+ body = sub_random(body)
131
+ #puts "path #{path}"
132
+ #puts "body #{body}"
133
+ payload = {}
134
+ params = body.split("&")
135
+ params.each do |param|
136
+ key, value = param.split("=", 2)
137
+ payload[key] = value
138
+ end
139
+ url = @base_url + path.to_s
140
+ @request = RestClient::Request.new(:method => :put, :url => url,
141
+ :user => @username, :password => @password, :headers => @headers,
142
+ :payload => payload)
143
+ begin
144
+ @response = @request.execute()
145
+ rescue => e
146
+ @response = e.response
147
+ end
148
+ end
149
+
150
+ When /^I send a DELETE request to "([^\"]*)"$/ do |path|
151
+ path = sub_random(path)
152
+ #puts "path #{path}"
153
+
154
+ url = @base_url + path.to_s
155
+ @request = RestClient::Request.new(:method => :delete, :url => url,
156
+ :user => @username, :password => @password, :headers => @headers)
157
+ begin
158
+ @response = @request.execute()
159
+ rescue => e
160
+ @response = e.response
161
+ end
162
+ end
163
+
164
+ Then /^the response should be "([^\"]*)"$/ do |status|
165
+ puts "#{@response.body}" if @response.code != status.to_i
166
+ @response.code.should == status.to_i
167
+ end
168
+
169
+ Then /^the response should have the link(?:s)? "([^\"]*)"$/ do |link|
170
+ response_acceptable = false
171
+ link_names = link.split(",")
172
+ missing_names = link_names.select do |name|
173
+ if link = links[name.strip]
174
+ URI.parse(link['href'])
175
+ !link['method'] || !link['rel'] || !link['required_params']
176
+ else
177
+ true
178
+ end
179
+ end
180
+ raise "Response did not contain link(s) #{missing_names.join(", ")}" unless missing_names.empty?
181
+ true
182
+ end
183
+
184
+ Then /^the response should be one of "([^\"]*)"$/ do |acceptable_statuses|
185
+ response_acceptable = false
186
+ statuses = acceptable_statuses.split(",")
187
+ statuses.each do | status|
188
+ puts "#{@response.body}" if @response.code != status.to_i
189
+ response_acceptable = true unless @response.code != status.to_i
190
+ end
191
+ response_acceptable.should == true
192
+ end
193
+
194
+ Then /^the response should be a "([^\"]*)" with attributes "([^\"]*)"$/ do |tag, attributes_str|
195
+ attributes_str = sub_random(attributes_str)
196
+ attributes_array = attributes_str.split("&")
197
+ if @accept_type.upcase == "XML"
198
+ #puts @response.body
199
+ result = Nokogiri::XML(@response.body)
200
+ attributes_array.each do |attributes|
201
+ key, value = attributes.split("=", 2)
202
+ #puts "#{result.xpath("//#{tag}/#{key}").text} #{value}"
203
+ result.xpath("//#{tag}/#{key}").text.should == value
204
+ end
205
+ elsif @accept_type.upcase == "JSON"
206
+ result = JSON.parse(@response.body)
207
+ obj = result["data"]
208
+ attributes_array.each do |attributes|
209
+ key, value = attributes.split("=", 2)
210
+ obj[key].should == value
211
+ end
212
+ else
213
+ false
214
+ end
215
+ end
216
+
217
+ Then /^the response should be a list of "([^\"]*)" with attributes "([^\"]*)"$/ do |tag, attributes_str|
218
+ attributes_str = sub_random(attributes_str)
219
+ attributes_array = attributes_str.split("&")
220
+ if @accept_type.upcase == "XML"
221
+ #puts @response.body
222
+ result = Nokogiri::XML(@response.body)
223
+ attributes_array.each do |attributes|
224
+ key, value = attributes.split("=", 2)
225
+ #puts "#{result.xpath("//#{tag}/#{key}").text} #{value}"
226
+ result.xpath("//#{tag}/#{key}").text.should == value
227
+ end
228
+ elsif @accept_type.upcase == "JSON"
229
+ result = JSON.parse(@response.body)
230
+ obj = result["data"]
231
+ attributes_array.each do |attributes|
232
+ key, value = attributes.split("=", 2)
233
+ obj[key].should == value
234
+ end
235
+ else
236
+ false
237
+ end
238
+ end
239
+
240
+ Then /^the error message should have "([^\"]*)"$/ do |attributes_str|
241
+ attributes_str = sub_random(attributes_str)
242
+ attributes_array = attributes_str.split("&")
243
+ if @accept_type.upcase == "XML"
244
+ #puts @response.body
245
+ result = Nokogiri::XML(@response.body)
246
+ messages = result.xpath("//message")
247
+ #puts messages
248
+ attributes_array.each do |attributes|
249
+ key, value = attributes.split("=", 2)
250
+ key = key.sub("_", "-")
251
+ messages.each do |message|
252
+ #puts message
253
+ #puts message.xpath("#{key}").text
254
+ message.xpath("#{key}").text.should == value
255
+ end
256
+ end
257
+ elsif @accept_type.upcase == "JSON"
258
+ result = JSON.parse(@response.body)
259
+ messages = result["messages"]
260
+ attributes_array.each do |attributes|
261
+ key, value = attributes.split("=", 2)
262
+ messages.each do |message|
263
+ message[key].to_s.should == value
264
+ end
265
+ end
266
+ else
267
+ false
268
+ end
269
+ end
270
+
271
+ Then /^the response descriptor should have "([^\"]*)" as dependencies$/ do |deps|
272
+ #puts @response.body
273
+ if @accept_type.upcase == "XML"
274
+ page = Nokogiri::XML(@response.body)
275
+ desc_yaml = page.xpath("//response/data/datum")
276
+ desc = YAML.load(desc_yaml.text.to_s)
277
+ elsif @accept_type.upcase == "JSON"
278
+ page = JSON.parse(@response.body)
279
+ desc_yaml = page["data"]
280
+ desc = YAML.load(desc_yaml)
281
+ end
282
+ #desc = YAML.load(desc_yaml.text.to_s)
283
+ deps.split(",").each do |dep|
284
+ desc["Requires"].should include(dep)
285
+ end
286
+ end
287
+
288
+ Then /^the response should be a list of "([^\"]*)"$/ do |list_type|
289
+ items = unpacked_data(@response.body)
290
+ if items.length < 1 && list_type != 'application templates'
291
+ raise("I got an empty list of #{list_type}")
292
+ end
293
+ if list_type == 'cartridges'
294
+ items.each do |cartridge|
295
+ check_cartridge(cartridge)
296
+ end
297
+ elsif list_type == 'application templates'
298
+ items.each do |application_template|
299
+ check_application_template(application_template)
300
+ end
301
+ elsif list_type == 'quickstarts'
302
+ items.each do |item|
303
+ check_quickstart(item)
304
+ end
305
+ else
306
+ raise("I don't recognize list type #{list_type}")
307
+ end
308
+ end
309
+
310
+ Then /^the response should be a "([^\"]*)"$/ do |item_type|
311
+ item = unpacked_data(@response.body)[0]
312
+ if item_type == 'cartridge'
313
+ check_cartridge(item)
314
+ elsif item_type == 'application template'
315
+ check_application_template(item)
316
+ elsif item_type == 'quickstart'
317
+ check_quickstart(item)
318
+ else
319
+ raise("I don't recognize item type #{item_type}")
320
+ end
321
+ end
322
+
323
+ def check_cartridge(cartridge)
324
+ unless cartridge.has_key?("name") && cartridge['name'].match(/\S+/)
325
+ raise("I found a cartridge without a name")
326
+ end
327
+ end
328
+
329
+ def check_application_template(application_template)
330
+ unless application_template.has_key?("uuid") && application_template['uuid'].match(/\S+/)
331
+ raise("I found an application without a UUID")
332
+ end
333
+ end
334
+
335
+ def check_quickstart(quickstart)
336
+ unless quickstart.has_key?("quickstart") && quickstart['quickstart'].has_key?("id") && quickstart['quickstart']['id'].match(/\S+/)
337
+ raise("I found a quickstart without an ID")
338
+ end
339
+ end
340
+
341
+ # Gets a normalized response
342
+ def unpacked_data(response_body)
343
+ if @accept_type.upcase == 'JSON'
344
+ data = JSON.parse(@response.body)['data']
345
+ elsif @accept_type.upcase == 'XML'
346
+ data = Hash.from_xml(@response.body)['response']['data']['template']
347
+ end
348
+ return data.is_a?(Array) ? data : [data]
349
+ end
350
+
351
+ def sub_random(value)
352
+ if value and value.include? "<random>"
353
+ value = value.sub("<random>", @random.to_s)
354
+ end
355
+ return value
356
+ end
357
+
358
+ def sub_uuid(value)
359
+ if value and value.include? "<uuid>"
360
+ value = value.sub("<uuid>", @uuid)
361
+ end
362
+ return value
363
+ end
364
+
365
+ def links
366
+ @links ||= if @accept_type.upcase == "JSON"
367
+ result = JSON.parse(@response.body)['data']
368
+ end
369
+ end