LogManagerProvider with unit test.

This commit is contained in:
larvacea 2020-10-28 21:47:34 -07:00
Родитель a833996ea7
Коммит e5502a63d6
8 изменённых файлов: 1437 добавлений и 714 удалений

Просмотреть файл

@ -35,9 +35,9 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':maesdk')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

Просмотреть файл

@ -0,0 +1,159 @@
//
// Copyright (c) 2015-2020 Microsoft Corporation and Contributors.
// SPDX-License-Identifier: Apache-2.0
//
package com.microsoft.applications.events.maesdktest;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isA;
import static org.hamcrest.Matchers.isIn;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import android.content.Context;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import com.microsoft.applications.events.HttpClient;
import com.microsoft.applications.events.ILogConfiguration;
import com.microsoft.applications.events.ILogManager;
import com.microsoft.applications.events.ILogger;
import com.microsoft.applications.events.LogConfigurationKey;
import com.microsoft.applications.events.LogManager;
import com.microsoft.applications.events.LogManagerProvider;
import com.microsoft.applications.events.OfflineRoom;
import com.microsoft.applications.events.Status;
import java.util.Collections;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.FutureTask;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class LogManagerDDVUnitTest extends MaeUnitLogger {
public void log_failure(String filename, int line, String summary) {
fail(String.format("%s:%d: %s", filename, line, summary));
}
class MockRequest implements Runnable {
MockHttpClient m_parent;
String m_request_id;
public MockRequest(MockHttpClient parent, String id) {
m_parent = parent;
m_request_id = id;
}
public void run() {
String[] headers = {};
byte[] body = {};
m_parent.dispatchCallback(m_request_id, 200, headers, body);
}
}
class MockHttpClient extends HttpClient {
public SortedSet<String> urlSet;
public MockHttpClient(Context context) {
super(context);
urlSet = Collections.synchronizedSortedSet(new TreeSet());
}
public FutureTask<Boolean> createTask(
String url,
String method,
byte[] body,
String request_id,
int[] header_index,
byte[] header_buffer) {
synchronized (urlSet) {
urlSet.add(url);
}
Runnable r = new MockRequest(this, request_id);
return new FutureTask<Boolean>(r, true);
}
}
@Test
public void doubleManagerInstantiation() {
System.loadLibrary("maesdk");
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
MockHttpClient client = new MockHttpClient(appContext);
OfflineRoom.connectContext(appContext);
final String token =
"0123456789abcdef0123456789abcdef-01234567-0123-0123-0123-0123456789ab-0123";
final String contosoToken =
"0123456789abcdef9123456789abcdef-01234567-0123-0123-0123-0123456789ab-0124";
final String contosoUrl = "https://bozo.contoso.com/";
final String contosoName = "ContosoFactory";
final String contosoDatabase = "ContosoSequel";
ILogConfiguration custom = LogManager.logConfigurationFactory();
/*
Set up configuration for a second log manager instance. Why second, when we have
no previous log manager initialized in this test? Because we get a default, nameless
log manager in the SDK's internal tables whether we ask for it here or not.
Key points: we set CFG_STR_COLLECTOR_URL to define the collector URL we wish to use. We
set CFG_INT_MAX_TEARDOWN_TIME because the SDK will crash on teardown if this parameter
is missing. We set CFG_STR_FACTORY_NAME to give this log manager a unique identity and
unique configuration.
*/
custom.set(LogConfigurationKey.CFG_STR_PRIMARY_TOKEN, contosoToken);
custom.set(LogConfigurationKey.CFG_STR_COLLECTOR_URL, contosoUrl);
custom.set(LogConfigurationKey.CFG_INT_MAX_TEARDOWN_TIME, (long) 5);
custom.set(LogConfigurationKey.CFG_STR_FACTORY_NAME, contosoName);
custom.set(LogConfigurationKey.CFG_STR_CACHE_FILE_PATH, contosoDatabase);
assertThat(custom.getString(LogConfigurationKey.CFG_STR_PRIMARY_TOKEN), is(contosoToken));
assertThat(custom.getString(LogConfigurationKey.CFG_STR_COLLECTOR_URL), is(contosoUrl));
ILogger contosoLogger = LogManager.initialize(contosoToken, custom);
ILogConfiguration copy = LogManager.getLogConfigurationCopy();
assertThat(copy.getString(LogConfigurationKey.CFG_STR_PRIMARY_TOKEN), is(contosoToken));
assertThat(copy.getString(LogConfigurationKey.CFG_STR_COLLECTOR_URL), is(contosoUrl));
assertThat(copy.getLong(LogConfigurationKey.CFG_INT_MAX_TEARDOWN_TIME), is((long) 5));
assertThat(copy.getString(LogConfigurationKey.CFG_STR_FACTORY_NAME), is(contosoName));
/*
Log an event. Ideally, we would mock and verify that the HTTP client is uploading this
event to the desired endpoint. Coming soon to a unit test near you.
*/
assertThat(contosoLogger, isA(ILogger.class));
contosoLogger.logEvent("contosoevent");
assertThat(LogManager.flush(), is(Status.SUCCESS));
ILogConfiguration secondaryConfig = LogManager.logConfigurationFactory();
secondaryConfig.set(LogConfigurationKey.CFG_STR_PRIMARY_TOKEN, token);
secondaryConfig.set(LogConfigurationKey.CFG_STR_COLLECTOR_URL, "https://localhost:5000/");
secondaryConfig.set(LogConfigurationKey.CFG_INT_MAX_TEARDOWN_TIME, (long) 5);
secondaryConfig.set(LogConfigurationKey.CFG_STR_FACTORY_NAME, "osotnoc");
secondaryConfig.set(LogConfigurationKey.CFG_STR_CACHE_FILE_PATH, "osotnoc");
ILogManager secondaryManager = LogManagerProvider.createLogManager(secondaryConfig);
ILogger secondaryLogger = secondaryManager.getLogger(token, "osotnoc", "");
secondaryLogger.logEvent("osotnoc");
assertThat(secondaryManager.flush(), is(Status.SUCCESS));
LogManager.flushAndTeardown();
synchronized (client.urlSet) {
assertThat("https://localhost:5000/", isIn(client.urlSet));
assertThat(contosoUrl, isIn(client.urlSet));
}
/*
Both ILogger and ILogManager are AutoCloseable, and it is good practice
to call the close() method to tear each of them down. This will prevent use-after-free
disasters from Java wrappers passing dangling (freed) C++ native pointers into native code.
*/
}
}

