diff --git a/ietf/redirects/tests.py b/ietf/redirects/tests.py index 10a1061b4..38361cb78 100644 --- a/ietf/redirects/tests.py +++ b/ietf/redirects/tests.py @@ -101,98 +101,9 @@ class RedirectsTests(TestCase): location = location[17:] self.assertEqual(location, dst, (src, dst, location)) -def get_patterns(module): - all = [] - try: - patterns = module.urlpatterns - except AttributeError: - patterns = [] - for item in patterns: - try: - subpatterns = get_patterns(item.urlconf_module) - except: - subpatterns = [""] - for sub in subpatterns: - if not sub: - all.append(item.regex.pattern) - elif sub.startswith("^"): - all.append(item.regex.pattern + sub[1:]) - else: - all.append(item.regex.pattern + ".*" + sub) - return all - -class UrlCoverageTestCase(unittest.TestCase): - def testUrlCoverage(self): - print " Testing testurl.list coverage" - testtuples = [] - for root, dirs, files in os.walk(settings.BASE_DIR): - if "testurl.list" in files: - testtuples += read_testurls(root+"/testurl.list") - - patterns = get_patterns(ietf.urls) - covered = [] - for codes, testurl, goodurl in testtuples: - for pattern in patterns: - if re.match(pattern, testurl[1:]): - covered.append(pattern) - - if not set(patterns) == set(covered): - missing = list(set(patterns) - set(covered)) - print "The following URLs are not tested by any testurl.list" - for pattern in missing: - if not pattern[1:].split("/")[0] in [ "admin", "accounts" ]: - print " NoTest", pattern - print "" - else: - print "All URLs are included in some testurl.list" - class MainUrlTests(TestCase): def test_urls(self): self.assertEqual(self.client.get("/_doesnotexist/").status_code, 404) self.assertEqual(self.client.get("/sitemap.xml").status_code, 200) # Google webmaster tool verification page self.assertEqual(self.client.get("/googlea30ad1dacffb5e5b.html").status_code, 200) - - -def get_templates(): - templates = set() - # Shoud we teach this to use TEMPLATE_DIRS? - templatepath = os.path.join(settings.BASE_DIR,"templates") - for root, dirs, files in os.walk(templatepath): - if ".svn" in dirs: - dirs.remove(".svn") - relative_path = root[len(templatepath)+1:] - for file in files: - if file.endswith("~") or file.startswith("#"): - continue - if relative_path == "": - templates.add(file) - else: - templates.add(os.path.join(relative_path, file)) - return templates - -class TemplateCoverageTestCase(unittest.TestCase): - def testTemplateCoverage(self): - if not test_runner.loaded_templates: - print " Skipping template coverage test" - return - - print " Testing template coverage" - all_templates = get_templates() - - #notexist = list(test_runner.loaded_templates - all_templates) - #if notexist: - # notexist.sort() - # print "The following templates do not exist" - # for x in notexist: - # print "NotExist", x - - notloaded = list(all_templates - test_runner.loaded_templates) - if notloaded: - notloaded.sort() - print "The following templates were never loaded during test" - for x in notloaded: - print " NotLoaded", x - else: - print " All templates were loaded during test" - diff --git a/ietf/utils/test_runner.py b/ietf/utils/test_runner.py index b19b454ca..e97d0f2c1 100644 --- a/ietf/utils/test_runner.py +++ b/ietf/utils/test_runner.py @@ -32,7 +32,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import socket +import socket, re, os from django.conf import settings from django.template import TemplateDoesNotExist @@ -44,6 +44,7 @@ import debug import ietf.utils.mail loaded_templates = set() +visited_urls = set() test_database_name = None old_destroy = None old_create = None @@ -74,6 +75,77 @@ def template_coverage_loader(template_name, dirs): template_coverage_loader.is_usable = True +class RecordUrlsMiddleware(object): + def process_request(self, request): + visited_urls.add(request.path) + +def get_patterns(module): + all = [] + try: + patterns = module.urlpatterns + except AttributeError: + patterns = [] + for item in patterns: + try: + subpatterns = get_patterns(item.urlconf_module) + except: + subpatterns = [""] + for sub in subpatterns: + if not sub: + all.append(item.regex.pattern) + elif sub.startswith("^"): + all.append(item.regex.pattern + sub[1:]) + else: + all.append(item.regex.pattern + ".*" + sub) + return all + +def check_url_coverage(): + patterns = get_patterns(ietf.urls) + + IGNORED_PATTERNS = ("admin",) + + patterns = [(p, re.compile(p)) for p in patterns if p[1:].split("/")[0] not in IGNORED_PATTERNS] + + covered = set() + for url in visited_urls: + for pattern, compiled in patterns: + if pattern not in covered and compiled.match(url[1:]): # strip leading / + covered.add(pattern) + break + + missing = list(set(p for p, compiled in patterns) - covered) + + if missing: + print "The following URL patterns were not tested" + for pattern in sorted(missing): + print " Not tested", pattern + +def get_templates(): + templates = set() + # Should we teach this to use TEMPLATE_DIRS? + templatepath = os.path.join(settings.BASE_DIR, "templates") + for root, dirs, files in os.walk(templatepath): + if ".svn" in dirs: + dirs.remove(".svn") + relative_path = root[len(templatepath)+1:] + for file in files: + if file.endswith("~") or file.startswith("#"): + continue + if relative_path == "": + templates.add(file) + else: + templates.add(os.path.join(relative_path, file)) + return templates + +def check_template_coverage(): + all_templates = get_templates() + + not_loaded = list(all_templates - loaded_templates) + if not_loaded: + print "The following templates were never loaded during test" + for t in sorted(not_loaded): + print " Not loaded", t + def run_tests_1(test_labels, *args, **kwargs): global old_destroy, old_create, test_database_name from django.db import connection @@ -81,18 +153,33 @@ def run_tests_1(test_labels, *args, **kwargs): connection.creation.__class__.create_test_db = safe_create_1 old_destroy = connection.creation.__class__.destroy_test_db connection.creation.__class__.destroy_test_db = safe_destroy_0_1 - if not test_labels: + + check_coverage = not test_labels + + if check_coverage: settings.TEMPLATE_LOADERS = ('ietf.utils.test_runner.template_coverage_loader',) + settings.TEMPLATE_LOADERS - test_labels = [x.split(".")[-1] for x in settings.INSTALLED_APPS if x.startswith("ietf")] + ['redirects.TemplateCoverageTestCase',] + settings.MIDDLEWARE_CLASSES = ('ietf.utils.test_runner.RecordUrlsMiddleware',) + settings.MIDDLEWARE_CLASSES + + if not test_labels: + test_labels = [x.split(".")[-1] for x in settings.INSTALLED_APPS if x.startswith("ietf")] + if settings.SITE_ID != 1: print " Changing SITE_ID to '1' during testing." settings.SITE_ID = 1 + if settings.TEMPLATE_STRING_IF_INVALID != '': print " Changing TEMPLATE_STRING_IF_INVALID to '' during testing." settings.TEMPLATE_STRING_IF_INVALID = '' + assert(not settings.IDTRACKER_BASE_URL.endswith('/')) - kwargs["verbosity"] = kwargs["verbosity"] - return django_run_tests(test_labels, *args, **kwargs) + + results = django_run_tests(test_labels, *args, **kwargs) + + if check_coverage: + check_url_coverage() + check_template_coverage() + + return results def run_tests(*args, **kwargs): # Tests that involve switching back and forth between the real