| #!/usr/bin/env python |
| # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Tests for module csv_merger.""" |
| |
| import datetime |
| import filecmp |
| import os |
| import random |
| import scipy |
| import shutil |
| import tempfile |
| import unittest |
| |
| import csv_comparer |
| |
| |
| class TestCsvComparer(unittest.TestCase): |
| |
| def setUp(self): |
| self._test_csv_dir = os.path.join( |
| os.path.dirname(os.path.realpath(__file__)), |
| 'test_data', 'csv_comparer') |
| self._actual_output_dir = tempfile.mkdtemp() |
| |
| # Set mocks. |
| class _MockUtcNow(object): |
| @staticmethod |
| def strftime(format_str): |
| self.assertEqual('%Y-%m-%d %H:%M UTC', format_str) |
| return '2014-05-19 16:50 UTC' |
| class _MockDatetime(object): |
| @staticmethod |
| def utcnow(): |
| return _MockUtcNow() |
| self._original_datetime = datetime.datetime |
| datetime.datetime = _MockDatetime |
| |
| def tearDown(self): |
| shutil.rmtree(self._actual_output_dir) |
| datetime.datetime = self._original_datetime |
| |
| def _AssertHTMLFiles(self, sub_dir, additional_files=()): |
| # Ensure that the two html files we care about are as expected. |
| for html_file in ('index.html', 'fieldname1.html') + additional_files: |
| self.assertTrue( |
| filecmp.cmp(os.path.join(self._test_csv_dir, sub_dir, html_file), |
| os.path.join(self._actual_output_dir, html_file))) |
| |
| def test_E2EComparerWithDiscardOutliers(self): |
| comparer = csv_comparer.CsvComparer( |
| csv_file1=os.path.join(self._test_csv_dir, 'comparer_csv1.csv'), |
| csv_file2=os.path.join(self._test_csv_dir, 'comparer_csv2.csv'), |
| output_html_dir=self._actual_output_dir, |
| requester_email='superman@krypton.com', |
| chromium_patch_link='http://chromium-patch.com', |
| skia_patch_link='http://skia-patch.com', |
| raw_csv_nopatch='http://raw-csv-nopatch.com', |
| raw_csv_withpatch='http://raw-csv-withpatch.com', |
| variance_threshold=10, |
| absolute_url='', |
| min_pages_in_each_field=1, |
| discard_outliers=12.5, |
| num_repeated=3, |
| target_platform='Android', |
| crashed_instances='build1-b5 build10-b5', |
| missing_devices='build99-b5 build100-b5', |
| browser_args_nopatch='--test=1', |
| browser_args_withpatch='--test=2', |
| pageset_type='Mobile10k', |
| chromium_hash='abcdefg1234567', |
| skia_hash='tuvwxyz1234567', |
| missing_output_workers='1 3 100', |
| logs_link_prefix=('https://chrome-swarming.appspot.com/tasklist?' |
| 'l=500&f=runid:testing&f=name:perf_task_'), |
| description='E2EComparerWithDiscardOutliers', |
| total_archives='', |
| ) |
| comparer.Compare() |
| self._AssertHTMLFiles('discard_outliers') |
| |
| def test_E2EComparerWithNoDiscardOutliers(self): |
| comparer = csv_comparer.CsvComparer( |
| csv_file1=os.path.join(self._test_csv_dir, 'comparer_csv1.csv'), |
| csv_file2=os.path.join(self._test_csv_dir, 'comparer_csv2.csv'), |
| output_html_dir=self._actual_output_dir, |
| requester_email='superman@krypton.com', |
| chromium_patch_link='http://chromium-patch.com', |
| skia_patch_link='http://skia-patch.com', |
| raw_csv_nopatch='http://raw-csv-nopatch.com', |
| raw_csv_withpatch='http://raw-csv-withpatch.com', |
| variance_threshold=0, |
| absolute_url='', |
| min_pages_in_each_field=0, |
| discard_outliers=0, |
| num_repeated=3, |
| target_platform='Linux', |
| crashed_instances='', |
| missing_devices='', |
| browser_args_nopatch='', |
| browser_args_withpatch='', |
| pageset_type='10k', |
| chromium_hash='abcdefg1234567', |
| skia_hash='tuvwxyz1234567', |
| missing_output_workers='', |
| logs_link_prefix='', |
| description='E2EComparerWithNoDiscardOutliers', |
| total_archives='10', |
| ) |
| comparer.Compare() |
| self._AssertHTMLFiles('keep_outliers', |
| ('fieldname2.html', 'fieldname3.html')) |
| |
| def test_find95ConfidenceInterval(self): |
| random.seed(0) # avoid test flakiness |
| iterations = 100 |
| hits = 0 |
| for _ in range(iterations): |
| # Create random nopatch and withpatch values. |
| values1 = [random.gauss(0, 5) for x in range(1000)] |
| values2 = [random.gauss(0, 5) for x in range(1000)] |
| |
| field_values = [] |
| total_no_patch = 0 |
| total_with_patch = 0 |
| for i in range(1000): |
| field_values.append(csv_comparer.PageValues( |
| value1=values1[i], value2=values2[i], |
| # Below are unused values. |
| perc_diff=0, perc_change=0, pageset_link='', archive_link='', |
| traceUrls1=[], traceUrls2=[], page_name='')) |
| total_no_patch += values1[i] |
| total_with_patch += values2[i] |
| |
| field_totals = csv_comparer.FieldNameValues( |
| value1=total_no_patch, value2=total_with_patch, |
| # Below are unused values. |
| perc_diff=0, total_webpages_reported=0) |
| perc_change = csv_comparer._GetPercentageChange(total_no_patch, |
| total_with_patch) |
| field_totals.perc_change = perc_change |
| |
| low, high = csv_comparer.find95ConfidenceInterval(field_values, |
| field_totals) |
| hits += 1 if (low<=0 and high>=0) else 0 |
| |
| # CI should contain 0 roughly 95% of the time |
| p = scipy.stats.binomtest(hits, iterations, 0.95, "less") |
| print('scipy.stats.binomtest:', p) |
| assert p.pvalue>0.01, 'CI does not contain zero 95% of the time' |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |
| |