Skip to content

Commit

Permalink
Merge f8b826e into d063fb6
Browse files Browse the repository at this point in the history
  • Loading branch information
smarr committed Feb 12, 2023
2 parents d063fb6 + f8b826e commit 320ef9d
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 16 deletions.
8 changes: 8 additions & 0 deletions rebench/environment.py
Expand Up @@ -41,6 +41,14 @@ def extract_base(branch_or_tag):
return branch_or_tag.replace('HEAD -> ', '')


def git_not_available():
return _exec(['git', '--version']) is None


def git_repo_not_initialized():
return _exec(['git', 'rev-parse']) is None


def determine_source_details(configurator):
global _source # pylint: disable=global-statement
if _source:
Expand Down
19 changes: 15 additions & 4 deletions rebench/executor.py
Expand Up @@ -402,8 +402,9 @@ def process_output(self, name, stdout_result, stderr_result):
log_file.write(stderr_result)

def execute_run(self, run_id):
gauge_adapter = self._get_gauge_adapter_instance(
run_id.get_gauge_adapter_name())
gauge_adapter = self._get_gauge_adapter_instance(run_id)
if gauge_adapter is None:
return True

cmdline = self._construct_cmdline(run_id, gauge_adapter)

Expand Down Expand Up @@ -441,8 +442,18 @@ def execute_run(self, run_id):

return terminate

def _get_gauge_adapter_instance(self, adapter_name):
return instantiate_adapter(adapter_name, self._include_faulty, self)
def _get_gauge_adapter_instance(self, run_id):
adapter_name = run_id.get_gauge_adapter_name()
adapter = instantiate_adapter(adapter_name,
self._include_faulty,
self)

if adapter is None:
run_id.fail_immediately()
msg = "{ind}Couldn't find gauge adapter: %s\n" % adapter_name
self.ui.error_once(msg, run_id)

return adapter

def _generate_data_point(self, cmdline, gauge_adapter, run_id,
termination_check):
Expand Down
6 changes: 3 additions & 3 deletions rebench/tests/configurator_test.py
Expand Up @@ -52,15 +52,15 @@ def test_number_of_experiments_testconf(self):
self.ui, None, None, 'all')
self.assertEqual(6, len(cnf.get_experiments()))

def test_get_experiment(self):
def _get_experiment(self):
cnf = Configurator(load_config(self._path + '/small.conf'), DataStore(self.ui),
self.ui, None)
exp = cnf.get_experiment('Test')
self.assertIsNotNone(exp)
return exp

def test_get_runs(self):
exp = self.test_get_experiment()
exp = self._get_experiment()
runs = exp.runs
self.assertEqual(2 * 2 * 2, len(runs))

Expand Down Expand Up @@ -139,7 +139,7 @@ def test_machine_filter_m1_and_m2(self):

# allow command-line execution
def test_suite():
return unittest.makeSuite(ConfiguratorTest)
unittest.defaultTestLoader.loadTestsFromTestCase(ConfiguratorTest)


if __name__ == "__main__":
Expand Down
8 changes: 5 additions & 3 deletions rebench/tests/environment_test.py
@@ -1,13 +1,15 @@
from unittest import TestCase
from unittest import TestCase, skipIf

from ..denoise import DenoiseResult
from ..environment import determine_source_details, determine_environment,\
init_environment, extract_base
init_environment, extract_base, git_not_available, git_repo_not_initialized
from ..ui import TestDummyUI


class ReBenchTestCase(TestCase):
class EnvironmentTest(TestCase):

@skipIf(git_not_available() or git_repo_not_initialized(),
"git seems not to be installed, or on the path, or the .git dir is missing")
def test_source_details(self):
details = determine_source_details(None)
self.assertEqual(len(details['commitId']), 40)
Expand Down
2 changes: 1 addition & 1 deletion rebench/tests/executor_test.py
Expand Up @@ -184,7 +184,7 @@ def test_determine_exp_name_and_filters_only_others(self):


def test_suite():
return unittest.makeSuite(ExecutorTest)
unittest.defaultTestLoader.loadTestsFromTestCase(ExecutorTest)


if __name__ == "__main__":
Expand Down
4 changes: 4 additions & 0 deletions rebench/tests/perf/issue_166_profiling_test.py
@@ -1,5 +1,7 @@
from unittest import skipIf
from ..mock_http_server import MockHTTPServer
from ...configurator import Configurator, load_config
from ...environment import git_not_available, git_repo_not_initialized
from ...executor import Executor
from ...model.profile_data import ProfileData
from ...persistence import DataStore
Expand Down Expand Up @@ -148,6 +150,8 @@ def test_execute_profiling_profile2(self):
self.assertEqual(7, run_id.completed_invocations)
self.assertEqual(7, run_id.get_number_of_data_points())

