@@ -112,20 +112,35 @@ def check_endpoint_lifecycle():
112112 ep .libDestroy ()
113113
114114
115- def check_sip_registration (registrar : str , user : str , password : str ,
116- domain : str , timeout : int = 20 ):
115+ def check_sip_register_unregister (registrar : str , user : str , password : str ,
116+ domain : str , timeout : int = 30 ):
117+ """Register then explicitly unregister, verifying both callbacks fire."""
117118 import pjsua2
118119
119- result : dict = {"ok" : False , "code" : None , "reason" : "" }
120- done = threading .Event ()
120+ reg_result : dict = {"ok" : False , "code" : None , "reason" : "" }
121+ unreg_result : dict = {"ok" : False , "code" : None , "reason" : "" }
122+ reg_done = threading .Event ()
123+ unreg_done = threading .Event ()
121124
122125 class _Account (pjsua2 .Account ):
123126 def onRegState (self , prm ):
124- result ["code" ] = prm .code
125- result ["reason" ] = prm .reason
126- if prm .code // 100 == 2 :
127- result ["ok" ] = True
128- done .set ()
127+ code = prm .code
128+ reason = prm .reason
129+ expiry = prm .expiration
130+ if not reg_done .is_set ():
131+ # First callback → registration response
132+ reg_result ["code" ] = code
133+ reg_result ["reason" ] = reason
134+ if code // 100 == 2 and expiry > 0 :
135+ reg_result ["ok" ] = True
136+ reg_done .set ()
137+ else :
138+ # Second callback → unregistration response (expiry == 0)
139+ unreg_result ["code" ] = code
140+ unreg_result ["reason" ] = reason
141+ if code // 100 == 2 and expiry == 0 :
142+ unreg_result ["ok" ] = True
143+ unreg_done .set ()
129144
130145 ep = pjsua2 .Endpoint ()
131146 cfg = pjsua2 .EpConfig ()
@@ -147,17 +162,36 @@ def onRegState(self, prm):
147162 acc_cfg .sipConfig .authCreds .append (cred )
148163 acc .create (acc_cfg )
149164
150- fired = done .wait (timeout = timeout )
151- acc .delete ()
152- ep .libDestroy ()
153-
154- if not fired :
165+ # --- Wait for REGISTER 200 OK ---
166+ if not reg_done .wait (timeout = timeout ):
167+ acc .delete ()
168+ ep .libDestroy ()
155169 raise AssertionError (
156170 f"SIP registration timed out after { timeout } s (no response from { registrar } )"
157171 )
158- if not result ["ok" ]:
172+ if not reg_result ["ok" ]:
173+ acc .delete ()
174+ ep .libDestroy ()
175+ raise AssertionError (
176+ f"SIP registration failed: { reg_result ['code' ]} { reg_result ['reason' ]} "
177+ )
178+
179+ # --- Send REGISTER with Expires: 0 (unregister) ---
180+ acc .setRegistration (False )
181+
182+ if not unreg_done .wait (timeout = timeout ):
183+ acc .delete ()
184+ ep .libDestroy ()
185+ raise AssertionError (
186+ f"SIP unregistration timed out after { timeout } s"
187+ )
188+
189+ acc .delete ()
190+ ep .libDestroy ()
191+
192+ if not unreg_result ["ok" ]:
159193 raise AssertionError (
160- f"SIP registration failed: { result ['code' ]} { result ['reason' ]} "
194+ f"SIP unregistration failed: { unreg_result ['code' ]} { unreg_result ['reason' ]} "
161195 )
162196
163197
@@ -211,18 +245,19 @@ def run(label: str, fn):
211245 run ("module attributes" , lambda : f"{ check_modules (pjsua2_mod )} attrs" )
212246 run ("endpoint lifecycle" , check_endpoint_lifecycle )
213247
214- sip_creds = (args .sip_registrar , args .sip_user ,
215- args .sip_password , args .sip_domain )
248+ # Domain defaults to registrar host when not specified separately
249+ sip_domain = args .sip_domain or args .sip_registrar
250+ sip_creds = (args .sip_registrar , args .sip_user , args .sip_password , sip_domain )
216251 if all (sip_creds ):
217252 run (
218- f"SIP registration ({ args .sip_user } @{ args . sip_domain } )" ,
219- lambda : check_sip_registration (
253+ f"SIP register+unregister ({ args .sip_user } @{ sip_domain } )" ,
254+ lambda : check_sip_register_unregister (
220255 args .sip_registrar , args .sip_user ,
221- args .sip_password , args . sip_domain ,
256+ args .sip_password , sip_domain ,
222257 ),
223258 )
224259 else :
225- print (" SIP registration ... SKIP (set SIP_* secrets to enable)" )
260+ print (" SIP register+unregister ... SKIP (set SIP_* vars to enable)" )
226261
227262 print ("=" * 60 )
228263 print (f"Results: { passed } passed, { failed } failed" )
0 commit comments