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.booter;
20  
21  import javax.annotation.Nonnull;
22  
23  /**
24   * Immutable object which encapsulates PID and elapsed time (Unix) or start time (Windows).
25   * <br>
26   * Methods
27   * ({@link #getPID()}, {@link #getTime()}, {@link #isTimeBefore(ProcessInfo)}, {@link #isTimeEqualTo(ProcessInfo)})
28   * throw {@link IllegalStateException}
29   * if {@link #canUse()} returns {@code false} or {@link #isError()} returns {@code true}.
30   *
31   * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
32   * @since 2.20.1
33   */
34  final class ProcessInfo {
35      static final ProcessInfo INVALID_PROCESS_INFO = new ProcessInfo(null, 0);
36      static final ProcessInfo ERR_PROCESS_INFO = new ProcessInfo(null, 0);
37  
38      /**
39       * On Unix we do not get PID due to the command is interested only to etime of PPID:
40       * <br>
41       * <pre>/bin/ps -o etime= -p 123</pre>
42       */
43      static @Nonnull ProcessInfo unixProcessInfo(String pid, long etime) {
44          return new ProcessInfo(pid, etime);
45      }
46  
47      static @Nonnull ProcessInfo windowsProcessInfo(String pid, long startTimestamp) {
48          return new ProcessInfo(pid, startTimestamp);
49      }
50  
51      /**
52       * Creates process info from ProcessHandle API data.
53       *
54       * @param pid the process ID
55       * @param startTimeMillis the process start time in epoch milliseconds
56       * @return a new ProcessInfo instance
57       */
58      static @Nonnull ProcessInfo processHandleInfo(String pid, long startTimeMillis) {
59          return new ProcessInfo(pid, startTimeMillis);
60      }
61  
62      private final String pid;
63      private final long time;
64  
65      private ProcessInfo(String pid, long time) {
66          this.pid = pid;
67          this.time = time;
68      }
69  
70      boolean canUse() {
71          return !isError();
72      }
73  
74      boolean isInvalid() {
75          return this == INVALID_PROCESS_INFO;
76      }
77  
78      boolean isError() {
79          return this == ERR_PROCESS_INFO;
80      }
81  
82      String getPID() {
83          checkValid();
84          return pid;
85      }
86  
87      long getTime() {
88          checkValid();
89          return time;
90      }
91  
92      boolean isTimeEqualTo(ProcessInfo that) {
93          checkValid();
94          that.checkValid();
95          return time == that.time;
96      }
97  
98      boolean isTimeBefore(ProcessInfo that) {
99          checkValid();
100         that.checkValid();
101         return time < that.time;
102     }
103 
104     private void checkValid() {
105         if (!canUse()) {
106             throw new IllegalStateException("invalid process info");
107         }
108     }
109 }