blob: 302ee6466691940dd0c8f8f3ba06af96551c83f0 [file]
#!/usr/bin/env python3
# Copyright (C) 2026 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" Runs the perfetto Java SDK test suite on a host JVM.
Companion to tools/run_android_test (which runs the same test under ART on a
device or emulator). Uses the JDK pointed to by $JAVA_HOME, the Maven jars
landed by `tools/install-build-deps --java-sdk`, and the host stubs in
src/android_sdk/java/host_stubs/ to compile the perfetto Java SDK and the
PerfettoTraceTest suite for host. Links against the libperfetto_jni.so the
gn+ninja pipeline produces and runs the JUnit suite.
Prerequisites
-------------
$JAVA_HOME points at a JDK >= 11 install root.
tools/install-build-deps # standard C++ toolchain
tools/install-build-deps --java-sdk # Maven jars (opt-in)
"""
import logging
import os
import subprocess
import sys
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
JAVA_DEPS_DIR = os.path.join(ROOT_DIR, 'buildtools/java_sdk')
SDK_DIR = os.path.join(ROOT_DIR, 'src/android_sdk/java')
OUT_DIR = os.path.join(ROOT_DIR, 'out/android_sdk_host_test')
JAVA_PROTOS_TARGET = 'src/android_sdk/java/test:perfetto_test_java_protos'
JAVA_PROTOS_DIR = 'gen/src/android_sdk/java/test'
TEST_CLASS = 'dev.perfetto.sdk.test.PerfettoTraceTest'
def Die(msg):
logging.error(msg)
sys.exit(1)
def Run(cmd, **kwargs):
logging.debug('+ %s', ' '.join(cmd))
return subprocess.run(cmd, check=True, **kwargs)
def JdkHome():
jh = os.environ.get('JAVA_HOME')
if not jh:
Die('JAVA_HOME not set. Install a JDK >= 11 and set JAVA_HOME.')
if not os.path.exists(os.path.join(jh, 'include/jni.h')):
Die('JAVA_HOME=%s does not look like a JDK install (no include/jni.h).' %
jh)
return jh
def Glob(root, suffix):
for dirpath, _, files in os.walk(root):
for f in files:
if f.endswith(suffix):
yield os.path.join(dirpath, f)
def MavenJars():
jars = sorted(Glob(JAVA_DEPS_DIR, '.jar'))
if not jars:
Die('No jars in %s. Run `tools/install-build-deps --java-sdk`.' %
JAVA_DEPS_DIR)
return jars
def Classpath(*entries):
return os.pathsep.join(entries)
def Gn(jdk_home):
os.makedirs(OUT_DIR, exist_ok=True)
Run([
os.path.join(ROOT_DIR, 'tools/gn'), 'gen', OUT_DIR, '--args=' + ' '.join([
'is_debug=false',
'enable_perfetto_android_java_sdk=true',
'jdk_include_path="%s"' % os.path.join(jdk_home, 'include'),
])
])
def Ninja():
Run([
os.path.join(ROOT_DIR, 'tools/ninja'),
'-C',
OUT_DIR,
'libperfetto_jni',
JAVA_PROTOS_TARGET,
])
def Javac(jdk_home, classes_dir, classpath, srcs):
Run([
os.path.join(jdk_home, 'bin/javac'), '-d', classes_dir, '-cp', classpath,
'-source', '11', '-target', '11'
] + srcs)
def Jar(jdk_home, jar_path, classes_dir):
Run([
os.path.join(jdk_home, 'bin/jar'), 'cf', jar_path, '-C', classes_dir, '.'
])
def CompileSdk(jdk_home, jars, java_proto_dir):
classes = os.path.join(OUT_DIR, 'sdk_classes')
os.makedirs(classes, exist_ok=True)
srcs = (
list(Glob(os.path.join(SDK_DIR, 'main'), '.java')) +
list(Glob(os.path.join(SDK_DIR, 'host_stubs'), '.java')) +
list(Glob(java_proto_dir, '.java')))
Javac(jdk_home, classes, Classpath(*jars), srcs)
jar = os.path.join(OUT_DIR, 'perfetto_sdk_host.jar')
Jar(jdk_home, jar, classes)
return jar
def CompileTest(jdk_home, jars, sdk_jar):
classes = os.path.join(OUT_DIR, 'test_classes')
os.makedirs(classes, exist_ok=True)
srcs = list(Glob(os.path.join(SDK_DIR, 'test'), '.java'))
Javac(jdk_home, classes, Classpath(sdk_jar, *jars), srcs)
jar = os.path.join(OUT_DIR, 'perfetto_sdk_host_test.jar')
Jar(jdk_home, jar, classes)
return jar
def RunTests(jdk_home, jars, sdk_jar, test_jar):
env = dict(os.environ, LD_LIBRARY_PATH=OUT_DIR)
Run([
os.path.join(jdk_home,
'bin/java'), '-Djava.library.path=' + OUT_DIR, '-cp',
Classpath(sdk_jar, test_jar, *jars), 'org.junit.runner.JUnitCore',
TEST_CLASS
],
env=env)
def main():
logging.basicConfig(level=logging.INFO, format='%(message)s')
jdk_home = JdkHome()
jars = MavenJars()
Gn(jdk_home)
Ninja()
java_protos = os.path.join(OUT_DIR, JAVA_PROTOS_DIR)
sdk_jar = CompileSdk(jdk_home, jars, java_protos)
test_jar = CompileTest(jdk_home, jars, sdk_jar)
RunTests(jdk_home, jars, sdk_jar, test_jar)
if __name__ == '__main__':
main()