UserHistoryDictionaryTests.java revision 5ed30a7660048ef4bf78077e77554c97786eae2b
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.content.SharedPreferences; 20import android.preference.PreferenceManager; 21import android.test.AndroidTestCase; 22import android.test.suitebuilder.annotation.LargeTest; 23import android.util.Log; 24 25import com.android.inputmethod.latin.ExpandableBinaryDictionary; 26import com.android.inputmethod.latin.utils.CollectionUtils; 27 28import java.io.File; 29import java.util.ArrayList; 30import java.util.List; 31import java.util.Random; 32import java.util.Set; 33import java.util.concurrent.TimeUnit; 34 35/** 36 * Unit tests for UserHistoryDictionary 37 */ 38@LargeTest 39public class UserHistoryDictionaryTests extends AndroidTestCase { 40 private static final String TAG = UserHistoryDictionaryTests.class.getSimpleName(); 41 private SharedPreferences mPrefs; 42 43 private static final String[] CHARACTERS = { 44 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", 45 "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" 46 }; 47 48 private static final int MIN_USER_HISTORY_DICTIONARY_FILE_SIZE = 1000; 49 private static final int WAIT_TERMINATING_IN_MILLISECONDS = 100; 50 51 @Override 52 public void setUp() { 53 mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); 54 } 55 56 /** 57 * Generates a random word. 58 */ 59 private String generateWord(final int value) { 60 final int lengthOfChars = CHARACTERS.length; 61 StringBuilder builder = new StringBuilder(); 62 long lvalue = Math.abs((long)value); 63 while (lvalue > 0) { 64 builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]); 65 lvalue /= lengthOfChars; 66 } 67 return builder.toString(); 68 } 69 70 private List<String> generateWords(final int number, final Random random) { 71 final Set<String> wordSet = CollectionUtils.newHashSet(); 72 while (wordSet.size() < number) { 73 wordSet.add(generateWord(random.nextInt())); 74 } 75 return new ArrayList<String>(wordSet); 76 } 77 78 private void addToDict(final UserHistoryDictionary dict, final List<String> words) { 79 String prevWord = null; 80 for (String word : words) { 81 dict.addToDictionary(prevWord, word, true); 82 prevWord = word; 83 } 84 } 85 86 /** 87 * @param checksContents if true, checks whether written words are actually in the dictionary 88 * or not. 89 */ 90 private void addAndWriteRandomWords(final String testFilenameSuffix, final int numberOfWords, 91 final Random random, final boolean checksContents) { 92 final List<String> words = generateWords(numberOfWords, random); 93 final UserHistoryDictionary dict = 94 PersonalizationHelper.getUserHistoryDictionary(getContext(), 95 testFilenameSuffix /* locale */, mPrefs); 96 // Add random words to the user history dictionary. 97 addToDict(dict, words); 98 if (checksContents) { 99 try { 100 Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS)); 101 } catch (InterruptedException e) { 102 } 103 // Limit word count to check when using a Java on memory dictionary. 104 final int wordCountToCheck = 105 ExpandableBinaryDictionary.ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE ? 106 numberOfWords : 10; 107 for (int i = 0; i < wordCountToCheck; ++i) { 108 final String word = words.get(i); 109 // This may fail as long as we use tryLock on inserting the bigram words 110 assertTrue(dict.isInDictionaryForTests(word)); 111 } 112 } 113 // write to file. 114 dict.close(); 115 } 116 117 public void testRandomWords() { 118 File dictFile = null; 119 Log.d(TAG, "This test can be used for profiling."); 120 Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true."); 121 final String testFilenameSuffix = "testRandomWords" + System.currentTimeMillis(); 122 final int numberOfWords = 1000; 123 final Random random = new Random(123456); 124 125 try { 126 addAndWriteRandomWords(testFilenameSuffix, numberOfWords, random, 127 true /* checksContents */); 128 } finally { 129 try { 130 final UserHistoryDictionary dict = 131 PersonalizationHelper.getUserHistoryDictionary(getContext(), 132 testFilenameSuffix, mPrefs); 133 Log.d(TAG, "waiting for writing ..."); 134 dict.shutdownExecutorForTests(); 135 while (!dict.isTerminatedForTests()) { 136 Thread.sleep(WAIT_TERMINATING_IN_MILLISECONDS); 137 } 138 } catch (InterruptedException e) { 139 Log.d(TAG, "InterruptedException: " + e); 140 } 141 142 final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix 143 + ExpandableBinaryDictionary.DICT_FILE_EXTENSION; 144 dictFile = new File(getContext().getFilesDir(), fileName); 145 146 if (dictFile != null) { 147 assertTrue(dictFile.exists()); 148 assertTrue(dictFile.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE); 149 dictFile.delete(); 150 } 151 } 152 } 153 154 public void testStressTestForSwitchingLanguagesAndAddingWords() { 155 final int numberOfLanguages = 2; 156 final int numberOfLanguageSwitching = 80; 157 final int numberOfWordsInsertedForEachLanguageSwitch = 100; 158 159 final File dictFiles[] = new File[numberOfLanguages]; 160 final String testFilenameSuffixes[] = new String[numberOfLanguages]; 161 try { 162 final Random random = new Random(123456); 163 164 // Create filename suffixes for this test. 165 for (int i = 0; i < numberOfLanguages; i++) { 166 testFilenameSuffixes[i] = "testSwitchingLanguages" + i; 167 final String fileName = UserHistoryDictionary.NAME + "." + 168 testFilenameSuffixes[i] + ExpandableBinaryDictionary.DICT_FILE_EXTENSION; 169 dictFiles[i] = new File(getContext().getFilesDir(), fileName); 170 } 171 172 final long start = System.currentTimeMillis(); 173 174 for (int i = 0; i < numberOfLanguageSwitching; i++) { 175 final int index = i % numberOfLanguages; 176 // Switch languages to testFilenameSuffixes[index]. 177 addAndWriteRandomWords(testFilenameSuffixes[index], 178 numberOfWordsInsertedForEachLanguageSwitch, random, 179 false /* checksContents */); 180 } 181 182 final long end = System.currentTimeMillis(); 183 Log.d(TAG, "testStressTestForSwitchingLanguageAndAddingWords took " 184 + (end - start) + " ms"); 185 } finally { 186 try { 187 Log.d(TAG, "waiting for writing ..."); 188 for (int i = 0; i < numberOfLanguages; i++) { 189 final UserHistoryDictionary dict = 190 PersonalizationHelper.getUserHistoryDictionary(getContext(), 191 testFilenameSuffixes[i], mPrefs); 192 dict.shutdownExecutorForTests(); 193 while (!dict.isTerminatedForTests()) { 194 Thread.sleep(WAIT_TERMINATING_IN_MILLISECONDS); 195 } 196 } 197 } catch (InterruptedException e) { 198 Log.d(TAG, "InterruptedException: " + e); 199 } 200 for (final File file : dictFiles) { 201 if (file != null) { 202 assertTrue(file.exists()); 203 assertTrue(file.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE); 204 file.delete(); 205 } 206 } 207 } 208 } 209 210 public void testAddManyWords() { 211 File dictFile = null; 212 final String testFilenameSuffix = "testRandomWords" + System.currentTimeMillis(); 213 final int numberOfWords = 214 ExpandableBinaryDictionary.ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE ? 215 10000 : 1000; 216 final Random random = new Random(123456); 217 218 UserHistoryDictionary dict = 219 PersonalizationHelper.getUserHistoryDictionary(getContext(), 220 testFilenameSuffix, mPrefs); 221 try { 222 addAndWriteRandomWords(testFilenameSuffix, numberOfWords, random, 223 true /* checksContents */); 224 dict.close(); 225 } finally { 226 try { 227 Log.d(TAG, "waiting for writing ..."); 228 dict.shutdownExecutorForTests(); 229 while (!dict.isTerminatedForTests()) { 230 Thread.sleep(WAIT_TERMINATING_IN_MILLISECONDS); 231 } 232 } catch (InterruptedException e) { 233 Log.d(TAG, "InterruptedException: ", e); 234 } 235 final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix 236 + ExpandableBinaryDictionary.DICT_FILE_EXTENSION; 237 dictFile = new File(getContext().getFilesDir(), fileName); 238 if (dictFile != null) { 239 assertTrue(dictFile.exists()); 240 assertTrue(dictFile.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE); 241 dictFile.delete(); 242 } 243 } 244 } 245 246} 247