Rewrite create-jctf-tests.sh in python
Bug:
Change-Id: I6d79c852b5118d2e5b9ae8f46823961ac364e7ed
diff --git a/build.gradle b/build.gradle
index 695e898..6667647 100644
--- a/build.gradle
+++ b/build.gradle
@@ -326,12 +326,11 @@
task createJctfTests(type: Exec) {
def outputDir = "build/generated/test/java/com/android/tools/r8/jctf"
- def script = "scripts/create-jctf-tests.sh"
+ def script = "tools/create_jctf_tests.py"
inputs.file script
outputs.dir outputDir
dependsOn downloadDeps
- executable "bash"
- args "${projectDir}/${script}"
+ commandLine "python", script
workingDir = projectDir
}
diff --git a/scripts/create-jctf-tests.sh b/scripts/create-jctf-tests.sh
deleted file mode 100755
index 2f4e91e..0000000
--- a/scripts/create-jctf-tests.sh
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-function generate_test() {
- local name=$1
- local testClassName=$2
- local fileName=$3
- local compilerUnderTest=$4
- local classFile=$5
- local relativePackage=$6
- # The bash uppercase substitution ^^ is not supported on the bash version on Mac OS.
- local compilerUnderTestEnum=$(echo ${compilerUnderTest} | tr /a-z/ /A-Z/)
-
- PACKAGE_PREFIX="com.google.jctf.test.lib.java."
-
- if [[ ! $name =~ ^$PACKAGE_PREFIX ]]; then
- echo "Test full class name expected to start with \"$PACKAGE_PREFIX\" but it's \"$name\"" >&2
- exit 1
- fi
-
- mkdir -p $(dirname $fileName)
-
- cat <<EOF > $fileName
-// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.jctf.${compilerUnderTest}.${relativePackage};
-
-import org.junit.Test;
-import com.android.tools.r8.R8RunArtTestsTest;
-
-/**
- * Auto-generated test for the jctf test:
- * ${name}
- *
- * DO NOT EDIT THIS FILE. EDIT THE HERE DOCUMENT TEMPLATE IN scripts/create-jctf-tests.sh INSTEAD!
- */
-public class ${testClassName} extends R8RunArtTestsTest {
-
- public ${testClassName}() {
- super("${name:${#PACKAGE_PREFIX}}", DexTool.NONE);
- }
-
- @Test
- public void run${testClassName}() throws Exception {
- // For testing with other Art VMs than the default set the system property 'dex_vm'
- // to the desired VM string (e.g. '4.4.4', see ToolHelper.DexVm)
- runJctfTest(CompilerUnderTest.${compilerUnderTestEnum},
- "$classFile",
- "$name"
- );
- }
-}
-EOF
-}
-
-JCTFROOT="third_party/jctf"
-DESTINATIONDIR="build/generated/test/java/com/android/tools/r8/jctf"
-
-if [ ! -e $JCTFROOT ]; then
- echo "Missing jctf tests in $JCTFROOT."
- exit
-fi
-
-for d in $DESTINATIONDIR/r8 $DESTINATIONDIR/d8; do
- rm -rf $d
- mkdir -p $d
-done
-
-RELATIVE_TESTDIR="LibTests/src/com/google/jctf/test/lib/java"
-TESTDIR="$JCTFROOT/$RELATIVE_TESTDIR"
-
-COUNT=$(grep -r "@Test" "$TESTDIR" --include=*.java -l | wc -l)
-echo "JCTF: $COUNT files to generate"
-
-grep -r "@Test" "$TESTDIR" --include=*.java -l | while read -r line; do
- TESTNAME=$(basename $line .java)
- TESTCLASSNAME="${TESTNAME//-/_}"
-
- RELATIVE_TEST_PATH=$(expr "$line" : ".*$RELATIVE_TESTDIR/\(.*$\)")
-
- PACKAGE=$(grep package $line | grep -o -m 1 "com[^;]*")
- CLASSFILE="$(echo $PACKAGE | tr '.' '/')/$TESTNAME.class"
- RELATIVE_PACKAGE=$(expr "$PACKAGE" : ".*\.java\.\(.*$\)")
-
- generate_test $PACKAGE.$TESTNAME $TESTCLASSNAME \
- "$DESTINATIONDIR/r8/$RELATIVE_TEST_PATH" r8 \
- $CLASSFILE $RELATIVE_PACKAGE
- generate_test $PACKAGE.$TESTNAME $TESTCLASSNAME \
- "$DESTINATIONDIR/d8/$RELATIVE_TEST_PATH" d8 \
- $CLASSFILE $RELATIVE_PACKAGE
-done
-
diff --git a/tools/create_jctf_tests.py b/tools/create_jctf_tests.py
new file mode 100755
index 0000000..0f1ca98
--- /dev/null
+++ b/tools/create_jctf_tests.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+# Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+from __future__ import print_function
+from glob import glob
+from itertools import chain
+from os import makedirs
+from os.path import exists, join, dirname
+from shutil import rmtree
+from string import Template, upper
+import os
+import re
+import sys
+
+import utils
+
+JCTFROOT = 'third_party/jctf'
+DESTINATION_DIR = 'build/generated/test/java/com/android/tools/r8/jctf'
+PACKAGE_PREFIX = 'com.google.jctf.test.lib.java.'
+RELATIVE_TESTDIR = 'LibTests/src/com/google/jctf/test/lib/java'
+TESTDIR = join(JCTFROOT, RELATIVE_TESTDIR)
+TEMPLATE = Template(
+"""// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.jctf.${compilerUnderTest}.${relativePackage};
+
+import org.junit.Test;
+import com.android.tools.r8.R8RunArtTestsTest;
+
+/**
+ * Auto-generated test for the jctf test:
+ * ${name}
+ *
+ * DO NOT EDIT THIS FILE. EDIT THE HERE DOCUMENT TEMPLATE IN
+ * tools/create_jctf_tests.py INSTEAD!
+ */
+public class ${testClassName} extends R8RunArtTestsTest {
+
+ public ${testClassName}() {
+ super("${nameWithoutPackagePrefix}", DexTool.NONE);
+ }
+
+ @Test
+ public void run${testClassName}() throws Exception {
+ // For testing with other Art VMs than the default set the system property
+ // 'dex_vm' to the desired VM string (e.g. '4.4.4', see ToolHelper.DexVm)
+ runJctfTest(CompilerUnderTest.${compilerUnderTestEnum},
+ "$classFile",
+ "$name"
+ );
+ }
+}
+""")
+
+EXIT_FAILURE = 1
+RE_PACKAGE = re.compile('package\\s+(com[^\\s;]*)')
+
+def file_contains_string(filepath, search_string):
+ with open(filepath) as f:
+ return search_string in f.read()
+
+def read_package_from_java_file(filepath):
+ with open(filepath) as f:
+ for line in f:
+ m = RE_PACKAGE.search(line)
+ if m:
+ return m.groups()[0]
+ raise IOError("Can't find package statement in java file: " + filepath)
+
+
+def generate_test(class_name, compiler_under_test, relative_package):
+ filename = join(DESTINATION_DIR, compiler_under_test,
+ relative_package.replace('.', '/'), class_name + '.java')
+ utils.makedirs_if_needed(dirname(filename))
+
+ full_class_name = '{}{}.{}'.format(PACKAGE_PREFIX, relative_package,
+ class_name)
+ contents = TEMPLATE.substitute(
+ compilerUnderTest = compiler_under_test,
+ relativePackage = relative_package,
+ name = full_class_name,
+ testClassName = class_name,
+ compilerUnderTestEnum = compiler_under_test.upper(),
+ classFile = full_class_name.replace('.', '/') + '.class',
+ nameWithoutPackagePrefix = '{}.{}'.format(relative_package, class_name))
+
+ with open(filename, 'w') as f:
+ f.write(contents)
+
+def Main():
+ if not exists(JCTFROOT):
+ print('JCTF test package not found in {}'.format(JCTFROOT),
+ file = sys.stderr)
+ return EXIT_FAILURE
+
+ for tool in ['d8', 'r8']:
+ p = join(DESTINATION_DIR, tool)
+ if exists(p):
+ rmtree(p)
+ makedirs(p)
+
+ java_files = (chain.from_iterable(glob(join(x[0], '*.java'))
+ for x in os.walk(TESTDIR)))
+
+ dot_java_dot = '.java.'
+
+ for f in java_files:
+ if not file_contains_string(f, '@Test'):
+ continue
+
+ class_name = os.path.splitext(os.path.basename(f))[0]
+ assert class_name.find('-') < 0
+
+ package = read_package_from_java_file(f)
+
+ idx = package.find(dot_java_dot)
+ assert idx >= 0
+ relative_package = package[idx + len(dot_java_dot):]
+
+ for d in ['r8', 'd8']:
+ generate_test(class_name, d, relative_package)
+
+
+if __name__ == '__main__':
+ sys.exit(Main())