예제 #1
0
  @Test
  public void testProcessTree() throws Exception {

    try {
      if (!ProcfsBasedProcessTree.isAvailable()) {
        System.out.println("ProcfsBasedProcessTree is not available on this system. Not testing");
        return;
      }
    } catch (Exception e) {
      LOG.info(StringUtils.stringifyException(e));
      return;
    }
    // create shell script
    Random rm = new Random();
    File tempFile =
        new File(TEST_ROOT_DIR, getClass().getName() + "_shellScript_" + rm.nextInt() + ".sh");
    tempFile.deleteOnExit();
    shellScript = TEST_ROOT_DIR + File.separator + tempFile.getName();

    // create pid file
    tempFile = new File(TEST_ROOT_DIR, getClass().getName() + "_pidFile_" + rm.nextInt() + ".pid");
    tempFile.deleteOnExit();
    pidFile = TEST_ROOT_DIR + File.separator + tempFile.getName();

    lowestDescendant = TEST_ROOT_DIR + File.separator + "lowestDescendantPidFile";

    // write to shell-script
    try {
      FileWriter fWriter = new FileWriter(shellScript);
      fWriter.write(
          "# rogue task\n"
              + "sleep 1\n"
              + "echo hello\n"
              + "if [ $1 -ne 0 ]\n"
              + "then\n"
              + " sh "
              + shellScript
              + " $(($1-1))\n"
              + "else\n"
              + " echo $$ > "
              + lowestDescendant
              + "\n"
              + " while true\n do\n"
              + "  sleep 5\n"
              + " done\n"
              + "fi");
      fWriter.close();
    } catch (IOException ioe) {
      LOG.info("Error: " + ioe);
      return;
    }

    Thread t = new RogueTaskThread();
    t.start();
    String pid = getRogueTaskPID();
    LOG.info("Root process pid: " + pid);
    ProcfsBasedProcessTree p = createProcessTree(pid);
    p.getProcessTree(); // initialize
    LOG.info("ProcessTree: " + p.toString());

    File leaf = new File(lowestDescendant);
    // wait till lowest descendant process of Rougue Task starts execution
    while (!leaf.exists()) {
      try {
        Thread.sleep(500);
      } catch (InterruptedException ie) {
        break;
      }
    }

    p.getProcessTree(); // reconstruct
    LOG.info("ProcessTree: " + p.toString());

    // Get the process-tree dump
    String processTreeDump = p.getProcessTreeDump();

    // destroy the process and all its subprocesses
    destroyProcessTree(pid);

    if (isSetsidAvailable()) { // whole processtree should be gone
      Assert.assertFalse("Proceesses in process group live", isAnyProcessInTreeAlive(p));
    } else { // process should be gone
      Assert.assertFalse("ProcessTree must have been gone", isAlive(pid));
    }

    LOG.info("Process-tree dump follows: \n" + processTreeDump);
    Assert.assertTrue(
        "Process-tree dump doesn't start with a proper header",
        processTreeDump.startsWith(
            "\t|- PID PPID PGRPID SESSID CMD_NAME "
                + "USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) "
                + "RSSMEM_USAGE(PAGES) FULL_CMD_LINE\n"));
    for (int i = N; i >= 0; i--) {
      String cmdLineDump =
          "\\|- [0-9]+ [0-9]+ [0-9]+ [0-9]+ \\(sh\\)"
              + " [0-9]+ [0-9]+ [0-9]+ [0-9]+ sh "
              + shellScript
              + " "
              + i;
      Pattern pat = Pattern.compile(cmdLineDump);
      Matcher mat = pat.matcher(processTreeDump);
      Assert.assertTrue(
          "Process-tree dump doesn't contain the cmdLineDump of " + i + "th process!", mat.find());
    }

    // Not able to join thread sometimes when forking with large N.
    try {
      t.join(2000);
      LOG.info("RogueTaskThread successfully joined.");
    } catch (InterruptedException ie) {
      LOG.info("Interrupted while joining RogueTaskThread.");
    }

    // ProcessTree is gone now. Any further calls should be sane.
    p.getProcessTree();
    Assert.assertFalse("ProcessTree must have been gone", isAlive(pid));
    Assert.assertTrue(
        "Cumulative vmem for the gone-process is "
            + p.getCumulativeVmem()
            + " . It should be zero.",
        p.getCumulativeVmem() == 0);
    Assert.assertTrue(p.toString().equals("[ ]"));
  }
