UserHistoryDictionaryTests.java revision 7d7f082075768c03e4b1d4b84ba2e6ef6cba1132
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.BinaryDictionaryUtils;
25
26import java.io.File;
27import java.util.Locale;
28import java.util.Random;
29
30/**
31 * Unit tests for UserHistoryDictionary
32 */
33@LargeTest
34public class UserHistoryDictionaryTests extends AndroidTestCase {
35    private static final String TAG = UserHistoryDictionaryTests.class.getSimpleName();
36    private static final int WAIT_FOR_WRITING_FILE_IN_MILLISECONDS = 3000;
37    private static final String TEST_ACCOUNT = "account@example.com";
38
39    private int mCurrentTime = 0;
40
41    private static void printAllFiles(final File dir) {
42        Log.d(TAG, dir.getAbsolutePath());
43        for (final File file : dir.listFiles()) {
44            Log.d(TAG, "  " + file.getName());
45        }
46    }
47
48    private static void assertDictionaryExists(final UserHistoryDictionary dict,
49            final File dictFile) {
50        Log.d(TAG, "waiting for writing ...");
51        dict.waitAllTasksForTests();
52        if (!dictFile.exists()) {
53            try {
54                Log.d(TAG, dictFile + " is not existing. Wait "
55                        + WAIT_FOR_WRITING_FILE_IN_MILLISECONDS + " ms for writing.");
56                printAllFiles(dictFile.getParentFile());
57                Thread.sleep(WAIT_FOR_WRITING_FILE_IN_MILLISECONDS);
58            } catch (final InterruptedException e) {
59                Log.e(TAG, "Interrupted during waiting for writing the dict file.");
60            }
61        }
62        assertTrue("Following dictionary file doesn't exist: " + dictFile, dictFile.exists());
63    }
64
65    @Override
66    protected void setUp() throws Exception {
67        super.setUp();
68        resetCurrentTimeForTestMode();
69        UserHistoryDictionaryTestsHelper.removeAllTestDictFiles(
70                UserHistoryDictionaryTestsHelper.TEST_LOCALE_PREFIX, mContext);
71    }
72
73    @Override
74    protected void tearDown() throws Exception {
75        UserHistoryDictionaryTestsHelper.removeAllTestDictFiles(
76                UserHistoryDictionaryTestsHelper.TEST_LOCALE_PREFIX, mContext);
77        stopTestModeInNativeCode();
78        super.tearDown();
79    }
80
81    private void resetCurrentTimeForTestMode() {
82        mCurrentTime = 0;
83        setCurrentTimeForTestMode(mCurrentTime);
84    }
85
86    private static int setCurrentTimeForTestMode(final int currentTime) {
87        return BinaryDictionaryUtils.setCurrentTimeForTest(currentTime);
88    }
89
90    private static int stopTestModeInNativeCode() {
91        return BinaryDictionaryUtils.setCurrentTimeForTest(-1);
92    }
93
94    /**
95     * Clear all entries in the user history dictionary.
96     * @param dict the user history dictionary.
97     */
98    private static void clearHistory(final UserHistoryDictionary dict) {
99        dict.waitAllTasksForTests();
100        dict.clear();
101        dict.close();
102        dict.waitAllTasksForTests();
103    }
104
105    private void doTestRandomWords(final String testAccount) {
106        Log.d(TAG, "This test can be used for profiling.");
107        Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true.");
108        final Locale dummyLocale = UserHistoryDictionaryTestsHelper.getDummyLocale("random_words");
109        final String dictName = UserHistoryDictionary.getUserHistoryDictName(
110                UserHistoryDictionary.NAME, dummyLocale,
111                null /* dictFile */,
112                testAccount /* account */);
113        final File dictFile = ExpandableBinaryDictionary.getDictFile(
114                mContext, dictName, null /* dictFile */);
115        final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary(
116                getContext(), dummyLocale, testAccount);
117        clearHistory(dict);
118
119        final int numberOfWords = 1000;
120        final Random random = new Random(123456);
121        assertTrue(UserHistoryDictionaryTestsHelper.addAndWriteRandomWords(
122                dict, numberOfWords, random, true /* checksContents */, mCurrentTime));
123        assertDictionaryExists(dict, dictFile);
124    }
125
126    public void testRandomWords_NullAccount() {
127        doTestRandomWords(null /* testAccount */);
128    }
129
130    public void testRandomWords() {
131        doTestRandomWords(TEST_ACCOUNT);
132    }
133
134    public void testStressTestForSwitchingLanguagesAndAddingWords() {
135        doTestStressTestForSwitchingLanguagesAndAddingWords(TEST_ACCOUNT);
136    }
137
138    public void testStressTestForSwitchingLanguagesAndAddingWords_NullAccount() {
139        doTestStressTestForSwitchingLanguagesAndAddingWords(null /* testAccount */);
140    }
141
142    private void doTestStressTestForSwitchingLanguagesAndAddingWords(final String testAccount) {
143        final int numberOfLanguages = 2;
144        final int numberOfLanguageSwitching = 80;
145        final int numberOfWordsInsertedForEachLanguageSwitch = 100;
146
147        final File dictFiles[] = new File[numberOfLanguages];
148        final UserHistoryDictionary dicts[] = new UserHistoryDictionary[numberOfLanguages];
149
150        try {
151            final Random random = new Random(123456);
152
153            // Create filename suffixes for this test.
154            for (int i = 0; i < numberOfLanguages; i++) {
155                final Locale dummyLocale =
156                        UserHistoryDictionaryTestsHelper.getDummyLocale("switching_languages" + i);
157                final String dictName = UserHistoryDictionary.getUserHistoryDictName(
158                        UserHistoryDictionary.NAME, dummyLocale, null /* dictFile */,
159                        testAccount /* account */);
160                dictFiles[i] = ExpandableBinaryDictionary.getDictFile(
161                        mContext, dictName, null /* dictFile */);
162                dicts[i] = PersonalizationHelper.getUserHistoryDictionary(getContext(),
163                        dummyLocale, testAccount);
164                clearHistory(dicts[i]);
165            }
166
167            final long start = System.currentTimeMillis();
168
169            for (int i = 0; i < numberOfLanguageSwitching; i++) {
170                final int index = i % numberOfLanguages;
171                // Switch to dicts[index].
172                assertTrue(UserHistoryDictionaryTestsHelper.addAndWriteRandomWords(dicts[index],
173                        numberOfWordsInsertedForEachLanguageSwitch,
174                        random,
175                        false /* checksContents */,
176                        mCurrentTime));
177            }
178
179            final long end = System.currentTimeMillis();
180            Log.d(TAG, "testStressTestForSwitchingLanguageAndAddingWords took "
181                    + (end - start) + " ms");
182        } finally {
183            for (int i = 0; i < numberOfLanguages; i++) {
184                assertDictionaryExists(dicts[i], dictFiles[i]);
185            }
186        }
187    }
188
189    public void testAddManyWords() {
190        doTestAddManyWords(TEST_ACCOUNT);
191    }
192
193    public void testAddManyWords_NullAccount() {
194        doTestAddManyWords(null /* testAccount */);
195    }
196
197    private void doTestAddManyWords(final String testAccount) {
198        final Locale dummyLocale =
199                UserHistoryDictionaryTestsHelper.getDummyLocale("many_random_words");
200        final String dictName = UserHistoryDictionary.getUserHistoryDictName(
201                UserHistoryDictionary.NAME, dummyLocale, null /* dictFile */, testAccount);
202        final File dictFile = ExpandableBinaryDictionary.getDictFile(
203                mContext, dictName, null /* dictFile */);
204        final int numberOfWords = 10000;
205        final Random random = new Random(123456);
206        final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary(
207                getContext(), dummyLocale, testAccount);
208        clearHistory(dict);
209        assertTrue(UserHistoryDictionaryTestsHelper.addAndWriteRandomWords(dict,
210                numberOfWords, random, true /* checksContents */, mCurrentTime));
211        assertDictionaryExists(dict, dictFile);
212    }
213}