| #!/usr/bin/env python3 |
| # Copyright 2021 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import os |
| import csv |
| import tempfile |
| from typing import List |
| import shutil |
| import unittest |
| |
| from file_reading import enumerate_all_argument_combinations |
| from file_reading import expand_tests_from_action_parameter_wildcards |
| from file_reading import enumerate_markdown_file_lines_to_table_rows |
| from file_reading import human_friendly_name_to_canonical_action_name |
| from file_reading import generate_test_id_from_test_steps |
| from file_reading import get_and_maybe_delete_tests_in_browsertest |
| from file_reading import read_actions_file |
| from file_reading import read_enums_file |
| from file_reading import read_platform_supported_actions |
| from file_reading import resolve_bash_style_replacement |
| from file_reading import read_unprocessed_coverage_tests_file |
| from models import ActionsByName |
| from models import ArgEnum |
| from models import CoverageTest |
| from models import TestIdTestNameTuple |
| from models import TestPlatform |
| |
| TEST_DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), |
| "test_data") |
| |
| |
| class TestAnalysisTest(unittest.TestCase): |
| def test_markdown_file_mapping(self): |
| test_input = [ |
| "Test", "# Hello", "| #test |", "| ------- | Value |", |
| "| WML | Value | Value", " | ADF |" |
| ] |
| output = enumerate_markdown_file_lines_to_table_rows(test_input) |
| expected = [(4, ["WML", "Value", "Value"]), (5, ["ADF"])] |
| self.assertEqual(expected, output) |
| |
| def test_argument_combinations(self): |
| argument_types: List[ArgEnum] = [] |
| argument_types.append(ArgEnum("T1", ["T1V1", "T1V2"], None)) |
| argument_types.append(ArgEnum("T2", ["T2V1", "T2V2"], None)) |
| |
| combinations = enumerate_all_argument_combinations(argument_types) |
| |
| self.assertEqual([["T1V1", "T2V1"], ["T1V1", "T2V2"], ["T1V2", "T2V1"], |
| ["T1V2", "T2V2"]], combinations) |
| |
| def test_resolving_output_action_names(self): |
| self.assertEqual("Test", |
| resolve_bash_style_replacement("$1", ["Test"])) |
| self.assertEqual( |
| "Correct sentence! over over.", |
| resolve_bash_style_replacement("$1 $2ence! $3 $3.", |
| ["Correct", "sent", "over"])) |
| |
| def test_human_friendly_name_to_canonical_action_name(self): |
| self.assertEqual( |
| "action_with_arg1_arg2", |
| human_friendly_name_to_canonical_action_name( |
| "action_with(arg1, arg2)", {})) |
| self.assertEqual( |
| "action_with_arg1_arg2", |
| human_friendly_name_to_canonical_action_name( |
| "action_with", {"action_with": "arg1_arg2"})) |
| |
| def test_enums(self): |
| enums_file = os.path.join(TEST_DATA_DIR, "test_enums.md") |
| |
| with open(enums_file, "r", encoding="utf-8") \ |
| as enum_types: |
| enums = read_enums_file(enum_types.readlines()) |
| self.assertEqual(len(enums), 3) |
| self.assertIn("Animal", enums) |
| animal = enums["Animal"] |
| self.assertEqual("Animal", animal.type_name) |
| self.assertEqual(["Chicken", "Dog"], animal.values) |
| self.assertEqual("Chicken", animal.default_value) |
| |
| self.assertIn("AnimalLess", enums) |
| animal = enums["AnimalLess"] |
| self.assertEqual("AnimalLess", animal.type_name) |
| self.assertEqual(["Chicken"], animal.values) |
| self.assertEqual("Chicken", animal.default_value) |
| |
| self.assertIn("Color", enums) |
| color = enums["Color"] |
| self.assertEqual("Color", color.type_name) |
| self.assertEqual(["Green", "Red"], color.values) |
| self.assertEqual(None, color.default_value) |
| |
| def test_supported_actions(self): |
| supported_actions_filename = os.path.join( |
| TEST_DATA_DIR, "framework_supported_actions.csv") |
| |
| with open(supported_actions_filename, "r", encoding="utf-8") \ |
| as supported_actions: |
| supported = read_platform_supported_actions( |
| csv.reader(supported_actions, delimiter=',')) |
| self.assertEqual(len(supported), 4) |
| (check_a_partial, check_a_full) = supported["check_a"] |
| self.assertEqual(len(check_a_partial), 1) |
| self.assertEqual(len(check_a_full), 3) |
| (check_b_partial, check_b_full) = supported["check_b"] |
| self.assertEqual(len(check_b_partial), 1) |
| self.assertEqual(len(check_b_full), 3) |
| (state_change_a_partial, |
| state_change_a_full) = supported["state_change_a"] |
| self.assertEqual(len(state_change_a_partial), 0) |
| self.assertEqual(len(state_change_a_full), 4) |
| (state_change_b_partial, |
| state_change_b_full) = supported["state_change_b"] |
| self.assertEqual(len(state_change_b_partial), 0) |
| self.assertEqual(len(state_change_b_full), 3) |
| |
| def test_action_file_reading(self): |
| actions_filename = os.path.join(TEST_DATA_DIR, "test_actions.md") |
| supported_actions_filename = os.path.join( |
| TEST_DATA_DIR, "framework_supported_actions.csv") |
| enums_filename = os.path.join(TEST_DATA_DIR, "test_enums.md") |
| |
| with open(actions_filename, "r", encoding="utf-8") as f, \ |
| open(supported_actions_filename, "r", encoding="utf-8") \ |
| as supported_actions, \ |
| open (enums_filename, "r", encoding="utf-8") as enums: |
| supported_actions = read_platform_supported_actions( |
| csv.reader(supported_actions, delimiter=',')) |
| actions_tsv = f.readlines() |
| enums = read_enums_file(enums.readlines()) |
| |
| (actions, action_base_name_to_default_param) = read_actions_file( |
| actions_tsv, enums, supported_actions) |
| self.assertEqual(len(actions), 13) |
| self.assertEqual(len(action_base_name_to_default_param), 3) |
| |
| # Check Cpp methods |
| self.assertIn('check_b_Chicken_Green', actions) |
| self.assertEqual("CheckB(Animal::kChicken, Color::kGreen)", |
| actions['check_b_Chicken_Green'].cpp_method) |
| |
| # Check parameterized action state. |
| self.assertIn('changes_Chicken', actions) |
| self.assertIn('changes_Dog', actions) |
| self.assertTrue('checks' in actions) |
| checks_output_actions = actions['checks'].output_actions |
| self.assertEqual(len(checks_output_actions), 2) |
| self.assertCountEqual( |
| checks_output_actions, |
| [actions['check_a_Chicken'], actions['check_b_Chicken_Green']]) |
| |
| def test_coverage_file_reading(self): |
| actions_filename = os.path.join(TEST_DATA_DIR, "test_actions.md") |
| supported_actions_filename = os.path.join( |
| TEST_DATA_DIR, "framework_supported_actions.csv") |
| enums_filename = os.path.join(TEST_DATA_DIR, "test_enums.md") |
| |
| actions: ActionsByName = {} |
| action_base_name_to_default_param = {} |
| with open(actions_filename) as f, \ |
| open(supported_actions_filename, "r", encoding="utf-8") \ |
| as supported_actions, \ |
| open(enums_filename, "r", encoding="utf-8") as enums: |
| supported_actions = read_platform_supported_actions( |
| csv.reader(supported_actions, delimiter=',')) |
| actions_tsv = f.readlines() |
| enums = read_enums_file(enums.readlines()) |
| (actions, action_base_name_to_default_param) = read_actions_file( |
| actions_tsv, enums, supported_actions) |
| |
| coverage_filename = os.path.join(TEST_DATA_DIR, |
| "test_unprocessed_coverage.md") |
| coverage_tests: List[CoverageTest] = [] |
| with open(coverage_filename) as f: |
| coverage_tsv = f.readlines() |
| coverage_tests = read_unprocessed_coverage_tests_file( |
| coverage_tsv, actions, enums, |
| action_base_name_to_default_param) |
| self.assertEqual(6, len(coverage_tests)) |
| |
| def test_browsertest_detection(self): |
| browsertest_filename = os.path.join(TEST_DATA_DIR, "tests_default.cc") |
| tests_and_platforms = get_and_maybe_delete_tests_in_browsertest( |
| browsertest_filename) |
| expected_key = TestIdTestNameTuple( |
| "state_change_a_Chicken_check_a_Chicken_check_b_Chicken_Green", |
| "3Chicken_1Chicken_2ChickenGreen") |
| self.assertListEqual(list(tests_and_platforms.keys()), [expected_key]) |
| tests_and_platforms = tests_and_platforms[expected_key] |
| self.assertEqual( |
| {TestPlatform.LINUX, TestPlatform.CHROME_OS, TestPlatform.MAC}, |
| tests_and_platforms) |
| |
| def test_browertest_in_place_deletion(self): |
| input_file = os.path.join(TEST_DATA_DIR, "tests_for_deletion.cc") |
| after_deletion_file = os.path.join(TEST_DATA_DIR, "tests_default.cc") |
| with tempfile.TemporaryDirectory(dir=TEST_DATA_DIR) as tmpdirname: |
| output_file = os.path.join(tmpdirname, "output.cc") |
| shutil.copyfile(input_file, output_file) |
| tests_and_platforms = get_and_maybe_delete_tests_in_browsertest( |
| output_file, { |
| TestIdTestNameTuple( |
| "state_change_a_Chicken_check_a_Chicken_check_b_Chicken_Green", |
| "StateChangeAChicken") |
| }, |
| delete_in_place=True) |
| |
| with open(output_file, 'r') as f, open(after_deletion_file, |
| 'r') as f2: |
| self.assertTrue(f.read(), f2.read()) |
| |
| tests_and_platforms = tests_and_platforms[TestIdTestNameTuple( |
| "state_change_a_Chicken_check_a_Chicken_check_b_Chicken_Green", |
| "3Chicken_1Chicken_2ChickenGreen")] |
| self.assertEqual( |
| {TestPlatform.LINUX, TestPlatform.CHROME_OS, TestPlatform.MAC}, |
| tests_and_platforms) |
| |
| def test_action_param_expansion(self): |
| enum_map: Dict[str, ArgEnum] = { |
| "EnumType": ArgEnum("EnumType", ["Value1", "Value2"], None) |
| } |
| actions: List[str] = [ |
| "Action1(EnumType::All)", "Action2(EnumType::All, EnumType::All)" |
| ] |
| |
| combinations = expand_tests_from_action_parameter_wildcards( |
| enum_map, actions) |
| expected = [['Action1(Value1)', 'Action2(Value1, Value1)'], |
| ['Action1(Value2)', 'Action2(Value1, Value1)'], |
| ['Action1(Value1)', 'Action2(Value1, Value2)'], |
| ['Action1(Value2)', 'Action2(Value1, Value2)'], |
| ['Action1(Value1)', 'Action2(Value2, Value1)'], |
| ['Action1(Value2)', 'Action2(Value2, Value1)'], |
| ['Action1(Value1)', 'Action2(Value2, Value2)'], |
| ['Action1(Value2)', 'Action2(Value2, Value2)']] |
| self.assertCountEqual(combinations, expected) |
| |
| def test_generate_test_id_from_test_steps(self): |
| test_steps = [ |
| "helper_.StateChangeA(Animal::kChicken);", |
| "helper_.CheckB(Animal::kChicken, Color::kGreen);", |
| "helper_.StateChangeB();" |
| ] |
| test_id = generate_test_id_from_test_steps(test_steps) |
| expected_test_id = ( |
| "state_change_a_Chicken_check_b_Chicken_Green_state_change_b" |
| ) |
| self.assertEqual(test_id, expected_test_id) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |