1 16 17 package org.apache.tester; 18 19 20 import java.io.FileNotFoundException ; 21 import java.io.InputStream ; 22 import java.io.IOException ; 23 import java.io.OutputStream ; 24 import java.io.PrintWriter ; 25 import java.net.ConnectException ; 26 import java.net.HttpURLConnection ; 27 import java.net.Socket ; 28 import java.net.URL ; 29 import java.util.ArrayList ; 30 import java.util.HashMap ; 31 import java.util.Iterator ; 32 import org.apache.tools.ant.BuildException; 33 import org.apache.tools.ant.Task; 34 35 36 84 85 public class TestClient extends Task { 86 87 88 90 91 95 protected ArrayList saveGolden = new ArrayList (); 96 97 98 103 protected HashMap saveHeaders = new HashMap (); 104 105 106 110 protected ArrayList saveResponse = new ArrayList (); 111 112 113 115 116 119 protected int debug = 0; 120 121 public int getDebug() { 122 return (this.debug); 123 } 124 125 public void setDebug(int debug) { 126 this.debug = debug; 127 } 128 129 130 133 protected String golden = null; 134 135 public String getGolden() { 136 return (this.golden); 137 } 138 139 public void setGolden(String golden) { 140 this.golden = golden; 141 } 142 143 144 147 protected String host = "localhost"; 148 149 public String getHost() { 150 return (this.host); 151 } 152 153 public void setHost(String host) { 154 this.host = host; 155 } 156 157 158 162 protected String inContent = null; 163 164 public String getInContent() { 165 return (this.inContent); 166 } 167 168 public void setInContent(String inContent) { 169 this.inContent = inContent; 170 } 171 172 173 177 protected String inHeaders = null; 178 179 public String getInHeaders() { 180 return (this.inHeaders); 181 } 182 183 public void setInHeaders(String inHeaders) { 184 this.inHeaders = inHeaders; 185 } 186 187 188 192 protected boolean joinSession = false; 193 194 public boolean getJoinSession() { 195 return (this.joinSession); 196 } 197 198 public void setJoinSession(boolean joinSession) { 199 this.joinSession = true; 200 } 201 202 203 206 protected String message = null; 207 208 public String getMessage() { 209 return (this.message); 210 } 211 212 public void setMessage(String message) { 213 this.message = message; 214 } 215 216 217 220 protected String method = "GET"; 221 222 public String getMethod() { 223 return (this.method); 224 } 225 226 public void setMethod(String method) { 227 this.method = method; 228 } 229 230 231 234 protected String outContent = null; 235 236 public String getOutContent() { 237 return (this.outContent); 238 } 239 240 public void setOutContent(String outContent) { 241 this.outContent = outContent; 242 } 243 244 245 249 protected String outHeaders = null; 250 251 public String getOutHeaders() { 252 return (this.outHeaders); 253 } 254 255 public void setOutHeaders(String outHeaders) { 256 this.outHeaders = outHeaders; 257 } 258 259 260 263 protected int port = 8080; 264 265 public int getPort() { 266 return (this.port); 267 } 268 269 public void setPort(int port) { 270 this.port = port; 271 } 272 273 274 279 protected String protocol = null; 280 281 public String getProtocol() { 282 return (this.protocol); 283 } 284 285 public void setProtocol(String protocol) { 286 this.protocol = protocol; 287 } 288 289 290 293 protected boolean redirect = false; 294 295 public boolean getRedirect() { 296 return (this.redirect); 297 } 298 299 public void setRedirect(boolean redirect) { 300 this.redirect = redirect; 301 } 302 303 304 307 protected String request = null; 308 309 public String getRequest() { 310 return (this.request); 311 } 312 313 public void setRequest(String request) { 314 this.request = request; 315 } 316 317 318 321 protected int status = 200; 322 323 public int getStatus() { 324 return (this.status); 325 } 326 327 public void setStatus(int status) { 328 this.status = status; 329 } 330 331 332 334 335 340 protected static String sessionId = null; 341 342 343 345 346 351 public void execute() throws BuildException { 352 353 saveHeaders.clear(); 354 try { 355 readGolden(); 356 } catch (IOException e) { 357 log("FAIL: readGolden(" + golden + ")"); 358 e.printStackTrace(System.out); 359 } 360 if ((protocol == null) || (protocol.length() == 0)) 361 executeHttp(); 362 else 363 executeSocket(); 364 365 } 366 367 368 370 371 376 protected void executeHttp() throws BuildException { 377 378 String summary = "[" + method + " " + request + "]"; 380 if (debug >= 1) 381 log("RQST: " + summary); 382 boolean success = true; 383 String result = null; 384 Throwable throwable = null; 385 HttpURLConnection conn = null; 386 387 try { 388 389 URL url = new URL ("http", host, port, request); 391 conn = (HttpURLConnection ) url.openConnection(); 392 conn.setAllowUserInteraction(false); 393 conn.setDoInput(true); 394 if (inContent != null) { 395 conn.setDoOutput(true); 396 conn.setRequestProperty("Content-Length", 397 "" + inContent.length()); 398 if (debug >= 1) 399 log("INPH: Content-Length: " + 400 inContent.length()); 401 } else { 402 conn.setDoOutput(false); 403 } 404 405 if (joinSession && (sessionId != null)) { 407 conn.setRequestProperty("Cookie", 408 "JSESSIONID=" + sessionId); 409 if (debug >= 1) 410 log("INPH: Cookie: JSESSIONID=" + 411 sessionId); 412 } 413 414 if (this.redirect && (debug >= 1)) 415 log("FLAG: setInstanceFollowRedirects(" + 416 this.redirect + ")"); 417 conn.setInstanceFollowRedirects(this.redirect); 418 conn.setRequestMethod(method); 419 if (inHeaders != null) { 420 String headers = inHeaders; 421 while (headers.length() > 0) { 422 int delimiter = headers.indexOf("##"); 423 String header = null; 424 if (delimiter < 0) { 425 header = headers; 426 headers = ""; 427 } else { 428 header = headers.substring(0, delimiter); 429 headers = headers.substring(delimiter + 2); 430 } 431 int colon = header.indexOf(":"); 432 if (colon < 0) 433 break; 434 String name = header.substring(0, colon).trim(); 435 String value = header.substring(colon + 1).trim(); 436 conn.setRequestProperty(name, value); 437 if (debug >= 1) 438 log("INPH: " + name + ": " + value); 439 } 440 } 441 442 conn.connect(); 444 if (inContent != null) { 445 if (debug >= 1) 446 log("INPD: " + inContent); 447 OutputStream os = conn.getOutputStream(); 448 for (int i = 0; i < inContent.length(); i++) 449 os.write(inContent.charAt(i)); 450 os.close(); 451 } 452 453 String outData = ""; 455 String outText = ""; 456 boolean eol = false; 457 InputStream is = conn.getInputStream(); 458 int lines = 0; 459 while (true) { 460 String line = read(is); 461 if (line == null) 462 break; 463 if (lines == 0) 464 outData = line; 465 else 466 outText += line + "\r\n"; 467 saveResponse.add(line); 468 lines++; 469 } 470 is.close(); 471 472 if (debug >= 1) 474 log("RESP: " + conn.getResponseCode() + " " + 475 conn.getResponseMessage()); 476 for (int i = 1; i < 1000; i++) { 477 String name = conn.getHeaderFieldKey(i); 478 String value = conn.getHeaderField(i); 479 if ((name == null) || (value == null)) 480 break; 481 if (debug >= 1) 482 log("HEAD: " + name + ": " + value); 483 save(name, value); 484 if ("Set-Cookie".equals(name)) 485 parseSession(value); 486 } 487 if (debug >= 1) { 488 log("DATA: " + outData); 489 if (outText.length() > 2) 490 log("TEXT: " + outText); 491 } 492 493 if (success) { 495 result = validateStatus(conn.getResponseCode()); 496 if (result != null) 497 success = false; 498 } 499 if (success) { 500 result = validateMessage(conn.getResponseMessage()); 501 if (result != null) 502 success = false; 503 } 504 if (success) { 505 result = validateHeaders(); 506 if (result != null) 507 success = false; 508 } 509 if (success) { 510 result = validateData(outData); 511 if (result != null) 512 success = false; 513 } 514 if (success) { 515 result = validateGolden(); 516 if (result != null) 517 success = false; 518 } 519 520 } catch (Throwable t) { 521 if (t instanceof FileNotFoundException ) { 522 if (status == 404) { 523 success = true; 524 result = "Not Found"; 525 throwable = null; 526 } else { 527 success = false; 528 try { 529 result = "Status=" + conn.getResponseCode() + 530 ", Message=" + conn.getResponseMessage(); 531 } catch (IOException e) { 532 result = e.toString(); 533 } 534 throwable = null; 535 } 536 } else if (t instanceof ConnectException ) { 537 success = false; 538 result = t.getMessage(); 539 throwable = null; 540 } else { 541 success = false; 542 result = t.getMessage(); 543 throwable = t; 544 } 545 } 546 547 if (success) 549 log("OK " + summary); 550 else { 551 log("FAIL " + summary + " " + result); 552 if (throwable != null) 553 throwable.printStackTrace(System.out); 554 } 555 556 } 557 558 559 564 protected void executeSocket() throws BuildException { 565 566 String command = method + " " + request + " " + protocol; 568 String summary = "[" + command + "]"; 569 if (debug >= 1) 570 log("RQST: " + summary); 571 boolean success = true; 572 String result = null; 573 Socket socket = null; 574 OutputStream os = null; 575 PrintWriter pw = null; 576 InputStream is = null; 577 Throwable throwable = null; 578 int outStatus = 0; 579 String outMessage = null; 580 581 try { 582 583 socket = new Socket (host, port); 585 os = socket.getOutputStream(); 586 pw = new PrintWriter (os); 587 is = socket.getInputStream(); 588 589 pw.print(command + "\r\n"); 591 if (inContent != null) { 592 if (debug >= 1) 593 log("INPH: " + "Content-Length: " + 594 inContent.length()); 595 pw.print("Content-Length: " + inContent.length() + "\r\n"); 596 } 597 598 if (joinSession && (sessionId != null)) { 600 pw.println("Cookie: JSESSIONID=" + sessionId); 601 if (debug >= 1) 602 log("INPH: Cookie: JSESSIONID=" + 603 sessionId); 604 } 605 606 if (inHeaders != null) { 608 String headers = inHeaders; 609 while (headers.length() > 0) { 610 int delimiter = headers.indexOf("##"); 611 String header = null; 612 if (delimiter < 0) { 613 header = headers; 614 headers = ""; 615 } else { 616 header = headers.substring(0, delimiter); 617 headers = headers.substring(delimiter + 2); 618 } 619 int colon = header.indexOf(":"); 620 if (colon < 0) 621 break; 622 String name = header.substring(0, colon).trim(); 623 String value = header.substring(colon + 1).trim(); 624 if (debug >= 1) 625 log("INPH: " + name + ": " + value); 626 pw.print(name + ": " + value + "\r\n"); 627 } 628 } 629 pw.print("\r\n"); 630 631 if (inContent != null) { 633 if (debug >= 1) 634 log("INPD: " + inContent); 635 for (int i = 0; i < inContent.length(); i++) 636 pw.print(inContent.charAt(i)); 637 } 638 pw.flush(); 639 640 String line = read(is); 642 if (line == null) { 643 outStatus = -1; 644 outMessage = "NO RESPONSE"; 645 } else { 646 line = line.trim(); 647 if (debug >= 1) 648 System.out.println("RESP: " + line); 649 int space = line.indexOf(" "); 650 if (space >= 0) { 651 line = line.substring(space + 1).trim(); 652 space = line.indexOf(" "); 653 } 654 try { 655 if (space < 0) { 656 outStatus = Integer.parseInt(line); 657 outMessage = ""; 658 } else { 659 outStatus = Integer.parseInt(line.substring(0, space)); 660 outMessage = line.substring(space + 1).trim(); 661 } 662 } catch (NumberFormatException e) { 663 outStatus = -1; 664 outMessage = "NUMBER FORMAT EXCEPTION"; 665 } 666 } 667 if (debug >= 1) 668 System.out.println("STAT: " + outStatus + " MESG: " + 669 outMessage); 670 671 String headerName = null; 673 String headerValue = null; 674 while (true) { 675 line = read(is); 676 if ((line == null) || (line.length() == 0)) 677 break; 678 int colon = line.indexOf(":"); 679 if (colon < 0) { 680 if (debug >= 1) 681 System.out.println("????: " + line); 682 } else { 683 headerName = line.substring(0, colon).trim(); 684 headerValue = line.substring(colon + 1).trim(); 685 if (debug >= 1) 686 System.out.println("HEAD: " + headerName + ": " + 687 headerValue); 688 save(headerName, headerValue); 689 if ("Set-Cookie".equals(headerName)) 690 parseSession(headerValue); 691 } 692 } 693 694 String outData = ""; 696 String outText = ""; 697 int lines = 0; 698 while (true) { 699 line = read(is); 700 if (line == null) 701 break; 702 if (lines == 0) 703 outData = line; 704 else 705 outText += line + "\r\n"; 706 saveResponse.add(line); 707 lines++; 708 } 709 is.close(); 710 if (debug >= 1) { 711 System.out.println("DATA: " + outData); 712 if (outText.length() > 2) 713 System.out.println("TEXT: " + outText); 714 } 715 716 if (success) { 718 result = validateStatus(outStatus); 719 if (result != null) 720 success = false; 721 } 722 if (success) { 723 result = validateMessage(message); 724 if (result != null) 725 success = false; 726 } 727 if (success) { 728 result = validateHeaders(); 729 if (result != null) 730 success = false; 731 } 732 if (success) { 733 result = validateData(outData); 734 if (result != null) 735 success = false; 736 } 737 if (success) { 738 result = validateGolden(); 739 if (result != null) 740 success = false; 741 } 742 743 } catch (Throwable t) { 744 success = false; 745 result = "Status=" + outStatus + 746 ", Message=" + outMessage; 747 throwable = null; 748 } finally { 749 if (pw != null) { 750 try { 751 pw.close(); 752 } catch (Throwable w) { 753 ; 754 } 755 } 756 if (os != null) { 757 try { 758 os.close(); 759 } catch (Throwable w) { 760 ; 761 } 762 } 763 if (is != null) { 764 try { 765 is.close(); 766 } catch (Throwable w) { 767 ; 768 } 769 } 770 if (socket != null) { 771 try { 772 socket.close(); 773 } catch (Throwable w) { 774 ; 775 } 776 } 777 } 778 779 if (success) 780 System.out.println("OK " + summary); 781 else { 782 System.out.println("FAIL " + summary + " " + result); 783 if (throwable != null) 784 throwable.printStackTrace(System.out); 785 } 786 787 } 788 789 790 795 protected void parseSession(String value) { 796 797 if (value == null) 798 return; 799 int equals = value.indexOf("JSESSIONID="); 800 if (equals < 0) 801 return; 802 value = value.substring(equals + "JSESSIONID=".length()); 803 int semi = value.indexOf(";"); 804 if (semi >= 0) 805 value = value.substring(0, semi); 806 807 if (debug >= 1) 808 System.out.println("SESSION ID: " + value); 809 sessionId = value; 810 811 } 812 813 814 823 protected String read(InputStream stream) throws IOException { 824 825 StringBuffer result = new StringBuffer (); 826 while (true) { 827 int b = stream.read(); 828 if (b < 0) { 829 if (result.length() == 0) 830 return (null); 831 else 832 break; 833 } 834 char c = (char) b; 835 if (c == '\r') 836 continue; 837 else if (c == '\n') 838 break; 839 else 840 result.append(c); 841 } 842 return (result.toString()); 843 844 } 845 846 847 853 protected void readGolden() throws IOException { 854 855 saveGolden.clear(); 857 if (golden == null) 858 return; 859 860 URL url = new URL ("http", host, port, golden); 862 HttpURLConnection conn = 863 (HttpURLConnection ) url.openConnection(); 864 conn.setAllowUserInteraction(false); 865 conn.setDoInput(true); 866 conn.setDoOutput(false); 867 conn.setFollowRedirects(true); 868 conn.setRequestMethod("GET"); 869 870 conn.connect(); 872 InputStream is = conn.getInputStream(); 873 while (true) { 874 String line = read(is); 875 if (line == null) 876 break; 877 saveGolden.add(line); 878 } 879 is.close(); 880 conn.disconnect(); 881 882 } 883 884 885 891 protected void save(String name, String value) { 892 893 String key = name.toLowerCase(); 894 ArrayList list = (ArrayList ) saveHeaders.get(key); 895 if (list == null) { 896 list = new ArrayList (); 897 saveHeaders.put(key, list); 898 } 899 list.add(value); 900 901 } 902 903 904 910 protected String validateData(String data) { 911 912 if (outContent == null) 913 return (null); 914 else if (data.startsWith(outContent)) 915 return (null); 916 else 917 return ("Expected data '" + outContent + "', got data '" + 918 data + "'"); 919 920 } 921 922 923 927 protected String validateGolden() { 928 929 if (golden == null) 930 return (null); 931 boolean ok = true; 932 if (saveGolden.size() != saveResponse.size()) 933 ok = false; 934 if (ok) { 935 for (int i = 0; i < saveGolden.size(); i++) { 936 String golden = (String ) saveGolden.get(i); 937 String response = (String ) saveResponse.get(i); 938 if (!golden.equals(response)) { 939 ok = false; 940 break; 941 } 942 } 943 } 944 if (ok) 945 return (null); 946 System.out.println("EXPECTED: ======================================"); 947 for (int i = 0; i < saveGolden.size(); i++) 948 System.out.println((String ) saveGolden.get(i)); 949 System.out.println("================================================"); 950 System.out.println("RECEIVED: ======================================"); 951 for (int i = 0; i < saveResponse.size(); i++) 952 System.out.println((String ) saveResponse.get(i)); 953 System.out.println("================================================"); 954 return ("Failed Golden File Comparison"); 955 956 } 957 958 959 964 protected String validateHeaders() { 965 966 if (outHeaders == null) 968 return (null); 969 970 String headers = outHeaders; 972 while (headers.length() > 0) { 973 int delimiter = headers.indexOf("##"); 975 String header = null; 976 if (delimiter < 0) { 977 header = headers; 978 headers = ""; 979 } else { 980 header = headers.substring(0, delimiter); 981 headers = headers.substring(delimiter + 2); 982 } 983 int colon = header.indexOf(":"); 984 String name = header.substring(0, colon).trim(); 985 String value = header.substring(colon + 1).trim(); 986 ArrayList list = (ArrayList ) saveHeaders.get(name.toLowerCase()); 988 if (list == null) 989 return ("Missing header name '" + name + "'"); 990 boolean found = false; 991 for (int i = 0; i < list.size(); i++) { 992 if (value.equals((String ) list.get(i))) { 993 found = true; 994 break; 995 } 996 } 997 if (!found) 998 return ("Missing header name '" + name + "' with value '" + 999 value + "'"); 1000 } 1001 1002 return (null); 1004 1005 } 1006 1007 1008 1014 protected String validateMessage(String message) { 1015 1016 if (this.message == null) 1017 return (null); 1018 else if (this.message.equals(message)) 1019 return (null); 1020 else 1021 return ("Expected message='" + this.message + "', got message='" + 1022 message + "'"); 1023 1024 } 1025 1026 1027 1033 protected String validateStatus(int status) { 1034 1035 if (this.status == 0) 1036 return (null); 1037 if (this.status == status) 1038 return (null); 1039 else 1040 return ("Expected status=" + this.status + ", got status=" + 1041 status); 1042 1043 } 1044 1045 1046} 1047 | Popular Tags |