prof 0.30.9 → 0.31.0

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 (26) hide show
  1. checksums.yaml +4 -4
  2. data/lib/prof/environment/pcf_drinks.rb +17 -51
  3. data/lib/prof/external_spec/helpers/capybara.rb +5 -0
  4. data/lib/prof/external_spec/helpers/file_helper.rb +3 -9
  5. data/lib/prof/external_spec/spec_helper.rb +11 -6
  6. data/lib/prof/ops_manager.rb +35 -109
  7. data/lib/prof/version.rb +1 -1
  8. metadata +6 -24
  9. data/lib/prof/external_spec/helpers/debug.rb +0 -53
  10. data/lib/prof/ops_manager/rails_500_error.rb +0 -15
  11. data/lib/prof/ops_manager/web_app_internals/page/checkbox_field.rb +0 -38
  12. data/lib/prof/ops_manager/web_app_internals/page/click_field.rb +0 -40
  13. data/lib/prof/ops_manager/web_app_internals/page/dashboard.rb +0 -100
  14. data/lib/prof/ops_manager/web_app_internals/page/flash_message.rb +0 -53
  15. data/lib/prof/ops_manager/web_app_internals/page/form.rb +0 -130
  16. data/lib/prof/ops_manager/web_app_internals/page/form_error.rb +0 -43
  17. data/lib/prof/ops_manager/web_app_internals/page/form_field.rb +0 -51
  18. data/lib/prof/ops_manager/web_app_internals/page/form_fields.rb +0 -35
  19. data/lib/prof/ops_manager/web_app_internals/page/installation_progress.rb +0 -149
  20. data/lib/prof/ops_manager/web_app_internals/page/login.rb +0 -83
  21. data/lib/prof/ops_manager/web_app_internals/page/modal.rb +0 -85
  22. data/lib/prof/ops_manager/web_app_internals/page/rails_500.rb +0 -41
  23. data/lib/prof/ops_manager/web_app_internals/page/select_field.rb +0 -27
  24. data/lib/prof/ops_manager/web_app_internals/page/tile_settings.rb +0 -105
  25. data/lib/prof/ops_manager/web_app_internals.rb +0 -63
  26. data/lib/prof/ops_manager_log_fetcher.rb +0 -30
