View Javadoc
1   /*
2    * Copyright (c) 2001-2017, Zoltan Farkas All Rights Reserved.
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this program; if not, write to the Free Software
16   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17   *
18   * Additionally licensed with:
19   *
20   * Licensed under the Apache License, Version 2.0 (the "License");
21   * you may not use this file except in compliance with the License.
22   * You may obtain a copy of the License at
23   *
24   *      http://www.apache.org/licenses/LICENSE-2.0
25   *
26   * Unless required by applicable law or agreed to in writing, software
27   * distributed under the License is distributed on an "AS IS" BASIS,
28   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29   * See the License for the specific language governing permissions and
30   * limitations under the License.
31   */
32  package org.spf4j.base;
33  
34  import org.spf4j.os.OperatingSystem;
35  import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
36  import java.io.IOException;
37  import java.lang.reflect.Method;
38  import java.util.concurrent.CancellationException;
39  import java.util.concurrent.CountDownLatch;
40  import java.util.concurrent.ExecutionException;
41  import java.util.concurrent.Future;
42  import java.util.concurrent.TimeUnit;
43  import java.util.concurrent.TimeoutException;
44  import java.util.stream.Collectors;
45  import org.hamcrest.Matchers;
46  import org.junit.Assert;
47  import org.junit.Assume;
48  import org.junit.Test;
49  import org.slf4j.Logger;
50  import org.slf4j.LoggerFactory;
51  import org.spf4j.concurrent.DefaultExecutor;
52  import org.spf4j.concurrent.DefaultScheduler;
53  import org.spf4j.os.StdOutToStringProcessHandler;
54  import org.spf4j.log.Level;
55  import org.spf4j.test.log.LogCollection;
56  import org.spf4j.test.log.TestLoggers;
57  import org.spf4j.test.log.annotations.ExpectLog;
58  
59  /**
60   * @author zoly
61   */
62  public final class RuntimeTest {
63  
64    private static final Logger LOG = LoggerFactory.getLogger(RuntimeTest.class);
65  
66    @Test
67    public void testHaveJnaPlatform() {
68      Assert.assertTrue(Runtime.haveJnaPlatform());
69    }
70  
71    @Test
72    public void testSpecVersion() {
73      Assert.assertEquals(Runtime.Version.V1_8,  Runtime.Version.fromSpecVersion("1.8.0_151"));
74    }
75  
76  
77    @Test
78    public void testMainClass() throws NoSuchMethodException {
79      Class<?> mainClass = Runtime.getMainClass();
80      Assert.assertNotNull(mainClass);
81      Method method = mainClass.getMethod("main", String[].class);
82      Assert.assertNotNull(method);
83    }
84  
85    @Test
86    public void testMaxOpenFiles() {
87      Assume.assumeFalse(Runtime.isWindows());
88      Assert.assertNotEquals(Integer.MAX_VALUE, OperatingSystem.getMaxFileDescriptorCount());
89    }
90  
91    /**
92     * Test of goDownWithError method, of class Runtime.
93     */
94    @Test
95    public void testSomeParams() {
96      LOG.debug("PID={}", Runtime.PID);
97      LOG.debug("OSNAME={}", Runtime.OS_NAME);
98      int nrOpenFiles = Runtime.getNrOpenFiles();
99      LOG.debug("NR_OPEN_FILES={}", nrOpenFiles);
100     Assert.assertThat(nrOpenFiles, Matchers.greaterThan(0));
101     CharSequence lsofOutput = Runtime.getLsofOutput();
102     LOG.debug("LSOF_OUT={}", lsofOutput);
103     Assert.assertNotNull(lsofOutput);
104     Assert.assertThat(lsofOutput.toString(), Matchers.containsString("jar"));
105     LOG.debug("MAX_OPEN_FILES={}", OperatingSystem.getMaxFileDescriptorCount());
106   }
107 
108   @Test(expected = ExecutionException.class, timeout = 60000)
109   @ExpectLog(category = "org.spf4j.os", level = Level.ERROR, nrTimes = 2)
110   public void testExitCode() throws IOException, InterruptedException, ExecutionException, TimeoutException {
111     Runtime.jrun(RuntimeTest.TestError.class, 60000);
112   }
113 
114   @ExpectLog(category = "org.spf4j.os", level = Level.ERROR, nrTimes = 2)
115   @Test(expected = ExecutionException.class, timeout = 60000)
116   public void testExitCode2() throws IOException, InterruptedException, ExecutionException, TimeoutException {
117     Runtime.jrun(RuntimeTest.TestError2.class, 60000);
118   }
119 
120   @Test(expected = TimeoutException.class, timeout = 30000)
121   public void testExitCode3() throws IOException, InterruptedException, ExecutionException, TimeoutException {
122     LogCollection<Long> collect = TestLoggers.sys().collect(StdOutToStringProcessHandler.class.getName(), Level.ERROR,
123             Level.ERROR, false, Collectors.counting());
124     Runtime.jrun(RuntimeTest.TestError3.class, 10000);
125     Assert.assertTrue(collect.get() > 0);
126   }
127 
128   @Test(expected = InterruptedException.class, timeout = 30000)
129   public void testExitCode4() throws IOException, InterruptedException, ExecutionException, TimeoutException {
130     final Thread t = Thread.currentThread();
131     DefaultScheduler.INSTANCE.schedule(() -> {
132       t.interrupt();
133     }, 1, TimeUnit.SECONDS);
134     Runtime.jrun(RuntimeTest.TestSleeping.class, 10000);
135   }
136 
137   @SuppressFBWarnings("SIC_INNER_SHOULD_BE_STATIC_ANON")
138   @Test(expected = CancellationException.class, timeout = 30000)
139 //  @ExpectLog(level = Level.ERROR, category = "org.spf4j.os", nrTimes = 2)
140   public void testExitCode5() throws InterruptedException, ExecutionException, TimeoutException {
141     final CountDownLatch latch = new CountDownLatch(1);
142     final CountDownLatch canCancel = new CountDownLatch(1);
143     Future<?> submit = DefaultExecutor.INSTANCE.submit(new AbstractRunnable() {
144 
145       @Override
146       public void doRun() throws IOException, InterruptedException, ExecutionException, TimeoutException {
147         try {
148           canCancel.countDown();
149           Runtime.jrun(RuntimeTest.TestError3.class, 10000);
150         } catch (InterruptedException ex) {
151           LOG.info("Interrupted jrun TestError3", ex);
152           latch.countDown();
153         } catch (Exception ex) {
154           LOG.info("Exception jrun TestError3", ex);
155         }
156       }
157     });
158     if (!canCancel.await(3000, TimeUnit.MILLISECONDS)) {
159       Assert.fail("exec should happen");
160     }
161     LOG.debug("cancelling {}", submit);
162     submit.cancel(true);
163     if (!latch.await(1, TimeUnit.SECONDS)) {
164       Assert.fail("exec should be cancelled");
165     }
166     submit.get(10000, TimeUnit.MILLISECONDS);
167 
168   }
169 
170   public static final class TestSleeping {
171 
172     @SuppressFBWarnings("MDM_THREAD_YIELD")
173     public static void main(final String[] args) throws InterruptedException {
174       Thread.sleep(60000);
175     }
176   }
177 
178 
179   public static final class TestError {
180 
181     public static void main(final String[] args) {
182       throw new RuntimeException();
183     }
184   }
185 
186   public static final class TestError2 {
187 
188     public static void main(final String[] args) {
189       Thread.setDefaultUncaughtExceptionHandler((final Thread t, final Throwable e) -> {
190         Throwables.writeTo(e, System.err, Throwables.PackageDetail.SHORT);
191       });
192       throw new RuntimeException();
193     }
194   }
195 
196   public static final class TestError3 {
197 
198     public static void main(final String[] args) {
199       Thread.setDefaultUncaughtExceptionHandler((final Thread t, final Throwable e) -> {
200         Throwables.writeTo(e, System.err, Throwables.PackageDetail.SHORT);
201       });
202       DefaultScheduler.INSTANCE.scheduleAtFixedRate(AbstractRunnable.NOP, 10, 10, TimeUnit.MILLISECONDS);
203       throw new RuntimeException();
204     }
205   }
206 
207 }