blob: d7effba132c5405145fe4fa262f8e76f800a3150 [file] [log] [blame]
/*
*
* Copyright (c) 2014-2017 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <Weave/Support/CodeUtils.h>
#include <Weave/Support/logging/WeaveLogging.h>
#include "MockTimeSyncUtil.h"
#if WEAVE_CONFIG_TIME
using namespace nl::Weave::Profiles::Time;
void Abort()
{
abort();
}
void TestError(WEAVE_ERROR err, const char *msg)
{
if (err != WEAVE_NO_ERROR)
{
printf("%s: %s\n", msg, nl::ErrorStr(err));
Abort();
}
}
void TestAssert(bool assert, const char *msg)
{
if (!assert)
{
printf("%s\n", msg);
Abort();
}
}
void TestCase1(void)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
WeaveLogProgress(TimeService, "------------------------------------------------------------");
// test case 1, size == 4, PDT
{
uint8_t buffer[TimeZoneUtcOffset::BufferSizeForEncoding] = { 0 };
TimeZoneUtcOffset utc_offset_enc;
TimeZoneUtcOffset utc_offset_dec;
uint32_t size = sizeof(buffer);
utc_offset_enc.mSize = 4;
utc_offset_enc.mUtcOffsetRecord[0].mBeginAt_usec = 1394355600000000LL; // 3/9/2014 2AM PST
utc_offset_enc.mUtcOffsetRecord[0].mUtcOffset_sec = -3600 * 7;
utc_offset_enc.mUtcOffsetRecord[1].mBeginAt_usec = 1414922400000000LL; // 11/2/2014 2AM PDT
utc_offset_enc.mUtcOffsetRecord[1].mUtcOffset_sec = -3600 * 8;
utc_offset_enc.mUtcOffsetRecord[2].mBeginAt_usec = 1425805200000000LL; // 3/8/2015 2AM PST
utc_offset_enc.mUtcOffsetRecord[2].mUtcOffset_sec = -3600 * 7;
utc_offset_enc.mUtcOffsetRecord[3].mBeginAt_usec = 1446372000000000LL; // 11/2/2015 2AM PDT
utc_offset_enc.mUtcOffsetRecord[3].mUtcOffset_sec = -3600 * 8;
WeaveLogProgress(TimeService, "TimeZone Unit Test Case 1: normal case");
WeaveLogProgress(TimeService, "Encoding buffer size %u, Number of records: %u", size, utc_offset_enc.mSize);
err = utc_offset_enc.Encode(buffer, &size);
SuccessOrExit(err);
WeaveLogProgress(TimeService, "Encoding buffer size used %u");
err = utc_offset_dec.Decode(buffer, size);
SuccessOrExit(err);
WeaveLogProgress(TimeService, "Decoded number of records: %u", utc_offset_dec.mSize);
for (int i = 0; i < utc_offset_dec.mSize; ++i)
{
WeaveLogProgress(TimeService, "[%d] timestamp usec: %ld, offset sec %d", i,
utc_offset_dec.mUtcOffsetRecord[i].mBeginAt_usec, utc_offset_dec.mUtcOffsetRecord[i].mUtcOffset_sec);
}
{
timesync_t utc_time = 1403303320000000LL; // Fri Jun 20 15:28:40 2014, PDT
timesync_t local_time;
time_t temp;
temp = time_t(utc_time / 1000000);
// we use 'local time' to convert the utc to local time
WeaveLogProgress(TimeService, "Sample time: %s", asctime(localtime(&temp)));
// this time we use GetCurrentLocalTime to convert utc to local time
err = utc_offset_dec.GetCurrentLocalTime(&local_time, utc_time);
SuccessOrExit(err);
temp = time_t(local_time / 1000000);
// since it's already converted, we use gmtime to process it (as there is no further tz/dst correction applied)
WeaveLogProgress(TimeService, "Local time: %s", asctime(gmtime(&temp)));
}
WeaveLogProgress(TimeService, "TimeZone Unit Test Case 1: succeeded");
}
WeaveLogProgress(TimeService, "------------------------------------------------------------");
exit:
TestError(err, "Test Case 1 Failed");
}
void TestCase2(void)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
WeaveLogProgress(TimeService, "------------------------------------------------------------");
// test case 2, size == 4, very large offsets and changes
// Samoa, timezone Pacific/Apia, in the middle of Pacific ocean, changed their timezone from UTC-11 to UTC+13 in 2012,
// essentially advanced one full day
{
uint8_t buffer[TimeZoneUtcOffset::BufferSizeForEncoding] = { 0 };
TimeZoneUtcOffset utc_offset_enc;
TimeZoneUtcOffset utc_offset_dec;
uint32_t size = sizeof(buffer);
utc_offset_enc.mSize = 4;
utc_offset_enc.mUtcOffsetRecord[0].mBeginAt_usec = 1394355600000000LL; //
utc_offset_enc.mUtcOffsetRecord[0].mUtcOffset_sec = -3600 * 11;
utc_offset_enc.mUtcOffsetRecord[1].mBeginAt_usec = 1414922400000000LL; //
utc_offset_enc.mUtcOffsetRecord[1].mUtcOffset_sec = +3600 * 13;
utc_offset_enc.mUtcOffsetRecord[2].mBeginAt_usec = 1425805200000000LL; //
utc_offset_enc.mUtcOffsetRecord[2].mUtcOffset_sec = +3600 * 14;
utc_offset_enc.mUtcOffsetRecord[3].mBeginAt_usec = 1446372000000000LL; //
utc_offset_enc.mUtcOffsetRecord[3].mUtcOffset_sec = +3600 * 13;
WeaveLogProgress(TimeService, "TimeZone Unit Test Case 2: huge offset changes");
WeaveLogProgress(TimeService, "Encoding buffer size %u, Number of records: %u", size, utc_offset_enc.mSize);
err = utc_offset_enc.Encode(buffer, &size);
SuccessOrExit(err);
WeaveLogProgress(TimeService, "Encoding buffer size used %u");
err = utc_offset_dec.Decode(buffer, size);
SuccessOrExit(err);
WeaveLogProgress(TimeService, "Decoded number of records: %u", utc_offset_dec.mSize);
for (int i = 0; i < utc_offset_dec.mSize; ++i)
{
WeaveLogProgress(TimeService, "[%d] timestamp usec: %ld, offset sec %d", i,
utc_offset_dec.mUtcOffsetRecord[i].mBeginAt_usec, utc_offset_dec.mUtcOffsetRecord[i].mUtcOffset_sec);
}
WeaveLogProgress(TimeService, "TimeZone Unit Test Case 2: succeeded");
}
WeaveLogProgress(TimeService, "------------------------------------------------------------");
exit:
TestError(err, "Test Case 2 Failed");
}
void TestCase3(void)
{
WEAVE_ERROR err = WEAVE_NO_ERROR;
WeaveLogProgress(TimeService, "------------------------------------------------------------");
// test case 2, size == 4, very large offsets and changes
// Samoa, timezone Pacific/Apia, in the middle of Pacific ocean, changed their timezone from UTC-11 to UTC+13 in 2012,
// essentially advanced one full day
{
uint8_t buffer[TimeZoneUtcOffset::BufferSizeForEncoding] = { 0 };
TimeZoneUtcOffset utc_offset_enc;
TimeZoneUtcOffset utc_offset_dec;
uint32_t size = sizeof(buffer);
utc_offset_enc.mSize = 1;
utc_offset_enc.mUtcOffsetRecord[0].mBeginAt_usec = 0; //
utc_offset_enc.mUtcOffsetRecord[0].mUtcOffset_sec = +3600 * 7;
WeaveLogProgress(TimeService, "TimeZone Unit Test Case 3: no DST case, single UTC offset");
WeaveLogProgress(TimeService, "Encoding buffer size %u, Number of records: %u", size, utc_offset_enc.mSize);
err = utc_offset_enc.Encode(buffer, &size);
SuccessOrExit(err);
WeaveLogProgress(TimeService, "Encoding buffer size used %u");
err = utc_offset_dec.Decode(buffer, size);
SuccessOrExit(err);
WeaveLogProgress(TimeService, "Decoded number of records: %u", utc_offset_dec.mSize);
for (int i = 0; i < utc_offset_dec.mSize; ++i)
{
WeaveLogProgress(TimeService, "[%d] timestamp usec: %ld, offset sec %d", i,
utc_offset_dec.mUtcOffsetRecord[i].mBeginAt_usec, utc_offset_dec.mUtcOffsetRecord[i].mUtcOffset_sec);
}
{
timesync_t utc_time = 1403303320000000LL; // Fri Jun 20 15:28:40 2014, PDT
timesync_t local_time;
time_t temp;
temp = time_t(utc_time / 1000000);
// we use 'asctime/gmtime' to convert the time to string, with UTC offset 0
WeaveLogProgress(TimeService, "Sample time: %s", asctime(gmtime(&temp)));
// this time we use GetCurrentLocalTime to convert utc to local time
err = utc_offset_dec.GetCurrentLocalTime(&local_time, utc_time);
SuccessOrExit(err);
temp = time_t(local_time / 1000000);
// fixed offset shall be applied here
WeaveLogProgress(TimeService, "Local time: %s", asctime(gmtime(&temp)));
}
WeaveLogProgress(TimeService, "TimeZone Unit Test Case 3: succeeded");
}
WeaveLogProgress(TimeService, "------------------------------------------------------------");
exit:
TestError(err, "Test Case 3 Failed");
}
int main()
{
TestCase1();
TestCase2();
TestCase3();
printf("All tests passed\n");
return 0;
}
#else // WEAVE_CONFIG_TIME
int main()
{
printf("Weave Time is NOT ENABLED. Test Skipped\n");
return -1;
}
#endif // WEAVE_CONFIG_TIME