Skip to content

Commit 111fb3c

Browse files
Treehugger RobotGerrit Code Review
authored andcommitted
Merge "Move AppSearch testutils to the cts repo" into android14-tests-dev
2 parents 6ad4349 + d456ca3 commit 111fb3c

23 files changed

Lines changed: 2570 additions & 5 deletions

hostsidetests/appsearch/Android.bp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ android_test_helper_app {
4747
name: "CtsAppSearchHostTestHelperA",
4848
defaults: ["cts_defaults"],
4949
static_libs: [
50-
"AppSearchTestUtils",
50+
"CtsAppSearchTestUtils",
5151
"androidx.test.ext.junit",
5252
"androidx.test.rules",
5353
"compatibility-device-util-axt",
@@ -70,7 +70,7 @@ android_test_helper_app {
7070
name: "CtsAppSearchHostTestHelperB",
7171
defaults: ["cts_defaults"],
7272
static_libs: [
73-
"AppSearchTestUtils",
73+
"CtsAppSearchTestUtils",
7474
"androidx.test.ext.junit",
7575
"androidx.test.rules",
7676
"compatibility-device-util-axt",

tests/appsearch/Android.bp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ android_test {
2020
name: "CtsAppSearchTestCases",
2121
defaults: ["cts_defaults"],
2222
static_libs: [
23-
"AppSearchTestUtils",
23+
"CtsAppSearchTestUtils",
2424
"androidx.test.ext.junit",
2525
"androidx.test.rules",
2626
"compatibility-device-util-axt",
@@ -47,7 +47,7 @@ android_test_helper_app {
4747
name: "CtsAppSearchTestHelperA",
4848
defaults: ["cts_defaults"],
4949
static_libs: [
50-
"AppSearchTestUtils",
50+
"CtsAppSearchTestUtils",
5151
"androidx.test.ext.junit",
5252
"androidx.test.rules",
5353
"compatibility-device-util-axt",
@@ -74,7 +74,7 @@ android_test_helper_app {
7474
name: "CtsAppSearchTestHelperB",
7575
defaults: ["cts_defaults"],
7676
static_libs: [
77-
"AppSearchTestUtils",
77+
"CtsAppSearchTestUtils",
7878
"androidx.test.ext.junit",
7979
"androidx.test.rules",
8080
"compatibility-device-util-axt",
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (C) 2020 The Android Open Source Project
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package {
16+
default_applicable_licenses: ["Android-Apache-2.0"],
17+
}
18+
19+
java_library {
20+
name: "CtsAppSearchTestUtils",
21+
srcs: ["src/**/*.java"],
22+
libs: [
23+
"androidx.test.ext.junit",
24+
"framework-annotations-lib",
25+
"framework-appsearch.impl",
26+
"guava",
27+
"service-appsearch-for-tests",
28+
"truth",
29+
],
30+
sdk_version: "system_server_current",
31+
visibility: [
32+
"//cts/hostsidetests/appsearch",
33+
"//cts/tests:__subpackages__",
34+
"//packages/modules/AppSearch/testing:__subpackages__",
35+
],
36+
}
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/*
2+
* Copyright 2020 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 android.app.appsearch.testutil;
18+
19+
import android.annotation.NonNull;
20+
import android.annotation.UserIdInt;
21+
import android.app.appsearch.AppSearchBatchResult;
22+
import android.app.appsearch.AppSearchManager;
23+
import android.app.appsearch.AppSearchResult;
24+
import android.app.appsearch.AppSearchSession;
25+
import android.app.appsearch.AppSearchSessionShim;
26+
import android.app.appsearch.Features;
27+
import android.app.appsearch.GenericDocument;
28+
import android.app.appsearch.GetByDocumentIdRequest;
29+
import android.app.appsearch.GetSchemaResponse;
30+
import android.app.appsearch.PutDocumentsRequest;
31+
import android.app.appsearch.RemoveByDocumentIdRequest;
32+
import android.app.appsearch.ReportUsageRequest;
33+
import android.app.appsearch.SearchResults;
34+
import android.app.appsearch.SearchResultsShim;
35+
import android.app.appsearch.SearchSpec;
36+
import android.app.appsearch.SearchSuggestionResult;
37+
import android.app.appsearch.SearchSuggestionSpec;
38+
import android.app.appsearch.SetSchemaRequest;
39+
import android.app.appsearch.SetSchemaResponse;
40+
import android.app.appsearch.StorageInfo;
41+
import android.app.appsearch.exceptions.AppSearchException;
42+
import android.content.Context;
43+
import android.os.UserHandle;
44+
45+
import androidx.test.core.app.ApplicationProvider;
46+
47+
import com.google.common.util.concurrent.Futures;
48+
import com.google.common.util.concurrent.ListenableFuture;
49+
import com.google.common.util.concurrent.SettableFuture;
50+
51+
import java.util.List;
52+
import java.util.Objects;
53+
import java.util.Set;
54+
import java.util.concurrent.ExecutorService;
55+
import java.util.concurrent.Executors;
56+
57+
/**
58+
* This test class adapts the AppSearch Framework API to ListenableFuture, so it can be tested via
59+
* a consistent interface.
60+
* @hide
61+
*/
62+
public class AppSearchSessionShimImpl implements AppSearchSessionShim {
63+
private final AppSearchSession mAppSearchSession;
64+
private final ExecutorService mExecutor;
65+
66+
/** Creates the SearchSessionShim with given SearchContext. */
67+
@NonNull
68+
public static ListenableFuture<AppSearchSessionShim> createSearchSessionAsync(
69+
@NonNull AppSearchManager.SearchContext searchContext) {
70+
Context context = ApplicationProvider.getApplicationContext();
71+
return createSearchSessionAsync(context, searchContext, Executors.newCachedThreadPool());
72+
}
73+
74+
/** Creates the SearchSessionShim with given SearchContext for the given user. */
75+
@NonNull
76+
public static ListenableFuture<AppSearchSessionShim> createSearchSessionAsync(
77+
@NonNull AppSearchManager.SearchContext searchContext, @UserIdInt int userId) {
78+
Context context = ApplicationProvider.getApplicationContext()
79+
.createContextAsUser(UserHandle.of(userId), /*flags=*/ 0);
80+
return createSearchSessionAsync(context, searchContext, Executors.newCachedThreadPool());
81+
}
82+
83+
/** Creates the SearchSession with given Context and ExecutorService. */
84+
@NonNull
85+
public static ListenableFuture<AppSearchSessionShim> createSearchSessionAsync(
86+
@NonNull Context context,
87+
@NonNull AppSearchManager.SearchContext searchContext,
88+
@NonNull ExecutorService executor) {
89+
AppSearchManager appSearchManager = context.getSystemService(AppSearchManager.class);
90+
SettableFuture<AppSearchResult<AppSearchSession>> future = SettableFuture.create();
91+
appSearchManager.createSearchSession(searchContext, executor, future::set);
92+
return Futures.transform(
93+
future,
94+
instance -> new AppSearchSessionShimImpl(instance.getResultValue(), executor),
95+
executor);
96+
}
97+
98+
private AppSearchSessionShimImpl(
99+
@NonNull AppSearchSession session, @NonNull ExecutorService executor) {
100+
mAppSearchSession = Objects.requireNonNull(session);
101+
mExecutor = Objects.requireNonNull(executor);
102+
}
103+
104+
@Override
105+
@NonNull
106+
public ListenableFuture<SetSchemaResponse> setSchemaAsync(@NonNull SetSchemaRequest request) {
107+
SettableFuture<AppSearchResult<SetSchemaResponse>> future = SettableFuture.create();
108+
mAppSearchSession.setSchema(request, mExecutor, mExecutor, future::set);
109+
return Futures.transformAsync(future, this::transformResult, mExecutor);
110+
}
111+
112+
@Override
113+
@NonNull
114+
public ListenableFuture<GetSchemaResponse> getSchemaAsync() {
115+
SettableFuture<AppSearchResult<GetSchemaResponse>> future = SettableFuture.create();
116+
mAppSearchSession.getSchema(mExecutor, future::set);
117+
return Futures.transformAsync(future, this::transformResult, mExecutor);
118+
}
119+
120+
@NonNull
121+
@Override
122+
public ListenableFuture<Set<String>> getNamespacesAsync() {
123+
SettableFuture<AppSearchResult<Set<String>>> future = SettableFuture.create();
124+
mAppSearchSession.getNamespaces(mExecutor, future::set);
125+
return Futures.transformAsync(future, this::transformResult, mExecutor);
126+
}
127+
128+
@Override
129+
@NonNull
130+
public ListenableFuture<AppSearchBatchResult<String, Void>> putAsync(
131+
@NonNull PutDocumentsRequest request) {
132+
SettableFuture<AppSearchBatchResult<String, Void>> future = SettableFuture.create();
133+
mAppSearchSession.put(
134+
request, mExecutor, new BatchResultCallbackAdapter<>(future));
135+
return future;
136+
}
137+
138+
@Override
139+
@NonNull
140+
public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentIdAsync(
141+
@NonNull GetByDocumentIdRequest request) {
142+
SettableFuture<AppSearchBatchResult<String, GenericDocument>> future =
143+
SettableFuture.create();
144+
mAppSearchSession.getByDocumentId(
145+
request, mExecutor, new BatchResultCallbackAdapter<>(future));
146+
return future;
147+
}
148+
149+
@Override
150+
@NonNull
151+
public SearchResultsShim search(
152+
@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
153+
SearchResults searchResults = mAppSearchSession.search(queryExpression, searchSpec);
154+
return new SearchResultsShimImpl(searchResults, mExecutor);
155+
}
156+
157+
@Override
158+
@NonNull
159+
public ListenableFuture<Void> reportUsageAsync(@NonNull ReportUsageRequest request) {
160+
SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
161+
mAppSearchSession.reportUsage(request, mExecutor, future::set);
162+
return Futures.transformAsync(future, this::transformResult, mExecutor);
163+
}
164+
165+
@Override
166+
@NonNull
167+
public ListenableFuture<AppSearchBatchResult<String, Void>> removeAsync(
168+
@NonNull RemoveByDocumentIdRequest request) {
169+
SettableFuture<AppSearchBatchResult<String, Void>> future = SettableFuture.create();
170+
mAppSearchSession.remove(request, mExecutor, new BatchResultCallbackAdapter<>(future));
171+
return future;
172+
}
173+
174+
@Override
175+
@NonNull
176+
public ListenableFuture<Void> removeAsync(
177+
@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
178+
SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
179+
mAppSearchSession.remove(queryExpression, searchSpec, mExecutor, future::set);
180+
return Futures.transformAsync(future, this::transformResult, mExecutor);
181+
}
182+
183+
@NonNull
184+
@Override
185+
public ListenableFuture<StorageInfo> getStorageInfoAsync() {
186+
SettableFuture<AppSearchResult<StorageInfo>> future = SettableFuture.create();
187+
mAppSearchSession.getStorageInfo(mExecutor, future::set);
188+
return Futures.transformAsync(future, this::transformResult, mExecutor);
189+
}
190+
191+
@Override
192+
@NonNull
193+
public ListenableFuture<Void> requestFlushAsync() {
194+
SettableFuture<AppSearchResult<Void>> future = SettableFuture.create();
195+
// The data in platform will be flushed by scheduled task. AppSearchSession won't do
196+
// anything extra flush.
197+
future.set(AppSearchResult.newSuccessfulResult(null));
198+
return Futures.transformAsync(future, this::transformResult, mExecutor);
199+
}
200+
201+
@Override
202+
@NonNull
203+
public ListenableFuture<List<SearchSuggestionResult>> searchSuggestionAsync(
204+
@NonNull String suggestionQueryExpression,
205+
@NonNull SearchSuggestionSpec searchSuggestionSpec) {
206+
SettableFuture<AppSearchResult<List<SearchSuggestionResult>>> future =
207+
SettableFuture.create();
208+
mAppSearchSession.searchSuggestion(
209+
suggestionQueryExpression, searchSuggestionSpec, mExecutor, future::set);
210+
return Futures.transform(future, AppSearchResult::getResultValue, mExecutor);
211+
}
212+
213+
@Override
214+
@NonNull
215+
public Features getFeatures() {
216+
return new MainlineFeaturesImpl();
217+
}
218+
219+
@Override
220+
public void close() {
221+
mAppSearchSession.close();
222+
}
223+
224+
private <T> ListenableFuture<T> transformResult(
225+
@NonNull AppSearchResult<T> result) throws AppSearchException {
226+
if (!result.isSuccess()) {
227+
throw new AppSearchException(result.getResultCode(), result.getErrorMessage());
228+
}
229+
return Futures.immediateFuture(result.getResultValue());
230+
}
231+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (C) 2022 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 android.app.appsearch.testutil;
18+
19+
import android.app.appsearch.AppSearchBatchResult;
20+
import android.app.appsearch.BatchResultCallback;
21+
22+
import com.google.common.util.concurrent.SettableFuture;
23+
24+
final class BatchResultCallbackAdapter<K, V>
25+
implements BatchResultCallback<K, V> {
26+
private final SettableFuture<AppSearchBatchResult<K, V>> mFuture;
27+
28+
BatchResultCallbackAdapter(SettableFuture<AppSearchBatchResult<K, V>> future) {
29+
mFuture = future;
30+
}
31+
32+
@Override
33+
public void onResult(AppSearchBatchResult<K, V> result) {
34+
mFuture.set(result);
35+
}
36+
37+
@Override
38+
public void onSystemError(Throwable t) {
39+
mFuture.setException(t);
40+
}
41+
}

0 commit comments

Comments
 (0)