Merge branch 'master' into mkoscumb-make-eventuploadcontextpr-smart

This commit is contained in:
Matthew Koscumb 2020-07-08 16:32:07 -07:00 коммит произвёл GitHub
Родитель c745b1c0f0 9a67b4a478
Коммит d1bdd22846
9 изменённых файлов: 406 добавлений и 184 удалений

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

@ -165,4 +165,61 @@ public class SDKUnitNativeTest extends MaeUnitLogger {
assertThat((LogConfigurationImpl) postConfig, isValueSuperset(current));
}
}
@Test
public void roundTripConfigLong() {
System.loadLibrary("maesdk");
ILogConfiguration config = LogManager.logConfigurationFactory();
config.set(LogConfigurationKey.CFG_INT_METASTATS_INTERVAL, (long) 23);
ILogConfiguration mangled = config.roundTrip();
assertThat((LogConfigurationImpl) mangled, isValueSuperset(config));
}
@Test
public void roundTripConfigBool() {
System.loadLibrary("maesdk");
ILogConfiguration config = LogManager.logConfigurationFactory();
config.set(LogConfigurationKey.CFG_BOOL_COMPAT_DOTS, false);
ILogConfiguration mangled = config.roundTrip();
assertThat((LogConfigurationImpl) mangled, isValueSuperset(config));
}
@Test
public void roundTripConfigString() {
System.loadLibrary("maesdk");
ILogConfiguration config = LogManager.logConfigurationFactory();
config.set(LogConfigurationKey.CFG_STR_PRIMARY_TOKEN, "foobar");
ILogConfiguration mangled = config.roundTrip();
assertThat((LogConfigurationImpl) mangled, isValueSuperset(config));
}
@Test
public void roundTripConfigMap() {
System.loadLibrary("maesdk");
ILogConfiguration submap = LogManager.logConfigurationFactory();
submap.set(LogConfigurationKey.CFG_INT_METASTATS_INTERVAL, (long) 23);
ILogConfiguration config = LogManager.logConfigurationFactory();
config.set(LogConfigurationKey.CFG_MAP_FACTORY_CONFIG, submap);
ILogConfiguration mangled = config.roundTrip();
assertThat((LogConfigurationImpl) mangled, isValueSuperset(config));
}
@Test
public void roundTripConfigArray() {
System.loadLibrary("maesdk");
Long[] foobar = new Long[7];
for (int i = 0; i < 7; ++i) {
foobar[i] = Long.valueOf(i);
}
ILogConfiguration config = LogManager.logConfigurationFactory();
config.set("foobar", foobar);
ILogConfiguration mangled = config.roundTrip();
assertThat((LogConfigurationImpl) mangled, isValueSuperset(config));
}
}

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

