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 static com.google.common.truth.Truth.assertThat; 20 import static com.google.common.truth.Truth.assertWithMessage; 21 22 import android.annotation.NonNull; 23 import android.app.appsearch.AppSearchBatchResult; 24 import android.app.appsearch.AppSearchSessionShim; 25 import android.app.appsearch.GenericDocument; 26 import android.app.appsearch.GetByDocumentIdRequest; 27 import android.app.appsearch.SearchResult; 28 import android.app.appsearch.SearchResultsShim; 29 30 import com.android.server.appsearch.external.localstorage.visibilitystore.CallerAccess; 31 import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityChecker; 32 import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore; 33 34 import java.util.ArrayList; 35 import java.util.List; 36 import java.util.Set; 37 import java.util.concurrent.Future; 38 39 /** 40 * Class with helper functions for testing for AppSearch. 41 * 42 * @hide 43 */ 44 public class AppSearchTestUtils { AppSearchTestUtils()45 private AppSearchTestUtils() {} 46 47 /** Checks batch result. */ 48 @NonNull checkIsBatchResultSuccess( @onNull Future<AppSearchBatchResult<K, V>> future)49 public static <K, V> AppSearchBatchResult<K, V> checkIsBatchResultSuccess( 50 @NonNull Future<AppSearchBatchResult<K, V>> future) throws Exception { 51 AppSearchBatchResult<K, V> result = future.get(); 52 assertWithMessage("AppSearchBatchResult not successful: " + result) 53 .that(result.isSuccess()) 54 .isTrue(); 55 return result; 56 } 57 58 /** Gets documents from ids. */ 59 @NonNull doGet( @onNull AppSearchSessionShim session, @NonNull String namespace, @NonNull String... ids)60 public static List<GenericDocument> doGet( 61 @NonNull AppSearchSessionShim session, 62 @NonNull String namespace, 63 @NonNull String... ids) 64 throws Exception { 65 AppSearchBatchResult<String, GenericDocument> result = 66 checkIsBatchResultSuccess( 67 session.getByDocumentIdAsync( 68 new GetByDocumentIdRequest.Builder(namespace).addIds(ids).build())); 69 assertThat(result.getSuccesses()).hasSize(ids.length); 70 assertThat(result.getFailures()).isEmpty(); 71 List<GenericDocument> list = new ArrayList<>(ids.length); 72 for (String id : ids) { 73 list.add(result.getSuccesses().get(id)); 74 } 75 return list; 76 } 77 78 /** Gets documents from {@link GetByDocumentIdRequest}. */ 79 @NonNull doGet( @onNull AppSearchSessionShim session, @NonNull GetByDocumentIdRequest request)80 public static List<GenericDocument> doGet( 81 @NonNull AppSearchSessionShim session, @NonNull GetByDocumentIdRequest request) 82 throws Exception { 83 AppSearchBatchResult<String, GenericDocument> result = 84 checkIsBatchResultSuccess(session.getByDocumentIdAsync(request)); 85 Set<String> ids = request.getIds(); 86 assertThat(result.getSuccesses()).hasSize(ids.size()); 87 assertThat(result.getFailures()).isEmpty(); 88 List<GenericDocument> list = new ArrayList<>(ids.size()); 89 for (String id : ids) { 90 list.add(result.getSuccesses().get(id)); 91 } 92 return list; 93 } 94 95 /** Extracts documents from {@link SearchResultsShim}. */ 96 @NonNull convertSearchResultsToDocuments( @onNull SearchResultsShim searchResults)97 public static List<GenericDocument> convertSearchResultsToDocuments( 98 @NonNull SearchResultsShim searchResults) throws Exception { 99 List<SearchResult> results = retrieveAllSearchResults(searchResults); 100 List<GenericDocument> documents = new ArrayList<>(results.size()); 101 for (SearchResult result : results) { 102 documents.add(result.getGenericDocument()); 103 } 104 return documents; 105 } 106 107 /** Extracts all {@link SearchResult} from {@link SearchResultsShim}. */ 108 @NonNull retrieveAllSearchResults( @onNull SearchResultsShim searchResults)109 public static List<SearchResult> retrieveAllSearchResults( 110 @NonNull SearchResultsShim searchResults) throws Exception { 111 List<SearchResult> page = searchResults.getNextPageAsync().get(); 112 List<SearchResult> results = new ArrayList<>(); 113 while (!page.isEmpty()) { 114 results.addAll(page); 115 page = searchResults.getNextPageAsync().get(); 116 } 117 return results; 118 } 119 120 /** 121 * Creates a mock {@link VisibilityChecker} where schema is searchable if prefixedSchema is one 122 * of the provided set of visiblePrefixedSchemas and caller does not have system access. 123 * 124 * @param visiblePrefixedSchemas Schema types that are accessible to any caller. 125 * @return Mocked {@link VisibilityChecker} instance. 126 */ 127 @NonNull createMockVisibilityChecker( @onNull Set<String> visiblePrefixedSchemas)128 public static VisibilityChecker createMockVisibilityChecker( 129 @NonNull Set<String> visiblePrefixedSchemas) { 130 return new VisibilityChecker() { 131 @Override 132 public boolean isSchemaSearchableByCaller( 133 @NonNull CallerAccess callerAccess, 134 @NonNull String packageName, 135 @NonNull String prefixedSchema, 136 @NonNull VisibilityStore visibilityStore) { 137 return visiblePrefixedSchemas.contains(prefixedSchema); 138 } 139 140 @Override 141 public boolean doesCallerHaveSystemAccess(@NonNull String s) { 142 return false; 143 } 144 }; 145 } 146 147 /** 148 * Creates a mock {@link VisibilityChecker}, where it can be configured if schema is searchable 149 * by caller and caller does not have system access. 150 * 151 * @param isSchemaSearchableByCaller Schema visibility for caller. 152 * @return Mocked {@link VisibilityChecker} instance. 153 */ 154 @NonNull 155 public static VisibilityChecker createMockVisibilityChecker( 156 boolean isSchemaSearchableByCaller) { 157 return new VisibilityChecker() { 158 @Override 159 public boolean isSchemaSearchableByCaller( 160 @NonNull CallerAccess callerAccess, 161 @NonNull String packageName, 162 @NonNull String prefixedSchema, 163 @NonNull VisibilityStore visibilityStore) { 164 return isSchemaSearchableByCaller; 165 } 166 167 @Override 168 public boolean doesCallerHaveSystemAccess(@NonNull String s) { 169 return false; 170 } 171 }; 172 } 173 } 174