diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b986a2ee..464e28a01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +22.09.1 +* Adding a way to override metrics sent by "begin session" requests. +* Fixed bug where "setApplicationVersion" would not set the application version in metrics +* ! Minor breaking change ! The following methods and their functionality are deprecated from the "Config" class and will not function anymore: + - "getApplicationName" + - "setApplicationName" + 22.09.0 * The "resetDeviceId", "login", and "logout" have been deprecated. * ! Minor breaking change ! The following methods and their functionality are deprecated from the "Config" class and will not function anymore: diff --git a/app-java/src/main/java/ly/count/java/demo/Sample.java b/app-java/src/main/java/ly/count/java/demo/Sample.java index 9173f9258..4dad57a3e 100755 --- a/app-java/src/main/java/ly/count/java/demo/Sample.java +++ b/app-java/src/main/java/ly/count/java/demo/Sample.java @@ -104,6 +104,10 @@ public static void main(String[] args) throws Exception { String COUNTLY_SERVER_URL = "https://try.count.ly/"; String COUNTLY_APP_KEY = "YOUR_APP_KEY"; + Map metricOverride = new HashMap<>(); + metricOverride.put("aa", "11"); + metricOverride.put("bb", "222"); + Config config = new Config(COUNTLY_SERVER_URL, COUNTLY_APP_KEY) .setLoggingLevel(Config.LoggingLevel.DEBUG) .setDeviceIdStrategy(Config.DeviceIdStrategy.UUID) @@ -115,7 +119,9 @@ public static void main(String[] args) throws Exception { public void LogHappened(String logMessage, Config.LoggingLevel logLevel) { System.out.println("[" + logLevel + "] " + logMessage); } - }); + }) + .setMetricOverride(metricOverride) + .setApplicationVersion("123.56.h"); // Countly needs persistent storage for requests, configuration storage, user profiles and other temporary data, // therefore requires a separate data folder to run diff --git a/gradle.properties b/gradle.properties index 9fd909834..163c9dac1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,39 +1,39 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true - -# RELEASE FIELD SECTION -VERSION_NAME=22.09.0 -GROUP=ly.count.sdk - -POM_URL=https://github.com/Countly/countly-sdk-java -POM_SCM_URL=https://github.com/Countly/countly-sdk-java - -POM_LICENCE_NAME=MIT License -POM_LICENCE_URL=http://www.opensource.org/licenses/mit-license.php -POM_LICENCE_DIST=repo - -POM_DEVELOPER_NAME=Countly - -#SIGNING SECTION -signing.keyId=xx -signing.password=xx -signing.secretKeyRingFile=xx - -mavenCentralUsername=xx -mavenCentralPassword=xx +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +# RELEASE FIELD SECTION +VERSION_NAME=22.09.1 +GROUP=ly.count.sdk + +POM_URL=https://github.com/Countly/countly-sdk-java +POM_SCM_URL=https://github.com/Countly/countly-sdk-java + +POM_LICENCE_NAME=MIT License +POM_LICENCE_URL=http://www.opensource.org/licenses/mit-license.php +POM_LICENCE_DIST=repo + +POM_DEVELOPER_NAME=Countly + +#SIGNING SECTION +signing.keyId=xx +signing.password=xx +signing.secretKeyRingFile=xx + +mavenCentralUsername=xx +mavenCentralPassword=xx diff --git a/sdk-java/src/main/java/ly/count/sdk/java/Config.java b/sdk-java/src/main/java/ly/count/sdk/java/Config.java index 38fd98368..78ec7b56b 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/Config.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/Config.java @@ -269,12 +269,7 @@ public boolean restore(byte[] data) { /** * Countly SDK version to be sent in HTTP requests */ - protected String sdkVersion = "22.09.0"; - - /** - * Countly Application name to be sent in HTTP requests - */ - protected String applicationName; + protected String sdkVersion = "22.09.1"; /** * Countly SDK version to be sent in HTTP requests @@ -291,6 +286,8 @@ public boolean restore(byte[] data) { */ protected boolean enableBackendMode = false; + protected Map metricOverride = new HashMap<>(); + /** * Salt string for parameter tampering protection */ @@ -892,13 +889,9 @@ public Config setSdkVersion(String sdkVersion) { * * @param name new name * @return {@code this} instance for method chaining + * @deprecated this will do nothing */ public Config setApplicationName(String name) { - if (Utils.isEmptyOrNull(name)) { - System.out.print("[ConfigCore] name cannot be empty"); - } else { - this.applicationName = name; - } return this; } @@ -1254,11 +1247,11 @@ public boolean isFeatureEnabled(int feature) { /** * Getter for {@link #applicationName} - * + * @deprecated will return empty string * @return {@link #applicationName} value */ public String getApplicationName() { - return applicationName; + return ""; } /** @@ -1414,5 +1407,15 @@ public Class getModuleOverride(int feature) { public boolean requiresConsent() { return requiresConsent; } + + /** + * Mechanism for overriding metrics that are sent together with "begin session" requests and remote config + * @param metricOverride map of values to be used for override + * @return {@code this} instance for method chaining + */ + public Config setMetricOverride(Map metricOverride) { + this.metricOverride.putAll(metricOverride); + return this; + } } diff --git a/sdk-java/src/main/java/ly/count/sdk/java/Countly.java b/sdk-java/src/main/java/ly/count/sdk/java/Countly.java index 9caff02d9..fb00e3f9e 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/Countly.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/Countly.java @@ -79,6 +79,12 @@ public static void init(final File directory, final Config config) { InternalConfig internalConfig = new InternalConfig(config); Log L = new Log(internalConfig.loggingLevel, internalConfig.logListener); + + device.setMetricOverride(internalConfig.getMetricOverride()); + if (internalConfig.getApplicationVersion() != null) { + device.setAppVersion(internalConfig.getApplicationVersion()); + } + SDKCore sdk = new SDKCore(); sdk.init(new CtxCore(sdk, internalConfig, L, directory), L); diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/Device.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/Device.java index 667c0d668..56cb42a00 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/internal/Device.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/Device.java @@ -7,8 +7,10 @@ import java.util.Calendar; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -31,6 +33,8 @@ public class Device { private Boolean online; private Boolean muted; + private Map metricOverride = new HashMap<>(); + protected Device() { dev = this; } @@ -50,62 +54,6 @@ public interface TimeGenerator { long timestamp(); } - /** - * Always increasing timer. - */ - static class UniformTimeGenerator implements TimeGenerator { - private Long last; - - @Override - public synchronized long timestamp() { - long ms = System.currentTimeMillis(); - if (last == null) { - last = ms; - } else if (last >= ms) { - last = last + 1; - return last; - } else { - last = ms; - } - return ms; - } - } - - /** - * Unique timer, keeps last 10 returned values in memory. - */ - static class UniqueTimeGenerator implements TimeGenerator { - List lastTsMs = new ArrayList<>(10); - long addition = 0; - - long currentTimeMillis() { - return System.currentTimeMillis() + addition; - } - - public synchronized long timestamp() { - long ms = currentTimeMillis(); - - // change time back case - if (lastTsMs.size() > 2) { - long min = Collections.min(lastTsMs); - if (ms < min) { - lastTsMs.clear(); - lastTsMs.add(ms); - return ms; - } - } - // usual case - while (lastTsMs.contains(ms)) { - ms += 1; - } - while (lastTsMs.size() >= 10) { - lastTsMs.remove(0); - } - lastTsMs.add(ms); - return ms; - } - } - protected TimeGenerator uniqueTimer = new UniqueTimeGenerator(); protected TimeGenerator uniformTimer = new UniformTimeGenerator(); @@ -149,19 +97,39 @@ public String getLocale() { /** * Build metrics {@link Params} object as required by Countly server - * - * @param ctx Ctx in which to request metrics */ - public Params buildMetrics(final CtxCore ctx) { + public Params buildMetrics() { Params params = new Params(); - params.obj("metrics") + Params.Obj metricObj = params.obj("metrics") .put("_device", getDevice()) .put("_os", getOS()) .put("_os_version", getOSVersion()) .put("_resolution", getResolution()) .put("_locale", getLocale()) - .put("_app_version", getAppVersion()) - .add(); + .put("_app_version", getAppVersion()); + + + //override metric values + if (metricOverride != null) { + for (String k : metricOverride.keySet()) { + if (k == null || k.length() == 0) { + //L.w("Provided metric override key can't be null or empty");//todo add log + continue; + } + + String overrideValue = metricOverride.get(k); + + if (overrideValue == null) { + //L.w("Provided metric override value can't be null, key:[" + k + "]");//todo add log + continue; + } + + metricObj.put(k, overrideValue); + } + } + + //add the object after adding the overrides + metricObj.add(); return params; } @@ -527,4 +495,9 @@ public Device setMuted(Boolean muted) { this.muted = muted; return this; } + + public Device setMetricOverride(Map givenMetricOverride) { + metricOverride.putAll(givenMetricOverride); + return this; + } } diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/DeviceIdGenerator.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/DeviceIdGenerator.java index 18bd42520..37c49723a 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/internal/DeviceIdGenerator.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/DeviceIdGenerator.java @@ -3,5 +3,5 @@ public interface DeviceIdGenerator { boolean isAvailable(); - String generate(CtxCore context, int realm); + String generate(CtxCore context); } diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/InternalConfig.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/InternalConfig.java index 8056020df..012b5aa2c 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/internal/InternalConfig.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/InternalConfig.java @@ -11,6 +11,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import ly.count.sdk.java.Config; @@ -120,7 +121,7 @@ public byte[] store() { stream.writeInt(loggingLevel.getLevel()); stream.writeUTF(sdkName); stream.writeUTF(sdkVersion); - stream.writeObject(applicationName); + stream.writeObject("name"); stream.writeObject(applicationVersion); stream.writeBoolean(usePOST); stream.writeObject(salt); @@ -211,7 +212,7 @@ public boolean restore(byte[] data) { sdkName = stream.readUTF(); sdkVersion = stream.readUTF(); - applicationName = (String) stream.readObject(); + String throwawayApplicationName = (String) stream.readObject();//we are only reading this for backwards compatibility. Throw away in the future applicationVersion = (String) stream.readObject(); usePOST = stream.readBoolean(); salt = (String) stream.readObject(); @@ -375,4 +376,8 @@ public Long getRemoteConfigUpdateTimeoutLength() { return remoteConfigUpdateRequestTimeout; } //endregion + + public Map getMetricOverride() { + return metricOverride; + } } diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleDeviceIdCore.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleDeviceIdCore.java index 3d1e41559..a5093dcbc 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleDeviceIdCore.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleDeviceIdCore.java @@ -30,7 +30,7 @@ public boolean isAvailable() { } @Override - public String generate(CtxCore context, int realm) { + public String generate(CtxCore context) { return UUID.randomUUID().toString(); } } @@ -42,7 +42,7 @@ public boolean isAvailable() { } @Override - public String generate(CtxCore context, int realm) { + public String generate(CtxCore context) { String customId = context.getConfig().getCustomDeviceId(); if (customId == null || customId.isEmpty()) { context.getLogger().e("[ModuleDeviceIdCore] Device ID should never be empty or null for CustomIDGenerator"); @@ -236,7 +236,7 @@ public byte[] doTheJob(Long id, byte[] data) { } /** - * Just a wrapper around {@link SDKInterface#onSignal(CtxCore, int, Byteable, Byteable)}} for {@link SDKCore.Signal#DID} case + * Just a wrapper around {@link SDKCore#onSignal(CtxCore, int, Byteable, Byteable)}} for {@link SDKCore.Signal#DID} case * * @param ctx Ctx to run in * @param id new {@link Config.DID} if any @@ -372,7 +372,7 @@ protected Config.DID acquireIdSync(final CtxCore ctx, final Config.DID holder, f return null; } } else { - String id = generator.generate(ctx, holder.realm); + String id = generator.generate(ctx); if (Utils.isNotEmpty(id)) { return new Config.DID(holder.realm, index, id); } else if (fallbackAllowed) { diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleRequests.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleRequests.java index cafaf9247..82b4fe0cc 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleRequests.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleRequests.java @@ -24,7 +24,7 @@ public void init(InternalConfig config, Log logger) { @Override public void onContextAcquired(CtxCore ctx) { super.onContextAcquired(ctx); - ModuleRequests.metrics = Device.dev.buildMetrics(ctx); + ModuleRequests.metrics = Device.dev.buildMetrics(); } @Override diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKCore.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKCore.java index 65b408e98..f04b64cc1 100644 --- a/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKCore.java +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKCore.java @@ -7,12 +7,13 @@ import java.util.*; import java.util.concurrent.Future; -public class SDKCore implements SDKInterface { +public class SDKCore { protected static SDKCore instance; protected SDKStorage sdkStorage; private UserImpl user; + public InternalConfig config; protected Networking networking; protected Queue requestQueueMemory = null; @@ -97,12 +98,10 @@ public boolean isTracking(Integer feat) { return modules != null && modules.containsKey(feat); } - @Override public void init(CtxCore ctx) { prepareMappings(ctx); } - @Override public void stop(final CtxCore ctx, final boolean clear) { if (instance == null) { return; @@ -358,7 +357,12 @@ protected void eachModule(Modulator modulator) { } } - @Override + /** + * Notify all {@link Module} instances about new session has just been started + * + * @param session session to begin + * @return supplied session for method chaining + */ public SessionImpl onSessionBegan(CtxCore ctx, SessionImpl session) { for (Module m : modules.values()) { m.onSessionBegan(session, ctx); @@ -366,7 +370,12 @@ public SessionImpl onSessionBegan(CtxCore ctx, SessionImpl session) { return session; } - @Override + /** + * Notify all {@link Module} instances session was ended + * + * @param session session to end + * @return supplied session for method chaining + */ public SessionImpl onSessionEnded(CtxCore ctx, SessionImpl session) { for (Module m : modules.values()) { m.onSessionEnded(session, ctx); @@ -378,7 +387,6 @@ public SessionImpl onSessionEnded(CtxCore ctx, SessionImpl session) { return session; } - @Override public SessionImpl getSession() { ModuleSessions sessions = (ModuleSessions) module(CoreFeature.Sessions.getIndex()); if (sessions != null) { @@ -387,7 +395,13 @@ public SessionImpl getSession() { return null; } - @Override + /** + * Get current {@link SessionImpl} or create new one if current is {@code null}. + * + * @param ctx Ctx to create new {@link SessionImpl} in + * @param id ID of new {@link SessionImpl} if needed + * @return current {@link SessionImpl} instance + */ public SessionImpl session(CtxCore ctx, Long id) { ModuleSessions sessions = (ModuleSessions) module(CoreFeature.Sessions.getIndex()); if (sessions != null) { @@ -529,7 +543,6 @@ public void run(int feature, Module module) { }); } - @Override public UserImpl user() { return user; } @@ -538,12 +551,10 @@ TimedEvents timedEvents() { return ((ModuleSessions) module(CoreFeature.Sessions.getIndex())).timedEvents(); } - @Override public InternalConfig config() { return config; } - @Override public void onCrash(CtxCore ctx, Throwable t, boolean fatal, String name, Map segments, String[] logs) { L.i("[SDKCore] [SDKCore] onCrash: t: " + t.toString() + " fatal: " + fatal + " name: " + name + " segments: " + segments); ModuleCrash module = (ModuleCrash) module(CoreFeature.CrashReporting.getIndex()); @@ -552,7 +563,6 @@ public void onCrash(CtxCore ctx, Throwable t, boolean fatal, String name, Map cohortsAdded, final Set cohortsRemoved) { eachModule(new Modulator() { @Override @@ -562,7 +572,6 @@ public void run(int feature, Module module) { }); } - @Override public void onDeviceId(CtxCore ctx, Config.DID id, Config.DID old) { L.d((config.isLimited() ? "limited" : "non-limited") + " onDeviceId " + id + ", old " + old); @@ -701,14 +710,13 @@ protected void recover(CtxCore ctx) { * Core instance config */ - @Override public void onSignal(CtxCore ctx, int id, Byteable param1, Byteable param2) { if (id == Signal.DID.getIndex()) { networking.check(ctx); } } - @Override + public void onSignal(CtxCore ctx, int id, String param) { if (id == Signal.Ping.getIndex()) { networking.check(ctx); @@ -741,7 +749,6 @@ private boolean processCrash(CtxCore ctx, Long id) { //transferred from original subclass - @Override public void onRequest(ly.count.sdk.java.internal.CtxCore ctx, Request request) { onSignal(ctx, SDKCore.Signal.Ping.getIndex(), null); } diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKInterface.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKInterface.java deleted file mode 100644 index 2726203ad..000000000 --- a/sdk-java/src/main/java/ly/count/sdk/java/internal/SDKInterface.java +++ /dev/null @@ -1,62 +0,0 @@ -package ly.count.sdk.java.internal; - -import org.json.JSONObject; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import ly.count.sdk.java.Config; - -/** - * Abstraction over particular SDK implementation: java-native or Android - */ -public interface SDKInterface { - UserImpl user(); - - InternalConfig config(); - - void init(CtxCore ctx); - - void stop(CtxCore ctx, boolean clear); - - void onDeviceId(CtxCore ctx, Config.DID id, Config.DID old); - - SessionImpl getSession(); - - /** - * Get current {@link SessionImpl} or create new one if current is {@code null}. - * - * @param ctx Ctx to create new {@link SessionImpl} in - * @param id ID of new {@link SessionImpl} if needed - * @return current {@link SessionImpl} instance - */ - SessionImpl session(CtxCore ctx, Long id); - - /** - * Notify all {@link Module} instances about new session has just been started - * - * @param session session to begin - * @return supplied session for method chaining - */ - SessionImpl onSessionBegan(CtxCore ctx, SessionImpl session); - - /** - * Notify all {@link Module} instances session was ended - * - * @param session session to end - * @return supplied session for method chaining - */ - SessionImpl onSessionEnded(CtxCore ctx, SessionImpl session); - - void onRequest(CtxCore ctx, Request request); - - void onCrash(CtxCore ctx, Throwable t, boolean fatal, String name, Map segments, String[] logs); - - void onUserChanged(CtxCore ctx, JSONObject changes, Set cohortsAdded, Set cohortsRemoved); - - // -------------------- Service ------------------------ - void onSignal(CtxCore ctx, int id, Byteable param1, Byteable param2); - - void onSignal(CtxCore ctx, int id, String param); -} diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/UniformTimeGenerator.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/UniformTimeGenerator.java new file mode 100644 index 000000000..58e293a2f --- /dev/null +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/UniformTimeGenerator.java @@ -0,0 +1,22 @@ +package ly.count.sdk.java.internal; + +/** + * Always increasing timer. + */ +public class UniformTimeGenerator implements Device.TimeGenerator { + private Long last; + + @Override + public synchronized long timestamp() { + long ms = System.currentTimeMillis(); + if (last == null) { + last = ms; + } else if (last >= ms) { + last = last + 1; + return last; + } else { + last = ms; + } + return ms; + } +} \ No newline at end of file diff --git a/sdk-java/src/main/java/ly/count/sdk/java/internal/UniqueTimeGenerator.java b/sdk-java/src/main/java/ly/count/sdk/java/internal/UniqueTimeGenerator.java new file mode 100644 index 000000000..5a9a949fb --- /dev/null +++ b/sdk-java/src/main/java/ly/count/sdk/java/internal/UniqueTimeGenerator.java @@ -0,0 +1,40 @@ +package ly.count.sdk.java.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Unique timer, keeps last 10 returned values in memory. + */ +class UniqueTimeGenerator implements Device.TimeGenerator { + List lastTsMs = new ArrayList<>(10); + long addition = 0; + + long currentTimeMillis() { + return System.currentTimeMillis() + addition; + } + + public synchronized long timestamp() { + long ms = currentTimeMillis(); + + // change time back case + if (lastTsMs.size() > 2) { + long min = Collections.min(lastTsMs); + if (ms < min) { + lastTsMs.clear(); + lastTsMs.add(ms); + return ms; + } + } + // usual case + while (lastTsMs.contains(ms)) { + ms += 1; + } + while (lastTsMs.size() >= 10) { + lastTsMs.remove(0); + } + lastTsMs.add(ms); + return ms; + } +} diff --git a/sdk-java/src/test/java/ly/count/sdk/java/internal/ConfigTests.java b/sdk-java/src/test/java/ly/count/sdk/java/internal/ConfigTests.java index df071b0f2..714bff91a 100644 --- a/sdk-java/src/test/java/ly/count/sdk/java/internal/ConfigTests.java +++ b/sdk-java/src/test/java/ly/count/sdk/java/internal/ConfigTests.java @@ -8,6 +8,8 @@ import org.junit.runners.JUnit4; import java.net.URL; +import java.util.HashMap; +import java.util.Map; @RunWith(JUnit4.class) public class ConfigTests extends BaseTestsCore { @@ -79,7 +81,7 @@ public void testSDKName() { @Test public void testSDKVersion() { - String versionName = "22.09.0"; + String versionName = "22.09.1"; Assert.assertEquals(versionName, internalConfig.getSdkVersion()); internalConfig.setSdkVersion(null); @@ -110,4 +112,21 @@ public void testEventBufferSize() { internalConfig.setEventsBufferSize(60); Assert.assertEquals(60, internalConfig.getEventsBufferSize()); } + + @Test + public void metricOverride() { + Map initialVals = internalConfig.getMetricOverride(); + Assert.assertEquals(0, initialVals.size()); + + Map newVals = new HashMap<>(); + newVals.put("a", "1"); + newVals.put("b", "2"); + + internalConfig.setMetricOverride(newVals); + + Map postVals = internalConfig.getMetricOverride(); + Assert.assertEquals(2, initialVals.size()); + Assert.assertEquals("1", postVals.get("a")); + Assert.assertEquals("2", postVals.get("b")); + } } diff --git a/sdk-java/src/test/java/ly/count/sdk/java/internal/DeviceTests.java b/sdk-java/src/test/java/ly/count/sdk/java/internal/DeviceTests.java index b1b76ba7f..dca75b431 100644 --- a/sdk-java/src/test/java/ly/count/sdk/java/internal/DeviceTests.java +++ b/sdk-java/src/test/java/ly/count/sdk/java/internal/DeviceTests.java @@ -1,77 +1,31 @@ package ly.count.sdk.java.internal; +import org.json.JSONObject; import org.junit.Assert; import org.junit.Test; +import java.util.HashMap; +import java.util.Map; public class DeviceTests { + /** + * Lame test for checking metric override + */ @Test - public void testAsIs() { - Device.UniqueTimeGenerator simulator = new Device.UniqueTimeGenerator(); + public void metricOverride_1() { + Map newVals = new HashMap<>(); + newVals.put("a12345", "1qwer"); + newVals.put("b5678", "2sdfg"); - long last = simulator.timestamp(); + Device dev = new Device(); + dev.setMetricOverride(newVals); - for (int i = 0; i < 10000; i++) { - long next = simulator.timestamp(); - Assert.assertNotSame(last, next); - } - } - - @Test - public void testMidTimeChange() { - Device.UniqueTimeGenerator simulator = new Device.UniqueTimeGenerator(); - - long last = simulator.timestamp(); - - for (int i = 0; i < 100; i++) { - long next = simulator.timestamp(); - Assert.assertNotSame(last, next); - } - - simulator.addition = -10000; - - for (int i = 0; i < 100; i++) { - long next = simulator.timestamp(); - Assert.assertNotSame(last, next); - } - - simulator.addition = 0; - - for (int i = 0; i < 100; i++) { - long next = simulator.timestamp(); - Assert.assertNotSame(last, next); - } - - simulator.addition = 10000; - - for (int i = 0; i < 100; i++) { - long next = simulator.timestamp(); - Assert.assertNotSame(last, next); - } - } - - @Test - public void testMidTimeRandomChange() { - Device.UniqueTimeGenerator simulator = new Device.UniqueTimeGenerator(); - - long last = simulator.timestamp(); - - for (int i = 0; i < 100000; i++) { - if (i % 30 == 0) { - simulator.addition = Math.round(Math.random() * 10000 - 5000); - } - long next = simulator.timestamp(); - Assert.assertNotSame(last, next); - } - - simulator.addition = 0; + Params mParams = dev.buildMetrics(); + String sMetrics = mParams.toString(); - for (int i = 0; i < 100000; i++) { - if (i % 30 == 0) { - simulator.addition += Math.round(Math.random() * 1000 - 500); - } - long next = simulator.timestamp(); - Assert.assertNotSame(last, next); - } + Assert.assertTrue(sMetrics.contains("a12345")); + Assert.assertTrue(sMetrics.contains("1qwer")); + Assert.assertTrue(sMetrics.contains("b5678")); + Assert.assertTrue(sMetrics.contains("2sdfg")); } } diff --git a/sdk-java/src/test/java/ly/count/sdk/java/internal/TestUtils.java b/sdk-java/src/test/java/ly/count/sdk/java/internal/TestUtils.java new file mode 100644 index 000000000..07f37eabf --- /dev/null +++ b/sdk-java/src/test/java/ly/count/sdk/java/internal/TestUtils.java @@ -0,0 +1,7 @@ +package ly.count.sdk.java.internal; + +public class TestUtils { + public String[] getCurrentRequestQueue() { + return new String[] {}; + } +} diff --git a/sdk-java/src/test/java/ly/count/sdk/java/internal/TimeGeneratorTests.java b/sdk-java/src/test/java/ly/count/sdk/java/internal/TimeGeneratorTests.java new file mode 100644 index 000000000..8a1b9aab0 --- /dev/null +++ b/sdk-java/src/test/java/ly/count/sdk/java/internal/TimeGeneratorTests.java @@ -0,0 +1,76 @@ +package ly.count.sdk.java.internal; + +import org.junit.Assert; +import org.junit.Test; + +public class TimeGeneratorTests { + @Test + public void testAsIs() { + UniqueTimeGenerator simulator = new UniqueTimeGenerator(); + + long last = simulator.timestamp(); + + for (int i = 0; i < 10000; i++) { + long next = simulator.timestamp(); + Assert.assertNotSame(last, next); + } + } + + @Test + public void testMidTimeChange() { + UniqueTimeGenerator simulator = new UniqueTimeGenerator(); + + long last = simulator.timestamp(); + + for (int i = 0; i < 100; i++) { + long next = simulator.timestamp(); + Assert.assertNotSame(last, next); + } + + simulator.addition = -10000; + + for (int i = 0; i < 100; i++) { + long next = simulator.timestamp(); + Assert.assertNotSame(last, next); + } + + simulator.addition = 0; + + for (int i = 0; i < 100; i++) { + long next = simulator.timestamp(); + Assert.assertNotSame(last, next); + } + + simulator.addition = 10000; + + for (int i = 0; i < 100; i++) { + long next = simulator.timestamp(); + Assert.assertNotSame(last, next); + } + } + + @Test + public void testMidTimeRandomChange() { + UniqueTimeGenerator simulator = new UniqueTimeGenerator(); + + long last = simulator.timestamp(); + + for (int i = 0; i < 100000; i++) { + if (i % 30 == 0) { + simulator.addition = Math.round(Math.random() * 10000 - 5000); + } + long next = simulator.timestamp(); + Assert.assertNotSame(last, next); + } + + simulator.addition = 0; + + for (int i = 0; i < 100000; i++) { + if (i % 30 == 0) { + simulator.addition += Math.round(Math.random() * 1000 - 500); + } + long next = simulator.timestamp(); + Assert.assertNotSame(last, next); + } + } +}