Skip to content

Commit

Permalink
Merge pull request #378 from Countly/staging
Browse files Browse the repository at this point in the history
24.7.2
  • Loading branch information
turtledreams authored Aug 16, 2024
2 parents e6944d3 + 9669272 commit 09d7817
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 6 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 24.7.2
* Mitigated an issue in the upload plugin that prevented the upload of a symbol file

## 24.7.1
* ! Minor breaking change ! Unsupported types for user properties will now be omitted, they won't be converted to strings.

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ org.gradle.configureondemand=true
android.useAndroidX=true
android.enableJetifier=true
# RELEASE FIELD SECTION
VERSION_NAME=24.7.1
VERSION_NAME=24.7.2
GROUP=ly.count.android
POM_URL=https://github.com/Countly/countly-sdk-android
POM_SCM_URL=https://github.com/Countly/countly-sdk-android
Expand Down
104 changes: 104 additions & 0 deletions sdk/src/androidTest/java/ly/count/android/sdk/CountlyTimerTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package ly.count.android.sdk;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.concurrent.ExecutorService;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;

@RunWith(AndroidJUnit4.class)
public class CountlyTimerTests {

private CountlyTimer countlyTimer;
private ModuleLog mockLog;

@Before
public void setUp() {
countlyTimer = new CountlyTimer();
mockLog = Mockito.mock(ModuleLog.class);
CountlyTimer.TIMER_DELAY_MS = 0;
}

@After
public void tearDown() {
countlyTimer.stopTimer(mockLog);
Assert.assertNull(countlyTimer.timerService);
}

@Test
public void validateInitialValues() {
Assert.assertNull(countlyTimer.timerService);
Assert.assertEquals(0, CountlyTimer.TIMER_DELAY_MS);
}

@Test
public void startTimer_validDelay() {
Runnable mockRunnable = Mockito.mock(Runnable.class);

countlyTimer.startTimer(1, mockRunnable, mockLog);
Mockito.verify(mockLog).i("[CountlyTimer] startTimer, Starting timer timerDelay: [1000 ms]");
}

@Test
public void startTimer_invalidDelay() {
Runnable mockRunnable = Mockito.mock(Runnable.class);

countlyTimer.startTimer(-1, mockRunnable, mockLog);
Mockito.verify(mockLog).i("[CountlyTimer] startTimer, Starting timer timerDelay: [1000 ms]");
}

@Test
public void startTimer() {
Runnable mockRunnable = Mockito.mock(Runnable.class);

countlyTimer.startTimer(99, mockRunnable, mockLog);
Mockito.verify(mockLog).i("[CountlyTimer] startTimer, Starting timer timerDelay: [99000 ms]");
}

@Test
public void startTimer_withTimerDelayMS() {
CountlyTimer.TIMER_DELAY_MS = 500;
Runnable mockRunnable = Mockito.mock(Runnable.class);

countlyTimer.startTimer(1, mockRunnable, mockLog);
Mockito.verify(mockLog).i("[CountlyTimer] startTimer, Starting timer timerDelay: [500 ms]");
}

/**
* Test that the timer is stopped when a new timer is started
* This is to prevent multiple timers from running at the same time
* And it is not reusing the previous timer
*/
@Test
public void startTimer_reuseTimer() {
countlyTimer.stopTimer(mockLog);

Assert.assertNull(countlyTimer.timerService);

Runnable mockRunnable = Mockito.mock(Runnable.class);
countlyTimer.startTimer(1, mockRunnable, mockLog);

Assert.assertNotNull(countlyTimer.timerService);
ExecutorService timerService = countlyTimer.timerService;

countlyTimer.startTimer(2, mockRunnable, mockLog);
Assert.assertNotEquals(timerService, countlyTimer.timerService);
}

@Test
public void stopTimer() {
countlyTimer.startTimer(1, Mockito.mock(Runnable.class), mockLog);
countlyTimer.stopTimer(mockLog);
Mockito.verify(mockLog).i("[CountlyTimer] stopTimer, Stopping timer");
}

@Test
public void stopTimer_nullTimer() {
countlyTimer.stopTimer(mockLog);
Mockito.verify(mockLog, Mockito.never()).i("[CountlyTimer] stopTimer, Stopping timer");
Mockito.verify(mockLog).d("[CountlyTimer] stopTimer, Timer already stopped");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class TestUtils {
public final static String commonAppKey = "appkey";
public final static String commonDeviceId = "1234";
public final static String SDK_NAME = "java-native-android";
public final static String SDK_VERSION = "24.7.1";
public final static String SDK_VERSION = "24.7.2";
public static final int MAX_THREAD_COUNT_PER_STACK_TRACE = 50;

public static class Activity2 extends Activity {
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/main/java/ly/count/android/sdk/Countly.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ of this software and associated documentation files (the "Software"), to deal
*/
public class Countly {

private final String DEFAULT_COUNTLY_SDK_VERSION_STRING = "24.7.1";
private final String DEFAULT_COUNTLY_SDK_VERSION_STRING = "24.7.2";

/**
* Used as request meta data on every request
Expand Down
54 changes: 54 additions & 0 deletions sdk/src/main/java/ly/count/android/sdk/CountlyTimer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package ly.count.android.sdk;

import androidx.annotation.NonNull;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

class CountlyTimer {

ScheduledExecutorService timerService;
protected static int TIMER_DELAY_MS = 0; // for testing purposes

protected void stopTimer(@NonNull ModuleLog L) {
if (timerService != null) {
L.i("[CountlyTimer] stopTimer, Stopping timer");
try {
timerService.shutdown();
if (!timerService.awaitTermination(1, TimeUnit.SECONDS)) {
timerService.shutdownNow();
if (!timerService.awaitTermination(1, TimeUnit.SECONDS)) {
L.e("[CountlyTimer] stopTimer, Global timer must be locked");
}
}
} catch (Exception e) {
L.e("[CountlyTimer] stopTimer, Error while stopping global timer " + e);
}
timerService = null;
} else {
L.d("[CountlyTimer] stopTimer, Timer already stopped");
}
}

protected void startTimer(long timerDelay, @NonNull Runnable runnable, @NonNull ModuleLog L) {
long timerDelayInternal = timerDelay * 1000;

if (timerDelayInternal < UtilsTime.ONE_SECOND_IN_MS) {
timerDelayInternal = UtilsTime.ONE_SECOND_IN_MS;
}

if (TIMER_DELAY_MS > 0) {
timerDelayInternal = TIMER_DELAY_MS;
}

L.i("[CountlyTimer] startTimer, Starting timer timerDelay: [" + timerDelayInternal + " ms]");

if (timerService != null) {
L.d("[CountlyTimer] startTimer, timer was running, stopping it");
stopTimer(L);
}

timerService = Executors.newSingleThreadScheduledExecutor();
timerService.scheduleWithFixedDelay(runnable, 0, timerDelayInternal, TimeUnit.MILLISECONDS);
}
}
1 change: 1 addition & 0 deletions sdk/src/main/java/ly/count/android/sdk/UtilsTime.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.List;

public class UtilsTime {
protected static int ONE_SECOND_IN_MS = 1000;

public static class Instant {
public final long timestampMs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ class UploadSymbolsPlugin implements Plugin<Project> {
throw new StopExecutionException("Please specify your server in countly block.")
}
String buildVersion = project.android.defaultConfig.versionName
String url = "${ext.server}/i/crash_symbols/upload_symbol"
String url = ext.server;
String path = "i/crash_symbols/upload_symbol";
// Ensure there is exactly one "/" between the base URL and the path
url = url.endsWith("/") ? url + path : url + "/" + path;
def filePath = "$project.buildDir/$ext.mappingFile"
logger.debug("uploadJavaSymbols, Version name:[ {} ], Upload symbol url:[ {} ], Mapping file path:[ {} ]", buildVersion, url, filePath)
File file = new File(filePath)
Expand All @@ -55,17 +58,27 @@ class UploadSymbolsPlugin implements Plugin<Project> {
.build()
request = new Request.Builder().url(url).post(formBody).build()
}
logger.debug("uploadJavaSymbols, Generated request: {}", request.body().toString())
doLast {
if (request == null) {
logger.error("Request not constructed")
throw new StopActionException("Something happened while constructing the request. Please try again.")
}

if (request.body() != null) {
logger.debug("uploadJavaSymbols, Generated request: {}", request.body().toString())
} else {
logger.error("uploadJavaSymbols, Request body is null which should not be the case")
}

client = new OkHttpClient()
Response response = client.newCall(request).execute()

if (response.code() != 200) {
logger.error("An error occurred while uploading the mapping file: {}", response.body().string())
if (response.body() != null) {
logger.error("An error occurred while uploading the mapping file: {}", response.body().string())
} else {
logger.error("An error occurred while uploading the mapping file, response body null")
}
} else {
logger.debug("File upload successful")
}
Expand Down

0 comments on commit 09d7817

Please sign in to comment.