changeset 1205:0488d15d3f0e

Kill processes in Integration Tests more cleanly; revised 2015-04-13 Jie Kang <jkang@redhat.com> Kill processes in Integration Tests more cleanly; revised * Makefile.am: remove all instances of softkiller (softkiller no longer works) * tests/test-extensions/net/sourceforge/jnlp/ProcessAssasin.java: use SIGTERM instead of SIGINT, don't destroy process after sending signal * tests/test-extensions/net/sourceforge/jnlp/ServerAccess.java: reduce timeout from 20 seconds to 10 * tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Firefox.java: remove usage of softkiller to close tabs * tests/softkiller/Makefile: * tests/softkiller/softkiller.c: remove softkiller
author Jie Kang <jkang@redhat.com>
date Mon, 13 Apr 2015 10:38:15 -0400
parents a5e268a5b6dd
children 039af1289ac9
files ChangeLog Makefile.am tests/softkiller/Makefile tests/softkiller/softkiller.c tests/test-extensions/net/sourceforge/jnlp/ProcessAssasin.java tests/test-extensions/net/sourceforge/jnlp/ServerAccess.java tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Firefox.java
diffstat 7 files changed, 22 insertions(+), 499 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Apr 13 10:32:57 2015 -0400
+++ b/ChangeLog	Mon Apr 13 10:38:15 2015 -0400
@@ -1,3 +1,17 @@
+2015-04-13  Jie Kang  <jkang@redhat.com>
+	Kill processes in Integration Tests more cleanly; revised
+    * Makefile.am:
+    remove all instances of softkiller (softkiller no longer works)
+	* tests/test-extensions/net/sourceforge/jnlp/ProcessAssasin.java:
+	use SIGTERM instead of SIGINT, don't destroy process after sending signal
+	* tests/test-extensions/net/sourceforge/jnlp/ServerAccess.java:
+	reduce timeout from 20 seconds to 10
+	* tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Firefox.java:
+	remove usage of softkiller to close tabs
+    * tests/softkiller/Makefile:
+    * tests/softkiller/softkiller.c:
+    remove softkiller
+
 2015-04-13  Jie Kang  <jkang@redhat.com>
 	Add reproducers for jnlp_href attribute
 	* tests/reproducers/simple/JnlpHrefAttribute/resources/JnlpHrefAttribute.html:
--- a/Makefile.am	Mon Apr 13 10:32:57 2015 -0400
+++ b/Makefile.am	Mon Apr 13 10:38:15 2015 -0400
@@ -52,7 +52,6 @@
 export TEST_CERT_ALIAS=icedteaweb
 export PUBLIC_KEYSTORE_STUB=icedtea-web/security/trusted.certs
 export PUBLIC_KEYSTORE_PASS=changeit
-export SOFTKILLER=softkiller
 
 export JUNIT_RUNNER_JAR=$(abs_top_builddir)/junit-runner.jar
 export UNIT_CLASS_NAMES = $(abs_top_builddir)/unit_class_names
@@ -980,14 +979,9 @@
 	done ; \
 	echo $$class_names > $(REPRODUCERS_CLASS_NAMES)
 
-$(TESTS_DIR)/$(SOFTKILLER):
-	cd  $(TESTS_SRCDIR)/$(SOFTKILLER); \
-	$(MAKE) ; \
-	mv $(SOFTKILLER) $(TESTS_DIR)/
-
 stamps/run-netx-dist-tests.stamp: stamps/netx-dist.stamp stamps/plugin.stamp launcher.build/$(javaws) \
  javaws.desktop stamps/docs.stamp launcher.build/$(itweb_settings) itweb-settings.desktop launcher.build/$(policyeditor) policyeditor.desktop \
- stamps/netx.stamp stamps/junit-jnlp-dist-dirs stamps/netx-dist-tests-import-cert-to-public $(TESTS_DIR)/softkiller \
+ stamps/netx.stamp stamps/junit-jnlp-dist-dirs stamps/netx-dist-tests-import-cert-to-public \
  stamps/test-extensions-compile.stamp stamps/compile-reproducers-testcases.stamp $(JUNIT_RUNNER_JAR) stamps/copy-reproducers-resources.stamp\
  $(TESTS_DIR)/$(REPORT_STYLES_DIRNAME) $(REPRODUCERS_CLASS_NAMES) stamps/process-custom-reproducers.stamp
 	cd $(TEST_EXTENSIONS_DIR) ; \
