rhc 1.1.11 → 1.2.7

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 (45) hide show
  1. data/features/cartridge.feature +14 -1
  2. data/features/domain.feature +1 -1
  3. data/features/lib/rhc_helper.rb +3 -3
  4. data/features/lib/rhc_helper/app.rb +11 -3
  5. data/features/lib/rhc_helper/cartridge.rb +8 -0
  6. data/features/lib/rhc_helper/domain.rb +8 -15
  7. data/features/lib/rhc_helper/httpify.rb +11 -6
  8. data/features/lib/rhc_helper/runnable.rb +43 -7
  9. data/features/sshkey.feature +3 -4
  10. data/features/step_definitions/application_steps.rb +5 -5
  11. data/features/step_definitions/cartridge_steps.rb +12 -0
  12. data/features/step_definitions/client_steps.rb +3 -2
  13. data/features/step_definitions/sshkey_steps.rb +3 -3
  14. data/features/support/assumptions.rb +11 -11
  15. data/features/support/before_hooks.rb +23 -5
  16. data/features/support/env.rb +14 -4
  17. data/lib/rhc-common.rb +5 -2
  18. data/lib/rhc/cartridge_helpers.rb +7 -1
  19. data/lib/rhc/command_runner.rb +8 -4
  20. data/lib/rhc/commands.rb +6 -0
  21. data/lib/rhc/commands/app.rb +15 -7
  22. data/lib/rhc/commands/base.rb +3 -3
  23. data/lib/rhc/commands/cartridge.rb +78 -2
  24. data/lib/rhc/commands/port-forward.rb +137 -24
  25. data/lib/rhc/exceptions.rb +23 -8
  26. data/lib/rhc/helpers.rb +25 -4
  27. data/lib/rhc/output_helpers.rb +23 -0
  28. data/lib/rhc/rest.rb +38 -19
  29. data/lib/rhc/rest/base.rb +7 -3
  30. data/lib/rhc/rest/cartridge.rb +10 -1
  31. data/lib/rhc/usage_templates/command_help.erb +12 -12
  32. data/lib/rhc/usage_templates/command_syntax_help.erb +1 -1
  33. data/lib/rhc/usage_templates/help.erb +3 -3
  34. data/lib/rhc/usage_templates/missing_help.erb +1 -1
  35. data/lib/rhc/version.rb +1 -5
  36. data/lib/rhc/wizard.rb +4 -32
  37. data/spec/rest_spec_helper.rb +18 -4
  38. data/spec/rhc/commands/cartridge_spec.rb +91 -0
  39. data/spec/rhc/commands/domain_spec.rb +6 -2
  40. data/spec/rhc/commands/port-forward_spec.rb +95 -54
  41. data/spec/rhc/commands/snapshot_spec.rb +5 -0
  42. data/spec/rhc/rest_spec.rb +23 -2
  43. data/spec/rhc/wizard_spec.rb +9 -12
  44. data/spec/spec_helper.rb +5 -0
  45. metadata +228 -224
@@ -1,4 +1,4 @@
1
- @single_cartridge @domain_required
1
+ @single_cartridge @domain_required @cartridge_storage_user_required
2
2
  Feature: Single Cartridge Tests
3
3
 
4
4
  # Need to keep these outlines duplicated until we update cucumber to allow tagged examples
@@ -32,3 +32,16 @@ Feature: Single Cartridge Tests
32
32
  | php-5.3 | PHP 5.3 |
33
33
  | mongodb-2.2 | MongoDB NoSQL |
34
34
  | cron-1.4 | Cron 1.4 |
35
+
36
+ # Commenting this out for US2438
37
+ # Scenario Outline: Cartridge Storage
38
+ # Given we have a running mysql-5.1 cartridge
39
+ # When we <action> storage for the mysql-5.1 cartridge
40
+ # Then the additional cartridge storage amount should be <total>
41
+ #
42
+ # Examples:
43
+ # | action | total |
44
+ # | show | None |
45
+ # | add 5GB | 5GB |
46
+ # | remove 3GB | 2GB |
47
+ # | set 4GB | 4GB |
@@ -17,7 +17,7 @@ Feature: Existing Domain Operations
17
17
 
