示例#1
0
  def send_rpc(self,
               cmd_name,
               arg,
               expected_rpc_error_codes=()):
    """
    Send RPC 'cmd_name' via RpcClient. Returns the deserialized protobuf
    response from the server.

    If 'expected_rpc_error_codes' is not empty, then we expect the RPC to
    fail with the given RPC error codes.
    """
    arg_data = arg.SerializeToString()
    rpc_client = AgentRpcClient("127.0.0.1")
    ret, err = rpc_client.send_rpc(cmd_name, arg)
    if expected_rpc_error_codes:
      if err is None:
        self.fail("RPC '%s' should have failed with error codes '%s'" % (
          cmd_name, ", ".join(map(str, expected_rpc_error_codes))))
      actual_rpc_error_codes = err.error_codes
      actual_rpc_error_codes_set = set(actual_rpc_error_codes)
      expected_rpc_error_codes_set = set(expected_rpc_error_codes)
      self.assertEqual(actual_rpc_error_codes_set,
                       expected_rpc_error_codes_set)
    else:
      self.assert_(ret is not None)
    return ret
示例#2
0
    def check_cmd(self, cmd_id, desired_state=CmdStatus.kSucceeded):
        """Check if a command has reached a desired state.

    Args:
      cmd_id (str): ID of the command to check.
      desired_state (CmdStatus): Desired command state.

    Returns:
      CmdStatus protobuf on success, and None if the command is in progress.

    Raises:
      CurieTestException if the command has reached a terminal state that is
        different from the desired state.
    """
        rpc_client = AgentRpcClient(self._vm_ip)
        arg = charon_agent_interface_pb2.CmdStatusArg()
        arg.cmd_id = cmd_id
        ret, err = rpc_client.CmdStatus(arg)
        if ret.cmd_status.state == desired_state:
            # Command has reached the desired state. The desired state could be a
            # non-terminal state or a terminal state.
            cmd_status = ret.cmd_status
            CHECK(cmd_status)
            return cmd_status
        elif ret.cmd_status.state != CmdStatus.kRunning:
            # Command has reached a terminal state. If we're here, this implies
            # that the command's terminal state is not the desired state because
            # if it was, then we would have already returned above.
            CHECK_NE(ret.cmd_status.state, desired_state)
            error_msg = ("Command %s terminal state %s != desired state %s" %
                         (cmd_id, CmdStatus.Type.Name(ret.cmd_status.state),
                          CmdStatus.Type.Name(desired_state)))
            raise CurieTestException(error_msg)
        return None
示例#3
0
 def _test_body(self, user, hostname_stdout):
   # Test CmdExecute.
   arg = charon_agent_interface_pb2.CmdExecuteArg()
   arg.user = user
   arg.cmd_id = str(int(time.time() * 1e6))
   arg.cmd = "hostname"
   self.send_rpc("CmdExecute", arg)
   self.send_rpc("CmdExecute", arg)  # Idempotent so this shouldn't fail.
   # Test CmdStatus while waiting for the command to finish and CmdStop.
   ret = self.wait_for_cmd(arg.cmd_id, include_output=True)
   self.cmd_stop(arg.cmd_id)
   self.cmd_stop(arg.cmd_id)  # Idempotent so this shouldn't fail.
   self.assert_(ret.cmd_status.HasField("exit_status"))
   self.assertEqual(ret.cmd_status.exit_status, 0)
   self.assert_(ret.HasField("stdout"))
   self.assert_(ret.HasField("stderr"))
   self.assertEqual(ret.stdout, hostname_stdout)
   self.assertEqual(ret.stderr, "")
   # Test CmdList.
   ret = self.cmd_list()
   self.assertEqual(len(ret.cmd_summary_list), 1)
   self.assertEqual(ret.cmd_summary_list[0].cmd_id, arg.cmd_id)
   self.assertEqual(ret.cmd_summary_list[0].cmd, "hostname")
   self.assertEqual(ret.cmd_summary_list[0].state, CmdStatus.kSucceeded)
   # Test CmdRemove.
   self.cmd_remove(arg.cmd_id)
   ret = self.cmd_list()
   self.assertEqual(len(ret.cmd_summary_list), 0)
   self.cmd_remove(arg.cmd_id)  # Idempotent so this shouldn't fail.
   ret = self.cmd_list()
   self.assertEqual(len(ret.cmd_summary_list), 0)
   # Test method for simulating synchronous commands.
   rpc_client = AgentRpcClient("127.0.0.1")
   arg = charon_agent_interface_pb2.CmdExecuteArg()
   arg.user = user
   arg.cmd_id = str(int(time.time() * 1e6))
   arg.cmd = "hostname"
   exit_status, stdout, stderr = \
       rpc_client.cmd_execute_sync(arg, 10, include_output=True)
   self.assertEqual(exit_status, 0)
   self.assertEqual(stdout, hostname_stdout)
   self.assertEqual(stderr, "")
   ret = self.cmd_list()
   self.assertEqual(len(ret.cmd_summary_list), 0)  # Should be removed.
   arg = charon_agent_interface_pb2.CmdExecuteArg()
   arg.user = user
   arg.cmd_id = str(int(time.time() * 1e6))
   arg.cmd = "hostname"
   exit_status, stdout, stderr = \
       rpc_client.cmd_execute_sync(arg, 10, include_output=False)
   self.assertEqual(exit_status, 0)
   self.assert_(stdout is None)
   self.assert_(stderr is None)
   ret = self.cmd_list()
   self.assertEqual(len(ret.cmd_summary_list), 0)  # Should be removed.
