1 /*
   2  * Copyright 2010 Google, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 import java.util.*;
  26 import sun.misc.Continuation;
  27 
  28 /*
  29  * Basic tests for Continuation.
  30  */
  31 public class ContinuationTest1 {
  32 
  33     public Object subSave(Continuation cont, int a, int b, int c, int d, int e) {
  34         int i;
  35         cont.save();
  36         i = 0;
  37         i += a;
  38         i += b;
  39         i += c;
  40         i += d;
  41         i += e;
  42         assertEquals(15, i);
  43         return 10102;
  44     }
  45 
  46     private int cnt = 0;
  47 
  48     public void testRec() {
  49         final Continuation c = new Continuation();
  50         Runnable r1 = new Runnable() {
  51             public void run() {
  52                 assertEquals(10102, subSave(c, 1, 2, 3, 4, 5));
  53             }
  54           };
  55         Continuation.enter(r1, null);
  56         Runnable r2 = new Runnable() {
  57             public void run() {
  58                 c.resume(null);
  59             }
  60           };
  61         Continuation.enter(r2, null);
  62         System.out.println("testRec   : PASS");
  63     }
  64 
  65     public void testSimple() {
  66         final List<Integer> actions = new LinkedList<Integer>();
  67         final Continuation c = new Continuation();
  68         String data1 = "data1";
  69         Runnable r1 = new Runnable() {
  70             public void run() {
  71                 actions.add(1);
  72                 c.save();
  73                 actions.add(3);
  74             }
  75           };
  76         Continuation.enter(r1, data1);
  77         Runnable r2 = new Runnable() {
  78             public void run() {
  79                 actions.add(2);
  80                 c.resume(null);
  81                 actions.add(100);
  82             }
  83           };
  84         Continuation.enter(r2, null);
  85         assertIdentity(c.data1(), data1);
  86         assertEquals(actions.size(), 3);
  87         assertEquals(actions.get(0), 1);
  88         assertEquals(actions.get(1), 2);
  89         assertEquals(actions.get(2), 3);
  90         System.out.println("testSimple: PASS");
  91     }
  92 
  93     // If a monitor is held when a continuation is attempted to be saved,
  94     // an exception should be thrown.
  95     public void testMonitors() {
  96         final Continuation c = new Continuation();
  97         final Object lock = new Object();
  98         Runnable r1 = new Runnable() {
  99             public void run() {
 100                 synchronized(lock) {
 101                     c.save(); // this should throw an exception
 102                     assertTrue(false);
 103                 }
 104                 assertTrue(false);
 105             }
 106           };
 107         try {
 108             Continuation.enter(r1, null);
 109         } catch (Throwable t) {
 110             System.out.println("testMonitors: PASS");
 111             return;
 112         }
 113         assertTrue(false);
 114     }
 115 
 116     // If the continuation is attempted to be resumed twice, an
 117     // exception should be thrown.
 118     public void testDoubleResume() {
 119         final Continuation c = new Continuation();
 120         final Object lock = new Object();
 121         Runnable r1 = new Runnable() {
 122             public void run() {
 123                 c.save();
 124             }
 125           };
 126         Continuation.enter(r1, null);
 127         Runnable r2 = new Runnable() {
 128             public void run() {
 129                 c.resume(null);
 130             }
 131           };
 132         Continuation.enter(r2, null);
 133         try {
 134             Continuation.enter(r2, null);
 135         } catch (Throwable t) {
 136             System.out.println("testDoubleResume: PASS");
 137             return;
 138         }
 139         assertTrue(false);
 140     }
 141 
 142     public void testData1() throws Exception {
 143         final Continuation c = new Continuation();
 144         final Object data1 = new Object();
 145         Runnable r1 = new Runnable() {
 146             public void run() {
 147                 c.save();
 148                 assertIdentity(c.data1(), data1);
 149             }
 150           };
 151         Continuation.enter(r1, data1);
 152         assertIdentity(c.data1(), data1);
 153         Runnable r2 = new Runnable() {
 154             public void run() {
 155                 Runnable r3 = new Runnable() {
 156                     public void run() {
 157                         c.resume(null);
 158                     }
 159                   };
 160                 Continuation.enter(r3, null);
 161             }
 162           };
 163         Thread t = new Thread(r2);
 164         t.start();
 165         t.join();
 166         System.out.println("testData1: PASS");
 167     }
 168 
 169     public void testManyParams() {
 170         final Continuation c = new Continuation();
 171         Runnable r1 = new Runnable() {
 172             public void run() {
 173                 Object rv = manyParamsSub(c, 5, true, false, 1, (short) 2, (byte) 3, (char) 4, (long) 5, 6, (short) 7, (byte) 8, (char) 9,
 174                                           (long) 10, (float) 11, (double) 12, (float) 13, (double) 14, 15, 16, 17, 18, 19, 20);
 175                 assertEquals(43, rv);
 176             }
 177           };
 178         Continuation.enter(r1, null);
 179         Runnable r2 = new Runnable() {
 180             public void run() {
 181                 c.resume(43);
 182             }
 183           };
 184         Continuation.enter(r2, null);
 185         System.out.println("testManyParams: PASS");
 186     }
 187 
 188     private Object manyParamsSub(Continuation cont, int depth, boolean a, boolean b, int c, short d, byte e, char f,
 189                                  long g, Integer h, Short i, Byte j, Character k, Long l, float m, double n, Float o, Double p, Integer q, int r,
 190                                  int s, int t, int u, int v) {
 191         final Object ret;
 192         if (depth > 0)
 193             ret = manyParamsSub(cont, depth - 1, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v);
 194         else
 195             ret = cont.save();
 196         assertEquals(a, true);
 197         assertEquals(b, false);
 198         assertEquals(c, 1);
 199         assertEquals(d, (short) 2);
 200         assertEquals(e, (byte) 3);
 201         assertEquals(f, (char) 4);
 202         assertEquals(g, (long) 5);
 203         assertEquals(h, 6);
 204         assertEquals(i, (short) 7);
 205         assertEquals(j, (byte) 8);
 206         assertEquals(k, (char) 9);
 207         assertEquals(l, (long) 10);
 208         assertEquals(m, (float) 11);
 209         assertEquals(n, (double) 12);
 210         assertEquals(o, (float) 13);
 211         assertEquals(p, (double) 14);
 212         assertEquals(q, 15);
 213         assertEquals(r, 16);
 214         assertEquals(s, 17);
 215         assertEquals(t, 18);
 216         assertEquals(u, 19);
 217         assertEquals(v, 20);
 218         return ret;
 219     }
 220 
 221     public static void main(String[] args) throws Exception {
 222         ContinuationTest1 test = new ContinuationTest1();
 223         test.testSimple();
 224         test.testData1();
 225         test.testRec();
 226         test.testManyParams();
 227         test.testMonitors();
 228         test.testDoubleResume();
 229     }
 230 
 231     private static void assertTrue(boolean cond) {
 232         if (!cond) {
 233             throw new RuntimeException("assertion failed");
 234         }
 235     }
 236 
 237     private static void assertEquals(Object o1, Object o2) {
 238         if (!o1.equals(o2)) {
 239             throw new RuntimeException("assertion failed: [" + o1 + "] != [" + o2 + "]");
 240         }
 241     }
 242 
 243     private static void assertIdentity(Object o1, Object o2) {
 244         if (o1 != o2) {
 245             throw new RuntimeException("assertion failed: [" + o1 + "] != [" + o2 + "]");
 246         }
 247     }
 248 }