18
18
  Scenario: Domain Create Fails
19
19
  When rhc domain create is called
20
- Then the domain command should fail with an exitcode of 128
20
+ Then the domain command should fail with an exitcode of 103
21
21
 
22
22
  Scenario: Domain Delete
23
23
  When domain is deleted
@@ -6,13 +6,13 @@ require 'tmpdir'
6
6
  module RHCHelper
7
7
  TEMP_DIR = File.join(Dir.tmpdir, "rhc") unless const_defined?(:TEMP_DIR)
8
8
  # The regex to parse the UUID output from the create app results
9
- UUID_OUTPUT_PATTERN = %r|UUID\s*=\s*(.+)| unless const_defined?(:UUID_OUTPUT_PATTERN)
9
+ UUID_OUTPUT_PATTERN = /UUID\s*(?:\:|=)\s*(.+)/i unless const_defined?(:UUID_OUTPUT_PATTERN)
10
10
  # The regex to parse the Gear Profile output from the create app results
11
- GEAR_PROFILE_OUTPUT_PATTERN = %r|Application Info.*Gear Size\s*=\s*(\w+)|m unless const_defined?(:GEAR_PROFILE_OUTPUT_PATTERN)
11
+ GEAR_PROFILE_OUTPUT_PATTERN = /Info.*Gear Size\s*(?:\:|=)\s*(\w+)/m unless const_defined?(:GEAR_PROFILE_OUTPUT_PATTERN)
12
12
  # Regex to parse passwords out of logging messages
13
13
  PASSWORD_REGEX = / -p [^\s]* / unless const_defined?(:PASSWORD_REGEX)
14
14
  end
15
-
15
+ \
16
16
  require 'rhc_helper/loggable'
17
17
  require 'rhc_helper/commandify'
18
18
  require 'rhc_helper/httpify'
@@ -36,15 +36,23 @@ module RHCHelper
36
36
  # 2 - password
37
37
  # 3 - upload SSH keys
38
38
  # 4 - if no namespace is found, create namespace? (blank is no)
39
+ args = [$username, $password]
40
+ args << 'yes' unless ($keyed_users ||= []).include?($username)
41
+ puts "User #{$username} has no keys" if args.length == 3
42
+ args << '' # always skip namespace
39
43
  if $namespace
40
44
  # Namespace is already created, so don't pass anything in
41
45
  logger.info("Namespace (#{$namespace}) should be found by the wizard")
42
- run("rhc setup", nil, [$username, $password, 'yes', ""])
46
+ run("rhc setup", nil, args) do |exitstatus, out, err, arg|
47
+ raise "Unmatched namespace #{$namespace}" unless out.include?($namespace)
48
+ end
43
49
  else
44
50
  # Pass in a blank value for namespace to create in the next step
51
+ args << ''
45
52
  logger.info("Skipping namespace creation")
46
- run("rhc setup", nil, [$username, $password, 'yes', "", ""])
53
+ run("rhc setup", nil, args)
47
54
  end
55
+ $keyed_users << $username
48
56
  end
49
57
 
50
58
  def self.create_unique(type, scalable, gear_profile=nil, prefix="test")
@@ -58,7 +66,7 @@ module RHCHelper
58
66
  test_names << app.name if app.name.start_with?(prefix)
59
67
  end
60
68
  end
61
-
69
+
62
70
  loop do
63
71
  # Generate a random application name
64
72
  chars = ("1".."9").to_a
@@ -78,6 +78,14 @@ module RHCHelper
78
78
  status
79
79
  end
80
80
 
81
+ def storage(cartridge, args)
82
+ output = nil
83
+ rhc_cartridge("storage #{cartridge} #{args}") do |exitstatus, out, err, arg|
84
+ output = out.split(" ")[-1]
85
+ end
86
+ output
87
+ end
88
+
81
89
  def show