@@ -1,100 +0,0 @@
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 'prof/ops_manager/web_app_internals/page/installation_progress'
12
- require 'prof/ops_manager/web_app_internals/page/modal'
13
- require 'prof/ops_manager/web_app_internals/page/tile_settings'
14
-
15
- module Prof
16
- class OpsManager
17
- class WebAppInternals
18
- module Page
19
- class Dashboard
20
-
21
- class ModalPresent < StandardError; end
22
-
23
- def initialize(opts = {})
24
- @page = opts.fetch(:page)
25
- end
26
-
27
- def tile(tile)
28
- begin
29
- page.find("#show-#{tile.name}-configure-action").click
30
- rescue Capybara::ElementNotFound
31
- page.visit(page.current_url)
32
- page.find("#show-#{tile.name}-configure-action").click
33
- end
34
-
35
- TileSettings.new(page: page)
36
- end
37
-
38
- def tile_configure(target_tile, configuration)
39
- tile(target_tile).configure(configuration)
40
- end
41
-
42
- def tile_configuration(target_tile)
43
- tile_setting_page = tile(target_tile)
44
-
45
- Hash.new.tap do |config|
46
- tile_setting_page.setting_names.each do |setting_name|
47
- config[setting_name] = tile_setting_page.settings_for(setting_name)
48
- end
49
-
50
- tile_setting_page.return_to_dashboard
51
- end
52
- end
53
-
54
- def apply_setting(target_tile, field_name, field_value)
55
- tile(target_tile).set_field_value('Resource Config', field_name, field_value).return_to_dashboard
56
- end
57
-
58
- def tile_configured?(target_tile)
59
- page.find("#show-#{target_tile.name}-configure-action")['data-progress'] == '100'
60
- rescue Capybara::ElementNotFound
61
- false
62
- end
63
-
64
- def tile_uninstall(target_tile)
65
- page.find("#show-#{target_tile.name}-configure-action ~ #open-delete-#{target_tile.name}-modal").click
66
- modal.confirm
67
- rescue Capybara::ElementNotFound
68
- end
69
-
70
- def apply_changes
71
- check_no_modal!
72
-
73
- page.click_link_or_button 'Apply changes'
74
- InstallationProgress.new(page: page)
75
- end
76
-
77
- def pending_changes?
78
- pending_changes.any?
79
- end
80
-
81
- def pending_changes
82
- page.all('.pending-changes-list li').map(&:text)
83
- end
84
-
85
- private
86
-
87
- attr_reader :page
88
-
89
- def check_no_modal!
90
- raise ModalPresent, "A modal was present with text: '#{modal.message}'" if modal.present?
91
- end
92
-
93
- def modal
94
- Modal.new(page: page)
95
- end
96
- end
97
- end
98
- end
99
- end
100
- end
@@ -1,53 +0,0 @@
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 OpsManager
13
- class WebAppInternals
14
- module Page
15
- class FlashMessage
16
- def initialize(opts = {})
17
- @page = opts.fetch(:page)
18
- end
19
-
20
- def text
21
- page.find('.flash-message:not(.in-progress)', wait: 60).text
22
- end
23
-
24
- def success?
25
- !error? && page.all('.flash-message.success').any?
26
- end
27
-
28
- def error?
29
- page.all('.flash-message.error').any?
30
- end
31
-
32
- def installation_in_progress?
33
- page.all('.flash-message.in-progress').any?
34
- end
35
-
36
- def icmp_error?
37
- return false unless error?
38
- error = page.all('.flash-message.error').first.text
39
- error.include? 'ignorable if ICMP is disabled'
40
- end
41
-
42
- def ignore_warnings
43
- page.find('#ignore-install-action').click
44
- end
45
-
46
- private
47
-
48
- attr_reader :page
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,130 +0,0 @@
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 'prof/ops_manager/web_app_internals/page/form_error'
12
- require 'prof/ops_manager/web_app_internals/page/flash_message'
13
- require 'prof/ops_manager/web_app_internals/page/form_fields'
14
- require 'prof/ops_manager/web_app_internals/page/form_field'
15
- require 'prof/ops_manager/web_app_internals/page/select_field'
16
- require 'prof/ops_manager/web_app_internals/page/checkbox_field'
17
- require 'prof/ops_manager/web_app_internals/page/click_field'
18
-
19
- module Prof
20
- class OpsManager
21
- class WebAppInternals
22
- module Page
23
- class Form
24
- def initialize(opts = {})
25
- @page = opts.fetch(:page)
26
- @form_element = opts.fetch(:form_element)
27
- end
28
-
29
- def update(config = {}, &_block)
30
- case config
31
- when Array
32
- update_list(config)
33
- when Hash, FormFields
34
- raise "Add button on page #{page.current_url}, maybe you should update a list?" if add_button
35
-
36
- update_fields(config)
37
- else
38
- raise "Unrecognised config #{config.inspect}"
39
- end
40
-
41
- yield self, page if block_given?
42
-
43
- form_element.click_on 'Save'
44
-
45
- # raise "Failed to save, the server 500ed" if page.status_code.to_i >= 500
46
- raise "Failed to save, no success message. #{error_message}" unless success?
47
- end
48
-
49
- private
50
-
51
- attr_reader :form_element, :page
52
-
53
- def update_list(list)
54
- raise "No add button on page #{page.current_url}, are you sure you want to update a list?" unless add_button
55
- clear_list
56
-
57
- list.each do |item_config|
58
- add_button.click
59
-
60
- update_fields(item_config)
61
- end
62
- end
63
-
64
- def clear_list
65
- form_element.all('.with-delete-record').each(&:click)
66
- end
67
-
68
- def add_button
69
- form_element.first(:link_or_button, 'Add')
70
- end
71
-
72
- def update_fields(config)
73
- if(config.is_a? FormFields)
74
- update_fields_from_form_fields(config)
75
- else
76
- update_fields_from_string_hash(config)
77
- end
78
- end
79
-
80
- def update_fields_from_string_hash(config)
81
- config.each do |field, value|
82
- selector = field_to_selector(field)
83
- input = form_element.all(selector).last
84
-
85
- raise "Could not find element with selector #{selector}" unless input
86
-
87
- if input.tag_name == 'select'
88
- input.find(:option, value).select_option
89
- else
90
- input.set(value)
91
- end
92
- end
93
- end
94
-
95
- def update_fields_from_form_fields(config)
96
- config.each do |field|
97
- field.set(form_element)
98
- end
99
- end
100
-
101
- def field_to_selector(field)
102
- if field.include?('[') && field.include?(']')
103
- "[name='#{field}']"
104
- else
105
- "[name$='#{field}]']"
106
- end
107
- end
108
-
109
- def success?
110
- flash_message.success?
111
- end
112
-
113
- def error_message
114
- "#{flash_message.text} #{errors.join(', ')}"
115
- end
116
-
117
- def flash_message
118
- FlashMessage.new(page: page)
119
- end
120
-
121
- def errors
122
- form_element.all('.help-block').map do |error_element|
123
- FormError.new(error_element: error_element)
124
- end
125
- end
126
- end
127
- end
128
- end
129
- end
130
- end
@@ -1,43 +0,0 @@
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 OpsManager
13
- class WebAppInternals
14
- module Page
15
- class FormError
16
- def initialize(opts = {})
17
- @error_element = opts.fetch(:error_element)
18
- end
19
-
20
- def name
21
- /[^\[]*\[([^\]]+)\]$/.match(full_name).to_a[1]
22
- end
23
-
24
- def error
25
- error_element.text
26
- end
27
-
28
- def to_s
29
- "#{name} #{error}"
30
- end
31
-
32
- private
33
-
34
- attr_reader :error_element
35
-
36
- def full_name
37
- error_element.find('~ input')[:name]
38
- end
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,51 +0,0 @@
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 OpsManager
13
- class WebAppInternals
14
- module Page
15
- class FormField
16
-
17
- def initialize(name:, value:)
18
- @name = name
19
- @value = value
20
- end
21
-
22
- def set(form_element)
23
- field = find_field(form_element)
24
- raise "Could not find element with name #{name} and selector #{selector}" unless field
25
- set_value(field)
26
- end
27
-
28
- private
29
-
30
- attr_reader :name, :value
31
-
32
- def find_field(form_element)
33
- form_element.all(selector).last
34
- end
35
-
36
- def set_value(field)
37
- field.set(value)
38
- end
39
-
40
- def selector
41
- if name.include?('[') && name.include?(']')
42
- "[name='#{name}']"
43
- else
44
- "[name$='[#{name}]']"
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,35 +0,0 @@
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 OpsManager
13
- class WebAppInternals
14
- module Page
15
- class FormFields
16
- include Enumerable
17
-
18
- def initialize(fields)
19
- @fields = fields
20
- end
21
-
22
- def each
23
- fields.each do |field|
24
- yield field
25
- end
26
- end
27
-
28
- private
29
-
30
- attr_reader :fields
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,149 +0,0 @@
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 'prof/ops_manager/web_app_internals/page/modal'
12
- require 'prof/ops_manager/web_app_internals/page/flash_message'
13
- require 'prof/ops_manager/web_app_internals/page/rails_500'
14
-
15
- require 'nokogiri'
16
-
17
- module Prof
18
- class OpsManager
19
-
20
- class InstallationError < StandardError; end
21
-
22
- class WebAppInternals
23
- module Page
24
- class InstallationProgress
25
- MAX_INSTALL_STEP_SECONDS = 60 * 45
26
-
27
- class TimeoutWaitingForStep < InstallationError; end
28
-
29
- def initialize(page:, output: STDOUT)
30
- @page = page
31
- @output = output
32
-
33
- if flash_message.icmp_error?
34
- flash_message.ignore_warnings
35
- end
36
-
37
- raise InstallationError, flash_message.text if flash_message.error?
38
- end
39
-
40
- def install_successful?
41
- install_steps.each do |step|
42
- wait_until_completed step
43
- end
44
-
45
- if modal.success?
46
- modal.confirm
47
- return true
48
- else
49
- output.puts modal.message
50
- modal.confirm
51
- return false
52
- end
53
- end
54
-
55
- private
56
-
57
- attr_reader :page, :output
58
-
59
- def log(dt, _step)
60
- elapsed_time = sprintf('%02i:%02i:%02i', dt / 3600, dt / 60, dt % 60)
61
- output.puts " done. [#{elapsed_time}]"
62
- end
63
-
64
- def wait_until_completed(step)
65
- start = Time.now
66
- output.print "Running step [#{step.index}/#{step.total}]: #{step}..."
67
- page.document.synchronize(MAX_INSTALL_STEP_SECONDS, errors: [TimeoutWaitingForStep]) do
68
- raise TimeoutWaitingForStep, "Timed out after #{MAX_INSTALL_STEP_SECONDS} seconds waiting for #{step.name} to finish.\n\n#{verbose_output}" unless step.finished?
69
- end
70
- duration = Time.now - start
71
-
72
- log(duration, step)
73
- end
74
-
75
- def modal
76
- Modal.new(page: page)
77
- end
78
-
79
- def flash_message
80
- FlashMessage.new(page: page)
81
- end
82
-
83
- def install_steps
84
- @install_steps ||= begin
85
- step_nodes = page.all('#install-steps .step')
86
- raise rails_500.error if rails_500?
87
- raise 'No install steps found' if step_nodes.empty?
88
-
89
- step_nodes.map.with_index(1) do |node, index|
90
- InstallStep.new(node: node, page: page, index: index, total: step_nodes.size)
91
- end
92
- end
93
- end
94
-
95
- def verbose_output
96
- Nokogiri::HTML(page.html).css('.output').text
97
- end
98
-
99
- def rails_500?
100
- rails_500.matches?
101
- end
102
-
103
- def rails_500
104
- Rails500.new(page: page)
105
- end
106
-
107
- class InstallStep
108
- class InstallStepNotPresent < InstallationError; end
109
-
110
- def initialize(node:, page:, index: index, total: total)
111
- @id = node['data-step-id']
112
- @page = page
113
- @index = index
114
- @total = total
115
- end
116
-
117
- def name
118
- node.text
119
- end
120
-
121
- def finished?
122
- state == 'finished'
123
- end
124
-
125
- def state
126
- node['data-step-state']
127
- end
128
-
129
- def to_s
130
- name
131
- end
132
-
133
- attr_reader :index, :total
134
-
135
- private
136
-
137
- attr_reader :page, :id
138
-
139
- def node
140
- page.find("[data-step-id='#{id}']")
141
- rescue Capybara::ElementNotFound
142
- raise InstallStepNotPresent, "The install step '#{id}'' is no longer on the page - has Ops Manager crashed?"
143
- end
144
- end
145
- end
146
- end
147
- end
148
- end
149
- end
@@ -1,83 +0,0 @@
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 'prof/ops_manager/web_app_internals/page/dashboard'
13
-
14
- module Prof
15
- class OpsManager
16
- class WebAppInternals
17
- module Page
18
- class Login
19
- def initialize(page:, url:, username:, password:, version:)
20
- @page = page
21
- @url = url
22
- @username = username
23
- @password = password
24
- @version = version
25
-
26
- resp = page.visit login_url
27
-
28
- if resp['status'] == 'fail'
29
- raise StandardError.new("Failed to fetch url: #{login_url}")
30
- end
31
- end
32
-
33
- def login
34
- puts "Logging into tempest at #{login_url}"
35
- if login_via_uaa?
36
- uaa_login
37
- else
38
- basic_login
39
- end
40
-
41
- Dashboard.new(page: page)
42
- end
43
-
44
- private
45
-
46
- attr_reader :page, :url, :username, :password, :version
47
-
48
- def login_url
49
- if login_via_uaa?
50
- uaa_login_url
51
- else
52
- basic_login_url
53
- end
54
- end
55
-
56
- def login_via_uaa?
57
- version >= Gem::Version.new("1.7")
58
- end
59
-
60
- def uaa_login_url
61
- URI.join(url, "uaa/login")
62
- end
63
-
64
- def basic_login_url
65
- URI.join(url, 'login')
66
- end
67
-
68
- def uaa_login
69
- page.fill_in 'username', with: username
70
- page.fill_in 'password', with: password
71
- page.click_on 'Sign in'
72
- end
73
-
74
- def basic_login
75
- page.fill_in 'login[user_name]', with: username
76
- page.fill_in 'login[password]', with: password
77
- page.click_on 'login-action'
78
- end
79
- end
80
- end
81
- end
82
- end
83
- end