184d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada/* 284d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * Copyright (C) 2012 The Android Open Source Project 384d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * 484d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * Licensed under the Apache License, Version 2.0 (the "License"); 584d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * you may not use this file except in compliance with the License. 684d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * You may obtain a copy of the License at 784d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * 884d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * http://www.apache.org/licenses/LICENSE-2.0 984d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * 1084d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * Unless required by applicable law or agreed to in writing, software 1184d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * distributed under the License is distributed on an "AS IS" BASIS, 1284d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1384d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * See the License for the specific language governing permissions and 1484d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * limitations under the License. 1584d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada */ 1684d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada 17ffcbbaf12788a9fc9398607a548e552d7d2bf05eSatoshi Kataokapackage com.android.inputmethod.latin.personalization; 1884d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada 1984d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanadaimport android.test.AndroidTestCase; 20b4598f7d05d6afd01ddc7ea0bed71dda837d1debTadashi G. Takaokaimport android.test.suitebuilder.annotation.LargeTest; 2184d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanadaimport android.util.Log; 2284d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada 238aaae56cf6694ec75043be56f1c7812a343b24d5Yuichiro Hanadaimport com.android.inputmethod.latin.ExpandableBinaryDictionary; 24e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagiimport com.android.inputmethod.latin.PrevWordsInfo; 25e708b1bc2e11285ad404133b8de21719ce08acb5Keisuke Kuroyanagiimport com.android.inputmethod.latin.PrevWordsInfo.WordInfo; 26e784148ae6872942434eaa55ca32b4c6442cc8e8Keisuke Kuroyanagiimport com.android.inputmethod.latin.utils.BinaryDictionaryUtils; 2717bd4eb0c984125d968ca05a567180c2bd3761f6Keisuke Kuroyanagiimport com.android.inputmethod.latin.utils.DistracterFilter; 280cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaokaimport com.android.inputmethod.latin.utils.FileUtils; 29e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasa 306def28d1dacb0f02c08d91c8be3ed877624f74abYuichiro Hanadaimport java.io.File; 3184d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanadaimport java.util.ArrayList; 32a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaokaimport java.util.HashSet; 3384d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanadaimport java.util.List; 342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaimport java.util.Locale; 3584d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanadaimport java.util.Random; 360d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanadaimport java.util.concurrent.TimeUnit; 3784d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada 3884d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada/** 3984d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * Unit tests for UserHistoryDictionary 4084d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada */ 41b4598f7d05d6afd01ddc7ea0bed71dda837d1debTadashi G. Takaoka@LargeTest 4284d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanadapublic class UserHistoryDictionaryTests extends AndroidTestCase { 4384d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada private static final String TAG = UserHistoryDictionaryTests.class.getSimpleName(); 4484d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada 4584d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada private static final String[] CHARACTERS = { 4684d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", 4784d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" 4884d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada }; 4984d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada 500bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi private int mCurrentTime = 0; 510bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi 520bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi @Override 530bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi protected void setUp() throws Exception { 540bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi super.setUp(); 5521f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi resetCurrentTimeForTestMode(); 560bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi } 570bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi 580bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi @Override 590bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi protected void tearDown() throws Exception { 600bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi stopTestModeInNativeCode(); 610bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi super.tearDown(); 620bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi } 630bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi 6421f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi private void resetCurrentTimeForTestMode() { 6521f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi mCurrentTime = 0; 6621f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi setCurrentTimeForTestMode(mCurrentTime); 6721f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi } 6821f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi 690bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi private void forcePassingShortTime() { 7021f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi // 3 days. 7121f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi final int timeToElapse = (int)TimeUnit.DAYS.toSeconds(3); 720bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi mCurrentTime += timeToElapse; 730bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi setCurrentTimeForTestMode(mCurrentTime); 740bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi } 750bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi 760bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi private void forcePassingLongTime() { 7773a2426d455e6e83dd9402913889f80a0071f0acKeisuke Kuroyanagi // 365 days. 7873a2426d455e6e83dd9402913889f80a0071f0acKeisuke Kuroyanagi final int timeToElapse = (int)TimeUnit.DAYS.toSeconds(365); 790bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi mCurrentTime += timeToElapse; 800bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi setCurrentTimeForTestMode(mCurrentTime); 810bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi } 820bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi 830bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi private static int setCurrentTimeForTestMode(final int currentTime) { 84e784148ae6872942434eaa55ca32b4c6442cc8e8Keisuke Kuroyanagi return BinaryDictionaryUtils.setCurrentTimeForTest(currentTime); 850bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi } 860bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi 870bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi private static int stopTestModeInNativeCode() { 88e784148ae6872942434eaa55ca32b4c6442cc8e8Keisuke Kuroyanagi return BinaryDictionaryUtils.setCurrentTimeForTest(-1); 890bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi } 900bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi 9184d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada /** 9284d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada * Generates a random word. 9384d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada */ 940cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka private static String generateWord(final int value) { 9584d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada final int lengthOfChars = CHARACTERS.length; 9684d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada StringBuilder builder = new StringBuilder(); 9784d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada long lvalue = Math.abs((long)value); 9884d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada while (lvalue > 0) { 9984d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]); 10084d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada lvalue /= lengthOfChars; 10184d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada } 10284d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada return builder.toString(); 10384d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada } 10484d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada 1050cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka private static List<String> generateWords(final int number, final Random random) { 106a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka final HashSet<String> wordSet = new HashSet<>(); 10784d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada while (wordSet.size() < number) { 10884d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada wordSet.add(generateWord(random.nextInt())); 10984d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada } 110a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka return new ArrayList<>(wordSet); 11184d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada } 11284d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada 1130cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka private static void addToDict(final UserHistoryDictionary dict, final List<String> words) { 114a790c5b68324da41428aeb68594d43ca5632f66dKeisuke Kuroyanagi PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; 11584d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada for (String word : words) { 116e507d92aa3ee4ae43124c5452f20aa8ed0ecef4cKeisuke Kuroyanagi UserHistoryDictionary.addToDictionary(dict, prevWordsInfo, word, true, 11717bd4eb0c984125d968ca05a567180c2bd3761f6Keisuke Kuroyanagi (int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), 11817bd4eb0c984125d968ca05a567180c2bd3761f6Keisuke Kuroyanagi DistracterFilter.EMPTY_DISTRACTER_FILTER); 119e708b1bc2e11285ad404133b8de21719ce08acb5Keisuke Kuroyanagi prevWordsInfo = prevWordsInfo.getNextPrevWordsInfo(new WordInfo(word)); 12084d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada } 12184d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada } 12284d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada 123e5a35711b854aedeeea2f45105b941b9deee49bcSatoshi Kataoka /** 124a328f538c34ad2dafdfa53642085cb1072224d80Yuichiro Hanada * @param checkContents if true, checks whether written words are actually in the dictionary 125e5a35711b854aedeeea2f45105b941b9deee49bcSatoshi Kataoka * or not. 126e5a35711b854aedeeea2f45105b941b9deee49bcSatoshi Kataoka */ 1270cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka private void addAndWriteRandomWords(final Locale locale, final int numberOfWords, 128a328f538c34ad2dafdfa53642085cb1072224d80Yuichiro Hanada final Random random, final boolean checkContents) { 1290d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada final List<String> words = generateWords(numberOfWords, random); 1300cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary( 1310cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka mContext, locale); 1320d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada // Add random words to the user history dictionary. 1330d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada addToDict(dict, words); 134a328f538c34ad2dafdfa53642085cb1072224d80Yuichiro Hanada if (checkContents) { 1352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa dict.waitAllTasksForTests(); 136a328f538c34ad2dafdfa53642085cb1072224d80Yuichiro Hanada for (int i = 0; i < numberOfWords; ++i) { 137e5a35711b854aedeeea2f45105b941b9deee49bcSatoshi Kataoka final String word = words.get(i); 1381910392eeddf2c9f4c1d34925e64f8d8772e7dc4Keisuke Kuroyanagi assertTrue(dict.isInDictionary(word)); 139e5a35711b854aedeeea2f45105b941b9deee49bcSatoshi Kataoka } 140e5a35711b854aedeeea2f45105b941b9deee49bcSatoshi Kataoka } 1410d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada // write to file. 1420d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada dict.close(); 1430d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada } 1440d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada 14511f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi /** 14611f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi * Clear all entries in the user history dictionary. 1470cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka * @param locale dummy locale for testing. 14811f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi */ 1490cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka private void clearHistory(final Locale locale) { 1500cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary( 1510cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka mContext, locale); 15268069c55c49d21dcccd0a90369cd0fd61982d8cfKeisuke Kuroyanagi dict.waitAllTasksForTests(); 1532dcb5c1b4d399501fc7645bf933f08f3a0e7e512Keisuke Kuroyanagi dict.clear(); 15411f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi dict.close(); 15568069c55c49d21dcccd0a90369cd0fd61982d8cfKeisuke Kuroyanagi dict.waitAllTasksForTests(); 15611f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi } 15711f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi 15811f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi /** 15911f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi * Shut down executer and wait until all operations of user history are done. 1600cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka * @param locale dummy locale for testing. 16111f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi */ 1620cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka private void waitForWriting(final Locale locale) { 1630cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary( 1640cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka mContext, locale); 1652fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa dict.waitAllTasksForTests(); 16611f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi } 16711f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi 16884d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada public void testRandomWords() { 1690d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada Log.d(TAG, "This test can be used for profiling."); 1700d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true."); 1710cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final Locale dummyLocale = new Locale("test_random_words" + System.currentTimeMillis()); 1720cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final String dictName = ExpandableBinaryDictionary.getDictName( 1730cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka UserHistoryDictionary.NAME, dummyLocale, null /* dictFile */); 1740cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final File dictFile = ExpandableBinaryDictionary.getDictFile( 1750cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka mContext, dictName, null /* dictFile */); 17611f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi 1770d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada final int numberOfWords = 1000; 1780d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada final Random random = new Random(123456); 1796def28d1dacb0f02c08d91c8be3ed877624f74abYuichiro Hanada 1800d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada try { 1810cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka clearHistory(dummyLocale); 1820cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka addAndWriteRandomWords(dummyLocale, numberOfWords, random, 183e5a35711b854aedeeea2f45105b941b9deee49bcSatoshi Kataoka true /* checksContents */); 1840d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada } finally { 18511f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi Log.d(TAG, "waiting for writing ..."); 1860cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka waitForWriting(dummyLocale); 1870cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka assertTrue("check exisiting of " + dictFile, dictFile.exists()); 1880cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka FileUtils.deleteRecursively(dictFile); 18984d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada } 19084d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada } 19128a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi 19228a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi public void testStressTestForSwitchingLanguagesAndAddingWords() { 19328a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi final int numberOfLanguages = 2; 1940d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada final int numberOfLanguageSwitching = 80; 1950d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada final int numberOfWordsInsertedForEachLanguageSwitch = 100; 19628a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi 19728a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi final File dictFiles[] = new File[numberOfLanguages]; 1980cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final Locale dummyLocales[] = new Locale[numberOfLanguages]; 19928a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi try { 20028a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi final Random random = new Random(123456); 20128a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi 2020d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada // Create filename suffixes for this test. 20328a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi for (int i = 0; i < numberOfLanguages; i++) { 2040cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka dummyLocales[i] = new Locale("test_switching_languages" + i); 2050cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final String dictName = ExpandableBinaryDictionary.getDictName( 2060cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka UserHistoryDictionary.NAME, dummyLocales[i], null /* dictFile */); 2070cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka dictFiles[i] = ExpandableBinaryDictionary.getDictFile( 2080cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka mContext, dictName, null /* dictFile */); 2090cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka clearHistory(dummyLocales[i]); 21028a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi } 21128a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi 2120d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada final long start = System.currentTimeMillis(); 21328a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi 21428a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi for (int i = 0; i < numberOfLanguageSwitching; i++) { 21528a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi final int index = i % numberOfLanguages; 2160d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada // Switch languages to testFilenameSuffixes[index]. 2170cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka addAndWriteRandomWords(dummyLocales[index], 218e5a35711b854aedeeea2f45105b941b9deee49bcSatoshi Kataoka numberOfWordsInsertedForEachLanguageSwitch, random, 219e5a35711b854aedeeea2f45105b941b9deee49bcSatoshi Kataoka false /* checksContents */); 22028a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi } 22128a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi 22228a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi final long end = System.currentTimeMillis(); 22328a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi Log.d(TAG, "testStressTestForSwitchingLanguageAndAddingWords took " 2240d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada + (end - start) + " ms"); 2250d70bcc821c22f7001b66f4c7b83842661b8391eYuichiro Hanada } finally { 22611f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi Log.d(TAG, "waiting for writing ..."); 22711f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi for (int i = 0; i < numberOfLanguages; i++) { 2280cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka waitForWriting(dummyLocales[i]); 22928a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi } 2300cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka for (final File dictFile : dictFiles) { 2310cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka assertTrue("check exisiting of " + dictFile, dictFile.exists()); 2320cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka FileUtils.deleteRecursively(dictFile); 23328a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi } 23428a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi } 23528a70b63c5748783c3b6fcac551cb69852840474Keisuke Kuroynagi } 2362e58670da9687fd1fd28c322e03343957d11568cKeisuke Kuroyanagi 2372e58670da9687fd1fd28c322e03343957d11568cKeisuke Kuroyanagi public void testAddManyWords() { 2380cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final Locale dummyLocale = new Locale("test_random_words" + System.currentTimeMillis()); 2390cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final String dictName = ExpandableBinaryDictionary.getDictName( 2400cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka UserHistoryDictionary.NAME, dummyLocale, null /* dictFile */); 2410cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka final File dictFile = ExpandableBinaryDictionary.getDictFile( 2420cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka mContext, dictName, null /* dictFile */); 2432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final int numberOfWords = 10000; 2442e58670da9687fd1fd28c322e03343957d11568cKeisuke Kuroyanagi final Random random = new Random(123456); 2450cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka clearHistory(dummyLocale); 2462e58670da9687fd1fd28c322e03343957d11568cKeisuke Kuroyanagi try { 2470cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka addAndWriteRandomWords(dummyLocale, numberOfWords, random, true /* checksContents */); 2482e58670da9687fd1fd28c322e03343957d11568cKeisuke Kuroyanagi } finally { 24911f7cae094720c3ab47e6c18772b1fc44e9e5372Keisuke Kuroyanagi Log.d(TAG, "waiting for writing ..."); 2500cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka waitForWriting(dummyLocale); 2510cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka assertTrue("check exisiting of " + dictFile, dictFile.exists()); 2520cda0e8a9ceaeab5a0e918c4fc76f77770d89b2cTadashi G. Takaoka FileUtils.deleteRecursively(dictFile); 2532e58670da9687fd1fd28c322e03343957d11568cKeisuke Kuroyanagi } 2542e58670da9687fd1fd28c322e03343957d11568cKeisuke Kuroyanagi } 2550bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi 2560bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi public void testDecaying() { 2570bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi final Locale dummyLocale = new Locale("test_decaying" + System.currentTimeMillis()); 2580bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi final int numberOfWords = 5000; 2590bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi final Random random = new Random(123456); 26021f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi resetCurrentTimeForTestMode(); 2610bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi clearHistory(dummyLocale); 2620bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi final List<String> words = generateWords(numberOfWords, random); 2630bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi final UserHistoryDictionary dict = 2640bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi PersonalizationHelper.getUserHistoryDictionary(getContext(), dummyLocale); 26521f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi dict.waitAllTasksForTests(); 266e708b1bc2e11285ad404133b8de21719ce08acb5Keisuke Kuroyanagi PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; 2670bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi for (final String word : words) { 26817bd4eb0c984125d968ca05a567180c2bd3761f6Keisuke Kuroyanagi UserHistoryDictionary.addToDictionary(dict, prevWordsInfo, word, true, mCurrentTime, 26917bd4eb0c984125d968ca05a567180c2bd3761f6Keisuke Kuroyanagi DistracterFilter.EMPTY_DISTRACTER_FILTER); 270e708b1bc2e11285ad404133b8de21719ce08acb5Keisuke Kuroyanagi prevWordsInfo = prevWordsInfo.getNextPrevWordsInfo(new WordInfo(word)); 2711737b7ff5c59b68693b85a410d5b5a901407087eKeisuke Kuroyanagi dict.waitAllTasksForTests(); 2721910392eeddf2c9f4c1d34925e64f8d8772e7dc4Keisuke Kuroyanagi assertTrue(dict.isInDictionary(word)); 2730bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi } 2740bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi forcePassingShortTime(); 275d302b98ce63743bde9d8d8c14755b5cf71c4e7a3Keisuke Kuroyanagi dict.runGCIfRequired(); 27621f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi dict.waitAllTasksForTests(); 2770bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi for (final String word : words) { 2781910392eeddf2c9f4c1d34925e64f8d8772e7dc4Keisuke Kuroyanagi assertTrue(dict.isInDictionary(word)); 2790bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi } 2800bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi forcePassingLongTime(); 281d302b98ce63743bde9d8d8c14755b5cf71c4e7a3Keisuke Kuroyanagi dict.runGCIfRequired(); 28221f94829994d5a5c2773605fec6b7eeef920c646Keisuke Kuroyanagi dict.waitAllTasksForTests(); 2830bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi for (final String word : words) { 2841910392eeddf2c9f4c1d34925e64f8d8772e7dc4Keisuke Kuroyanagi assertFalse(dict.isInDictionary(word)); 2850bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi } 2860bc66daae36ef7a1f2db1e2fd5c22abfe1b20163Keisuke Kuroyanagi } 28784d858ed5e187eb9d4b56b593e1d9287f762bbcaYuichiro Hanada} 288