summaryrefslogtreecommitdiff
path: root/testsuite/driver/testglobals.py
diff options
context:
space:
mode:
authorDavid Eichmann <davide@Well-Typed.com>2018-11-07 12:02:47 -0500
committerBen Gamari <ben@smart-cactus.org>2018-11-07 12:07:11 -0500
commit932cd41d8c7984c767c1b3b58e05146f69cc5c15 (patch)
tree41e77f048036a19100c5bee508c77b2ab8ec55d4 /testsuite/driver/testglobals.py
parent82a5c2410a47b16df09039b9786c2c0e34ba130e (diff)
downloadhaskell-932cd41d8c7984c767c1b3b58e05146f69cc5c15.tar.gz
testsuite: Save performance metrics in git notes.
This patch makes the following improvement: - Automatically records test metrics (per test environment) so that the programmer need not supply nor update expected values in *.T files. - On expected metric changes, the programmer need only indicate the direction of change in the git commit message. - Provides a simple python tool "perf_notes.py" to compare metrics over time. Issues: - Using just the previous commit allows performance to drift with each commit. - Currently we allow drift as we have a preference for minimizing false positives. - Some possible alternatives include: - Use metrics from a fixed commit per test: the last commit that allowed a change in performance (else the oldest metric) - Or use some sort of aggregate since the last commit that allowed a change in performance (else all available metrics) - These alternatives may result in a performance issue (with the test driver) having to heavily search git commits/notes. - Run locally, performance tests will trivially pass unless the tests were run locally on the previous commit. This is often not the case e.g. after pulling recent changes. Previously, *.T files contain statements such as: ``` stats_num_field('peak_megabytes_allocated', (2, 1)) compiler_stats_num_field('bytes allocated', [(wordsize(64), 165890392, 10)]) ``` This required the programmer to give the expected values and a tolerance deviation (percentage). With this patch, the above statements are replaced with: ``` collect_stats('peak_megabytes_allocated', 5) collect_compiler_stats('bytes allocated', 10) ``` So that programmer must only enter which metrics to test and a tolerance deviation. No expected value is required. CircleCI will then run the tests per test environment and record the metrics to a git note for that commit and push them to the git.haskell.org ghc repo. Metrics will be compared to the previous commit. If they are different by the tolerance deviation from the *.T file, then the corresponding test will fail. By adding to the git commit message e.g. ``` # Metric (In|De)crease <metric(s)> <options>: <tests> Metric Increase ['bytes allocated', 'peak_megabytes_allocated'] \ (test_env='linux_x86', way='default'): Test012, Test345 Metric Decrease 'bytes allocated': Test678 Metric Increase: Test711 ``` This will allow the noted changes (letting the test pass). Note that by omitting metrics or options, the change will apply to all possible metrics/options (i.e. in the above, an increase for all metrics in all test environments is allowed for Test711) phabricator will use the message in the description Reviewers: bgamari, hvr Reviewed By: bgamari Subscribers: rwbarton, carter GHC Trac Issues: #12758 Differential Revision: https://phabricator.haskell.org/D5059
Diffstat (limited to 'testsuite/driver/testglobals.py')
-rw-r--r--testsuite/driver/testglobals.py33
1 files changed, 24 insertions, 9 deletions
diff --git a/testsuite/driver/testglobals.py b/testsuite/driver/testglobals.py
index 311e39be7f..03a62503b4 100644
--- a/testsuite/driver/testglobals.py
+++ b/testsuite/driver/testglobals.py
@@ -31,6 +31,9 @@ class TestConfig:
self.accept_platform = False
self.accept_os = False
+ # File in which to save the performance metrics.
+ self.metrics_file = ''
+
# File in which to save the summary
self.summary_file = ''
@@ -122,6 +125,15 @@ class TestConfig:
# Should we skip performance tests
self.skip_perf_tests = False
+ # Only do performance tests
+ self.only_perf_tests = False
+
+ # Allowed performance changes (see perf_notes.get_allowed_perf_changes())
+ self.allowed_perf_changes = {}
+
+ # The test environment.
+ self.test_env = 'local'
+
global config
config = TestConfig()
@@ -156,6 +168,12 @@ class TestRun:
self.unexpected_failures = []
self.unexpected_stat_failures = []
+ # List of all metrics measured in this test run.
+ # [(change, PerfStat)] where change is one of the MetricChange
+ # constants: NewMetric, NoChange, Increase, Decrease.
+ # NewMetric happens when the previous git commit has no metric recorded.
+ self.metrics = []
+
global t
t = TestRun()
@@ -215,16 +233,14 @@ class TestOptions:
# extra files to copy to the testdir
self.extra_files = []
- # which -t numeric fields do we want to look at, and what bounds must
- # they fall within?
- # Elements of these lists should be things like
- # ('bytes allocated',
- # 9300000000,
- # 10)
- # To allow a 10% deviation from 9300000000.
- self.compiler_stats_range_fields = {}
+ # Map from metric to expectected value and allowed percentage deviation. e.g.
+ # { 'bytes allocated': (9300000000, 10) }
+ # To allow a 10% deviation from 9300000000 for the 'bytes allocated' metric.
self.stats_range_fields = {}
+ # Does this test the compiler's performance as opposed to the generated code.
+ self.is_compiler_stats_test = False
+
# should we run this test alone, i.e. not run it in parallel with
# any other threads
self.alone = False
@@ -292,4 +308,3 @@ default_testopts = TestOptions()
# (bug, directory, name) of tests marked broken
global brokens
brokens = []
-