Просмотреть файл

@ -16,7 +16,6 @@ import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import com.microsoft.applications.events.DataCategory;
import com.microsoft.applications.events.EventProperties;
import com.microsoft.applications.events.EventProperty;
import com.microsoft.applications.events.HttpClient;
import com.microsoft.applications.events.ILogConfiguration;
@ -145,7 +144,7 @@ public class SDKUnitNativeTest extends MaeUnitLogger {
assertNotNull(logger);
logger.logEvent("amazingAndroidUnitTest");
LogManager.flushAndTeardown();
LogManager.flush();
}
@Test
@ -231,6 +230,7 @@ public class SDKUnitNativeTest extends MaeUnitLogger {
}
public native int nativeGetPiiType(EventProperty property);
public native int nativeGetDataCategory(EventProperty property);
@Test
@ -245,4 +245,3 @@ public class SDKUnitNativeTest extends MaeUnitLogger {
assertThat(roundTrip, is(DataCategory.PartB.getValue()));
}
}

Просмотреть файл

@ -62,9 +62,9 @@ dependencies {
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
testImplementation 'junit:junit:4.13'
testImplementation 'junit:junit:4.13.1'
testImplementation 'org.mockito:mockito-inline:3.2.4'
testImplementation "androidx.room:room-testing:$room_version"
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

Просмотреть файл

@ -4,8 +4,56 @@
//
package com.microsoft.applications.events;
public interface ILogManager extends AutoCloseable {
public ILogger getLogger(String tenantToken);
public ILogConfiguration getLogConfigurationCopy();
}
import java.util.Date;
import java.util.UUID;
public interface ILogManager extends AutoCloseable {
public ILogger getLogger(String token, String source, String scope);
public ILogConfiguration getLogConfigurationCopy();
public void flushAndTeardown();
public Status flush();
public Status uploadNow();
public Status pauseTransmission();
public Status resumeTransmission();
public Status setTransmitProfile(TransmitProfile profile);
public Status setTransmitProfile(String profile);
public Status loadTransmitProfiles(String profilesJson);
public Status resetTransmitProfiles();
public String getTransmitProfileName();
public ISemanticContext getSemanticContext();
public Status setContext(final String name, final String value, final PiiKind piiKind);
public Status setContext(final String name, final int value, final PiiKind piiKind);
public Status setContext(final String name, final long value, final PiiKind piiKind);
public Status setContext(final String name, final double value, final PiiKind piiKind);
public Status setContext(final String name, final boolean value, final PiiKind piiKind);
public Status setContext(final String name, final Date value, final PiiKind piiKind);
public Status setContext(final String name, final UUID value, final PiiKind piiKind);
public boolean initializeDiagnosticDataViewer(String machineIdentifier, String endpoint);
public void disableViewer();
public boolean isViewerEnabled();
public String getCurrentEndpoint();
}

Просмотреть файл

@ -4,6 +4,9 @@
//
package com.microsoft.applications.events;
import java.util.Date;
import java.util.UUID;
public class LogManagerProvider {
public static ILogManager createLogManager(ILogConfiguration config) {
return new LogManagerImpl(nativeCreateLogManager(config));
@ -20,9 +23,11 @@ public class LogManagerProvider {
this.nativeLogManager = nativeLogManager;
}
private native long nativeGetLogger(String token, String source, String scope);
@Override
public ILogger getLogger(String tenantToken) {
return null;
public ILogger getLogger(String token, String source, String scope) {
return new Logger(nativeGetLogger(token, source, scope));
}
@Override
@ -39,6 +44,165 @@ public class LogManagerProvider {
}
protected native void nativeClose(long nativeLogManager);
protected native void nativeFlushAndTeardown(long nativeLogManager);
@Override
public void flushAndTeardown() {}
protected native int nativeFlush(long nativeLogManager);
@Override
public Status flush() {
return Status.getEnum(nativeFlush(nativeLogManager));
}
protected native int nativeUploadNow(long nativeLogManager);
@Override
public Status uploadNow() {
return Status.SUCCESS;
}
protected native int nativePauseTransmission(long nativeLogManager);
@Override
public Status pauseTransmission() {
return Status.getEnum(nativePauseTransmission(nativeLogManager));
}
protected native int nativeResumeTransmission(long nativeLogManager);
@Override
public Status resumeTransmission() {
return Status.getEnum(nativeResumeTransmission(nativeLogManager));
}
protected native int nativeSetTransmitProfileTP(long nativeLogManager, int profile);
@Override
public Status setTransmitProfile(TransmitProfile profile) {
return Status.getEnum(nativeSetTransmitProfileTP(nativeLogManager, profile.getValue()));
}
protected native int nativeSetTransmitProfileS(long nativeLogManager, String profile);
@Override
public Status setTransmitProfile(String profile) {
return Status.getEnum(nativeSetTransmitProfileS(nativeLogManager, profile));
}
protected native int nativeLoadTransmitProfiles(long nativeLogManager, String json);
@Override
public Status loadTransmitProfiles(String profilesJson) {
return Status.getEnum(nativeLoadTransmitProfiles(nativeLogManager, profilesJson));
}
protected native int nativeResetTransmitProfiles(long nativeLogManager);
@Override
public Status resetTransmitProfiles() {
return Status.getEnum(nativeResetTransmitProfiles(nativeLogManager));
}
protected native String nativeGetTransmitProfileName(long nativeLogManager);
@Override
public String getTransmitProfileName() {
return nativeGetTransmitProfileName(nativeLogManager);
}
protected native long nativeGetSemanticContext(long nativeLogManager);
@Override
public ISemanticContext getSemanticContext() {
return new SemanticContext(nativeGetSemanticContext(nativeLogManager));
}
protected native int nativeSetContextString(
long nativeLogManager, String name, String value, int piiKind);
@Override
public Status setContext(final String name, final String value, final PiiKind piiKind) {
return Status.getEnum(
nativeSetContextString(nativeLogManager, name, value, piiKind.getValue()));
}
protected native int nativeSetContextInt(
long nativeLogManager, String name, int value, int piiKind);
@Override
public Status setContext(final String name, final int value, final PiiKind piiKind) {
return Status.getEnum(nativeSetContextInt(nativeLogManager, name, value, piiKind.getValue()));
}
protected native int nativeSetContextLong(
long nativeLogManager, String name, long value, int piiKind);
@Override
public Status setContext(final String name, final long value, final PiiKind piiKind) {
return Status.getEnum(nativeSetContextLong(nativeLogManager, name, value, piiKind.getValue()));
}
protected native int nativeSetContextDouble(
long nativeLogManager, String name, double value, int piiKind);
@Override
public Status setContext(final String name, final double value, final PiiKind piiKind) {
return Status.getEnum(nativeSetContextDouble(nativeLogManager, name, value, piiKind.getValue()));
}
protected native int nativeSetContextBoolean(
long nativeLogManager, String name, boolean value, int piiKind);
@Override
public Status setContext(final String name, final boolean value, final PiiKind piiKind) {
return Status.getEnum(nativeSetContextBoolean(nativeLogManager, name, value, piiKind.getValue()));
}
protected native int nativeSetContextDate(
long nativeLogManager, String name, Date value, int piiKind);
@Override
public Status setContext(final String name, final Date value, final PiiKind piiKind) {
return Status.getEnum(nativeSetContextDate(nativeLogManager, name, value, piiKind.getValue()));
}
protected native int nativeSetContextUUID(
long nativeLogManager, String name, String value, int piiKind);
@Override
public Status setContext(final String name, final UUID value, final PiiKind piiKind) {
return Status.getEnum(nativeSetContextUUID(nativeLogManager, name, value.toString(), piiKind.getValue()));
}
protected native boolean nativeInitializeDDV(long nativeLogManager, String machineIdentifier, String endpoint);
@Override
public boolean initializeDiagnosticDataViewer(String machineIdentifier, String endpoint) {
return nativeInitializeDDV(nativeLogManager, machineIdentifier, endpoint);
}
protected native void nativeDisableViewer(long nativeLogManager);
@Override
public void disableViewer() {
nativeDisableViewer(nativeLogManager);
}
protected native boolean nativeIsViewerEnabled(long nativeLogManager);
@Override
public boolean isViewerEnabled() {
return false;
}
protected native String nativeGetCurrentEndpoint(long nativeLogManager);
@Override
public String getCurrentEndpoint() {
return nativeGetCurrentEndpoint(nativeLogManager);
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

@ -1 +1 @@
Subproject commit bf9497940531fdedb99b3de7d002b9a92a940552
Subproject commit d01471fa862732d63695a20dda8c4fb1a3ab96c7