1 #! /usr/bin/python3 2 # 3 # Copyright (C) 2017 The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 """ 18 Generate Java test files for test 648-many-direct-methods. 19 """ 20 21 import os 22 import sys 23 from pathlib import Path 24 25 BUILD_TOP = os.getenv("ANDROID_BUILD_TOP") 26 if BUILD_TOP is None: 27 print("ANDROID_BUILD_TOP not set. Please run build/envsetup.sh", file=sys.stderr) 28 sys.exit(1) 29 30 # Allow us to import utils and mixins. 31 sys.path.append(str(Path(BUILD_TOP)/"art"/"test"/"utils"/"python")) 32 33 from testgen.utils import get_copyright, subtree_sizes, gensym, filter_blanks 34 import testgen.mixins as mixins 35 36 class MainClass(mixins.DumpMixin, mixins.Named, mixins.JavaFileMixin): 37 """ 38 A Main.java file containing the Main class and the main function. It will run 39 all the test functions we have. 40 """ 41 42 MAIN_CLASS_TEMPLATE = """{copyright} 43 public class Main {{ 44 {main_func} 45 {test_groups} 46 47 }}""" 48 49 MAIN_FUNCTION_TEMPLATE = """ 50 public static void main(String[] args) { 51 System.out.println("passed"); 52 }""" 53 54 def __init__(self): 55 """ 56 Initialize this MainClass. We start out with no tests. 57 """ 58 self.tests = set() 59 60 def add_test_method(self, num): 61 """ 62 Add test method number 'num' 63 """ 64 self.tests.add(TestMethod(num)) 65 66 def get_name(self): 67 """ 68 Get the name of this class 69 """ 70 return "Main" 71 72 def __str__(self): 73 """ 74 Print the MainClass Java code. 75 """ 76 all_tests = sorted(self.tests) 77 test_groups = "" 78 for t in all_tests: 79 test_groups += str(t) 80 main_func = self.MAIN_FUNCTION_TEMPLATE 81 82 return self.MAIN_CLASS_TEMPLATE.format(copyright = get_copyright("java"), 83 main_func = main_func, 84 test_groups = test_groups) 85 86 class TestMethod(mixins.Named, mixins.NameComparableMixin): 87 """ 88 A function that represents a test method. Should only be 89 constructed by MainClass.add_test_method. 90 """ 91 92 TEST_FUNCTION_TEMPLATE = """ 93 public static void {fname}() {{}}""" 94 95 def __init__(self, farg): 96 """ 97 Initialize a test method for the given argument. 98 """ 99 self.farg = farg 100 101 def get_name(self): 102 """ 103 Get the name of this test method. 104 """ 105 return "method{:05d}".format(self.farg) 106 107 def __str__(self): 108 """ 109 Print the Java code of this test method. 110 """ 111 return self.TEST_FUNCTION_TEMPLATE.format(fname=self.get_name()) 112 113 # Number of generated test methods. This number has been chosen to 114 # make sure the number of direct methods in class Main is greater or 115 # equal to 2^16, and thus requires an *unsigned* 16-bit (short) 116 # integer to be represented (b/33650497). 117 NUM_TEST_METHODS = 32768 118 119 def create_test_file(): 120 """ 121 Creates the object representing the test file. It just needs to be dumped. 122 """ 123 mc = MainClass() 124 for i in range(1, NUM_TEST_METHODS + 1): 125 mc.add_test_method(i) 126 return mc 127 128 def main(argv): 129 java_dir = Path(argv[1]) 130 if not java_dir.exists() or not java_dir.is_dir(): 131 print("{} is not a valid Java dir".format(java_dir), file=sys.stderr) 132 sys.exit(1) 133 mainclass = create_test_file() 134 mainclass.dump(java_dir) 135 136 if __name__ == '__main__': 137 main(sys.argv) 138