UserHistoryDictionaryTests.java revision 5095fabdd0b9dcfd1af582d33792034763e612de
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.inputmethod.latin.personalization; 18 19import android.test.AndroidTestCase; 20import android.test.suitebuilder.annotation.LargeTest; 21import android.util.Log; 22 23import com.android.inputmethod.latin.ExpandableBinaryDictionary; 24import com.android.inputmethod.latin.utils.CollectionUtils; 25 26import java.io.File; 27import java.util.ArrayList; 28import java.util.List; 29import java.util.Locale; 30import java.util.Random; 31import java.util.Set; 32import java.util.concurrent.TimeUnit; 33 34/** 35 * Unit tests for UserHistoryDictionary 36 */ 37@LargeTest 38public class UserHistoryDictionaryTests extends AndroidTestCase { 39 private static final String TAG = UserHistoryDictionaryTests.class.getSimpleName(); 40 41 private static final String[] CHARACTERS = { 42 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", 43 "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" 44 }; 45 46 /** 47 * Generates a random word. 48 */ 49 private String generateWord(final int value) { 50 final int lengthOfChars = CHARACTERS.length; 51 StringBuilder builder = new StringBuilder(); 52 long lvalue = Math.abs((long)value); 53 while (lvalue > 0) { 54 builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]); 55 lvalue /= lengthOfChars; 56 } 57 return builder.toString(); 58 } 59 60 private List<String> generateWords(final int number, final Random random) { 61 final Set<String> wordSet = CollectionUtils.newHashSet(); 62 while (wordSet.size() < number) { 63 wordSet.add(generateWord(random.nextInt())); 64 } 65 return new ArrayList<String>(wordSet); 66 } 67 68 private void addToDict(final UserHistoryDictionary dict, final List<String> words) { 69 String prevWord = null; 70 for (String word : words) { 71 dict.addToDictionary(prevWord, word, true, 72 (int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())); 73 prevWord = word; 74 } 75 } 76 77 /** 78 * @param checkContents if true, checks whether written words are actually in the dictionary 79 * or not. 80 */ 81 private void addAndWriteRandomWords(final String testFilenameSuffix, final int numberOfWords, 82 final Random random, final boolean checkContents) { 83 final List<String> words = generateWords(numberOfWords, random); 84 final UserHistoryDictionary dict = 85 PersonalizationHelper.getUserHistoryDictionary(getContext(), 86 new Locale(testFilenameSuffix)); 87 // Add random words to the user history dictionary. 88 addToDict(dict, words); 89 if (checkContents) { 90 dict.waitAllTasksForTests(); 91 for (int i = 0; i < numberOfWords; ++i) { 92 final String word = words.get(i); 93 assertTrue(dict.isInUnderlyingBinaryDictionaryForTests(word)); 94 } 95 } 96 // write to file. 97 dict.close(); 98 } 99 100 /** 101 * Clear all entries in the user history dictionary. 102 * @param testFilenameSuffix file name suffix used for testing. 103 */ 104 private void clearHistory(final String testFilenameSuffix) { 105 final UserHistoryDictionary dict = 106 PersonalizationHelper.getUserHistoryDictionary(getContext(), 107 new Locale(testFilenameSuffix)); 108 dict.waitAllTasksForTests(); 109 dict.clearAndFlushDictionary(); 110 dict.close(); 111 dict.waitAllTasksForTests(); 112 } 113 114 /** 115 * Shut down executer and wait until all operations of user history are done. 116 * @param testFilenameSuffix file name suffix used for testing. 117 */ 118 private void waitForWriting(final String testFilenameSuffix) { 119 final UserHistoryDictionary dict = 120 PersonalizationHelper.getUserHistoryDictionary(getContext(), 121 new Locale(testFilenameSuffix)); 122 dict.waitAllTasksForTests(); 123 } 124 125 public void testRandomWords() { 126 Log.d(TAG, "This test can be used for profiling."); 127 Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true."); 128 final String testFilenameSuffix = "test_random_words" + System.currentTimeMillis(); 129 final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix 130 + ExpandableBinaryDictionary.DICT_FILE_EXTENSION; 131 132 final int numberOfWords = 1000; 133 final Random random = new Random(123456); 134 135 try { 136 clearHistory(testFilenameSuffix); 137 addAndWriteRandomWords(testFilenameSuffix, numberOfWords, random, 138 true /* checksContents */); 139 } finally { 140 Log.d(TAG, "waiting for writing ..."); 141 waitForWriting(testFilenameSuffix); 142 final File dictFile = new File(getContext().getFilesDir(), fileName); 143 if (dictFile != null) { 144 assertTrue(dictFile.exists()); 145 dictFile.delete(); 146 } 147 } 148 } 149 150 public void testStressTestForSwitchingLanguagesAndAddingWords() { 151 final int numberOfLanguages = 2; 152 final int numberOfLanguageSwitching = 80; 153 final int numberOfWordsInsertedForEachLanguageSwitch = 100; 154 155 final File dictFiles[] = new File[numberOfLanguages]; 156 final String testFilenameSuffixes[] = new String[numberOfLanguages]; 157 try { 158 final Random random = new Random(123456); 159 160 // Create filename suffixes for this test. 161 for (int i = 0; i < numberOfLanguages; i++) { 162 testFilenameSuffixes[i] = "test_switching_languages" + i; 163 final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffixes[i] 164 + ExpandableBinaryDictionary.DICT_FILE_EXTENSION; 165 dictFiles[i] = new File(getContext().getFilesDir(), fileName); 166 clearHistory(testFilenameSuffixes[i]); 167 } 168 169 final long start = System.currentTimeMillis(); 170 171 for (int i = 0; i < numberOfLanguageSwitching; i++) { 172 final int index = i % numberOfLanguages; 173 // Switch languages to testFilenameSuffixes[index]. 174 addAndWriteRandomWords(testFilenameSuffixes[index], 175 numberOfWordsInsertedForEachLanguageSwitch, random, 176 false /* checksContents */); 177 } 178 179 final long end = System.currentTimeMillis(); 180 Log.d(TAG, "testStressTestForSwitchingLanguageAndAddingWords took " 181 + (end - start) + " ms"); 182 } finally { 183 Log.d(TAG, "waiting for writing ..."); 184 for (int i = 0; i < numberOfLanguages; i++) { 185 waitForWriting(testFilenameSuffixes[i]); 186 } 187 for (final File file : dictFiles) { 188 if (file != null) { 189 assertTrue(file.exists()); 190 file.delete(); 191 } 192 } 193 } 194 } 195 196 public void testAddManyWords() { 197 final String testFilenameSuffix = "test_random_words" + System.currentTimeMillis(); 198 final int numberOfWords = 10000; 199 final Random random = new Random(123456); 200 clearHistory(testFilenameSuffix); 201 try { 202 addAndWriteRandomWords(testFilenameSuffix, numberOfWords, random, 203 true /* checksContents */); 204 } finally { 205 Log.d(TAG, "waiting for writing ..."); 206 waitForWriting(testFilenameSuffix); 207 final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix 208 + ExpandableBinaryDictionary.DICT_FILE_EXTENSION; 209 final File dictFile = new File(getContext().getFilesDir(), fileName); 210 if (dictFile != null) { 211 assertTrue(dictFile.exists()); 212 dictFile.delete(); 213 } 214 } 215 } 216 217} 218