blob: b9b7a95eb973acc033ef2104b930aba37f593abf [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.textclassifier.common.statsd;
import static com.google.common.truth.Truth.assertThat;
import android.os.Binder;
import android.os.Parcel;
import android.view.textclassifier.TextClassificationSessionId;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import com.android.internal.os.StatsdConfigProto.StatsdConfig;
import com.android.os.AtomsProto.Atom;
import com.android.os.AtomsProto.TextClassifierApiUsageReported;
import com.android.os.AtomsProto.TextClassifierApiUsageReported.ApiType;
import com.android.os.AtomsProto.TextClassifierApiUsageReported.ResultType;
import com.android.textclassifier.common.statsd.TextClassifierApiUsageLogger.Session;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.stream.Collectors;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class TextClassifierApiUsageLoggerTest {
/** A statsd config ID, which is arbitrary. */
private static final long CONFIG_ID = 689777;
private static final long SHORT_TIMEOUT_MS = 1000;
private static final String SESSION_ID = "abcdef";
@Before
public void setup() throws Exception {
StatsdTestUtils.cleanup(CONFIG_ID);
StatsdConfig.Builder builder =
StatsdConfig.newBuilder()
.setId(CONFIG_ID)
.addAllowedLogSource(ApplicationProvider.getApplicationContext().getPackageName());
StatsdTestUtils.addAtomMatcher(builder, Atom.TEXT_CLASSIFIER_API_USAGE_REPORTED_FIELD_NUMBER);
StatsdTestUtils.pushConfig(builder.build());
}
@After
public void tearDown() throws Exception {
StatsdTestUtils.cleanup(CONFIG_ID);
}
@Test
public void reportSuccess() throws Exception {
TextClassifierApiUsageLogger textClassifierApiUsageLogger =
new TextClassifierApiUsageLogger(
/* sampleRateSupplier= */ () -> 1, MoreExecutors.directExecutor());
Session session =
textClassifierApiUsageLogger.createSession(
TextClassifierApiUsageLogger.API_TYPE_SUGGEST_SELECTION,
createTextClassificationSessionId());
// so that the latency we log is greater than 0.
Thread.sleep(10);
session.reportSuccess();
ImmutableList<Atom> loggedAtoms = StatsdTestUtils.getLoggedAtoms(CONFIG_ID, SHORT_TIMEOUT_MS);
ImmutableList<TextClassifierApiUsageReported> loggedEvents =
ImmutableList.copyOf(
loggedAtoms.stream()
.map(Atom::getTextClassifierApiUsageReported)
.collect(Collectors.toList()));
assertThat(loggedEvents).hasSize(1);
TextClassifierApiUsageReported event = loggedEvents.get(0);
assertThat(event.getApiType()).isEqualTo(ApiType.SUGGEST_SELECTION);
assertThat(event.getResultType()).isEqualTo(ResultType.SUCCESS);
assertThat(event.getLatencyMillis()).isGreaterThan(0L);
assertThat(event.getSessionId()).isEqualTo(SESSION_ID);
}
@Test
public void reportFailure() throws Exception {
TextClassifierApiUsageLogger textClassifierApiUsageLogger =
new TextClassifierApiUsageLogger(
/* sampleRateSupplier= */ () -> 1, MoreExecutors.directExecutor());
Session session =
textClassifierApiUsageLogger.createSession(
TextClassifierApiUsageLogger.API_TYPE_CLASSIFY_TEXT,
createTextClassificationSessionId());
// so that the latency we log is greater than 0.
Thread.sleep(10);
session.reportFailure();
ImmutableList<Atom> loggedAtoms = StatsdTestUtils.getLoggedAtoms(CONFIG_ID, SHORT_TIMEOUT_MS);
ImmutableList<TextClassifierApiUsageReported> loggedEvents =
ImmutableList.copyOf(
loggedAtoms.stream()
.map(Atom::getTextClassifierApiUsageReported)
.collect(Collectors.toList()));
assertThat(loggedEvents).hasSize(1);
TextClassifierApiUsageReported event = loggedEvents.get(0);
assertThat(event.getApiType()).isEqualTo(ApiType.CLASSIFY_TEXT);
assertThat(event.getResultType()).isEqualTo(ResultType.FAIL);
assertThat(event.getLatencyMillis()).isGreaterThan(0L);
assertThat(event.getSessionId()).isEqualTo(SESSION_ID);
}
@Test
public void noLog_sampleRateZero() throws Exception {
TextClassifierApiUsageLogger textClassifierApiUsageLogger =
new TextClassifierApiUsageLogger(
/* sampleRateSupplier= */ () -> 0, MoreExecutors.directExecutor());
Session session =
textClassifierApiUsageLogger.createSession(
TextClassifierApiUsageLogger.API_TYPE_CLASSIFY_TEXT,
createTextClassificationSessionId());
session.reportSuccess();
ImmutableList<Atom> loggedAtoms = StatsdTestUtils.getLoggedAtoms(CONFIG_ID, SHORT_TIMEOUT_MS);
ImmutableList<TextClassifierApiUsageReported> loggedEvents =
ImmutableList.copyOf(
loggedAtoms.stream()
.map(Atom::getTextClassifierApiUsageReported)
.collect(Collectors.toList()));
assertThat(loggedEvents).isEmpty();
}
private static TextClassificationSessionId createTextClassificationSessionId() {
// Used a hack to create TextClassificationSessionId because its constructor is @hide.
Parcel parcel = Parcel.obtain();
parcel.writeString(SESSION_ID);
parcel.writeStrongBinder(new Binder());
parcel.setDataPosition(0);
return TextClassificationSessionId.CREATOR.createFromParcel(parcel);
}
}