82
90
  result = ""
83
91
  rhc_cartridge('show') do |exitstatus, out, err, arg|
@@ -27,13 +27,14 @@ module RHCHelper
27
27
 
28
28
  def self.create_if_needed(prefix="test")
29
29
  unless $namespace
30
- $namespace = unique_namespace(prefix)
31
- # Create the domain
32
- rhc_domain_create
33
-
34
- # Write the new domain to a file in the temp directory
35
- File.open(File.join(RHCHelper::TEMP_DIR, 'namespace'), 'w') do |f|
36
- f.write($namespace)
30
+ client = RHC::Rest::Client.new($end_point, $username, $password)
31
+ domain = client.domains.first
32
+ if domain
33
+ $namespace = domain.id
34
+ else
35
+ $namespace = unique_namespace(prefix)
36
+ # Create the domain
37
+ rhc_domain_create
37
38
  end
38
39
  end
39
40
  end
@@ -45,9 +46,6 @@ module RHCHelper
45
46
  def self.delete
46
47
  rhc_domain_delete
47
48
  $namespace = nil
48
- # Write the new domain to a file in the temp directory
49
- namespace_file = File.join(RHCHelper::TEMP_DIR, 'namespace')
50
- File.delete(namespace_file) if File.exists?(namespace_file)
51
49
  end
52
50
 
53
51
  def self.update(prefix="update")
@@ -55,12 +53,7 @@ module RHCHelper
55
53
  $namespace = unique_namespace(prefix)
56
54
  rhc_domain_update
57
55
 
58
- namespace_file = File.join(RHCHelper::TEMP_DIR, 'namespace')
59
56
  if @exitcode == 0
60
- # Write the new domain to a file in the temp directory
61
- File.open(namespace_file, 'w') do |f|
62
- f.write($namespace)
63
- end
64
57
  else
65
58
  $namespace = $old_namespace
66
59
  end
@@ -70,25 +70,26 @@ module RHCHelper
70
70
  begin
71
71
  timeout(options[:timeout]) do
72
72
  loop do
73
+ logger.debug "HTTP_CHECK: Requesting: #{uri}"
73
74
  # Send the HTTP request
74
75
  response = begin
75
76
  http = http_instance(uri,options[:http_timeout])
76
- logger.debug "Requesting: #{uri}"
77
77
  http.send_request(
78
78
  options[:method].to_s.upcase, # Allow options to be a symbol
79
79
  uri.request_uri, nil, headers
80
80
  )
81
81
  rescue Exception => e
82
82
  # Pass these up so we can check them
83
- return e
83
+ e
84
84
  end
85
-
85
+ logger.debug "HTTP_CHECK: Response: #{response.class}"
86
86
  case response
87
87
  # Catch any response if we're expecting it or redirection
88
88
  when expected.class, Net::HTTPRedirection
89
89
  break
90
90
  # Retry these responses
91
- when Net::HTTPServiceUnavailable, SocketError
91
+ when Net::HTTPServiceUnavailable, SocketError, Timeout::Error
92
+ logger.debug "HTTP_CHECK: Error #{response.message}"
92
93
  my_sleep(response,expected,start,options)
93
94
  else
94
95
  case expected
@@ -123,13 +124,17 @@ module RHCHelper
123
124
 
124
125
  def is_inaccessible?(options = {})
125
126
  check_response(options.merge({
126
- :expected => Net::HTTPServiceUnavailable
127
+ :expected => Net::HTTPServiceUnavailable,
128
+ :http_timeout => 2,
129
+ :timeout => 60,
127
130
  }))
128
131
  end
129
132
 
130
133
  def is_accessible?(options = {})
131
134
  check_response(options.merge({
132
- :expected => Net::HTTPSuccess
135
+ :expected => Net::HTTPSuccess,
136
+ :http_timeout => 20,
137
+ :timeout => 180,
133
138
  }))
134
139
  end
135
140
 
@@ -1,10 +1,28 @@
1
1
  require 'open4'
