Skip to content

Adding CI unit testing for ArduinoCore-API #122

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 102 commits into from
Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
95a146f
Initial minimal commit to compile a host-run test binary
aentinger Sep 8, 2020
1fcfa7f
Adding test code for 'isHexadecimalDigit'
aentinger Sep 8, 2020
2efc193
Adding test code for 'isUpperCase'
aentinger Sep 8, 2020
e35d969
Adding test code for 'isSpace'
aentinger Sep 8, 2020
7639c5c
Adding test code for 'max'
aentinger Sep 8, 2020
3541f60
Adding test code for 'min'
aentinger Sep 8, 2020
5841c06
Adding test code for 'makeWord' and 'word'
aentinger Sep 8, 2020
da4b985
Adding test code for 'isPunct'
aentinger Sep 8, 2020
1c0027c
Adding test code for 'isLowerCase'
aentinger Sep 8, 2020
09ce806
Adding test code for 'isDigit'
aentinger Sep 8, 2020
c616c58
Adding test code for 'isControl'
aentinger Sep 8, 2020
09d4c4c
Adding test code for 'isWhitespace'
aentinger Sep 8, 2020
4749b49
Adding test code for 'RingbufferN::isFull'
aentinger Sep 8, 2020
0c2502b
Fix: 'memset' requires including of 'string.h'
aentinger Sep 8, 2020
ed6bea5
Adding test code for 'RingbufferN::available'
aentinger Sep 8, 2020
33da3fd
Separating tests for RingbufferN::available from RingBufferN::availab…
aentinger Sep 8, 2020
f4d76bd
Adding test code for 'RingbufferN::clear'
aentinger Sep 8, 2020
208f455
Augment test for 'RingBufferN::isFull'
aentinger Sep 8, 2020
b8ae7a0
Fixing RingBufferN
aentinger Sep 8, 2020
7219305
Augment test for 'RingBufferN::store_char'
aentinger Sep 8, 2020
b7edc11
Adding test code for 'Ringbuffer::read_char'
aentinger Sep 9, 2020
9a14dd6
Fixing bugs when attempting to read from ringbuffer
aentinger Sep 9, 2020
2efb5d4
Adding test code for 'Ringbuffer::peek'
aentinger Sep 9, 2020
0520927
Cross-compiling 'String' which requires to provide implementions for …
aentinger Sep 9, 2020
81b202f
Adding basic tests for 'Print::print'
aentinger Sep 9, 2020
2e88c2e
Adding PrintMock object to be shared by multiple test modules
aentinger Sep 10, 2020
9c3efec
Replacing PrintMock within test_print module with the one general ava…
aentinger Sep 10, 2020
369aad4
Adding basic tests for 'Print::getWriteError'
aentinger Sep 10, 2020
d1dda97
Adding basic tests for 'Print::clearWriteError'
aentinger Sep 10, 2020
3f868e7
Adding ests for all 'IPAddress' ctors
aentinger Sep 10, 2020
4f67378
Adding test code for 'IPAddress::fromString'
aentinger Sep 10, 2020
4574f2a
Fixing IPAddress::fromString for '1.1.1.' as well as '...'
aentinger Sep 10, 2020
4540cf4
Adding test code for 'IPAddress::operator ==(...)'
aentinger Sep 25, 2020
9951941
Adding test code for 'IPAddress::operator !=(...)'
aentinger Sep 25, 2020
e514ac5
Adding test code for 'IPAddress::operator =(...)'
aentinger Sep 25, 2020
19fdf41
Add workflow to run unit tests
per1234 Sep 25, 2020
5baa2db
Adding test code for testing all the String::Ctors(...)
aentinger Oct 5, 2020
da48f24
Repairing itoa module as we'd have doubly defined functions since ito…
aentinger Oct 5, 2020
c760378
Adding test code for String::length
aentinger Oct 7, 2020
9bbd479
Fixing name of parameter of String::concat(unsigned char) to be consi…
aentinger Oct 7, 2020
e77606b
Adding test code for String::concat(...)
aentinger Oct 7, 2020
ae57e3c
Adding test code for String::toLowerCase/toUpperCase
aentinger Oct 7, 2020
8da1dcf
Adding test code for String::trim
aentinger Oct 7, 2020
4e295b1
Adding test code for String::replace(...)
aentinger Oct 7, 2020
27cfc4e
Only perform the strcpy if writeTo and readFrom are different from on…
aentinger Oct 7, 2020
b76e0af
Adding test code for String::toInt()
aentinger Oct 7, 2020
fe61782
Adding test code for String::toFloat
aentinger Oct 8, 2020
a46aef0
Adding test code for String::toDouble
aentinger Oct 8, 2020
153a1f1
Adding test code for String::remove(...)
aentinger Oct 8, 2020
8fd3148
Adding test code for String::indexOf(...)
aentinger Oct 9, 2020
2c77098
Adding test code for String::lastIndexOf(...)
aentinger Oct 9, 2020
560a67c
Add test code for String::compareTo(...)
giulcioffi Oct 12, 2020
56d0de2
Add test code for String comparison functions
giulcioffi Oct 12, 2020
4673dd3
Add test for String character access Functions
giulcioffi Oct 13, 2020
5a05bb6
Add test code for String::String(unsigned char value, unsigned char b…
giulcioffi Oct 13, 2020
3965a74
Add test code for String::substring(...)
giulcioffi Oct 13, 2020
b59d22c
Add test code for String::String(const __FlashStringHelper)
giulcioffi Oct 13, 2020
e83ce70
Add test code for String::concat(const __FlashStringHelper *)
giulcioffi Oct 14, 2020
c3e155c
Add test code for String operator +
giulcioffi Oct 15, 2020
e4febf7
Add test code to complete coverage of String::replace(const String& f…
giulcioffi Oct 15, 2020
411e44a
Fix implementation of String::replace(const String& find, const Strin…
giulcioffi Oct 15, 2020
1891605
Add new test code for 'find' len higher than 'replace' len
giulcioffi Oct 16, 2020
7592064
Use arduino/cpp-test-action in Unit Test CI workflow
per1234 Oct 13, 2020
3df9f93
Merge pull request #125 from per1234/ci-unit-test-workflow-update
aentinger Nov 2, 2020
dd4467c
Adding test code for print(long/unsigned long/long long/unsigned long…
aentinger Nov 2, 2020
d616d12
Adding test code for print(double, int = 2)
aentinger Nov 2, 2020
4bcdd13
When a negative parameter is fed for the number of digits then defaul…
aentinger Nov 2, 2020
23ef4ce
Adding test code for print(Printable)
aentinger Nov 2, 2020
5bd28b7
Adding test code for Common::map
aentinger Nov 2, 2020
e1c65ce
Providing test code for IPAddress::printTo(...)
aentinger Nov 2, 2020
5d4e194
Adding test code for IPAddress::operator()
aentinger Nov 2, 2020
724015b
Adding test code for all those Print::println(...) variants
aentinger Nov 3, 2020
b87d192
Adding test code for Print::print/println(const String &)
aentinger Nov 3, 2020
cbd8350
Adding test code for Print::print/println(const char [])
aentinger Nov 3, 2020
c4a6cc7
Adding test code for Print::print/println(unsigned char, int)
aentinger Nov 3, 2020
4bd4018
Adding test code for Print::availableForWrite
aentinger Nov 3, 2020
4bdadc9
Adding missing but relevant REQUIRE statement
aentinger Nov 3, 2020
f2dcfc4
Adding test code for Print::print/println(const __FlashStringHelper *)
aentinger Nov 3, 2020
b6a55a8
Adding StreamMock class to test functions of Stream base class as wel…
aentinger Nov 4, 2020
09541b3
Disable 'int atexit(void (*func)()) __attribute__((weak));' for host …
aentinger Nov 4, 2020
4f5332d
Compiling 'Stream.cpp' for which it's necessary to provide a fake mil…
aentinger Nov 4, 2020
716c324
Renaming module 'millis' to 'MillisFake' to better reflect the actual…
aentinger Nov 4, 2020
ff7e4a6
Adding test code for Stream::readString
aentinger Nov 4, 2020
abee6d1
Fixing a couple of issues within StreamMock so that it's now fully fu…
aentinger Nov 4, 2020
fbe1cd0
Augmenting the MillisFake module with an automatic mode where real sy…
aentinger Nov 4, 2020
7182f67
Adding test code for Stream::readStringUntil(...)
aentinger Nov 5, 2020
08a44c9
Adding test code for Stream::find(...)
aentinger Nov 5, 2020
a7e0931
Adding test code for Stream::findUntil(...)
aentinger Nov 5, 2020
52ddc44
Addding test code for Stream::parseInt(...)
aentinger Nov 5, 2020
5c7276a
Adding test code for Stream::parseFloat(...)
aentinger Nov 5, 2020
da7100c
Reworking parseInt test code
aentinger Nov 5, 2020
2c1feec
Adding test code for Stream::readBytes(...)
aentinger Nov 5, 2020
3af6c3c
Adding test code for Stream::readBytesUntil()
aentinger Nov 5, 2020
1cf220b
Add test case for String::compareTo() with empty buffer
giulcioffi Nov 3, 2020
73550eb
Add test cases for String::toInt() and String::toDouble() with invali…
giulcioffi Nov 4, 2020
d2c8b2e
Add test code for & String::operator[]
giulcioffi Nov 4, 2020
6d9db81
Test String(const __FlashStringHelper) constructor() with invalid buffer
giulcioffi Nov 4, 2020
db294c0
Add test code for String(String &&) and String(StringSumHelper &&)
giulcioffi Nov 5, 2020
1dd2db6
Add test code for String::operator =
giulcioffi Nov 5, 2020
760e397
Add test code that implies move(String &rhs) from larger to smaller b…
giulcioffi Nov 5, 2020
0b454b7
Add readme badges for Unit Tests workflow and Codecov
per1234 Nov 6, 2020
c4a350a
Merge pull request #126 from per1234/badge
aentinger Nov 6, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Unit Tests

on:
pull_request:
# Only run workflow if a file in these paths are modified
paths:
- ".github/workflows/unit-tests.yml"
- "test/**"
- "api/**"

push:
paths:
- ".github/workflows/unit-tests.yml"
- "test/**"
- "api/**"

jobs:
test:
name: Run unit tests
runs-on: ubuntu-latest

env:
COVERAGE_DATA_PATH: extras/coverage-data/coverage.info

steps:
- name: Checkout repository
uses: actions/checkout@v2

# See: https://github.com/arduino/cpp-test-action/blob/main/README.md
- uses: arduino/cpp-test-action@main
with:
source-path: test
build-path: test/build
runtime-path: test/build/bin/test-ArduinoCore-API
coverage-exclude-paths: |
- '*/test/*'
- '/usr/*'
coverage-data-path: ${{ env.COVERAGE_DATA_PATH }}

# See: https://github.com/codecov/codecov-action/blob/master/README.md
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v1
with:
file: ${{ env.COVERAGE_DATA_PATH }}
fail_ci_if_error: true
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# ArduinoCore-API

[![Unit Tests](https://github.com/arduino/ArduinoCore-API/workflows/Unit%20Tests/badge.svg)](https://github.com/arduino/ArduinoCore-API/actions?workflow=Unit+Tests)
[![codecov](https://codecov.io/gh/arduino/ArduinoCore-API/branch/master/graph/badge.svg)](https://codecov.io/gh/arduino/ArduinoCore-API)

This repository hosts the hardware independent layer of Arduino core.

All Arduino official cores are being ported to the new structure so they take advantage of this single repo.
Expand Down
2 changes: 2 additions & 0 deletions api/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ typedef uint16_t word;
void init(void);
void initVariant(void);

#ifndef HOST
int atexit(void (*func)()) __attribute__((weak));
#endif
int main() __attribute__((weak));

#ifdef EXTENDED_PIN_MODE
Expand Down
14 changes: 11 additions & 3 deletions api/IPAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ bool IPAddress::fromString(const char *address)
{
// TODO: add support for "a", "a.b", "a.b.c" formats

uint16_t acc = 0; // Accumulator
int16_t acc = -1; // Accumulator
uint8_t dots = 0;

while (*address)
{
char c = *address++;
if (c >= '0' && c <= '9')
{
acc = acc * 10 + (c - '0');
acc = (acc < 0) ? (c - '0') : acc * 10 + (c - '0');
if (acc > 255) {
// Value out of [0..255] range
return false;
Expand All @@ -69,8 +69,12 @@ bool IPAddress::fromString(const char *address)
// Too much dots (there must be 3 dots)
return false;
}
if (acc < 0) {
/* No value between dots, e.g. '1..' */
return false;
}
_address.bytes[dots++] = acc;
acc = 0;
acc = -1;
}
else
{
Expand All @@ -83,6 +87,10 @@ bool IPAddress::fromString(const char *address)
// Too few dots (there must be 3 dots)
return false;
}
if (acc < 0) {
/* No value between dots, e.g. '1..' */
return false;
}
_address.bytes[3] = acc;
return true;
}
Expand Down
5 changes: 4 additions & 1 deletion api/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,11 @@ size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
return bytes;
}

size_t Print::printFloat(double number, uint8_t digits)
size_t Print::printFloat(double number, int digits)
{
if (digits < 0)
digits = 2;

size_t n = 0;

if (isnan(number)) return print("nan");
Expand Down
2 changes: 1 addition & 1 deletion api/Print.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Print
int write_error;
size_t printNumber(unsigned long, uint8_t);
size_t printULLNumber(unsigned long long, uint8_t);
size_t printFloat(double, uint8_t);
size_t printFloat(double, int);
protected:
void setWriteError(int err = 1) { write_error = err; }
public:
Expand Down
30 changes: 13 additions & 17 deletions api/RingBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define _RING_BUFFER_

#include <stdint.h>
#include <string.h>

namespace arduino {

Expand All @@ -38,6 +39,7 @@ class RingBufferN
uint8_t _aucBuffer[N] ;
volatile int _iHead ;
volatile int _iTail ;
volatile int _numElems;

public:
RingBufferN( void ) ;
Expand All @@ -51,6 +53,7 @@ class RingBufferN

private:
int nextIndex(int index);
inline bool isEmpty() const { return (_numElems == 0); }
};

typedef RingBufferN<SERIAL_BUFFER_SIZE> RingBuffer;
Expand All @@ -66,16 +69,15 @@ RingBufferN<N>::RingBufferN( void )
template <int N>
void RingBufferN<N>::store_char( uint8_t c )
{
int i = nextIndex(_iHead);

// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if ( i != _iTail )
if (!isFull())
{
_aucBuffer[_iHead] = c ;
_iHead = i ;
_iHead = nextIndex(_iHead);
_numElems++;
}
}

Expand All @@ -84,44 +86,38 @@ void RingBufferN<N>::clear()
{
_iHead = 0;
_iTail = 0;
_numElems = 0;
}

template <int N>
int RingBufferN<N>::read_char()
{
if(_iTail == _iHead)
if (isEmpty())
return -1;

uint8_t value = _aucBuffer[_iTail];
_iTail = nextIndex(_iTail);
_numElems--;

return value;
}

template <int N>
int RingBufferN<N>::available()
{
int delta = _iHead - _iTail;

if(delta < 0)
return N + delta;
else
return delta;
return _numElems;
}

template <int N>
int RingBufferN<N>::availableForStore()
{
if (_iHead >= _iTail)
return N - 1 - _iHead + _iTail;
else
return _iTail - _iHead - 1;
return (N - _numElems);
}

template <int N>
int RingBufferN<N>::peek()
{
if(_iTail == _iHead)
if (isEmpty())
return -1;

return _aucBuffer[_iTail];
Expand All @@ -136,7 +132,7 @@ int RingBufferN<N>::nextIndex(int index)
template <int N>
bool RingBufferN<N>::isFull()
{
return (nextIndex(_iHead) == _iTail);
return (_numElems == N);
}

}
Expand Down
21 changes: 13 additions & 8 deletions api/String.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,17 +646,22 @@ void String::replace(const String& find, const String& replace)
readFrom = foundAt + replace.len;
}
} else if (diff < 0) {
char *writeTo = buffer;
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
unsigned int n = foundAt - readFrom;
memcpy(writeTo, readFrom, n);
writeTo += n;
memcpy(writeTo, replace.buffer, replace.len);
writeTo += replace.len;
readFrom = foundAt + find.len;
len += diff;
diff = 0 - diff;
size -= diff;
}
if (size == len) return;
int index = len - 1;
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = buffer + index + find.len;
memmove(readFrom - diff, readFrom, len - (readFrom - buffer));
len -= diff;
buffer[len] = 0;
memcpy(buffer + index, replace.buffer, replace.len);
index--;
}
strcpy(writeTo, readFrom);
} else {
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
Expand Down
2 changes: 1 addition & 1 deletion api/String.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class String
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(char c);
unsigned char concat(unsigned char c);
unsigned char concat(unsigned char num);
unsigned char concat(int num);
unsigned char concat(unsigned int num);
unsigned char concat(long num);
Expand Down
1 change: 1 addition & 0 deletions test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build
Loading