#!/usr/bin/env vpython3
# Copyright (C) 2021 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import copy
import logging
import json
import six
import unittest
if six.PY3:
from io import StringIO as DataIO
else:
from io import BytesIO as DataIO
from blinkpy.common.host import Host
from blinkpy.common.host_mock import MockHost
from blinkpy.common.system.executive import ScriptError
from blinkpy.common.system.executive_mock import MockExecutive
from collections import namedtuple
from diff_wpt_results import (
map_tests_to_results, WPTResultsDiffer, CSV_HEADING,
_get_product_test_results)
MockArgs = namedtuple('MockArgs', ['product_to_compare', 'baseline_product'])
TEST_PRODUCT = 'android_webview'
TEST_BASELINE_PRODUCT = 'chrome_android'
class MockWPTResultsDiffer(WPTResultsDiffer):
def __init__(self, actual_results_map, baseline_results_map, csv_output):
super(MockWPTResultsDiffer, self).__init__(
MockArgs(product_to_compare=TEST_PRODUCT,
baseline_product=TEST_BASELINE_PRODUCT),
MockHost(),
actual_results_map, baseline_results_map, csv_output)
def _get_bot_expectations(self, product):
assert product in (TEST_PRODUCT, TEST_BASELINE_PRODUCT)
class BotExpectations(object):
def flakes_by_path(self, *args, **kwargs):
class AlwaysGet(object):
def get(self, *_):
if product == TEST_PRODUCT:
return {'FAIL', 'TIMEOUT'}
else:
return {'CRASH', }
return AlwaysGet()
return BotExpectations()
class JsonResultsCompressTest(unittest.TestCase):
def test_compress_json(self):
output_mp = {}
input_mp = {'dir1': {'dir2': {'actual': 'PASS'}}}
map_tests_to_results(output_mp, input_mp)
self.assertEquals(output_mp, {'dir1/dir2': {'actual': 'PASS'}})
class CreateCsvTest(unittest.TestCase):
def test_name_with_comma_escaped_in_csv(self):
actual_mp = {'test, name.html': {'actual': 'PASS'}}
with DataIO() as csv_out:
MockWPTResultsDiffer(actual_mp, actual_mp, csv_out).create_csv()
csv_out.seek(0)
content = csv_out.read()
heading = CSV_HEADING % (TEST_PRODUCT, TEST_BASELINE_PRODUCT)
self.assertEquals(content, heading +
('"test, name.html",PASS,PASS,'
'SAME RESULTS,"{FAIL, PASS, TIMEOUT}",'
'"{CRASH, PASS}",Yes\n'))
def test_create_csv_with_same_result(self):
actual_mp = {'test.html': {'actual': 'PASS'}}
with DataIO() as csv_out:
MockWPTResultsDiffer(actual_mp, actual_mp, csv_out).create_csv()
csv_out.seek(0)
content = csv_out.read()
heading = CSV_HEADING % (TEST_PRODUCT, TEST_BASELINE_PRODUCT)
self.assertEquals(content, heading +
('test.html,PASS,PASS,SAME RESULTS,'
'"{FAIL, PASS, TIMEOUT}","{CRASH, PASS}",Yes\n'))
def test_create_csv_with_reliable_different_result(self):
actual_mp = {'test.html': {'actual': 'PASS'}}
baseline_mp = copy.deepcopy(actual_mp)
baseline_mp['test.html']['actual'] = 'FAIL'
with DataIO() as csv_out:
MockWPTResultsDiffer(actual_mp, baseline_mp, csv_out).create_csv()
csv_out.seek(0)
content = csv_out.read()
heading = CSV_HEADING % (TEST_PRODUCT, TEST_BASELINE_PRODUCT)
self.assertEquals(content, heading +
('test.html,PASS,FAIL,DIFFERENT RESULTS,'
'"{FAIL, PASS, TIMEOUT}","{CRASH, FAIL}",No\n'))
def test_create_csv_with_unreliable_different_result(self):
actual_mp = {'test.html': {'actual': 'CRASH'}}
baseline_mp = copy.deepcopy(actual_mp)
baseline_mp['test.html']['actual'] = 'FAIL'
with DataIO() as csv_out:
MockWPTResultsDiffer(actual_mp, baseline_mp, csv_out).create_csv()
csv_out.seek(0)
content = csv_out.read()
heading = CSV_HEADING % (TEST_PRODUCT, TEST_BASELINE_PRODUCT)
self.assertEquals(content, heading +
('test.html,CRASH,FAIL,DIFFERENT RESULTS,'
'"{CRASH, FAIL, TIMEOUT}","{CRASH, FAIL}",Yes\n'))
def test_create_csv_with_missing_result(self):
actual_mp = {'test.html': {'actual': 'PASS'}}
with DataIO() as csv_out:
MockWPTResultsDiffer(actual_mp, {}, csv_out).create_csv()
csv_out.seek(0)
content = csv_out.read()
heading = CSV_HEADING % (TEST_PRODUCT, TEST_BASELINE_PRODUCT)
self.assertEquals(content, heading +
'test.html,PASS,MISSING,MISSING RESULTS,{},{},No\n')
def test_use_bb_to_get_results(self):
actual_mp = {'tests': {'test.html': {'actual': 'PASS'}}}
baseline_mp = copy.deepcopy(actual_mp)
baseline_mp['tests']['test.html']['actual'] = 'FAIL'
host = Host()
def process_cmds(cmd_args):
if 'token' in cmd_args:
return '00000'
elif (('system_webview_wpt on '
'Ubuntu-16.04 or Ubuntu-18.04') in cmd_args):
return json.dumps(actual_mp)
elif (('chrome_public_wpt on '
'Ubuntu-16.04 or Ubuntu-18.04') in cmd_args):
raise ScriptError('Test Error')
elif 'chrome_public_wpt' in cmd_args:
return json.dumps(baseline_mp)
else:
return '{"number": 400, "id":"abcd"}'
host.executive = MockExecutive(run_command_fn=process_cmds)
with DataIO() as csv_out, \
_get_product_test_results(host, 'android_webview', 0) as test_results, \
_get_product_test_results(host, 'chrome_android', 0) as baseline_results:
actual_results_json = json.loads(test_results.read())
baseline_results_json = json.loads(baseline_results.read())
tests_to_actual_results = {}
tests_to_baseline_results = {}
map_tests_to_results(tests_to_actual_results,
actual_results_json['tests'])
map_tests_to_results(tests_to_baseline_results,
baseline_results_json['tests'])
MockWPTResultsDiffer(tests_to_actual_results,
tests_to_baseline_results,
csv_out).create_csv()
csv_out.seek(0)
content = csv_out.read()
heading = CSV_HEADING % (TEST_PRODUCT, TEST_BASELINE_PRODUCT)
self.assertEquals(content, heading +
('test.html,PASS,FAIL,DIFFERENT RESULTS,'
'"{FAIL, PASS, TIMEOUT}","{CRASH, FAIL}",No\n'))
if __name__ == '__main__':
logging.basicConfig()
unittest.main()