From 62aa9819680cc72d5b5d3d0c085727b19f05c54b Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Fri, 18 May 2012 13:54:50 +0000 Subject: [PATCH] add test suite for Python binding - add unit test suite for Python binding - make Python syntax 2to3 compatible to allow Python3 porting - use @top_builddir@ to reference lib in python/setup.py.in git-svn-id: file:///tmp/cracklib-svn/trunk@191 4175fe1e-86d5-4fdc-8e6a-506fab9d8533 --- cracklib/NEWS | 1 + cracklib/python/cracklib.py | 26 ++++-- cracklib/python/setup.py.in | 4 +- cracklib/python/test_cracklib.py | 134 +++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 9 deletions(-) create mode 100644 cracklib/python/test_cracklib.py diff --git a/cracklib/NEWS b/cracklib/NEWS index b5b2055..6994749 100644 --- a/cracklib/NEWS +++ b/cracklib/NEWS @@ -1,6 +1,7 @@ v2.8.19 drop autogenerated files from SVN (Mike Frysinger) add words from "The Top 500 Worst Passwords of All Time" to dicts/cracklib-small (patch by Fabian Greffrath) include sys/stat.h in python/_cracklibmodule.c (Mike Frysinger) + add test suite for Python binding (Jan Dittberner) v2.8.18 also include stdlib.h in stringlib.c (Mike Frysinger) make sure python lib builds against build dir instead of system installed libs (Arfrever Frehtes Taifersar Arahesis) v2.8.17 fixed compilation on interix systems diff --git a/cracklib/python/cracklib.py b/cracklib/python/cracklib.py index d43aa51..3f9572a 100644 --- a/cracklib/python/cracklib.py +++ b/cracklib/python/cracklib.py @@ -4,7 +4,7 @@ # Parts of this code are based on work Copyright (c) 2003 by Domenico # Andreoli. # -# Copyright (c) 2008, 2009 Jan Dittberner +# Copyright (c) 2008, 2009, 2012 Jan Dittberner # # This file is part of cracklib. # @@ -27,6 +27,8 @@ import string from _cracklib import FascistCheck +__version__ = '2.8.19' + ASCII_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ASCII_LOWERCASE = "abcdefghijklmnopqrstuvwxyz" @@ -190,18 +192,18 @@ def VeryFascistCheck(new, old = None, dictpath = None): """ if old != None: if new == old: - raise ValueError, "is the same as the old one" + raise ValueError("is the same as the old one") oldmono = old.lower() newmono = new.lower() wrapped = old + old if newmono == oldmono: - raise ValueError, "case changes only" + raise ValueError("case changes only") if wrapped.find(new) != -1: - raise ValueError, "is rotated" + raise ValueError("is rotated") if similar(oldmono, newmono): - raise ValueError, "is too similar to the old one" + raise ValueError("is too similar to the old one") if dictpath == None: FascistCheck(new) @@ -209,8 +211,18 @@ def VeryFascistCheck(new, old = None, dictpath = None): FascistCheck(new, dictpath) if palindrome(new): - raise ValueError, "is a palindrome" + raise ValueError("is a palindrome") if simple(new): - raise ValueError, "is too simple" + raise ValueError("is too simple") return new + + +def test(verbosity=1, repeat=1): + """Test cracklib methods.""" + import test_cracklib + import sys + result = test_cracklib.run(verbosity=verbosity, repeat=repeat) + if result.wasSuccessful(): + sys.exit(0) + sys.exit(1) diff --git a/cracklib/python/setup.py.in b/cracklib/python/setup.py.in index ae5a9f2..a68f3b9 100644 --- a/cracklib/python/setup.py.in +++ b/cracklib/python/setup.py.in @@ -24,9 +24,9 @@ from setuptools import setup, Extension, find_packages extensions = [ Extension("_cracklibmodule", ["_cracklibmodule.c"], - include_dirs = ["../lib"], + include_dirs = ["@top_builddir@/lib"], libraries = ["crack"], - library_dirs = ["../lib/.libs"]), + library_dirs = ["@top_builddir@/lib/.libs"]), ] setup( diff --git a/cracklib/python/test_cracklib.py b/cracklib/python/test_cracklib.py new file mode 100644 index 0000000..980b9b4 --- /dev/null +++ b/cracklib/python/test_cracklib.py @@ -0,0 +1,134 @@ +# -*- python -*- +# -*- coding: utf-8 -*- +""" +Test suite for cracklib's Python binding. +""" +import os +import sys +import unittest +import cracklib + +__version__ = '2.8.19' + +tests = [] + + +class TestModuleFunctions(unittest.TestCase): + def test_VeryFascistCheck(self): + try: + cracklib.VeryFascistCheck('test') + self.fail('expected ValueError') + except ValueError: + pass + try: + cracklib.VeryFascistCheck('LhIRI6JXpKhUqBjT') + except ValueError: + self.fail('password should be good enough') + + def test_palindrome(self): + try: + cracklib.VeryFascistCheck('ot23#xyx#32to') + self.fail('expected ValueError') + except ValueError: + e = sys.exc_info()[1] + self.assertEqual('is a palindrome', str(e)) + + def test_same(self): + try: + cracklib.VeryFascistCheck('test', 'test') + self.fail('expected ValueError') + except ValueError: + e = sys.exc_info()[1] + self.assertEqual('is the same as the old one', str(e)) + + def test_case_change(self): + try: + cracklib.VeryFascistCheck('test', 'TeSt') + self.fail('expected ValueError') + except ValueError: + e = sys.exc_info()[1] + self.assertEqual('case changes only', str(e)) + + def test_similar(self): + try: + cracklib.VeryFascistCheck('test12', 'test34') + self.fail('expected ValueError') + except ValueError: + e = sys.exc_info()[1] + self.assertEqual('is too similar to the old one', str(e)) + + def test_simple(self): + try: + cracklib.VeryFascistCheck('t3sx24') + self.fail('expected ValueError') + except ValueError: + e = sys.exc_info()[1] + self.assertEqual('is too simple', str(e)) + + def test_simple_lower(self): + for passwd in ['t' * i for i in range( + cracklib.MIN_LENGTH - cracklib.LOW_CREDIT)]: + self.assertEquals( + 1, cracklib.simple(passwd), + 'password {0} should be detected as too simple'.format( + passwd)) + self.assertEquals(0, cracklib.simple( + 't' * (cracklib.MIN_LENGTH - cracklib.LOW_CREDIT))) + + def test_simple_upper(self): + for passwd in ['T' * i for i in range( + cracklib.MIN_LENGTH - cracklib.UP_CREDIT)]: + self.assertEquals( + 1, cracklib.simple(passwd), + 'password {0} should be detected as too simple'.format( + passwd)) + self.assertEquals(0, cracklib.simple( + 'T' * (cracklib.MIN_LENGTH - cracklib.UP_CREDIT))) + + def test_simple_digit(self): + for passwd in ['1' * i for i in range( + cracklib.MIN_LENGTH - cracklib.DIG_CREDIT)]: + self.assertEquals( + 1, cracklib.simple(passwd), + 'password {0} should be detected as too simple'.format( + passwd)) + self.assertEquals(0, cracklib.simple( + '1' * (cracklib.MIN_LENGTH - cracklib.DIG_CREDIT))) + + def test_simple_other(self): + for passwd in ['#' * i for i in range( + cracklib.MIN_LENGTH - cracklib.OTH_CREDIT)]: + self.assertEquals( + 1, cracklib.simple(passwd), + 'password {0} should be detected as too simple'.format( + passwd)) + self.assertEquals(0, cracklib.simple( + '#' * (cracklib.MIN_LENGTH - cracklib.OTH_CREDIT))) + + def test_simple_combinations(self): + testset = '#a' * (cracklib.MIN_LENGTH // 2) + for passwd in [testset[:i] for i in range( + cracklib.MIN_LENGTH - cracklib.LOW_CREDIT - cracklib.OTH_CREDIT)]: + self.assertEquals( + 1, cracklib.simple(passwd), + 'password {0} should be detected as too simple'.format( + passwd)) + self.assertEquals(0, cracklib.simple( + testset[:(cracklib.MIN_LENGTH - cracklib.LOW_CREDIT - + cracklib.OTH_CREDIT)])) + + +tests.append(TestModuleFunctions) + + +def run(verbosity=1, repeat=1): + print(('cracklib is installed in: ' + os.path.dirname(__file__))) + print(('cracklib version: ' + __version__)) + print((sys.version)) + + suite = unittest.TestSuite() + for cls in tests: + for _ in range(repeat): + suite.addTest(unittest.makeSuite(cls)) + runner = unittest.TextTestRunner(verbosity=verbosity) + return runner.run(suite) -- 2.40.0