def testBucketingLossApproximately(self): """Tests that we report the bucketing loss correctly.""" with metrics.RuntimeBreakdownTimer('fubar') as runtime: for i in range(300): with runtime.Step('step%d' % i): self._IncrementFakeTime(1) self.assertEqual(metrics.CumulativeSecondsDistribution.call_count, 1) self.assertEqual(metrics.CumulativeSecondsDistribution.call_args[0][0], 'fubar/total_duration') self.assertEqual(self._mockCumulativeSecondsDistribution.add.call_count, 1) self.assertEqual( self._mockCumulativeSecondsDistribution.add.call_args[0][0], 300.0) self.assertEqual(metrics.CumulativeMetric.call_count, 1) self.assertEqual(metrics.CumulativeMetric.call_args[0][0], 'fubar/bucketing_loss') self.assertEqual(self._mockCumulativeMetric.increment_by.call_count, 1) # Each steps is roughly 1/300 ~ .33%. # Our bucket resolution is 0.1 % so we expect to lose ~ 0.033% each report. # Total # of reports = 300. So we'll lose ~9.99% # Let's loosely bound that number to allow for floating point computation # errors. error = self._mockCumulativeMetric.increment_by.call_args[0][0] self.assertGreater(error, 9.6) self.assertLess(error, 10.2)
def testSucessfulBreakdown(self): """Tests that the context manager emits expected breakdowns.""" with metrics.RuntimeBreakdownTimer('fubar') as runtime: with runtime.Step('step1'): self._IncrementFakeTime(4) with runtime.Step('step2'): self._IncrementFakeTime(1) self._IncrementFakeTime(5) self.assertEqual(metrics.CumulativeSecondsDistribution.call_count, 1) self.assertEqual(metrics.CumulativeSecondsDistribution.call_args[0][0], 'fubar/total_duration') self.assertEqual( self._mockCumulativeSecondsDistribution.add.call_count, 1) self.assertEqual( self._mockCumulativeSecondsDistribution.add.call_args[0][0], 10.0) self.assertEqual(metrics.PercentageDistribution.call_count, 3) breakdown_names = [ x[0][0] for x in metrics.PercentageDistribution.call_args_list ] self.assertEqual( set(breakdown_names), { 'fubar/breakdown/step1', 'fubar/breakdown/step2', 'fubar/breakdown_unaccounted' }) breakdown_values = [ x[0][0] for x in self._mockPercentageDistribution.add.call_args_list ] self.assertEqual(set(breakdown_values), {40.0, 10.0, 50.0}) self.assertEqual(metrics.CumulativeMetric.call_count, 1) self.assertEqual(metrics.CumulativeMetric.call_args[0][0], 'fubar/bucketing_loss') self.assertEqual(metrics.Float.call_count, 2) for call_args in metrics.Float.call_args_list: self.assertEqual(call_args[0][0], 'fubar/duration_breakdown') self.assertEqual(self._mockFloat.set.call_count, 2) step_names = [ x[1]['fields']['step_name'] for x in self._mockFloat.set.call_args_list ] step_ratios = [x[0][0] for x in self._mockFloat.set.call_args_list] self.assertEqual(set(step_names), {'step1', 'step2'}) self.assertEqual(set(step_ratios), {0.4, 0.1})
def testNestedStepIgnored(self): """Tests that trying to enter nested .Step contexts raises.""" with metrics.RuntimeBreakdownTimer('fubar') as runtime: with runtime.Step('step1'): with runtime.Step('step2'): self._IncrementFakeTime(1) self.assertEqual(metrics.PercentageDistribution.call_count, 2) breakdown_names = [x[0][0] for x in metrics.PercentageDistribution.call_args_list] self.assertEqual(set(breakdown_names), {'fubar/breakdown/step1', 'fubar/breakdown_unaccounted'}) self.assertEqual(metrics.Float.call_count, 1) self.assertEqual(metrics.Float.call_args[0][0], 'fubar/duration_breakdown') self.assertEqual(self._mockFloat.set.call_count, 1) self.assertEqual(self._mockFloat.set.call_args[1]['fields']['step_name'], 'step1')
def testStepsWithClientCodeException(self): """Test that breakdown is reported correctly when client code raises.""" with self.assertRaises(ClientException): with metrics.RuntimeBreakdownTimer('fubar') as runtime: with runtime.Step('step1'): self._IncrementFakeTime(1) raise ClientException() self.assertEqual(metrics.PercentageDistribution.call_count, 2) breakdown_names = [x[0][0] for x in metrics.PercentageDistribution.call_args_list] self.assertEqual(set(breakdown_names), {'fubar/breakdown/step1', 'fubar/breakdown_unaccounted'}) self.assertEqual(metrics.Float.call_count, 1) self.assertEqual(metrics.Float.call_args[0][0], 'fubar/duration_breakdown') self.assertEqual(self._mockFloat.set.call_count, 1) self.assertEqual(self._mockFloat.set.call_args[1]['fields']['step_name'], 'step1')