prof 0.29.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/LEGAL +13 -0
  3. data/lib/prof/cloud_foundry.rb +145 -0
  4. data/lib/prof/environment/cloud_foundry.rb +150 -0
  5. data/lib/prof/environment/pcf_drinks.rb +156 -0
  6. data/lib/prof/environment_manager.rb +93 -0
  7. data/lib/prof/external_spec/helpers/capybara.rb +58 -0
  8. data/lib/prof/external_spec/helpers/debug.rb +53 -0
  9. data/lib/prof/external_spec/helpers/file_helper.rb +35 -0
  10. data/lib/prof/external_spec/helpers/product_path.rb +23 -0
  11. data/lib/prof/external_spec/shared_examples/deployment.rb +23 -0
  12. data/lib/prof/external_spec/shared_examples/ops_manager_upgrade.rb +32 -0
  13. data/lib/prof/external_spec/shared_examples/service.rb +105 -0
  14. data/lib/prof/external_spec/shared_examples/service_broker.rb +25 -0
  15. data/lib/prof/external_spec/spec_helper.rb +35 -0
  16. data/lib/prof/marketplace_service.rb +20 -0
  17. data/lib/prof/matchers/metadata.rb +180 -0
  18. data/lib/prof/matchers/only_support_ssl_with_cipher_set.rb +102 -0
  19. data/lib/prof/matchers/ssl.rb +67 -0
  20. data/lib/prof/matchers/tile_configuration.rb +47 -0
  21. data/lib/prof/ops_manager/rails_500_error.rb +15 -0
  22. data/lib/prof/ops_manager/web_app_internals/page/checkbox_field.rb +38 -0
  23. data/lib/prof/ops_manager/web_app_internals/page/click_field.rb +40 -0
  24. data/lib/prof/ops_manager/web_app_internals/page/dashboard.rb +100 -0
  25. data/lib/prof/ops_manager/web_app_internals/page/flash_message.rb +53 -0
  26. data/lib/prof/ops_manager/web_app_internals/page/form.rb +130 -0
  27. data/lib/prof/ops_manager/web_app_internals/page/form_error.rb +43 -0
  28. data/lib/prof/ops_manager/web_app_internals/page/form_field.rb +51 -0
  29. data/lib/prof/ops_manager/web_app_internals/page/form_fields.rb +35 -0
  30. data/lib/prof/ops_manager/web_app_internals/page/installation_progress.rb +149 -0
  31. data/lib/prof/ops_manager/web_app_internals/page/login.rb +53 -0
  32. data/lib/prof/ops_manager/web_app_internals/page/modal.rb +85 -0
  33. data/lib/prof/ops_manager/web_app_internals/page/rails_500.rb +41 -0
  34. data/lib/prof/ops_manager/web_app_internals/page/select_field.rb +27 -0
  35. data/lib/prof/ops_manager/web_app_internals/page/tile_settings.rb +105 -0
  36. data/lib/prof/ops_manager/web_app_internals.rb +63 -0
  37. data/lib/prof/ops_manager.rb +141 -0
  38. data/lib/prof/ops_manager_log_fetcher.rb +30 -0
  39. data/lib/prof/product.rb +59 -0
  40. data/lib/prof/pushed_test_app.rb +40 -0
  41. data/lib/prof/service_instance.rb +21 -0
  42. data/lib/prof/ssh_gateway.rb +104 -0
  43. data/lib/prof/ssl/check.rb +79 -0
  44. data/lib/prof/ssl/cipher_set.rb +56 -0
  45. data/lib/prof/ssl/result.rb +27 -0
  46. data/lib/prof/ssl/results.rb +74 -0
  47. data/lib/prof/test_app.rb +19 -0
  48. data/lib/prof/tile.rb +25 -0
  49. data/lib/prof/uaa_client.rb +66 -0
  50. data/lib/prof/version.rb +13 -0
  51. metadata +403 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 40bcbedb4a82be8debb7fb4b120faa9ea9480d10
