1// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import <Cocoa/Cocoa.h>
6
7#include "base/metrics/histogram.h"
8#import "chrome/browser/chrome_browser_application_mac.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11using base::Histogram;
12using base::StatisticsRecorder;
13
14namespace chrome_browser_application_mac {
15
16// Generate an NSException with the given name.
17NSException* ExceptionNamed(NSString* name) {
18  return [NSException exceptionWithName:name
19                                 reason:@"No reason given"
20                               userInfo:nil];
21}
22
23// Helper to keep binning expectations readible.
24size_t BinForExceptionNamed(NSString* name) {
25  return BinForException(ExceptionNamed(name));
26}
27
28TEST(ChromeApplicationMacTest, ExceptionBinning) {
29  // These exceptions must be in this order.
30  EXPECT_EQ(BinForExceptionNamed(NSGenericException), 0U);
31  EXPECT_EQ(BinForExceptionNamed(NSRangeException), 1U);
32  EXPECT_EQ(BinForExceptionNamed(NSInvalidArgumentException), 2U);
33  EXPECT_EQ(BinForExceptionNamed(NSMallocException), 3U);
34
35  // Random other exceptions map to |kUnknownNSException|.
36  EXPECT_EQ(BinForExceptionNamed(@"CustomName"), kUnknownNSException);
37  EXPECT_EQ(BinForExceptionNamed(@"Custom Name"), kUnknownNSException);
38  EXPECT_EQ(BinForExceptionNamed(@""), kUnknownNSException);
39  EXPECT_EQ(BinForException(nil), kUnknownNSException);
40}
41
42TEST(ChromeApplicationMacTest, RecordException) {
43  // Start up a histogram recorder.
44  StatisticsRecorder recorder;
45
46  StatisticsRecorder::Histograms histograms;
47  StatisticsRecorder::GetSnapshot("OSX.NSException", &histograms);
48  EXPECT_EQ(0U, histograms.size());
49
50  // Record some known exceptions.
51  RecordExceptionWithUma(ExceptionNamed(NSGenericException));
52  RecordExceptionWithUma(ExceptionNamed(NSGenericException));
53  RecordExceptionWithUma(ExceptionNamed(NSGenericException));
54  RecordExceptionWithUma(ExceptionNamed(NSGenericException));
55  RecordExceptionWithUma(ExceptionNamed(NSRangeException));
56  RecordExceptionWithUma(ExceptionNamed(NSInvalidArgumentException));
57  RecordExceptionWithUma(ExceptionNamed(NSInvalidArgumentException));
58  RecordExceptionWithUma(ExceptionNamed(NSInvalidArgumentException));
59  RecordExceptionWithUma(ExceptionNamed(NSMallocException));
60  RecordExceptionWithUma(ExceptionNamed(NSMallocException));
61
62  // Record some unknown exceptions.
63  RecordExceptionWithUma(ExceptionNamed(@"CustomName"));
64  RecordExceptionWithUma(ExceptionNamed(@"Custom Name"));
65  RecordExceptionWithUma(ExceptionNamed(@""));
66  RecordExceptionWithUma(nil);
67
68  // We should have exactly the right number of exceptions.
69  StatisticsRecorder::GetSnapshot("OSX.NSException", &histograms);
70  EXPECT_EQ(1U, histograms.size());
71  EXPECT_EQ(Histogram::kUmaTargetedHistogramFlag, histograms[0]->flags());
72  Histogram::SampleSet sample;
73  histograms[0]->SnapshotSample(&sample);
74  EXPECT_EQ(4, sample.counts(0));
75  EXPECT_EQ(1, sample.counts(1));
76  EXPECT_EQ(3, sample.counts(2));
77  EXPECT_EQ(2, sample.counts(3));
78
79  // The unknown exceptions should end up in the overflow bucket.
80  EXPECT_EQ(kUnknownNSException + 1, histograms[0]->bucket_count());
81  EXPECT_EQ(4, sample.counts(kUnknownNSException));
82}
83
84}  // chrome_browser_application_mac
85