Home | History | Annotate | Download | only in util-src
      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