o
    +ke5                     @   s   d dl Z d dlZd dlmZmZ d dlmZ d dlZddl	m
Z
 ddlmZmZ ddlmZmZmZmZmZmZmZmZmZmZmZ dZd	Zd
ZdZe dd ZG dd dZe dd Z G dd dZ!G dd dZ"e dd Z#G dd dZ$dS )    N)ThreadLock)
format_exc   )	daemonize)get_process_idprocess_alive)TimeoutTimerExclusiveLockr   
LockRosterADDREMOVESHARED	EXCLUSIVELockTimeout	NotLocked	NotMyLock)Zfoo   r   )Zbarr   r   (   g?c                  C   s,   t  \} }}	 tdd}t| ||s|S q)zBReturn a free PID not used by any process (naturally this is racy)Ti  i  )r   randomrandintr   )hostpidtid r   :usr/lib/python3.10/site-packages/borg/testsuite/locking.pyfree_pid   s   r   c                   @   s   e Zd Zdd Zdd ZdS )TestTimeoutTimerc                 C   s:   d}t | }| rJ t|d  | sJ d S )N      ?g      ?)r	   start	timed_outtimesleep)selftimeouttr   r   r   test_timeout   s
   zTestTimeoutTimer.test_timeoutc                 C   sf   d\}}t || }| rJ t |jd|  ksJ | r$J t |jd|  ks1J d S )N)Nr   r   r   )r	   r   Ztimed_out_or_sleepr!   Z
start_time)r#   r$   r"   r%   r   r   r   test_notimeout_sleep&   s   z%TestTimeoutTimer.test_notimeout_sleepN)__name__
__module____qualname__r&   r'   r   r   r   r   r      s    r   c                 C      t | dS )NlockstrjoinZtmpdirr   r   r   lockpath/      r1   c                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )TestExclusiveLockc                 C   sF   t |dd}| r| sJ W d    d S 1 sw   Y  d S )Nr   )r$   )r
   Z	is_lockedby_mer#   r1   r,   r   r   r   test_checks5   s   "zTestExclusiveLock.test_checksc                 C   sJ   t |td }|  t |td	 W d    d S 1 sw   Y  d S Nid)r
   ID1acquire
break_lockID2r5   r   r   r   test_acquire_break_reacquire9   s
   "z.TestExclusiveLock.test_acquire_break_reacquirec              	   C   s~   t |td/ tt t |tdd  W d    n1 s w   Y  W d    d S W d    d S 1 s8w   Y  d S )Nr8   皙?r9   r$   )r
   r:   pytestraisesr   r=   r;   r#   r1   r   r   r   r&   ?   s   "zTestExclusiveLock.test_timeoutc           
   	   C   s<  t   \}}}}|||f}d}t||d }	t||d! tt |	  W d    n1 s2w   Y  W d    n1 sAw   Y  tt |	  W d    n1 sZw   Y  t||d/ tt t||dd  W d    n1 sw   Y  W d    d S W d    d S 1 sw   Y  d S )Nzfoo.bar.example.netr   r   r8   r?   r@   )	r   r
   r;   rA   rB   r   releaser   r   )
r#   r1   r   r   r   r   our_iddead_idcant_know_if_dead_id	dead_lockr   r   r   test_kill_staleD   s(   


"z!TestExclusiveLock.test_kill_stalec                 C   s   t t}}|d |d ksJ t||d }|j|ksJ |j}| s'J ||| |j|ks4J |j}| s=J ||ksCJ d S Nr   r8   )r:   r=   r
   r;   r9   Zunique_namer4   migrate_lock)r#   r1   old_idnew_idr,   Zold_unique_nameZnew_unique_namer   r   r   test_migrate_lockT   s   
z#TestExclusiveLock.test_migrate_lockc           
   
      s   G dd d}fddd fdd	}t d | }| }t d }d\}}ttD ]}	t||||	ft|	|||fd	}|  q,|  | d
