changeset 345:786f51893420

JCStress API samples.
author shade
date Fri, 20 Jan 2017 12:43:57 +0100
parents f1d5d6b3ff31
children 3a4794448398
files jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_01_Simple.java jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_02_Arbiters.java jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_03_Termination.java jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_04_Nesting.java jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_05_SharedMetadata.java jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_06_Descriptions.java jcstress-samples/src/main/java/org/openjdk/jcstress/tests/JCStressSample_01_IncrementAtomicity.java
diffstat 7 files changed, 435 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_01_Simple.java	Fri Jan 20 12:43:57 2017 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016, Red Hat Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jcstress.samples;
+
+import org.openjdk.jcstress.annotations.*;
+import org.openjdk.jcstress.infra.results.IntResult2;
+
+/*
+    This is our first concurrency test. It is deliberately simplistic to show
+    testing approaches, introduce JCStress APIs, etc.
+
+    Suppose we want to see if the field increment is atomic. We can make test
+    with two actors, both actors incrementing the field and recording what
+    value they observed into the result object. As JCStress runs, it will
+    invoke these methods on the objects holding the field once per each actor
+    and instance, and record what results are coming from there.
+
+    Done enough times, we will get the history of observed results, and that
+    would tell us something about the concurrent behavior. For example, running
+    this test would yield:
+
+          [OK] o.o.j.t.JCStressSample_01_Simple
+        (JVM args: [-server])
+      Observed state   Occurrences   Expectation  Interpretation
+                1, 1    54,734,140    ACCEPTABLE  Both threads came up with the same value: atomicity failure.
+                1, 2    47,037,891    ACCEPTABLE  actor1 incremented, then actor2.
+                2, 1    53,204,629    ACCEPTABLE  actor2 incremented, then actor1.
+
+     How to run this test:
+       $ java -jar jcstress-samples/target/jcstress.jar -t JCStress_APISample_01_Simple
+ */
+
+// Mark the class as JCStress test.
+@JCStressTest
+
+// These are the test outcomes.
+@Outcome(id = "1, 1", expect = Expect.ACCEPTABLE_INTERESTING, desc = "Both actors came up with the same value: atomicity failure.")
+@Outcome(id = "1, 2", expect = Expect.ACCEPTABLE, desc = "actor1 incremented, then actor2.")
+@Outcome(id = "2, 1", expect = Expect.ACCEPTABLE, desc = "actor2 incremented, then actor1.")
+
+// This is a state object
+@State
+public class JCStress_APISample_01_Simple {
+
+    int v;
+
+    @Actor
+    public void actor1(IntResult2 r) {
+        r.r1 = ++v; // record result from actor1 to field r1
+    }
+
+    @Actor
+    public void actor2(IntResult2 r) {
+        r.r2 = ++v; // record result from actor2 to field r2
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_02_Arbiters.java	Fri Jan 20 12:43:57 2017 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016, Red Hat Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jcstress.samples;
+
+import org.openjdk.jcstress.annotations.*;
+import org.openjdk.jcstress.infra.results.IntResult1;
+
+/*
+    Another flavor of the same test as JCStress_APISample_01_Simple is using
+    arbiters. Arbiters run after both actors, and therefore can observe the
+    final result.
+
+    This allows to directly observe the atomicity failure:
+
+          [OK] org.openjdk.jcstress.samples.JCStress_APISample_02_Arbiters
+        (JVM args: [-server])
+      Observed state   Occurrences              Expectation  Interpretation
+                   1       940,359   ACCEPTABLE_INTERESTING  One update lost: atomicity failure.
+                   2   168,950,601               ACCEPTABLE  Actors updated independently.
+
+    How to run this test:
+       $ java -jar jcstress-samples/target/jcstress.jar -t JCStress_APISample_02_Arbiters
+ */
+
+@JCStressTest
+
+// These are the test outcomes.
+@Outcome(id = "1", expect = Expect.ACCEPTABLE_INTERESTING, desc = "One update lost: atomicity failure.")
+@Outcome(id = "2", expect = Expect.ACCEPTABLE, desc = "Actors updated independently.")
+@State
+public class JCStress_APISample_02_Arbiters {
+
+    int v;
+
+    @Actor
+    public void actor1() {
+        v++;
+    }
+
+    @Actor
+    public void actor2() {
+        v++;
+    }
+
+    @Arbiter
+    public void arbiter(IntResult1 r) {
+        r.r1 = v;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_03_Termination.java	Fri Jan 20 12:43:57 2017 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016, Red Hat Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jcstress.samples;
+
+import org.openjdk.jcstress.annotations.*;
+
+/*
+    Some concurrency tests are not following the "run continously" pattern. One
+    of interesting test groups is that asserts if the code had terminated after
+    a signal.
+
+    Here, we use a single @Actor that busy-waits on a field, and a @Signal that
+    sets that field. JCStress would start actor, and then deliver the signal.
+    If it exits in reasonable time, it will record "TERMINATED" result, otherwise
+    record "STALE".
+
+    How to run this test:
+       $ java -jar jcstress-samples/target/jcstress.jar -t JCStress_APISample_03_Termination
+ */
+
+@JCStressTest(Mode.Termination)
+@Outcome(id = "TERMINATED", expect = Expect.ACCEPTABLE, desc = "Gracefully finished.")
+@Outcome(id = "STALE", expect = Expect.ACCEPTABLE_INTERESTING, desc = "Test hung up.")
+@State
+public class JCStress_APISample_03_Termination {
+
+    int v;
+
+    @Actor
+    public void actor1() {
+        while (v == 0) {
+            // spin
+        }
+    }
+
+    @Signal
+    public void signal() {
+        v = 1;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_04_Nesting.java	Fri Jan 20 12:43:57 2017 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, Red Hat Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jcstress.samples;
+
+import org.openjdk.jcstress.annotations.*;
+import org.openjdk.jcstress.infra.results.IntResult2;
+
+/*
+    It is sometimes convenient to put the tests in the same source file for
+    better comparison. JCStress allows to nest tests like this:
+
+    How to run this test:
+       $ java -jar jcstress-samples/target/jcstress.jar -t JCStress_APISample_04_Nesting
+ */
+
+public class JCStress_APISample_04_Nesting {
+
+    @JCStressTest
+    @Outcome(id = "1, 1", expect = Expect.ACCEPTABLE_INTERESTING, desc = "Both actors came up with the same value: atomicity failure.")
+    @Outcome(id = "1, 2", expect = Expect.ACCEPTABLE, desc = "actor1 incremented, then actor2.")
+    @Outcome(id = "2, 1", expect = Expect.ACCEPTABLE, desc = "actor2 incremented, then actor1.")
+    @State
+    public static class PlainTest {
+        int v;
+
+        @Actor
+        public void actor1(IntResult2 r) {
+            r.r1 = ++v;
+        }
+
+        @Actor
+        public void actor2(IntResult2 r) {
+            r.r2 = ++v;
+        }
+    }
+
+    @JCStressTest
+    @Outcome(id = "1, 1", expect = Expect.ACCEPTABLE_INTERESTING, desc = "Both actors came up with the same value: atomicity failure.")
+    @Outcome(id = "1, 2", expect = Expect.ACCEPTABLE, desc = "actor1 incremented, then actor2.")
+    @Outcome(id = "2, 1", expect = Expect.ACCEPTABLE, desc = "actor2 incremented, then actor1.")
+    @State
+    public static class VolatileTest {
+        volatile int v;
+
+        @Actor
+        public void actor1(IntResult2 r) {
+            r.r1 = ++v;
+        }
+
+        @Actor
+        public void actor2(IntResult2 r) {
+            r.r2 = ++v;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_05_SharedMetadata.java	Fri Jan 20 12:43:57 2017 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, Red Hat Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jcstress.samples;
+
+import org.openjdk.jcstress.annotations.*;
+import org.openjdk.jcstress.infra.results.IntResult2;
+
+/*
+   In many cases, tests share the outcomes and other metadata. To common them,
+   there is a special @JCStressMeta annotation that says to look up the metadata
+   at another class.
+
+   How to run this test:
+      $ java -jar jcstress-samples/target/jcstress.jar -t JCStress_APISample_05_SharedMetadata
+ */
+
+@Outcome(id = "1, 1", expect = Expect.ACCEPTABLE_INTERESTING, desc = "Both actors came up with the same value: atomicity failure.")
+@Outcome(id = "1, 2", expect = Expect.ACCEPTABLE, desc = "actor1 incremented, then actor2.")
+@Outcome(id = "2, 1", expect = Expect.ACCEPTABLE, desc = "actor2 incremented, then actor1.")
+public class JCStress_APISample_05_SharedMetadata {
+
+    @JCStressTest
+    @JCStressMeta(JCStress_APISample_05_SharedMetadata.class)
+    @State
+    public static class PlainTest {
+        int v;
+
+        @Actor
+        public void actor1(IntResult2 r) {
+            r.r1 = ++v;
+        }
+
+        @Actor
+        public void actor2(IntResult2 r) {
+            r.r2 = ++v;
+        }
+    }
+
+    @JCStressTest
+    @JCStressMeta(JCStress_APISample_05_SharedMetadata.class)
+    @State
+    public static class VolatileTest {
+        volatile int v;
+
+        @Actor
+        public void actor1(IntResult2 r) {
+            r.r1 = ++v;
+        }
+
+        @Actor
+        public void actor2(IntResult2 r) {
+            r.r2 = ++v;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-samples/src/main/java/org/openjdk/jcstress/samples/JCStress_APISample_06_Descriptions.java	Fri Jan 20 12:43:57 2017 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016, Red Hat Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jcstress.samples;
+
+import org.openjdk.jcstress.annotations.*;
+import org.openjdk.jcstress.infra.results.IntResult2;
+
+/*
+    JCStress also allows to put the descriptions and references right at the test.
+    This helps to identify the goal for the test, as well as the discussions about
+    the behavior in question.
+
+   How to run this test:
+      $ java -jar jcstress-samples/target/jcstress.jar -t JCStress_APISample_06_Descriptions
+ */
+
+@JCStressTest
+
+// Optional test description
+@Description("Sample Hello World test")
+
+// Optional references. @Ref is repeatable.
+@Ref("http://openjdk.java.net/projects/code-tools/jcstress/")
+
+@Outcome(id = "1, 1", expect = Expect.ACCEPTABLE_INTERESTING, desc = "Both actors came up with the same value: atomicity failure.")
+@Outcome(id = "1, 2", expect = Expect.ACCEPTABLE, desc = "actor1 incremented, then actor2.")
+@Outcome(id = "2, 1", expect = Expect.ACCEPTABLE, desc = "actor2 incremented, then actor1.")
+@State
+public class JCStress_APISample_06_Descriptions {
+
+    int v;
+
+    @Actor
+    public void actor1(IntResult2 r) {
+        r.r1 = ++v;
+    }
+
+    @Actor
+    public void actor2(IntResult2 r) {
+        r.r2 = ++v;
+    }
+
+}
--- a/jcstress-samples/src/main/java/org/openjdk/jcstress/tests/JCStressSample_01_IncrementAtomicity.java	Fri Jan 20 11:34:10 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2016, Red Hat Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jcstress.tests;
-
-import org.openjdk.jcstress.annotations.*;
-import org.openjdk.jcstress.infra.results.IntResult2;
-
-/*
-    This is our first concurrency test. It is deliberately simplistic to show
-    testing approaches, introduce JCStress APIs, etc.
-
-    Suppose we want to see if the field increment is atomic. We can make test
-    with two actors, both actors incrementing the field and recording what
-    value they observed into the result object. As JCStress runs, it will
-    invoke these methods on the objects holding the field once per each actor
-    and instance, and record what results are coming from there.
-
-    Done enough times, we will get the history of observed results, and that
-    would tell us something about the concurrent behavior. For example, running
-    this test would yield:
-
-          [OK] o.o.j.t.JCStressSample_01_IncrementAtomicity
-        (JVM args: [-server])
-      Observed state   Occurrences   Expectation  Interpretation
-                1, 1    54,734,140    ACCEPTABLE  Both threads came up with the same value: atomicity failure.
-                1, 2    47,037,891    ACCEPTABLE  actor1 incremented, then actor2.
-                2, 1    53,204,629    ACCEPTABLE  actor2 incremented, then actor1.
- */
-
-@JCStressTest
-
-// These are the test outcomes.
-@Outcome(id = "1, 1", expect = Expect.ACCEPTABLE, desc = "Both actors came up with the same value: atomicity failure.")
-@Outcome(id = "1, 2", expect = Expect.ACCEPTABLE, desc = "actor1 incremented, then actor2.")
-@Outcome(id = "2, 1", expect = Expect.ACCEPTABLE, desc = "actor2 incremented, then actor1.")
-
-// This is a state object
-@State
-public class JCStressSample_01_IncrementAtomicity {
-
-    int v;
-
-    @Actor
-    public void actor1(IntResult2 r) {
-        r.r1 = ++v; // record result from actor1 to field r1
-    }
-
-    @Actor
-    public void actor2(IntResult2 r) {
-        r.r2 = ++v; // record result from actor2 to field r2
-    }
-
-}