1
2
3
4
5 package oshi.software.os;
6
7 import static org.hamcrest.MatcherAssert.assertThat;
8 import static org.hamcrest.Matchers.anything;
9 import static org.hamcrest.Matchers.both;
10 import static org.hamcrest.Matchers.closeTo;
11 import static org.hamcrest.Matchers.empty;
12 import static org.hamcrest.Matchers.emptyString;
13 import static org.hamcrest.Matchers.greaterThan;
14 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
15 import static org.hamcrest.Matchers.hasSize;
16 import static org.hamcrest.Matchers.is;
17 import static org.hamcrest.Matchers.lessThan;
18 import static org.hamcrest.Matchers.lessThanOrEqualTo;
19 import static org.hamcrest.Matchers.not;
20 import static org.hamcrest.Matchers.notNullValue;
21 import static org.hamcrest.Matchers.oneOf;
22
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Locale;
29 import java.util.Map;
30 import java.util.Set;
31
32 import org.junit.jupiter.api.BeforeAll;
33 import org.junit.jupiter.api.Test;
34 import org.junit.jupiter.api.TestInstance;
35 import org.junit.jupiter.api.TestInstance.Lifecycle;
36
37 import com.sun.jna.Platform;
38
39 import oshi.SystemInfo;
40 import oshi.software.os.OSProcess.State;
41 import oshi.software.os.OperatingSystem.OSVersionInfo;
42 import oshi.software.os.OperatingSystem.ProcessFiltering;
43 import oshi.software.os.OperatingSystem.ProcessSorting;
44
45
46
47
48 @TestInstance(Lifecycle.PER_CLASS)
49 class OperatingSystemTest {
50
51 private OperatingSystem os = new SystemInfo().getOperatingSystem();
52 private OSProcess proc = os.getProcess(os.getProcessId());
53
54 @BeforeAll
55 void setUp() {
56
57
58 if (this.proc == null) {
59 this.proc = os.getProcess(os.getProcessId());
60 }
61
62 assertThat("Current process PID returned null", proc, is(notNullValue()));
63 }
64
65 @Test
66 void testOperatingSystem() {
67 assertThat("OS family shouldn't be null", os.getFamily(), is(notNullValue()));
68 assertThat("OS manufacturer shouldn't be null", os.getManufacturer(), is(notNullValue()));
69 OSVersionInfo versionInfo = os.getVersionInfo();
70 assertThat("OS version info shouldn't be null", versionInfo, is(notNullValue()));
71
72 assertThat("OS uptime in seconds should be greater than 0", os.getSystemUptime(), is(greaterThan(0L)));
73 assertThat("OS boot time in seconds since Unix epoch should be greater than 0", os.getSystemBootTime(),
74 is(greaterThan(0L)));
75 assertThat("OS boot time in seconds since Unix epoch should be before the current time", os.getSystemBootTime(),
76 is(lessThan(System.currentTimeMillis() / 1000L)));
77
78 assertThat("OS should have 1 or more currently running processes", os.getProcessCount(), is(greaterThan(0)));
79 assertThat("OS should have 1 or more currently running threads", os.getThreadCount(), is(greaterThan(0)));
80 assertThat("OS bitness should either be 32 or 64 ", os.getBitness(), is(oneOf(32, 64)));
81 assertThat("The current process id should be greater than 0", os.getProcessId(), is(greaterThan(0)));
82
83 assertThat(
84 "The current process' permissions (if has sudo or Administrator privileges) should be determined correctly",
85 os.isElevated(), is(anything()));
86
87 assertThat("OS should have at least 1 currently running process", os.getProcesses(null, null, 0),
88 is(not(empty())));
89 }
90
91 @Test
92 void testProcessStrings() {
93 assertThat("Current running process name shouldn't be empty", proc.getName(), is(not(emptyString())));
94 assertThat("Current running process path name shouldn't be empty", proc.getPath(), is(not(emptyString())));
95 assertThat("Current running process command line shouldn't be null", proc.getCommandLine(), is(notNullValue()));
96 assertThat("Current running process working directory shouldn't be null", proc.getCurrentWorkingDirectory(),
97 is(notNullValue()));
98 assertThat("Current running process user name shouldn't be null", proc.getUser(), is(notNullValue()));
99 assertThat("Current running process user id shouldn't be null ", proc.getUserID(), is(notNullValue()));
100 assertThat("Current running process group shouldn't be null", proc.getGroup(), is(notNullValue()));
101 assertThat("Current running process group id shouldn't be null", proc.getGroupID(), is(notNullValue()));
102 }
103
104 @Test
105 void testProcessStats() {
106 assertThat("Current running process state shouldn't be INVALID", proc.getState(), is(not(State.INVALID)));
107 assertThat("Current running process id should be equal to the OS current running process id", os.getProcessId(),
108 is(proc.getProcessID()));
109 assertThat("Current running process parent process id should be 0 or higher", proc.getParentProcessID(),
110 is(greaterThanOrEqualTo(0)));
111 assertThat("Current running process thread count should be greater than 0", proc.getThreadCount(),
112 is(greaterThan(0)));
113 if (Platform.isAIX()) {
114 assertThat("Current running process priority should be between -20 and 255", proc.getPriority(),
115 is(both(greaterThanOrEqualTo(1)).and(lessThanOrEqualTo(255))));
116 } else {
117 assertThat("Current running process priority should be between -20 and 128", proc.getPriority(),
118 is(both(greaterThanOrEqualTo(-20)).and(lessThanOrEqualTo(128))));
119 }
120 assertThat("Current running process virtual memory size should be 0 or higher", proc.getVirtualSize(),
121 is(greaterThanOrEqualTo(0L)));
122 assertThat("Current running process resident set size should be 0 or higher", proc.getResidentSetSize(),
123 is(greaterThanOrEqualTo(0L)));
124 assertThat("Current running process time elapsed in system/kernel should be 0 or higher", proc.getKernelTime(),
125 is(greaterThanOrEqualTo(0L)));
126 assertThat("Current running process time elapsed in user mode should be 0 or higher", proc.getUserTime(),
127 is(greaterThanOrEqualTo(0L)));
128 assertThat("Current running process uptime should be 0 or higher", proc.getUpTime(),
129 is(greaterThanOrEqualTo(0L)));
130 assertThat("Current process minor faults should be 0 or higher", proc.getMinorFaults(),
131 is(greaterThanOrEqualTo(0L)));
132 assertThat("Current process major faults should be 0 or higher", proc.getMajorFaults(),
133 is(greaterThanOrEqualTo(0L)));
134 assertThat("Current process context switches should be 0 or higher", proc.getContextSwitches(),
135 is(greaterThanOrEqualTo(0L)));
136 assertThat("Current process cumulative cpu usage should be 0.0 or higher", proc.getProcessCpuLoadCumulative(),
137 is(greaterThanOrEqualTo(0d)));
138 assertThat("Current process cumulative cpu usage should be the same as the current process",
139 proc.getProcessCpuLoadBetweenTicks(null),
140 is(closeTo(proc.getProcessCpuLoadCumulative(), Double.MIN_VALUE)));
141 assertThat(
142 "Current process cumulative cpu usage should be the same for a previous snapshot of the same process",
143 proc.getProcessCpuLoadBetweenTicks(proc),
144 is(closeTo(proc.getProcessCpuLoadCumulative(), Double.MIN_VALUE)));
145 assertThat("Current process start time should be 0 or higher", proc.getStartTime(),
146 is(greaterThanOrEqualTo(0L)));
147 assertThat("Current process bytes read from disk should be 0 or higher", proc.getBytesRead(),
148 is(greaterThanOrEqualTo(0L)));
149 assertThat("Current process bytes written to disk should be 0 or higher", proc.getBytesWritten(),
150 is(greaterThanOrEqualTo(0L)));
151 assertThat("Process bitness can't exceed OS bitness", proc.getBitness(),
152 is(lessThanOrEqualTo(os.getBitness())));
153 assertThat("Bitness must be 0, 32 or 64", proc.getBitness(), is(oneOf(0, 32, 64)));
154 assertThat("Current process open file handles should be -1 or higher", proc.getOpenFiles(),
155 is(greaterThanOrEqualTo(0L)));
156 assertThat("Soft open file limit for process should be -1 or higher", proc.getSoftOpenFileLimit(),
157 is(greaterThanOrEqualTo(-1L)));
158 assertThat("Hard open file limit for process should be -1 or higher", proc.getHardOpenFileLimit(),
159 is(greaterThanOrEqualTo(-1L)));
160 }
161
162 @Test
163 void testThreads() {
164 List<OSThread> threads = proc.getThreadDetails();
165 for (OSThread thread : threads) {
166 assertThat("OS thread shouldn't be null", thread, is(notNullValue()));
167 }
168 }
169
170
171
172
173 @Test
174 void testProcessQueryByList() {
175 SystemInfo si = new SystemInfo();
176 OperatingSystem os = si.getOperatingSystem();
177 assertThat("OS family shouldn't be null", os.getFamily(), is(notNullValue()));
178 assertThat("OS manufacturer shouldn't be null", os.getManufacturer(), is(notNullValue()));
179 OSVersionInfo versionInfo = os.getVersionInfo();
180 assertThat("OS version info shouldn't be null", versionInfo, is(notNullValue()));
181
182 assertThat("OS currently running processes should be 1 or higher", os.getProcessCount(), is(greaterThan(0)));
183 assertThat("OS thread count should be 1 or higher", os.getThreadCount(), is(greaterThan(0)));
184 assertThat("OS current running process id should be 0 or higher", os.getProcessId(),
185 is(greaterThanOrEqualTo(0)));
186
187 List<OSProcess> processes = os.getProcesses(null, null, 0);
188 assertThat("Currently running processes shouldn't be null", processes, is(notNullValue()));
189 assertThat("every OS should have at least one process running on it", processes, is(not(empty())));
190
191 List<Integer> pids = new ArrayList<>();
192 for (OSProcess p : processes) {
193 pids.add(p.getProcessID());
194 }
195
196 Collection<OSProcess> processes1 = os.getProcesses(pids);
197
198
199
200 while (processes1.size() < pids.size()) {
201 pids.clear();
202 for (OSProcess p : processes1) {
203 pids.add(p.getProcessID());
204 }
205
206 processes1 = os.getProcesses(pids);
207 }
208 assertThat("OS processes should match processes with pids we want info on", pids, hasSize(processes1.size()));
209
210 }
211
212
213
214
215 @Test
216 void testGetChildAndDependentProcesses() {
217
218
219
220
221
222
223
224
225
226
227
228
229
230 SystemInfo si = new SystemInfo();
231 OperatingSystem os = si.getOperatingSystem();
232 List<OSProcess> processes = os.getProcesses(null, null, 0);
233 Map<Integer, Long> zeroChildMap = new HashMap<>();
234 Map<Integer, Long> oneChildMap = new HashMap<>();
235 Map<Integer, Long> manyChildMap = new HashMap<>();
236
237 for (OSProcess p : processes) {
238 zeroChildMap.put(p.getProcessID(), p.getStartTime());
239 }
240
241 for (OSProcess p : processes) {
242 int ppid = p.getParentProcessID();
243 long startTime = p.getStartTime();
244 if (zeroChildMap.containsKey(ppid) && zeroChildMap.get(ppid) >= startTime) {
245
246 oneChildMap.put(ppid, zeroChildMap.get(ppid));
247 zeroChildMap.remove(ppid);
248 } else if (oneChildMap.containsKey(ppid) && oneChildMap.get(ppid) >= startTime) {
249
250 manyChildMap.put(ppid, oneChildMap.get(ppid));
251 oneChildMap.remove(ppid);
252 }
253 }
254
255
256 int matchedChild = 0;
257 int matchedDescendant = 0;
258 int descendantNotLessThanChild = 0;
259 if (zeroChildMap.size() > 9) {
260 int total = 0;
261 for (Integer i : zeroChildMap.keySet()) {
262 List<OSProcess> children = os.getChildProcesses(i, null, null, 0);
263 List<OSProcess> descendants = os.getDescendantProcesses(i, null, null, 0);
264 if (children.size() == 0) {
265 matchedChild++;
266 }
267 if (descendants.size() == 0) {
268 matchedDescendant++;
269 }
270
271 if (++total > 9) {
272 break;
273 }
274 }
275 assertThat("Most processes with no children should not suddenly have them.", matchedChild,
276 is(greaterThan(total / 3)));
277 assertThat("Most processes with no children should not suddenly have descendants.", matchedDescendant,
278 is(greaterThan(total / 3)));
279 }
280
281 matchedChild = 0;
282 matchedDescendant = 0;
283 descendantNotLessThanChild = 0;
284 if (oneChildMap.size() > 9) {
285 int total = 0;
286 for (Integer i : oneChildMap.keySet()) {
287 List<OSProcess> children = os.getChildProcesses(i, null, null, 0);
288 List<OSProcess> descendants = os.getDescendantProcesses(i, null, null, 0);
289 if (children.size() == 1) {
290 matchedChild++;
291 }
292 if (descendants.size() >= 1) {
293 matchedDescendant++;
294 }
295 if (descendants.size() >= children.size()) {
296 descendantNotLessThanChild++;
297 }
298
299 if (++total > 9) {
300 break;
301 }
302 }
303 assertThat("Most processes with one child should not suddenly have zero or more than one.", matchedChild,
304 is(greaterThan(total / 3)));
305 assertThat("Most processes with one child should not suddenly have zero descendants.", matchedDescendant,
306 is(greaterThan(total / 3)));
307 assertThat("Most processes with one child should have no more children than descendants",
308 descendantNotLessThanChild, is(greaterThan(total / 3)));
309 }
310
311 matchedChild = 0;
312 matchedDescendant = 0;
313 descendantNotLessThanChild = 0;
314 if (manyChildMap.size() > 9) {
315 int total = 0;
316 for (Integer i : manyChildMap.keySet()) {
317
318 List<OSProcess> children = os.getChildProcesses(i, ProcessFiltering.VALID_PROCESS,
319 ProcessSorting.CPU_DESC, Integer.MAX_VALUE);
320 List<OSProcess> descendants = os.getDescendantProcesses(i, ProcessFiltering.VALID_PROCESS,
321 ProcessSorting.CPU_DESC, Integer.MAX_VALUE);
322 if (children.size() > 0) {
323 matchedChild++;
324 }
325 if (descendants.size() > 0) {
326 matchedDescendant++;
327 }
328 if (descendants.size() >= children.size()) {
329 descendantNotLessThanChild++;
330 }
331
332 if (++total > 9) {
333 break;
334 }
335 }
336 assertThat("Most processes with more than one child should not suddenly have none.", matchedChild,
337 is(greaterThan(total / 3)));
338 assertThat("Most processes with more than one child should not suddenly have no descendants.",
339 matchedDescendant, is(greaterThan(total / 3)));
340 assertThat("Most processes with more than one child should have no more children than descendants",
341 descendantNotLessThanChild, is(greaterThan(total / 3)));
342 }
343 }
344
345 @Test
346 void testGetCommandLine() {
347 int processesWithNonEmptyCmdLine = 0;
348
349 SystemInfo si = new SystemInfo();
350 OperatingSystem os = si.getOperatingSystem();
351 for (OSProcess process : os.getProcesses(null, null, 0)) {
352 if (!process.getCommandLine().trim().isEmpty()) {
353 processesWithNonEmptyCmdLine++;
354 }
355 }
356
357 assertThat("Processes with non-empty command line should be 1 or higher", processesWithNonEmptyCmdLine,
358 is(greaterThan(0)));
359 }
360
361 @Test
362 void testGetArguments() {
363 SystemInfo si = new SystemInfo();
364 OperatingSystem os = si.getOperatingSystem();
365 List<OSProcess> processesWithNonEmptyArguments = os.getProcesses(p -> !p.getArguments().isEmpty(), null, 0);
366
367 assertThat("Processes with non-empty arguments should be non-empty", processesWithNonEmptyArguments,
368 not(empty()));
369 }
370
371 @Test
372 void testGetEnvironment() {
373 int processesWithNonEmptyEnvironment = 0;
374
375 SystemInfo si = new SystemInfo();
376 OperatingSystem os = si.getOperatingSystem();
377 for (OSProcess process : os.getProcesses(null, null, 0)) {
378 if (!process.getEnvironmentVariables().isEmpty()) {
379 processesWithNonEmptyEnvironment++;
380 }
381 }
382
383 assertThat("Processes with non-empty environment should be 1 or higher", processesWithNonEmptyEnvironment,
384 is(greaterThan(0)));
385 }
386
387
388
389
390 @Test
391 void testGetServices() {
392 SystemInfo si = new SystemInfo();
393 OperatingSystem os = si.getOperatingSystem();
394 List<OSService> services = os.getServices();
395
396 if (!services.isEmpty()) {
397 int stopped = 0;
398 int running = 0;
399 for (OSService svc : services) {
400 assertThat(svc.getName(), is(not(emptyString())));
401 switch (svc.getState()) {
402 case STOPPED:
403 stopped++;
404 break;
405 case RUNNING:
406 running++;
407 break;
408 default:
409 break;
410 }
411 }
412
413 assertThat("There should be at least 1 stopped service", stopped, is(greaterThan(0)));
414 assertThat("There should be at least 1 running service", running, is(greaterThan(0)));
415 }
416 }
417
418
419
420
421 @Test
422 void testGetSessions() {
423 SystemInfo si = new SystemInfo();
424 OperatingSystem os = si.getOperatingSystem();
425 for (OSSession sess : os.getSessions()) {
426 assertThat("Logged in user's name for the session shouldn't be empty", sess.getUserName(),
427 is(not(emptyString())));
428 assertThat("Sessions' terminal device name shouldn't be empty", sess.getTerminalDevice(),
429 is(not(emptyString())));
430
431 assertThat(
432 String.format(Locale.ROOT, "Logon time should be before now: %d < %d%n%s", sess.getLoginTime(),
433 System.currentTimeMillis(), sess),
434 sess.getLoginTime(), is(lessThanOrEqualTo(System.currentTimeMillis())));
435 assertThat("Session host shouldn't be null", sess.getHost(), is(notNullValue()));
436 }
437 }
438
439
440
441
442 @Test
443 void testGetDesktopWindows() {
444 SystemInfo si = new SystemInfo();
445 OperatingSystem os = si.getOperatingSystem();
446 List<OSDesktopWindow> allWindows = os.getDesktopWindows(false);
447 List<OSDesktopWindow> visibleWindows = os.getDesktopWindows(true);
448 assertThat("Visible should be a subset of all windows", visibleWindows.size(),
449 is(lessThanOrEqualTo(allWindows.size())));
450 Set<Long> windowIds = new HashSet<>();
451 for (OSDesktopWindow dw : visibleWindows) {
452 assertThat("Visible window should be visible", dw.isVisible(), is(true));
453 assertThat("Height should be nononegative", dw.getLocAndSize().height, is(greaterThanOrEqualTo(0)));
454 assertThat("Width should be nononegative", dw.getLocAndSize().width, is(greaterThanOrEqualTo(0)));
455 windowIds.add(dw.getWindowId());
456 }
457 assertThat("Window IDs should be unique", windowIds.size(), is(visibleWindows.size()));
458 }
459 }