15fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain#! /usr/bin/python3 25fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# 35fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# Copyright (C) 2017 The Android Open Source Project 45fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# 55fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# Licensed under the Apache License, Version 2.0 (the "License"); 65fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# you may not use this file except in compliance with the License. 75fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# You may obtain a copy of the License at 85fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# 95fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# http://www.apache.org/licenses/LICENSE-2.0 105fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# 115fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# Unless required by applicable law or agreed to in writing, software 125fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# distributed under the License is distributed on an "AS IS" BASIS, 135fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# See the License for the specific language governing permissions and 155fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# limitations under the License. 165fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 175fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain""" 185fa822dd1f22886a25515690fce7f8a4c40701b2Roland LevillainGenerate Java test files for test 648-many-direct-methods. 195fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain""" 205fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 215fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainimport os 225fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainimport sys 235fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainfrom pathlib import Path 245fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 255fa822dd1f22886a25515690fce7f8a4c40701b2Roland LevillainBUILD_TOP = os.getenv("ANDROID_BUILD_TOP") 265fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainif BUILD_TOP is None: 275fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain print("ANDROID_BUILD_TOP not set. Please run build/envsetup.sh", file=sys.stderr) 285fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain sys.exit(1) 295fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 305fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# Allow us to import utils and mixins. 315fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainsys.path.append(str(Path(BUILD_TOP)/"art"/"test"/"utils"/"python")) 325fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 335fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainfrom testgen.utils import get_copyright, subtree_sizes, gensym, filter_blanks 345fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainimport testgen.mixins as mixins 355fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 365fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainclass MainClass(mixins.DumpMixin, mixins.Named, mixins.JavaFileMixin): 375fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 385fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain A Main.java file containing the Main class and the main function. It will run 395fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain all the test functions we have. 405fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 415fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 425fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain MAIN_CLASS_TEMPLATE = """{copyright} 435fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainpublic class Main {{ 445fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain{main_func} 455fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain{test_groups} 465fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 475fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain}}""" 485fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 495fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain MAIN_FUNCTION_TEMPLATE = """ 505fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain public static void main(String[] args) { 515fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain System.out.println("passed"); 525fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain }""" 535fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 545fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain def __init__(self): 555fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 565fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain Initialize this MainClass. We start out with no tests. 575fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 585fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain self.tests = set() 595fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 605fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain def add_test_method(self, num): 615fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 625fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain Add test method number 'num' 635fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 645fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain self.tests.add(TestMethod(num)) 655fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 665fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain def get_name(self): 675fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 685fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain Get the name of this class 695fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 705fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain return "Main" 715fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 725fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain def __str__(self): 735fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 745fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain Print the MainClass Java code. 755fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 765fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain all_tests = sorted(self.tests) 775fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain test_groups = "" 785fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain for t in all_tests: 795fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain test_groups += str(t) 805fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain main_func = self.MAIN_FUNCTION_TEMPLATE 815fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 825fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain return self.MAIN_CLASS_TEMPLATE.format(copyright = get_copyright("java"), 835fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain main_func = main_func, 845fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain test_groups = test_groups) 855fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 865fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainclass TestMethod(mixins.Named, mixins.NameComparableMixin): 875fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 885fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain A function that represents a test method. Should only be 895fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain constructed by MainClass.add_test_method. 905fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 915fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 925fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain TEST_FUNCTION_TEMPLATE = """ 935fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain public static void {fname}() {{}}""" 945fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 955fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain def __init__(self, farg): 965fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 975fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain Initialize a test method for the given argument. 985fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 995fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain self.farg = farg 1005fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 1015fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain def get_name(self): 1025fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 1035fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain Get the name of this test method. 1045fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 1055fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain return "method{:05d}".format(self.farg) 1065fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 1075fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain def __str__(self): 1085fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 1095fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain Print the Java code of this test method. 1105fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 1115fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain return self.TEST_FUNCTION_TEMPLATE.format(fname=self.get_name()) 1125fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 1135fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# Number of generated test methods. This number has been chosen to 1145fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# make sure the number of direct methods in class Main is greater or 1155fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# equal to 2^16, and thus requires an *unsigned* 16-bit (short) 1165fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain# integer to be represented (b/33650497). 1175fa822dd1f22886a25515690fce7f8a4c40701b2Roland LevillainNUM_TEST_METHODS = 32768 1185fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 1195fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillaindef create_test_file(): 1205fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 1215fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain Creates the object representing the test file. It just needs to be dumped. 1225fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain """ 1235fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain mc = MainClass() 1245fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain for i in range(1, NUM_TEST_METHODS + 1): 1255fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain mc.add_test_method(i) 1265fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain return mc 1275fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 1285fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillaindef main(argv): 1295fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain java_dir = Path(argv[1]) 1305fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain if not java_dir.exists() or not java_dir.is_dir(): 1315fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain print("{} is not a valid Java dir".format(java_dir), file=sys.stderr) 1325fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain sys.exit(1) 1335fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain mainclass = create_test_file() 1345fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain mainclass.dump(java_dir) 1355fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain 1365fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillainif __name__ == '__main__': 1375fa822dd1f22886a25515690fce7f8a4c40701b2Roland Levillain main(sys.argv) 138