Commit 5d52e1fc authored by Kirill Smelkov's avatar Kirill Smelkov

py2: *: Use dummy placeholder instead of nonlocal

nonlocal is not supported on python2.

In kpi_test.py we call Measurement.__init__() directly to remove the
need for `mlog = ...` reassignment.
parent 80114cf1
...@@ -662,20 +662,23 @@ def __repr__(s): ...@@ -662,20 +662,23 @@ def __repr__(s):
def _x_stats_srv(ctx, reqch, conn): def _x_stats_srv(ctx, reqch, conn):
dt_rate = 10*tti dt_rate = 10*tti
class X: pass
x = X()
# rx_ue_get_stats sends `ue_get[stats]` request and returns server response. # rx_ue_get_stats sends `ue_get[stats]` request and returns server response.
rtt_ue_stats = _IncStats() # time it takes to send ue_get and to receive response x.rtt_ue_stats = _IncStats() # time it takes to send ue_get and to receive response
dt_ue_stats = _IncStats() # δ(ue_stats.timestamp) x.dt_ue_stats = _IncStats() # δ(ue_stats.timestamp)
t_ue_stats = None # last ue_stats.timestamp x.t_ue_stats = None # last ue_stats.timestamp
def rx_ue_get_stats(ctx): # -> ue_stats def rx_ue_get_stats(ctx): # -> ue_stats
nonlocal t_ue_stats #nonlocal t_ue_stats
t_tx = time.now() t_tx = time.now()
ue_stats = conn.req(ctx, 'ue_get', {'stats': True}) ue_stats = conn.req(ctx, 'ue_get', {'stats': True})
t_rx = time.now() t_rx = time.now()
rtt_ue_stats.add(t_rx-t_tx) x.rtt_ue_stats.add(t_rx-t_tx)
t = ue_stats['utc'] t = ue_stats['utc']
if t_ue_stats is not None: if x.t_ue_stats is not None:
dt_ue_stats.add(t-t_ue_stats) x.dt_ue_stats.add(t-x.t_ue_stats)
t_ue_stats = t x.t_ue_stats = t
return ue_stats return ue_stats
# rx_stats sends `stats` request and returns server response. # rx_stats sends `stats` request and returns server response.
...@@ -686,19 +689,19 @@ def _x_stats_srv(ctx, reqch, conn): ...@@ -686,19 +689,19 @@ def _x_stats_srv(ctx, reqch, conn):
# we can retrieve both ue_get and stats each at 100Hz simultaneously. # we can retrieve both ue_get and stats each at 100Hz simultaneously.
conn_stats = amari.connect(ctx, conn.wsuri) conn_stats = amari.connect(ctx, conn.wsuri)
defer(conn_stats.close) defer(conn_stats.close)
rtt_stats = _IncStats() # like rtt_ue_stats but for stat instead of ue_get x.rtt_stats = _IncStats() # like rtt_ue_stats but for stat instead of ue_get
dt_stats = _IncStats() # δ(stats.timestamp) x.dt_stats = _IncStats() # δ(stats.timestamp)
t_stats = None # last stats.timestamp x.t_stats = None # last stats.timestamp
def rx_stats(ctx): # -> stats def rx_stats(ctx): # -> stats
nonlocal t_stats #nonlocal t_stats
t_tx = time.now() t_tx = time.now()
stats = conn_stats.req(ctx, 'stats', {}) stats = conn_stats.req(ctx, 'stats', {})
t_rx = time.now() t_rx = time.now()
rtt_stats.add(t_rx-t_tx) x.rtt_stats.add(t_rx-t_tx)
t = stats['utc'] t = stats['utc']
if t_stats is not None: if x.t_stats is not None:
dt_stats.add(t-t_stats) x.dt_stats.add(t-x.t_stats)
t_stats = t x.t_stats = t
return stats return stats
# issue first dummy stats. It won't report most of statistics due to # issue first dummy stats. It won't report most of statistics due to
# initial_delay=0, but it will make the next stats query avoid pausing for 0.4s. # initial_delay=0, but it will make the next stats query avoid pausing for 0.4s.
...@@ -706,7 +709,7 @@ def _x_stats_srv(ctx, reqch, conn): ...@@ -706,7 +709,7 @@ def _x_stats_srv(ctx, reqch, conn):
# rx_all simultaneously issues `ue_get[stats]` and `stats` requests and returns server responses. # rx_all simultaneously issues `ue_get[stats]` and `stats` requests and returns server responses.
# the requests are issued synchronized in time. # the requests are issued synchronized in time.
d_ue_stats = _IncStats() # ue_stats.timestamp - stats.timestamp x.d_ue_stats = _IncStats() # ue_stats.timestamp - stats.timestamp
def rx_all(ctx): # -> ue_stats, stats def rx_all(ctx): # -> ue_stats, stats
uq = chan(1) uq = chan(1)
sq = chan(1) sq = chan(1)
...@@ -741,7 +744,7 @@ def _x_stats_srv(ctx, reqch, conn): ...@@ -741,7 +744,7 @@ def _x_stats_srv(ctx, reqch, conn):
stats = _rx stats = _rx
sq = nilchan sq = nilchan
d_ue_stats.add(ue_stats['utc'] - stats['utc']) x.d_ue_stats.add(ue_stats['utc'] - stats['utc'])
return ue_stats, stats return ue_stats, stats
ueget_reqch = chan() ueget_reqch = chan()
...@@ -774,9 +777,9 @@ def _x_stats_srv(ctx, reqch, conn): ...@@ -774,9 +777,9 @@ def _x_stats_srv(ctx, reqch, conn):
# Tmain is the main thread that drives the process overall # Tmain is the main thread that drives the process overall
def Tmain(ctx): def Tmain(ctx):
nonlocal rtt_ue_stats, dt_ue_stats #nonlocal rtt_ue_stats, dt_ue_stats
nonlocal rtt_stats, dt_stats #nonlocal rtt_stats, dt_stats
nonlocal d_ue_stats #nonlocal d_ue_stats
t_req = time.now() t_req = time.now()
ue_stats, stats = rx_all(ctx) ue_stats, stats = rx_all(ctx)
...@@ -846,11 +849,11 @@ def _x_stats_srv(ctx, reqch, conn): ...@@ -846,11 +849,11 @@ def _x_stats_srv(ctx, reqch, conn):
account(qci_Sul, qci_ul) account(qci_Sul, qci_ul)
_debug() _debug()
_debug('rtt_ue: %s ms' % rtt_ue_stats .str('%.2f', time.millisecond)) _debug('rtt_ue: %s ms' % x.rtt_ue_stats .str('%.2f', time.millisecond))
_debug('dt_ue: %s ms' % dt_ue_stats .str('%.2f', time.millisecond)) _debug('dt_ue: %s ms' % x.dt_ue_stats .str('%.2f', time.millisecond))
_debug('rtt_stats: %s ms' % rtt_stats .str('%.2f', time.millisecond)) _debug('rtt_stats: %s ms' % x.rtt_stats .str('%.2f', time.millisecond))
_debug('dt_stats: %s ms' % dt_stats .str('%.2f', time.millisecond)) _debug('dt_stats: %s ms' % x.dt_stats .str('%.2f', time.millisecond))
_debug('δ(ue,stat): %s ms' % d_ue_stats .str('%.2f', time.millisecond)) _debug('δ(ue,stat): %s ms' % x.d_ue_stats .str('%.2f', time.millisecond))
qci_dict = {} qci_dict = {}
S0 = _S() S0 = _S()
...@@ -876,16 +879,16 @@ def _x_stats_srv(ctx, reqch, conn): ...@@ -876,16 +879,16 @@ def _x_stats_srv(ctx, reqch, conn):
'utc': ue_stats['utc'], 'utc': ue_stats['utc'],
'qci_dict': qci_dict, 'qci_dict': qci_dict,
'dt_ueget': { 'dt_ueget': {
'min': dt_ue_stats.min, 'min': x.dt_ue_stats.min,
'avg': dt_ue_stats.avg(), 'avg': x.dt_ue_stats.avg(),
'max': dt_ue_stats.max, 'max': x.dt_ue_stats.max,
'std': dt_ue_stats.std(), 'std': x.dt_ue_stats.std(),
}, },
'δ_ueget_vs_stats': { 'δ_ueget_vs_stats': {
'min': d_ue_stats.min, 'min': x.d_ue_stats.min,
'avg': d_ue_stats.avg(), 'avg': x.d_ue_stats.avg(),
'max': d_ue_stats.max, 'max': x.d_ue_stats.max,
'std': d_ue_stats.std(), 'std': x.d_ue_stats.std(),
}, },
} }
...@@ -895,11 +898,11 @@ def _x_stats_srv(ctx, reqch, conn): ...@@ -895,11 +898,11 @@ def _x_stats_srv(ctx, reqch, conn):
qci_Sdl = {} qci_Sdl = {}
qci_Sul = {} qci_Sul = {}
rtt_ue_stats = _IncStats() x.rtt_ue_stats = _IncStats()
dt_ue_stats = _IncStats() x.dt_ue_stats = _IncStats()
rtt_stats = _IncStats() x.rtt_stats = _IncStats()
dt_stats = _IncStats() x.dt_stats = _IncStats()
d_ue_stats = _IncStats() x.d_ue_stats = _IncStats()
# sync time to keep t_req' - t_req ≈ dt_rate # sync time to keep t_req' - t_req ≈ dt_rate
# this should automatically translate to dt(ue_stats) ≈ dt_rate # this should automatically translate to dt(ue_stats) ≈ dt_rate
......
...@@ -148,6 +148,8 @@ def test_LogMeasure(): ...@@ -148,6 +148,8 @@ def test_LogMeasure():
t.expect_nodata() t.expect_nodata()
# note: no t.read() - see tstats # note: no t.read() - see tstats
class X: pass
x = X()
# tstats is the verb to check handling of stats message. # tstats is the verb to check handling of stats message.
# #
...@@ -169,23 +171,23 @@ def test_LogMeasure(): ...@@ -169,23 +171,23 @@ def test_LogMeasure():
# _(...) # verify effect on Measurements returned with period # _(...) # verify effect on Measurements returned with period
# _(...) # ending by timestamp of the above stats call. # _(...) # ending by timestamp of the above stats call.
# _(...) # i.e. Measurement₁ if tstats call corresponds to xlog₂. # _(...) # i.e. Measurement₁ if tstats call corresponds to xlog₂.
tau_xlog = 1 # timestamp of last emitted xlog entry x.tau_xlog = 1 # timestamp of last emitted xlog entry
tau_logm = tau_xlog-2+1 # timestamp of next measurement to be read from logm x.tau_logm = x.tau_xlog-2+1 # timestamp of next measurement to be read from logm
counters_prev = {} x.counters_prev = {}
def tstats(counters): def tstats(counters):
nonlocal tau_xlog, tau_logm, counters_prev #nonlocal tau_xlog, tau_logm, counters_prev
trace('\n>>> tstats tau_xlog: %s tau_logm: %s' % (tau_xlog, tau_logm)) trace('\n>>> tstats tau_xlog: %s tau_logm: %s' % (x.tau_xlog, x.tau_logm))
t.xlog( jstats(tau_xlog+1, counters) ) # xlog tau+1 t.xlog( jstats(x.tau_xlog+1, counters) ) # xlog tau+1
t.read() # read+assert M for tau-1 t.read() # read+assert M for tau-1
_('X.Tstart', tau_logm+1) # start preparing next expected M at tau _('X.Tstart', x.tau_logm+1) # start preparing next expected M at tau
_('X.δT', 1) _('X.δT', 1)
tau_xlog += 1 x.tau_xlog += 1
tau_logm += 1 x.tau_logm += 1
counters_prev = counters x.counters_prev = counters
# tdstats is like tstats but takes delta for counters. # tdstats is like tstats but takes delta for counters.
def tdstats(dcounters): def tdstats(dcounters):
counters = counters_prev.copy() counters = x.counters_prev.copy()
for k,dv in dcounters.items(): for k,dv in dcounters.items():
counters[k] = counters.get(k,0) + dv counters[k] = counters.get(k,0) + dv
tstats(counters) tstats(counters)
...@@ -193,15 +195,15 @@ def test_LogMeasure(): ...@@ -193,15 +195,15 @@ def test_LogMeasure():
# tevent is the verb to verify handling of events. # tevent is the verb to verify handling of events.
# its logic is similar to tstats. # its logic is similar to tstats.
def tevent(event): def tevent(event):
nonlocal tau_xlog, tau_logm, counters_prev #nonlocal tau_xlog, tau_logm, counters_prev
trace('\n>>> tstats tau_xlog: %s tau_logm: %s' % (tau_xlog, tau_logm)) trace('\n>>> tstats tau_xlog: %s tau_logm: %s' % (x.tau_xlog, x.tau_logm))
t.xlog(json.dumps({"meta": {"event": event, "time": tau_xlog+1}})) t.xlog(json.dumps({"meta": {"event": event, "time": x.tau_xlog+1}}))
t.read() t.read()
_('X.Tstart', tau_logm+1) _('X.Tstart', x.tau_logm+1)
_('X.δT', 1) _('X.δT', 1)
tau_xlog += 1 x.tau_xlog += 1
tau_logm += 1 x.tau_logm += 1
counters_prev = {} # reset x.counters_prev = {} # reset
# tdrb_stats is the verb to verify handling of x.drb_stats message. # tdrb_stats is the verb to verify handling of x.drb_stats message.
# #
...@@ -209,10 +211,10 @@ def test_LogMeasure(): ...@@ -209,10 +211,10 @@ def test_LogMeasure():
# next (dtau < 0) stats or event. # next (dtau < 0) stats or event.
def tdrb_stats(dtau, qci_trx): def tdrb_stats(dtau, qci_trx):
if dtau >= 0: if dtau >= 0:
tau = tau_xlog + dtau # after previous stats or event tau = x.tau_xlog + dtau # after previous stats or event
else: else:
tau = tau_xlog+1 + dtau # before next stats or event tau = x.tau_xlog+1 + dtau # before next stats or event
trace('\n>>> tdrb_stats tau: %s tau_xlog: %s tau_logm: %s' % (tau, tau_xlog, tau_logm)) trace('\n>>> tdrb_stats tau: %s tau_xlog: %s tau_logm: %s' % (tau, x.tau_xlog, x.tau_logm))
t.xlog( jdrb_stats(tau, qci_trx) ) t.xlog( jdrb_stats(tau, qci_trx) )
...@@ -379,10 +381,10 @@ def test_LogMeasure(): ...@@ -379,10 +381,10 @@ def test_LogMeasure():
t.expect_nodata() t.expect_nodata()
t.read() # LogMeasure flushes its queue on "service detach". t.read() # LogMeasure flushes its queue on "service detach".
_('X.Tstart', tau_logm+1) # After the flush t.read will need to go only 1 step behind _('X.Tstart', x.tau_logm+1) # After the flush t.read will need to go only 1 step behind
_('X.δT', 1) # corresponding t.xlog call instead of previously going 2 steps beyond. _('X.δT', 1) # corresponding t.xlog call instead of previously going 2 steps beyond.
t.expect_nodata() # Do one t.read step manually to catch up. t.expect_nodata() # Do one t.read step manually to catch up.
tau_logm += 1 x.tau_logm += 1
tevent("service connect failure") tevent("service connect failure")
t.expect_nodata() t.expect_nodata()
...@@ -397,8 +399,8 @@ def test_LogMeasure(): ...@@ -397,8 +399,8 @@ def test_LogMeasure():
tevent("service attach") tevent("service attach")
t.expect_nodata() t.expect_nodata()
t.xlog( jstats(tau_xlog+1, {i:1000, f:1000}) ) # LogMeasure restarts the queue after data starts to t.xlog( jstats(x.tau_xlog+1, {i:1000, f:1000}) ) # LogMeasure restarts the queue after data starts to
tau_xlog += 1 # come in again. Do one t.xlog step manually to x.tau_xlog += 1 # come in again. Do one t.xlog step manually to
# increase t.read - t.xlog distance back to 2. # increase t.read - t.xlog distance back to 2.
tstats({i:1000+2, f:1000+2}) tstats({i:1000+2, f:1000+2})
_(I, 2) # no "extra" events even if counters start with jumped values after reattach _(I, 2) # no "extra" events even if counters start with jumped values after reattach
......
...@@ -204,11 +204,14 @@ def test_Reader_timestamp_from_sync_wo_utc(): ...@@ -204,11 +204,14 @@ def test_Reader_timestamp_from_sync_wo_utc():
return json.dumps({"message": msg, "time": srv_time}) return json.dumps({"message": msg, "time": srv_time})
assert jmsg(123.4, "aaa") == '{"message": "aaa", "time": 123.4}' assert jmsg(123.4, "aaa") == '{"message": "aaa", "time": 123.4}'
data = b"" class X: pass
x = X()
x.data = b""
def _(line): def _(line):
nonlocal data #nonlocal data
assert '\n' not in line assert '\n' not in line
data += b(line+'\n') x.data += b(line+'\n')
A = "service attach" A = "service attach"
D = "service detach" D = "service detach"
...@@ -248,8 +251,8 @@ def test_Reader_timestamp_from_sync_wo_utc(): ...@@ -248,8 +251,8 @@ def test_Reader_timestamp_from_sync_wo_utc():
assert _.timestamp == timestamp assert _.timestamp == timestamp
xr = xlog.Reader(io.BytesIO(data)) xr = xlog.Reader(io.BytesIO(x.data))
br = xlog.Reader(io.BytesIO(data), reverse=True) br = xlog.Reader(io.BytesIO(x.data), reverse=True)
defer(xr.close) defer(xr.close)
defer(br.close) defer(br.close)
...@@ -281,7 +284,7 @@ def test_Reader_timestamp_from_sync_wo_utc(): ...@@ -281,7 +284,7 @@ def test_Reader_timestamp_from_sync_wo_utc():
_( jsync(1012, 12) ) _( jsync(1012, 12) )
_( jmsg(13, "hhh") ) _( jmsg(13, "hhh") )
_( jmsg(14, "iii") ) _( jmsg(14, "iii") )
bb = xlog.Reader(io.BytesIO(data), reverse=True) bb = xlog.Reader(io.BytesIO(x.data), reverse=True)
defer(bb.close) defer(bb.close)
expect_msg (bb, 1014, "iii") expect_msg (bb, 1014, "iii")
expect_msg (bb, 1013, "hhh") expect_msg (bb, 1013, "hhh")
......
...@@ -287,8 +287,9 @@ def test_Calc_success_rate(): ...@@ -287,8 +287,9 @@ def test_Calc_success_rate():
# Mlog reinitializes mlog according to specified Measurements in mv. # Mlog reinitializes mlog according to specified Measurements in mv.
def Mlog(*mv): def Mlog(*mv):
nonlocal mlog #nonlocal mlog
mlog = MeasurementLog() #mlog = MeasurementLog()
mlog.__init__()
for m in mv: for m in mv:
mlog.append(m) mlog.append(m)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment