From 9d7c8ecffac384edba24d6a0a006fc9961261d03 Mon Sep 17 00:00:00 2001 From: Darshit Shah
Date: Thu, 24 Jul 2014 16:25:44 +0530 Subject: [PATCH 1/8] Introducing Python based Test Environment Squashed Commit, of the following commits: 7743384 Update documentation to reflect changes in code b703633 Add feature that allows to ensure that Wget correctly crawls the website in recursive mode 0758f47 Add new test for recursive spider mode 43bb61b Smartly guess content type header d4d0e63 Support substring replace in File Contents too f578500 Compatibility fix with multiple servers 8b1a9b6 Extend Functionality to support spawning multiple servers e84192a Use the provided calls to shutdown server instead of rewriting it 99659f3 Improve Documentation cb94e52 Slight code cleanup. Remove unused code 886ac1a Shift to new Threading Model from Multiprocessing model e74c2ec Add new test for POST Requests 48644f1 Print diff when file contents don't match b6f9efe Add tests for Cookie support 4c9e6b4 Document pending work e13bc90 Add new test to ensure Content Disposition and Auth work together 60d1f4d Add new Test for Continue command 738b299 Add test, Test-Head 9b9d16b Edit non-unique TEST_NAME variable ae958db Minor optimizations to the way Server Rules are executed 50b4f0c The rules need not be a defaultdict. dccc154 Introducing Python based Test Environment --- ChangeLog | 5 + Makefile.am | 2 +- configure.ac | 2 +- testenv/ChangeLog | 222 +++++++++++++ testenv/ColourTerm.py | 23 ++ testenv/FTPServer.py | 162 ++++++++++ testenv/HTTPServer.py | 430 ++++++++++++++++++++++++++ testenv/Makefile.am | 53 ++++ testenv/README | 262 ++++++++++++++++ testenv/Test--spider-r.py | 105 +++++++ testenv/Test-Content-disposition-2.py | 52 ++++ testenv/Test-Content-disposition.py | 55 ++++ testenv/Test-Head.py | 43 +++ testenv/Test-O.py | 44 +++ testenv/Test-Parallel-Proto.py | 52 ++++ testenv/Test-Post.py | 47 +++ testenv/Test-Proto.py | 70 +++++ testenv/Test-auth-basic-fail.py | 50 +++ testenv/Test-auth-basic.py | 58 ++++ testenv/Test-auth-both.py | 76 +++++ testenv/Test-auth-digest.py | 49 +++ testenv/Test-auth-no-challenge-url.py | 53 ++++ testenv/Test-auth-no-challenge.py | 53 ++++ testenv/Test-auth-retcode.py | 49 +++ testenv/Test-auth-with-content-disposition.py | 53 ++++ testenv/Test-c-full.py | 52 ++++ testenv/Test-cookie-401.py | 58 ++++ testenv/Test-cookie-domain-mismatch.py | 56 ++++ testenv/Test-cookie-expires.py | 79 +++++ testenv/Test-cookie.py | 56 ++++ testenv/WgetTest.py | 302 ++++++++++++++++++ 31 files changed, 2671 insertions(+), 2 deletions(-) create mode 100644 testenv/ChangeLog create mode 100644 testenv/ColourTerm.py create mode 100644 testenv/FTPServer.py create mode 100644 testenv/HTTPServer.py create mode 100644 testenv/Makefile.am create mode 100644 testenv/README create mode 100755 testenv/Test--spider-r.py create mode 100755 testenv/Test-Content-disposition-2.py create mode 100755 testenv/Test-Content-disposition.py create mode 100755 testenv/Test-Head.py create mode 100755 testenv/Test-O.py create mode 100755 testenv/Test-Parallel-Proto.py create mode 100755 testenv/Test-Post.py create mode 100755 testenv/Test-Proto.py create mode 100755 testenv/Test-auth-basic-fail.py create mode 100755 testenv/Test-auth-basic.py create mode 100755 testenv/Test-auth-both.py create mode 100755 testenv/Test-auth-digest.py create mode 100755 testenv/Test-auth-no-challenge-url.py create mode 100755 testenv/Test-auth-no-challenge.py create mode 100755 testenv/Test-auth-retcode.py create mode 100755 testenv/Test-auth-with-content-disposition.py create mode 100755 testenv/Test-c-full.py create mode 100755 testenv/Test-cookie-401.py create mode 100755 testenv/Test-cookie-domain-mismatch.py create mode 100755 testenv/Test-cookie-expires.py create mode 100755 testenv/Test-cookie.py create mode 100644 testenv/WgetTest.py diff --git a/ChangeLog b/ChangeLog index c7d7aef..54df848 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-08-31 Darshit Shah + + * configure.ac: Add testenv/Makefile to AC_CONFIG_FILES. + * Makefile.am: Add testenv to SUBDIRS + 2014-07-22 Darshit Shah * configure.ac: Fix broken code for detecting libpsl diff --git a/Makefile.am b/Makefile.am index c9869b7..fe7a4cb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,7 +41,7 @@ distuninstallcheck_listfiles = find . -type f | \ ACLOCAL_AMFLAGS = -I m4 # subdirectories in the distribution -SUBDIRS = lib src doc po tests util +SUBDIRS = lib src doc po tests util testenv EXTRA_DIST = ChangeLog.README MAILING-LIST \ msdos/ChangeLog msdos/config.h msdos/Makefile.DJ \ diff --git a/configure.ac b/configure.ac index 9cd0d5f..273fc64 100644 --- a/configure.ac +++ b/configure.ac @@ -579,7 +579,7 @@ dnl Create output dnl AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile util/Makefile po/Makefile.in tests/Makefile tests/WgetTest.pm - lib/Makefile]) + lib/Makefile testenv/Makefile]) AC_CONFIG_HEADERS([src/config.h]) AC_OUTPUT diff --git a/testenv/ChangeLog b/testenv/ChangeLog new file mode 100644 index 0000000..f4e116d --- /dev/null +++ b/testenv/ChangeLog @@ -0,0 +1,222 @@ +2013-09-16 Darshit Shah + + * README: Update documentation + +2013-09-14 Darshit Shah + + * HTTPServer.py (StoppableHTTPServer): Define object variable + request_headers which stores a list of requests received by the server + (StoppableHTTPServer.get_req_headers): Return the list of Request + Headers stored by the server + (_Handler.do_HEAD): Send the Request MEthod string for identification + (_Handler.do_GET): Same + (_Handler.__log_request): Log the request in Request_Headers list + (_Handler.send_head): Make a call to __log_request + * Test--spider-r.py: Add new list, Request_List, which contains all + the requests that Wget is expected to send. This will allow for + fine-grained tests on recursive downloading. + * WgetTest.py (CommonMethods.FilesCrawled): New Post-Test Hook, that + ensures that all the expected Files on the server were accessed as + expected. + (HTTPTest.stop_HTTP_server): On stopping server, asks it to respond + with list of all requests it received. + +2013-09-13 Darshit Shah + + * Test--spider-r.py: Test retrieval in recursive spider mode. + * Makefile.am: add new file + +2013-09-13 Darshit Shah + + * HTTPServer.py (_Handler.do_HEAD): If requested path is /, respond + with /index.html + (_Handler.do_HEAD): Smartly guess value of Content-Type Header from + file extension + (_Handler.guess_type): Use a preset list of extensions and + Content-Type strings. If the extension matches one in the list, use + that string, else default to "text/plain" + +2013-09-13 Darshit Shah + + * WgetTest.py (CommonMethods._replace_substring): New method that will + replace a substring delimited by {{ }} characters by the value of + self.+ Some text and a link to a second page. + Also, a broken link. +
+ + +""" + + +secondpage = """ + + ++ Some text and a link to a third page. + Also, a broken link. +
+ + +""" + +thirdpage = """ + + ++ Some text and a link to a text file. + Also, another broken link. +
+ + +""" + +dummyfile = "Don't care." + + +index_html = WgetFile ("index.html", mainpage) +secondpage_html = WgetFile ("secondpage.html", secondpage) +thirdpage_html = WgetFile ("thirdpage.html", thirdpage) +dummy_txt = WgetFile ("dummy.txt", dummyfile) + +Request_List = [ + [ + "HEAD /", + "GET /", + "GET /robots.txt", + "HEAD /secondpage.html", + "GET /secondpage.html", + "HEAD /nonexistent", + "HEAD /thirdpage.html", + "GET /thirdpage.html", + "HEAD /dummy.txt", + "HEAD /againnonexistent" + ] +] + +WGET_OPTIONS = "-d --spider -r" +WGET_URLS = [[""]] + +Files = [[index_html, secondpage_html, thirdpage_html, dummy_txt]] + +ExpectedReturnCode = 8 +ExpectedDownloadedFiles = [] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode, + "FilesCrawled" : Request_List +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-Content-disposition-2.py b/testenv/Test-Content-disposition-2.py new file mode 100755 index 0000000..c2512e1 --- /dev/null +++ b/testenv/Test-Content-disposition-2.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget parses the Content-Disposition header + correctly and creates the appropriate file when the said filename exists. +""" +TEST_NAME = "Content Disposition Clobber" +############# File Definitions ############################################### +File1 = "Teapot" +File2 = "The Teapot Protocol" + +File2_rules = { + "SendHeader" : { + "Content-Disposition" : "Attachment; filename=HTTP.Teapot" + } +} +A_File = WgetFile ("HTTP.Teapot", File1) +B_File = WgetFile ("File2", File2, rules=File2_rules) + +WGET_OPTIONS = "-d --content-disposition" +WGET_URLS = [["File2"]] + +Files = [[B_File]] +Existing_Files = [A_File] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [WgetFile ("HTTP.Teapot.1", File2), A_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files, + "LocalFiles" : Existing_Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-Content-disposition.py b/testenv/Test-Content-disposition.py new file mode 100755 index 0000000..0a81dea --- /dev/null +++ b/testenv/Test-Content-disposition.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget parses the Content-Disposition header + correctly and creates a local file accordingly. +""" +TEST_NAME = "Content Disposition Header" +############# File Definitions ############################################### +File1 = """All that is gold does not glitter, + Not all those who wander are lost; + The old that is strong does not wither, + Deep roots are not reached by the frost. + From the ashes a fire shall be woken, + A light from the shadows shall spring; + Renewed shall be blade that was broken, + The crownless again shall be king.""" + +File1_rules = { + "SendHeader" : { + "Content-Disposition" : "Attachment; filename=JRR.Tolkein" + } +} +A_File = WgetFile ("LOTR", File1, rules=File1_rules) + +WGET_OPTIONS = "-d --content-disposition" +WGET_URLS = [["LOTR"]] + +Files = [[A_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [WgetFile ("JRR.Tolkein", File1)] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-Head.py b/testenv/Test-Head.py new file mode 100755 index 0000000..49aaa41 --- /dev/null +++ b/testenv/Test-Head.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget correctly handles responses to HEAD requests + and does not actually download any data +""" +TEST_NAME = "HEAD Requests" +############# File Definitions ############################################### +File1 = "You shall not pass!" + +A_File = WgetFile ("File1", File1) + +WGET_OPTIONS = "-d --method=HEAD" +WGET_URLS = [["File1"]] + +Files = [[A_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files, +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-O.py b/testenv/Test-O.py new file mode 100755 index 0000000..613fbcd --- /dev/null +++ b/testenv/Test-O.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget correctly handles the -O command for output + filenames. +""" +TEST_NAME = "Output Filename Command" +############# File Definitions ############################################### +File1 = "Test Contents." + +A_File = WgetFile ("File1", File1) + +WGET_OPTIONS = "-d -O NewFile.txt" +WGET_URLS = [["File1"]] + +Files = [[A_File]] +ExistingFiles = [A_File] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [WgetFile ("NewFile.txt", File1)] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-Parallel-Proto.py b/testenv/Test-Parallel-Proto.py new file mode 100755 index 0000000..56efd93 --- /dev/null +++ b/testenv/Test-Parallel-Proto.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This is a Prototype Test File for multiple servers. + Ideally this File should be copied and edited to write new tests. +""" +TEST_NAME = "Parallel Prototype" +############# File Definitions ############################################### +File1 = "Would you like some Tea?" +File2 = "With lemon or cream?" +File3 = "Sure you're joking Mr. Feynman" + +A_File = WgetFile ("File1", File1) +B_File = WgetFile ("File2", File2) +C_File = WgetFile ("File3", File3) + +WGET_OPTIONS = "-d" +WGET_URLS = [["File1"], ["File2"]] + +Files = [[A_File], [B_File]] +Existing_Files = [C_File] + +no_of_servers = 2 + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File, B_File, C_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files, + "LocalFiles" : Existing_Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test, + servers=no_of_servers +).begin () + +exit (err) diff --git a/testenv/Test-Post.py b/testenv/Test-Post.py new file mode 100755 index 0000000..632326f --- /dev/null +++ b/testenv/Test-Post.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + Simple test for HTTP POST Requests usiong the --method command +""" +TEST_NAME = "HTTP POST Requests" +############# File Definitions ############################################### +File1 = """A reader lives a thousand lives before he dies, said Jojen. +The man who never reads lives only one""" + +File1_response = """A reader lives a thousand lives before he dies, said Jojen. +The man who never reads lives only one +TestMessage""" + +A_File = WgetFile ("File1", File1) + +WGET_OPTIONS = "-d --method=post --body-data=TestMessage" +WGET_URLS = [["File1"]] + +Files = [[A_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [WgetFile ("File1", File1_response)] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-Proto.py b/testenv/Test-Proto.py new file mode 100755 index 0000000..03523e5 --- /dev/null +++ b/testenv/Test-Proto.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This is a Prototype Test File. + Ideally this File should be copied and edited to write new tests. +""" +TEST_NAME = "Prototype" +############# File Definitions ############################################### +File1 = "Would you like some Tea?" +File2 = "With lemon or cream?" +File3 = "Sure you're joking Mr. Feynman" + +File1_rules = { + "Authentication" : { + "Type" : "Both", + "User" : "Sauron", + "Pass" : "TheEye" + }, + "RejectHeader" : { + "Authorization" : "Basic U2F1cm9uOlRoZUV5ZQ==" + } +} +File2_rules = { + "Authentication" : { + "Type" : "Both_inline", + "User" : "Sauron", + "Pass" : "TheEye" + }, + "SendHeader" : { + "Content-Disposition" : "Attachment; filename=newfile" + } +} + +A_File = WgetFile ("File1", File1, rules=File1_rules) +B_File = WgetFile ("File2", File2, rules=File2_rules) +C_File = WgetFile ("File3", File3) + +WGET_OPTIONS = "-d --content-disposition --user=Sauron --password=TheEye" +WGET_URLS = [["File1", "File2"]] + +Files = [[A_File, B_File]] +Existing_Files = [C_File] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File, WgetFile ("newfile", File2), C_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files, + "LocalFiles" : Existing_Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-auth-basic-fail.py b/testenv/Test-auth-basic-fail.py new file mode 100755 index 0000000..894e96d --- /dev/null +++ b/testenv/Test-auth-basic-fail.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget returns the correct exit code when Basic + authentcation failes due to a username/password error. +""" +TEST_NAME = "Basic Authentication Failure" +############# File Definitions ############################################### +File1 = "I am an invisble man." + +File1_rules = { + "Authentication" : { + "Type" : "Basic", + "User" : "Sauron", + "Pass" : "TheEye" + } +} +A_File = WgetFile ("File1", File1, rules=File1_rules) + +WGET_OPTIONS = "-d --user=Sauron --password=Eye" +WGET_URLS = [["File1"]] + +Files = [[A_File]] + +ExpectedReturnCode = 6 +ExpectedDownloadedFiles = [] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-auth-basic.py b/testenv/Test-auth-basic.py new file mode 100755 index 0000000..96141e0 --- /dev/null +++ b/testenv/Test-auth-basic.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures Wget's Basic Authorization Negotiation. + Also, we ensure that Wget saves the host after a successfull auth and + doesn't wait for a challenge the second time. +""" +TEST_NAME = "Basic Authorization" +############# File Definitions ############################################### +File1 = "I am an invisble man." +File2 = "I too am an invisible man." + +File1_rules = { + "Authentication" : { + "Type" : "Basic", + "User" : "Sauron", + "Pass" : "TheEye" + } +} +File2_rules = { + "ExpectHeader" : { + "Authorization" : "Basic U2F1cm9uOlRoZUV5ZQ==" + } +} +A_File = WgetFile ("File1", File1, rules=File1_rules) +B_File = WgetFile ("File2", File2, rules=File2_rules) + +WGET_OPTIONS = "-d --user=Sauron --password=TheEye" +WGET_URLS = [["File1", "File2"]] + +Files = [[A_File, B_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File, B_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-auth-both.py b/testenv/Test-auth-both.py new file mode 100755 index 0000000..9837134 --- /dev/null +++ b/testenv/Test-auth-both.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures Wget's Basic Authorization Negotiation. + Also, we ensure that Wget saves the host after a successfull auth and + doesn't wait for a challenge the second time. +""" +TEST_NAME = "Multiple authentication support" +############# File Definitions ############################################### +File1 = "Would you like some Tea?" +File2 = "With lemon or cream?" +File3 = "Sure you're joking Mr. Feynman" + +File1_rules = { + "Authentication" : { + "Type" : "Both", + "User" : "Sauron", + "Pass" : "TheEye" + }, + "RejectHeader" : { + "Authorization" : "Basic U2F1cm9uOlRoZUV5ZQ==" + } +} +File2_rules = { + "Authentication" : { + "Type" : "Both_inline", + "User" : "Sauron", + "Pass" : "TheEye" + }, + "RejectHeader" : { + "Authorization" : "Basic U2F1cm9uOlRoZUV5ZQ==" + } +} +File3_rules = { + "Authentication" : { + "Type" : "Digest", + "User" : "Sauron", + "Pass" : "TheEye" + } +} + +A_File = WgetFile ("File1", File1, rules=File1_rules) +B_File = WgetFile ("File2", File2, rules=File2_rules) +C_File = WgetFile ("File3", File3, rules=File3_rules) + +WGET_OPTIONS = "-d --user=Sauron --password=TheEye" +WGET_URLS = [["File1", "File2", "File3"]] + +Files = [[A_File, B_File, C_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File, B_File, C_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-auth-digest.py b/testenv/Test-auth-digest.py new file mode 100755 index 0000000..a66b2c9 --- /dev/null +++ b/testenv/Test-auth-digest.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures Wget's Digest Authorization Negotiation. +""" +TEST_NAME = "Digest Authorization" +############# File Definitions ############################################### +File1 = "Need a cookie?" + +File1_rules = { + "Authentication" : { + "Type" : "Digest", + "User" : "Pacman", + "Pass" : "Omnomnom" + } +} +A_File = WgetFile ("File1", File1, rules=File1_rules) + +WGET_OPTIONS = "-d --user=Pacman --password=Omnomnom" +WGET_URLS = [["File1"]] + +Files = [[A_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-auth-no-challenge-url.py b/testenv/Test-auth-no-challenge-url.py new file mode 100755 index 0000000..eb88ac5 --- /dev/null +++ b/testenv/Test-auth-no-challenge-url.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures Wget's Basic Authorization Negotiation, when credentials + are provided in-URL +""" +TEST_NAME = "Auth no challenge in URL" +############# File Definitions ############################################### +File1 = "Need a cookie?" + +File1_rules = { + "Authentication" : { + "Type" : "Basic", + "User" : "Pacman", + "Pass" : "Omnomnom" + }, + "ExpectHeader" : { + "Authorization" : "Basic UGFjbWFuOk9tbm9tbm9t" + } +} +A_File = WgetFile ("File1", File1, rules=File1_rules) + +WGET_OPTIONS = "-d --auth-no-challenge http://Pacman:address@hidden:{{port}}/File1" +WGET_URLS = [[]] + +Files = [[A_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-auth-no-challenge.py b/testenv/Test-auth-no-challenge.py new file mode 100755 index 0000000..774bd59 --- /dev/null +++ b/testenv/Test-auth-no-challenge.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures Wget's Basic Authorization Negotiation, when the + --auth-no-challenge command is used. +""" +TEST_NAME = "Auth No Challenge Command" +############# File Definitions ############################################### +File1 = "Need a cookie?" + +File1_rules = { + "Authentication" : { + "Type" : "Basic", + "User" : "Pacman", + "Pass" : "Omnomnom" + }, + "ExpectHeader" : { + "Authorization" : "Basic UGFjbWFuOk9tbm9tbm9t" + } +} +A_File = WgetFile ("File1", File1, rules=File1_rules) + +WGET_OPTIONS = "-d --auth-no-challenge --user=Pacman --password=Omnomnom" +WGET_URLS = [["File1"]] + +Files = [[A_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-auth-retcode.py b/testenv/Test-auth-retcode.py new file mode 100755 index 0000000..adbcbb0 --- /dev/null +++ b/testenv/Test-auth-retcode.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget returns the correct return code when sent + a 403 Forbidden by the Server. +""" + +TEST_NAME = "Forbidden Retcode" + +############# File Definitions ############################################### +File1 = "Apples and Oranges? Really?" + +File1_rules = { + "Response" : 403 +} + +A_File = WgetFile ("File1", File1, rules=File1_rules) + +WGET_OPTIONS = "-d" +WGET_URLS = [["File1"]] + +Files = [[A_File]] + +ExpectedReturnCode = 8 +ExpectedDownloadedFiles = [] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-auth-with-content-disposition.py b/testenv/Test-auth-with-content-disposition.py new file mode 100755 index 0000000..50e08ba --- /dev/null +++ b/testenv/Test-auth-with-content-disposition.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget handles Content-Disposition correctly when + coupled with Authentication +""" +TEST_NAME = "Authentication with Content Disposition" +############# File Definitions ############################################### +File1 = "Need a cookie?" + +File1_rules = { + "Authentication" : { + "Type" : "Basic", + "User" : "Pacman", + "Pass" : "Omnomnom" + }, + "SendHeader" : { + "Content-Disposition" : "Attachment; filename=Arch" + } +} +A_File = WgetFile ("File1", File1, rules=File1_rules) + +WGET_OPTIONS = "-d --user=Pacman --password=Omnomnom --content-disposition" +WGET_URLS = [["File1"]] + +Files = [[A_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [WgetFile ("Arch", File1)] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-c-full.py b/testenv/Test-c-full.py new file mode 100755 index 0000000..87ffc52 --- /dev/null +++ b/testenv/Test-c-full.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + Test Wget's response when the file requested already exists on disk with + a filesize greater than or equal to the requested file. +""" +TEST_NAME = "Test continue option" +############# File Definitions ############################################### +File1 = "abababababababababababababababababababababababababababababababababab" +File2 = "ababababababababababababababababababab" + +A_File = WgetFile ("File1", File1) +B_File = WgetFile ("File1", File1) + +C_File = WgetFile ("File2", File1) +D_File = WgetFile ("File2", File2) + +E_File = WgetFile ("File3", File1) + +WGET_OPTIONS = "-d -c" +WGET_URLS = [["File1", "File2", "File3"]] + +Files = [[A_File, C_File, E_File]] +Existing_Files = [B_File, D_File] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File, C_File, E_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files, + "LocalFiles" : Existing_Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-cookie-401.py b/testenv/Test-cookie-401.py new file mode 100755 index 0000000..9ca9641 --- /dev/null +++ b/testenv/Test-cookie-401.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget stores the cookie even in the event of a + 401 Unauthorized Response +""" +TEST_NAME = "Basic Cookie 401 Response" +############# File Definitions ############################################### +File1 = """All happy families are alike; +Each unhappy family is unhappy in its own way""" +File2 = "Anyone for chocochip cookies?" + +File1_rules = { + "SendHeader" : { + "Set-Cookie" : "sess-id=0213; path=/" + }, + "Response" : 401 +} +File2_rules = { + "ExpectHeader" : { + "Cookie" : "sess-id=0213" + }, +} + +A_File = WgetFile ("File1", File1, rules=File1_rules) +B_File = WgetFile ("File2", File2, rules=File2_rules) + +WGET_OPTIONS = "-d" +WGET_URLS = [["File1", "File2"]] + +Files = [[A_File, B_File]] + +ExpectedReturnCode = 6 +ExpectedDownloadedFiles = [B_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-cookie-domain-mismatch.py b/testenv/Test-cookie-domain-mismatch.py new file mode 100755 index 0000000..ae108d9 --- /dev/null +++ b/testenv/Test-cookie-domain-mismatch.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget identifies bad servers trying to set cookies + for a different domain and rejects them. +""" +TEST_NAME = "Cookie Domain Mismatch" +############# File Definitions ############################################### +File1 = "Would you care for a cup of coffee?" +File2 = "Anyone for chocochip cookies?" + +File1_rules = { + "SendHeader" : { + "Set-Cookie" : "sess-id=0213; path=/; domain=.example.com" + } +} +File2_rules = { + "RejectHeader" : { + "Cookie" : "sess-id=0213" + } +} + +A_File = WgetFile ("File1", File1, rules=File1_rules) +B_File = WgetFile ("File2", File2, rules=File2_rules) + +WGET_OPTIONS = "-d" +WGET_URLS = [["File1", "File2"]] + +Files = [[A_File, B_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File, B_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-cookie-expires.py b/testenv/Test-cookie-expires.py new file mode 100755 index 0000000..2ae3bf9 --- /dev/null +++ b/testenv/Test-cookie-expires.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget handles Cookie expiry dates correctly. + Simultaneuously, we also check if multiple cookies to the same domain + are handled correctly +""" +TEST_NAME = "Cookie Expires" +############# File Definitions ############################################### +File1 = "Hello World!" +File2 = "'Ello! This is Amazing!" +File3 = "So what are we looking at?" +File4 = "This was downloaded" + +File1_rules = { + "SendHeader" : { + "Set-Cookie" : "sess-id=0213; path=/" + } +} +File2_rules = { + "ExpectHeader" : { + "Cookie" : "sess-id=0213" + }, + "SendHeader" : { + "Set-Cookie" : "new-sess=N" + } +} +File3_rules = { + "SendHeader" : { + "Set-Cookie" : "sess-id=0213; path=/; Expires=Sun, 06 Nov 2001 12:32:43 GMT" + }, + "ExpectHeader" : { + "Cookie" : "new-sess=N; sess-id=0213" + } +} +File4_rules = { + "RejectHeader" : { + "Cookie" : "sess-id=0213" + }, + "ExpectHeader" : { + "Cookie" : "new-sess=N" + } +} +A_File = WgetFile ("File1", File1, rules=File1_rules) +B_File = WgetFile ("File2", File2, rules=File2_rules) +C_File = WgetFile ("File3", File3, rules=File3_rules) +D_File = WgetFile ("File4", File4, rules=File4_rules) + +WGET_OPTIONS = "-d" +WGET_URLS = [["File1", "File2", "File3", "File4"]] + +Files = [[A_File, B_File, C_File, D_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File, B_File, C_File, D_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/Test-cookie.py b/testenv/Test-cookie.py new file mode 100755 index 0000000..7f5b093 --- /dev/null +++ b/testenv/Test-cookie.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +from sys import exit +from WgetTest import HTTPTest, WgetFile + +""" + This test ensures that Wget's cookie jar support works correctly. +""" +TEST_NAME = "Basic Cookie Functionality" +############# File Definitions ############################################### +File1 = """All happy families are alike; +Each unhappy family is unhappy in its own way""" +File2 = "Anyone for chocochip cookies?" + +File1_rules = { + "SendHeader" : { + "Set-Cookie" : "sess-id=0213; path=/" + } +} +File2_rules = { + "ExpectHeader" : { + "Cookie" : "sess-id=0213" + } +} + +A_File = WgetFile ("File1", File1, rules=File1_rules) +B_File = WgetFile ("File2", File2, rules=File2_rules) + +WGET_OPTIONS = "-d" +WGET_URLS = [["File1", "File2"]] + +Files = [[A_File, B_File]] + +ExpectedReturnCode = 0 +ExpectedDownloadedFiles = [A_File, B_File] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +err = HTTPTest ( + name=TEST_NAME, + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test +).begin () + +exit (err) diff --git a/testenv/WgetTest.py b/testenv/WgetTest.py new file mode 100644 index 0000000..9e5d2fe --- /dev/null +++ b/testenv/WgetTest.py @@ -0,0 +1,302 @@ +import os +import shutil +import shlex +import sys +import traceback +import HTTPServer +import re +from subprocess import call +from ColourTerm import printer +from difflib import unified_diff + +""" A Custom Exception raised by the Test Environment. """ + +class TestFailed (Exception): + + def __init__ (self, error): + self.error = error + + +""" Class that defines methods common to both HTTP and FTP Tests. """ + +class CommonMethods: + TestFailed = TestFailed + + def init_test_env (self, name): + testDir = name + "-test" + try: + os.mkdir (testDir) + except FileExistsError: + shutil.rmtree (testDir) + os.mkdir (testDir) + os.chdir (testDir) + self.tests_passed = True + + def get_domain_addr (self, addr): + self.port = str (addr[1]) + return addr[0] + ":" + str(addr[1]) + "/" + + def exec_wget (self, options, urls, domain_list): + cmd_line = self.get_cmd_line (options, urls, domain_list) + params = shlex.split (cmd_line) + print (params) + retcode = call (params) + return retcode + + def get_cmd_line (self, options, urls, domain_list): + TEST_PATH = os.path.abspath (".") + WGET_PATH = os.path.join (TEST_PATH, "..", "..", "src", "wget") + WGET_PATH = os.path.abspath (WGET_PATH) + cmd_line = WGET_PATH + " " + options + " " + for i in range (0, self.servers): + for url in urls[i]: + cmd_line += domain_list[i] + url + " " +# for url in urls: +# cmd_line += domain_list[0] + url + " " + print (cmd_line) + return cmd_line + + def __test_cleanup (self): + testDir = self.name + "-test" + os.chdir ('..') + try: + if os.getenv ("NO_CLEANUP") is None: + shutil.rmtree (testDir) + except Exception as ae: + print ("Unknown Exception while trying to remove Test Environment.") + + def _exit_test (self): + self.__test_cleanup () + + def begin (self): + return 0 if self.tests_passed else 100 + + """ Methods to check if the Test Case passes or not. """ + + def __gen_local_filesys (self): + file_sys = dict () + for parent, dirs, files in os.walk ('.'): + for name in files: + onefile = dict () + # Create the full path to file, removing the leading ./ + # Might not work on non-unix systems. Someone please test. + filepath = os.path.join (parent, name) + file_handle = open (filepath, 'r') + file_content = file_handle.read () + onefile['content'] = file_content + filepath = filepath[2:] + file_sys[filepath] = onefile + file_handle.close () + return file_sys + + + def __check_downloaded_files (self, exp_filesys): + local_filesys = self.__gen_local_filesys () + for files in exp_filesys: + if files.name in local_filesys: + local_file = local_filesys.pop (files.name) + if files.content != local_file ['content']: + for line in unified_diff (local_file['content'], files.content, fromfile="Actual", tofile="Expected"): + sys.stderr.write (line) + raise TestFailed ("Contents of " + files.name + " do not match") + else: + raise TestFailed ("Expected file " + files.name + " not found") + if local_filesys: + print (local_filesys) + raise TestFailed ("Extra files downloaded.") + + def _replace_substring (self, string): + pattern = re.compile ('\{\{\w+\}\}') + match_obj = pattern.search (string) + if match_obj is not None: + rep = match_obj.group() + temp = getattr (self, rep.strip ('{}')) + string = string.replace (rep, temp) + return string + + + """ Test Rule Definitions """ + """ This should really be taken out soon. All this extra stuff to ensure + re-use of old code is crap. Someone needs to re-write it. The new rework + branch is much better written, but integrating it requires effort. + All these classes should never exist. The whole server needs to modified. + """ + + class Authentication: + def __init__ (self, auth_obj): + self.auth_type = auth_obj['Type'] + self.auth_user = auth_obj['User'] + self.auth_pass = auth_obj['Pass'] + + class ExpectHeader: + def __init__ (self, header_obj): + self.headers = header_obj + + class RejectHeader: + def __init__ (self, header_obj): + self.headers = header_obj + + class Response: + def __init__ (self, retcode): + self.response_code = retcode + + class SendHeader: + def __init__ (self, header_obj): + self.headers = header_obj + + def get_server_rules (self, file_obj): + """ The handling of expect header could be made much better when the + options are parsed in a true and better fashion. For an example, + see the commented portion in Test-basic-auth.py. + """ + server_rules = dict () + for rule in file_obj.rules: + r_obj = getattr (self, rule) (file_obj.rules[rule]) + server_rules[rule] = r_obj + return server_rules + + """ Pre-Test Hook Function Calls """ + + def ServerFiles (self, server_files): + for i in range (0, self.servers): + file_list = dict () + server_rules = dict () + for file_obj in server_files[i]: + content = self._replace_substring (file_obj.content) + file_list[file_obj.name] = content + rule_obj = self.get_server_rules (file_obj) + server_rules[file_obj.name] = rule_obj + self.server_list[i].server_conf (file_list, server_rules) + + def LocalFiles (self, local_files): + for file_obj in local_files: + file_handler = open (file_obj.name, "w") + file_handler.write (file_obj.content) + file_handler.close () + + """ Test Option Function Calls """ + + def WgetCommands (self, command_list): + self.options = self._replace_substring (command_list) + + def Urls (self, url_list): + self.urls = url_list + + """ Post-Test Hook Function Calls """ + + def ExpectedRetcode (self, retcode): + if self.act_retcode != retcode: + pr = "Return codes do not match.\nExpected: " + str(retcode) + "\nActual: " + str(self.act_retcode) + raise TestFailed (pr) + + def ExpectedFiles (self, exp_filesys): + self.__check_downloaded_files (exp_filesys) + + def FilesCrawled (self, Request_Headers): + for i in range (0, self.servers): + headers = set(Request_Headers[i]) + o_headers = self.Request_remaining[i] + header_diff = headers.symmetric_difference (o_headers) + if len(header_diff) is not 0: + printer ("RED", str (header_diff)) + raise TestFailed ("Not all files were crawled correctly") + + +""" Class for HTTP Tests. """ + +class HTTPTest (CommonMethods): + +# Temp Notes: It is expected that when pre-hook functions are executed, only an empty test-dir exists. +# pre-hook functions are executed just prior to the call to Wget is made. +# post-hook functions will be executed immediately after the call to Wget returns. + + def __init__ ( + self, + name="Unnamed Test", + pre_hook=dict(), + test_params=dict(), + post_hook=dict(), + servers=1 + ): + try: + self.HTTP_setup (name, pre_hook, test_params, post_hook, servers) + except TestFailed as tf: + printer ("RED", "Error: " + tf.error) + self.tests_passed = False + except Exception as ae: + printer ("RED", "Unhandled Exception Caught.") + print ( ae.__str__ ()) + traceback.print_exc () + self.tests_passed = False + else: + printer ("GREEN", "Test Passed") + finally: + self._exit_test () + def HTTP_setup (self, name, pre_hook, test_params, post_hook, servers): + self.name = name + self.servers = servers + printer ("BLUE", "Running Test " + self.name) + self.init_test_env (name) + self.server_list = list() + self.domain_list = list() + for server_number in range (0, servers): + server_inst = self.init_HTTP_Server () + self.server_list.append (server_inst) + domain = self.get_domain_addr (server_inst.server_address) + self.domain_list.append (domain) + #self.server = self.init_HTTP_Server () + #self.domain = self.get_domain_addr (self.server.server_address) + + for pre_hook_func in pre_hook: + try: + assert hasattr (self, pre_hook_func) + except AssertionError as ae: + self.stop_HTTP_Server (self.server) + raise TestFailed ("Pre Test Function " + pre_hook_func + " not defined.") + getattr (self, pre_hook_func) (pre_hook[pre_hook_func]) + + for test_func in test_params: + try: + assert hasattr (self, test_func) + except AssertionError as ae: + self.stop_HTTP_Server (self.server) + raise TestFailed ("Test Option " + test_func + " unknown.") + getattr (self, test_func) (test_params[test_func]) + + self.act_retcode = self.exec_wget (self.options, self.urls, self.domain_list) + self.stop_HTTP_Server () + + for post_hook_func in post_hook: + try: + assert hasattr (self, post_hook_func) + except AssertionError as ae: + raise TestFailed ("Post Test Function " + post_hook_func + " not defined.") + getattr (self, post_hook_func) (post_hook[post_hook_func]) + + def init_HTTP_Server (self): + server = HTTPServer.HTTPd () + server.start () + return server + + def stop_HTTP_Server (self): + self.Request_remaining = list () + for server in self.server_list: + server_req = server.server_inst.get_req_headers () + self.Request_remaining.append (server_req) + server.server_inst.shutdown () + +""" WgetFile is a File Data Container object """ + +class WgetFile: + + def __init__ ( + self, + name, + content="Test Contents", + timestamp=None, + rules=dict() + ): + self.name = name + self.content = content + self.timestamp = timestamp + self.rules = rules -- 2.0.2