91 lines
2.9 KiB
Python
91 lines
2.9 KiB
Python
# Lint as: python3
|
|
# Copyright 2019 Google LLC. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License,Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""Supporting tools and classes for diagnose_me."""
|
|
|
|
import json
|
|
import subprocess
|
|
from typing import List, Text
|
|
|
|
|
|
class ExecutorResponse(object):
|
|
"""Class for keeping track of output of _executor methods.
|
|
|
|
Data model for executing commands and capturing their response. This class
|
|
defines the data model layer for execution results, based on MVC design
|
|
pattern.
|
|
|
|
TODO() This class should be extended to contain data structure to better
|
|
represent the underlying data instaed of dict for various response types.
|
|
"""
|
|
|
|
def execute_command(self, command_list: List[Text]):
|
|
"""Executes the command in command_list.
|
|
|
|
sets values for _stdout,_std_err, and returncode accordingly.
|
|
|
|
TODO(): This method is kept in ExecutorResponse for simplicity, however this
|
|
deviates from MVP design pattern. It should be factored out in future.
|
|
|
|
Args:
|
|
command_list: A List of strings that represts the command and parameters
|
|
to be executed.
|
|
|
|
Returns:
|
|
Instance of utility.ExecutorResponse.
|
|
"""
|
|
|
|
try:
|
|
# TODO() switch to process.run to simplify the code.
|
|
process = subprocess.Popen(
|
|
command_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
stdout, stderr = process.communicate()
|
|
self._stdout = stdout.decode('utf-8')
|
|
self._stderr = stderr.decode('utf-8')
|
|
self._returncode = process.returncode
|
|
except OSError as e:
|
|
self._stderr = e
|
|
self._stdout = ''
|
|
self._returncode = e.errno
|
|
self._parse_raw_input()
|
|
return self
|
|
|
|
def _parse_raw_input(self):
|
|
"""Parses the raw input and popluates _json and _parsed properies."""
|
|
try:
|
|
self._parsed_output = json.loads(self._stdout)
|
|
self._json = self._stdout
|
|
except json.JSONDecodeError:
|
|
self._json = json.dumps(self._stdout)
|
|
self._parsed_output = self._stdout
|
|
|
|
@property
|
|
def parsed_output(self) -> Text:
|
|
"""Json load results of stdout or raw results if stdout was not Json."""
|
|
return self._parsed_output
|
|
|
|
@property
|
|
def has_error(self) -> bool:
|
|
"""Returns true if execution error code was not 0."""
|
|
return self._returncode != 0
|
|
|
|
@property
|
|
def json_output(self) -> Text:
|
|
"""Run results in stdout in json format."""
|
|
return self._parsed_output
|
|
|
|
@property
|
|
def stderr(self):
|
|
return self._stderr
|