Mercurial > hg > release > icedtea-web-1.6
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