@@ -1404,10 +1398,7 @@
 	rm -f $(TESTS_DIR)/summary_unit.txt
 	rm -f $(TESTS_DIR)/summary_reproducers.txt
 
-clean-$(SOFTKILLER):
-	rm -f $(TESTS_DIR)/softkiller
- 
-clean-netx-dist-tests: clean_tests_reports netx-dist-tests-remove-cert-from-public clean-custom-reproducers clean-$(SOFTKILLER)
+clean-netx-dist-tests: clean_tests_reports netx-dist-tests-remove-cert-from-public clean-custom-reproducers
 	rm -f test-extensions-source-files.txt
 	rm -f test-extensions-tests-source-files.txt
 	rm -f $(TEST_EXTENSIONS_COMPATIBILITY_SYMLINK)
@@ -1474,7 +1465,6 @@
 	rm -f jacoco-operator-source-files.txt
 	rm -f stamps/build-fake-plugin.stamp
 
-
 # plugin tests
 
 if ENABLE_PLUGIN
--- a/tests/softkiller/Makefile	Mon Apr 13 10:32:57 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-# we need c99 because of snprintf function!
-# (this function does not exist in C89/ANSI C)
-
-softkiller:	softkiller.c
-	$(CC) -Wall -pedantic -std=c99 -o $@ $< -lX11
-
-clean:
-	rm softkiller
-
--- a/tests/softkiller/softkiller.c	Mon Apr 13 10:32:57 2015 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,443 +0,0 @@
-/* X Window app killer
- *
- * Author: Pavel Tisnovsky <ptisnovs@redhat.com>
- *
- * Compile:
- *     gcc -Wall -pedantic -std=c99 -o softkiller softkiller.c -lX11
- *     (please note that -std=c99 is needed because we use snprintf
- *      function which does not exist in C89/ANSI C)
- *
- * Run:
- *     ./softkiller PID
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <glob.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-
-/*
- * Number of long decimal digits + 1 (for ASCIIZ storage)
- */
-#define MAX_LONG_DECIMAL_DIGITS 21
-
-/*
- * Max line length in /proc/stat files
- */
-#define MAX_LINE 8192
-
-/*
- * Max filename length for /proc/... files
- */
-#define MAX_FILENAME 32
-
-/*
- * Return values
- */
-#define EXIT_CODE_OK 0
-#define EXIT_CODE_ERROR 1
-
-/*
- * Different softkilling strategies
- */
-#define TRY_TO_CLOSE_WINDOW 1
-#define TRY_TO_KILL_WINDOW 1
-
-/*
- * Delay between application of different softkilling strategies.
- */
-#define SLEEP_AMOUNT 2
-
-/*
- * Not in c89/c99...
- */
-#define file_no(FP) ((FP)->_fileno)
-
-/*
- * Basic information about given process
- */
-typedef struct ProcStruct
-{
-    long uid, pid, ppid;
-    char cmd[MAX_LINE];
-} ProcStruct;
-
-ProcStruct *P = NULL;
-
-int N = 0;
-
-Display *display;
-Window root_window;
-Atom atom_pid;
-
-
-
-/*
- * Read basic process info from the file /proc/${PID}/stat
- * where ${PID} is process ID.
- */
-int read_process_info(char *file_name_part, ProcStruct *P)
-{
-    FILE *fin;
-    char filename[MAX_FILENAME];
-    struct stat stat;
-
-    /* try to open file /proc/${PID}/stat for reading */
-    snprintf(filename, sizeof(filename), "%s%s", file_name_part, "/stat");
-    fin = fopen(filename, "r");
-
-    if (fin == NULL)
-    {
-        return 0; /* process vanished since glob() */
-    }
-
-    /* read basic process info */
-    if (3 != fscanf(fin, "%ld %s %*c %ld", &(P->pid), P->cmd, &(P->ppid)))
-    {
-        fclose(fin);
-        return 0; /* Problem with file format, AFAIK should not happen */
-    }
-    if (fstat(file_no(fin), &stat))
-    {
-        fclose(fin);
-        return 0;
-    }
-    P->uid = stat.st_uid;
-
-    /* fin can't be NULL here */
-    fclose(fin);
-    return 1;
-}
-
-
-
-/*
- * Read command line parameters for given ${PID}
- */
-int read_cmd_line(char *file_name_part, char *cmd)
-{
-    FILE *fin;
-    char filename[MAX_FILENAME];
-    int c;
-    int k = 0;
-
-    /* try to open file /proc/${PID}/cmdline for reading */
-    snprintf(filename, sizeof(filename), "%s%s", file_name_part, "/cmdline");
-    fin = fopen(filename, "r");
-
-    if (fin == NULL)
-    {
-        return 0; /* process vanished since glob() */
-    }
-
-    /* replace \0 by spaces */
-    while (k < MAX_LINE - 1 && EOF != (c = fgetc(fin)))
-    {
-        cmd[k++] = c == '\0' ? ' ' : c;
-    }
-    if (k > 0)
-    {
-        cmd[k] = '\0';
-    }
-
-    /* fin can't be NULL here */
-    fclose(fin);
-    return 1;
-}
-
-
-
-/*
- * Fill in an array pointed by P.
- */
-int get_processes(void)
-{
-    glob_t globbuf;
-    unsigned int i, j;
-
-    glob("/proc/[0-9]*", GLOB_NOSORT, NULL, &globbuf);
-
-    P = calloc(globbuf.gl_pathc, sizeof(struct ProcStruct));
-    if (P == NULL)
-    {
-        fprintf(stderr, "Problems with malloc, it should not happen...\n");
-        exit(1);
-    }
-
-    for (i = j = 0; i < globbuf.gl_pathc; i++)
-    {
-        char * name_part = globbuf.gl_pathv[globbuf.gl_pathc - i - 1];
-        if (read_process_info(name_part, &(P[j])) == 0)
-        {
-            continue;
-        }
-        if (read_cmd_line(name_part, P[j].cmd) == 0)
-        {
-            continue;
-        }
-        /* Debug output */
-        /* printf("uid=%5ld, pid=%5ld, ppid=%5ld, cmd='%s'\n", P[j].uid, P[j].pid, P[j].ppid, P[j].cmd); */
-        j++;
-    }
-    globfree(&globbuf);
-    return j;
-}
-
-
-
-/*
- * Try to open X Display
- */
-Display * open_display(void)
-{
-    Display *display = XOpenDisplay(0);
-    if (display == NULL)
-    {
-        puts("Cannot open display");
-        exit(EXIT_CODE_ERROR);
-    }
-    return display;
-}
-
-
-
-/*
- * Return the atom identifier for the atom name "_NET_WM_PID"
- */
-Atom get_atom_pid(Display *display)
-{
-    Atom atom_pid = XInternAtom(display, "_NET_WM_PID", True);
-    if (atom_pid == None)
-    {
-        printf("No such atom _NET_WM_PID");
-        exit(EXIT_CODE_ERROR);
-    }
-    return atom_pid;
-}
-
-
-
-/*
- * Try to focus the window and send Ctrl+W to it.
- */
-void close_window(Window window, long processId)
-{
-    char windowIDstr[MAX_LONG_DECIMAL_DIGITS];
-    pid_t pid;
-
-    snprintf(windowIDstr, MAX_LONG_DECIMAL_DIGITS, "%ld", window);
-    char *args[] =
-    {
-        "/usr/bin/xdotool",
-        "windowfocus",
-        windowIDstr,
-        "windowactivate",
-        windowIDstr,
-        "key",
-        "--window",
-        windowIDstr,
-        "--clearmodifiers",
-        "Ctrl+W",
-        (char *) NULL
-    };
-    if ((pid = fork()) == -1)
-    {
-        perror("some fork error");
-    }
-    else if (pid == 0)
-    {
-        /* child process */
-        printf("Trying to close window ID %ld for process ID %ld\n", (long)window, processId);
-        execv("/usr/bin/xdotool", args);
-    }
-    else
-    {
-        /* parent process */
-        sleep(SLEEP_AMOUNT);
-    }
-}
-
-
-
-/*
- * Run xkill to kill window with specified window ID
- */
-void kill_window(Window window, long processId)
-{
-    char windowIDstr[MAX_LONG_DECIMAL_DIGITS];
-    pid_t pid;
-
-    /* we need to convert window id (long) into a string to call xkill */
-    snprintf(windowIDstr, MAX_LONG_DECIMAL_DIGITS, "%ld", window);
-    char *args[] =
-    {
-        "/usr/bin/xkill",
-        "-id",
-        windowIDstr,
-        (char *) NULL
-    };
-    if ((pid = fork()) == -1)
-    {
-        perror("some fork error");
-    }
-    else if (pid == 0)
-    {
-        printf("Trying to kill window ID %ld for process ID %ld\n", (long)window, processId);
-        execv("/usr/bin/xkill", args);
-    }
-    else
-    {
-        // parent
-        sleep(SLEEP_AMOUNT);
-    }
-}
-
-
-
-/*
- * Recursivelly search for a window(s) associated with given process ID
- */
-void search_and_destroy(Display *display, Window window, Atom atomPID, long processId)
-{
-    Atom           type;
-    int            format;
-    unsigned long  nItems;
-    unsigned long  bytesAfter;
-    unsigned char *propertyPID = NULL;
-
-    /* read _NET_WM_PID property, if exists */
-    if (Success == XGetWindowProperty(display, window, atomPID, 0, 1, False, XA_CARDINAL,
-                                         &type, &format, &nItems, &bytesAfter, &propertyPID))
-    {
-        if (propertyPID != NULL)
-        {
-            if (processId == *((unsigned long *)propertyPID))
-            {
-                printf("Found window ID %ld for process ID %ld\n", (long)window, processId);
-                XFree(propertyPID);
-#if TRY_TO_CLOSE_WINDOW == 1
-                close_window(window, processId);
-#endif
-#if TRY_TO_KILL_WINDOW == 1
-                kill_window(window, processId);
-#endif
-            }
-        }
-    }
-
-    /* recurse into child windows */
-    Window    rootWindow;
-    Window    parentWindow;
-    Window   *childWindows;
-    unsigned  nChildren;
-    if (0 != XQueryTree(display, window, &rootWindow, &parentWindow, &childWindows, &nChildren))
-    {
-        unsigned int i;
-        for(i = 0; i < nChildren; i++)
-        {
-            search_and_destroy(display, childWindows[i], atomPID, processId);
-        }
-    }
-}
-
-
-
-/*
- * Kill process with given ancestor PID.
- */
-void kill_process(int pid)
-{
-    Atom atom_pid = get_atom_pid(display);
-    printf("Searching for windows associated with PID %d\n", pid);
-    search_and_destroy(display, root_window, atom_pid, pid);
-}
-
-
-
-/*
- * Kill all processes with given ppid (ancestor PID)
- */
-void kill_processes_with_ppid(int ppid)
-{
-    int i;
-    int done = 1;
-    for (i = 0; i < N; i++)
-    {
-        if (ppid == P[i].ppid)
-        {
-            int pid = P[i].pid;
-            printf("uid=%5ld, pid=%5ld, ppid=%5ld, cmd='%s'\n", P[i].uid, P[i].pid, P[i].ppid, P[i].cmd);
-            kill_processes_with_ppid(pid);
-            /* at least one child process exists */
-            done = 0;
-            kill_process(pid);
-        }
-    }
-    kill_process(ppid);
-    /* if none child processes have been found we are at bottom of the process tree */
-    if (done)
-    {
-        return;
-    }
-}
-
-
-
-/* TODO: better check for user input */
-int read_pid(int argc, char **argv)
-{
-    int pid;
-
-    if (argc != 2)
-    {
-        puts("Usage softkiller PID");
-        exit(EXIT_CODE_ERROR);
-    }
-
-    pid = atoi(argv[1]);
-
-    if (sscanf(argv[1], "%d", &pid) != 1)
-    {
-        printf("Wrong PID entered: %s\n", argv[1]);
-        exit(EXIT_CODE_ERROR);
-    }
-
-    /* basic check (nobody should try to kill PID 0 :) */
-    if (pid <= 0)
-    {
-        printf("Wrong process ID %d\n", pid);
-        exit(EXIT_CODE_ERROR);
-    }
-
-    return pid;
-}
-
-
-
-/*
- * Entry point to this tool.
- */
-int main(int argc, char **argv)
-{
-    int pid = read_pid(argc, argv);
-
-    printf("ancestor PID to kill: %d\n", pid);
-
-    N = get_processes();
-    printf("N = %d\n", N);
-    display = open_display();
-    root_window = XDefaultRootWindow(display);
-    atom_pid = get_atom_pid(display);
-
-    kill_processes_with_ppid(pid);
-
-    puts("*** Done! ***");
-    return 0;
-}
-
--- a/tests/test-extensions/net/sourceforge/jnlp/ProcessAssasin.java	Mon Apr 13 10:32:57 2015 -0400
+++ b/tests/test-extensions/net/sourceforge/jnlp/ProcessAssasin.java	Mon Apr 13 10:38:15 2015 -0400
@@ -200,17 +200,16 @@
             String pid = (f.get(p)).toString();
             if (reactingProcess != null) {
                 reactingProcess.beforeKill(pid);
-            };
-            sigInt(pid);
-            //sigTerm(pid);
-            //sigKill(pid);
+            }
+//            sigInt(pid);
+            sigTerm(pid);
+//            sigKill(pid);
         } catch (Exception ex) {
             ServerAccess.logException(ex);
         } finally {
-            p.destroy();
             if (reactingProcess != null) {
                 reactingProcess.afterKill("");
-            };
+            }
         }
     }
 