ksQJ d| dks_J d|  |	 d
ksmJ d|	  d S )Nc                   @   s6   e Zd ZdddZdd Zdd Zdd	 Zd
d ZdS )zBTestExclusiveLock.test_race_condition.<locals>.SynchronizedCounterr   c                 S   s   t  | _|| _|| _d S N)ThreadingLockr,   countmaxcount)r#   rR   r   r   r   __init__e   s   
zKTestExclusiveLock.test_race_condition.<locals>.SynchronizedCounter.__init__c                 S   0   | j  | jW  d    S 1 sw   Y  d S rP   r,   rR   r#   r   r   r   valuej      $zHTestExclusiveLock.test_race_condition.<locals>.SynchronizedCounter.valuec                 S   rU   rP   )r,   rS   rW   r   r   r   maxvaluen   rY   zKTestExclusiveLock.test_race_condition.<locals>.SynchronizedCounter.maxvaluec                 S   sR   | j  |  jd7  _| j| jkr| j| _| jW  d    S 1 s"w   Y  d S Nr   )r,   rR   rS   rW   r   r   r   incrr   s   $zGTestExclusiveLock.test_race_condition.<locals>.SynchronizedCounter.incrc                 S   s>   | j  |  jd8  _| jW  d    S 1 sw   Y  d S r[   rV   rW   r   r   r   decry   s   $zGTestExclusiveLock.test_race_condition.<locals>.SynchronizedCounter.decrN)r   )r(   r)   r*   rT   rX   rZ   r\   r]   r   r   r   r   SynchronizedCounterc   s    
r^   c                    s2     t |  W d    d S 1 sw   Y  d S rP   )print)msg)
print_lockr   r   print_locked~   s   
"z;TestExclusiveLock.test_race_condition.<locals>.print_lockedc              	      s(  d|| | f  t |d }d}| s|d7 }z;t | |d dd' | }	d|||	f  td | }	d	|||	f  W d    n1 sPw   Y  W n% tyg   d
||f  Y n   | }
t	 }d|||
|f  Y | rd||f  |d ur|
  d S d S )NzIThread %2d: Starting acquire_release_loop(id=%s, timeout=%d); lockpath=%sr   r      )r9   r$   r"   zbThread %2d: Acquired the lock. It's my %d. loop cycle. I am the %d. who has the lock concurrently.g{Gzt?zjThread %2d: Releasing the lock, finishing my %d. loop cycle. Currently, %d colleagues still have the lock.z9Thread %2d: Got LockTimeout, finishing my %d. loop cycle.zdThread %2d: Exception thrown, finishing my %d. loop cycle. It's the %d. exception seen until now: %sz=Thread %2d: Loop timed out--terminating after %d loop cycles.)r	   r   r    r
   r\   r!   r"   r]   r   r   r/   )r9   r$   	thread_idlock_owner_counterexception_counterra   Zlast_threadZtimercycleZlock_owner_countZexception_counte)r1   rb   r   r   acquire_release_loop   s2   
zCTestExclusiveLock.test_race_condition.<locals>.acquire_release_loop )Zdifferenthosti  )targetargsr   z3Never gained the lock? Something went wrong here...r   zKMaximal number of concurrent lock holders was %d. So exclusivity is broken.zFExclusiveLock threw %d exceptions due to unclean concurrency handling.rP   )
r_   rQ   rangeRACE_TEST_NUM_THREADSr   RACE_TEST_DURATIONr   r/   rZ   rX   )
r#   r1   r^   rj   rf   rg   threadZhost_idZ
process_idre   r   )r1   ra   rb   r   test_race_conditiona   s(   
 z%TestExclusiveLock.test_race_conditionN)	r(   r)   r*   r6   r>   r&   rJ   rO   rr   r   r   r   r   r3   4   s    r3   c                   @   sT   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdS )TestLockc                 C   s   t |dtd }t |dtd }t|jtdksJ t|jtdks*J |j	ttr3J |j	ts;J |
  |
  d S )NF	exclusiver9   r   r   )r   r:   r;   r=   len_rostergetr   r   emptyrE   )r#   r1   Zlock1Zlock2r   r   r   test_shared   s   zTestLock.test_sharedc                 C   sv   t |dtd*}t|jtdksJ t|jtdks J |jttr)J W d    d S 1 s4w   Y  d S )NTrt   r   r   )r   r:   rv   rw   rx   r   r   ry   r5   r   r   r   test_exclusive   s
   "zTestLock.test_exclusivec                 C   s   t |dd2}|  |  t|jtdksJ t|jtdks'J |jttr0J W d    d S 1 s;w   Y  d S )NFru   r   r   )r   upgraderv   rw   rx   r   r   ry   r5   r   r   r   test_upgrade   s   "zTestLock.test_upgradec                 C   sr   t |dd)}|  |  t|jtdksJ t|jtdks'J W d    d S 1 s2w   Y  d S )NTr|   r   r   )r   Z	downgraderv   rw   rx   r   r   r5   r   r   r   test_downgrade   s   "zTestLock.test_downgradec                 C   sF   t |dtd}| rJ |  | sJ |  | r!J d S )NTrt   )r   r:   Zgot_exclusive_lockr;   rE   r5   r   r   r   test_got_exclusive_lock   s   z TestLock.test_got_exclusive_lockc                 C   s~   t |dtd }|  t|jtdksJ t|jtdks%J t |dt	d	 W d    d S 1 s8w   Y  d S )NTrt   r   )