2
2
  require 'timeout'
3
+ require 'iconv'
4
+ require 'rubygems'
3
5
 
4
6
  module RHCHelper
5
7
  module Runnable
6
8
  include Loggable
7
9
 
10
+ class StringTee < StringIO
11
+ attr_reader :tee
12
+ def initialize(other)
13
+ @tee = other
14
+ super()
15
+ end
16
+ def <<(buf)
17
+ tee << buf
18
+ super
19
+ end
20
+ end
21
+
22
+ def iconv_handler
23
+ @iconv ||= Iconv.new('UTF-8//IGNORE', 'UTF-8')
24
+ end
25
+
8
26
  def run(cmd, arg=nil, input=[])
9
27
  logger.info("Running: #{cmd}")
10
28
 
@@ -12,17 +30,35 @@ module RHCHelper
12
30
  output = nil
13
31
 
14
32
  # Don't let a command run more than 5 minutes
15
- Timeout::timeout(500) do
16
- pid, stdin, stdout, stderr = Open4::popen4 cmd
17
- input.each {|line| stdin.puts line}
18
- stdin.close
33
+ Timeout::timeout(240) do
34
+
35
+ stdout, stderr = (ENV['VERBOSE'] ? [$stdout, $stderr] : [logger, logger]).map{ |t| StringTee.new(t) }
36
+ stdin = input.inject(StringIO.new){ |io, s| io.puts s; io }
37
+ stdin.close_write
38
+ stdin.rewind
39
+ status = Open4.spawn(cmd, 'stdout' => stdout, 'stderr' => stderr, 'stdin' => stdin, 'quiet' => true)
40
+ out, err = [stdout, stderr].map(&:string)
41
+
42
+ #pid, stdin, stdout, stderr = Open4::popen4 cmd
43
+ #input.each {|line| stdin.puts line}
44
+ #stdin.close
19
45
 
20
46
  # Block until the command finishes
21
- ignored, status = Process::waitpid2 pid
22
- out = stdout.read.strip
23
- err = stderr.read.strip
47
+ #ignored, status = Process::waitpid2 pid
48
+ #out = stdout.read.strip
49
+ #err = stderr.read.strip
24
50
  stdout.close
25
51
  stderr.close
52
+
53
+ # Force the output to ASCII-only characters or logger will barf.
54
+ if (Gem::Version.new(RUBY_VERSION.dup) <=> Gem::Version.new('1.9.3')) >= 0
55
+ out.encode!('UTF-8', 'UTF-8', :undef => :replace, :invalid => :replace)
56
+ err.encode!('UTF-8', 'UTF-8', :undef => :replace, :invalid => :replace)
57
+ else
58
+ out = iconv_handler.iconv(out + ' ')[0..-2]
59
+ err = iconv_handler.iconv(err + ' ')[0..-2]
60
+ end
61
+
26
62
  logger.debug("Standard Output:\n#{out}")
27
63
  logger.debug("Standard Error:\n#{err}")
28
64
 
@@ -28,7 +28,7 @@ As an OpenShift user, I want to manage SSH keys with 'rhc sshkey' commands.
28
28
  @sshkey_add
29
29
  Scenario: invalid key name is given
30
30
  When a new SSH key "key1.pub" is added as "blah\\ss"
31
- Then the command exits with status code 128
31
+ Then the command exits with status code 117
32
32
 
33
33
  @sshkey_add
34
34
  Scenario: invalid SSH key is added
@@ -43,14 +43,13 @@ As an OpenShift user, I want to manage SSH keys with 'rhc sshkey' commands.
43
43
  @sshkey_add @key1
44
44
  Scenario: SSH key with the same name already exists
45
45
  When a new SSH key "key2.pub" is added as "key1"
46
- Then the command exits with status code 128
46
+ Then the command exits with status code 120
47
47
 
48
48
  @sshkey_add
49
49
  Scenario: SSH key with the identical content already exists
50
50
  Given a new SSH key "key1.pub" is added as "key1"
