diff --git a/s3transfer/bandwidth.py b/s3transfer/bandwidth.py index 3ac9b340..8b3f6f50 100644 --- a/s3transfer/bandwidth.py +++ b/s3transfer/bandwidth.py @@ -401,7 +401,14 @@ def record_consumption_rate(self, amt, time_at_consumption): self._last_time = time_at_consumption def _calculate_rate(self, amt, time_at_consumption): - return amt / (time_at_consumption - self._last_time) + time_delta = time_at_consumption - self._last_time + if time_delta <= 0: + # While it is really unlikley to see this in an actual transfer, + # we do not want to be returning back a negative rate or try to + # divide the amount by zero. So instead return back an infinite + # rate as the time delta is infinitesimally small. + return float('inf') + return amt / (time_delta) def _calculate_exponential_moving_average_rate(self, amt, time_at_consumption): diff --git a/tests/unit/test_bandwidth.py b/tests/unit/test_bandwidth.py index c6bb1986..4f35a7a8 100644 --- a/tests/unit/test_bandwidth.py +++ b/tests/unit/test_bandwidth.py @@ -456,3 +456,10 @@ def test_get_projected_rate(self): self.assertEqual(projected_rate, 0.96) self.rate_tracker.record_consumption_rate(1, 3) self.assertEqual(self.rate_tracker.current_rate, projected_rate) + + def test_get_projected_rate_for_same_timestamp(self): + self.rate_tracker.record_consumption_rate(1, 1) + self.assertEqual( + self.rate_tracker.get_projected_rate(1, 1), + float('inf') + )