Skip to content
This repository was archived by the owner on Jan 23, 2024. It is now read-only.

Commit 7d09b9a

Browse files
authored
fix: Breakpoint Expiry in Firebase Backend Version (#74)
- The firebase backend client code now calls on_idle periodically - The breakpoint expiration code now checks for the `createTimeUnixMsec` breakpoint field Fixes #72
1 parent 3d3e066 commit 7d09b9a

4 files changed

Lines changed: 68 additions & 6 deletions

File tree

src/googleclouddebugger/firebase_client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,12 @@ def _MainThreadProc(self):
311311

312312
self._StartMarkActiveTimer()
313313

314+
while not self._shutdown:
315+
if self.on_idle is not None:
316+
self.on_idle()
317+
318+
time.sleep(1)
319+
314320
def _TransmissionThreadProc(self):
315321
"""Entry point for the transmission worker thread."""
316322

src/googleclouddebugger/python_breakpoint.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,16 +252,40 @@ def GetBreakpointId(self):
252252
return self.definition['id']
253253

254254
def GetExpirationTime(self):
255-
"""Computes the timestamp at which this breakpoint will expire."""
256-
# TODO: Move this to a common method.
257-
if '.' not in self.definition['createTime']:
255+
"""Computes the timestamp at which this breakpoint will expire.
256+
257+
If no creation time can be found an expiration time in the past will be
258+
used.
259+
"""
260+
return self.GetCreateTime() + self.expiration_period
261+
262+
def GetCreateTime(self):
263+
"""Retrieves the creation time of this breakpoint.
264+
265+
If no creation time can be found a creation time in the past will be used.
266+
"""
267+
if 'createTime' in self.definition:
268+
return self.GetTimeFromRfc3339Str(self.definition['createTime'])
269+
else:
270+
return self.GetTimeFromUnixMsec(
271+
self.definition.get('createTimeUnixMsec', 0))
272+
273+
def GetTimeFromRfc3339Str(self, rfc3339_str):
274+
if '.' not in rfc3339_str:
258275
fmt = '%Y-%m-%dT%H:%M:%S%Z'
259276
else:
260277
fmt = '%Y-%m-%dT%H:%M:%S.%f%Z'
261278

262-
create_datetime = datetime.strptime(
263-
self.definition['createTime'].replace('Z', 'UTC'), fmt)
264-
return create_datetime + self.expiration_period
279+
return datetime.strptime(rfc3339_str.replace('Z', 'UTC'), fmt)
280+
281+
def GetTimeFromUnixMsec(self, unix_msec):
282+
try:
283+
return datetime.fromtimestamp(unix_msec / 1000)
284+
except (TypeError, ValueError, OSError, OverflowError) as e:
285+
native.LogWarning(
286+
'Unexpected error (%s) occured processing unix_msec %s, breakpoint: %s'
287+
% (repr(e), str(unix_msec), self.GetBreakpointId()))
288+
return datetime.fromtimestamp(0)
265289

266290
def ExpireBreakpoint(self):
267291
"""Expires this breakpoint."""

tests/py/python_breakpoint_test.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,22 @@ def testHitNewTimestamp(self):
457457
self.assertGreater(len(self._update_queue[0]['stackFrames']), 3)
458458
self.assertTrue(self._update_queue[0]['isFinalState'])
459459

460+
def testHitTimestampUnixMsec(self):
461+
# Using the Snapshot Debugger (Firebase backend) version of creation time
462+
self._template.pop('createTime', None);
463+
self._template[
464+
'createTimeUnixMsec'] = python_test_util.DateTimeToUnixMsec(
465+
self._base_time)
466+
467+
breakpoint = python_breakpoint.PythonBreakpoint(self._template, self, self,
468+
None)
469+
breakpoint._BreakpointEvent(native.BREAKPOINT_EVENT_HIT,
470+
inspect.currentframe())
471+
self.assertEqual(set(['BP_ID']), self._completed)
472+
self.assertLen(self._update_queue, 1)
473+
self.assertGreater(len(self._update_queue[0]['stackFrames']), 3)
474+
self.assertTrue(self._update_queue[0]['isFinalState'])
475+
460476
def testDoubleHit(self):
461477
breakpoint = python_breakpoint.PythonBreakpoint(self._template, self, self,
462478
None)
@@ -541,6 +557,18 @@ def testExpirationTime(self):
541557
self.assertEqual(
542558
datetime(year=2015, month=1, day=2), breakpoint.GetExpirationTime())
543559

560+
def testExpirationTimeUnixMsec(self):
561+
# Using the Snapshot Debugger (Firebase backend) version of creation time
562+
self._template.pop('createTime', None);
563+
self._template[
564+
'createTimeUnixMsec'] = python_test_util.DateTimeToUnixMsec(
565+
self._base_time)
566+
breakpoint = python_breakpoint.PythonBreakpoint(self._template, self, self,
567+
None)
568+
breakpoint.Clear()
569+
self.assertEqual(
570+
self._base_time + timedelta(hours=24), breakpoint.GetExpirationTime())
571+
544572
def testExpirationTimeWithExpiresIn(self):
545573
definition = self._template.copy()
546574
definition['expires_in'] = {

tests/py/python_test_util.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ def DateTimeToTimestampNew(t):
106106
"""
107107
return t.strftime('%Y-%m-%dT%H:%M:%S') + 'Z'
108108

109+
def DateTimeToUnixMsec(t):
110+
"""Returns the Unix time as in integer value in milliseconds"""
111+
return int(t.timestamp() * 1000)
112+
109113

110114
def PackFrameVariable(breakpoint, name, frame=0, collection='locals'):
111115
"""Finds local variable or argument by name.

0 commit comments

Comments
 (0)