prof 0.30.9 → 0.31.0

Sign up to get free protection for your applications and to get access to all the features.
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