public static boolean isAnyPosixProcessPidDirAlive(Collection<Long> pids, String user) throws IOException {
        return isAnyPosixProcessPidDirAlive(pids, user, false);
    }
@Test
    public void testIsAnyProcessPosixProcessPidDirAlive() throws IOException {
        final String testName = "testIsAnyProcessPosixProcessPidDirAlive";
        List<String> errors = new ArrayList<>();
        int maxPidCnt = 5;
        if (ServerUtils.IS_ON_WINDOWS) {
            LOG.info("{}: test cannot be run on Windows. Marked as successful", testName);
            return;
        }
        final Path parentDir = Paths.get("/proc");
        if (!parentDir.toFile().exists()) {
            LOG.info("{}: test cannot be run on system without process directory {}, os.name={}",
                    testName, parentDir, System.getProperty("os.name"));
            // check if we can get process id on this Posix system - testing test code, useful on Mac
            String cmd = "/bin/sleep 10";
            if (getPidOfPosixProcess(Runtime.getRuntime().exec(cmd), errors) < 0) {
                fail(String.format("%s: Cannot obtain process id for executed command \"%s\"\n%s",
                        testName, cmd, String.join("\n\t", errors)));
            }
            return;
        }
        // Create processes and wait for their termination
        Set<Long> observables = new HashSet<>();

        for (int i = 0 ; i < maxPidCnt ; i++) {
            String cmd = "sleep 20000";
            Process process = Runtime.getRuntime().exec(cmd);
            long pid = getPidOfPosixProcess(process, errors);
            LOG.info("{}: ({}) ran process \"{}\" with pid={}", testName, i, cmd, pid);
            if (pid < 0) {
                String e = String.format("%s: (%d) Cannot obtain process id for executed command \"%s\"", testName, i, cmd);
                errors.add(e);
                LOG.error(e);
                continue;
            }
            observables.add(pid);
        }
        String userName = System.getProperty("user.name");
        // now kill processes one by one
        List<Long> pidList = new ArrayList<>(observables);
        final long processKillIntervalMs = 2000;
        for (int i = 0; i < pidList.size(); i++) {
            long pid = pidList.get(i);
            LOG.info("{}: ({}) Sleeping for {} milliseconds before kill", testName, i, processKillIntervalMs);
            if (sleepInterrupted(processKillIntervalMs)) {
                return;
            }
            Runtime.getRuntime().exec("kill -9 " + pid);
            LOG.info("{}: ({}) Sleeping for {} milliseconds after kill", testName, i, processKillIntervalMs);
            if (sleepInterrupted(processKillIntervalMs)) {
                return;
            }
            boolean pidDirsAvailable = ServerUtils.isAnyPosixProcessPidDirAlive(observables, userName);
            if (i < pidList.size() - 1) {
                if (pidDirsAvailable) {
                    LOG.info("{}: ({}) Found existing process directories before killing last process", testName, i);
                } else {
                    String e = String.format("%s: (%d) Found no existing process directories before killing last process", testName, i);
                    errors.add(e);
                    LOG.error(e);
                }
            } else {
                if (pidDirsAvailable) {
                    String e = String.format("%s: (%d) Found existing process directories after killing last process", testName, i);
                    errors.add(e);
                    LOG.error(e);
                } else {
                    LOG.info("{}: ({}) Found no existing process directories after killing last process", testName, i);
                }
            }
        }
        if (!errors.isEmpty()) {
            fail(String.format("There are %d failures in test:\n\t%s", errors.size(), String.join("\n\t", errors)));
        }
    }