Skip to content

Commit 6a41986

Browse files
[Sdk 891] Timestamp issue fixed (#83)
* namespace added on countly classes * event timestamp added reqeust timestamp updated to milliseconds * Events and Request unit tests updated Timestamp check added * event common params assert moved into a function. * Update event.cpp * Update main.cpp * Update main.cpp Co-authored-by: ArtursKadikis <[email protected]>
1 parent e008b66 commit 6a41986

File tree

4 files changed

+98
-35
lines changed

4 files changed

+98
-35
lines changed

src/countly.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ void Countly::_sendIndependantLocationRequest() {
223223
}
224224

225225
const std::chrono::system_clock::time_point now = Countly::getTimestamp();
226-
const auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
226+
const auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
227227

228228
if (!data.empty()) {
229229
data["app_key"] = session_params["app_key"].get<std::string>();
@@ -278,7 +278,7 @@ void Countly::_changeDeviceIdWithMerge(const std::string &value) {
278278
session_params["device_id"] = value;
279279

280280
const std::chrono::system_clock::time_point now = Countly::getTimestamp();
281-
const auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
281+
const auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
282282
std::map<std::string, std::string> data = {
283283
{"app_key", session_params["app_key"].get<std::string>()},
284284
{"device_id", session_params["device_id"].get<std::string>()},
@@ -524,7 +524,7 @@ bool Countly::beginSession() {
524524
}
525525

526526
const std::chrono::system_clock::time_point now = Countly::getTimestamp();
527-
const auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
527+
const auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
528528

529529
std::map<std::string, std::string> data = {{"sdk_name", COUNTLY_SDK_NAME}, {"sdk_version", COUNTLY_SDK_VERSION}, {"timestamp", std::to_string(timestamp.count())}, {"app_key", session_params["app_key"].get<std::string>()}, {"device_id", session_params["device_id"].get<std::string>()},
530530
{"begin_session", "1"}};
@@ -677,7 +677,7 @@ bool Countly::updateSession() {
677677
bool Countly::endSession() {
678678
log(Countly::LogLevel::INFO, "[Countly][endSession]");
679679
const std::chrono::system_clock::time_point now = Countly::getTimestamp();
680-
const auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
680+
const auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
681681
const auto duration = std::chrono::duration_cast<std::chrono::seconds>(getSessionDuration(now));
682682

683683
mutex.lock();

src/event.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,28 @@ namespace cly {
44
Event::Event(const std::string &key, size_t count) : object({}), timer_running(false) {
55
object["key"] = key;
66
object["count"] = count;
7+
setTimestamp();
78
}
89

910
Event::Event(const std::string &key, size_t count, double sum) : object({}), timer_running(false) {
1011
object["key"] = key;
1112
object["count"] = count;
1213
object["sum"] = sum;
14+
setTimestamp();
1315
}
1416

1517
Event::Event(const std::string &key, size_t count, double sum, double duration) : object({}), timer_running(false) {
1618
object["key"] = key;
1719
object["count"] = count;
1820
object["sum"] = sum;
1921
object["dur"] = duration;
22+
23+
setTimestamp();
2024
}
2125

2226
void Event::setTimestamp() {
2327
timestamp = std::chrono::system_clock::now();
24-
object["timestamp"] = std::chrono::duration_cast<std::chrono::seconds>(timestamp.time_since_epoch()).count();
28+
object["timestamp"] = std::chrono::duration_cast<std::chrono::milliseconds>(timestamp.time_since_epoch()).count();
2529
}
2630

2731
void Event::startTimer() {

tests/event.cpp

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,100 @@
1-
#include "countly.hpp"
1+
#include "countly/event.hpp"
22
#include "doctest.h"
3+
#include <iostream>
4+
#include <string>
5+
using namespace cly;
6+
7+
void valideEventParams(nlohmann::json eventJson, std::string key, int count) {
8+
CHECK(eventJson["key"].get<std::string>() == key);
9+
CHECK(eventJson["count"].get<int>() == count);
10+
CHECK(std::to_string(eventJson["timestamp"].get<long long>()).size() == 13);
11+
}
312

413
TEST_CASE("events are serialized correctly") {
514
SUBCASE("without segmentation") {
615
SUBCASE("without sum") {
716
cly::Event event("win", 1);
8-
CHECK(event.serialize() == "{\"count\":1,\"key\":\"win\"}");
17+
18+
nlohmann::json e = nlohmann::json::parse(event.serialize());
19+
valideEventParams(e, "win", 1);
920
}
1021

1122
SUBCASE("with sum") {
1223
cly::Event event("buy", 2, 9.99);
13-
CHECK(event.serialize() == "{\"count\":2,\"key\":\"buy\",\"sum\":9.99}");
24+
25+
nlohmann::json e = nlohmann::json::parse(event.serialize());
26+
CHECK(e["sum"].get<double>() == 9.99);
27+
valideEventParams(e, "buy", 2);
1428
}
1529
}
1630

1731
SUBCASE("with segmentation") {
1832
SUBCASE("with signed integer") {
1933
cly::Event event("lose", 3);
2034
event.addSegmentation("points", -144);
21-
CHECK(event.serialize() == "{\"count\":3,\"key\":\"lose\",\"segmentation\":{\"points\":-144}}");
35+
36+
nlohmann::json e = nlohmann::json::parse(event.serialize());
37+
valideEventParams(e, "lose", 3);
38+
39+
nlohmann::json s = e["segmentation"].get<nlohmann::json>();
40+
CHECK(s["points"].get<int>() == -144);
2241
}
2342

2443
SUBCASE("with unsigned integer") {
2544
cly::Event event("win", 1);
2645
event.addSegmentation("points", 232U);
27-
CHECK(event.serialize() == "{\"count\":1,\"key\":\"win\",\"segmentation\":{\"points\":232}}");
46+
47+
nlohmann::json e = nlohmann::json::parse(event.serialize());
48+
valideEventParams(e, "win", 1);
49+
50+
nlohmann::json s = e["segmentation"].get<nlohmann::json>();
51+
CHECK(s["points"].get<unsigned int>() == 232U);
2852
}
2953

3054
SUBCASE("with boolean") {
3155
cly::Event event("win", 1);
3256
event.addSegmentation("alive", true);
33-
CHECK(event.serialize() == "{\"count\":1,\"key\":\"win\",\"segmentation\":{\"alive\":true}}");
57+
58+
nlohmann::json e = nlohmann::json::parse(event.serialize());
59+
valideEventParams(e, "win", 1);
60+
61+
nlohmann::json s = e["segmentation"].get<nlohmann::json>();
62+
CHECK(s["alive"].get<bool>() == true);
3463
}
3564

3665
SUBCASE("with string") {
3766
cly::Event event("message", 1);
3867
event.addSegmentation("sender", "TheLegend27");
39-
CHECK(event.serialize() == "{\"count\":1,\"key\":\"message\",\"segmentation\":{\"sender\":\"TheLegend27\"}}");
68+
69+
nlohmann::json e = nlohmann::json::parse(event.serialize());
70+
valideEventParams(e, "message", 1);
71+
72+
nlohmann::json s = e["segmentation"].get<nlohmann::json>();
73+
CHECK(s["sender"].get<std::string>() == "TheLegend27");
4074
}
4175

4276
SUBCASE("with multiple values") {
4377
cly::Event event("buy", 5);
4478
event.addSegmentation("quantity", 27);
4579
event.addSegmentation("searchQuery", "cheap cheese");
46-
CHECK(event.serialize() == "{\"count\":5,\"key\":\"buy\",\"segmentation\":{\"quantity\":27,\"searchQuery\":\"cheap cheese\"}}");
47-
}
4880

49-
SUBCASE("with changing values") {
50-
cly::Event event("lose", 3);
51-
event.addSegmentation("points", -144);
52-
event.addSegmentation("points", 2000);
53-
CHECK(event.serialize() == "{\"count\":3,\"key\":\"lose\",\"segmentation\":{\"points\":2000}}");
54-
}
81+
nlohmann::json e = nlohmann::json::parse(event.serialize());
82+
valideEventParams(e, "buy", 5);
5583

56-
SUBCASE("with count, sum, duration and segmentation") {
57-
cly::Event event("lose", 3, 10, 100);
58-
event.addSegmentation("points", 2000);
59-
CHECK(event.serialize() == "{\"count\":3,\"dur\":100.0,\"key\":\"lose\",\"segmentation\":{\"points\":2000},\"sum\":10.0}");
84+
nlohmann::json s = e["segmentation"].get<nlohmann::json>();
85+
CHECK(s["quantity"].get<int>() == 27);
86+
CHECK(s["searchQuery"].get<std::string>() == "cheap cheese");
6087
}
6188

6289
SUBCASE("with multibyte strings") {
6390
cly::Event event("测试", 1);
6491
event.addSegmentation("苹果", "美味");
65-
CHECK(event.serialize() == "{\"count\":1,\"key\":\"测试\",\"segmentation\":{\"苹果\":\"美味\"}}");
92+
93+
nlohmann::json e = nlohmann::json::parse(event.serialize());
94+
valideEventParams(e, "测试", 1);
95+
96+
nlohmann::json s = e["segmentation"].get<nlohmann::json>();
97+
CHECK(s["苹果"].get<std::string>() == "美味");
6698
}
6799
}
68100
}

tests/main.cpp

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ Countly::HTTPResponse fakeSendHTTP(bool use_post, const std::string &url, const
104104

105105
void logToConsole(Countly::LogLevel level, const std::string &message) { std::cout << level << '\t' << message << std::endl; }
106106

107-
long getUnixTimestamp() {
107+
long long getUnixTimestamp() {
108108
const std::chrono::system_clock::time_point now = Countly::getTimestamp();
109-
const auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
109+
const auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
110110
return timestamp.count();
111111
}
112112

@@ -196,19 +196,19 @@ TEST_CASE("events are sent correctly") {
196196
#endif
197197

198198
countly.start(COUNTLY_TEST_APP_KEY, COUNTLY_TEST_HOST, COUNTLY_TEST_PORT, false);
199-
long timestamp;
199+
long long timestamp;
200200

201201
SUBCASE("session begins") {
202202
timestamp = getUnixTimestamp();
203203
countly.beginSession();
204204
HTTPCall http_call = popHTTPCall();
205-
long timestampDiff = stol(http_call.data["timestamp"]) - timestamp;
205+
long long timestampDiff = stoll(http_call.data["timestamp"]) - timestamp;
206206
CHECK(!http_call.use_post);
207207
CHECK(http_call.data["app_key"] == COUNTLY_TEST_APP_KEY);
208208
CHECK(http_call.data["device_id"] == COUNTLY_TEST_DEVICE_ID);
209209
CHECK(http_call.data["begin_session"] == "1");
210210
CHECK(timestampDiff >= 0);
211-
CHECK(timestampDiff <= 1);
211+
CHECK(timestampDiff <= 100);//todo find out what the sweetspot is for the difference
212212
}
213213

214214
SUBCASE("remote config is fetched") {
@@ -229,7 +229,15 @@ TEST_CASE("events are sent correctly") {
229229
CHECK(!http_call.use_post);
230230
CHECK(http_call.data["app_key"] == COUNTLY_TEST_APP_KEY);
231231
CHECK(http_call.data["device_id"] == COUNTLY_TEST_DEVICE_ID);
232-
CHECK(http_call.data["events"] == "[{\"count\":4,\"key\":\"win\",\"segmentation\":{\"points\":100}}]");
232+
233+
nlohmann::json events = nlohmann::json::parse(http_call.data["events"]);
234+
nlohmann::json e = events[0];
235+
CHECK(e["key"].get<std::string>() == "win");
236+
CHECK(e["count"].get<int>() == 4);
237+
CHECK(std::to_string(e["timestamp"].get<long long>()).size() == 13);
238+
239+
nlohmann::json s = e["segmentation"].get<nlohmann::json>();
240+
CHECK(s["points"].get<int>() == 100);
233241
}
234242

235243
SUBCASE("two events are sent") {
@@ -244,7 +252,17 @@ TEST_CASE("events are sent correctly") {
244252
CHECK(!http_call.use_post);
245253
CHECK(http_call.data["app_key"] == COUNTLY_TEST_APP_KEY);
246254
CHECK(http_call.data["device_id"] == COUNTLY_TEST_DEVICE_ID);
247-
CHECK(http_call.data["events"] == "[{\"count\":2,\"key\":\"win\"},{\"count\":1,\"key\":\"achievement\"}]");
255+
256+
nlohmann::json events = nlohmann::json::parse(http_call.data["events"]);
257+
nlohmann::json e = events[0];
258+
CHECK(e["key"].get<std::string>() == "win");
259+
CHECK(e["count"].get<int>() == 2);
260+
CHECK(std::to_string(e["timestamp"].get<long long>()).size() == 13);
261+
262+
e = events[1];
263+
CHECK(e["key"].get<std::string>() == "achievement");
264+
CHECK(e["count"].get<int>() == 1);
265+
CHECK(std::to_string(e["timestamp"].get<long long>()).size() == 13);
248266
}
249267

250268
SUBCASE("event with count, sum, duration and segmentation is sent") {
@@ -259,7 +277,16 @@ TEST_CASE("events are sent correctly") {
259277
CHECK(!http_call.use_post);
260278
CHECK(http_call.data["app_key"] == COUNTLY_TEST_APP_KEY);
261279
CHECK(http_call.data["device_id"] == COUNTLY_TEST_DEVICE_ID);
262-
CHECK(http_call.data["events"] == "[{\"count\":3,\"dur\":100.0,\"key\":\"lose\",\"segmentation\":{\"points\":2000},\"sum\":10.0}]");
280+
281+
nlohmann::json events = nlohmann::json::parse(http_call.data["events"]);
282+
nlohmann::json e = events[0];
283+
CHECK(e["key"].get<std::string>() == "lose");
284+
CHECK(e["count"].get<int>() == 3);
285+
CHECK(e["sum"].get<double>() == 10.0);
286+
CHECK(std::to_string(e["timestamp"].get<long long>()).size() == 13);
287+
288+
nlohmann::json s = e["segmentation"].get<nlohmann::json>();
289+
CHECK(s["points"].get<int>() == 2000);
263290
}
264291

265292
SUBCASE("100 events are sent") {
@@ -280,12 +307,12 @@ TEST_CASE("events are sent correctly") {
280307
SUBCASE("session ends") {
281308
countly.stop();
282309
HTTPCall http_call = popHTTPCall();
283-
long timestampDiff = stol(http_call.data["timestamp"]) - timestamp;
310+
long long timestampDiff = stoll(http_call.data["timestamp"]) - timestamp;
284311
CHECK(!http_call.use_post);
285312
CHECK(http_call.data["app_key"] == COUNTLY_TEST_APP_KEY);
286313
CHECK(http_call.data["device_id"] == COUNTLY_TEST_DEVICE_ID);
287314
CHECK(http_call.data["end_session"] == "1");
288315
CHECK(timestampDiff >= 0);
289-
CHECK(timestampDiff <= 1);
316+
CHECK(timestampDiff <= 100);//todo find out what the sweetspot is for the difference
290317
}
291318
}

0 commit comments

Comments
 (0)