1// Copyright (c) 2012 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#import "base/mac/scoped_nsexception_enabler.h" 8#include "base/memory/scoped_ptr.h" 9#include "base/metrics/histogram.h" 10#include "base/metrics/histogram_samples.h" 11#include "base/metrics/statistics_recorder.h" 12#import "chrome/browser/chrome_browser_application_mac.h" 13#include "testing/gtest/include/gtest/gtest.h" 14 15using base::HistogramBase; 16using base::HistogramSamples; 17using base::StatisticsRecorder; 18 19namespace chrome_browser_application_mac { 20 21// Generate an NSException with the given name. 22NSException* ExceptionNamed(NSString* name) { 23 base::mac::ScopedNSExceptionEnabler enabler; 24 25 return [NSException exceptionWithName:name 26 reason:@"No reason given" 27 userInfo:nil]; 28} 29 30// Helper to keep binning expectations readible. 31size_t BinForExceptionNamed(NSString* name) { 32 return BinForException(ExceptionNamed(name)); 33} 34 35TEST(ChromeApplicationMacTest, ExceptionBinning) { 36 // These exceptions must be in this order. 37 EXPECT_EQ(BinForExceptionNamed(NSGenericException), 0U); 38 EXPECT_EQ(BinForExceptionNamed(NSRangeException), 1U); 39 EXPECT_EQ(BinForExceptionNamed(NSInvalidArgumentException), 2U); 40 EXPECT_EQ(BinForExceptionNamed(NSMallocException), 3U); 41 42 // Random other exceptions map to |kUnknownNSException|. 43 EXPECT_EQ(BinForExceptionNamed(@"CustomName"), kUnknownNSException); 44 EXPECT_EQ(BinForExceptionNamed(@"Custom Name"), kUnknownNSException); 45 EXPECT_EQ(BinForExceptionNamed(@""), kUnknownNSException); 46 EXPECT_EQ(BinForException(nil), kUnknownNSException); 47} 48 49TEST(ChromeApplicationMacTest, RecordException) { 50 // Start up a histogram recorder. 51 // TODO(rtenneti): Leaks StatisticsRecorder and will update suppressions. 52 base::StatisticsRecorder::Initialize(); 53 54 StatisticsRecorder::Histograms histograms; 55 StatisticsRecorder::GetSnapshot("OSX.NSException", &histograms); 56 EXPECT_EQ(0U, histograms.size()); 57 58 // Record some known exceptions. 59 RecordExceptionWithUma(ExceptionNamed(NSGenericException)); 60 RecordExceptionWithUma(ExceptionNamed(NSGenericException)); 61 RecordExceptionWithUma(ExceptionNamed(NSGenericException)); 62 RecordExceptionWithUma(ExceptionNamed(NSGenericException)); 63 RecordExceptionWithUma(ExceptionNamed(NSRangeException)); 64 RecordExceptionWithUma(ExceptionNamed(NSInvalidArgumentException)); 65 RecordExceptionWithUma(ExceptionNamed(NSInvalidArgumentException)); 66 RecordExceptionWithUma(ExceptionNamed(NSInvalidArgumentException)); 67 RecordExceptionWithUma(ExceptionNamed(NSMallocException)); 68 RecordExceptionWithUma(ExceptionNamed(NSMallocException)); 69 70 // Record some unknown exceptions. 71 RecordExceptionWithUma(ExceptionNamed(@"CustomName")); 72 RecordExceptionWithUma(ExceptionNamed(@"Custom Name")); 73 RecordExceptionWithUma(ExceptionNamed(@"")); 74 RecordExceptionWithUma(nil); 75 76 // We should have exactly the right number of exceptions. 77 StatisticsRecorder::GetSnapshot("OSX.NSException", &histograms); 78 EXPECT_EQ(1U, histograms.size()); 79 EXPECT_EQ(HistogramBase::kUmaTargetedHistogramFlag, histograms[0]->flags()); 80 81 scoped_ptr<HistogramSamples> samples(histograms[0]->SnapshotSamples()); 82 EXPECT_EQ(4, samples->GetCount(0)); 83 EXPECT_EQ(1, samples->GetCount(1)); 84 EXPECT_EQ(3, samples->GetCount(2)); 85 EXPECT_EQ(2, samples->GetCount(3)); 86 87 // The unknown exceptions should end up in the overflow bucket. 88 EXPECT_TRUE(histograms[0]->HasConstructionArguments(1, 89 kUnknownNSException, 90 kUnknownNSException + 1)); 91 EXPECT_EQ(4, samples->GetCount(kUnknownNSException)); 92} 93 94} // chrome_browser_application_mac 95