51
51
  And a new SSH key "key1.pub" is added as "key2"
52
- Then the command exits with status code 128
53
-
52
+ Then the command exits with status code 121
54
53
 
55
54
  @sshkey_remove @key1
56
55
  Scenario: SSH key is deleted successfully
@@ -25,9 +25,9 @@ Given /^an existing (or new )?(scaled )?(.+) (application with.*)$/ do |create,
25
25
  @app = nil if @app.nil? or not @app.is_created?
26
26
 
27
27
  if create && @app.nil?
28
- When "a #{scaled}#{type} application is created"
28
+ step "a #{scaled}#{type} application is created"
29
29
  embeds.each do |embed|
30
- When "the #{embed} cartridge is added"
30
+ step "the #{embed} cartridge is added"
31
31
  end
32
32
  end
33
33
 
@@ -45,7 +45,7 @@ end
45
45
  When /^(\d+) (.+) applications are created$/ do |app_count, type|
46
46
  old_app = @app
47
47
  @apps = app_count.to_i.times.collect do
48
- Then "a #{type} application is created"
48
+ step "a #{type} application is created"
49
49
  @app
50
50
  end
51
51
  @app = old_app
@@ -88,7 +88,7 @@ end
88
88
  Then /^the applications should be accessible?$/ do
89
89
  old_app = @app
90
90
  @apps.each do |app|
91
- Then "the application should be accessible"
91
+ step "the application should be accessible"
92
92
  end
93
93
  @app = old_app
94
94
  end
@@ -110,7 +110,7 @@ Then /^it should succeed$/ do
110
110
  end
111
111
 
112
112
  Then /^the application should be scalable/ do
113
- Then "the haproxy-1.4 cartridge should be running"
113
+ step "the haproxy-1.4 cartridge should be running"
114
114
  end
115
115
 
116
116
  Then /^the application should have a (.*) gear$/ do |gear_profile|
@@ -19,6 +19,8 @@ When /^the (.+) cartridge is (stopped|(?:re)?started)$/ do |name,command|
19
19
  'start'
20
20
  when :restarted
21
21
  'restart'
22
+ else
23
+ raise "Unrecognized command type #{status}"
22
24
  end
23
25
  @app.cartridge(name).send(cmd)
24
26
  end
@@ -31,6 +33,8 @@ Then /^the (.+) cartridge should be (.*)$/ do |name,status|
31
33
  "(.+) stopped"
32
34
  when :removed
33
35
  "Invalid cartridge specified: '#{name}'"
36
+ else
37
+ raise "Unrecognized status type #{status}"
34
38
  end
35
39
  @app.cartridge(name).status.should match(expected)
36
40
  end
@@ -51,6 +55,10 @@ When /^we list cartridges$/ do
51
55
  @exitcode, @cartridge_output = Cartridge.list
52
56
  end
53
57
 
58
+ When /^we (.+) storage for the (.+) cartridge$/ do |storage_action,cartridge|
59
+ @output = @app.cartridge(@cartridge_name).send(:storage, cartridge, "--#{storage_action}")
60
+ end
61
+
54
62
  Then /^the (\w+) scaling value should be (.*)$/ do |minmax,value|
