blob: caa3fa007d85663188f5b441bc8cfaadcd61533f [file] [log] [blame]
/*
*
* Copyright (c) 2016-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.
*/
/**
* @file
* This file implements a process to effect a functional test for
* the Weave Nest serial number support utilities.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <Weave/Support/logging/WeaveLogging.h>
#include <Weave/Support/SerialNumberUtils.h>
using namespace nl;
void Abort()
{
abort();
}
void TestAssert(bool assert, const char *msg)
{
if (!assert)
{
printf("%s\n", msg);
Abort();
}
}
class MfgDateTestCase
{
public:
uint16_t inYear;
uint8_t inMonth;
uint8_t inDay;
uint16_t outMfgYear;
uint8_t outMfgWeek;
uint16_t outYear;
uint8_t outMonth;
uint8_t outDay;
};
MfgDateTestCase gMfgDateTestCases[] =
{
// inYear, inMonth, inDay, outMfgYear, outMfgWeek, outYear, outMonth, outDay
{ 2011, 1, 3, 2011, 2, 2011, 1, 2 },
{ 2011, 7, 31, 2011, 32, 2011, 7, 31 },
{ 2011, 9, 14, 2011, 38, 2011, 9, 11 },
{ 2011, 12, 31, 2011, 53, 2011, 12, 25 },
{ 2012, 2, 26, 2012, 9, 2012, 2, 26 },
{ 2012, 2, 27, 2012, 9, 2012, 2, 26 },
{ 2012, 2, 28, 2012, 9, 2012, 2, 26 },
{ 2012, 2, 29, 2012, 9, 2012, 2, 26 },
{ 2012, 3, 1, 2012, 9, 2012, 2, 26 },
{ 2012, 3, 2, 2012, 9, 2012, 2, 26 },
{ 2012, 3, 3, 2012, 9, 2012, 2, 26 },
{ 2012, 3, 4, 2012, 10, 2012, 3, 4 },
{ 2013, 1, 2, 2013, 1, 2012, 12, 30 },
{ 2013, 1, 9, 2013, 2, 2013, 1, 6 },
{ 2013, 1, 16, 2013, 3, 2013, 1, 13 },
{ 2013, 1, 23, 2013, 4, 2013, 1, 20 },
{ 2013, 1, 30, 2013, 5, 2013, 1, 27 },
{ 2013, 2, 6, 2013, 6, 2013, 2, 3 },
{ 2013, 2, 13, 2013, 7, 2013, 2, 10 },
{ 2013, 2, 20, 2013, 8, 2013, 2, 17 },
{ 2013, 2, 27, 2013, 9, 2013, 2, 24 },
{ 2013, 3, 6, 2013, 10, 2013, 3, 03 },
{ 2013, 3, 13, 2013, 11, 2013, 3, 10 },
{ 2013, 3, 20, 2013, 12, 2013, 3, 17 },
{ 2013, 3, 27, 2013, 13, 2013, 3, 24 },
{ 2013, 4, 3, 2013, 14, 2013, 3, 31 },
{ 2013, 4, 10, 2013, 15, 2013, 4, 7 },
{ 2013, 4, 17, 2013, 16, 2013, 4, 14 },
{ 2013, 4, 24, 2013, 17, 2013, 4, 21 },
{ 2013, 5, 1, 2013, 18, 2013, 4, 28 },
{ 2013, 5, 8, 2013, 19, 2013, 5, 5 },
{ 2013, 5, 15, 2013, 20, 2013, 5, 12 },
{ 2013, 5, 22, 2013, 21, 2013, 5, 19 },
{ 2013, 5, 29, 2013, 22, 2013, 5, 26 },
{ 2013, 6, 5, 2013, 23, 2013, 6, 2 },
{ 2013, 6, 12, 2013, 24, 2013, 6, 9 },
{ 2013, 6, 19, 2013, 25, 2013, 6, 16 },
{ 2013, 6, 26, 2013, 26, 2013, 6, 23 },
{ 2013, 7, 3, 2013, 27, 2013, 6, 30 },
{ 2013, 7, 10, 2013, 28, 2013, 7, 7 },
{ 2013, 7, 17, 2013, 29, 2013, 7, 14 },
{ 2013, 7, 24, 2013, 30, 2013, 7, 21 },
{ 2013, 7, 31, 2013, 31, 2013, 7, 28 },
{ 2013, 8, 7, 2013, 32, 2013, 8, 4 },
{ 2013, 8, 14, 2013, 33, 2013, 8, 11 },
{ 2013, 8, 21, 2013, 34, 2013, 8, 18 },
{ 2013, 8, 28, 2013, 35, 2013, 8, 25 },
{ 2013, 9, 4, 2013, 36, 2013, 9, 1 },
{ 2013, 9, 11, 2013, 37, 2013, 9, 8 },
{ 2013, 9, 18, 2013, 38, 2013, 9, 15 },
{ 2013, 9, 25, 2013, 39, 2013, 9, 22 },
{ 2013, 10, 2, 2013, 40, 2013, 9, 29 },
{ 2013, 10, 9, 2013, 41, 2013, 10, 6 },
{ 2013, 10, 16, 2013, 42, 2013, 10, 13 },
{ 2013, 10, 23, 2013, 43, 2013, 10, 20 },
{ 2013, 10, 30, 2013, 44, 2013, 10, 27 },
{ 2013, 11, 6, 2013, 45, 2013, 11, 3 },
{ 2013, 11, 13, 2013, 46, 2013, 11, 10 },
{ 2013, 11, 20, 2013, 47, 2013, 11, 17 },
{ 2013, 11, 27, 2013, 48, 2013, 11, 24 },
{ 2013, 12, 4, 2013, 49, 2013, 12, 1 },
{ 2013, 12, 11, 2013, 50, 2013, 12, 8 },
{ 2013, 12, 18, 2013, 51, 2013, 12, 15 },
{ 2013, 12, 25, 2013, 52, 2013, 12, 22 },
{ 2015, 1, 1, 2015, 1, 2014, 12, 28 },
{ 2015, 2, 9, 2015, 7, 2015, 2, 8 },
{ 0 }
};
void TestMfgDateConversion(void)
{
for (MfgDateTestCase *testCase = gMfgDateTestCases; testCase->inYear != 0; testCase++)
{
uint16_t mfgYear;
uint8_t mfgWeek;
uint16_t year;
uint8_t month;
uint8_t day;
DateToManufacturingWeek(testCase->inYear, testCase->inMonth, testCase->inDay, mfgYear, mfgWeek);
TestAssert(mfgYear == testCase->outMfgYear, "Invalid mfgYear returned by DateToManufacturingWeek()");
TestAssert(mfgWeek == testCase->outMfgWeek, "Invalid mfgWeek returned by DateToManufacturingWeek()");
ManufacturingWeekToDate(mfgYear, mfgWeek, year, month, day);
TestAssert(year == testCase->outYear, "Invalid year returned by ManufacturingWeekToDate()");
TestAssert(month == testCase->outMonth, "Invalid month returned by ManufacturingWeekToDate()");
TestAssert(day == testCase->outDay, "Invalid day returned by ManufacturingWeekToDate()");
}
}
void TestMfgDateFromSerialNum(void)
{
WEAVE_ERROR err;
uint16_t year;
uint8_t month;
uint8_t day;
for (MfgDateTestCase *testCase = gMfgDateTestCases; testCase->inYear != 0; testCase++)
{
char serialNum[17];
sprintf(serialNum, "02AA01AB%02d%02d001P", testCase->outMfgWeek, testCase->outMfgYear % 100);
err = ExtractManufacturingDateFromSerialNumber(serialNum, year, month, day);
TestAssert(err == WEAVE_NO_ERROR, "Error returned by ExtractManufacturingDateFromSerialNumber()");
TestAssert(year == testCase->outYear, "Invalid year returned by ExtractManufacturingDateFromSerialNumber()");
TestAssert(month == testCase->outMonth, "Invalid month returned by ExtractManufacturingDateFromSerialNumber()");
TestAssert(day == testCase->outDay, "Invalid day returned by ExtractManufacturingDateFromSerialNumber()");
}
err = ExtractManufacturingDateFromSerialNumber("02AA01AC25130CD", year, month, day);
TestAssert(err == WEAVE_ERROR_INVALID_ARGUMENT, "Error not detected by ExtractManufacturingDateFromSerialNumber()");
err = ExtractManufacturingDateFromSerialNumber("02AA01AC25130CD87", year, month, day);
TestAssert(err == WEAVE_ERROR_INVALID_ARGUMENT, "Error not detected by ExtractManufacturingDateFromSerialNumber()");
err = ExtractManufacturingDateFromSerialNumber("02AA01AC251A0CD8", year, month, day);
TestAssert(err == WEAVE_ERROR_INVALID_ARGUMENT, "Error not detected by ExtractManufacturingDateFromSerialNumber()");
err = ExtractManufacturingDateFromSerialNumber("02AA01AC,5130CD8", year, month, day);
TestAssert(err == WEAVE_ERROR_INVALID_ARGUMENT, "Error not detected by ExtractManufacturingDateFromSerialNumber()");
}
void TestSerialNumValidation(void)
{
static const char *GoodSNs[] =
{
"01AA02RA09140021",
"01AA02RA2014000C",
"01AA02RA2014002J",
"01AA02RA20140042",
"01AA02RA20140051",
"01AA02RA2014006F",
"01AA02RA201400F2",
"01AA02RA201400FL",
"01AA02RA201400HM",
"02AA01AB391203BM",
"02AA01AC0714060Y",
"02AA01AB401203K8",
"02AA01AC40130425",
"02AA01AC071405AB",
"02AA01AC071407LX",
"02AA01AC071405WR",
"02AA01AC071405A8",
"02AA01AB371205S0",
"02AA01AB4112091K",
"02AA01AB381206N0",
"01AA02RA20140048",
"02AA01RC221400TQ",
"02AA01RC221400GL",
"02AA01RC2214010E",
"02AA01AC35130FZ4",
"02AA01AC35130FZ0",
"02AA01AC4013045L",
"02AA01RC221400R7",
"02AA01AC401303XC",
"01AA02AB0712005J",
"01AA01RA26120091",
"02AA01AB04130DLC",
"02AA01AC211400SH",
"02AA01AC211406P1",
"02AA01AC211405L9",
"05BA01AC0313003G",
"05BA01AC231300AB",
"05CA01AC291300AG",
NULL
};
static const char *BadSNs[] =
{
"02AA01AC25130CD", // too short
"02AA01AC25130CD87", // too long
"02AA01AC75230CD8", // invalid week
"Z2AA01AC25130CD8", // invalid character pos 1
"0ZAA01AC25130CD8", // invalid character pos 2
"020A01AC25130CD8", // invalid character pos 3
"02A201AC25130CD8", // invalid character pos 4
"02AAZ1AC25130CD8", // invalid character pos 5
"02AA0ZAC25130CD8", // invalid character pos 6
"02AA019C25130CD8", // invalid character pos 7
"02AA01A925130CD8", // invalid character pos 8
"02AA01AAZ5130CD8", // invalid character pos 9
"02AA01AA2Z130CD8", // invalid character pos 10
"02AA01AA25Z30CD8", // invalid character pos 11
"02AA01AA251Z0CD8", // invalid character pos 12
"02AA01AA2513ICD8", // invalid character pos 13
"02AA01AA25130OD8", // invalid character pos 14
"02AA01AA25130C*8", // invalid character pos 15
"02AA01AA25130CD)", // invalid character pos 16
NULL
};
for (const char **sn = GoodSNs; *sn != NULL; sn++)
{
bool isValid = IsValidSerialNumber(*sn);
if (!isValid)
printf("%s\n", *sn);
TestAssert(isValid, "IsValidSerialNumber() returned false for valid serial number");
}
for (const char **sn = BadSNs; *sn != NULL; sn++)
{
bool isValid = IsValidSerialNumber(*sn);
if (isValid)
printf("%s\n", *sn);
TestAssert(!isValid, "IsValidSerialNumber() returned true for invalid serial number");
}
}
int main()
{
TestMfgDateConversion();
TestMfgDateFromSerialNum();
TestSerialNumValidation();
printf("All tests passed\n");
return 0;
}