示例#4
0
 def execute_async(self, cmd_id, cmd, user="******"):
     "See Vm.execute_async documentation."
     rpc_client = AgentRpcClient(self._vm_ip)
     arg = charon_agent_interface_pb2.CmdExecuteArg()
     arg.user = user
     arg.cmd_id = cmd_id
     arg.cmd = cmd
     log.debug("%s executing async command: %s", self, cmd)
     ret, err = rpc_client.CmdExecute(arg)
     if err is not None:
         raise CurieException(
             err.error_codes[0],
             "Command %s (%s) failed, err %s" % (cmd, cmd_id, err))
示例#5
0
    def stop_cmd(self, cmd_id):
        """Stop a command running on this VM.

    The command specified by cmd_id must already be running.

    Args:
      cmd_id: (str) ID of the command to stop.

    Raises:
      CurieException: If stopping the command fails.
    """
        rpc_client = AgentRpcClient(self._vm_ip)
        arg = charon_agent_interface_pb2.CmdStopArg()
        arg.cmd_id = cmd_id
        log.debug("Stopping command with id: %s", cmd_id)
        ret, err = rpc_client.CmdStop(arg)
        if err is not None:
            raise CurieException(
                CurieError.kInternalError,
                "Stopping command with id '%s' failed: %s" % (cmd_id, err))
示例#6
0
 def execute_sync(self,
                  cmd_id,
                  cmd,
                  timeout_secs,
                  user="******",
                  include_output=False):
     "See Vm.execute_sync documentation."
     rpc_client = AgentRpcClient(self._vm_ip)
     arg = charon_agent_interface_pb2.CmdExecuteArg()
     arg.user = user
     arg.cmd_id = cmd_id
     arg.cmd = cmd
     log.debug("%s executing synchronous command: %s", self, cmd)
     exit_status, stdout, stderr = \
       rpc_client.cmd_execute_sync(arg,
                                   timeout_secs,
                                   include_output=include_output)
     if exit_status != 0:
         raise CurieException(
             CurieError.kInternalError,
             "Command %s (%s) failed, exit_status %d, %s, %s" %
             (cmd, cmd_id, exit_status, stdout, stderr))
     return (exit_status, stdout, stderr)
示例#7
0
 def transfer_from(self,
                   remote_path,
                   local_path,
                   timeout_secs,
                   recursive=False):
     """See Vm.transfer_from documentation.
 """
     if not recursive:
         # If we're fetching a single file, use a FileGet RPC which is much faster
         # than forking and running scp.
         rpc_client = AgentRpcClient(self._vm_ip)
         arg = charon_agent_interface_pb2.FileGetArg()
         arg.path = remote_path
         try:
             ret, err = rpc_client.FileGet(arg)
         except CurieException as ex:
             log.debug("Caught CurieException during FileGet")
             ret, err = None, ex.error_msg
         if err is not None:
             log.exception("Error fetching file %s from %s", remote_path,
                           self._vm_ip)
             result = False
         else:
             open(local_path, "w").write(ret.data)
             result = True
     else:
         result = self._scp_client.transfer_from(remote_path,
                                                 local_path,
                                                 timeout_secs,
                                                 recursive=recursive)
     if result:
         log.debug("Transferred %s from %s:%s", local_path, self,
                   remote_path)
     else:
         log.error("Failed to transfer %s from %s:%s", local_path, self,
                   remote_path)
     return result