Skip to content

Testing the JDK

因为好奇心,想看下 jdk 的 test 怎么写的,然后就有了这篇游记。

下载 jdk 源码,哦,是OpenJDK。呃,网络不好,那git clone --depth=1吧,然后git fetch--depth=N,可以将 N 一直加大到无穷。

开箱一看,但是里面怎么感觉有点乱呀。。。

$ ls test/jdk/java/util/ArrayList/
AddAll.java  ArrayManagement.java  Bug6533203.java  Bug8146568.java  EnsureCapacity.java  IteratorMicroBenchmark.java  RangeCheckMicroBenchmark.java

好吧,我先去邮件列表看看是否有人也如我懵懂无知,看完Unit tests for OpenJDK?,哦,原来是 OpenJDK 自从 SUN 2006 年放出代码之前高司令们就已经开发了了将近 10 年(1.0 是 1995 年 5 月释出的),很多测试依赖 JCK 2,单元测试,和功能测试,而这些不在 OpenJDK 当中(或许 Sun 发布时出于某些原因删除了?),所以老的代码很多没有测试,但是新的代码测试覆盖就很全了。 邮件列表中还建议去 Youtube 搜索相关视频。(Alan Bateman OR Stuart Marks) openjdk test ,我找到了这个Meet the OpenJDK Tests。 视频里介绍了 quality discuss 邮件列表。可以围观下最新的测试结果OpenJDK 13 Early Access Build Test Results

以 JDK-8196207 Inefficient ArrayList.subList().toArray()为例,之前代码是调用 AbstractColleciton 的 toArray 方法

    public Object[] toArray() {
        // Estimate size of array; be prepared to see more or fewer elements
        Object[] r = new Object[size()];
        Iterator<E> it = iterator();
        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) // fewer elements than expected
                return Arrays.copyOf(r, i);
            r[i] = it.next();
        }
        return it.hasNext() ? finishToArray(r, it) : r;
    }

一个个元素来。。。所以可以改进,e3dcdd73a549 就直接调用 Arrays.copyOfRange 或者 System.arraycopy

+        public Object[] toArray() {
+            checkForComodification();
+            return Arrays.copyOfRange(root.elementData, offset, offset + size);
+        }
+
+        @SuppressWarnings("unchecked")
+        public <T> T[] toArray(T[] a) {
+            checkForComodification();
+            if (a.length < size)
+                return (T[]) Arrays.copyOfRange(
+                        root.elementData, offset, offset + size, a.getClass());
+            System.arraycopy(root.elementData, offset, a, 0, size);
+            if (a.length > size)
+                a[size] = null;
+            return a;
+        }

至于这两个 copy 的区别就是,copyOfRange 会调用 arraycopy。 1 2 而这个改动的测试就在两个不同的 IteratorMicroBenchmark.java 里,嗯,你没看错,两个,一个是 ArrayList 目录下,另一个是 Collection 目录下。

另一个实例就是 寒泉子 提的这个小修正 GC Metaspace printing after full gccommit。而这次测试文件路径为 test/hotspot/jtreg/gc/logging/TestMetaSpaceLog.java ,还提交了个 jar 文件到 test/hotspot/jtreg/gc/logging/testcases.jar。

jtreg

好,主角上场了,Regression Test Harness for the JDK: jtreg,我估计全称就是 java test regression。 An Introduction to jtreg里介绍了支持的几种测试,API 测试,编译测试,Applet 测试,以及 Shell 测试,三种 JVM 模式 othervm, samevm, agentvm。而一个 jtreg 测试就是简单用退出状态来判定是否达到预期(当然 negative 测试就是要异常退出)。

$ find . -name TEST.ROOT
./test/jdk/TEST.ROOT
./test/langtools/TEST.ROOT
./test/hotspot/jtreg/TEST.ROOT
./test/nashorn/TEST.ROOT
./test/failure_handler/test/TEST.ROOT
./test/jaxp/TEST.ROOT
./make/langtools/test/TEST.ROOT

Build

磁盘大概 8G(编译后大概 6G),普通 2G1CPU 大约半个小时,8G8CPU 大约 4 分钟。 Building OpenJDK

sudo apt-get install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev libcups2-dev libfontconfig1-dev libasound2-dev libelf-dev
# 需要先准备版本为N-1的boot JDK,我是sdkman安装的`sdk install java 12.0.1-open`
# build and install jtreg first, https://openjdk.java.net/jtreg/
bash configure --with-jtreg=$HOME/jtreg
make images  # Build the JRE and JDK images
./build/*/images/jdk/bin/java -version
openjdk version "13-internal" 2019-09-17

Test

Testing the JDK

run-test-tier1 可能需要跑一两个小时,还需要大约 20G 的硬盘。。。

sudo apt install jtreg
# 不要选择带有@ignore 标签或者在ProblemList.txt的测试
make test TEST="jtreg:test/jdk/java/util/AbstractList"  # test-only will ignore source file change

参考

  1. 面对 JDK 的 BUG 该如何是好?, 深入理解 Java 虚拟机 #01# 自己编译 JDK
  2. Differences Between Oracle JDK and OpenJDK
  3. Android's Java 9, 10, 11, and 12 Support
  4. JEP proposed to drop from JDK 12: 326: Raw String Literals (Preview)
  5. JDK 9 学习笔记 - (1)开发环境准备

  1. Why is Arrays.copyOf 2 times faster than System.arraycopy for small arrays? What is more efficient: System.arraycopy or Arrays.copyOf? 

  2. JCK(Java Compatibility Kit ),这个是兼容性测试,需要单独获取,可以先阅读 azul 的这篇Why would you risk your apps on an uncertified JVM?。获取方式参考Gaining Access to the JCK,现在已经签署的名单在OCTLA Signatories List,看到了阿里和华为。 

Comments