1 /*
2  * Copyright (c) 2014, 2019, Oracle and/or its affiliates. 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.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 8044131
27  * @summary Tests the hooks used for detecting idleness of the sjavac server.
28  * @modules jdk.compiler/com.sun.tools.javac.main
29  *          jdk.compiler/com.sun.tools.sjavac.server
30  * @build Wrapper
31  * @run main Wrapper IdleShutdown
32  */
33 
34 import java.util.concurrent.atomic.AtomicLong;
35 
36 import com.sun.tools.javac.main.Main.Result;
37 import com.sun.tools.sjavac.server.IdleResetSjavac;
38 import com.sun.tools.sjavac.server.Sjavac;
39 import com.sun.tools.sjavac.server.Terminable;
40 
41 
42 public class IdleShutdown {
43 
44     final static long TEST_START = System.currentTimeMillis();
45     final static long TIMEOUT_MS = 3000;
46 
main(String[] args)47     public static void main(String[] args) throws InterruptedException {
48 
49         final AtomicLong timeoutTimestamp = new AtomicLong(-1);
50 
51         log("Starting IdleCallbackJavacService with timeout: " + TIMEOUT_MS);
52         Sjavac service = new IdleResetSjavac(
53                 new NoopJavacService(),
54                 new Terminable() {
55                     public void shutdown(String msg) {
56                         // Record the idle timeout time
57                         log("Timeout detected");
58                         timeoutTimestamp.set(System.currentTimeMillis());
59                     }
60                 },
61                 TIMEOUT_MS);
62 
63         // Make sure it didn't timeout immediately
64         if (timeoutTimestamp.get() != -1)
65             throw new AssertionError("Premature timeout detected.");
66 
67         // Use Sjavac object and wait less than TIMEOUT_MS in between calls
68         Thread.sleep(TIMEOUT_MS - 1000);
69         log("Compiling");
70         service.compile(new String[0]);
71 
72         Thread.sleep(TIMEOUT_MS - 1000);
73         log("Compiling");
74         service.compile(new String[0]);
75 
76         if (timeoutTimestamp.get() != -1)
77             throw new AssertionError("Premature timeout detected.");
78 
79         long expectedTimeout = System.currentTimeMillis() + TIMEOUT_MS;
80 
81         // Wait for actual timeout
82         log("Awaiting idle timeout");
83         Thread.sleep(TIMEOUT_MS + 1000);
84 
85         // Check result
86         if (timeoutTimestamp.get() == -1)
87             throw new AssertionError("Timeout never occurred");
88 
89         long error = Math.abs(expectedTimeout - timeoutTimestamp.get());
90         log("Timeout error: " + error + " ms");
91         String timeoutFactorText = System.getProperty("test.timeout.factor", "1.0");
92         double timeoutFactor = Double.parseDouble(timeoutFactorText);
93         double allowedError = TIMEOUT_MS * 0.1 * timeoutFactor;
94         if (error > allowedError) {
95             throw new AssertionError("Timeout error too large, error is " + error +
96                                      " milliseconds, we allowed " + allowedError + " milliseconds");
97         }
98         log("Shutting down");
99         service.shutdown();
100     }
101 
log(String msg)102     private static void log(String msg) {
103         long logTime = System.currentTimeMillis() - TEST_START;
104         System.out.printf("After %5d ms: %s%n", logTime, msg);
105     }
106 
107     private static class NoopJavacService implements Sjavac {
108         @Override
shutdown()109         public void shutdown() {
110         }
111         @Override
compile(String[] args)112         public Result compile(String[] args) {
113             // Attempt to trigger idle timeout during a call by sleeping
114             try {
115                 Thread.sleep(TIMEOUT_MS + 1000);
116             } catch (InterruptedException e) {
117             }
118             return Result.OK;
119         }
120     }
121 }
122