@@ -240,27 +239,4 @@
     void setReactingProcess(ReactingProcess reactingProcess) {
         this.reactingProcess = reactingProcess;
     }
-
-    public static void closeWindow(String pid) throws Exception {
-        List<String> ll = new ArrayList<String>(2);
-        ll.add(ServerAccess.getInstance().getDir().getParent() + "/softkiller");
-        ll.add(pid);
-        ServerAccess.executeProcess(ll); //sync, but  acctually release
-        //before affected application "close"
-        Thread.sleep(100);
-
-    }
-
-    public static void closeWindows(String s) throws Exception {
-        closeWindows(s, 10);
-    }
-    
-    public static void closeWindows(String s, int count) throws Exception {
-        //each close closes just one tab...
-        for (int i = 0; i < count; i++) {
-            ProcessAssasin.closeWindow(s);
-        }
-    }
-
-
 }
--- a/tests/test-extensions/net/sourceforge/jnlp/ServerAccess.java	Mon Apr 13 10:32:57 2015 -0400
+++ b/tests/test-extensions/net/sourceforge/jnlp/ServerAccess.java	Mon Apr 13 10:38:15 2015 -0400
@@ -108,7 +108,7 @@
      * timeout in ms to let process to finish, before assassin will kill it.
      * This can be changed in runtime, but will affect all following tasks
      */
-    public static long PROCESS_TIMEOUT = 20 * 1000;//ms
+    public static long PROCESS_TIMEOUT = 10 * 1000;//ms
     /**
      * this flag is indicating whether output of executeProcess should be logged. By default true.
      */
--- a/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Firefox.java	Mon Apr 13 10:32:57 2015 -0400
+++ b/tests/test-extensions/net/sourceforge/jnlp/browsertesting/browsers/Firefox.java	Mon Apr 13 10:38:15 2015 -0400
@@ -77,11 +77,6 @@
 
     @Override
     public void beforeKill(String s) {
-        try {
-            ProcessAssasin.closeWindows(s);
-        } catch (Exception ex) {
-            throw new RuntimeException(ex);
-        }
     }
 
     @Override