Current File : //usr/lib/python2.7/site-packages/passlib/tests/utils.pyc
�
���Xc@�s�dZddlmZddlmZddlZddlmZmZddl	Z	ddl
Z
e
je�Z
ddlZddlZddlZddlZddlZddlZddlZddlmZmZddlmZmZddlZddlmZdd	lmZdd
lmZddl j!Z!ddl"m#Z$m%Z%m&Z&m'Z'm(Z(ddl)m*Z*m+Z+m,Z,m-Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4dd
lm5Z5m6Z6m7Z7m8Z8m9Z9ddl:m;Z;ddl<j=j>Z?dddddgZ@yddlAZBWneCk
r0eDZEnXeFZEd�ZGd�ZHeHe3�ZIdddgZJeJjKejLjMdd�jN�jO��ZPeQeQd�ZRd�ZSeQd�ZTd�ZUeQeDd�ZVd�ZWd �ZXd!�ZYejZd"��Z[d#�Z\d$�Z]d%�Z^d&�Z_d'�Z`d(�ZaeQd)d*d+�Zbd,d-d.�Zcde$fd/��YZ#d0dgZdde#fd1��YZed2eefd3��YZfd4eefd5��YZgd6eefd7��YZhd8ejifd9��YZjdS(:shelpers for passlib unittestsi����(twith_statement(t	unhexlifyN(twrapstpartial(tPasslibHashWarningtPasslibConfigWarning(tPY3tJYTHON(twarn(texc(tMissingBackendError(tTestCasetskiptskipIft
skipUnlesstSkipTest(
thas_rounds_infot
has_salt_infotrounds_cost_valuestrngt
getrandstrt
is_ascii_safet
to_native_strt
repeat_stringtticktbatch(t	iteritemstirangetutunicodetPY2(t
classpropertyt	TEST_MODEtset_filetget_fileRtHandlerCasecC�sRtjj|�}x9tjj|�|krMtjd�tj|d�qWdS(sensure file's mtime has changedg�������?N(tostpathtgetmtimettimetsleeptutimetNone(R%tlast((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytensure_mtime_changed;s
c�s/�fd��t�fd�td�D��S(Nc�s1��}}x||kr(��}qW||S(N((tstarttcur(ttimer(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytsampleEs

c3�s|]}��VqdS(N((t.0t_(R0(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pys	<genexpr>Jsi(tmintrange(R/((R0R/s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt_get_timer_resolutionDstquicktdefaulttfulltPASSLIB_TEST_MODEcC�sB|rttj|�krtS|r>ttj|�kr>tStS(s�check if test for specified mode should be enabled.

    ``"quick"``
        run the bare minimum tests to ensure functionality.
        variable-cost hashes are tested at their lowest setting.
        hash algorithms are only tested against the backend that will
        be used on the current host. no fuzz testing is done.

    ``"default"``
        same as ``"quick"``, except: hash algorithms are tested
        at default levels, and a brief round of fuzz testing is done
        for each hash.

    ``"full"``
        extra regression and internal tests are enabled, hash algorithms are tested
        against all available backends, unavailable ones are mocked whre possible,
        additional time is devoted to fuzz testing.
    (t
_test_modet_TEST_MODEStindextFalsetTrue(R3tmax((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR Ts
cC�s2t|d�rtSd|jkp1t|tj�S(s'check if handler supports 'relaxed' kwdtorig_prefixtrelaxed(thasattrR=tsetting_kwdst
issubclasstuhtGenericHandler(thandler((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pythas_relaxed_settingpscC�s"t|�}|d|dt�jS(s'get effective rounds value from handlertroundstuse_defaults(tunwrap_handlerR>RI(RGRI((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytget_effective_rounds|scC�s[y|j�}Wntk
r$tSXz!|jd�|j�|kSWd|j|�XdS(s*check if backend is the default for sourceR7N(tget_backendR
R=tset_backend(RGtbackendtorig((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytis_default_backend�s

cc�s|dkr|j�}n|j}|r=|j|�dnd}x5||D])}||krN|j|�rN|VqNqNWdS(s�
    iterate over alternate backends available to handler.

    .. warning::
        not thread-safe due to has_backend() call
    iiN(R*RMtbackendsR<thas_backend(RGtcurrenttfallbackRRtidxRO((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytiter_alt_backends�s	cO�sxt||�D]}|SWdS(N(RWR*(targstkwdsRO((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytget_alt_backend�scC�s#xt|d�r|j}qW|S(s5return original handler, removing any wrapper objectstwrapped(RBR[(RG((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRK�s
cC�s�||krtSt|tj�rLx#|rG||kr;tS|j}q%WtSt|t�rzt|tj�rzt||�St	d|f��dS(sG
    test if <handler> was derived from <base> via <base.using()>.
    s%don't know how to inspect handler: %rN(
R>t
isinstanceREt
PrefixWrappert
_derived_fromR=ttypeRDtMinimalHandlertNotImplementedError(RGtbase((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pythandler_derived_from�s	
!
c#�s�t|t�r[t|tj�r[|j��fd�}||_z	dVWd�|_Xn9t|tj�r�t|j��
dVWdQXn	dVdSdS(s
    internal helper for do_config_encrypt() --
    context manager which temporarily replaces handler's _calc_checksum()
    with one that uses min_rounds; useful when trying to generate config
    with high rounds value, but don't care if output is correct.
    c�s:|j}z |j|_�|||�SWd||_XdS(N(RIt
min_rounds(tselfRXRYRI(R[(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytwrapper�s
	N(	R\R_RDREt	HasRoundst_calc_checksumR]tpatch_calc_min_roundsR[(RGRf((R[s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRi�s!			
cC�sJt|t�r!|jd�}nt|d��}|j|�WdQXdS(sset file to specified bytessutf-8twbN(R\Rtencodetopentwrite(R%tcontenttfh((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR!�scC�s&t|d��}|j�SWdQXdS(sread file as bytestrbN(Rltread(R%Ro((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR"�scC�sYt|t�s|Str&|jd�Sy|jd�SWntk
rT|jd�SXdS(s*convert native string to non-native stringsutf-8slatin-1N(R\tstrRRktdecodetUnicodeDecodeError(tsource((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttonn�s

cC�sttjdd|��S(sT
    helper for represent byte strings in hex.

    usage: ``hb("deadbeef23")``
    s\st(Rtretsub(Ru((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pythb�scC�s$||kr|S||kr |S|S(N((tvaluetlowertupper((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytlimit�s
cC�s't�}xt�||kr"qWdS(sAbecause time.sleep() doesn't even have 10ms accuracy on some OSesN(R(tdelayR-((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt
quicksleeps	ii
c
C�s�ddlm}ddlm}||d|p2d�}d}t�|}xXtr�t|j||��}	t�|kr�|	|t||d��fS|d9}qNWdS(	s�
    timeit() wrapper which tries to get as accurate a measurement as possible w/in maxtime seconds.

    :returns:
        ``(avg_seconds_per_call, log10_number_of_repetitions)``
    i����(tTimer(tlogtsetupRwii
N(	ttimeitR�tmathR�RR>R3trepeattint(
tfuncR�tmaxtimetbestofR�R�R/tnumbertendtdelta((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt	time_call	s
	i�I����j?$c�s��fd�}|S(s<
    decorator run test method w/ multiple fixed seeds.
    c�s%t�����fd��}|S(Nc�sJtj��}x4t��D]&}|jd�|d<�||�qWdS(Ni tseed(trandomtRandomRtgetrandbits(RXRYRR2(tcountR�tmaster_seed(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRf s(R(R�Rf(R�R�(R�s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytbuilders!((R�R�R�((R�R�s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytrun_with_fixed_seedsscB�sNeZdZdZd�Zed��Zed��Ze	Z
e	Zd�Zd�Z
e	Zd�Zdd�Zd�ZeZZdddddddd	�Zd
ejfd��YZdddd�Zdd
�Zd�Zd�Zd�Zd�Zd�Zej �Z!dZ"dZ#ddd�Z$dZ%d�Z&e	e'd�Z(RS(sRpasslib-specific test case class

    this class adds a number of features to the standard TestCase...
    * common prefix for all test descriptions
    * resets warnings filter & registry for every test
    * tweaks to message formatting
    * __msg__ kwd added to assertRaises()
    * suite of methods for matching against warnings
    cC�sGtt|�j�}|j}|rCd||p9t|�f}n|S(s;wrap shortDescription() method to prepend descriptionPrefixs%s: %s(tsuperRtshortDescriptiontdescriptionPrefixRr(Retdesctprefix((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�Bs
	cC�s,|j}|jd�p+t|d|t�S(NR2s_%s__unittest_skip(t__name__t
startswithtgetattrR=(tclstname((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt__unittest_skip__Ns	cC�s|jS(N(R�(R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt__test__UscC�s!tt|�j�|j�dS(N(R�RtsetUpt
setUpWarnings(Re((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�dscC�sS|jrOt�}|j�|j|j�tjdd�tjdd�ndS(s6helper to init warning filters before subclass setUp()tignores<the method .*\.(encrypt|genconfig|genhash)\(\) is deprecateds&the 'vary_rounds' option is deprecatedN(tresetWarningStatetreset_warningst	__enter__t
addCleanupt__exit__twarningstfilterwarnings(Retctx((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�hs		
cC�sF|jr8|r8|j�jd�r8d|j�|fS|pA|SdS(Nt:s%s %s(tlongMessagetrstriptendswith(Retmsgtstd((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt_formatMessage{s$c	O�s�|jdd�}|dkr=tt|�j|d||�Sy|||�}Wn|k
rf}|SXd||f}|j|j||���dS(Nt__msg__s-function returned %r, expected it to raise %r(tpopR*R�RtassertRaisestfailureExceptionR�(	Ret	_exc_typet	_callableRXRYR�tresultterrR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��s

cO�std��dS(Ns%this alias is deprecated by unittest2(tAssertionError(Retatk((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytassertEquals�sc	C�sOt|d�r!|}	|j}nd}	|rI|jt|�||�n|rk|jt|�||�n|r�|j|||�n|s�|r|	s�td��n|	j}
|
j	d�s�|
j	d�r�|
d }
n|r�|j|
||�n|r|j|
||�qn|rK|	s2td��n|j|	j
||�ndS(s�check if warning matches specified parameters.
        'warning' is the instance of Warning to match against;
        can also be instance of WarningMessage (as returned by catch_warnings).
        tcategorys7matching on filename requires a WarningMessage instances.pycs.pyoi����s5matching on lineno requires a WarningMessage instanceN(RBtmessageR*tassertEqualRrtassertRegextassertIsInstancet	TypeErrortfilenameR�tlineno(Retwarningt
message_reR�R�tfilename_reR�R�R�twmsgtreal((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt
assertWarning�s0	
t_AssertWarningListcB�s)eZdZd�Zd�Zd�ZRS(s'context manager for assertWarningList()cK�s>||_||_ttj|�|_|jjdt�dS(Ntrecord(tcaseRYR�RR�t_AssertWarningList__supert__init__R>(ReR�RY((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��s		cC�s|jj�|_dS(N(R�R�R�(Re((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��scG�s@|jj|�|ddkr<|jj|j|j�ndS(Ni(R�R�R*R�tassertWarningListR�RY(Retexc_info((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��s(R�t
__module__t__doc__R�R�R�(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��s		cC�s�|dkr7|dk	st�|j|d|d|�S|dk	sIt�t|ttf�sj|g}nx�t|�D]�\}}t|t�r�td|�}nNt|t	�r�t
|t�r�td|�}nt|t�s�td��ny||}Wnt
k
rPnX|j|d||�qwWt|�t|�krKdSdt|�t|�|j|�|f}|j|j||���dS(sBcheck that warning list (e.g. from catch_warnings) matches patternR�R�R�R�s#entry must be str, warning, or dictNs0expected %d warnings, found %d: wlist=%s desc=%r(R*R�R�R\tlistttuplet	enumerateRrtdictR_RDtWarningR�t
IndexErrorR�tlent_formatWarningListR�R�(RetwlistR�R�RVtentrytdataR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��s.
(cO�s3|dkrg}n|j||||�|2dS(sD[deprecated] assertWarningList() variant that clears list afterwardsN(R*R�(ReR�R�RXRY((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytconsumeWarningList�s	cC�s�d}t|d�rWd|j|jf}|jrK|d|jf7}n|j}nt|�}d|j|jt|�|fS(NRwR�s filename=%r lineno=%rs line=%rs<%s.%s message=%r%s>(	RBR�R�tlineR�R_R�R�Rr(ReR�ttailR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt_formatWarnings	c�s!ddj�fd�|D��S(Ns[%s]s, c3�s|]}�j|�VqdS(N(R�(R1R�(Re(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pys	<genexpr>
s(tjoin(ReR�((Res7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�scC�s@ddlm}|s<ddlm}|jd|��ndS(s,helper to skip test if stringprep is missingi����(t
stringprep(t_stringprep_missing_reasons%not available - stringprep module is N(t
passlib.utilsR�R�tskipTest(ReR�R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytrequire_stringpreps
	cC�s&t|�s"|jd|��ndS(s8skip test for all PASSLIB_TEST_MODE values below <level>srequires >= %r test modeN(R R�(Retlevel((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytrequire_TEST_MODEscC�str|jd�SdS(s'skip test if writeable FS not availables.GAE doesn't offer read/write filesystem accessN(tGAER�(Re((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytrequire_writeable_filesystemsR7c	C�sc|j}|r#||kr#||S|j�1|j}|rP||krP||S|sfi}|_n|prtj}|dkr�ttjjd�p�tjjd�p�t	j
d��}t_tjd|�nt
|�}djt|�|j|j|j|g�}tj|jd��j�}t|d d�}tj|�}||<|SWdQXdS(	sU
        Return a :class:`random.Random` object for current test method to use.
        Within an instance, multiple calls with the same name will return
        the same object.

        When first created, each RNG will be seeded with value derived from
        a global seed, the test class module & name, the current test method name,
        and the **name** parameter.

        The global seed taken from the $RANDOM_TEST_SEED env var,
        the $PYTHONHASHSEED env var, or a randomly generated the
        first time this method is called. In all cases, the value
        is logged for reproducibility.

        :param name:
            name to uniquely identify separate RNGs w/in a test
            (e.g. for threaded tests).

        :param seed:
            override global seed when initialzing rng.

        :rtype: random.Random
        tRANDOM_TEST_SEEDtPYTHONHASHSEEDi susing RANDOM_TEST_SEED=%ds
sutf-8iN(t
_random_cachet_random_global_lockRt_random_global_seedR*R�R$tenvirontgettsys_rngR�R�tinfoR_R�RrR�R�t_testMethodNamethashlibtsha256Rkt	hexdigestR�R�(	ReR�R�tcachetglobal_seedR�RutdigestR{((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt	getRandom2s,	
	c�s�|j�tj||�\}}tj|�|j��dkrpg�|_�fd�}|j|�n�j|�|S(s1create temp file that's cleaned up at end of testc�s;x0�D](}tjj|�rtj|�qqW�2dS(N(R$R%texiststremove(R%(tqueue(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytcleaner|s
N(	R�ttempfiletmkstempR$tcloset
_mktemp_queueR*R�tappend(ReRXRYtfdR%R((Rs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytmktempts

	

c�s�yt���}Wn<tk
rQ|r/�n��fd�}|j|�nX|jt��|�|r�t||�}t|�|�nt��|�dS(s=monkeypatch object value, restoring original value on cleanupc�s)yt���Wntk
r$nXdS(N(tdelattrtAttributeError((tattrtobj(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytcleanup�s
N(R�RR�tsetattrRR(ReRRR{trequire_existingtwrapRPR((RRs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt	patchAttr�s
N()R�R�R�R*R�R�RR�R�R>t_TestCase__unittest_skipR�R�R�R�R�R�R�tassertNotEqualstassertRegexMatchesR�R�tcatch_warningsR�R�R�R�R�R�R�R�t	threadingtLockR�R�R�RR	RR=R(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR-sD	
				
	
+					@	tanycB�s�eZdZdYZdYZgZgZgZgZ	gZ
dZd[d\gZed�ed�d	gZ
eZeZeZeZed
��ZeZed��Zed��Zd
�ZdYed�Zd�Zd�Zd�ZedYdYd�Z dYd�Z!d�Z"d�Z#d�Z$dYdYd�Z%dZ&ed��Z'ed��Z(d�Z)d�Z*d�Z+d�Z,ed�Z-d �Z.d!�Z/d"�Z0d#�Z1d$�Z2d%�Z3ed&��Z4d'�Z5d(�Z6d)�Z7eZ8d*�Z9d+�Z:ed,��Z;d-�Z<d.�Z=d/�Z>d0�Z?d1�Z@d2�ZAd3�ZBd4�ZCd5�ZDd6�ZEd7�ZFd8�ZGd9�ZHd:�ZId;�ZJd<�ZKd=�ZLd>�ZMd?�ZNd@�ZOdA�ZPdB�ZQdC�ZRdD�ZSdE�ZTdF�ZUdG�ZVdH�ZWdI�ZXdJ�ZYdK�ZZdL�Z[dM�Z\dN�Z]edO�Z^dP�Z_edQ��Z`edR��Zad]ZbedT�ZcdU�ZddVeefdW��YZfdX�ZgRS(^s�base class for testing password hash handlers (esp passlib.utils.handlers subclasses)

    In order to use this to test a handler,
    create a subclass will all the appropriate attributes
    filled as listed in the example below,
    and run the subclass via unittest.

    .. todo::

        Document all of the options HandlerCase offers.

    .. note::

        This is subclass of :class:`unittest.TestCase`
        (or :class:`unittest2.TestCase` if available).
    t	des_cryptt
6f8c114b58f2ct	md5_crypts"$1$dOHYPKoP$tnxS1T8Q6VVn3kpV8cN6o.tsha512_cryptsx$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwcelCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1ttests
\u20AC\u00A5$s€¥$cC�s#dt|jdd�krdSdS(Ntos_cryptRRt((R�RGR*(R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytforbidden_characters�scC�s?|j}|j}t|d�r;|d|j�f7}n|S(NRMs
 (%s backend)(RGR�RBRM(ReRGR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�
s
		cc�syx"|jD]\}}||fVq
Wx%|jD]\}}}||fVq/Wx%|jD]\}}}||fVqWWdS(s*iterate through known (secret, hash) pairsN(tknown_correct_hashestknown_correct_configstknown_alternate_hashes(R�tsecretthashtconfigtalt((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytiter_known_hashesscC�s%t|j��}|j�j|�S(s#test random sample secret/hash pair(R�R,Rtchoice(Retknown((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytget_sample_hash#scC�s�|j||�}|j|tkp-|tkd|f�|jjsM|r�|sWdS|spd||f}n|j|��n2|r�dS|s�d||f}n|j|��dS(s>helper to check verify() outcome, honoring is_disabled_handlers'verify() returned non-boolean value: %rNs4verify incorrectly returned True: secret=%r, hash=%rs!verify failed: secret=%r, hash=%r(t	do_verifyt
assertTrueR>R=RGtis_disabledR�(ReR(R)R�tnegateR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytcheck_verify+scC�s!|j|td||f�dS(Ns'%s() failed to return native string: %r(R�Rr(ReR�t	func_name((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytcheck_returned_native_str>scC�s�|j}d|jkr�d|kr�|j}|j}tdd�r[td|�|d<q�d}t|dd�dkr�||8}n|d|>}td||�|d<ndS(	s0subclassable method to populate default settingsRIR?R6itrounds_costtlog2iN(RGRCRdtdefault_roundsR R?R�R*(ReRYRGtmntdftfactor((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytpopulate_settingsFs			
cC�s|S(s?subclassable method allowing 'secret' to be encode context kwds((ReR(RY((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytpopulate_contextYscK�s�|j|�|dkr"i}n|j||�}|r�g}|rc|j|�|jd�n|j|��|p|jj||�SWdQXn"|p�|jj|�j	||�SdS(s3call handler's hash() method with specified optionss"passing settings to.*is deprecatedN(
R=R*R>tupdateR
R�RGtencrypttusingR)(ReR(tuse_encryptRGtcontexttsettingsR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt
do_encrypt^s
	
"cK�s.|j||�}|p|jj|||�S(scall handler's verify method(R>RGtverify(ReR(R)RGRY((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR0pscC�s|jj|�S(scall handler's identify method(RGtidentify(ReR)((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytdo_identifyuscK�s|j|�|jj|�S(s6call handler's genconfig method with specified options(R=RGt	genconfig(ReRY((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytdo_genconfigys
cK�s(|j||�}|jj|||�S(s4call handler's genhash method with specified options(R>RGtgenhash(ReR(R*RY((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt
do_genhash~scK�sf|p|jj|�}|dkr-i}n|jd|�}t|��|j||�SWdQXdS(s�
        return sample hash for handler, w/o caring if digest is valid
        (uses some monkeypatching to minimize digest calculation cost)
        RwN(RGRAR*R>RiR)(ReRGRCRDR(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytdo_stub_encrypt�s	
sbackend not availablecC�sD|j}t||�r*td�r*dS|j|�r=dS|jS(s�
        helper for create_backend_case() --
        returns reason to skip backend, or None if backend should be tested
        R8s$only default backend is being testedN(RGRQR RSR*tBACKEND_NOT_AVAILABLE(R�RORG((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt_get_skip_backend_reason�s	c
C�s�|j}|j}t|d�s-td��||jksOtd|f��|f}|dkrt|tf7}ntd||f|tdd||fd|d	|j��}|j	|�}|r�t
|�|�}n|S(
NRRs0handler must support uh.HasManyBackends protocolsunknown backend: %rR"s
%s_%s_testR�s%s (%s backend)ROR�(RGR�RBR�RRtOsCryptMixinR_R�R�ROR(R�RORGR�tbasestsubclstskip_reason((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytcreate_backend_case�s$		"	
cC�s�tt|�j�|j}|j}|rrt|d�sItd��n|j|j|j	��|j|�nddl
m}|j|d|j
d��dS(NRNs)handler doesn't support multiple backendsi����(thandlersRssalt generator(R�R#R�RGRORBtRuntimeErrorR�RNRMR�RURR(ReRGRORU((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��s		c�s�|j��fd�}|d�}|j|d�|j|td�|j|j�|kd�|jtjd|�d|f�|d�}|j|dk	d	�|j|td
�|d�}|j|dk	d�|j|td
�dS(svalidate required attributesc�st�|d�S(N(R�R*(R�(RG(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytga�sR�sname not defined:sname must be native strsname not lower-case:s^[a-z0-9_]+$s&name must be alphanum + underscore: %rRCssetting_kwds must be defined:ssetting_kwds must be a tuple:tcontext_kwdsscontext_kwds must be defined:scontext_kwds must be a tuple:N(	RGR1R�RrR|RxtmatchR*R�(ReRWR�RDRC((RGs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_01_required_attributes�s	cC�sr|j�}|j|d�|jd|�}|j|d�|jd|�|j|j|�d|f�dS(s�test basic config-string workflow

        this tests that genconfig() returns the expected types,
        and that identify() and genhash() handle the result correctly.
        RItstubRKRws4identify() failed to identify genconfig() output: %rN(RJR6RLR0R1RH(ReR*R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_02_config_workflow�s
cC�s?|j}|j�}|j||�|j|j|j�dS(stest basic using() workflowN(RGRAtassertIsNotR�R�(ReRGRR((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_02_using_workflows	cC�szd}xm|jD]b}|j|d|�}|j|d�|j||�|j||dt�|j||�}|j|d�|jjr�|jr�|j	||d|||f�n |j
||d|||f�|j||�}|j|d�|jjr9|jr9|j
||d||||f�n#|j	||d	||||f�|j|j|��qWd
S(s�test basic hash-string workflow.

        this tests that hash()'s hashes are accepted
        by verify() and identify(), and regenerated correctly by genhash().
        the test is run against a couple of different stock passwords.
        R[RBR)R3RKsBgenhash() failed to salt result hash: secret=%r hash=%r: result=%rs@genhash() failed to reproduce hash: secret=%r hash=%r: result=%rsYgenhash() failed to reproduce disabled-hash: secret=%r hash=%r other_secret=%r: result=%rsGgenhash() duplicated hash: secret=%r hash=%r wrong_secret=%r: result=%rN(
tstock_passwordsRER6R4R>RLRGR2tdisabled_contains_salttassertNotEqualR�R1RH(Ret
use_16_legacytwrong_secretR(R�tother((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_03_hash_workflow"s*cC�s|jdt�dS(sEtest hash-string workflow with legacy .encrypt() & .genhash() methodsRbN(ReR>(Re((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_03_legacy_hash_workflowYscC�s=|jtd��}|j|d�|jdt|��|jtd�t|��|jdt|��}|j|d�|jjr�|jr�|j||�n|j	||�|jtd�t|��}|j|d�|jjr
|jr
|j||�n|j	||�|j
|jt|���dS(s#test hashes can be unicode or bytesR[R)RKN(RERvR6R4RLRGR2R`RaR�R1RH(ReR�Rd((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_04_hash_types]scC�s|j}t|d�s*|jd��n|j|j|j��x�|jD]�}|j|t�|j	|t
d|f�|j|�}|tkr�|j|�|j
|j�|�qM|tkr�|jt|j|�qMtd||f��qMWdS(stest multi-backend supportRNshandler only has one backendsinvalid backend name: %rs*has_backend(%r) returned invalid value: %rN(RGRBR�R�RNRMRRR�RrtassertNotIntRESERVED_BACKEND_NAMESRSR>R�R=R�R
R�(ReRGROtret((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_05_backends�s"	

cC�s(d|jjkr$|jd��ndS(Ntsaltshandler doesn't have salt(RGRCR�(Re((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytrequire_salt�scC�s/|j�t|j�s+|jd��ndS(Ns!handler doesn't provide salt info(RmRRGR�(Re((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytrequire_salt_info�s
c	C�s�|j�|j}|j}|jd
k	}|rO|jdkrO|d��n|jdkrm|d��n|r�|j|jkr�|d��n|j|jkr�|d��n|r�|j|jkr�|d��nd|jkr|s|j|jkrtd	|j	f�n|j
rx|js<|d
��nxQ|jD]+}||j
krF|d|f��qFqFWn|js�|d��nd
S(s!validate optional salt attributesismax_salt_chars must be >= 1ismin_salt_chars must be >= 0s(min_salt_chars must be <= max_salt_charss*default_salt_size must be >= min_salt_sizes*default_salt_size must be <= max_salt_sizet	salt_sizesT%s: hash handler supports range of salt sizes, but doesn't offer 'salt_size' settings$default_salt_chars must not be emptysEdefault_salt_chars must be subset of salt_chars: %r not in salt_charss;default_salt_chars MUST be specified if salt_chars is emptyN(RnR�RGt
max_salt_sizeR*t
min_salt_sizetdefault_salt_sizeRCRR�t
salt_charstdefault_salt_chars(ReR�R�tmx_settc((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt test_10_optional_salt_attributes�s2
		(			cC�s[|j}t|�s(td|j��ddlm}t|j|t|j	�d��S(s%calculate number of salt bits in hashsneed explicit bit-size for i����(R�i(
RGRR�R�R�R�R�RrR�Rt(ReRGR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt	salt_bits�s
		c�sV�j�tdd�j����fd�}|�j�|�fd��dS(s4test hash() / genconfig() creates new salt each timeiiic�sS|�}x-t��D]}|�}||krdSqW�jd�f��dS(Ns.failed to find different salt after %d samples(RR�(R�tvalue1R2tvalue2(tsamplesRe(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytsampler�s			c�s
�jd�S(NR[(RE((Re(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt<lambda>�sNi(RmR?RxRJ(ReR|((R{Res7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_11_unique_salt�s


cC�s�|j�|j}|jdd!}|j}||}|jd|�|jdd|�|dkr�|jt|jd|d �n|jt|jdd|d�dS(s.test hash() / genconfig() honors min_salt_sizeiiRlR[Roi����N(RnRGRsRqRJRER�t
ValueError(ReRGt	salt_chartmin_sizets1((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_12_min_salt_size�s
		
c	
C�s�|j�|j}|j}|jdd!}|d	ksD|dkr�|d}|jd|�}|jd||�}|j||�|jdd�n�||}|jd|�}|jd|�||}|jt|jd|�|jt|jd|d�t	|�rUt
jdt��|jd|dt�}Wd	QX|j
||�n|j|kr�|jd|d
 �}|j||�nd	S(s.test hash() / genconfig() honors max_salt_sizeiiiiRlRoR�RANi����i(RnRGRpRsR*RMRaR�RRHR�RR>R�Rq(	ReRGtmax_sizeR�R�tc1tc2ts2tc3((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_13_max_salt_sizes.
		


cC�s/|jr+ddlm}|j|�}n|S(sprepare generated salti����(tbcrypt64(tfuzz_salts_need_bcrypt_repairtpasslib.utils.binaryR�t
repair_unused(ReRlR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytprepare_saltQs	c

C�s!|j�|j}|j}|j}|j}t|t�}x`t||pOd�D]I}t|�|kr}t	||�}n|j
|�}|jd|�qSWtd�}|r�|j
d�}nt|d�}xG|D]?}	|	|kr�|jt|jd|	|dd|	f�q�q�WdS(	stest hash() honors salt_charsi Rlt�slatin-1iR�sinvalid salt char %r:N(RnRGRpRqRsR\tbytesRR�RR�RMRRkR?R�R(
ReRGtmxR:tcstrawRlRutchunkRv((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_14_salt_charsXs&
				
cC�s!t|jdt�rtStSdS(s)hack to determine salt keyword's datatypet_salt_is_bytesN(R�RGR=R�R(Re((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt	salt_typessc
C�s�|j�|j}t|jdd�p+d}dtfd��Y}|jt|jdd|��|tk	r�|jt|jddt	d�|�n|t
kp�to�|tks�|jt|jddd|�nd	S(
stest non-string salt valuesRqiitfakecB�seZRS((R�R�(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��sR[RltxN(RmR�R�RGtobjectR�R�RERRR�R(ReR�RoR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_15_salt_type|s
	)c
C�s|j�|j}|j}|j}|j}|jt|jdd�|jt	g��|jdddt
�}WdQX|j|j|�|r�|jt|jd|d�|jt	g��!|jd|ddt
�}WdQX|j|j|�n||kr�|jd|d�}|j|j|d�|j|j|�|jd|d�}|j|j|d�|j|j|�n||kr�|}n
|d}|jdt|��}|j|j|�|jt|jdt|�d�|jd|�}|j|j|�dS(	s$Handler.using() -- default_salt_sizeRri����RANiitxxxRo(
RnRGRqRpRrR�RRAR�RR>R�Rr(ReRGR:R�R;ttemptref((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_using_salt_size�s:
				"	
#cC�s%t|j�s!|jd��ndS(Nshandler lacks rounds attributes(RRGR�(Re((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytrequire_rounds_info�scC�s|j�|j}|j}|jd
kr:|d��n|jdkrX|d��n|jdkrv|d��n|j|jkr�|d��n|jd
k	r�|j|jkr�|d��n|j|jkr�|d��q�n|jtkr|d	|jf��nd
S(s#validate optional rounds attributessmax_rounds not specifiedismax_rounds must be >= 1ismin_rounds must be >= 0s min_rounds must be <= max_roundss$default_rounds must be >= min_roundss$default_rounds must be <= max_roundss unknown rounds cost constant: %rN(	R�RGR�t
max_roundsR*RdR9R7R(ReR�R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt"test_20_optional_rounds_attributes�s$
		cC�s�|j�|j}|j}|jd|�|jdd|�|jt|jd|d�|jt|jdd|d�dS(s+test hash() / genconfig() honors min_roundsRIR[iN(R�RGRdRJRER�R(ReRGRd((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_21_min_rounds�s
		cC�s�|j�|j}|j}|dk	rh|jt|jd|d�|jt|jdd|d�n|dkr�|jdd�n|jd|�dS(s+test hash() / genconfig() honors max_roundsRIiR[iNI�i���(	R�RGR�R*R�RRJRERM(ReRGR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_21b_max_rounds�s
		#c

�s?|j�|j}|jdkrO|�|j�}t�fd��|_n|j}|j}|j}|psd|d}||kr�|d7}n||d}|p�d|d}|jdkr�|dO}|dO}|dO}d}nd}|j	g��#|jd|d|d|�}	Wd	QX||	||||fS(
sU
        setup test helpers for testing handler.using()'s rounds parameters.
        t
bsdi_cryptc�st�|�j�S(N(R�t_generate_rounds(R�(torig_handler(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR}si'iitmin_desired_roundstmax_desired_roundsR9N(
R�RGR�RAtclassmethodR�RdR�R9R�(
ReRGtorig_min_roundstorig_max_roundstorig_default_roundstmediumtsmalltlargetadjRR((R�s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt_create_using_rounds_helper
s4
				



		c
C�s|j�|j}|j}|j}|j}|j�\}}}}}}	|j|j|�|j|j|�|j|jd�|j|j	d�|j|j|�|j|j|�|j|j|�|j|j|�|j|j|�|j|j	|�dS(s@
        HasRounds.using() -- sanity check test harness
        N(
R�RGRdR�R9R�R�R�R*R�(
ReRGR�R�R�RRR�R�R�R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_has_rounds_using_harness5s 
				c
C�s�|j�\}}}}}}|j}|j}|j}	|dkr�|jt|jd||�|jtg��!|jd||dt	�}
WdQX|j
|
j|�n|r|jt|jd||�|jtg��!|jd||dt	�}
WdQX|j
|
j|�n|jg��|jd||�}
WdQX|j
|
j||�|jd|d|�}
|j
|
j|d|�|jg��|jd||�}
WdQX|j
|
j||�|j
t|||�||�|j
t||�|�|jg��&|j
t|||�||�WdQX|jd|�}
|j
|
j|�|jdt
|��}
|j
|
j|�|jt|jdt
|�d�dS(sF
        HasRounds.using() -- min_rounds / min_desired_rounds
        iR�RANiRdR�(R�RdR�R9R�RRAR�RR>R�R�RLRr(ReRGRRR�R�R�R�R�R�R�R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt"test_has_rounds_using_w_min_roundsOs>			""!'c

C�s�|j�\}}}}}}|j}|j}|dkr�|jt|jd||�|jtg��!|jd||dt�}	WdQX|j	|	j
|�n|r|jt|jd||�|jtg��!|jd||dt�}	WdQX|j	|	j
|�n|jtg��|jd||�}	WdQX|j	|	j
|�|jt|jd||d||�|jd|d|�}	|j	|	j|d|�|jg��|jd||�}	WdQX|j	|	j
||�|j	t
|||�||�|j	t
||�|�|jg��&|j	t
|||�||�WdQX|jd|�}	|j	|	j
|�|jdt|��}	|j	|	j
|�|jt|jdt|�d�dS(	sF
        HasRounds.using() -- max_rounds / max_desired_rounds
        iR�RANR�iR�R�(R�RdR�R�RRAR�RR>R�R�RR�RLRr(
ReRGRRR�R�R�R�R�R�R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt$test_has_rounds_replace_w_max_rounds�sB		""
!'c	C�sM|j�\}}}}}}|j}|jd||�}|j|j||�|jd||�}|j|j||�|jt|jd||�|r�|jt|jd||�n|jt|�|�|jt|||�||�|jdt|��}|j|j|�|jt|jdt|�d�dS(s5
        HasRounds.using() -- default_rounds
        RdR�R9R�N(	R�R�RAR�R9R�RRLRr(	ReRGRRR�R�R�R�R�R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt&test_has_rounds_using_w_default_rounds�s	 !c	
C�s�|j�\}}}}}}|j}|jd||�}|j|j||�|j|j||�|j|j||�|jd|dd||d|d||�}|j|j||�|j|j|�|j|j||�dS(s-
        HasRounds.using() -- rounds
        RIiRdR9R�N(R�R�RAR�R�R9R�(	ReRGRRR�R�R�R�R�R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_has_rounds_using_w_rounds�s	c�s�|j�\}�}}}}�fd�}|j|d�d�|j|d�d�|j|d�d�|j|d�d�|j|d�d�|jt|d�|jt|d�d	S(
s:
        HasRounds.using() -- vary_rounds parsing
        c�s�jd|�jS(Ntvary_rounds(RAR�(R{(RR(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytparsesg�������?s0.1s10%i�t1000g��������g�������?N(R�R�R�R(ReRGR�R�R�R�R�((RRs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt+test_has_rounds_using_w_vary_rounds_parsing�sc	�sz�j�\}�}}}}d�����fd�}|d||�|d||�||||||�|dt||d�t||d��|jdkr�|d||�|d||�|d	|||�n���jd
d	��\}}�j|t||d���j|t||d���j|t||d
���j|t||d��dS(s=
        HasRounds.using() -- vary_rounds generation
        c�s8t�fd�td�D��}t|�t|�fS(Nc3�s|]}t��VqdS(N(RL(R1R2(R�(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pys	<genexpr>si�(tsetRR3R?(R�tseen((R�s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytget_effective_ranges"c�sN�jd|�}�|�\}}�j||d��j||d�dS(NR�s"vary_rounds had wrong lower limit:s"vary_rounds had wrong upper limit:(RAR�(R�R|R}R�t
seen_lowert
seen_upper(R�ReRR(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytassert_rounds_range!sis0%i2R8s1%s49%s50%R�g�?g�������?g333333�?g�?N(R�R?R3R7RAtassertGreaterEqualtassertLessEqual(	ReRGR�R�R�R�R�R|R}((R�ReRRs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt.test_has_rounds_using_w_vary_rounds_generations 	*cC�s|j�\}}}}}}|jd|dd|d�}|j|d|�}|j|d|�}	|j|d|�}
|j|j|��|j|j|	��|j|j|
��|j|j|��|j|j|	��|j|j|
��dS(sF
        HasRounds.using() -- desired_rounds + needs_update()
        R�iR�RIN(R�RARMtassertFalsetneeds_updateR1(ReRGRRR�R�R�R�R�t
small_hashtmedium_hasht
large_hash((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt&test_has_rounds_using_and_needs_update@s cC�sB|j}t|t�s,t|tj�r>|jd��ndS(Ns)handler doesn't derive from HasManyIdents(RGR\R_RDREt
HasManyIdentsR�(ReRG((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytrequire_many_identsZs	#cC�s�|j}|j�|jd|jk�x$|jD]}|j|td�q3W|jt|j�dkd�|j|jtd�|j|j|jkd�|j	rxft
|j	�D]R\}}|j|td�|j|td�|j||jkd	|f�q�Wn|}|j�d}|j|�}|d=|d|j|�|j
t||�|d
t|�|j
t|dd|�dS(
s$validate HasManyIdents configurationtidents!cls.ident_values must be unicode:is'cls.ident_values must have 2+ elements:s"cls.default_ident must be unicode:s9cls.default_ident must specify member of cls.ident_valuess'cls.ident_aliases keys must be unicode:s)cls.ident_aliases values must be unicode:s:cls.ident_aliases must map to cls.ident_values members: %rRJtxXxN(RGR�R1RCtident_valuesR�RR�t
default_identt
ident_aliasesRR/t	parsehashR�R�R>R(ReR�R{taliasR�RGR)RY((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_30_HasManyIdents_s8	
	cC�s�|j�|j}|j}x:|jD]}||kr&Pq&q&Wtd||jf��d�}|j�}|j|j|�|jd|�}|j|j|�|j|j|�|j||�|�|j||�|�|jt|jdd�|jd|�}|j|j|�|j|j|�|jt	|jd|d|�|j
r�xO|j
j�D];\}}|jd|�}|j|j|dd|�qnWndS(	s=HasManyIdents.using() -- 'default_ident' and 'ident' keywordss6expected to find alternate ident: default=%r values=%rcS�st|�}|dt�jS(NRJ(RKR>R�(R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyteffective_ident�sR�R�R�R�s	alias %r:N(R�RGR�R�R�RAR�R�RR�R�titems(ReRGt
orig_identt	alt_identR�RRR�R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_has_many_idents_using�s2
				c�s|j��jdkr/|jd�j�dS�jsK|j�j�nd�jkrn|j�j�dS�fd�}|j	|d��j�|j	|t
�t
�|j	|d�t
�|j	|t�t�|j	|d�t�|jt
|d�dS(sH
        validate 'truncate_error' setting & related attributes
        ttruncate_errorNc�s�jd|�jS(NR�(RAR�(R{(thasher(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytparse_value�sttruetfalseR�(RGt
truncate_sizeR*RhRCR�R�ttruncate_verify_rejectR1R�R>R=R�R(ReR�((R�s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_truncate_error_setting�s 		cC�s�|j}|jd
k	r=|j|jd�|jd��ndd}d}|j|�}|j}|j|j||�|dd�|d |}|j	|j||�d	�d
S(sO
        test no password size limits enforced (if truncate_size=None)
        istruncate_size is setstoo many secretsiR�R�sverify rejected correct secreti����s full password not used in digestN(
RGR�R*R�R�RER2R�R0R�(ReR�R(R+R)tverify_successt
alt_secret((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_secret_wo_truncate_size�s		

c	C�sX|j}|j}|s*|jd��ntj}d|jkrr|jdt�}|jdt�}tj	}n$|j
r�d	}|}n|}d	}d}d}t||d�}|d }	|d |}
|	d |}|j
}|o�|j}
|s|st�x�||gD]�}|j|	d|�}|j|j|	|d|�|�|j|j||d|�d�|j|j||d|�|
�qW|r|j|d|�}|j|j||d|�|�|j|j|
|d|�|�|j|j|	|d|��n|rT|j||j|d|�}|j|j|�nd	S(
sQ
        test password size limits raise truncate_error (if appropriate)
        struncate_size not setR�stoo many secretsR�ii����RGs truncate_size value is too largeN(RGR�R�R	tPasswordSizeErrorRCRAR=R>tPasswordTruncateErrorR�R*RR2R�R�RER�R0R�R1R�R�(ReRGR�tsize_error_typet
without_errort
with_errorRbR+tlong_secrettshort_secrettalt_long_secrettalt_short_secrettshort_verify_successtlong_verify_successtcand_hashert
short_hasht	long_hashR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_secret_w_truncate_sizesb					



cC�sE|jtk}|jtdgk}d}d}|j|�}|rq|jjrq|j|j||�d�n|j|j||�d�|j|�}|r�|jjr�|j|j||�d�n|j|j||�d�|j||�}|s|jjr.|j	r.|j
||d�n|j||d�dS(	stest password case sensitivitysverify-onlyR!tTESTs%verify() should not be case sensitives!verify() should be case sensitives&genhash() should not be case sensitives"genhash() should be case sensitiveN(tsecret_case_insensitiveR>RERGR2R1R0R�RLR`R�Ra(Rethash_insensitivetverify_insensitiveR|R}th1th2((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_61_secret_case_sensitivets.	


cC�s�|j�d}|jt|jd�|jt|jd|�|jt|jd|�|jt|jd�|jt|jd|�|jt|jd|�dS(s&test non-string passwords are rejectediN(R/R�R�RER*RLR0(ReR)((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_62_secret_border�scC�s�ddlm}ddlm}dd|}|j�d}|j||j||�}|j|j|�|j||j	|�|j||j
||�dS(s"test MAX_PASSWORD_SIZE is enforcedi����(R�(tMAX_PASSWORD_SIZEt.iN(tpasslib.excR�R�R�R/R�RLR�R�RER0(ReR�R�R(R)R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_63_large_secret�scC�s�|j}|s!|jd��ntd�}t|t�rjddlm}||�}|jd�}nx,|D]$}|jt	|j
|||�qqWdS(s1test forbidden characters not allowed in passwordsnone listedR[i����(titer_byte_charstasciiN(R$R�RR\R�tpasslib.utils.compatRRkR�RRE(RetcharsRbRRv((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_64_forbidden_chars�s	
cC�s|j|i�}t|�S(N(R>R(ReR(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytis_secret_8bit�scC�sQtrM|jdkrMt|t�rMy|jd�WqMtk
rItSXntS(sl
        check if we're expecting potential verify failure due to crypt.crypt() encoding limitation
        R"sutf-8(RROR\R�RsRtR>R=(ReR(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytexpect_os_crypt_failure�s$
c
C�sL|j|jp|jd�t}x	|j�D]�\}}|j|�rSt}n|j|j|�d|f�|j|�}y�|j	||d||f�|j
||�}|j|td|f�|j
jr�|jr�w/n|j||d|||f�Wq/tk
r)|s*�q*q/Xq/W|sHtd|j�ndS(stest known hashessOtest must set at least one of 'known_correct_hashes' or 'known_correct_configs's&identify() failed to identify hash: %rs1verify() of known hash failed: secret=%r, hash=%rs,genhash() failed to return native string: %rsGgenhash() failed to reproduce known hash: secret=%r, hash=%r: result=%rs%s: no 8-bit secrets testedN(R1R%R&R=R,RR>RHRR4RLR�RrRGR2R`R�R
Rt	__class__(Retsaw8bitR(R)RR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_70_hashes�s0	
c
C�s�|js|jd��nx�|jD]�\}}}|j|j|�d|f�|j||d||f�|j||�}|j|td|f�|jj	r�|j
r�q%n|j||d||||f�q%WdS(stest known alternate hashessno alternate hashes provideds0identify() failed to identify alternate hash: %rs;verify() of known alternate hash failed: secret=%r, hash=%rs,genhash() failed to return native string: %rsYgenhash() failed to normalize known alternate hash: secret=%r, alt=%r, hash=%r: result=%rN(R'R�R1RHR4RLR�RrRGR2R`R�(ReR+R(R)R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_71_alternates�s	c	C�s!|jjs1|j|jd�|jd��n|jsL|jd��n|jrktjddt�nx�|jD]�\}}}|j	|j
|�d|f�|jt|j
||dd|f�|j||�}|j|td	|f�|j||d
||||f�quWdS(stest known config stringss&handler should not have config stringsshash has no settingssno config strings providedR�R�s5identify() failed to identify known config string: %rR�s+verify() failed to reject config string: %rs,genhash() failed to return native string: %rs^genhash() failed to reproduce known hash from config: secret=%r, config=%r, hash=%r: result=%rN(RGRCR�R&R�tfilter_config_warningsR�R�RR1RHR�RR0RLR�RrR�(ReR*R(R)R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_72_configs	s(		c	C�s�|js|jd��nx}|jD]r}|j|j|�d|f�|jt|jd|dd|f�|jt|jd|dd|f�q%WdS(s)test known unidentifiably-mangled stringssno unidentified hashes provideds?identify() incorrectly identified known unidentifiable hash: %rR[R�s:verify() failed to throw error for unidentifiable hash: %rs;genhash() failed to throw error for unidentifiable hash: %rN(tknown_unidentified_hashesR�R�RHR�RR0RL(ReR)((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_73_unidentified;	s	c	C�s�|js|jd��nx}|jD]r}|j|j|�d|f�|jt|jd|dd|f�|jt|jd|dd|f�q%WdS(s-test known identifiable-but-malformed stringssno malformed hashes provideds6identify() failed to identify known malformed hash: %rR[R�s5verify() failed to throw error for malformed hash: %rs6genhash() failed to throw error for malformed hash: %rN(tknown_malformed_hashesR�R1RHR�RR0RL(ReR)((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_74_malformedP	s	c
C�s:|jr|jd��n|js6|jd��nx�|jD]�\}}||jjkr�|j|j|�d|f�|jd|�|jd|�}|j	|t
d|f�q@|j|j|�d||f�|jt
|jd|dd||f�|jt
|jd|dd	||f�q@Wd
S(stest known foreign hashessnot applicablesno foreign hashes provideds,identify() failed to identify known hash: %rR[s,genhash() failed to return native string: %rs:identify() incorrectly identified hash belonging to %s: %rR�s;verify() failed to throw error for hash belonging to %s: %rs<genhash() failed to throw error for hash belonging to %s: %rN(taccepts_all_hashesR�tknown_other_hashesRGR�R1RHR0RLR�RrR�R�R(ReR�R)R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_75_foreigne	s*		cC�sv|jt|jd�|jt|jdd�|jt|jdd�|jt|jd�|jt|jdd�|jt|jdd�x�td�dgD]�}|jr�|j|j|��|jd|�|jd|�}|j	|d�q�|j
|j|�d�|jt|jd|dd�|jt|jd|dd�q�W|jd	�|jd
�dS(s#test non-string hashes are rejectedR[iRwRKs,identify() incorrectly identified empty hashR�s$verify() failed to reject empty hashs%genhash() failed to reject empty hashs€¥$sabc�N(R�R�RHR*R0RLRRR1R6R�R(ReR)R�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_76_hash_border�	s(	
c
�s�|jjr|jd��nddlm}|j}|dkrU|jd��n|jd|�}d��|r�tj�j	}nd}|j
d	|�}|j||�}tj
d
|j||t|�dj�fd�|D���|�}||}	d}
x[|�|	krf|j�}|d
}|d}
|d}|d}|rb||d<n|j||�}x�|D]�}�|�}||||�}|dkr�q{n|tks�|tks�t�|s�|jd||||f��n|j�dkr{||
||�}|rU|dkrU|jd||
|||f��qUq{q{W|
d7}
qWtj
d|j||�||
�dS(sfuzz testing -- random passwords and options

        This test attempts to perform some basic fuzz testing of the hash,
        based on whatever information can be found about it.
        It does as much as it can within a fixed amount of time
        (defaults to 1 second, but can be overridden via $PASSLIB_TEST_FUZZ_TIME).
        It tests the following:

        * randomly generated passwords including extended unicode chars
        * randomly selected rounds values (if rounds supported)
        * randomly selected salt sizes (if salts supported)
        * randomly selected identifiers (if multiple found)
        * runs output of selected backend against other available backends
          (if any) to detect errors occurring between different backends.
        * runs output against other "external" verifiers such as OS crypt()

        :param report_thread_state:
            if true, writes state of loop to current_thread().passlib_fuzz_state.
            used to help debug multi-threaded fuzz test issues (below)
        snot applicablei����(Risdisabled by test modetthreadedcS�s|jp|jj�dS(Ni(R�R�t
splitlines(tv((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytvname�	ss	fuzz testR�s.%s: %s: started; max_time=%r verifiers=%d (%s)s, c3�s|]}�|�VqdS(N((R1R(R(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pys	<genexpr>�	sR(RdRDRCRsAfailed to verify against %r verifier: secret=%r config=%r hash=%rg�������?s\was able to verify wrong password using %s: wrong_secret=%r real_secret=%r config=%r hash=%ris!%s: %s: done; elapsed=%r count=%rN(RGR2R�R�Rt
max_fuzz_timetget_fuzz_verifiersRtcurrent_threadR�RtFuzzHashGeneratorR�tdebugR�R�R�tgenerateRER>R=R�R�R�(ReRRtmax_timet	verifierstthread_nameRt	generatorR-tstopR�toptsR(RdRDR�R)RFR�R�((Rs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_77_fuzz_input�	sZ			 	






		#	c�s��jd�ddl��jjr7�jd��n�j}|dks[�jdkrm�jd��n�j��dg����fd����fd	�}gt|�D]}||�^q�}�j|d
}d}xM|D]E}|j	|�|j
�sq�ntjd|j
|�|d7}q�W�dr_�jd�d|f��n|r��jd
||f��ndS(s�multithreaded fuzz testing -- random password & options using multiple threads

        run test_77 simultaneously in multiple threads
        in an attempt to detect any concurrency issues
        (e.g. the bug fixed by pybcrypt 0.3)
        R8i����Nsnot applicableiisdisabled by test modec�sRy�jdt�Wn7tk
r'n'���dcd7<WdQX�nXdS(NRii(R%R>R((tfailedtfailed_lockRe(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRf*
s
c�s@d|f}�jd�d|�}|jt�|j�|S(NsFuzz-Thread-%dttargetR�(tThreadt	setDaemonR>R-(tnR�tthread(RRf(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytlaunch3
s



is%s timed out after %f secondssH%d/%d threads failed concurrent fuzz testing (see error log for details)sP%d/%d threads stalled during concurrent fuzz testing (see error log for details)(R�RRGR2R�tfuzz_thread_countRRRR�tis_aliveR�terrorR�tfail(Retthread_countR-R+tthreadsttimeouttstalledR,((R&R'ReRRfs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_78_fuzz_threading
s4
			%


		cC�sVttjjd�pd�}|r(|Stdd�r;dStdd�rNdSdSdS(	s'amount of time to spend on fuzz testingtPASSLIB_TEST_FUZZ_TIMEiR?R6R7iiN(tfloatR$R�R�R (ReR{((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRR
scC�sCttjjd�pd�}|r(|Stdd�r;dSdSdS(s+number of threads for threaded fuzz testingtPASSLIB_TEST_FUZZ_THREADSiR?R6i
N(R�R$R�R�R (ReR{((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR._
stfuzz_verifier_defaultc�s�|j�g}x?|jD]4}t||��}|dk	r|j|�qqWt�d�r�td�r�|r��fd�}x*t��D]}|j||��q�Wn|S(s�return list of password verifiers (including external libs)

        used by fuzz testing.
        verifiers should be callable with signature
        ``func(password: unicode, hash: ascii str) -> ok: bool``.
        RRR8c�s4��fd�}d�d|_�d|_|S(Nc�sB�j�}z!�j���j||�SWd�j|�XdS(N(RMRNRF(R(R)torig_backend(RORG(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��
s

tcheck_t_backends-backend(R�R�(ROR�(RG(ROs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytmaker�
s
N(RGtfuzz_verifiersR�R*R
RBR RW(ReRR tmethod_nameR�R>RO((RGs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRs
s	"c�s8�fd�}�jr+�jd|_n	d|_|S(Nc�s�j|||�S(N(R0(R(R)R�(Re(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt
check_default�
ss-backendRe(ROR�(ReRA((Res7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR:�
s
		RcB�s�eZdZed�ZdZedddddd�ZiZd	�Z	d
�Z
d�Zd�Zd
�Z
d�Zd�Zd�Zd�ZRS(s�
        helper which takes care of generating random
        passwords & configuration options to test hash with.
        separate from test class so we can create one per thread.
        s.qwertyASDF1234<>.@*#! \u00E1\u0259\u0411\u2113sutf-8RIt
random_roundsRotrandom_salt_sizeR�trandom_identcC�s"||_|j|_||_dS(N(R!RGR(ReR!R((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��
s	c
�sR�fd�}�j�\}}td|d|d|�j�d|�j��S(s�
            generate random password and options for fuzz testing.
            :returns:
                `(secret, other_secret, settings_kwds, context_kwds)`
            c�sai}xT|j�D]F\}}t�|�}t�|��}|dk	r|||<qqW|S(N(R�R�R*(tmaptouttkeytmethR�R{(Re(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytgendict�
sR(RdRDRC(trandom_password_pairR�tsettings_maptcontext_map(ReRIR(Rd((Res7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�
scC�s+|jj||�}tt|||��S(s)generate random int w/ gauss distirbution(Rt
normalvariateR�R~(ReR|R}tmutsigmaR{((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytrandintgauss�
scC�s||j}t|�sdS|jp(|j}|j}|jdkrL|}nt|d|j�}|j||||d�S(NR8ig�?(	RGRR*R9RdR7R3R�RP(ReRGR7R|R}((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRB�
s			cC�sg|j}t|�o!d|jks(dS|j}|j}|jpJ|d}|j||||d�S(NRoig�?(RGRRCR*RrRqRpRP(ReRGR7R|R}((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRC�
s			cC�sm|j}|j}d|jks1t|d�r5dS|j�dkrKdSt|d|�}|j|j�S(NR�R�g�?R[(	RRGRCRBR*R�R�R-R�(ReRRG((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRD�
s		cC�s�|j�}x,tr:|j�}|j||�rPqqW|j}|jdd�rk|j|j�}n|jdd�r�|j|j�}n||fS(s=generate random password, and non-matching alternate passwordii(trandom_passwordR>taccept_password_pairRtrandintRktpassword_encoding(ReR(RdR((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRJs		cC�s|j}|j�dkr%td�S|j}|jo=|j}|pId}|dksj|j�dkr�|jdt|d�dd�}n!|jdt|d�d	d
�}t||j	|�}|rt
|t�rx,t|j
d��|kr|d }q�Wn|S(
s*generate random passwords for fuzz testingg-C��6?Rwi?Bi2g�?iiiciFisutf-8i����(RR�RRGR�R�RPR3Rtpassword_alphabetR\RR�Rk(ReRRGR�R�tsizeR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRQs	
	$!cC�s
||kS(s-verify fuzz pair contains different passwords((ReR(Rd((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRR7s(R�R�R�RRURTR�RKRLR�RRPRBRCRDRJRQRR(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�
s 											cC�s�|j}|js`|jt|d��|jt|d��|j|j�|jd��n|j�}|j|tdd�|j	|j
|�dd|�|j�j|j
�d}|j|�}|j|tdd�|j	|j
|�dd|�|jtd|j|�y|j|�}d}Wntk
rV}d}|}nX|dkr�|j|tdd	�|j||�n&|j|t�|jdt|��|j�}|jr�|j||�n|dkr�|j||�n|j|�}	|jr$|j|	|�n|j|	|�|j|d
�}
|js\|dkro|j|
|�n|j|
|�dS(s.disable() / .enable() methodstdisabletenablesnot applicableR�s#disable() must return native strings0identify() didn't recognize disable() result: %riscannot restore original hashs"enable() must return native stringR�N(RGR2R�RBR`R�RWR�RrR1RGRR-RtassertRaisesRegexRRXR*R�R�Ra(ReRGtdisabled_defaultR[t
disabled_stubR�R0tetdisabled_default2tdisabled_stub2tdisabled_other((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_disable_and_enableCsX		


		N(RR(Rs"$1$dOHYPKoP$tnxS1T8Q6VVn3kpV8cN6o.(R sx$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwcelCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1(sfuzz_verifier_default(hR�R�R�R*RGROR%R&R'R
RRRR_R=R�RR`RRR$R>t_HandlerCase__unittest_skiptpropertyR�R�R,R/R4R6R=R>RER0RHRJRLRMRNRORTR�RZR\R^ReRfRgRkRmRnRwRxR~R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�R�RRRR	R
RRRRRR%R6RR.R?RR:R�RR`(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR#�s�
				

							
		 	)		7		#	,			)			6					2					+		8	<	&			)			3	4	!	 	m	&						,		#			&	.Y	@
$	
�RPcB�s�eZdZgZeZdZeZdZ	e
Zd�Ze
d��Zd�Ze
d��Zd�Zd�Zd�Zd	�Zd
�Zd�ZRS(
s�helper used by create_backend_case() which adds additional features
    to test the os_crypt backend.

    * if crypt support is missing, inserts fake crypt support to simulate
      a working safe_crypt, to test passlib's codepath as fully as possible.

    * extra tests to verify non-conformant crypt implementations are handled
      correctly.

    * check that native crypt support is detected correctly for known platforms.
    R"cC�sK|jdkst�|jjd�s4|j�ntt|�j�dS(NR"(ROR�RGRSt_patch_safe_cryptR�RPR�(Re((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��s
cC�sD|j}|s!t|j�}n|j�t|d�}||fS(s�
        return (handler, backend) pair to use for faking crypt.crypt() support for hash.
        backend will be None if none availabe.
        R"(talt_safe_crypt_handlerRKRGRMRZ(R�RGtalt_backend((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt_get_safe_crypt_handler_backend�s	
c�s~|j�\}}|s'td��n|j���j|��fd�}ddlj}|j|d|�t|_dS(s�if crypt() doesn't support current hash alg, this patches
        safe_crypt() so that it transparently uses another one of the handler's
        backends, so that we can go ahead and test as much of code path
        as possible.
        s,handler has no available alternate backends!c�s+�j||�}t|t�s't�|S(N(RKR\RrR�(R(R)(talt_handler(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt
crypt_stub�si����Nt_crypt(	RfR�RARNR�tutilsRR>tusing_patched_crypt(ReRGReRhtmod((Rgs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRc�s
cC�sz|dkst�tt|�j|�}ddlm}||jkrv|rvtd�ro|j�drodSdSn|S(s|
        make sure os_crypt backend is tested
        when it's known os_crypt will be faked by _patch_safe_crypt()
        R"i����(t	has_cryptR8is hash not supported by os crypt()N(
R�R�RPROR�RmRNR RfR*(R�ROtreasonRm((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRO�sc�sJddlj}�fd��|j�_d�_|j|d���S(s�
        patch passlib.utils.safe_crypt() so it returns mock value for duration of test.
        returns function whose .return_value controls what's returned.
        this defaults to None.
        i����Nc�s'|dkr�j||�S�jSdS(NR!(t__wrapped__treturn_value(R(R*(t
mock_crypt(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRqsRi(R�RjRiRoR*RpR(ReRl((Rqs7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt_use_mock_crypts	c�so�j�d�tf��j������fd�}|d�d�|�d �|�d�dS(stest with faulty crypt()ic�sU|�_�j��jd���j��jd��j��jd��dS(NR[(RpR�RLRER0(R{(t	exc_typesR)RqRe(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR!/s	s$xii����R�N(R/R�Rr(ReR!((RsR)RqRes7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_80_faulty_crypt)s	cC�s�|j�}d|_|jrk|jd�}|jd|�}|j||�|j|jd|��nhddl	m
}|j�d}|j||jd�|j||jd|�|j||jd|�dS(stest per-call crypt() fallbackR[i����(R
iN(
RrR*Rpthas_os_crypt_fallbackRERLR�R1R0R�R
R/R�(ReRqR�R�R
R)((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_81_crypt_fallback;s		cC�s�t|jd�r$|jd��ntj}x@|jD]"\}}tj||�r7Pq7q7W|jd|��|dkr�|jd|��nV||j	kr�dS|r�|j
d||jjf�n|j
d||jjf�dS(s0test platform-specific crypt() support detectionR@snot applicable to wrapperssno data for %r platformsvaried support on %r platformNs5expected %r platform would have native support for %rs;did not expect %r platform would have native support for %r(RBRGR�tsystplatformtplatform_crypt_supportRxRYR*RkR1R�(ReRxtpatterntstate((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_82_crypt_supportPs 			c�sZ�j}�js!t|d�r%dSddlm��jj����fd�}|S(stest results against OS crypt()R[i����(tcryptc�s5�j|�sdSt|��}�||�|kS(sstdlib-cryptR(tcrypt_supports_variantR(R(R)(R}tencodingRe(s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytcheck_cryptysN(RGRkRBR*R}RRT(ReRGR�((R}RRes7/usr/lib/python2.7/site-packages/passlib/tests/utils.pytfuzz_verifier_cryptls	cC�stS(s~
        fuzzy_verified_crypt() helper --
        used to determine if os crypt() supports a particular hash variant.
        (R>(ReR)((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR~�sN(R�R�R�RyR>RuR*Rdt_OsCryptMixin__unittest_skipROR=RkR�R�RfRcRORrRtRvR|R�R~(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyRP�s"							tUserHandlerMixincB�sceZdZdZeZeZeZd�Z	d�Z
d�Zd�Zde
jfd��YZRS(s(helper for handlers w/ 'user' context kwd; mixin for HandlerCase

    this overrides the HandlerCase test harness methods
    so that a username is automatically inserted to hash/verify
    calls. as well, passing in a pair of strings as the password
    will be interpreted as (secret,user)
    tusercC�s�|j}d}|j|d|j�}|jr{|jt|j|�|jt|j||�|jt|j||�n-|j|�|j||�|j||�dS(stest user context keywordR[R�N(RGR)tdefault_usert
requires_userR�R�RKRF(ReRGtpasswordR)((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_80_user�s		
cC�s�|jj�}|j�}|jddtd|��}|jrg|j|jd|d|�d�n"|j|jd|d|�d�dS(stest user case sensitivityR[RCR�s!user should not be case sensitivesuser should be case sensitiveN(	R�R|R}RER�tuser_case_insensitiveR1R0R�(ReR|R}R)((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_81_user_case�s	
cC�sx|j�}|jd|dd�}|jd|dd�}|j||�|jd|dd�}|j||�dS(stest user used as saltR[R�tadmintrootN(RMRLR�Ra(ReR*R�R�th3((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyttest_82_user_salt�scC�sQt|t�r|\}}n|js+|S|j}d|krM||d<n|S(sinsert username into kwdsR�(R\R�R�R�(ReR(RYR�((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR>�s		
RcB�s?eZejjj�Zejdd�ed�Zd�Z	RS(R�trandom_usert	asdQWE123cC�sK|j}|jjr,|j�dkr,dSt||j|jdd��S(Ng�������?ii
(RR!R�R�R*Rt
user_alphabetRS(ReR((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��s	(
R�R�R#RRLtcopyR?RR�R�(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�s(R�R�R�R�R>R�R=R�t _UserHandlerMixin__unittest_skipR�R�R�R>R#R(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��s				tEncodingHandlerMixincB�sQeZdZeZed�ded�gZdejfd��YZd�Z	RS(s helper for handlers w/ 'encoding' context kwd; mixin for HandlerCase

    this overrides the HandlerCase test harness methods
    so that an encoding can be inserted to hash/verify
    calls by passing in a pair of strings as the password
    will be interpreted as (secret,encoding)
    R!s\u00AC\u00BARcB�seZed�ZRS(sqwerty1234<>.@*#! \u00AC(R�R�RRU(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR
scC�s2t|t�r.|\}}|jd|�n|S(sinsert encoding into kwdsR(R\R�t
setdefault(ReR(RYR((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR>
s(
R�R�R�R>t$_EncodingHandlerMixin__unittest_skipRR_R#RR>(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR��s	R�cB�s/eZdZddd�Zd�Zd�ZRS(s@catch_warnings() wrapper which clears warning registry & filterstalwayss.*cK�sAtt|�j|�||_|r4tj|�nd|_dS(N(R�R�R�t
_reset_filterRxtcompileR*t_reset_registry(Retreset_filtertreset_registryRY((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�
s	cC�s�tt|�j�}|jr;tj�tj|j�n|j}|r�i}|_x}t	t
jj��D]c\}}|dksm|j|�r�qmnt|dd�}|rm|j�||<|j�qmqmWn|S(Nt__warningregistry__(R�R�R�R�R�t
resetwarningstsimplefilterR�t_orig_registryR�RwtmodulesR�R*RYR�R�tclear(ReRjRztbackupR�Rltreg((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�
s	
	
"cG�s�|j}|r�|j}x�ttjj��D]�\}}|dks.|j|�r\q.nt|dd�}|r�|j	�n|j
|�}|r.|dkr�t|d|�q�|j|�q.q.Wnt
t|�j|�dS(NR�(R�R�R�RwR�R�R*RYR�R�R�RR?R�R�R�(ReR�RzR�R�RlR�RP((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�3
s		"
(R�R�R�R�R�R�(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyR�
s	(kR�t
__future__RtbinasciiRt
contextlibt	functoolsRRR�tloggingt	getLoggerR�R�R�RxR$RwRRR'R�RRRRRR�RtpasslibR	R
tpasslib.registrytregistrytpasslib.tests.backportsRt	_TestCaseRR
RRR�RRRRR�RRRRRRRRRRRtpasslib.utils.decorRtpasslib.utils.handlersRjRUREt__all__tgoogle.appenginetgoogletImportErrorR=R�R>R,R5tTICK_RESOLUTIONR;R<R�R�tstripR|R:R*R RHRLRQRWRZRKRctcontextmanagerRiR!R"RvRzR~R�R�R�RiR#RPR�R�RR�(((s7/usr/lib/python2.7/site-packages/passlib/tests/utils.pyt<module>s�(F(		

								!						�t���������	�a&