예제 #2
0
  /**
   * Test the correctness of process-tree dump.
   *
   * @throws IOException
   */
  @Test
  public void testProcessTreeDump() throws IOException {

    String[] pids = {"100", "200", "300", "400", "500", "600"};

    File procfsRootDir = new File(TEST_ROOT_DIR, "proc");

    try {
      setupProcfsRootDir(procfsRootDir);
      setupPidDirs(procfsRootDir, pids);

      int numProcesses = pids.length;
      // Processes 200, 300, 400 and 500 are descendants of 100. 600 is not.
      ProcessStatInfo[] procInfos = new ProcessStatInfo[numProcesses];
      procInfos[0] =
          new ProcessStatInfo(
              new String[] {"100", "proc1", "1", "100", "100", "100000", "100", "1000", "200"});
      procInfos[1] =
          new ProcessStatInfo(
              new String[] {"200", "proc2", "100", "100", "100", "200000", "200", "2000", "400"});
      procInfos[2] =
          new ProcessStatInfo(
              new String[] {"300", "proc3", "200", "100", "100", "300000", "300", "3000", "600"});
      procInfos[3] =
          new ProcessStatInfo(
              new String[] {"400", "proc4", "200", "100", "100", "400000", "400", "4000", "800"});
      procInfos[4] =
          new ProcessStatInfo(
              new String[] {"500", "proc5", "400", "100", "100", "400000", "400", "4000", "800"});
      procInfos[5] =
          new ProcessStatInfo(
              new String[] {"600", "proc6", "1", "1", "1", "400000", "400", "4000", "800"});

      String[] cmdLines = new String[numProcesses];
      cmdLines[0] = "proc1 arg1 arg2";
      cmdLines[1] = "proc2 arg3 arg4";
      cmdLines[2] = "proc3 arg5 arg6";
      cmdLines[3] = "proc4 arg7 arg8";
      cmdLines[4] = "proc5 arg9 arg10";
      cmdLines[5] = "proc6 arg11 arg12";

      writeStatFiles(procfsRootDir, pids, procInfos);
      writeCmdLineFiles(procfsRootDir, pids, cmdLines);

      ProcfsBasedProcessTree processTree =
          createProcessTree("100", procfsRootDir.getAbsolutePath());
      // build the process tree.
      processTree.getProcessTree();

      // Get the process-tree dump
      String processTreeDump = processTree.getProcessTreeDump();

      LOG.info("Process-tree dump follows: \n" + processTreeDump);
      Assert.assertTrue(
          "Process-tree dump doesn't start with a proper header",
          processTreeDump.startsWith(
              "\t|- PID PPID PGRPID SESSID CMD_NAME "
                  + "USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) "
                  + "RSSMEM_USAGE(PAGES) FULL_CMD_LINE\n"));
      for (int i = 0; i < 5; i++) {
        ProcessStatInfo p = procInfos[i];
        Assert.assertTrue(
            "Process-tree dump doesn't contain the cmdLineDump of process " + p.pid,
            processTreeDump.contains(
                "\t|- "
                    + p.pid
                    + " "
                    + p.ppid
                    + " "
                    + p.pgrpId
                    + " "
                    + p.session
                    + " ("
                    + p.name
                    + ") "
                    + p.utime
                    + " "
                    + p.stime
                    + " "
                    + p.vmem
                    + " "
                    + p.rssmemPage
                    + " "
                    + cmdLines[i]));
      }

      // 600 should not be in the dump
      ProcessStatInfo p = procInfos[5];
      Assert.assertFalse(
          "Process-tree dump shouldn't contain the cmdLineDump of process " + p.pid,
          processTreeDump.contains(
              "\t|- "
                  + p.pid
                  + " "
                  + p.ppid
                  + " "
                  + p.pgrpId
                  + " "
                  + p.session
                  + " ("
                  + p.name
                  + ") "
                  + p.utime
                  + " "
                  + p.stime
                  + " "
                  + p.vmem
                  + " "
                  + cmdLines[5]));
    } finally {
      FileUtil.fullyDelete(procfsRootDir);
    }
  }