UserHistoryDictionaryTests.java revision 8aaae56cf6694ec75043be56f1c7812a343b24d5
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
50    @Override
51    public void setUp() {
52        mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
53    }
54
55    /**
56     * Generates a random word.
57     */
58    private String generateWord(final int value) {
59        final int lengthOfChars = CHARACTERS.length;
60        StringBuilder builder = new StringBuilder();
61        long lvalue = Math.abs((long)value);
62        while (lvalue > 0) {
63            builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]);
64            lvalue /= lengthOfChars;
65        }
66        return builder.toString();
67    }
68
69    private List<String> generateWords(final int number, final Random random) {
70        final Set<String> wordSet = CollectionUtils.newHashSet();
71        while (wordSet.size() < number) {
72            wordSet.add(generateWord(random.nextInt()));
73        }
74        return new ArrayList<String>(wordSet);
75    }
76
77    private void addToDict(final UserHistoryPredictionDictionary dict, final List<String> words) {
78        String prevWord = null;
79        for (String word : words) {
80            dict.forceAddWordForTest(prevWord, word, true);
81            prevWord = word;
82        }
83    }
84
85    private void addAndWriteRandomWords(final String testFilenameSuffix, final int numberOfWords,
86            final Random random) {
87        final List<String> words = generateWords(numberOfWords, random);
88        final UserHistoryPredictionDictionary dict =
89                PersonalizationDictionaryHelper.getUserHistoryPredictionDictionary(getContext(),
90                        testFilenameSuffix /* locale */, mPrefs);
91        // Add random words to the user history dictionary.
92        addToDict(dict, words);
93        // write to file.
94        dict.close();
95    }
96
97    public void testRandomWords() {
98        File dictFile = null;
99        Log.d(TAG, "This test can be used for profiling.");
100        Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true.");
101        final String testFilenameSuffix = "testRandomWords" + System.currentTimeMillis();
102        final int numberOfWords = 1000;
103        final Random random = new Random(123456);
104
105        try {
106            addAndWriteRandomWords(testFilenameSuffix, numberOfWords, random);
107        } finally {
108            try {
109                Log.d(TAG, "waiting for writing ...");
110                Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS));
111            } catch (InterruptedException e) {
112                Log.d(TAG, "InterruptedException: " + e);
113            }
114
115            final String fileName = UserHistoryPredictionDictionary.NAME + "." + testFilenameSuffix
116                    + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
117            dictFile = new File(getContext().getFilesDir(), fileName);
118
119            if (dictFile != null) {
120                assertTrue(dictFile.exists());
121                assertTrue(dictFile.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE);
122                dictFile.delete();
123            }
124        }
125    }
126
127    public void testStressTestForSwitchingLanguagesAndAddingWords() {
128        final int numberOfLanguages = 2;
129        final int numberOfLanguageSwitching = 80;
130        final int numberOfWordsInsertedForEachLanguageSwitch = 100;
131
132        final File dictFiles[] = new File[numberOfLanguages];
133        try {
134            final Random random = new Random(123456);
135
136            // Create filename suffixes for this test.
137            String testFilenameSuffixes[] = new String[numberOfLanguages];
138            for (int i = 0; i < numberOfLanguages; i++) {
139                testFilenameSuffixes[i] = "testSwitchingLanguages" + i;
140                final String fileName = UserHistoryPredictionDictionary.NAME + "." +
141                        testFilenameSuffixes[i] + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
142                dictFiles[i] = new File(getContext().getFilesDir(), fileName);
143            }
144
145            final long start = System.currentTimeMillis();
146
147            for (int i = 0; i < numberOfLanguageSwitching; i++) {
148                final int index = i % numberOfLanguages;
149                // Switch languages to testFilenameSuffixes[index].
150                addAndWriteRandomWords(testFilenameSuffixes[index],
151                        numberOfWordsInsertedForEachLanguageSwitch, random);
152            }
153
154            final long end = System.currentTimeMillis();
155            Log.d(TAG, "testStressTestForSwitchingLanguageAndAddingWords took "
156                    + (end - start) + " ms");
157        } finally {
158            Log.d(TAG, "waiting for writing ...");
159            try {
160                Log.d(TAG, "waiting for writing ...");
161                Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS));
162            } catch (InterruptedException e) {
163                Log.d(TAG, "InterruptedException: " + e);
164            }
165            for (final File file : dictFiles) {
166                if (file != null) {
167                    assertTrue(file.exists());
168                    assertTrue(file.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE);
169                    file.delete();
170                }
171            }
172        }
173    }
174}
175