Class: FruityBuilder::Execution

Inherits:
Object
  • Object
show all
Defined in:
lib/fruity_builder/lib/execution.rb

Overview

Provides method to execute terminal commands in a reusable way

Constant Summary collapse

COMMAND_TIMEOUT =

execute_with_timeout_and_retry constants

30
COMMAND_RETRIES =

base number of seconds to wait until adb command times out

5

Class Method Summary collapse

Class Method Details

.execute(command) ⇒ Object

actual maximum seconds waited before timeout is (1 * s) + (2 * s) + (3 * s) … up to (n * s) where s = COMMAND_TIMEOUT n = COMMAND_RETRIES



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/fruity_builder/lib/execution.rb', line 19

def self.execute(command)
  # Execute out to shell
  # Returns a struct collecting the execution results
  # struct = DeviceAPI::ADB.execute( 'adb devices' )
  # struct.stdout #=> "std out"
  # struct.stderr #=> ''
  # strict.exit #=> 0
  result = OpenStruct.new

  stdout, stderr, status = Open3.capture3(command)

  result.exit = status.exitstatus
  result.stdout = stdout
  result.stderr = stderr

  result
end

.execute_with_timeout_and_retry(command) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/fruity_builder/lib/execution.rb', line 37

def self.execute_with_timeout_and_retry(command)
  retries_left = COMMAND_RETRIES
  cmd_successful = false
  result = 0

  while (retries_left > 0) and (cmd_successful == false) do
    begin
      ::Timeout.timeout(COMMAND_TIMEOUT) do
        result = execute(command)
        cmd_successful = true
      end
    rescue ::Timeout::Error
      retries_left -= 1
      if retries_left > 0
        FruityBuilder.log.error "Command #{command} timed out after #{COMMAND_TIMEOUT.to_s} sec, retrying,"\
            + " #{retries_left.to_s} attempts left.."
      end
    end
  end

  if retries_left < COMMAND_RETRIES # if we had to retry
    if cmd_successful == false
      msg = "Command #{command} timed out after #{COMMAND_RETRIES.to_s} retries. !"\
        + " Exiting.."
      FruityBuilder.log.fatal(msg)
      raise FruityBuilder::CommandTimeoutError.new(msg)
    else
      FruityBuilder.log.info "Command #{command} succeeded execution after retrying"
    end
  end

  result
end