• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 
17 package com.android.textclassifier.downloader;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.view.textclassifier.TextClassification;
22 import android.view.textclassifier.TextClassification.Request;
23 import androidx.test.filters.FlakyTest;
24 import com.android.textclassifier.testing.ExtServicesTextClassifierRule;
25 import org.junit.After;
26 import org.junit.Before;
27 import org.junit.Ignore;
28 import org.junit.Rule;
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 import org.junit.runners.JUnit4;
32 
33 @Ignore("b/358423172")
34 @RunWith(JUnit4.class)
35 public class ModelDownloaderIntegrationTest {
36   private static final String TAG = "ModelDownloaderTest";
37   private static final String EXPERIMENTAL_EN_ANNOTATOR_MANIFEST_URL =
38       "https://www.gstatic.com/android/text_classifier/r/experimental/v999999999/en.fb.manifest";
39   private static final String EXPERIMENTAL_EN_TAG = "en_v999999999";
40   private static final String V804_EN_ANNOTATOR_MANIFEST_URL =
41       "https://www.gstatic.com/android/text_classifier/r/v804/en.fb.manifest";
42   private static final String V804_RU_ANNOTATOR_MANIFEST_URL =
43       "https://www.gstatic.com/android/text_classifier/r/v804/ru.fb.manifest";
44   private static final String V804_EN_TAG = "en_v804";
45   private static final String V804_RU_TAG = "ru_v804";
46   private static final String FACTORY_MODEL_TAG = "*";
47   private static final int ASSERT_MAX_ATTEMPTS = 20;
48   private static final int ASSERT_SLEEP_BEFORE_RETRY_MS = 1000;
49 
50   @Rule
51   public final ExtServicesTextClassifierRule extServicesTextClassifierRule =
52       new ExtServicesTextClassifierRule();
53 
54   @Before
setup()55   public void setup() throws Exception {
56     extServicesTextClassifierRule.addDeviceConfigOverride("config_updater_model_enabled", "false");
57     extServicesTextClassifierRule.addDeviceConfigOverride("model_download_manager_enabled", "true");
58     extServicesTextClassifierRule.addDeviceConfigOverride(
59         "model_download_backoff_delay_in_millis", "5");
60     extServicesTextClassifierRule.addDeviceConfigOverride("testing_locale_list_override", "en-US");
61     extServicesTextClassifierRule.overrideDeviceConfig();
62 
63     extServicesTextClassifierRule.enableVerboseLogging();
64     // Verbose logging only takes effect after restarting ExtServices
65     extServicesTextClassifierRule.forceStopExtServices();
66   }
67 
68   @After
tearDown()69   public void tearDown() throws Exception {
70     // This is to reset logging/locale_override for ExtServices.
71     extServicesTextClassifierRule.forceStopExtServices();
72   }
73 
74   @Test
75   @FlakyTest(bugId = 284901878)
smokeTest()76   public void smokeTest() throws Exception {
77     extServicesTextClassifierRule.addDeviceConfigOverride(
78         "manifest_url_annotator_en", V804_EN_ANNOTATOR_MANIFEST_URL);
79 
80     assertWithRetries(() -> verifyActiveEnglishModel(V804_EN_TAG));
81   }
82 
83   @Test
84   @FlakyTest(bugId = 284901878)
downgradeModel()85   public void downgradeModel() throws Exception {
86     // Download an experimental model.
87     extServicesTextClassifierRule.addDeviceConfigOverride(
88         "manifest_url_annotator_en", EXPERIMENTAL_EN_ANNOTATOR_MANIFEST_URL);
89 
90     assertWithRetries(() -> verifyActiveEnglishModel(EXPERIMENTAL_EN_TAG));
91 
92     // Downgrade to an older model.
93     extServicesTextClassifierRule.addDeviceConfigOverride(
94         "manifest_url_annotator_en", V804_EN_ANNOTATOR_MANIFEST_URL);
95 
96     assertWithRetries(() -> verifyActiveEnglishModel(V804_EN_TAG));
97   }
98 
99   @Test
100   @FlakyTest(bugId = 284901878)
upgradeModel()101   public void upgradeModel() throws Exception {
102     // Download a model.
103     extServicesTextClassifierRule.addDeviceConfigOverride(
104         "manifest_url_annotator_en", V804_EN_ANNOTATOR_MANIFEST_URL);
105 
106     assertWithRetries(() -> verifyActiveEnglishModel(V804_EN_TAG));
107 
108     // Upgrade to an experimental model.
109     extServicesTextClassifierRule.addDeviceConfigOverride(
110         "manifest_url_annotator_en", EXPERIMENTAL_EN_ANNOTATOR_MANIFEST_URL);
111 
112     assertWithRetries(() -> verifyActiveEnglishModel(EXPERIMENTAL_EN_TAG));
113   }
114 
115   @Test
116   @FlakyTest(bugId = 284901878)
clearFlag()117   public void clearFlag() throws Exception {
118     // Download a new model.
119     extServicesTextClassifierRule.addDeviceConfigOverride(
120         "manifest_url_annotator_en", EXPERIMENTAL_EN_ANNOTATOR_MANIFEST_URL);
121 
122     assertWithRetries(() -> verifyActiveEnglishModel(EXPERIMENTAL_EN_TAG));
123 
124     // Revert the flag.
125     extServicesTextClassifierRule.addDeviceConfigOverride("manifest_url_annotator_en", "");
126     // Fallback to use the universal model.
127     assertWithRetries(
128         () -> verifyActiveModel(/* text= */ "abc", /* expectedVersion= */ FACTORY_MODEL_TAG));
129   }
130 
131   @Test
132   @FlakyTest(bugId = 267344737)
modelsForMultipleLanguagesDownloaded()133   public void modelsForMultipleLanguagesDownloaded() throws Exception {
134     extServicesTextClassifierRule.addDeviceConfigOverride("multi_language_support_enabled", "true");
135     extServicesTextClassifierRule.addDeviceConfigOverride(
136         "testing_locale_list_override", "en-US,ru-RU");
137 
138     // download en model
139     extServicesTextClassifierRule.addDeviceConfigOverride(
140         "manifest_url_annotator_en", EXPERIMENTAL_EN_ANNOTATOR_MANIFEST_URL);
141 
142     // download ru model
143     extServicesTextClassifierRule.addDeviceConfigOverride(
144         "manifest_url_annotator_ru", V804_RU_ANNOTATOR_MANIFEST_URL);
145     assertWithRetries(() -> verifyActiveEnglishModel(EXPERIMENTAL_EN_TAG));
146 
147     assertWithRetries(this::verifyActiveRussianModel);
148 
149     assertWithRetries(
150         () -> verifyActiveModel(/* text= */ "français", /* expectedVersion= */ FACTORY_MODEL_TAG));
151   }
152 
assertWithRetries(Runnable assertRunnable)153   private void assertWithRetries(Runnable assertRunnable) throws Exception {
154     for (int i = 0; i < ASSERT_MAX_ATTEMPTS; i++) {
155       try {
156         extServicesTextClassifierRule.overrideDeviceConfig();
157         assertRunnable.run();
158         break; // success. Bail out.
159       } catch (AssertionError ex) {
160         if (i == ASSERT_MAX_ATTEMPTS - 1) { // last attempt, give up.
161           extServicesTextClassifierRule.dumpDefaultTextClassifierService();
162           throw ex;
163         } else {
164           Thread.sleep(ASSERT_SLEEP_BEFORE_RETRY_MS);
165         }
166       } catch (Exception unknownException) {
167         throw unknownException;
168       }
169     }
170   }
171 
verifyActiveModel(String text, String expectedVersion)172   private void verifyActiveModel(String text, String expectedVersion) {
173     TextClassification textClassification =
174         extServicesTextClassifierRule
175             .getTextClassifier()
176             .classifyText(new Request.Builder(text, 0, text.length()).build());
177     // The result id contains the name of the just used model.
178     assertThat(textClassification.getId()).contains(expectedVersion);
179   }
180 
verifyActiveEnglishModel(String expectedVersion)181   private void verifyActiveEnglishModel(String expectedVersion) {
182     verifyActiveModel("abc", expectedVersion);
183   }
184 
verifyActiveRussianModel()185   private void verifyActiveRussianModel() {
186     verifyActiveModel("привет", V804_RU_TAG);
187   }
188 }
189