@skipIf(git_not_available() or git_repo_not_initialized(),
"git source info not available, but needed for reporting to ReBenchDB")
def test_send_to_rebench_db(self):
server = MockHTTPServer()
port = server.get_free_port()
Expand Down
4 changes: 4 additions & 0 deletions rebench/tests/persistency_test.py
Expand Up @@ -17,12 +17,14 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
from unittest import skipIf
from .mock_http_server import MockHTTPServer
from .rebench_test_case import ReBenchTestCase

from ..persistence import DataStore

from ..configurator import Configurator, load_config
from ..environment import git_not_available, git_repo_not_initialized
from ..executor import Executor
from ..model.benchmark import Benchmark
from ..model.benchmark_suite import BenchmarkSuite
Expand Down Expand Up @@ -115,6 +117,8 @@ def test_data_discarding(self):

self._assert_runs(cnf2, 1, 10, 10)

@skipIf(git_not_available() or git_repo_not_initialized(),
"git source info not available, but needed for reporting to ReBenchDB")
def test_rebench_db(self):
option_parser = ReBench().shell_options()
cmd_config = option_parser.parse_args(['--experiment=Test', 'persistency.conf'])
Expand Down
2 changes: 1 addition & 1 deletion rebench/tests/subprocess_timeout_test.py
Expand Up @@ -65,7 +65,7 @@ def test_exec_with_timeout_python_interpreter(self):


def test_suite():
return unittest.makeSuite(SubprocessTimeoutTest)
unittest.defaultTestLoader.loadTestsFromTestCase(SubprocessTimeoutTest)


if __name__ == "__main__":
Expand Down
8 changes: 7 additions & 1 deletion rebench/tests/ui_test.py
Expand Up @@ -2,7 +2,7 @@
from yaml import YAMLError

from ..configurator import load_config
from ..ui import UIError, escape_braces
from ..ui import UI, UIError, escape_braces

from .rebench_test_case import ReBenchTestCase

Expand Down Expand Up @@ -36,3 +36,9 @@ def test_config_not_proper_yaml(self):
with self.assertRaises(UIError) as err:
load_config(self._path + '/broken-yaml.conf')
self.assertIsInstance(err.exception.source_exception, YAMLError)

def test_is_first_error_with(self):
ui = UI()
self.assertTrue(ui._is_first_error_with("a"))
self.assertFalse(ui._is_first_error_with("a"))
self.assertTrue(ui._is_first_error_with("b"))
29 changes: 26 additions & 3 deletions rebench/ui.py
Expand Up @@ -19,6 +19,7 @@
# IN THE SOFTWARE.
import sys

from io import StringIO
from os import getcwd

from humanfriendly.terminal import terminal_supports_colors, ansi_wrap, auto_encode
Expand All @@ -43,6 +44,7 @@ def __init__(self):
self._prev_cwd = None
self._progress_spinner = None
self._need_to_erase_spinner = False
self._error_once_cache = set()

def init(self, verbose, debug):
self._verbose = verbose
Expand Down Expand Up @@ -112,12 +114,15 @@ def output(self, text, *args, **kw):
auto_encode(sys.stdout, text + '\n', *args, **kw)
sys.stdout.flush()

def _output_on_stream(self, tmp_stream, out_stream, text, color, *args, **kw):
if terminal_supports_colors(out_stream):
text = ansi_wrap(text, color=color)
auto_encode(tmp_stream, text, ind=_DETAIL_INDENT, *args, **kw)

def _output(self, text, color, *args, **kw):
self._erase_spinner()

if terminal_supports_colors(sys.stdout):
text = ansi_wrap(text, color=color)
auto_encode(sys.stdout, text, ind=_DETAIL_INDENT, *args, **kw)
self._output_on_stream(sys.stdout, sys.stdout, text, color, *args, **kw)
sys.stdout.flush()

def warning(self, text, run_id=None, cmd=None, cwd=None, **kw):
Expand All @@ -128,6 +133,21 @@ def error(self, text, run_id=None, cmd=None, cwd=None, **kw):
self._output_detail_header(run_id, cmd, cwd)
self._output(text, 'red', **kw)

def _is_first_error_with(self, text):
if text not in self._error_once_cache:
self._error_once_cache.add(text)
return True
return False

def error_once(self, text, run_id=None, cmd=None, cwd=None, **kw):
stream = StringIO("")
self._output_on_stream(stream, sys.stdout, text, 'red', **kw)
stream_str = stream.getvalue()

if self._is_first_error_with(stream_str):
self._output_detail_header(run_id, cmd, cwd)
self._output(text, 'red', **kw)

def verbose_output_info(self, text, run_id=None, cmd=None, cwd=None, **kw):
if self._verbose:
self._output_detail_header(run_id, cmd, cwd)
Expand Down Expand Up @@ -191,6 +211,9 @@ def warning(self, text, run_id=None, cmd=None, cwd=None, **kw):
def error(self, text, run_id=None, cmd=None, cwd=None, **kw):
pass

def error_once(self, text, run_id=None, cmd=None, cwd=None, **kw):
pass

def verbose_output_info(self, text, run_id=None, cmd=None, cwd=None, **kw):
pass

Expand Down

0 comments on commit 320ef9d

Please sign in to comment.