prof 0.29.3

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 (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