1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/client/mac/tests/SimpleStringDictionaryTest.mm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,243 @@ 1.4 +// Copyright (c) 2008, Google Inc. 1.5 +// All rights reserved. 1.6 +// 1.7 +// Redistribution and use in source and binary forms, with or without 1.8 +// modification, are permitted provided that the following conditions are 1.9 +// met: 1.10 +// 1.11 +// * Redistributions of source code must retain the above copyright 1.12 +// notice, this list of conditions and the following disclaimer. 1.13 +// * Redistributions in binary form must reproduce the above 1.14 +// copyright notice, this list of conditions and the following disclaimer 1.15 +// in the documentation and/or other materials provided with the 1.16 +// distribution. 1.17 +// * Neither the name of Google Inc. nor the names of its 1.18 +// contributors may be used to endorse or promote products derived from 1.19 +// this software without specific prior written permission. 1.20 +// 1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 + 1.33 +#import "SimpleStringDictionaryTest.h" 1.34 +#import "SimpleStringDictionary.h" 1.35 + 1.36 +using google_breakpad::KeyValueEntry; 1.37 +using google_breakpad::SimpleStringDictionary; 1.38 +using google_breakpad::SimpleStringDictionaryIterator; 1.39 + 1.40 +@implementation SimpleStringDictionaryTest 1.41 + 1.42 +//============================================================================== 1.43 +- (void)testKeyValueEntry { 1.44 + KeyValueEntry entry; 1.45 + 1.46 + // Verify that initial state is correct 1.47 + STAssertFalse(entry.IsActive(), @"Initial key value entry is active!"); 1.48 + STAssertEquals(strlen(entry.GetKey()), (size_t)0, @"Empty key value did not " 1.49 + @"have length 0"); 1.50 + STAssertEquals(strlen(entry.GetValue()), (size_t)0, @"Empty key value did not " 1.51 + @"have length 0"); 1.52 + 1.53 + // Try setting a key/value and then verify 1.54 + entry.SetKeyValue("key1", "value1"); 1.55 + STAssertEqualCStrings(entry.GetKey(), "key1", @"key was not equal to key1"); 1.56 + STAssertEqualCStrings(entry.GetValue(), "value1", @"value was not equal"); 1.57 + 1.58 + // Try setting a new value 1.59 + entry.SetValue("value3"); 1.60 + 1.61 + // Make sure the new value took 1.62 + STAssertEqualCStrings(entry.GetValue(), "value3", @"value was not equal"); 1.63 + 1.64 + // Make sure the key didn't change 1.65 + STAssertEqualCStrings(entry.GetKey(), "key1", @"key changed after setting " 1.66 + @"value!"); 1.67 + 1.68 + // Try setting a new key/value and then verify 1.69 + entry.SetKeyValue("key2", "value2"); 1.70 + STAssertEqualCStrings(entry.GetKey(), "key2", @"New key was not equal to " 1.71 + @"key2"); 1.72 + STAssertEqualCStrings(entry.GetValue(), "value2", @"New value was not equal " 1.73 + @"to value2"); 1.74 + 1.75 + // Clear the entry and verify the key and value are empty strings 1.76 + entry.Clear(); 1.77 + STAssertFalse(entry.IsActive(), @"Key value clear did not clear object"); 1.78 + STAssertEquals(strlen(entry.GetKey()), (size_t)0, @"Length of cleared key " 1.79 + @"was not 0"); 1.80 + STAssertEquals(strlen(entry.GetValue()), (size_t)0, @"Length of cleared " 1.81 + @"value was not 0!"); 1.82 +} 1.83 + 1.84 +- (void)testEmptyKeyValueCombos { 1.85 + KeyValueEntry entry; 1.86 + entry.SetKeyValue(NULL, NULL); 1.87 + STAssertEqualCStrings(entry.GetKey(), "", @"Setting NULL key did not return " 1.88 + @"empty key!"); 1.89 + STAssertEqualCStrings(entry.GetValue(), "", @"Setting NULL value did not " 1.90 + @"set empty string value!"); 1.91 +} 1.92 + 1.93 + 1.94 +//============================================================================== 1.95 +- (void)testSimpleStringDictionary { 1.96 + // Make a new dictionary 1.97 + SimpleStringDictionary *dict = new SimpleStringDictionary(); 1.98 + STAssertTrue(dict != NULL, nil); 1.99 + 1.100 + // try passing in NULL for key 1.101 + //dict->SetKeyValue(NULL, "bad"); // causes assert() to fire 1.102 + 1.103 + // Set three distinct values on three keys 1.104 + dict->SetKeyValue("key1", "value1"); 1.105 + dict->SetKeyValue("key2", "value2"); 1.106 + dict->SetKeyValue("key3", "value3"); 1.107 + 1.108 + STAssertTrue(!strcmp(dict->GetValueForKey("key1"), "value1"), nil); 1.109 + STAssertTrue(!strcmp(dict->GetValueForKey("key2"), "value2"), nil); 1.110 + STAssertTrue(!strcmp(dict->GetValueForKey("key3"), "value3"), nil); 1.111 + STAssertEquals(dict->GetCount(), 3, @"GetCount did not return 3"); 1.112 + // try an unknown key 1.113 + STAssertTrue(dict->GetValueForKey("key4") == NULL, nil); 1.114 + 1.115 + // try a NULL key 1.116 + //STAssertTrue(dict->GetValueForKey(NULL) == NULL, nil); // asserts 1.117 + 1.118 + // Remove a key 1.119 + dict->RemoveKey("key3"); 1.120 + 1.121 + // Now make sure it's not there anymore 1.122 + STAssertTrue(dict->GetValueForKey("key3") == NULL, nil); 1.123 + 1.124 + // Remove a NULL key 1.125 + //dict->RemoveKey(NULL); // will cause assert() to fire 1.126 + 1.127 + // Remove by setting value to NULL 1.128 + dict->SetKeyValue("key2", NULL); 1.129 + 1.130 + // Now make sure it's not there anymore 1.131 + STAssertTrue(dict->GetValueForKey("key2") == NULL, nil); 1.132 +} 1.133 + 1.134 +//============================================================================== 1.135 +// The idea behind this test is to add a bunch of values to the dictionary, 1.136 +// remove some in the middle, then add a few more in. We then create a 1.137 +// SimpleStringDictionaryIterator and iterate through the dictionary, taking 1.138 +// note of the key/value pairs we see. We then verify that it iterates 1.139 +// through exactly the number of key/value pairs we expect, and that they 1.140 +// match one-for-one with what we would expect. In all cases we're setting 1.141 +// key value pairs of the form: 1.142 +// 1.143 +// key<n>/value<n> (like key0/value0, key17,value17, etc.) 1.144 +// 1.145 +- (void)testSimpleStringDictionaryIterator { 1.146 + SimpleStringDictionary *dict = new SimpleStringDictionary(); 1.147 + STAssertTrue(dict != NULL, nil); 1.148 + 1.149 + char key[KeyValueEntry::MAX_STRING_STORAGE_SIZE]; 1.150 + char value[KeyValueEntry::MAX_STRING_STORAGE_SIZE]; 1.151 + 1.152 + const int kDictionaryCapacity = SimpleStringDictionary::MAX_NUM_ENTRIES; 1.153 + const int kPartitionIndex = kDictionaryCapacity - 5; 1.154 + 1.155 + // We assume at least this size in the tests below 1.156 + STAssertTrue(kDictionaryCapacity >= 64, nil); 1.157 + 1.158 + // We'll keep track of the number of key/value pairs we think should 1.159 + // be in the dictionary 1.160 + int expectedDictionarySize = 0; 1.161 + 1.162 + // Set a bunch of key/value pairs like key0/value0, key1/value1, ... 1.163 + for (int i = 0; i < kPartitionIndex; ++i) { 1.164 + sprintf(key, "key%d", i); 1.165 + sprintf(value, "value%d", i); 1.166 + dict->SetKeyValue(key, value); 1.167 + } 1.168 + expectedDictionarySize = kPartitionIndex; 1.169 + 1.170 + // set a couple of the keys twice (with the same value) - should be nop 1.171 + dict->SetKeyValue("key2", "value2"); 1.172 + dict->SetKeyValue("key4", "value4"); 1.173 + dict->SetKeyValue("key15", "value15"); 1.174 + 1.175 + // Remove some random elements in the middle 1.176 + dict->RemoveKey("key7"); 1.177 + dict->RemoveKey("key18"); 1.178 + dict->RemoveKey("key23"); 1.179 + dict->RemoveKey("key31"); 1.180 + expectedDictionarySize -= 4; // we just removed four key/value pairs 1.181 + 1.182 + // Set some more key/value pairs like key59/value59, key60/value60, ... 1.183 + for (int i = kPartitionIndex; i < kDictionaryCapacity; ++i) { 1.184 + sprintf(key, "key%d", i); 1.185 + sprintf(value, "value%d", i); 1.186 + dict->SetKeyValue(key, value); 1.187 + } 1.188 + expectedDictionarySize += kDictionaryCapacity - kPartitionIndex; 1.189 + 1.190 + // Now create an iterator on the dictionary 1.191 + SimpleStringDictionaryIterator iter(*dict); 1.192 + 1.193 + // We then verify that it iterates through exactly the number of 1.194 + // key/value pairs we expect, and that they match one-for-one with what we 1.195 + // would expect. The ordering of the iteration does not matter... 1.196 + 1.197 + // used to keep track of number of occurrences found for key/value pairs 1.198 + int count[kDictionaryCapacity]; 1.199 + memset(count, 0, sizeof(count)); 1.200 + 1.201 + int totalCount = 0; 1.202 + 1.203 + const KeyValueEntry *entry; 1.204 + 1.205 + while ((entry = iter.Next())) { 1.206 + totalCount++; 1.207 + 1.208 + // Extract keyNumber from a string of the form key<keyNumber> 1.209 + int keyNumber; 1.210 + sscanf(entry->GetKey(), "key%d", &keyNumber); 1.211 + 1.212 + // Extract valueNumber from a string of the form value<valueNumber> 1.213 + int valueNumber; 1.214 + sscanf(entry->GetValue(), "value%d", &valueNumber); 1.215 + 1.216 + // The value number should equal the key number since that's how we set them 1.217 + STAssertTrue(keyNumber == valueNumber, nil); 1.218 + 1.219 + // Key and value numbers should be in proper range: 1.220 + // 0 <= keyNumber < kDictionaryCapacity 1.221 + bool isKeyInGoodRange = 1.222 + (keyNumber >= 0 && keyNumber < kDictionaryCapacity); 1.223 + bool isValueInGoodRange = 1.224 + (valueNumber >= 0 && valueNumber < kDictionaryCapacity); 1.225 + STAssertTrue(isKeyInGoodRange, nil); 1.226 + STAssertTrue(isValueInGoodRange, nil); 1.227 + 1.228 + if (isKeyInGoodRange && isValueInGoodRange) { 1.229 + ++count[keyNumber]; 1.230 + } 1.231 + } 1.232 + 1.233 + // Make sure each of the key/value pairs showed up exactly one time, except 1.234 + // for the ones which we removed. 1.235 + for (int i = 0; i < kDictionaryCapacity; ++i) { 1.236 + // Skip over key7, key18, key23, and key31, since we removed them 1.237 + if (!(i == 7 || i == 18 || i == 23 || i == 31)) { 1.238 + STAssertTrue(count[i] == 1, nil); 1.239 + } 1.240 + } 1.241 + 1.242 + // Make sure the number of iterations matches the expected dictionary size. 1.243 + STAssertTrue(totalCount == expectedDictionarySize, nil); 1.244 +} 1.245 + 1.246 +@end