1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.surefire.booter;
20
21 import java.lang.management.ManagementFactory;
22
23 import org.junit.Assume;
24 import org.junit.Test;
25
26 import static org.assertj.core.api.Assertions.assertThat;
27 import static org.assertj.core.api.Assertions.assertThatThrownBy;
28 import static org.junit.Assume.assumeTrue;
29
30
31
32
33
34
35 public class ProcessHandleCheckerTest {
36
37 @Test
38 public void shouldReportAvailableOnJava9Plus() {
39
40
41 double v = Double.parseDouble(System.getProperty("java.specification.version"));
42 Assume.assumeTrue(v >= 9.0);
43 assertThat(ProcessHandleChecker.isAvailable()).isTrue();
44 }
45
46 @Test
47 public void shouldDetectCurrentProcessAsAlive() {
48 assumeTrue("ProcessHandle not available", ProcessHandleChecker.isAvailable());
49
50 String currentPid = getCurrentPid();
51 assumeTrue("Could not determine current PID", currentPid != null);
52
53 ProcessHandleChecker checker = new ProcessHandleChecker(currentPid);
54
55 assertThat(checker.canUse()).isTrue();
56 assertThat(checker.isProcessAlive()).isTrue();
57 assertThat(checker.isStopped()).isFalse();
58 }
59
60 @Test
61 public void shouldDetectNonExistentProcessAsNotUsable() {
62 assumeTrue("ProcessHandle not available", ProcessHandleChecker.isAvailable());
63
64
65 ProcessHandleChecker checker = new ProcessHandleChecker("999999999");
66
67 assertThat(checker.canUse()).isTrue();
68 }
69
70 @Test
71 public void shouldStopChecker() {
72 assumeTrue("ProcessHandle not available", ProcessHandleChecker.isAvailable());
73
74 String currentPid = getCurrentPid();
75 assumeTrue("Could not determine current PID", currentPid != null);
76
77 ProcessHandleChecker checker = new ProcessHandleChecker(currentPid);
78
79 assertThat(checker.canUse()).isTrue();
80 assertThat(checker.isStopped()).isFalse();
81
82 checker.stop();
83
84 assertThat(checker.isStopped()).isTrue();
85 assertThat(checker.canUse()).isFalse();
86 }
87
88 @Test
89 public void shouldDestroyActiveCommands() {
90 assumeTrue("ProcessHandle not available", ProcessHandleChecker.isAvailable());
91
92 String currentPid = getCurrentPid();
93 assumeTrue("Could not determine current PID", currentPid != null);
94
95 ProcessHandleChecker checker = new ProcessHandleChecker(currentPid);
96
97 assertThat(checker.canUse()).isTrue();
98
99 checker.destroyActiveCommands();
100
101 assertThat(checker.isStopped()).isTrue();
102 assertThat(checker.canUse()).isFalse();
103 }
104
105 @Test
106 public void shouldReturnMeaningfulToString() {
107 assumeTrue("ProcessHandle not available", ProcessHandleChecker.isAvailable());
108
109 String currentPid = getCurrentPid();
110 assumeTrue("Could not determine current PID", currentPid != null);
111
112 ProcessHandleChecker checker = new ProcessHandleChecker(currentPid);
113
114 String toString = checker.toString();
115
116 assertThat(toString)
117 .contains("ProcessHandleChecker")
118 .contains("pid=" + currentPid)
119 .contains("stopped=false");
120 }
121
122 @Test
123 public void shouldReturnToStringWithStartInstantAfterCanUse() {
124 assumeTrue("ProcessHandle not available", ProcessHandleChecker.isAvailable());
125
126 String currentPid = getCurrentPid();
127 assumeTrue("Could not determine current PID", currentPid != null);
128
129 ProcessHandleChecker checker = new ProcessHandleChecker(currentPid);
130
131 checker.canUse();
132 String toString = checker.toString();
133
134 assertThat(toString).contains("ProcessHandleChecker").contains("hasHandle=true");
135 }
136
137 @Test
138 public void shouldCreateViaFactoryMethod() {
139 assumeTrue("ProcessHandle not available", ProcessHandleChecker.isAvailable());
140
141 String currentPid = getCurrentPid();
142 assumeTrue("Could not determine current PID", currentPid != null);
143
144 ProcessChecker checker = ProcessChecker.of(currentPid);
145
146 assertThat(checker).isInstanceOf(ProcessHandleChecker.class);
147 assertThat(checker.canUse()).isTrue();
148 assertThat(checker.isProcessAlive()).isTrue();
149 }
150
151 @Test
152 public void shouldReturnNullFromFactoryForNullPpid() {
153 ProcessChecker checker = ProcessChecker.of(null);
154
155 assertThat(checker).isNull();
156 }
157
158 @Test
159 public void shouldThrowOnInvalidPpidFormat() {
160 assertThatThrownBy(() -> new ProcessHandleChecker("not-a-number")).isInstanceOf(NumberFormatException.class);
161 }
162
163 @Test
164 public void shouldReturnProcessInfoAfterCanUse() {
165 assumeTrue("ProcessHandle not available", ProcessHandleChecker.isAvailable());
166
167 String currentPid = getCurrentPid();
168 assumeTrue("Could not determine current PID", currentPid != null);
169
170 ProcessHandleChecker checker = new ProcessHandleChecker(currentPid);
171
172
173 ProcessInfo processInfo = checker.processInfo();
174 assertThat(processInfo).isNotNull();
175 assertThat(processInfo.getPID()).isEqualTo(currentPid);
176 assertThat(processInfo.getTime()).isGreaterThan(0L);
177 }
178
179
180
181
182
183
184 private static String getCurrentPid() {
185
186 try {
187 Class<?> processHandleClass = Class.forName("java.lang.ProcessHandle");
188 Object currentHandle = processHandleClass.getMethod("current").invoke(null);
189 Long pid = (Long) processHandleClass.getMethod("pid").invoke(currentHandle);
190 return String.valueOf(pid);
191 } catch (Exception e) {
192
193 try {
194 String name = ManagementFactory.getRuntimeMXBean().getName();
195 int atIndex = name.indexOf('@');
196 if (atIndex > 0) {
197 return name.substring(0, atIndex);
198 }
199 } catch (Exception ex) {
200
201 }
202 }
203 return null;
204 }
205 }