View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.surefire.its.jiras;
20  
21  import java.util.Iterator;
22  
23  import org.apache.maven.surefire.its.fixture.OutputValidator;
24  import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
25  import org.apache.maven.surefire.its.fixture.SurefireLauncher;
26  import org.junit.Test;
27  import org.junit.runner.RunWith;
28  import org.junit.runners.Parameterized;
29  import org.junit.runners.Parameterized.Parameter;
30  import org.junit.runners.Parameterized.Parameters;
31  
32  import static java.util.Arrays.asList;
33  import static java.util.concurrent.TimeUnit.SECONDS;
34  import static org.apache.maven.surefire.its.jiras.Surefire1295AttributeJvmCrashesToTestsIT.ForkMode.DEFAULT;
35  import static org.apache.maven.surefire.its.jiras.Surefire1295AttributeJvmCrashesToTestsIT.ForkMode.ONE_FORK_NO_REUSE;
36  import static org.apache.maven.surefire.its.jiras.Surefire1295AttributeJvmCrashesToTestsIT.ForkMode.ONE_FORK_REUSE;
37  import static org.assertj.core.api.Assertions.assertThat;
38  import static org.junit.Assert.fail;
39  import static org.junit.Assume.assumeTrue;
40  
41  /**
42   * https://issues.apache.org/jira/browse/SUREFIRE-1295
43   * https://github.com/apache/maven-surefire/pull/136
44   *
45   * @author michaeltandy
46   * @since 2.20
47   */
48  @RunWith(Parameterized.class)
49  public class Surefire1295AttributeJvmCrashesToTestsIT extends SurefireJUnit4IntegrationTestCase {
50      private static final int ONE_FORK_REUSE_THREAD_COUNT = 1;
51  
52      /**
53       *
54       */
55      public enum ForkMode {
56          DEFAULT,
57          ONE_FORK_NO_REUSE,
58          ONE_FORK_REUSE
59      }
60  
61      @Parameters
62      public static Iterable<Object[]> parameters() {
63          return asList(new Object[][] {
64              //                exit() does not stop all Threads immediately,
65              //                see https://github.com/michaeltandy/crashjvm/issues/1
66              {"exit", DEFAULT},
67              {"exit", ONE_FORK_NO_REUSE},
68              {"exit", ONE_FORK_REUSE},
69              {"abort", DEFAULT},
70              {"abort", ONE_FORK_NO_REUSE},
71              {"abort", ONE_FORK_REUSE},
72              {"segfault", DEFAULT},
73              {"segfault", ONE_FORK_NO_REUSE},
74              {"segfault", ONE_FORK_REUSE}
75          });
76      }
77  
78      @Parameter(0)
79      @SuppressWarnings("checkstyle:visibilitymodifier")
80      public String crashStyle;
81  
82      @Parameter(1)
83      @SuppressWarnings("checkstyle:visibilitymodifier")
84      public ForkMode forkStyle;
85  
86      @Test
87      public void test() throws Exception {
88          SurefireLauncher launcher = unpack("crash-during-test", "_" + crashStyle + "_" + forkStyle.ordinal())
89                  .setForkJvm();
90  
91          switch (forkStyle) {
92              case DEFAULT:
93                  break;
94              case ONE_FORK_NO_REUSE:
95                  launcher.forkCount(1).reuseForks(false);
96                  break;
97              case ONE_FORK_REUSE:
98                  launcher.forkPerThread(ONE_FORK_REUSE_THREAD_COUNT).threadCount(ONE_FORK_REUSE_THREAD_COUNT);
99                  break;
100             default:
101                 fail();
102         }
103 
104         checkCrash(launcher.addGoal("-DcrashType=" + crashStyle));
105     }
106 
107     private static void checkCrash(SurefireLauncher launcher) throws Exception {
108         OutputValidator validator = launcher.maven().withFailure().executeTest();
109 
110         boolean osAndArchSupported = true;
111         for (Iterator<String> it = validator.loadLogLines().iterator(); it.hasNext(); ) {
112             String line = it.next();
113             if (line.contains("java.lang.RuntimeException: Unrecognised OS")
114                     || line.contains("java.lang.RuntimeException: Unrecognised arch")) {
115                 osAndArchSupported = false;
116                 break;
117             }
118         }
119 
120         assumeTrue(
121                 "crashjvm does not support " + System.getProperty("os.name") + "/" + System.getProperty("os.arch"),
122                 osAndArchSupported);
123 
124         validator
125                 .verifyTextInLog("The forked VM terminated without properly saying "
126                         + "goodbye. VM crash or System.exit called?")
127                 .verifyTextInLog("Crashed tests:");
128 
129         // Cannot flush log.txt stream because it is consumed internally by Verifier.
130         // Waiting for the stream to become flushed on disk.
131         SECONDS.sleep(1L);
132 
133         for (Iterator<String> it = validator.loadLogLines().iterator(); it.hasNext(); ) {
134             String line = it.next();
135             if (line.contains("Crashed tests:")) {
136                 line = it.next();
137                 if (it.hasNext()) {
138                     assertThat(line).contains("junit44.environment.Test1CrashedTest");
139                 } else {
140                     fail("Could not find any line after 'Crashed tests:'.");
141                 }
142             }
143         }
144     }
145 }