@ -1,111 +1,119 @@
#include <jni.h>
#include <android/log.h>
#include <string>
#include "gtest/gtest.h"
#include <android/log.h>
#include <jni.h>
#include <string>
#include "LogManager.hpp"
#include "api/LogManagerImpl.hpp"
LOGMANAGER_INSTANCE
class RunTests {
public:
static int run_all_tests(JNIEnv * env, jobject logger);
class RunTests
{
public:
static int run_all_tests(JNIEnv* env, jobject logger);
};
class AndroidLogger : public ::testing::EmptyTestEventListener {
class AndroidLogger : public ::testing::EmptyTestEventListener
{
jobject m_logger = nullptr;
JNIEnv *m_env = nullptr;
JNIEnv* m_env = nullptr;
constexpr static bool immediateJavaLogging = false;
public:
AndroidLogger(JNIEnv *env, jobject logger)
: m_logger(logger)
, m_env(env)
{}
void OnTestPartResult(const ::testing::TestPartResult &test_part_result) override {
public:
AndroidLogger(JNIEnv* env, jobject logger) :
m_logger(logger), m_env(env)
{
}
void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override
{
int prio = ANDROID_LOG_INFO;
const char * sf_string = "SUCCESS";
if (test_part_result.failed()) {
const char* sf_string = "SUCCESS";
if (test_part_result.failed())
{
prio = ANDROID_LOG_WARN;
sf_string = "FAILURE";
}
__android_log_print(
prio, "MAE",
"%s (%s: %d): %s\n",
sf_string,
test_part_result.file_name(),
test_part_result.line_number(),
test_part_result.summary()
);
if (immediateJavaLogging && m_logger && m_env && test_part_result.failed()) {
prio, "MAE",
"%s (%s: %d): %s\n",
sf_string,
test_part_result.file_name(),
test_part_result.line_number(),
test_part_result.summary());
if (immediateJavaLogging && m_logger && m_env && test_part_result.failed())
{
auto logger_class = m_env->GetObjectClass(m_logger);
if (!logger_class) {
if (!logger_class)
{
return;
}
auto method_id = m_env->GetMethodID(
logger_class,
"log_failure",
"(Ljava/lang/String;ILjava/lang/String;)V");
if (!method_id) {
logger_class,
"log_failure",
"(Ljava/lang/String;ILjava/lang/String;)V");
if (!method_id)
{
return;
}
m_env->CallVoidMethod(
m_logger,
method_id,
m_env->NewStringUTF(test_part_result.file_name()),
test_part_result.line_number(),
m_env->NewStringUTF(test_part_result.summary())
);
m_logger,
method_id,
m_env->NewStringUTF(test_part_result.file_name()),
test_part_result.line_number(),
m_env->NewStringUTF(test_part_result.summary()));
}
}
void OnTestStart(const ::testing::TestInfo& test_info) override {
void OnTestStart(const ::testing::TestInfo& test_info) override
{
auto param = test_info.value_param();
__android_log_print(
ANDROID_LOG_INFO,
"MAE",
"Start %s.%s\n",
test_info.test_case_name(),
test_info.name()
);
ANDROID_LOG_INFO,
"MAE",
"Start %s.%s\n",
test_info.test_case_name(),
test_info.name());
}
void OnTestEnd(const ::testing::TestInfo& test_info) override {
void OnTestEnd(const ::testing::TestInfo& test_info) override
{
__android_log_print(
ANDROID_LOG_INFO,
"MAE",
"End %s.%s: %s\n",
test_info.test_case_name(),
test_info.name(),
test_info.result()->Failed() ? "FAIL" : "OK"
);
ANDROID_LOG_INFO,
"MAE",
"End %s.%s: %s\n",
test_info.test_case_name(),
test_info.name(),
test_info.result()->Failed() ? "FAIL" : "OK");
}
void OnTestProgramEnd(const ::testing::UnitTest& unit) override {
void OnTestProgramEnd(const ::testing::UnitTest& unit) override
{
__android_log_print(ANDROID_LOG_INFO,
"MAE",
"%zu dead loggers", LogManagerImpl::GetDeadLoggerCount());
__android_log_print(
ANDROID_LOG_INFO,
"MAE",
"End tests: %d success, %d fail, %d total",
unit.successful_test_count(),
unit.failed_test_count(),
unit.total_test_count()
);
ANDROID_LOG_INFO,
"MAE",
"End tests: %d success, %d fail, %d total",
unit.successful_test_count(),
unit.failed_test_count(),
unit.total_test_count());
}
};
int RunTests::run_all_tests(JNIEnv * env, jobject java_logger)
int RunTests::run_all_tests(JNIEnv* env, jobject java_logger)
{
int argc = 2;
char command_name[] = "maesdk-test";
char filter[] = "--gtest_filter=*";
char *argv[] = { command_name, filter };
char* argv[] = {command_name, filter};
::testing::InitGoogleTest(&argc, argv);
::testing::TestEventListeners& listeners =
::testing::UnitTest::GetInstance()->listeners();
::testing::UnitTest::GetInstance()->listeners();
listeners.Append(new AndroidLogger(env, java_logger));
auto logger = Microsoft::Applications::Events::LogManager::Initialize("0123456789abcdef0123456789abcdef-01234567-0123-0123-0123-0123456789ab-0123");
return RUN_ALL_TESTS();
@ -113,9 +121,10 @@ int RunTests::run_all_tests(JNIEnv * env, jobject java_logger)
extern "C" JNIEXPORT jstring JNICALL
Java_com_microsoft_applications_events_maesdktest_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */,
jstring path) {
JNIEnv* env,
jobject /* this */,
jstring path)
{
auto result = RunTests::run_all_tests(env, path);
std::string hello = std::to_string(result);
return env->NewStringUTF(hello.c_str());
@ -124,10 +133,9 @@ Java_com_microsoft_applications_events_maesdktest_MainActivity_stringFromJNI(
extern "C" JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_maesdktest_TestStub_runNativeTests(
JNIEnv *env,
jobject /* stub */,
jobject logger
)
JNIEnv* env,
jobject /* stub */,
jobject logger)
{
return RunTests::run_all_tests(env, logger);
}

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

@ -24,4 +24,5 @@ public interface ILogConfiguration {
public void set(String key, Object value);
public ILogConfiguration roundTrip();
}

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

@ -1,6 +1,5 @@
package com.microsoft.applications.events;
import android.util.Log;
import androidx.annotation.Keep;
import java.util.Date;
import java.util.NavigableSet;
@ -19,7 +18,6 @@ public class LogManager {
* <p>The C++ side can translate values of type Boolean, Long, String, ILogConfiguration (nested
* maps) and arrays of these types (including nested arrays).
*/
public static class LogConfigurationImpl implements ILogConfiguration {
TreeMap<String, Object> configMap;
@ -51,15 +49,14 @@ public class LogManager {
}
/**
* Intended for unit tests: does this instance contain all of the
* non-null-valued key-value pairs of the other instance?
* Intended for unit tests: does this instance contain all of the non-null-valued key-value
* pairs of the other instance?
*
* @param subset the subset configuration
* @return true if the other is castable to ILogConfigurationImpl and all of its non-null
* content appears in this ILogConfigurationImpl
* content appears in this ILogConfigurationImpl
*/
public boolean valueContainsAll(LogConfigurationImpl subset, StringBuffer failure)
{
public boolean valueContainsAll(LogConfigurationImpl subset, StringBuffer failure) {
NavigableSet<String> keySet = subset.configMap.navigableKeySet();
for (String k : keySet) {
Object v = subset.configMap.get(k);
@ -79,8 +76,10 @@ public class LogManager {
continue;
}
if (!superV.getClass().isAssignableFrom(v.getClass())) {
failure.append(String.format("Value for key %s is class %s in superset, %s in subset",
superV.getClass().getName(), v.getClass().getName()));
failure.append(
String.format(
"Value for key %s is class %s in superset, %s in subset",
k, superV.getClass().getName(), v.getClass().getName()));
return false;
}
if (LogConfigurationImpl.class.isAssignableFrom(superV.getClass())) {
@ -92,9 +91,53 @@ public class LogManager {
failure.append(String.format("Sub-map %s: %s", k, subFailure));
return false;
}
if (superV.getClass().isArray()) {
if (!v.getClass().isArray()) {
failure.append(String.format("Super array %s: %s, sub %s", k, superV, v));
return false;
}
Object[] superVA = (Object[]) superV;
Object[] vA = (Object[]) v;
if (superVA.length != vA.length) {
failure.append(
String.format("Super array length %s: %d, sub %d", k, superVA.length, vA.length));
return false;
}
for (int i = 0; i < superVA.length; i += 1) {
Object superE = superVA[i];
Object subE = vA[i];
if (subE == null) {
continue;
}
if (superE == null) {
failure.append(String.format("Super %s[%d] is null", k, i));
return false;
}
if (!superE.getClass().isAssignableFrom(subE.getClass())) {
failure.append(
String.format(
"Value for key %s[%d] is class %s in superset, %s in subset",
k, i, superE.getClass().getName(), subE.getClass().getName()));
return false;
}
if (LogConfigurationImpl.class.isAssignableFrom(superE.getClass())) {
LogConfigurationImpl superMap = (LogConfigurationImpl) superE;
StringBuffer subFailure = new StringBuffer();
if (superMap.valueContainsAll((LogConfigurationImpl) subE, subFailure)) {
continue;
}
failure.append(String.format("Sub-map %s: %s", k, subFailure));
return false;
}
if (!superE.equals(superE.getClass().cast(subE))) {
failure.append(String.format("not equal %s[%d]: %s != %s", k, i, superE, subE));
return false;
}
}
continue;
}
if (!superV.equals(superV.getClass().cast(v))) {
String s = String.format("key %s, superset value %s, subset %s",
k, superV, v);
String s = String.format("key %s, superset value %s, subset %s", k, superV, v);
failure.append(s);
return false;
}
@ -117,8 +160,7 @@ public class LogManager {
}
@Override
public String toString()
{
public String toString() {
return configMap.toString();
}
@ -284,6 +326,9 @@ public class LogManager {
configMap.put(key, value);
}
@Override
public native ILogConfiguration roundTrip();
/**
* Return all keys as an array of String
*

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

@ -53,7 +53,13 @@ namespace ARIASDK_NS_BEGIN
m_deadLoggers.emplace_back(std::move(kv.second));
assert(!kv.second);
}
source.clear(); // source is dead
source.clear(); // source is dead
}
size_t DeadLoggers::GetDeadLoggerCount() const noexcept
{
std::lock_guard<std::mutex> lock(m_deadLoggersMutex);
return m_deadLoggers.size();
}
bool ILogManager::DispatchEventBroadcast(DebugEvent evt)
@ -306,6 +312,11 @@ namespace ARIASDK_NS_BEGIN
ILogManagerInternal::managers.erase(this);
}
size_t LogManagerImpl::GetDeadLoggerCount()
{
return s_deadLoggers.GetDeadLoggerCount();
}
void LogManagerImpl::FlushAndTeardown()
{
LOG_INFO("Shutting down...");

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

@ -7,11 +7,11 @@
#include "system/Contexts.hpp"
#include "IDecorator.hpp"
#include "IHttpClient.hpp"
#include "ILogManager.hpp"
#include "IModule.hpp"
#include "ITaskDispatcher.hpp"
#include "IDecorator.hpp"
#include "api/ContextFieldsProvider.hpp"
#include "api/Logger.hpp"
@ -124,10 +124,11 @@ namespace ARIASDK_NS_BEGIN
class DeadLoggers
{
public:
void AddMap(LoggerMap && source);
void AddMap(LoggerMap&& source);
size_t GetDeadLoggerCount() const noexcept;
std::vector<std::unique_ptr<Logger>> m_deadLoggers;
std::mutex m_deadLoggersMutex;
mutable std::mutex m_deadLoggersMutex;
};
class LogManagerImpl : public ILogManagerInternal
@ -282,6 +283,8 @@ namespace ARIASDK_NS_BEGIN
return m_context;
}
static size_t GetDeadLoggerCount();
protected:
std::unique_ptr<ITelemetrySystem>& GetSystem();
void InitializeModules() noexcept;

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

@ -10,7 +10,8 @@ ILogManager* LogManagerBase<WrapperConfig>::instance{};
extern "C"
{
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeInitializeWithoutTenantToken(
JNIEXPORT jlong JNICALL
Java_com_microsoft_applications_events_LogManager_nativeInitializeWithoutTenantToken(
JNIEnv* /* env */,
jclass /* LogManager.class */)
{
@ -18,7 +19,8 @@ extern "C"
return reinterpret_cast<jlong>(logger);
}
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeInitializeWithTenantToken(
JNIEXPORT jlong JNICALL
Java_com_microsoft_applications_events_LogManager_nativeInitializeWithTenantToken(
JNIEnv* env,
jclass /* LogManager.class */,
jstring jTenantToken)
@ -28,42 +30,48 @@ extern "C"
return reinterpret_cast<jlong>(logger);
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeFlushAndTeardown(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeFlushAndTeardown(
JNIEnv* /* env */,
jclass /* LogManager.class */)
{
return static_cast<jint>(WrapperLogManager::FlushAndTeardown());
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeFlush(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeFlush(
JNIEnv* /* env */,
jclass /* this */)
{
return static_cast<jint>(WrapperLogManager::Flush());
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeUploadNow(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeUploadNow(
JNIEnv* /* env */,
jclass /* this */)
{
return static_cast<jint>(WrapperLogManager::UploadNow());
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativePauseTransmission(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativePauseTransmission(
JNIEnv* /* env */,
jclass /* this */)
{
return static_cast<jint>(WrapperLogManager::PauseTransmission());
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeResumeTransmission(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeResumeTransmission(
JNIEnv* /* env */,
jclass /* this */)
{
return static_cast<jint>(WrapperLogManager::ResumeTransmission());
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetIntTransmitProfile(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeSetIntTransmitProfile(
JNIEnv* /* env */,
jclass /* this */,
jint jProfile)
@ -72,30 +80,36 @@ extern "C"
static_cast<TransmitProfile>(jProfile)));
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetTransmitProfileString(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeSetTransmitProfileString(
JNIEnv* env,
jclass /* this */,
jstring jstrProfile)
{
return static_cast<jint>(WrapperLogManager::SetTransmitProfile(JStringToStdString(env, jstrProfile)));
return static_cast<jint>(WrapperLogManager::SetTransmitProfile(
JStringToStdString(env, jstrProfile)));
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeLoadTransmitProfilesString(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeLoadTransmitProfilesString(
JNIEnv* env,
jclass /* this */,
jstring jstrProfilesJson)
{
return static_cast<jint>(WrapperLogManager::LoadTransmitProfiles(JStringToStdString(env, jstrProfilesJson)));
return static_cast<jint>(WrapperLogManager::LoadTransmitProfiles(
JStringToStdString(env, jstrProfilesJson)));
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeResetTransmitProfiles(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeResetTransmitProfiles(
JNIEnv* /* env */,
jclass /* this */)
{
return static_cast<jint>(WrapperLogManager::ResetTransmitProfiles());
}
JNIEXPORT jstring JNICALL Java_com_microsoft_applications_events_LogManager_getTransmitProfileName(
JNIEXPORT jstring JNICALL
Java_com_microsoft_applications_events_LogManager_getTransmitProfileName(
JNIEnv* env,
jclass /* this */)
{
@ -103,14 +117,16 @@ extern "C"
return static_cast<jstring>(env->NewStringUTF(profileName.c_str()));
}
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeGetSemanticContext(
JNIEXPORT jlong JNICALL
Java_com_microsoft_applications_events_LogManager_nativeGetSemanticContext(
JNIEnv* env,
jclass /* this */)
{
return reinterpret_cast<jlong>(WrapperLogManager::GetSemanticContext());
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextStringValue(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeSetContextStringValue(
JNIEnv* env,
jclass /* this */,
jstring jstrName,
@ -119,10 +135,13 @@ extern "C"
{
auto name = JStringToStdString(env, jstrName);
auto value = JStringToStdString(env, jstrValue);
return static_cast<jint>(WrapperLogManager::SetContext(name, value, static_cast<PiiKind>(piiKind)));
return static_cast<jint>(WrapperLogManager::SetContext(name,
value,
static_cast<PiiKind>(piiKind)));
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextIntValue(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeSetContextIntValue(
JNIEnv* env,
jclass /* this */,
jstring jstrName,
@ -130,10 +149,13 @@ extern "C"
jint piiKind)
{
auto name = JStringToStdString(env, jstrName);
return static_cast<jint>(WrapperLogManager::SetContext(name, static_cast<int32_t>(jValue), static_cast<PiiKind>(piiKind)));
return static_cast<jint>(WrapperLogManager::SetContext(name,
static_cast<int32_t>(jValue),
static_cast<PiiKind>(piiKind)));
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextLongValue(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeSetContextLongValue(
JNIEnv* env,
jclass /* this */,
jstring jstrName,
@ -141,10 +163,13 @@ extern "C"
jint piiKind)
{
auto name = JStringToStdString(env, jstrName);
return static_cast<jint>(WrapperLogManager::SetContext(name, static_cast<int64_t>(jValue), static_cast<PiiKind>(piiKind)));
return static_cast<jint>(WrapperLogManager::SetContext(name,
static_cast<int64_t>(jValue),
static_cast<PiiKind>(piiKind)));
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextDoubleValue(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeSetContextDoubleValue(
JNIEnv* env,
jclass /* this */,
jstring jstrName,
@ -152,10 +177,13 @@ extern "C"
jint piiKind)
{
auto name = JStringToStdString(env, jstrName);
return static_cast<jint>(WrapperLogManager::SetContext(name, static_cast<double>(jValue), static_cast<PiiKind>(piiKind)));
return static_cast<jint>(WrapperLogManager::SetContext(name,
static_cast<double>(jValue),
static_cast<PiiKind>(piiKind)));
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextBoolValue(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeSetContextBoolValue(
JNIEnv* env,
jclass /* this */,
jstring jstrName,
@ -163,10 +191,13 @@ extern "C"
jint piiKind)
{
auto name = JStringToStdString(env, jstrName);
return static_cast<jint>(WrapperLogManager::SetContext(name, static_cast<bool>(jValue), static_cast<PiiKind>(piiKind)));
return static_cast<jint>(WrapperLogManager::SetContext(name,
static_cast<bool>(jValue),
static_cast<PiiKind>(piiKind)));
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextTimeTicksValue(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeSetContextTimeTicksValue(
JNIEnv* env,
jclass /* this */,
jstring jstrName,
@ -174,10 +205,14 @@ extern "C"
jint piiKind)
{
auto name = JStringToStdString(env, jstrName);
return static_cast<jint>(WrapperLogManager::SetContext(name, time_ticks_t(static_cast<uint64_t>(jValue)), static_cast<PiiKind>(piiKind)));
return static_cast<jint>(WrapperLogManager::SetContext(name,
time_ticks_t(
static_cast<uint64_t>(jValue)),
static_cast<PiiKind>(piiKind)));
}
JNIEXPORT jint JNICALL Java_com_microsoft_applications_events_LogManager_nativeSetContextGuidValue(
JNIEXPORT jint JNICALL
Java_com_microsoft_applications_events_LogManager_nativeSetContextGuidValue(
JNIEnv* env,
jclass /* this */,
jstring jstrName,
@ -186,10 +221,13 @@ extern "C"
{
auto name = JStringToStdString(env, jstrName);
auto value = JStringToStdString(env, jstrValue);
return static_cast<jint>(WrapperLogManager::SetContext(name, GUID_t(value.c_str()), static_cast<PiiKind>(piiKind)));
return static_cast<jint>(WrapperLogManager::SetContext(name,
GUID_t(value.c_str()),
static_cast<PiiKind>(piiKind)));
}
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeGetLogger(
JNIEXPORT jlong JNICALL
Java_com_microsoft_applications_events_LogManager_nativeGetLogger(
JNIEnv* /* env */,
jclass /* this */)
{
@ -197,7 +235,8 @@ extern "C"
return reinterpret_cast<jlong>(logger);
}
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeGetLoggerWithSource(
JNIEXPORT jlong JNICALL
Java_com_microsoft_applications_events_LogManager_nativeGetLoggerWithSource(
JNIEnv* env,
jclass /* this */,
jstring jstrSource)
@ -207,7 +246,8 @@ extern "C"
return reinterpret_cast<jlong>(logger);
}
JNIEXPORT jlong JNICALL Java_com_microsoft_applications_events_LogManager_nativeGetLoggerWithTenantTokenAndSource(
JNIEXPORT jlong JNICALL
Java_com_microsoft_applications_events_LogManager_nativeGetLoggerWithTenantTokenAndSource(
JNIEnv* env,
jclass /* this */,
jstring jstrTenantToken,
@ -223,9 +263,9 @@ extern "C"
namespace
{
/**
* helper function: rethrow any exceptions from reverse-JNI calls
* @param env
*/
* helper function: rethrow any exceptions from reverse-JNI calls
* @param env
*/
void rethrow(JNIEnv* env)
{
if (env->ExceptionCheck())
@ -236,8 +276,8 @@ namespace
}
/**
* Smart object to manage PushLocalFrame/PopLocalFrame
*/
* Smart object to manage PushLocalFrame/PopLocalFrame
*/
class FrameWrapper
{
@ -249,8 +289,8 @@ namespace
public:
/*
* Constructor: takes JNIEnv* and the desired LocalStack frame depth
*/
* Constructor: takes JNIEnv* and the desired LocalStack frame depth
*/
FrameWrapper(JNIEnv* e, size_t s) :
env(e),
frameSize(s)
@ -260,11 +300,11 @@ namespace
}
/**
* Set the reference that will survive PopLocalFrame (as a new
* reference in the outer frame).
* @param r Object that should survive
* @return Previous result value
*/
* Set the reference that will survive PopLocalFrame (as a new
* reference in the outer frame).
* @param r Object that should survive
* @return Previous result value
*/
jobject* setResult(jobject* r)
{
jobject* t = result;
@ -273,8 +313,8 @@ namespace
}
/**
* On destruction, pop the frame with an optional result object.
*/
* On destruction, pop the frame with an optional result object.
*/
virtual ~FrameWrapper()
{
jobject localRef = nullptr;
@ -292,9 +332,9 @@ namespace
};
/**
* Enum of the types we know how to convert into a VariantMap or
* VariantArray.
*/
* Enum of the types we know how to convert into a VariantMap or
* VariantArray.
*/
enum class ValueTypes
{
BOOLEAN,
@ -305,18 +345,18 @@ namespace
};
/**
* POD to record how we handle each known value type
*/
* POD to record how we handle each known value type
*/
struct ValueInfo
{
/**
* JNI class reference for a known type
*/
* JNI class reference for a known type
*/
jclass valueClass;
/**
* Method ID for the method to cast into the primitive type for
* Long or Boolean
*/
* Method ID for the method to cast into the primitive type for
* Long or Boolean
*/
jmethodID castMethod;
};
@ -460,9 +500,10 @@ namespace
}
case ValueTypes::BOOLEAN:
{
auto booleanValue =
env->CallBooleanMethod(value,
kv.second.castMethod);
bool booleanValue =
(env->CallBooleanMethod(value,
kv.second.castMethod) ==
JNI_TRUE);
rethrow(env);
return Variant(booleanValue);
}
@ -541,10 +582,12 @@ namespace
this->env = env;
auto boolClass = env->FindClass("java/lang/Boolean");
rethrow(env);
auto truthField = env->GetStaticFieldID(boolClass, "TRUE", "Ljava/lang/Boolean;");
auto truthField =
env->GetStaticFieldID(boolClass, "TRUE", "Ljava/lang/Boolean;");
rethrow(env);
boolTrue = env->GetStaticObjectField(boolClass, truthField);
auto untruthField = env->GetStaticFieldID(boolClass, "FALSE", "Ljava/lang/Boolean;");
auto untruthField =
env->GetStaticFieldID(boolClass, "FALSE", "Ljava/lang/Boolean;");
rethrow(env);
boolFalse = env->GetStaticObjectField(boolClass, untruthField);
doubleClass = env->FindClass("java/lang/Double");
@ -557,11 +600,14 @@ namespace
rethrow(env);
objectClass = env->FindClass("java/lang/Object");
rethrow(env);
configClass = env->FindClass("com/microsoft/applications/events/LogManager$LogConfigurationImpl");
configClass = env->FindClass(
"com/microsoft/applications/events/LogManager$LogConfigurationImpl");
rethrow(env);
configInit = env->GetMethodID(configClass, "<init>", "()V");
rethrow(env);
setMethod = env->GetMethodID(configClass, "set", "(Ljava/lang/String;Ljava/lang/Object;)V");
setMethod = env->GetMethodID(configClass,
"set",
"(Ljava/lang/String;Ljava/lang/Object;)V");
rethrow(env);
}
@ -716,18 +762,24 @@ Java_com_microsoft_applications_events_LogManagerProvider_nativeCreateLogManager
VariantTranslator variantTranslator(env);
size_t n;
{
std::lock_guard<std::mutex> lock(jniManagersMutex);
n = jniManagers.size();
jniManagers.emplace_back();
}
variantTranslator.translateVariantMap(*jniManagers[n].config, configuration);
variantTranslator.translateVariantMap(*jniManagers[n].config,
configuration);
status_t status = status_t::STATUS_SUCCESS;
jniManagers[n].manager = MAT::LogManagerProvider::CreateLogManager(jniManagers.back().config, status);
jniManagers[n].manager = MAT::LogManagerProvider::CreateLogManager(
jniManagers[n].config,
status);
if (status == status_t::STATUS_SUCCESS && !!jniManagers[n].manager)
{
return n;
}
__android_log_print(ANDROID_LOG_ERROR, "MAE", "Failed to create log manager");
__android_log_print(ANDROID_LOG_ERROR,
"MAE",
"Failed to create log manager");
return -1;
}
@ -757,10 +809,12 @@ Java_com_microsoft_applications_events_LogManagerProvider_00024LogManagerImpl_na
jobject /* this */,
jlong nativeLogManager)
{
std::lock_guard<std::mutex> lock(jniManagersMutex);
if (nativeLogManager < 0 || nativeLogManager >= jniManagers.size())
{
return;
std::lock_guard<std::mutex> lock(jniManagersMutex);
if (nativeLogManager < 0 || nativeLogManager >= jniManagers.size())
{
return;
}
}
if (!jniManagers[nativeLogManager].manager)
{
@ -768,4 +822,17 @@ Java_com_microsoft_applications_events_LogManagerProvider_00024LogManagerImpl_na
}
MAT::LogManagerProvider::Release(jniManagers[nativeLogManager].config);
jniManagers[nativeLogManager].manager = nullptr;
}
extern "C" JNIEXPORT jobject JNICALL
Java_com_microsoft_applications_events_LogManager_00024LogConfigurationImpl_roundTrip(
JNIEnv* env,
jobject thiz)
{
ILogConfiguration logConfiguration;
VariantTranslator variantTranslator(env);
variantTranslator.translateVariantMap(*logConfiguration, thiz);
ConfigConstructor builder(env);
return builder.mapTranslate(*logConfiguration);
}

@ -1 +1 @@
Subproject commit e98525cc9658454856c890ec17c72e1e0d799d76
Subproject commit bde1d6fa2bbf79fc6f63e4a948660354458f3ca0

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

@ -1,40 +1,53 @@
// Copyright (c) Microsoft. All rights reserved.
#include "common/Common.hpp"
#include "api/LogManagerImpl.hpp"
#include "common/Common.hpp"
using namespace testing;
using namespace MAT;
class TestLogManagerImpl : public LogManagerImpl
{
public:
TestLogManagerImpl(ILogConfiguration& configuration)
: TestLogManagerImpl(configuration, false) { }
TestLogManagerImpl(ILogConfiguration& configuration, bool deferSystemStart)
: LogManagerImpl(configuration, deferSystemStart) { }
public:
TestLogManagerImpl(ILogConfiguration& configuration) :
TestLogManagerImpl(configuration, false)
{
}
TestLogManagerImpl(ILogConfiguration& configuration, bool deferSystemStart) :
LogManagerImpl(configuration, deferSystemStart)
{
}
using LogManagerImpl::m_httpClient;
// using LogManagerImpl::m_ownHttpClient;
using LogManagerImpl::m_modules;
using LogManagerImpl::TeardownModules;
using LogManagerImpl::InitializeModules;
using LogManagerImpl::m_httpClient;
// using LogManagerImpl::m_ownHttpClient;
using LogManagerImpl::InitializeModules;
using LogManagerImpl::m_modules;
using LogManagerImpl::TeardownModules;
};
class TestHttpClient : public IHttpClient
{
virtual IHttpRequest* CreateRequest() override { return nullptr; }
virtual void SendRequestAsync(IHttpRequest*, IHttpResponseCallback*) override { }
virtual void CancelRequestAsync(std::string const&) override { }
public:
IHttpRequest* theOnlyRequest = nullptr;
virtual IHttpRequest* CreateRequest() override
{
return theOnlyRequest;
}
virtual void SendRequestAsync(IHttpRequest*, IHttpResponseCallback*) override
{
}
virtual void CancelRequestAsync(std::string const&) override
{
}
};
TEST(LogManagerImplTests, Constructor_HttpClientIsNullptr_ConstructsOwnHttpClient)
{
ILogConfiguration configuration;
ILogConfiguration configuration;
#ifdef HAVE_MAT_DEFAULT_HTTP_CLIENT
TestLogManagerImpl logManager { configuration };
ASSERT_NE(logManager.m_httpClient, nullptr);
TestLogManagerImpl logManager{configuration};
ASSERT_NE(logManager.m_httpClient, nullptr);
#else
EXPECT_THROW(TestLogManagerImpl { configuration }, std::invalid_argument);
EXPECT_THROW(TestLogManagerImpl{configuration}, std::invalid_argument);
#endif
}
@ -45,20 +58,37 @@ TEST(LogManagerImplTests, Constructor_HttpClientIsNotNullptr_HttpClientIsSet)
// ASSERT_EQ(logManager.m_httpClient, &httpClient);
auto httpClient = std::make_shared<TestHttpClient>();
configuration.AddModule(CFG_MODULE_HTTP_CLIENT, httpClient);
TestLogManagerImpl logManager { configuration, true };
TestLogManagerImpl logManager{configuration, true};
ASSERT_EQ(logManager.m_httpClient, httpClient);
}
TEST(LogManagerImplTests, DeadLoggersAreDead)
{
ILogConfiguration configuration;
auto httpClient = std::make_shared<TestHttpClient>();
httpClient->theOnlyRequest = new SimpleHttpRequest("fred");
configuration.AddModule(CFG_MODULE_HTTP_CLIENT, httpClient);
size_t onEntry = LogManagerImpl::GetDeadLoggerCount();
TestLogManagerImpl logManager{configuration};
logManager.PauseTransmission();
ASSERT_EQ(onEntry, LogManagerImpl::GetDeadLoggerCount());
auto logger = logManager.GetLogger("fred");
logManager.FlushAndTeardown();
ASSERT_EQ(onEntry + 1, LogManagerImpl::GetDeadLoggerCount());
logger->LogEvent("DeadLoggerEvent");
}
class LogManagerModuleTests : public ::testing::Test
{
public:
public:
class TestModule : public IModule
{
public:
public:
TestModule(bool& initialzeCalled, bool& teardownCalled, const ILogManager*& pointerPassedToInitialize) noexcept
: initializeCalled(initialzeCalled)
, teardownCalled(teardownCalled)
, addressPassedToInitialize(pointerPassedToInitialize) { }
:
initializeCalled(initialzeCalled), teardownCalled(teardownCalled), addressPassedToInitialize(pointerPassedToInitialize)
{
}
virtual void Initialize(ILogManager* parentManager) noexcept override
{
@ -77,7 +107,7 @@ public:
};
ILogConfiguration configuration;
TestLogManagerImpl logManager{ configuration };
TestLogManagerImpl logManager{configuration};
const ILogManager* AddressPassedToInitialize{};
bool InitializeCalled{};
bool TeardownCalled{};
@ -109,13 +139,13 @@ TEST_F(LogManagerModuleTests, TeardownModules_OneModuleRegistered_UnregisterCall
TEST_F(LogManagerModuleTests, TeardownModules_OneModuleRegistered_SizeOfModulesIsZero)
{
logManager.TeardownModules();
ASSERT_EQ(logManager.m_modules.size(), size_t{ 0 });
ASSERT_EQ(logManager.m_modules.size(), size_t{0});
}
TEST(LogManagerImplTests, Constructor_DataViewerCollectionIsNotNullptr_DataViewerCollectionIsSet)
{
ILogConfiguration configuration;
TestHttpClient httpClient;
TestLogManagerImpl logManager { configuration, true };
TestLogManagerImpl logManager{configuration, true};
ASSERT_NO_THROW(logManager.GetDataViewerCollection());
}