r   r:   r;   r<   rv   rw   rx   r   r   r=   r5   r   r   r   
test_break   s   "zTestLock.test_breakc              	   C   sZ  t |dtd' tt t |dtdd  W d    n1 s"w   Y  W d    n1 s1w   Y  t |dtd' tt t |dtdd  W d    n1 sXw   Y  W d    n1 sgw   Y  t |dtd0 tt t |dtdd  W d    n1 sw   Y  W d    d S W d    d S 1 sw   Y  d S )NFrt   Tr?   )ru   r9   r$   )r   r:   rA   rB   r   r=   r;   rC   r   r   r   r&      s&   "zTestLock.test_timeoutc              	   C   sd  t   \}}}}|||f}d}t||dd }	|	j}
t||d |
tt ks,J |
t|hks6J W d    n1 s@w   Y  |
tt ksOJ |
tt ksYJ t	t
 |	  W d    n1 smw   Y  t||dd/ t	t t||dd  W d    n1 sw   Y  W d    d S W d    d S 1 sw   Y  d S )NrD   Tr9   ru   r8   r?   r@   )r   r   r;   rw   rx   r   setr   rA   rB   r   rE   r   )r#   r1   r   r   r   r   rF   rG   rH   rI   rosterr   r   r   rJ      s*   

"zTestLock.test_kill_stalec                 C   s   t t}}|d |d ksJ t||dd }|j|ksJ ||| |j|ks,J |  t||dd }|j|ks@J ||| |j|ksMJ |  d S )Nr   Tr   F)r:   r=   r   r;   r9   rL   rE   )r#   r1   rM   rN   r,   r   r   r   rO      s   
zTestLock.test_migrate_lockN)r(   r)   r*   rz   r{   r~   r   r   r   r&   rJ   rO   r   r   r   r   rs      s    
rs   c                 C   r+   )Nr   r-   r0   r   r   r   
rosterpath  r2   r   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
TestLockRosterc                 C   s*   t |}| }|| |i ksJ d S rP   )r   loadsave)r#   r   r   ry   r   r   r   
test_empty  s   
zTestLockRoster.test_emptyc                 C   s   t |td}|tt ksJ |tt |tthks J t |td}|tt |ttthks7J t |td}|tt |tthksMJ t |td}|tt |tt kscJ d S r7   )	r   r:   rx   r   r   modifyr   r=   r   )r#   r   roster1Zroster2r   r   r   test_modify_get  s   zTestLockRoster.test_modify_getc                 C   s  t   \}}}}|||f}t||d}d|_|tt ks J |tt |t|hks0J d}	t||	d}d|_|t|hksEJ |tt |t||	hksVJ t|}
|
t|	hksdJ |
tt |
t||	hksuJ t|}|t||	hksJ d S )Nr8   FrD   )r   r   Zkill_stale_locksrx   r   r   r   r   )r#   r   r   r   r   r   rF   rG   r   rH   Zkiller_rosterZother_killer_rosterr   r   r   rJ   '  s&   
zTestLockRoster.test_kill_stalec                 C   s   t t}}|d |d ksJ t||d}|j|ksJ |tt |t|hks,J |t|| |j|ks:J |t|hksDJ d S rK   )	r:   r=   r   r9   r   r   r   rx   rL   )r#   r   rM   rN   r   r   r   r   rO   D  s   
z TestLockRoster.test_migrate_lockN)r(   r)   r*   r   r   rJ   rO   r   r   r   r   r     s
    r   )%r   r!   	threadingr   r   rQ   	tracebackr   rA   helpersr   platformr   r   Zlockingr	   r
   r   r   r   r   r   r   r   r   r:   r=   ro   rp   Zfixturer   r   r1   r3   rs   r   r   r   r   r   r   <module>   s,    4


y_
