class Kitchen::Driver::QMPClient

Public Class Methods

new(io, timeout = 1) click to toggle source
# File lib/kitchen/driver/qmpclient.rb, line 26
def initialize(io, timeout = 1)
  @io = io
  @ioa = [ io ]
  @timeout = timeout
  @buf = []
  readnext(timeout) or raise Timeout
  execute('qmp_capabilities') or raise Timeout
  self
end

Public Instance Methods

close() click to toggle source
# File lib/kitchen/driver/qmpclient.rb, line 61
def close
  @io.close
end
execute(cmd, timeout = @timeout) click to toggle source
# File lib/kitchen/driver/qmpclient.rb, line 36
def execute(cmd, timeout = @timeout)
  send( 'execute' => cmd )
  loop do
    ret = readnext(timeout) or raise Timeout
    if ret['return']
      return ret['return']
    end
  end
end
wait_for_eof(timeout = @timeout) click to toggle source
# File lib/kitchen/driver/qmpclient.rb, line 46
def wait_for_eof(timeout = @timeout)
  while IO.select(@ioa, nil, nil, timeout)
    begin
      loop { @io.read_nonblock(4096) }
    rescue EOFError
      return
    rescue Errno::ECONNRESET
      return
    rescue IO::WaitReadable
      # do nothing
    end
  end
  raise Timeout
end

Private Instance Methods

readnext(timeout) click to toggle source
# File lib/kitchen/driver/qmpclient.rb, line 71
def readnext(timeout)
  loop do
    if not @buf.empty? and @buf.last.match("\n")
      s = @buf.pop.split("\n", 2)
      @buf.push(s[0])
      obj = JSON.parse(@buf.join(''))
      @buf.clear
      @buf.push(s[1]) unless s[1].empty?
      return obj
    end

    loop do
      return nil unless IO.select(@ioa, nil, nil, timeout)
      begin
        @buf.push(@io.read_nonblock(4096))
      rescue IO::WaitReadable
        # do nothing
      else
        break
      end
    end
  end
end
send(obj) click to toggle source
# File lib/kitchen/driver/qmpclient.rb, line 67
def send(obj)
  @io.write("#{obj.to_json}\r\n")
end