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

Commit

Permalink
fix: Breakpoint Expiry in Firebase Backend Version (#74)
Browse files Browse the repository at this point in the history
- The firebase backend client code now calls on_idle periodically
- The breakpoint expiration code now checks for the `createTimeUnixMsec` breakpoint field

Fixes #72
  • Loading branch information
jasonborg committed Feb 21, 2023
1 parent 3d3e066 commit 7d09b9a
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 6 deletions.
6 changes: 6 additions & 0 deletions src/googleclouddebugger/firebase_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,12 @@ def _MainThreadProc(self):

self._StartMarkActiveTimer()

while not self._shutdown:
if self.on_idle is not None:
self.on_idle()

time.sleep(1)

def _TransmissionThreadProc(self):
"""Entry point for the transmission worker thread."""

Expand Down
36 changes: 30 additions & 6 deletions src/googleclouddebugger/python_breakpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,16 +252,40 @@ def GetBreakpointId(self):
return self.definition['id']

def GetExpirationTime(self):
"""Computes the timestamp at which this breakpoint will expire."""
# TODO: Move this to a common method.
if '.' not in self.definition['createTime']:
"""Computes the timestamp at which this breakpoint will expire.
If no creation time can be found an expiration time in the past will be
used.
"""
return self.GetCreateTime() + self.expiration_period

def GetCreateTime(self):
"""Retrieves the creation time of this breakpoint.
If no creation time can be found a creation time in the past will be used.
"""
if 'createTime' in self.definition:
return self.GetTimeFromRfc3339Str(self.definition['createTime'])
else:
return self.GetTimeFromUnixMsec(
self.definition.get('createTimeUnixMsec', 0))

def GetTimeFromRfc3339Str(self, rfc3339_str):
if '.' not in rfc3339_str:
fmt = '%Y-%m-%dT%H:%M:%S%Z'
else:
fmt = '%Y-%m-%dT%H:%M:%S.%f%Z'

create_datetime = datetime.strptime(
self.definition['createTime'].replace('Z', 'UTC'), fmt)
return create_datetime + self.expiration_period
return datetime.strptime(rfc3339_str.replace('Z', 'UTC'), fmt)

def GetTimeFromUnixMsec(self, unix_msec):
try:
return datetime.fromtimestamp(unix_msec / 1000)
except (TypeError, ValueError, OSError, OverflowError) as e:
native.LogWarning(
'Unexpected error (%s) occured processing unix_msec %s, breakpoint: %s'
% (repr(e), str(unix_msec), self.GetBreakpointId()))
return datetime.fromtimestamp(0)

def ExpireBreakpoint(self):
"""Expires this breakpoint."""
Expand Down
28 changes: 28 additions & 0 deletions tests/py/python_breakpoint_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,22 @@ def testHitNewTimestamp(self):
self.assertGreater(len(self._update_queue[0]['stackFrames']), 3)
self.assertTrue(self._update_queue[0]['isFinalState'])

def testHitTimestampUnixMsec(self):
# Using the Snapshot Debugger (Firebase backend) version of creation time
self._template.pop('createTime', None);
self._template[
'createTimeUnixMsec'] = python_test_util.DateTimeToUnixMsec(
self._base_time)

breakpoint = python_breakpoint.PythonBreakpoint(self._template, self, self,
None)
breakpoint._BreakpointEvent(native.BREAKPOINT_EVENT_HIT,
inspect.currentframe())
self.assertEqual(set(['BP_ID']), self._completed)
self.assertLen(self._update_queue, 1)
self.assertGreater(len(self._update_queue[0]['stackFrames']), 3)
self.assertTrue(self._update_queue[0]['isFinalState'])

def testDoubleHit(self):
breakpoint = python_breakpoint.PythonBreakpoint(self._template, self, self,
None)
Expand Down Expand Up @@ -541,6 +557,18 @@ def testExpirationTime(self):
self.assertEqual(
datetime(year=2015, month=1, day=2), breakpoint.GetExpirationTime())

def testExpirationTimeUnixMsec(self):
# Using the Snapshot Debugger (Firebase backend) version of creation time
self._template.pop('createTime', None);
self._template[
'createTimeUnixMsec'] = python_test_util.DateTimeToUnixMsec(
self._base_time)
breakpoint = python_breakpoint.PythonBreakpoint(self._template, self, self,
None)
breakpoint.Clear()
self.assertEqual(
self._base_time + timedelta(hours=24), breakpoint.GetExpirationTime())

def testExpirationTimeWithExpiresIn(self):
definition = self._template.copy()
definition['expires_in'] = {
Expand Down
4 changes: 4 additions & 0 deletions tests/py/python_test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ def DateTimeToTimestampNew(t):
"""
return t.strftime('%Y-%m-%dT%H:%M:%S') + 'Z'

def DateTimeToUnixMsec(t):
"""Returns the Unix time as in integer value in milliseconds"""
return int(t.timestamp() * 1000)


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

0 comments on commit 7d09b9a

Please sign in to comment.