mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-25 20:02:37 +03:00
Device side test library and test runner
This commit is contained in:
parent
33723a9b52
commit
ab7af89002
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -1,3 +1,2 @@
|
||||
hardware
|
||||
tmp
|
||||
.env
|
||||
|
@ -1,155 +0,0 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "FS.h"
|
||||
|
||||
|
||||
void fail(const char* msg) {
|
||||
Serial.println(msg);
|
||||
while (true) {
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
WiFi.mode(WIFI_OFF);
|
||||
Serial.println("\n\nFS test\n");
|
||||
|
||||
{
|
||||
if (!SPIFFS.format()) {
|
||||
fail("format failed");
|
||||
}
|
||||
Dir root = SPIFFS.openDir("/");
|
||||
int count = 0;
|
||||
while (root.next()) {
|
||||
++count;
|
||||
}
|
||||
if (count > 0) {
|
||||
fail("some files left after format");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!SPIFFS.begin()) {
|
||||
fail("SPIFFS init failed");
|
||||
}
|
||||
|
||||
String text = "write test";
|
||||
{
|
||||
File out = SPIFFS.open("/tmp.txt", "w");
|
||||
if (!out) {
|
||||
fail("failed to open tmp.txt for writing");
|
||||
}
|
||||
out.print(text);
|
||||
}
|
||||
|
||||
{
|
||||
File in = SPIFFS.open("/tmp.txt", "r");
|
||||
if (!in) {
|
||||
fail("failed to open tmp.txt for reading");
|
||||
}
|
||||
Serial.printf("size=%d\r\n", in.size());
|
||||
if (in.size() != text.length()) {
|
||||
fail("invalid size of tmp.txt");
|
||||
}
|
||||
Serial.print("Reading data: ");
|
||||
in.setTimeout(0);
|
||||
String result = in.readString();
|
||||
Serial.println(result);
|
||||
if (result != text) {
|
||||
fail("invalid data in tmp.txt");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
String name = "seq_";
|
||||
name += i;
|
||||
name += ".txt";
|
||||
|
||||
File out = SPIFFS.open(name, "w");
|
||||
if (!out) {
|
||||
fail("can't open seq_ file");
|
||||
}
|
||||
|
||||
out.println(i);
|
||||
}
|
||||
}
|
||||
{
|
||||
Dir root = SPIFFS.openDir("/");
|
||||
while (root.next()) {
|
||||
String fileName = root.fileName();
|
||||
File f = root.openFile("r");
|
||||
Serial.printf("%s: %d\r\n", fileName.c_str(), f.size());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Dir root = SPIFFS.openDir("/");
|
||||
while (root.next()) {
|
||||
String fileName = root.fileName();
|
||||
Serial.print("deleting ");
|
||||
Serial.println(fileName);
|
||||
if (!SPIFFS.remove(fileName)) {
|
||||
fail("remove failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
File tmp = SPIFFS.open("/tmp1.txt", "w");
|
||||
tmp.println("rename test");
|
||||
}
|
||||
|
||||
{
|
||||
if (!SPIFFS.rename("/tmp1.txt", "/tmp2.txt")) {
|
||||
fail("rename failed");
|
||||
}
|
||||
File tmp2 = SPIFFS.open("/tmp2.txt", "r");
|
||||
if (!tmp2) {
|
||||
fail("open tmp2 failed");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
FSInfo info;
|
||||
if (!SPIFFS.info(info)) {
|
||||
fail("info failed");
|
||||
}
|
||||
Serial.printf("Total: %u\nUsed: %u\nBlock: %u\nPage: %u\nMax open files: %u\nMax path len: %u\n",
|
||||
info.totalBytes,
|
||||
info.usedBytes,
|
||||
info.blockSize,
|
||||
info.pageSize,
|
||||
info.maxOpenFiles,
|
||||
info.maxPathLength
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
if (!SPIFFS.format()) {
|
||||
fail("format failed");
|
||||
}
|
||||
Dir root = SPIFFS.openDir("/");
|
||||
int count = 0;
|
||||
while (root.next()) {
|
||||
++count;
|
||||
}
|
||||
if (count > 0) {
|
||||
fail("some files left after format");
|
||||
}
|
||||
}
|
||||
{
|
||||
File tmp = SPIFFS.open("/tmp.txt", "w");
|
||||
}
|
||||
{
|
||||
File tmp = SPIFFS.open("/tmp.txt", "w");
|
||||
if (!tmp) {
|
||||
fail("failed to re-open empty file");
|
||||
}
|
||||
}
|
||||
Serial.println("success");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <time.h>
|
||||
|
||||
const char* ssid = "..........";
|
||||
const char* password = "..........";
|
||||
|
||||
int timezone = 3;
|
||||
int dst = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
Serial.println("\nConnecting to WiFi");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
|
||||
Serial.println("\nWaiting for time");
|
||||
while (!time(nullptr)) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
time_t now = time(nullptr);
|
||||
Serial.println(ctime(&now));
|
||||
delay(1000);
|
||||
}
|
2
tests/device/.gitignore
vendored
Normal file
2
tests/device/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.build
|
||||
.hardware
|
98
tests/device/Makefile
Normal file
98
tests/device/Makefile
Normal file
@ -0,0 +1,98 @@
|
||||
SHELL := /bin/bash
|
||||
V ?= 0
|
||||
TEST_LIST ?= $(wildcard test_*/*.ino)
|
||||
ESP8266_CORE_PATH ?= ../..
|
||||
BUILD_DIR ?= $(PWD)/.build
|
||||
HARDWARE_DIR ?= $(PWD)/.hardware
|
||||
ESPTOOL ?= $(ESP8266_CORE_PATH)/tools/esptool/esptool
|
||||
UPLOAD_PORT ?= $(shell ls /dev/tty* | grep -m 1 -i USB)
|
||||
UPLOAD_BAUD ?= 921600
|
||||
UPLOAD_BOARD ?= nodemcu
|
||||
BS_DIR ?= libraries/BSTest
|
||||
DEBUG_LEVEL ?= DebugLevel=None____
|
||||
FQBN ?= esp8266com:esp8266:generic:CpuFrequency=80,FlashFreq=40,FlashMode=DIO,UploadSpeed=115200,FlashSize=4M1M,ResetMethod=none,Debug=Serial$(DEBUG_LEVEL)
|
||||
BUILD_TOOL = $(ARDUINO_IDE_PATH)/arduino-builder
|
||||
TEST_CONFIG = libraries/test_config/test_config.h
|
||||
|
||||
ifeq ("$(UPLOAD_PORT)","")
|
||||
$(error "Failed to detect upload port, please export UPLOAD_PORT manually")
|
||||
endif
|
||||
|
||||
ifeq ("$(ARDUINO_IDE_PATH)","")
|
||||
$(error "Please export ARDUINO_IDE_PATH")
|
||||
endif
|
||||
|
||||
ifneq ("$(V)","1")
|
||||
SILENT = @
|
||||
else
|
||||
BUILDER_DEBUG_FLAG = -verbose
|
||||
RUNNER_DEBUG_FLAG = -d
|
||||
UPLOAD_VERBOSE_FLAG = -v
|
||||
endif
|
||||
|
||||
|
||||
all: count tests
|
||||
|
||||
count:
|
||||
@echo Running $(words $(TEST_LIST)) tests
|
||||
|
||||
tests: $(BUILD_DIR) $(HARDWARE_DIR) virtualenv $(TEST_CONFIG) $(TEST_LIST)
|
||||
|
||||
$(TEST_LIST): LOCAL_BUILD_DIR=$(BUILD_DIR)/$(notdir $@)
|
||||
|
||||
$(TEST_LIST):
|
||||
$(SILENT)mkdir -p $(LOCAL_BUILD_DIR)
|
||||
ifneq ("$(NO_BUILD)","1")
|
||||
@echo Compiling $(notdir $@)
|
||||
$(SILENT)$(BUILD_TOOL) -compile -logger=human \
|
||||
-libraries "$(PWD)/libraries" \
|
||||
-core-api-version="10608" \
|
||||
-warnings=none \
|
||||
$(BUILDER_DEBUG_FLAG) \
|
||||
-build-path $(LOCAL_BUILD_DIR) \
|
||||
-tools $(ARDUINO_IDE_PATH)/tools-builder \
|
||||
-hardware $(HARDWARE_DIR)\
|
||||
-hardware $(ARDUINO_IDE_PATH)/hardware \
|
||||
-fqbn=$(FQBN) \
|
||||
$@
|
||||
endif
|
||||
ifneq ("$(NO_UPLOAD)","1")
|
||||
$(SILENT)$(ESPTOOL) $(UPLOAD_VERBOSE_FLAG) \
|
||||
-cp $(UPLOAD_PORT) \
|
||||
-cb $(UPLOAD_BAUD) \
|
||||
-cd $(UPLOAD_BOARD) \
|
||||
-cf $(LOCAL_BUILD_DIR)/$(notdir $@).bin
|
||||
endif
|
||||
ifneq ("$(NO_RUN)","1")
|
||||
@echo Running tests
|
||||
$(SILENT)$(ESPTOOL) $(UPLOAD_VERBOSE_FLAG) -cp $(UPLOAD_PORT) -cd $(UPLOAD_BOARD) -cr
|
||||
@source $(BS_DIR)/virtualenv/bin/activate && \
|
||||
python $(BS_DIR)/runner.py \
|
||||
$(RUNNER_DEBUG_FLAG) \
|
||||
-p $(UPLOAD_PORT) \
|
||||
-n $(basename $(notdir $@)) \
|
||||
-o $(LOCAL_BUILD_DIR)/test_result.xml
|
||||
endif
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(HARDWARE_DIR):
|
||||
mkdir -p $(HARDWARE_DIR)/esp8266com
|
||||
cd $(HARDWARE_DIR)/esp8266com && ln -s $(realpath $(ESP8266_CORE_PATH)) esp8266
|
||||
|
||||
virtualenv:
|
||||
make -C $(BS_DIR) virtualenv
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
rm -rf $(HARDWARE_DIR)
|
||||
|
||||
$(TEST_CONFIG):
|
||||
@echo "****** "
|
||||
@echo "****** libraries/test_config/test_config.h does not exist"
|
||||
@echo "****** Create one from libraries/test_config/test_config.h.template"
|
||||
@echo "****** "
|
||||
false
|
||||
|
||||
.PHONY: tests all count venv $(BUILD_DIR) $(TEST_LIST)
|
3
tests/device/libraries/BSTest/.gitignore
vendored
Normal file
3
tests/device/libraries/BSTest/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
test/test
|
||||
virtualenv
|
||||
|
22
tests/device/libraries/BSTest/Makefile
Normal file
22
tests/device/libraries/BSTest/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
PYTHON_ENV_DIR=virtualenv
|
||||
TEST_EXECUTABLE=test/test
|
||||
|
||||
all: test
|
||||
|
||||
install: $(PYTHON_ENV_DIR)
|
||||
|
||||
clean:
|
||||
rm -rf $(PYTHON_ENV_DIR)
|
||||
rm -rf $(TEST_EXECUTABLE)
|
||||
|
||||
$(PYTHON_ENV_DIR):
|
||||
virtualenv --no-site-packages $(PYTHON_ENV_DIR)
|
||||
source $(PYTHON_ENV_DIR)/bin/activate && pip install -r requirements.txt
|
||||
|
||||
test: $(TEST_EXECUTABLE) $(PYTHON_ENV_DIR)
|
||||
source $(PYTHON_ENV_DIR)/bin/activate && python runner.py -e $(TEST_EXECUTABLE)
|
||||
|
||||
$(TEST_EXECUTABLE): test/test.cpp
|
||||
g++ -std=c++11 -Isrc -o $@ test/test.cpp
|
||||
|
||||
.PHONY: test clean install all
|
9
tests/device/libraries/BSTest/library.properties
Normal file
9
tests/device/libraries/BSTest/library.properties
Normal file
@ -0,0 +1,9 @@
|
||||
name=BSTest
|
||||
version=0.1
|
||||
author=Ivan Grokhotkov <ivan@espressif.com>
|
||||
maintainer=Ivan Grokhotkov <ivan@espressif.com>
|
||||
sentence=BS Test library
|
||||
paragraph=
|
||||
category=Uncategorized
|
||||
url=
|
||||
architectures=esp8266
|
6
tests/device/libraries/BSTest/requirements.txt
Normal file
6
tests/device/libraries/BSTest/requirements.txt
Normal file
@ -0,0 +1,6 @@
|
||||
junit-xml==1.6
|
||||
pexpect==4.0.1
|
||||
ptyprocess==0.5.1
|
||||
pyserial==3.0.1
|
||||
six==1.10.0
|
||||
wheel==0.24.0
|
189
tests/device/libraries/BSTest/runner.py
Normal file
189
tests/device/libraries/BSTest/runner.py
Normal file
@ -0,0 +1,189 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
import pexpect
|
||||
from pexpect import EOF, TIMEOUT, fdpexpect
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import argparse
|
||||
import serial
|
||||
import subprocess
|
||||
from urlparse import urlparse
|
||||
from junit_xml import TestSuite, TestCase
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except:
|
||||
from StringIO import StringIO
|
||||
|
||||
debug = False
|
||||
|
||||
def debug_print(*args, **kwargs):
|
||||
if not debug:
|
||||
return
|
||||
print(file=sys.stderr, *args, **kwargs)
|
||||
|
||||
class BSTestRunner(object):
|
||||
|
||||
SUCCESS = 0
|
||||
FAIL = 1
|
||||
TIMEOUT = 2
|
||||
CRASH = 3
|
||||
|
||||
def __init__(self, spawn_obj, name):
|
||||
self.sp = spawn_obj
|
||||
self.tests = []
|
||||
self.reset_timeout = 2
|
||||
self.name = name
|
||||
|
||||
def get_test_list(self):
|
||||
self.sp.sendline('-1')
|
||||
timeout = 10
|
||||
while timeout > 0:
|
||||
res = self.sp.expect(['>>>>>bs_test_menu_begin', EOF])
|
||||
if res == 0:
|
||||
break
|
||||
timeout-=1
|
||||
time.sleep(0.1)
|
||||
debug_print('got begin')
|
||||
self.tests = []
|
||||
while True:
|
||||
res = self.sp.expect(['>>>>>bs_test_item id\=(\d+) name\="([^\"]*?)" desc="([^"]*?)"',
|
||||
'>>>>>bs_test_menu_end',
|
||||
EOF])
|
||||
if res == 0:
|
||||
m = self.sp.match
|
||||
t = {'id': m.group(1), 'name': m.group(2), 'desc': m.group(3)}
|
||||
self.tests.append(t)
|
||||
debug_print('added test', t)
|
||||
elif res == 1:
|
||||
break
|
||||
elif res == 2:
|
||||
time.sleep(0.1)
|
||||
|
||||
debug_print('got {} tests'.format(len(self.tests)))
|
||||
|
||||
def run_tests(self):
|
||||
test_cases = []
|
||||
for test in self.tests:
|
||||
desc = test['desc']
|
||||
name = test['name']
|
||||
index = test['id']
|
||||
test_case = TestCase(name, self.name)
|
||||
if '[.]' in desc:
|
||||
print('skipping test "{}"'.format(name))
|
||||
test_case.add_skipped_info(message="Skipped test marked with [.]")
|
||||
else:
|
||||
test_output = StringIO()
|
||||
self.sp.logfile = test_output
|
||||
t_start = time.time()
|
||||
result = self.run_test(index)
|
||||
t_stop = time.time()
|
||||
self.sp.logfile = None
|
||||
test_case.elapsed_sec = t_stop - t_start
|
||||
debug_print('test output was:')
|
||||
debug_print(test_output.getvalue())
|
||||
if result == BSTestRunner.SUCCESS:
|
||||
test_case.stdout = test_output.getvalue()
|
||||
print('test "{}" passed'.format(name))
|
||||
else:
|
||||
print('test "{}" failed'.format(name))
|
||||
test_case.add_failure_info('Test failed', output=test_output.getvalue())
|
||||
test_output.close()
|
||||
test_cases += [test_case];
|
||||
return TestSuite(self.name, test_cases)
|
||||
|
||||
def run_test(self, index):
|
||||
self.sp.sendline('{}'.format(index))
|
||||
timeout = 10
|
||||
while timeout > 0:
|
||||
res = self.sp.expect(['>>>>>bs_test_start', EOF])
|
||||
if res == 0:
|
||||
break
|
||||
time.sleep(0.1)
|
||||
timeout -= 0.1
|
||||
if timeout <= 0:
|
||||
raise 'test begin timeout'
|
||||
while timeout > 0:
|
||||
res = self.sp.expect(['>>>>>bs_test_check_failure line=(\d+)',
|
||||
'>>>>>bs_test_end line=(\d+) result=(\d+) checks=(\d+) failed_checks=(\d+)',
|
||||
TIMEOUT,
|
||||
EOF,
|
||||
'Exception',
|
||||
'ets Jan 8 2013',
|
||||
'wdt reset'])
|
||||
if res == 0:
|
||||
continue
|
||||
elif res == 1:
|
||||
test_result = self.sp.match.group(2)
|
||||
if test_result == '1':
|
||||
return BSTestRunner.SUCCESS
|
||||
else:
|
||||
if self.sp.match.group(1) != '0':
|
||||
time.sleep(1.0)
|
||||
self.sp.expect([TIMEOUT,
|
||||
'wdt reset',
|
||||
'Exception',
|
||||
'Panic',
|
||||
'Abort',
|
||||
'Soft WDT',
|
||||
EOF], timeout=self.reset_timeout)
|
||||
return BSTestRunner.FAIL
|
||||
elif res == 2 or res == 3:
|
||||
time.sleep(0.1)
|
||||
timeout -= 0.1
|
||||
continue
|
||||
elif res > 3:
|
||||
return BSTestRunner.CRASH
|
||||
if timeout <= 0:
|
||||
return BSTestRunner.TIMEOUT
|
||||
|
||||
ser = None
|
||||
|
||||
def spawn_port(port_name, baudrate=115200):
|
||||
global ser
|
||||
ser = serial.serial_for_url(port_name, baudrate=baudrate)
|
||||
return fdpexpect.fdspawn(ser, 'wb', timeout=0)
|
||||
|
||||
def spawn_exec(name):
|
||||
return pexpect.spawn(name, timeout=0)
|
||||
|
||||
def run_tests(spawn, name):
|
||||
tw = BSTestRunner(spawn, name)
|
||||
tw.get_test_list()
|
||||
return tw.run_tests()
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='BS test runner')
|
||||
parser.add_argument('-d', '--debug', help='Send test output to stderr', action='store_true')
|
||||
parser.add_argument('-p', '--port', help='Talk to the test over serial')
|
||||
parser.add_argument('-e', '--executable', help='Talk to the test executable')
|
||||
parser.add_argument('-n', '--name', help='Test run name')
|
||||
parser.add_argument('-o', '--output', help='Output JUnit format test report')
|
||||
return parser.parse_args()
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
spawn_func = None
|
||||
spawn_arg = None
|
||||
if args.port is not None:
|
||||
spawn_func = spawn_port
|
||||
spawn_arg = args.port
|
||||
elif args.executable is not None:
|
||||
spawn_func = spawn_exec
|
||||
spawn_arg = args.executable
|
||||
name = args.name or ""
|
||||
global debug
|
||||
if args.debug:
|
||||
debug = True
|
||||
if spawn_func is None:
|
||||
debug_print("Please specify port or executable", file=sys.stderr)
|
||||
return 1
|
||||
with spawn_func(spawn_arg) as sp:
|
||||
ts = run_tests(sp, name)
|
||||
if args.output:
|
||||
with open(args.output, "w") as f:
|
||||
TestSuite.to_file(f, [ts])
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
57
tests/device/libraries/BSTest/src/BSArduino.h
Normal file
57
tests/device/libraries/BSTest/src/BSArduino.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef BS_ARDUINO_H
|
||||
#define BS_ARDUINO_H
|
||||
|
||||
#include <Arduino.h>
|
||||
namespace bs
|
||||
{
|
||||
class ArduinoIOHelper
|
||||
{
|
||||
public:
|
||||
ArduinoIOHelper(Stream& stream) : m_stream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
size_t printf(const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
char temp[128];
|
||||
char* buffer = temp;
|
||||
size_t len = vsnprintf(temp, sizeof(temp), format, arg);
|
||||
va_end(arg);
|
||||
if (len > sizeof(temp) - 1) {
|
||||
buffer = new char[len + 1];
|
||||
if (!buffer) {
|
||||
return 0;
|
||||
}
|
||||
va_start(arg, format);
|
||||
ets_vsnprintf(buffer, len + 1, format, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
len = m_stream.write((const uint8_t*) buffer, len);
|
||||
if (buffer != temp) {
|
||||
delete[] buffer;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
bool read_int(int& result)
|
||||
{
|
||||
// TODO: fix this for 0 value
|
||||
result = m_stream.parseInt();
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
Stream& m_stream;
|
||||
};
|
||||
|
||||
typedef ArduinoIOHelper IOHelper;
|
||||
|
||||
inline void fatal() {
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
} // namespace bs
|
||||
|
||||
#endif //BS_ARDUINO_H
|
55
tests/device/libraries/BSTest/src/BSProtocol.h
Normal file
55
tests/device/libraries/BSTest/src/BSProtocol.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef BS_PROTOCOL_H
|
||||
#define BS_PROTOCOL_H
|
||||
|
||||
#define BS_LINE_PREFIX ">>>>>bs_test_"
|
||||
|
||||
namespace bs
|
||||
{
|
||||
namespace protocol
|
||||
{
|
||||
template<typename IO>
|
||||
void output_test_start(IO& io, const char* file, size_t line, const char* name, const char* desc)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "start file=\"%s\" line=%d name=\"%s\" desc=\"%s\"\n", file, line, name, desc);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_check_failure(IO& io, size_t line)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "check_failure line=%d\n", line);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_test_end(IO& io, bool success, size_t checks, size_t failed_checks, size_t line=0)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "end line=%d result=%d checks=%d failed_checks=%d\n", line, success, checks, failed_checks);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_begin(IO& io)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "menu_begin\n");
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_item(IO& io, int index, const char* name, const char* desc)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "item id=%d name=\"%s\" desc=\"%s\"\n", index, name, desc);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_end(IO& io)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "menu_end\n");
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
bool input_menu_choice(IO& io, int& result)
|
||||
{
|
||||
return io.read_int(result);
|
||||
}
|
||||
|
||||
} // ::protocol
|
||||
} // ::bs
|
||||
|
||||
#endif //BS_PROTOCOL_H
|
39
tests/device/libraries/BSTest/src/BSStdio.h
Normal file
39
tests/device/libraries/BSTest/src/BSStdio.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef BS_STDIO_H
|
||||
#define BS_STDIO_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <exception>
|
||||
|
||||
namespace bs
|
||||
{
|
||||
class StdIOHelper
|
||||
{
|
||||
public:
|
||||
StdIOHelper()
|
||||
{
|
||||
}
|
||||
|
||||
size_t printf(const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
size_t result = vprintf(format, arg);
|
||||
va_end(arg);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool read_int(int& result)
|
||||
{
|
||||
return scanf("%d", &result) == 1;
|
||||
}
|
||||
};
|
||||
|
||||
typedef StdIOHelper IOHelper;
|
||||
|
||||
inline void fatal() {
|
||||
throw std::runtime_error("fatal error");
|
||||
}
|
||||
|
||||
} // namespace bs
|
||||
|
||||
#endif //BS_STDIO_H
|
217
tests/device/libraries/BSTest/src/BSTest.h
Normal file
217
tests/device/libraries/BSTest/src/BSTest.h
Normal file
@ -0,0 +1,217 @@
|
||||
#ifndef BSTEST_H
|
||||
#define BSTEST_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
#include "BSProtocol.h"
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#include "BSArduino.h"
|
||||
#else
|
||||
#include "BSStdio.h"
|
||||
#endif
|
||||
|
||||
namespace bs
|
||||
{
|
||||
typedef void(*test_case_func_t)();
|
||||
|
||||
class TestCase
|
||||
{
|
||||
public:
|
||||
TestCase(TestCase* prev, test_case_func_t func, const char* file, size_t line, const char* name, const char* desc)
|
||||
: m_func(func), m_file(file), m_line(line), m_name(name), m_desc(desc)
|
||||
{
|
||||
if (prev) {
|
||||
prev->m_next = this;
|
||||
}
|
||||
}
|
||||
|
||||
void run() const
|
||||
{
|
||||
(*m_func)();
|
||||
}
|
||||
|
||||
TestCase* next() const
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
const char* file() const
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
|
||||
size_t line() const
|
||||
{
|
||||
return m_line;
|
||||
}
|
||||
|
||||
const char* name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const char* desc() const
|
||||
{
|
||||
return (m_desc)?m_desc:"";
|
||||
}
|
||||
|
||||
protected:
|
||||
TestCase* m_next = nullptr;
|
||||
test_case_func_t m_func;
|
||||
const char* m_file;
|
||||
size_t m_line;
|
||||
const char* m_name;
|
||||
const char* m_desc;
|
||||
};
|
||||
|
||||
struct Registry {
|
||||
void add(test_case_func_t func, const char* file, size_t line, const char* name, const char* desc)
|
||||
{
|
||||
TestCase* tc = new TestCase(m_last, func, file, line, name, desc);
|
||||
if (!m_first) {
|
||||
m_first = tc;
|
||||
}
|
||||
m_last = tc;
|
||||
}
|
||||
TestCase* m_first = nullptr;
|
||||
TestCase* m_last = nullptr;
|
||||
};
|
||||
|
||||
struct Env {
|
||||
std::function<void(void)> m_check_pass;
|
||||
std::function<void(size_t)> m_check_fail;
|
||||
std::function<void(size_t)> m_fail;
|
||||
Registry m_registry;
|
||||
};
|
||||
|
||||
extern Env g_env;
|
||||
|
||||
template<typename IO>
|
||||
class Runner
|
||||
{
|
||||
typedef Runner<IO> Tself;
|
||||
public:
|
||||
Runner(IO& io) : m_io(io)
|
||||
{
|
||||
g_env.m_check_pass = std::bind(&Tself::check_pass, this);
|
||||
g_env.m_check_fail = std::bind(&Tself::check_fail, this, std::placeholders::_1);
|
||||
g_env.m_fail = std::bind(&Tself::fail, this, std::placeholders::_1);
|
||||
}
|
||||
|
||||
~Runner()
|
||||
{
|
||||
g_env.m_check_pass = 0;
|
||||
g_env.m_check_fail = 0;
|
||||
g_env.m_fail = 0;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
do {
|
||||
} while(do_menu());
|
||||
}
|
||||
|
||||
void check_pass()
|
||||
{
|
||||
++m_check_pass_count;
|
||||
}
|
||||
|
||||
void check_fail(size_t line)
|
||||
{
|
||||
++m_check_fail_count;
|
||||
protocol::output_check_failure(m_io, line);
|
||||
}
|
||||
|
||||
void fail(size_t line)
|
||||
{
|
||||
protocol::output_test_end(m_io, false, m_check_pass_count + m_check_fail_count, m_check_fail_count, line);
|
||||
bs::fatal();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool do_menu()
|
||||
{
|
||||
protocol::output_menu_begin(m_io);
|
||||
int id = 1;
|
||||
for (TestCase* tc = g_env.m_registry.m_first; tc; tc = tc->next(), ++id) {
|
||||
protocol::output_menu_item(m_io, id, tc->name(), tc->desc());
|
||||
}
|
||||
protocol::output_menu_end(m_io);
|
||||
while(true) {
|
||||
int id;
|
||||
if (!protocol::input_menu_choice(m_io, id)) {
|
||||
continue;
|
||||
}
|
||||
if (id < 0) {
|
||||
return true;
|
||||
}
|
||||
TestCase* tc = g_env.m_registry.m_first;
|
||||
for (int i = 0; i != id - 1 && tc; ++i, tc = tc->next());
|
||||
if (!tc) {
|
||||
bs::fatal();
|
||||
}
|
||||
m_check_pass_count = 0;
|
||||
m_check_fail_count = 0;
|
||||
protocol::output_test_start(m_io, tc->file(), tc->line(), tc->name(), tc->desc());
|
||||
tc->run();
|
||||
bool success = m_check_fail_count == 0;
|
||||
protocol::output_test_end(m_io, success, m_check_pass_count + m_check_fail_count, m_check_fail_count);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
IO& m_io;
|
||||
size_t m_check_pass_count;
|
||||
size_t m_check_fail_count;
|
||||
};
|
||||
|
||||
class AutoReg
|
||||
{
|
||||
public:
|
||||
AutoReg(test_case_func_t func, const char* file, size_t line, const char* name, const char* desc = nullptr)
|
||||
{
|
||||
g_env.m_registry.add(func, file, line, name, desc);
|
||||
}
|
||||
};
|
||||
|
||||
inline void check(bool condition, size_t line)
|
||||
{
|
||||
if (!condition) {
|
||||
g_env.m_check_fail(line);
|
||||
} else {
|
||||
g_env.m_check_pass();
|
||||
}
|
||||
}
|
||||
|
||||
inline void require(bool condition, size_t line)
|
||||
{
|
||||
if (!condition) {
|
||||
g_env.m_check_fail(line);
|
||||
g_env.m_fail(line);
|
||||
} else {
|
||||
g_env.m_check_pass();
|
||||
}
|
||||
}
|
||||
|
||||
} // ::bs
|
||||
|
||||
#define BS_NAME_LINE2( name, line ) name##line
|
||||
#define BS_NAME_LINE( name, line ) BS_NAME_LINE2( name, line )
|
||||
#define BS_UNIQUE_NAME( name ) BS_NAME_LINE( name, __LINE__ )
|
||||
|
||||
#define TEST_CASE( ... ) \
|
||||
static void BS_UNIQUE_NAME( TEST_FUNC__ )(); \
|
||||
namespace{ bs::AutoReg BS_UNIQUE_NAME( test_autoreg__ )( &BS_UNIQUE_NAME( TEST_FUNC__ ), __FILE__, __LINE__, __VA_ARGS__ ); }\
|
||||
static void BS_UNIQUE_NAME( TEST_FUNC__ )()
|
||||
|
||||
#define CHECK(condition) bs::check((condition), __LINE__)
|
||||
#define REQUIRE(condition) bs::require((condition), __LINE__)
|
||||
#define FAIL() bs::g_env.m_fail(__LINE__)
|
||||
|
||||
#define BS_ENV_DECLARE() namespace bs { Env g_env; }
|
||||
#define BS_RUN(...) do { bs::IOHelper helper = bs::IOHelper(__VA_ARGS__); bs::Runner<bs::IOHelper> runner(helper); runner.run(); } while(0);
|
||||
#endif //BSTEST_H
|
51
tests/device/libraries/BSTest/test/test.cpp
Normal file
51
tests/device/libraries/BSTest/test/test.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "BSTest.h"
|
||||
#include <stdio.h>
|
||||
|
||||
BS_ENV_DECLARE();
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
while(true) {
|
||||
try{
|
||||
BS_RUN();
|
||||
return 0;
|
||||
}catch(...) {
|
||||
printf("Exception\n\n");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("this test runs successfully", "[bluesmoke]")
|
||||
{
|
||||
CHECK(1 + 1 == 2);
|
||||
REQUIRE(2 * 2 == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("another test which fails", "[bluesmoke][fail]")
|
||||
{
|
||||
CHECK(true);
|
||||
CHECK(false);
|
||||
CHECK(true);
|
||||
CHECK(false);
|
||||
}
|
||||
|
||||
TEST_CASE("another test which fails and crashes", "[bluesmoke][fail]")
|
||||
{
|
||||
CHECK(true);
|
||||
REQUIRE(false);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("third test which should be skipped", "[.]")
|
||||
{
|
||||
FAIL();
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("this test also runs successfully", "[bluesmoke]")
|
||||
{
|
||||
|
||||
}
|
1
tests/device/libraries/test_config/.gitignore
vendored
Normal file
1
tests/device/libraries/test_config/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
test_config.h
|
9
tests/device/libraries/test_config/library.properties
Normal file
9
tests/device/libraries/test_config/library.properties
Normal file
@ -0,0 +1,9 @@
|
||||
name=TestConfig
|
||||
version=0.0
|
||||
author=
|
||||
maintainer=
|
||||
sentence=
|
||||
paragraph=
|
||||
category=Uncategorized
|
||||
url=
|
||||
architectures=esp8266
|
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#define STA_SSID "test_wifi"
|
||||
#define STA_PASS "test_wifi_pass"
|
||||
|
||||
#define AP_SSID "test_wifi_ap"
|
||||
#define AP_PASS "test_wifi_ap_pass"
|
||||
|
136
tests/device/test_FS/test_FS.ino
Normal file
136
tests/device/test_FS/test_FS.ino
Normal file
@ -0,0 +1,136 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "FS.h"
|
||||
#include <BSTest.h>
|
||||
|
||||
BS_ENV_DECLARE();
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
BS_RUN(Serial);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("read-write test","[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
|
||||
String text = "write test";
|
||||
{
|
||||
File out = SPIFFS.open("/tmp.txt", "w");
|
||||
REQUIRE(out);
|
||||
out.print(text);
|
||||
}
|
||||
|
||||
{
|
||||
File in = SPIFFS.open("/tmp.txt", "r");
|
||||
REQUIRE(in);
|
||||
CHECK(in.size() == text.length());
|
||||
in.setTimeout(0);
|
||||
String result = in.readString();
|
||||
CHECK(result == text);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("A bunch of files show up in openDir, and can be removed", "[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
const int n = 10;
|
||||
int found[n] = {0};
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
String name = "seq_";
|
||||
name += i;
|
||||
name += ".txt";
|
||||
|
||||
File out = SPIFFS.open(name, "w");
|
||||
REQUIRE(out);
|
||||
|
||||
out.println(i);
|
||||
}
|
||||
|
||||
{
|
||||
Dir root = SPIFFS.openDir("/");
|
||||
while (root.next()) {
|
||||
String fileName = root.fileName();
|
||||
CHECK(fileName.indexOf("seq_") == 0);
|
||||
int i = fileName.substring(4).toInt();
|
||||
CHECK(i >= 0 && i < n);
|
||||
found[i]++;
|
||||
}
|
||||
|
||||
for (auto f : found) {
|
||||
CHECK(f == 1);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Dir root = SPIFFS.openDir("/");
|
||||
while (root.next()) {
|
||||
String fileName = root.fileName();
|
||||
CHECK(SPIFFS.remove(fileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("files can be renamed", "[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
{
|
||||
File tmp = SPIFFS.open("/tmp1.txt", "w");
|
||||
tmp.println("rename test");
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(SPIFFS.rename("/tmp1.txt", "/tmp2.txt"));
|
||||
|
||||
File tmp2 = SPIFFS.open("/tmp2.txt", "r");
|
||||
CHECK(tmp2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("FS::info works")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
FSInfo info;
|
||||
CHECK(SPIFFS.info(info));
|
||||
|
||||
Serial.printf("Total: %u\nUsed: %u\nBlock: %u\nPage: %u\nMax open files: %u\nMax path len: %u\n",
|
||||
info.totalBytes,
|
||||
info.usedBytes,
|
||||
info.blockSize,
|
||||
info.pageSize,
|
||||
info.maxOpenFiles,
|
||||
info.maxPathLength
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE("FS is empty after format","[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
REQUIRE(SPIFFS.format());
|
||||
|
||||
Dir root = SPIFFS.openDir("/");
|
||||
int count = 0;
|
||||
while (root.next()) {
|
||||
++count;
|
||||
}
|
||||
CHECK(count == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Can reopen empty file","[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
{
|
||||
File tmp = SPIFFS.open("/tmp.txt", "w");
|
||||
}
|
||||
{
|
||||
File tmp = SPIFFS.open("/tmp.txt", "w");
|
||||
CHECK(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
38
tests/device/test_Print_printf/test_Print_printf.ino
Normal file
38
tests/device/test_Print_printf/test_Print_printf.ino
Normal file
@ -0,0 +1,38 @@
|
||||
#include <BSTest.h>
|
||||
#include <StreamString.h>
|
||||
|
||||
BS_ENV_DECLARE();
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
BS_RUN(Serial);
|
||||
}
|
||||
|
||||
TEST_CASE("Print::printf works for any reasonable output length", "[Print]")
|
||||
{
|
||||
|
||||
auto test_printf = [](size_t size) {
|
||||
StreamString str;
|
||||
auto buf = new char[size + 1];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
buf[i] = 'a';
|
||||
}
|
||||
buf[size] = 0;
|
||||
str.printf("%s%8d", buf, 56789102);
|
||||
delete[] buf;
|
||||
CHECK(str.length() == size + 8);
|
||||
CHECK(str.substring(size) == "56789102");
|
||||
};
|
||||
|
||||
auto before = ESP.getFreeHeap();
|
||||
test_printf(1);
|
||||
test_printf(10);
|
||||
test_printf(100);
|
||||
test_printf(1000);
|
||||
test_printf(10000);
|
||||
auto after = ESP.getFreeHeap();
|
||||
CHECK(before == after);
|
||||
}
|
||||
|
||||
void loop() {}
|
35
tests/device/test_http_client/test_http_client.ino
Normal file
35
tests/device/test_http_client/test_http_client.ino
Normal file
@ -0,0 +1,35 @@
|
||||
#include <Arduino.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266HTTPClient.h>
|
||||
#include <BSTest.h>
|
||||
#include <test_config.h>
|
||||
|
||||
BS_ENV_DECLARE();
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.persistent(false);
|
||||
WiFi.begin(STA_SSID, STA_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
}
|
||||
BS_RUN(Serial);
|
||||
}
|
||||
|
||||
TEST_CASE("HTTP client GET request", "[HTTPClient]")
|
||||
{
|
||||
HTTPClient http;
|
||||
http.begin("http://httpbin.org/get?a=1&b=asdadf");
|
||||
auto httpCode = http.GET();
|
||||
CHECK(httpCode == HTTP_CODE_OK);
|
||||
String payload = http.getString();
|
||||
CHECK(payload.indexOf("\"a\": \"1\"") != -1);
|
||||
CHECK(payload.indexOf("\"b\": \"asdad\"") != -1);
|
||||
http.end();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
38
tests/device/test_overrides/test_overrides.ino
Normal file
38
tests/device/test_overrides/test_overrides.ino
Normal file
@ -0,0 +1,38 @@
|
||||
#include <BSTest.h>
|
||||
BS_ENV_DECLARE();
|
||||
|
||||
ADC_MODE(ADC_VCC);
|
||||
RF_MODE(RF_CAL);
|
||||
|
||||
static int rf_pre_init_flag = 0;
|
||||
|
||||
RF_PRE_INIT()
|
||||
{
|
||||
rf_pre_init_flag = 42;
|
||||
}
|
||||
|
||||
static unsigned setup_micros;
|
||||
|
||||
void setup()
|
||||
{
|
||||
setup_micros = micros();
|
||||
Serial.begin(115200);
|
||||
BS_RUN(Serial);
|
||||
}
|
||||
|
||||
TEST_CASE("ADC_MODE override works", "[core]")
|
||||
{
|
||||
auto vcc = ESP.getVcc();
|
||||
Serial.printf("VCC: %d\r\n", vcc);
|
||||
Serial.printf("A0: %d\r\n", analogRead(A0));
|
||||
CHECK(vcc > 3000 && vcc < 3600);
|
||||
}
|
||||
|
||||
TEST_CASE("RF_PRE_INIT override works", "[core]")
|
||||
{
|
||||
CHECK(rf_pre_init_flag == 42);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
47
tests/device/test_tests/test_tests.ino
Normal file
47
tests/device/test_tests/test_tests.ino
Normal file
@ -0,0 +1,47 @@
|
||||
#include <BSTest.h>
|
||||
#include <test_config.h>
|
||||
|
||||
BS_ENV_DECLARE();
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
BS_RUN(Serial);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("this test runs successfully", "[bs]")
|
||||
{
|
||||
CHECK(1 + 1 == 2);
|
||||
REQUIRE(2 * 2 == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("another test which fails", "[bs][fail]")
|
||||
{
|
||||
CHECK(true);
|
||||
CHECK(false);
|
||||
CHECK(true);
|
||||
CHECK(false);
|
||||
}
|
||||
|
||||
TEST_CASE("another test which fails and crashes", "[bs][fail]")
|
||||
{
|
||||
CHECK(true);
|
||||
REQUIRE(false);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("third test which should be skipped", "[.]")
|
||||
{
|
||||
FAIL();
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("this test also runs successfully", "[bs]")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
46
tests/device/test_time/test_time.ino
Normal file
46
tests/device/test_time/test_time.ino
Normal file
@ -0,0 +1,46 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <time.h>
|
||||
#include <ESP8266HTTPClient.h>
|
||||
#include <BSTest.h>
|
||||
#include <test_config.h>
|
||||
|
||||
BS_ENV_DECLARE();
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.persistent(false);
|
||||
WiFi.begin(STA_SSID, STA_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
}
|
||||
BS_RUN(Serial);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Can sync time", "[time]")
|
||||
{
|
||||
int timezone = 3;
|
||||
int dst = 0;
|
||||
|
||||
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
|
||||
Serial.println("\nWaiting for time");
|
||||
unsigned timeout = 5000;
|
||||
unsigned start = millis();
|
||||
while (millis() - start < timeout) {
|
||||
time_t now = time(nullptr);
|
||||
if (now > (2016 - 1970) * 365 * 24 * 3600) {
|
||||
return;
|
||||
}
|
||||
delay(100);
|
||||
}
|
||||
{
|
||||
time_t now = time(nullptr);
|
||||
Serial.println(ctime(&now));
|
||||
}
|
||||
CHECK(false);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
@ -1,13 +1,21 @@
|
||||
// test that we can include umm_malloc.h from sketch (#1652)
|
||||
#include <umm_malloc/umm_malloc.h>
|
||||
|
||||
#include <BSTest.h>
|
||||
|
||||
void setup() {
|
||||
BS_ENV_DECLARE();
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
BS_RUN(Serial);
|
||||
}
|
||||
|
||||
TEST_CASE("umm_info can be called", "[umm_malloc]")
|
||||
{
|
||||
umm_info(NULL, 1);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
ADC_MODE(ADC_VCC);
|
||||
RF_MODE(RF_DISABLED);
|
||||
RF_PRE_INIT()
|
||||
{
|
||||
}
|
||||
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user