openshift-origin-controller 1.3.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.
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