Skip to content

Commit

Permalink
Merge pull request #122 from bugsnag/fix-session-counts
Browse files Browse the repository at this point in the history
[PLAT-2139] Ensure session counts are reported thread safe
  • Loading branch information
fractalwrench authored Nov 29, 2018
2 parents 5e294cf + 3cfe6b6 commit 5449cd4
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 16 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# Changelog

## 3.4.2 (2018-11-28)
## 3.4.2 (2018-11-29)

* Ensure session counts are thread safe
[#122](https://github.com/bugsnag/bugsnag-java/pull/122)

* Prevent application hangs due to session flushing
[#121](https://github.com/bugsnag/bugsnag-java/pull/121)

Expand Down
29 changes: 14 additions & 15 deletions bugsnag/src/main/java/com/bugsnag/Report.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class Report {
private String groupingHash;
private Diagnostics diagnostics;
private boolean shouldCancel = false;
private Session session;
private Map<String, Object> sessionMap;
private final List<ThreadState> threadStates;

/**
Expand Down Expand Up @@ -131,23 +131,22 @@ public Map<String, Object> getMetaData() {

@Expose
Map<String, Object> getSession() {
if (session == null) {
return null;
}

Map<String, Object> map = new HashMap<String, Object>();
map.put("id", session.getId());
map.put("startedAt", session.getStartedAt());

Map<String, Object> handledCounts = new HashMap<String, Object>();
handledCounts.put("handled", session.getHandledCount());
handledCounts.put("unhandled", session.getUnhandledCount());
map.put("events", handledCounts);
return map;
return sessionMap;
}

void setSession(Session session) {
this.session = session;
if (session == null) {
sessionMap = null;
} else {
sessionMap = new HashMap<String, Object>();
sessionMap.put("id", session.getId());
sessionMap.put("startedAt", session.getStartedAt());

Map<String, Object> handledCounts = new HashMap<String, Object>();
handledCounts.put("handled", session.getHandledCount());
handledCounts.put("unhandled", session.getUnhandledCount());
sessionMap.put("events", handledCounts);
}
}

/**
Expand Down
23 changes: 23 additions & 0 deletions bugsnag/src/test/java/com/bugsnag/BugsnagTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,29 @@ public void close() {
assertTrue(bugsnag.notify(new Throwable()));
}

@Test
public void testMultipleHandledIncrementWithSession() {
bugsnag.startSession();
StubNotificationDelivery testDelivery = new StubNotificationDelivery();
bugsnag.setDelivery(testDelivery);

assertTrue(bugsnag.notify(new Throwable()));
assertTrue(bugsnag.notify(new Throwable()));
assertTrue(bugsnag.notify(new Throwable()));

for (int i = 0 ; i < testDelivery.getNotifications().size(); i++) {
Report report = testDelivery.getNotifications().get(i).getEvents().get(0);

Map<String, Object> session = report.getSession();
assertNotNull(session);

@SuppressWarnings("unchecked")
Map<String, Object> handledCounts = (Map<String, Object>) session.get("events");
assertEquals(i + 1, handledCounts.get("handled"));
assertEquals(0, handledCounts.get("unhandled"));
}
}

@Test
public void testSerialization() {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
Expand Down
15 changes: 15 additions & 0 deletions bugsnag/src/test/java/com/bugsnag/NotificationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
Expand All @@ -31,6 +32,9 @@ public void setUp() {
config.appVersion = "1.2.3";
config.releaseStage = "dev";
report = new Report(config, new RuntimeException());

// Only include properties with non-null values
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}

private JsonNode generateJson(ObjectMapper mapper,
Expand Down Expand Up @@ -67,6 +71,17 @@ public void testWithoutSessionSerialisation() throws Throwable {
assertNull(rootNode.get("events").get("session"));
}

@Test
public void testNullSession() throws Throwable {
report.setSession(null);

JsonNode rootNode = generateJson(mapper, config, report);
validateErrorReport(rootNode);

JsonNode session = rootNode.get("events").get(0).get("session");
assertNull(session);
}

private void validateErrorReport(JsonNode rootNode) {
assertNotNull(rootNode);
assertNotNull(rootNode.get("apiKey").asText());
Expand Down

0 comments on commit 5449cd4

Please sign in to comment.