55
63
  expected = {
56
64
  :min => "Minimum",
@@ -65,6 +73,10 @@ Then /^the (\w+) scaling value should be (.*)$/ do |minmax,value|
65
73
  @app.cartridge(@cartridge_name).send(:show).should match(regex)
66
74
  end
67
75
 
76
+ Then /^the additional cartridge storage amount should be (\w+)$/ do |value|
77
+ @output.should == value
78
+ end
79
+
68
80
  Then /^it should fail with code (\d+)$/ do |code|
69
81
  @exitcode.should == code.to_i
70
82
  end
@@ -22,6 +22,7 @@ Given /^the libra client tools$/ do
22
22
  end
23
23
 
24
24
  When /^the setup wizard is run$/ do
25
+ puts "Running setup"
25
26
  RHCHelper::App.rhc_setup
26
27
 
27
28
  # Force a refresh of the loaded RHC state
@@ -29,10 +30,10 @@ When /^the setup wizard is run$/ do
29
30
  end
30
31
 
31
32
  Then /^the client tools should be setup( if needed)?$/ do |setup|
32
- configured = (RHC::Config.has_local_config? or RHC::Config.has_opts_config?)
33
+ configured = (RHC::Config.default_rhlogin && RHC::Config.default_rhlogin == $username && $keyed_users.include?($username))
33
34
 
34
35
  if !configured && setup
35
- Then 'the setup wizard is run'
36
+ step 'the setup wizard is run'
36
37
  configured = (RHC::Config.has_local_config? or RHC::Config.has_opts_config?)
37
38
  end
38
39
 
@@ -9,7 +9,7 @@ When /^'rhc sshkey (\S+)( .*?)?'(?: command)? is run$/ do |subcommand, rest|
9
9
  end
10
10
 
11
11
  Given "the existing keys are listed" do
12
- When "'rhc sshkey list' is run"
12
+ step "'rhc sshkey list' is run"
13
13
  end
14
14
 
15
15
  Given /^the key "(.*?)" is (.*)$/ do |key,cmd|
@@ -19,12 +19,12 @@ Given /^the key "(.*?)" is (.*)$/ do |key,cmd|
19
19
  when "removed"
20
20
  "remove"
21
21
  end
22
- When "'rhc sshkey #{cmd} \"#{key}\"' is run"
22
+ step "'rhc sshkey #{cmd} \"#{key}\"' is run"
23
23
  end
24
24
 
25
25
  When /^a new SSH key "(.*?)" is added as "(.*)"$/ do |keyfile, name|
26
26
  keyfile = Sshkey.keyfile_path(keyfile)
27
- When "'rhc sshkey add #{name} #{keyfile}' is run"
27
+ step "'rhc sshkey add #{name} #{keyfile}' is run"
28
28
  end
29
29
 
30
30
  Then /^the command exits with status code (\d+)$/ do |arg1|
@@ -1,16 +1,16 @@
1
1
  Given 'we have the client tools setup' do
2
- When 'the libra client tools'
3
- When 'the client tools should be setup if needed'
2
+ step 'the libra client tools'
3
+ step 'the client tools should be setup if needed'
4
4
  end
5
5
 
6
6
  Given 'we have an existing domain' do
7
- When 'we have the client tools setup'
8
- When 'a new domain is needed and created'
7
+ step 'we have the client tools setup'
8
+ step 'a new domain is needed and created'
9
9
  begin
10
- When 'the key "key1" is shown'
11
- Then 'the output includes the key information for "key1"'
10
+ step 'the key "key1" is shown'
11
+ step 'the output includes the key information for "key1"'
12
12
  rescue Spec::Expectations::ExpectationNotMetError
13
- Given 'a new SSH key "key1.pub" is added as "key1"'
13
+ step 'a new SSH key "key1.pub" is added as "key1"'
14
14
  end
15
15
  end
16
16
 
@@ -26,9 +26,9 @@ Given /^we have a (.*) (.*) cartridge$/ do |status,type|
26
26
  # only try once
27
27
  retried = false
28
28
  begin
29
- When "the #{type} cartridge should be #{status}"
29
+ step "the #{type} cartridge should be #{status}"
30
30
  rescue Spec::Expectations::ExpectationNotMetError
31
- When "the #{type} cartridge is #{cmd}"
31
+ step "the #{type} cartridge is #{cmd}"
32
32
  (retried = true && retry) unless retried
33
33
  end
34
34
  end
@@ -42,8 +42,8 @@ Given /^we have a (stopped|running) application$/ do |state|
42
42
  end
43
43
 
44
44
  begin
45
- When "the application should #{before}"
45
+ step "the application should #{before}"
46
46
  rescue Spec::Expectations::ExpectationNotMetError
47
- When "the application is #{after}"
47
+ step "the application is #{after}"
48
48
  end
49
49
  end