4
+ data.tar.gz: b3660e7602268aaa31f487c29e5b8820d85f4dab
5
+ SHA512:
6
+ metadata.gz: 105928b4e69b0d47da3ae17a2e591bd09aa417899b2721297ae85d65387f755ed50e15252af1581bc8c0152d76242d25e0705797c9b1a2fb3167634432e26a92
7
+ data.tar.gz: 715dd614e05306fa15711845cfb03a54132e025211c5c1c0aceb87a38f4c0d8ec37cc7ced1bb02f4a6a177ab40463430bd700235a2d59a7ad4023be19d0d500e
data/LEGAL ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2014-2015 Pivotal Software, Inc. All rights reserved.
2
+
3
+ Unauthorized use, copying or distribution of this source code via any
4
+ medium is strictly prohibited without the express written consent of
5
+ Pivotal Software, Inc.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
8
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
10
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
11
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
12
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
13
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,145 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ require 'forwardable'
12
+ require 'hula/cloud_foundry'
13
+
14
+ require 'prof/marketplace_service'
15
+ require 'prof/pushed_test_app'
16
+ require 'prof/service_instance'
17
+
18
+ module Prof
19
+ class CloudFoundry
20
+ extend Forwardable
21
+
22
+ attr_reader :api_url, :domain, :username, :password
23
+
24
+ def_delegators :hula_cloud_foundry,
25
+ :add_public_service_broker,
26
+ :app_env,
27
+ :create_org,
28
+ :target_org,
29
+ :create_space,
30
+ :target_space,
31
+ :create_and_target_org,
32
+ :create_and_target_space,
33
+ :create_service_instance,
34
+ :delete_org,
35
+ :delete_space,
36
+ :delete_service_instance_and_unbind,
37
+ :push_app_and_start,
38
+ :remove_service_broker,
39
+ :service_brokers,
40
+ :setup_permissive_security_group,
41
+ :app_vcap_services,
42
+ :marketplace
43
+
44
+ def initialize(opts = {})
45
+ @domain = opts.fetch(:domain)
46
+ @api_url = opts.fetch(:api_url) { "https://api.#{domain}" }
47
+ @username = opts.fetch(:username)
48
+ @password = opts.fetch(:password)
49
+ end
50
+
51
+ def push_app(app, &_block)
52
+ pushed_app_name = "cf-app-#{SecureRandom.hex(4)}"
53
+ deployed_app = PushedTestApp.new(name: pushed_app_name, url: hula_cloud_foundry.url_for_app(pushed_app_name))
54
+
55
+ hula_cloud_foundry.push_app(app.path, deployed_app.name)
56
+
57
+ yield deployed_app
58
+ ensure
59
+ hula_cloud_foundry.delete_app deployed_app.name
60
+ end
61
+
62
+ def enable_diego_and_start_app(app)
63
+ hula_cloud_foundry.enable_diego_for_app(app.name)
64
+ hula_cloud_foundry.start_app(app.name)
65
+ end
66
+
67
+ def push_app_and_bind_with_service(app, service, &_block)
68
+ push_app(app) do |pushed_app|
69
+ provision_service(service) do |service_instance|
70
+ bind_service_and_run(pushed_app, service_instance) do
71
+ yield pushed_app, service_instance
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ def push_app_and_bind_with_service_instance(app, service_instance, &_block)
78
+ push_app(app) do |pushed_app|
79
+ bind_service_and_run(pushed_app, service_instance) do
80
+ yield pushed_app, service_instance
81
+ end
82
+ end
83
+ end
84
+
85
+ def bind_service_and_run(pushed_app, service_instance, &_block)
86
+ hula_cloud_foundry.bind_app_to_service(pushed_app.name, service_instance.name)
87
+ hula_cloud_foundry.start_app(pushed_app.name)
88
+
89
+ yield
90
+
91
+ hula_cloud_foundry.unbind_app_from_service(pushed_app.name, service_instance.name)
92
+ end
93
+
94
+ def provision_and_create_service_key(service, &_block)
95
+ provision_service(service) do |service_instance|
96
+ create_service_key(service_instance) do |service_key, service_key_data|
97
+ yield service_instance, service_key, service_key_data
98
+ end
99
+ end
100
+ end
101
+
102
+ def list_service_keys(service_instance)
103
+ hula_cloud_foundry.list_service_keys(service_instance.name)
104
+ end
105
+
106
+ def create_service_key(service_instance, &_block)
107
+ service_key_name = "#{service_instance.name}-#{SecureRandom.hex(4)}"
108
+ hula_cloud_foundry.create_service_key(service_instance.name, service_key_name)
109
+ service_key_raw = hula_cloud_foundry.service_key(service_instance.name, service_key_name)
110
+ service_key_data = JSON.parse(
111
+ service_key_raw.split("\n").slice(2..-1).join
112
+ )
113
+
114
+ yield service_key_name, service_key_data
115
+
116
+ hula_cloud_foundry.delete_service_key(service_instance.name, service_key_name)
117
+ end
118
+
119
+ def delete_service_key(service_instance, service_key)
120
+ hula_cloud_foundry.delete_service_key(service_instance.name, service_key)
121
+ end
122
+
123
+ def provision_service(service, &_block)
124
+ service_instance = ServiceInstance.new
125
+
126
+ hula_cloud_foundry.create_service_instance(service.name, service_instance.name, service.plan)
127
+
128
+ yield service_instance if block_given?
129
+
130
+ ensure
131
+ hula_cloud_foundry.delete_service_instance_and_unbind(service_instance.name)
132
+ end
133
+
134
+ private
135
+
136
+ def hula_cloud_foundry
137
+ @hula_cloud_foundry ||= Hula::CloudFoundry.new(
138
+ api_url: api_url,
139
+ domain: domain,
140
+ username: username,
141
+ password: password
142
+ )
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,150 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ require 'hula/bosh_director'
12
+ require 'hula/service_broker/client'
13
+ require 'hula/bosh_manifest'
14
+ require 'hula/socks4_proxy_ssh'
15
+ require 'hula/http_proxy_upstream_socks'
16
+
17
+ require 'prof/cloud_foundry'
18
+ require 'prof/ssh_gateway'
19
+ require 'prof/uaa_client'
20
+
21
+ module Prof
22
+ module Environment
23
+ class CloudFoundry
24
+ attr_reader :bosh_service_broker_job_name
25
+
26
+ def initialize(
27
+ cloud_foundry_domain: nil,
28
+
29
+ cloud_controller_identity: 'cloud_controller',
30
+ cloud_controller_password: 'cc-secret',
31
+
32
+ cloud_foundry_username: 'admin',
33
+ cloud_foundry_password: 'admin',
34
+ cloud_foundry_api_url: nil,
35
+
36
+ bosh_target: 'https://192.168.50.4:25555',
37
+ bosh_username: 'admin',
38
+ bosh_password: 'admin',
39
+
40
+ ssh_gateway_host: '192.168.50.4',
41
+ ssh_gateway_username: 'vagrant',
42
+ ssh_gateway_password: 'vagrant',
43
+
44
+ bosh_service_broker_job_name:,
45
+ bosh_manifest_path:,
46
+
47
+ use_proxy: true
48
+ )
49
+ @cloud_foundry_domain = cloud_foundry_domain
50
+ @cloud_controller_identity = cloud_controller_identity
51
+ @cloud_controller_password = cloud_controller_password
52
+ @cloud_foundry_username = cloud_foundry_username
53
+ @cloud_foundry_password = cloud_foundry_password
54
+ @bosh_target = bosh_target
55
+ @bosh_username = bosh_username
56
+ @bosh_password = bosh_password
57
+ @ssh_gateway_host = ssh_gateway_host
58
+ @ssh_gateway_username = ssh_gateway_username
59
+ @ssh_gateway_password = ssh_gateway_password
60
+ @bosh_service_broker_job_name = bosh_service_broker_job_name
61
+ @bosh_manifest_path = bosh_manifest_path
62
+ @cloud_foundry_api_url = cloud_foundry_api_url
63
+ @use_proxy = use_proxy
64
+ end
65
+
66
+ def cloud_foundry
67
+ @cloud_foundry ||= ::Prof::CloudFoundry.new(
68
+ domain: cloud_foundry_domain,
69
+ username: cloud_foundry_username,
70
+ password: cloud_foundry_password,
71
+ api_url: cloud_foundry_api_url
72
+ )
73
+ end
74
+
75
+ def bosh_manifest
76
+ @bosh_manifest ||= Hula::BoshManifest.from_file(bosh_manifest_path)
77
+ end
78
+
79
+ def cloud_foundry_domain
80
+ @cloud_foundry_domain ||= bosh_manifest.property('cf.domain')
81
+ end
82
+
83
+ def service_broker
84
+ @service_broker ||= Hula::ServiceBroker::Client.new(
85
+ url: URI::HTTPS.build(host: broker_registrar_properties.fetch('host')),
86
+ username: broker_registrar_properties.fetch('username'),
87
+ password: broker_registrar_properties.fetch('password'),
88
+ http_client: http_json_client(use_proxy: use_proxy)
89
+ )
90
+ end
91
+
92
+ def service_broker_name
93
+ broker_registrar_properties.fetch('name')
94
+ end
95
+
96
+ def bosh_director
97
+ @bosh_director ||= Hula::BoshDirector.new(
98
+ target_url: bosh_target,
99
+ username: bosh_username,
100
+ password: bosh_password,
101
+ manifest_path: bosh_manifest_path
102
+ )
103
+ end
104
+
105
+ def ssh_gateway
106
+ @ssh_gateway ||= SshGateway.new(
107
+ gateway_host: ssh_gateway_host,
108
+ gateway_username: ssh_gateway_username,
109
+ gateway_password: ssh_gateway_password
110
+ )
111
+ end
112
+
113
+ def cloud_foundry_uaa
114
+ @cloud_foundry_uaa ||= UAAClient.new(
115
+ cloud_foundry_domain,
116
+ cloud_controller_identity,
117
+ cloud_controller_password
118
+ )
119
+ end
120
+
121
+ def socks4_proxy
122
+ @socks4_proxy ||= Hula::Socks4ProxySsh.new(
123
+ ssh_username: ssh_gateway_username,
124
+ ssh_password: ssh_gateway_password,
125
+ ssh_host: ssh_gateway_host
126
+ ).tap(&:start)
127
+ end
128
+
129
+ def http_proxy
130
+ @http_proxy ||= Hula::HttpProxyUpstreamSocks.new(socks_proxy: socks4_proxy).tap(&:start)
131
+ end
132
+
133
+ private
134
+
135
+ attr_reader :cloud_controller_identity, :cloud_controller_password,
136
+ :cloud_foundry_username, :cloud_foundry_password, :bosh_target, :bosh_username, :bosh_password,
137
+ :ssh_gateway_host, :ssh_gateway_username, :ssh_gateway_password, :bosh_manifest_path,
138
+ :cloud_foundry_api_url, :use_proxy
139
+
140
+ def broker_registrar_properties
141
+ bosh_manifest.job('broker-registrar').properties.fetch('broker')
142
+ end
143
+
144
+ def http_json_client(use_proxy:)
145
+ proxy = use_proxy ? http_proxy : Hula::ServiceBroker::HttpProxyNull.new
146
+ @http_json_client ||= Hula::ServiceBroker::HttpJsonClient.new(http_proxy: proxy)
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,156 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ require 'uri'
12
+ require 'hula/bosh_director'
13
+ require 'capybara'
14
+
15
+ require 'prof/cloud_foundry'
16
+ require 'prof/ops_manager'
17
+ require 'prof/ops_manager_log_fetcher'
18
+ require 'prof/ssh_gateway'
19
+ require 'prof/uaa_client'
20
+
21
+ module Prof
22
+ module Environment
23
+ class NoDirectorVm < StandardError; end
24
+
25
+ class PcfDrinks
26
+ def initialize(tempest_config, page: default_capybara_session)
27
+ @tempest_config = tempest_config
28
+ @page = page
29
+ end
30
+
31
+ def ops_manager
32
+ @ops_manager ||= OpsManager.new(ops_manager_config.merge(page: page))
33
+ end
34
+
35
+ def cloud_foundry
36
+ @cloud_foundry ||= CloudFoundry.new(
37
+ domain: cloud_foundry_domain,
38
+ username: cloud_foundry_credentials.username,
39
+ password: cloud_foundry_credentials.password
40
+ )
41
+ end
42
+
43
+ def cloud_foundry_domain
44
+ tempest_config.fetch(:cloudfoundry).fetch(:domain)
45
+ end
46
+
47
+ def bosh_director
48
+ @bosh_director ||= Hula::BoshDirector.new(
49
+ target_url: bosh_director_url,
50
+ username: bosh_credentials.fetch('identity'),
51
+ password: bosh_credentials.fetch('password')
52
+ )
53
+ end
54
+
55
+ def ssh_gateway
56
+ SshGateway.new(
57
+ gateway_host: ssh_gateway_config.fetch(:host),
58
+ gateway_username: ssh_gateway_config.fetch(:username),
59
+ gateway_password: ssh_gateway_config[:password],
60
+ ssh_key: ssh_gateway_config[:ssh_key]
61
+ )
62
+ end
63
+
64
+ def cloud_foundry_uaa
65
+ @cloud_foundry_uaa ||= UAAClient.new(
66
+ cloud_foundry_domain,
67
+ cloud_controller_client_credentials.identity,
68
+ cloud_controller_client_credentials.password
69
+ )
70
+ end
71
+
72
+ private
73
+
74
+ attr_reader :tempest_config, :page
75
+
76
+ def default_capybara_session
77
+ Capybara::Session.new(Capybara.default_driver)
78
+ end
79
+
80
+ def log_fetcher
81
+ OpsManagerLogFetcher.new(
82
+ ssh_gateway: ssh_gateway,
83
+ host: ops_manager_hostname,
84
+ username: ops_manager_vm_config.fetch(:username),
85
+ password: ops_manager_vm_config.fetch(:password)
86
+ )
87
+ end
88
+
89
+ def cloud_controller_client_credentials
90
+ @cloud_controller_client_credentials ||= ops_manager.cc_client_credentials
91
+ end
92
+
93
+ def forwarded_bosh_port
94
+ @forwarded_bosh_port ||=
95
+ ssh_gateway.with_port_forwarded_to(
96
+ director.hostname,
97
+ 25555
98
+ )
99
+ end
100
+
101
+ def director
102
+ director = ops_manager.vms_for_job_type('director').first
103
+
104
+ if director.nil?
105
+ raise NoDirectorVm, "No director VM found for #{ops_manager.url}"
106
+ else
107
+ director
108
+ end
109
+ end
110
+
111
+ def ops_manager_hostname
112
+ URI.parse(ops_manager_config.fetch(:url)).hostname
113
+ end
114
+
115
+ def ops_manager_config
116
+ tempest_config.fetch(:tempest)
117
+ end
118
+
119
+ def ops_manager_vm_config
120
+ tempest_config.fetch(:tempest_vm)
121
+ end
122
+
123
+ def ssh_gateway_config
124
+ tempest_config.fetch(:proxy)
125
+ end
126
+
127
+ def bosh_director_url
128
+ return URI("https://127.0.0.1:#{forwarded_bosh_port}").to_s if !tempest_config[:proxy].nil?
129
+ return director.hostname
130
+ end
131
+
132
+ def bosh_product
133
+ # old versions of OpsMan (< v1.6 RC4)
134
+ @bosh_product ||= ops_manager
135
+ .send(:opsmanager_client)
136
+ .send(:product, 'microbosh')
137
+
138
+ # newer versions of OpsMan (>= v1.6 RC4)
139
+ @bosh_product ||= ops_manager
140
+ .send(:opsmanager_client)
141
+ .send(:product, 'p-bosh')
142
+ end
143
+
144
+ def bosh_credentials
145
+ # TODO: push this code into ops manager
146
+ @bosh_credentials ||= bosh_product
147
+ .job_of_type('director')
148
+ .properties.fetch('director_credentials')
149
+ end
150
+
151
+ def cloud_foundry_credentials
152
+ @cloud_foundry_credentials ||= ops_manager.cf_admin_credentials
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,93 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ module Prof
12
+ class EnvironmentManager
13
+ class OpsManagerNotConfigured < StandardError; end
14
+
15
+ def initialize(pcf_environment)
16
+ @pcf_environment = pcf_environment
17
+ end
18
+
19
+ def isolate_cloud_foundry(&_block)
20
+ cloud_foundry.create_and_target_org(cf_org_name)
21
+ cloud_foundry.create_and_target_space(cf_space_name)
22
+ cloud_foundry.setup_permissive_security_group(cf_org_name, cf_space_name)
23
+
24
+ yield
25
+
26
+ cloud_foundry.delete_org(cf_org_name)
27
+ end
28
+
29
+ def destroy_orphan_tiles
30
+ orphans = orphan_tiles
31
+ return unless orphans.any?
32
+
33
+ puts "Removing orphaned tile(s) #{orphans.map(&:name).join(', ')}"
34
+ ops_manager.uninstall_tiles(orphans)
35
+ end
36
+
37
+ def destroy_orphan_deployments
38
+ orphans = orphan_deployments
39
+ return unless orphans.any?
40
+
41
+ puts "Removing orphaned deployment(s) '#{orphans.join(', ')}'"
42
+ orphans.each do |deployment_name|
43
+ bosh_director.delete_deployment(deployment_name, force: true)
44
+ end
45
+ end
46
+
47
+ def uninstall_tiles
48
+ ops_manager.uninstall_tiles(ops_manager.product_tiles)
49
+ end
50
+
51
+ def reset
52
+ raise OpsManagerNotConfigured, "Please configure #{ops_manager.url}" unless ops_manager.cf_installed?
53
+
54
+ destroy_orphan_tiles
55
+ destroy_orphan_deployments
56
+ uninstall_tiles
57
+ end
58
+
59
+ private
60
+
61
+ attr_reader :pcf_environment
62
+
63
+ def cf_org_name
64
+ @cf_org_name ||= "cf-org-#{SecureRandom.hex(4)}"
65
+ end
66
+
67
+ def cf_space_name
68
+ @cf_space_name ||= "cf-space-#{SecureRandom.hex(4)}"
69
+ end
70
+
71
+ def cloud_foundry
72
+ pcf_environment.cloud_foundry
73
+ end
74
+
75
+ def ops_manager
76
+ pcf_environment.ops_manager
77
+ end
78
+
79
+ def orphan_deployments
80
+ tile_guids = pcf_environment.ops_manager.tiles.map(&:guid)
81
+ pcf_environment.bosh_director.deployment_names.reject { |deployment_name| tile_guids.include?(deployment_name) }
82
+ end
83
+
84
+ def orphan_tiles
85
+ bosh_deployment_names = pcf_environment.bosh_director.deployment_names
86
+ pcf_environment.ops_manager.product_tiles.reject { |tile| bosh_deployment_names.include?(tile.guid) }
87
+ end
88
+
89
+ def bosh_director
90
+ pcf_environment.bosh_director
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ require 'capybara/rspec'
12
+ require 'capybara/query'
13
+ require 'capybara/poltergeist'
14
+ require 'capybara/webkit'
15
+
16
+ module Prof
17
+ module ExternalSpec
18
+ module Helpers
19
+ module Capybara
20
+ def setup_browser(driver = :poltergeist)
21
+ unless %i{poltergeist webkit}.include?(driver)
22
+ raise StandardError.new("invalid driver")
23
+ end
24
+
25
+ ::Capybara.default_wait_time = 60
26
+ ::Capybara.default_driver = driver
27
+ ::Capybara.javascript_driver = driver
28
+
29
+ ::Capybara.register_driver :poltergeist do |app|
30
+ ::Capybara::Poltergeist::Driver.new(
31
+ app,
32
+ debug: ENV.key?('DEBUG'),
33
+ timeout: 240,
34
+ js_errors: false,
35
+ phantomjs_logger: null_io_object,
36
+ phantomjs_options: ['--ignore-ssl-errors=yes'],
37
+ window_size: [1300, 1000]
38
+ )
39
+ end
40
+
41
+ ::Capybara.register_driver :webkit do |app|
42
+ ::Capybara::Webkit::Driver.new(app).tap do |d|
43
+ d.browser.ignore_ssl_errors
44
+ d.browser.allow_url('*')
45
+ end
46
+ end
47
+ end
48
+
49
+ def null_io_object
50
+ f = File.open('/dev/null')
51
+ io = IO.for_fd(f.fileno)
52
+ io.autoclose = true
53
+ io
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,53 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ module Prof
12
+ module ExternalSpec
13
+ module Helpers
14
+ module Debug
15
+
16
+ def recording_exceptions
17
+ yield
18
+ rescue Exception => ex
19
+ @recorded_exception = ex
20
+ raise
21
+ end
22
+
23
+ def save_exceptions
24
+ yield
25
+ rescue Exception => ex
26
+ ops_manager.browser do |page|
27
+ name = "failure"
28
+ puts "Saving failure data for '#{name}'"
29
+ page.save_page("#{name}.html")
30
+ page.save_screenshot("#{name}.png")
31
+ end
32
+ raise
33
+ end
34
+
35
+ def save_exception_output(example)
36
+ unless @recorded_exception
37
+ return unless example.respond_to?(:exception)
38
+ return unless example.respond_to?(:full_description)
39
+ return unless respond_to?(:ops_manager)
40
+ return unless example.exception
41
+ end
42
+
43
+ ops_manager.browser do |page|
44
+ name = example.full_description.gsub(/\W/, '_')
45
+ puts "Saving failure data for '#{name}'"
46
+ page.save_page("#{name}.html")
47
+ page.save_screenshot("#{name}.png")
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end