mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-06 05:21:22 +03:00
Device tests updates (#9246)
Stop pyexpect from closing serial port when running with WSL2 Remove makefile flags & opts making it too silent. At some point it makes a lot of useful info just disappear. There are external means of silencing make, so probably best to leave useful data always available Replace SPIFFS with LittleFS in FS test Re-use certs-from-mozilla.py in FS test Fix libc tests w/o -fno-builtin not actually testing anything, also add the flag via .globals.h in case it breaks Fix libc tests generating warnings when using invalid (but safe) size arguments
This commit is contained in:
parent
a5f18b5f91
commit
92002ece2e
@ -13,15 +13,9 @@ import os
|
||||
import sys
|
||||
from shutil import which
|
||||
|
||||
from subprocess import Popen, PIPE, call
|
||||
try:
|
||||
from urllib.request import urlopen
|
||||
except Exception:
|
||||
from urllib2 import urlopen
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except Exception:
|
||||
from io import StringIO
|
||||
from io import StringIO
|
||||
from subprocess import Popen, PIPE, call, CalledProcessError
|
||||
from urllib.request import urlopen
|
||||
|
||||
# check if ar and openssl are available
|
||||
if which('ar') is None and not os.path.isfile('./ar') and not os.path.isfile('./ar.exe'):
|
||||
@ -62,10 +56,10 @@ for i in range(0, len(pems)):
|
||||
thisPem = pems[i].replace("'", "")
|
||||
print(names[i] + " -> " + certName)
|
||||
ssl = Popen(['openssl','x509','-inform','PEM','-outform','DER','-out', certName], shell = False, stdin = PIPE)
|
||||
pipe = ssl.stdin
|
||||
pipe.write(thisPem.encode('utf-8'))
|
||||
pipe.close()
|
||||
ssl.wait()
|
||||
ssl.communicate(thisPem.encode('utf-8'))
|
||||
ret = ssl.wait()
|
||||
if ret != 0:
|
||||
raise CalledProcessError(ret, certName)
|
||||
if os.path.exists(certName):
|
||||
derFiles.append(certName)
|
||||
idx = idx + 1
|
||||
|
@ -1,45 +1,65 @@
|
||||
SHELL := /bin/bash
|
||||
V ?= 0
|
||||
ESP8266_CORE_PATH ?= $(realpath ../..)
|
||||
BUILD_DIR ?= $(PWD)/.build
|
||||
HARDWARE_DIR ?= $(PWD)/.hardware
|
||||
|
||||
ESP8266_CORE_PATH ?= $(shell git rev-parse --show-toplevel)
|
||||
|
||||
BUILD_DIR ?= $(PWD)/build
|
||||
BS_DIR ?= $(PWD)/libraries/BSTest
|
||||
|
||||
PYTHON ?= python3
|
||||
ESPTOOL ?= $(PYTHON) $(ESP8266_CORE_PATH)/tools/esptool/esptool.py
|
||||
MKSPIFFS ?= $(ESP8266_CORE_PATH)/tools/mkspiffs/mkspiffs
|
||||
|
||||
VENV_PYTHON ?= $(BS_DIR)/virtualenv/bin/python
|
||||
VENV_JUNIT2HTML ?= $(BS_DIR)/virtualenv/bin/junit2html
|
||||
|
||||
MKFS ?= $(ESP8266_CORE_PATH)/tools/mklittlefs/mklittlefs
|
||||
|
||||
UPLOAD_PORT ?= $(shell ls /dev/tty* | grep -m 1 -i USB)
|
||||
UPLOAD_BAUD ?= 460800
|
||||
UPLOAD_BOARD ?= nodemcu
|
||||
BS_DIR ?= libraries/BSTest
|
||||
DEBUG_LEVEL ?= lvl=None____
|
||||
FQBN ?= esp8266com:esp8266:generic:xtal=160,FlashFreq=40,FlashMode=dio,baud=115200,eesz=4M1M,ip=lm2f,ResetMethod=nodemcu,dbg=Serial,$(DEBUG_LEVEL)
|
||||
BUILD_TOOL := $(ARDUINO_IDE_PATH)/arduino-builder
|
||||
|
||||
TEST_BAUD ?= 115200
|
||||
BUILD_TOOL ?= arduino-cli
|
||||
|
||||
BUILD_BOARD ?= generic
|
||||
BUILD_CPU ?= 160
|
||||
BUILD_SIZE ?= 4M1M
|
||||
BUILD_LWIP ?= lm2f
|
||||
BUILD_EXTRA ?= ,dbg=Serial,lvl=CORE
|
||||
|
||||
FQBN ?= esp8266com:esp8266:$(BUILD_BOARD):xtal=$(BUILD_CPU),baud=$(TEST_BAUD),eesz=$(BUILD_SIZE),ip=$(BUILD_LWIP)$(BUILD_EXTRA)
|
||||
|
||||
TEST_CONFIG := test_env.cfg
|
||||
TEST_RESULT_XML := test_result.xml
|
||||
TEST_REPORT_XML := test_report.xml
|
||||
TEST_REPORT_HTML := test_report.html
|
||||
|
||||
ifeq ("$(MOCK)", "1")
|
||||
# To enable a test for mock testing, just rename dir+files to '*_sw_*'
|
||||
TEST_LIST ?= $(wildcard test_sw_*/*.ino)
|
||||
else
|
||||
TEST_LIST ?= $(wildcard test_*/*.ino)
|
||||
BUILD_FLAGS ?=
|
||||
BS_FLAGS ?=
|
||||
|
||||
# To enable a test for mock testing, just rename dir+files to '*_sw_*'
|
||||
ifeq ("$(MOCK)", "1")
|
||||
TEST_LIST := $(filter test_sw_%.ino,$(TEST_LIST))
|
||||
NO_UPLOAD := 1
|
||||
NO_RUN := 1
|
||||
endif
|
||||
|
||||
ifneq ("$(V)","1")
|
||||
SILENT = @
|
||||
REDIR = >& /dev/null
|
||||
else
|
||||
BUILDER_DEBUG_FLAG = -verbose
|
||||
RUNNER_DEBUG_FLAG = -d
|
||||
#UPLOAD_VERBOSE_FLAG = -v
|
||||
# To enable verbose mode, call `make V=1` ...
|
||||
V ?= 0
|
||||
ifeq ("$(V)", "1")
|
||||
BUILD_FLAGS += --verbose
|
||||
BS_FLAGS += --debug
|
||||
endif
|
||||
|
||||
# ${sketch}.py helper script when building locally
|
||||
mock_script = \
|
||||
`test -f $(addsuffix .py, $(basename $(1))) && echo "--mock $(addsuffix .py, $(basename $(1)))" || echo ""`
|
||||
|
||||
help:
|
||||
@echo
|
||||
@echo 'make list - show list of tests'
|
||||
@echo 'make sometest/sometest.ino - run one test'
|
||||
@echo 'make all - run all tests'
|
||||
@echo 'make MOCK=1 all - run all emulation-on-host compatible tests'
|
||||
@echo 'variables needed: $$ARDUINO_IDE_PATH $$ESP8266_CORE_PATH'
|
||||
@echo 'make options: V=1 NO_BUILD=1 NO_UPLOAD=1 NO_RUN=1 MOCK=1'
|
||||
@echo
|
||||
|
||||
@ -49,110 +69,132 @@ all: count tests test_report
|
||||
|
||||
$(TEST_LIST): | virtualenv $(TEST_CONFIG) $(BUILD_DIR) $(HARDWARE_DIR)
|
||||
|
||||
.NOTPARALLEL: $(TEST_LIST)
|
||||
|
||||
tests: showtestlist $(TEST_LIST)
|
||||
|
||||
showtestlist:
|
||||
@echo "-------------------------------- test list:"
|
||||
@echo $(TEST_LIST)
|
||||
@printf '%s\n' $(TEST_LIST)
|
||||
@echo "--------------------------------"
|
||||
|
||||
$(TEST_LIST): LOCAL_BUILD_DIR=$(BUILD_DIR)/$(notdir $@)
|
||||
$(TEST_LIST): LOCAL_DATA_IMG=data.img
|
||||
|
||||
$(TEST_LIST):
|
||||
@echo "--------------------------------"
|
||||
@echo "Running test '$@' of $(words $(TEST_LIST)) tests"
|
||||
$(SILENT)mkdir -p $(LOCAL_BUILD_DIR)
|
||||
ifeq ("$(MOCK)", "1")
|
||||
@echo Compiling $(notdir $@)
|
||||
(cd ../host; make D=$(V) ULIBDIRS=../device/libraries/BSTest ../device/$(@:%.ino=%))
|
||||
$(SILENT)$(BS_DIR)/virtualenv/bin/python \
|
||||
$(BS_DIR)/runner.py \
|
||||
$(RUNNER_DEBUG_FLAG) \
|
||||
-e "$(ESP8266_CORE_PATH)/tests/host/bin/$(@:%.ino=%)" \
|
||||
-n $(basename $(notdir $@)) \
|
||||
-o $(LOCAL_BUILD_DIR)/test_result.xml \
|
||||
--env-file $(TEST_CONFIG) \
|
||||
`test -f $(addsuffix .py, $(basename $@)) && echo "-m $(addsuffix .py, $(basename $@))" || echo ""`
|
||||
else
|
||||
ifneq ("$(NO_BUILD)","1")
|
||||
@test -n "$(ARDUINO_IDE_PATH)" || (echo "Please export ARDUINO_IDE_PATH" && exit 1)
|
||||
@echo Compiling $(notdir $@)
|
||||
@rm -f $(LOCAL_BUILD_DIR)/build.options.json
|
||||
$(SILENT)$(BUILD_TOOL) -compile -logger=human \
|
||||
-libraries "$(PWD)/libraries" \
|
||||
-core-api-version="10608" \
|
||||
-warnings=all \
|
||||
$(BUILDER_DEBUG_FLAG) \
|
||||
-build-path $(LOCAL_BUILD_DIR) \
|
||||
-tools $(ARDUINO_IDE_PATH)/tools-builder \
|
||||
-hardware $(HARDWARE_DIR)\
|
||||
-hardware $(ARDUINO_IDE_PATH)/hardware \
|
||||
-fqbn=$(FQBN) \
|
||||
define build-arduino
|
||||
rm -f $(LOCAL_BUILD_DIR)/build.options.json
|
||||
$(BUILD_TOOL) compile \
|
||||
$(BUILD_FLAGS) \
|
||||
--libraries "$(PWD)/libraries" \
|
||||
--warnings=all \
|
||||
--build-path $(LOCAL_BUILD_DIR) \
|
||||
--fqbn=$(FQBN) \
|
||||
$@
|
||||
endif
|
||||
ifneq ("$(NO_UPLOAD)","1")
|
||||
@test -n "$(UPLOAD_PORT)" || (echo "Failed to detect upload port, please export UPLOAD_PORT manually" && exit 1)
|
||||
@test -e $(dir $@)/make_spiffs.py && ( \
|
||||
echo "Generating and uploading SPIFFS" && \
|
||||
(cd $(dir $@) && $(PYTHON) ./make_spiffs.py $(REDIR) ) && \
|
||||
$(MKSPIFFS) --create $(dir $@)data/ --size 0xFB000 \
|
||||
--block 8192 --page 256 $(LOCAL_BUILD_DIR)/spiffs.img $(REDIR) && \
|
||||
$(ESPTOOL) $(UPLOAD_VERBOSE_FLAG) \
|
||||
endef
|
||||
|
||||
define build-mock
|
||||
(cd $(ESP8266_CORE_PATH)/test/host; \
|
||||
$(MAKE) D=$(V) ULIBDIRS=$(PWD)/libraries/BSTest $(PWD)/$(@:%.ino=%))
|
||||
$(VENV_PYTHON) $(BS_DIR)/runner.py \
|
||||
$(BS_FLAGS) \
|
||||
--name $(basename $(notdir $@)) \
|
||||
--output $(LOCAL_BUILD_DIR)/$(TEST_RESULT_XML) \
|
||||
--env-file $(TEST_CONFIG) \
|
||||
$(call mock_script,$@) \
|
||||
executable "$(ESP8266_CORE_PATH)/tests/host/bin/$(@:%.ino=%)" || echo ""`
|
||||
endef
|
||||
|
||||
define upload-data
|
||||
@test -n "$(UPLOAD_PORT)" \
|
||||
|| (echo "Failed to detect upload port, please export UPLOAD_PORT manually" && exit 1)
|
||||
@test ! \( -d $(dir $@)/data/ \) -a \( -e $(dir $@)/make_data.py \) && \
|
||||
(cd $(dir $@) && ./make_data.py ) || echo "Filesystem creation skipped"
|
||||
@test -d $(dir $@)/data/ && ( \
|
||||
$(MKFS) \
|
||||
--create $(dir $@)/data/ \
|
||||
--size 0xFB000 \
|
||||
--block 8192 \
|
||||
--page 256 \
|
||||
$(LOCAL_BUILD_DIR)/$(LOCAL_DATA_IMG) && \
|
||||
$(ESPTOOL) \
|
||||
--chip esp8266 \
|
||||
--port $(UPLOAD_PORT) \
|
||||
--baud $(UPLOAD_BAUD) \
|
||||
--after no_reset \
|
||||
write_flash 0x300000 $(LOCAL_BUILD_DIR)/spiffs.img $(REDIR) ) \
|
||||
|| (echo "No SPIFFS to upload")
|
||||
@echo Uploading binary
|
||||
$(SILENT)$(ESPTOOL) $(UPLOAD_VERBOSE_FLAG) \
|
||||
write_flash 0x300000 $(LOCAL_BUILD_DIR)/$(LOCAL_DATA_IMG) ) \
|
||||
&& (echo "Uploaded filesystem") \
|
||||
|| (echo "Filesystem upload skipped")
|
||||
endef
|
||||
|
||||
define upload-binary
|
||||
@test -n "$(UPLOAD_PORT)" \
|
||||
|| (echo "Failed to detect upload port, please export UPLOAD_PORT manually" && exit 1)
|
||||
$(ESPTOOL) \
|
||||
--chip esp8266 \
|
||||
--port $(UPLOAD_PORT) \
|
||||
--baud $(UPLOAD_BAUD) \
|
||||
--after no_reset \
|
||||
write_flash 0x0 $(LOCAL_BUILD_DIR)/$(notdir $@).bin $(REDIR) # no reset
|
||||
endif
|
||||
ifneq ("$(NO_RUN)","1")
|
||||
@test -n "$(UPLOAD_PORT)" || (echo "Failed to detect upload port, please export UPLOAD_PORT manually" && exit 1)
|
||||
write_flash 0x0 $(LOCAL_BUILD_DIR)/$(notdir $@).bin
|
||||
endef
|
||||
|
||||
define run-test
|
||||
@test -n "$(UPLOAD_PORT)" \
|
||||
|| (echo "Failed to detect upload port, please export UPLOAD_PORT manually" && exit 1)
|
||||
@echo Running tests
|
||||
$(SILENT)$(ESPTOOL) $(UPLOAD_VERBOSE_FLAG) \
|
||||
$(ESPTOOL) \
|
||||
--chip esp8266 \
|
||||
--port $(UPLOAD_PORT) \
|
||||
--baud $(UPLOAD_BAUD) \
|
||||
read_flash_status $(REDIR) # reset
|
||||
$(SILENT)$(BS_DIR)/virtualenv/bin/python \
|
||||
$(BS_DIR)/runner.py \
|
||||
$(RUNNER_DEBUG_FLAG) \
|
||||
-p $(UPLOAD_PORT) \
|
||||
-n $(basename $(notdir $@)) \
|
||||
-o $(LOCAL_BUILD_DIR)/test_result.xml \
|
||||
--env-file $(TEST_CONFIG) \
|
||||
`test -f $(addsuffix .py, $(basename $@)) && echo "-m $(addsuffix .py, $(basename $@))" || echo ""`
|
||||
read_flash_status # reset via implicit stub reboot
|
||||
$(VENV_PYTHON) $(BS_DIR)/runner.py \
|
||||
$(BS_FLAGS) \
|
||||
--name $(basename $(notdir $@)) \
|
||||
--output $(LOCAL_BUILD_DIR)/$(TEST_RESULT_XML) \
|
||||
--env-file $(TEST_CONFIG) \
|
||||
$(call mock_script,$@) \
|
||||
port $(UPLOAD_PORT) \
|
||||
--baudrate $(TEST_BAUD)
|
||||
endef
|
||||
|
||||
$(TEST_LIST):
|
||||
@echo "--------------------------------"
|
||||
@echo "Running test '$@' of $(words $(TEST_LIST)) tests"
|
||||
mkdir -p $(LOCAL_BUILD_DIR)
|
||||
ifneq ("$(NO_BUILD)","1")
|
||||
@echo Building $(notdir $@)
|
||||
ifeq ("$(MOCK)", "1")
|
||||
$(build-mock)
|
||||
else
|
||||
$(build-arduino)
|
||||
endif
|
||||
endif
|
||||
ifneq ("$(NO_UPLOAD)","1")
|
||||
$(upload-filesystem)
|
||||
$(upload-binary)
|
||||
endif
|
||||
ifneq ("$(NO_RUN)","1")
|
||||
$(run-test)
|
||||
endif
|
||||
|
||||
$(TEST_REPORT_XML): $(HARDWARE_DIR) virtualenv
|
||||
$(SILENT)$(BS_DIR)/xunitmerge $(shell find $(BUILD_DIR) -name 'test_result.xml' | xargs echo) $(TEST_REPORT_XML)
|
||||
$(TEST_REPORT_XML): virtualenv
|
||||
$(BS_DIR)/xunitmerge \
|
||||
$(shell find $(BUILD_DIR) -name '$(TEST_RESULT_XML)' | xargs echo) \
|
||||
$(TEST_REPORT_XML)
|
||||
|
||||
$(TEST_REPORT_HTML): $(TEST_REPORT_XML) | virtualenv
|
||||
$(SILENT)$(BS_DIR)/virtualenv/bin/junit2html $< $@
|
||||
$(VENV_JUNIT2HTML) $< $@
|
||||
|
||||
test_report: $(TEST_REPORT_HTML)
|
||||
@echo "Test report generated in $(TEST_REPORT_HTML)"
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(HARDWARE_DIR):
|
||||
mkdir -p $(HARDWARE_DIR)/esp8266com
|
||||
cd $(HARDWARE_DIR)/esp8266com && ln -s $(realpath $(ESP8266_CORE_PATH)) esp8266
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
|
||||
virtualenv:
|
||||
@make -C $(BS_DIR) PYTHON=$(PYTHON) virtualenv
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
rm -rf $(HARDWARE_DIR)
|
||||
rm -rf $(BS_DIR)/virtualenv
|
||||
rm -f $(TEST_REPORT_HTML) $(TEST_REPORT_XML)
|
||||
|
||||
|
@ -1,40 +1,32 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import print_function
|
||||
|
||||
import serial
|
||||
|
||||
import pexpect
|
||||
from pexpect import EOF, TIMEOUT, fdpexpect
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import argparse
|
||||
import serial
|
||||
import subprocess
|
||||
|
||||
from importlib.machinery import SourceFileLoader
|
||||
|
||||
try:
|
||||
from configparser import ConfigParser
|
||||
except:
|
||||
from ConfigParser import ConfigParser
|
||||
import itertools
|
||||
try:
|
||||
from urllib.parse import urlparse, urlencode
|
||||
except ImportError:
|
||||
from urlparse import urlparse
|
||||
from junit_xml import TestSuite, TestCase
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except:
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
from configparser import ConfigParser
|
||||
from importlib.machinery import SourceFileLoader
|
||||
from io import StringIO
|
||||
from urllib.parse import urlparse, urlencode
|
||||
|
||||
import mock_decorators
|
||||
|
||||
debug = False
|
||||
#debug = True
|
||||
|
||||
sys.path.append(os.path.abspath(__file__))
|
||||
|
||||
IS_WSL = len(os.environ.get("WSL_DISTRO_NAME", "")) > 0
|
||||
|
||||
def debug_print(*args, **kwargs):
|
||||
if not debug:
|
||||
return
|
||||
@ -235,9 +227,11 @@ class BSTestRunner(object):
|
||||
|
||||
ser = None
|
||||
|
||||
def spawn_port(port_name, baudrate=115200):
|
||||
def spawn_port(port_name, baudrate=115200, close=True):
|
||||
global ser
|
||||
ser = serial.serial_for_url(port_name, baudrate=baudrate)
|
||||
if not close:
|
||||
ser.close = lambda: None
|
||||
return fdpexpect.fdspawn(ser, 'wb', timeout=0, encoding='cp437')
|
||||
|
||||
def spawn_exec(name):
|
||||
@ -250,30 +244,39 @@ def run_tests(spawn, name, mocks, env_vars):
|
||||
|
||||
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')
|
||||
parser.add_argument('-m', '--mock', help='Set python script to use for mocking purposes')
|
||||
parser.add_argument('--debug', help='Send test output to stderr', action='store_true')
|
||||
parser.add_argument('--name', help='Test run name')
|
||||
parser.add_argument('--output', help='Output JUnit format test report')
|
||||
parser.add_argument('--mock', help='Set python script to use for mocking purposes')
|
||||
parser.add_argument('--env-file', help='File containing a list of environment variables to set', type=argparse.FileType('r'))
|
||||
|
||||
sub = parser.add_subparsers()
|
||||
|
||||
def as_spawn_port(args):
|
||||
return spawn_port(args.port, args.baudrate, args.close)
|
||||
|
||||
port = sub.add_parser('port')
|
||||
port.add_argument('port', type=str)
|
||||
port.add_argument('--baudrate', help='Serial port baudrate', type=int, default=115200)
|
||||
port.add_argument('--close', help='Close serial port after the test', action=argparse.BooleanOptionalAction, default=not IS_WSL)
|
||||
port.set_defaults(func=as_spawn_port)
|
||||
|
||||
def as_spawn_exec(args):
|
||||
return spawn_exec(args.executable)
|
||||
|
||||
exe = sub.add_parser('executable')
|
||||
exe.add_argument('executable', help='Talk to the test executable')
|
||||
exe.set_defaults(func=as_spawn_exec)
|
||||
|
||||
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 = args.debug
|
||||
if args.func is None:
|
||||
debug_print("Please specify port or executable", file=sys.stderr)
|
||||
return 1
|
||||
env_vars = []
|
||||
@ -287,7 +290,8 @@ def main():
|
||||
if args.mock is not None:
|
||||
mocks_mod = SourceFileLoader('mocks', args.mock).load_module()
|
||||
mocks = mock_decorators.env
|
||||
with spawn_func(spawn_arg) as sp:
|
||||
|
||||
with args.func(args) as sp:
|
||||
ts = run_tests(sp, name, mocks, env_vars)
|
||||
if args.output:
|
||||
with open(args.output, "w") as f:
|
||||
|
1
tests/device/test_BearSSL/make_data.py
Symbolic link
1
tests/device/test_BearSSL/make_data.py
Symbolic link
@ -0,0 +1 @@
|
||||
../../../libraries/ESP8266WiFi/examples/BearSSL_CertStore/certs-from-mozilla.py
|
@ -1,71 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# This script pulls the list of Mozilla trusted certificate authorities
|
||||
# from the web at the "mozurl" below, parses the file to grab the PEM
|
||||
# for each cert, and then generates DER files in a new ./data directory
|
||||
# Upload these to a SPIFFS filesystem and use the CertManager to parse
|
||||
# and use them for your outgoing SSL connections.
|
||||
#
|
||||
# Script by Earle F. Philhower, III. Released to the public domain.
|
||||
from __future__ import print_function
|
||||
import csv
|
||||
import os
|
||||
import sys
|
||||
from subprocess import Popen, PIPE, call
|
||||
try:
|
||||
from urllib.request import urlopen
|
||||
except:
|
||||
from urllib2 import urlopen
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except:
|
||||
from io import StringIO
|
||||
|
||||
# Mozilla's URL for the CSV file with included PEM certs
|
||||
mozurl = "https://ccadb-public.secure.force.com/mozilla/IncludedCACertificateReportPEMCSV"
|
||||
|
||||
# Load the manes[] and pems[] array from the URL
|
||||
names = []
|
||||
pems = []
|
||||
response = urlopen(mozurl)
|
||||
csvData = response.read()
|
||||
if sys.version_info[0] > 2:
|
||||
csvData = csvData.decode('utf-8')
|
||||
csvFile = StringIO(csvData)
|
||||
csvReader = csv.reader(csvFile)
|
||||
for row in csvReader:
|
||||
names.append(row[0]+":"+row[1]+":"+row[2])
|
||||
pems.append(row[30])
|
||||
del names[0] # Remove headers
|
||||
del pems[0] # Remove headers
|
||||
|
||||
# Try and make ./data, skip if present
|
||||
try:
|
||||
os.mkdir("data")
|
||||
except:
|
||||
pass
|
||||
|
||||
derFiles = []
|
||||
idx = 0
|
||||
# Process the text PEM using openssl into DER files
|
||||
for i in range(0, len(pems)):
|
||||
certName = "data/ca_%03d.der" % (idx);
|
||||
thisPem = pems[i].replace("'", "")
|
||||
print(names[i] + " -> " + certName)
|
||||
ssl = Popen(['openssl','x509','-inform','PEM','-outform','DER','-out', certName], shell = False, stdin = PIPE)
|
||||
pipe = ssl.stdin
|
||||
pipe.write(thisPem.encode('utf-8'))
|
||||
pipe.close()
|
||||
ssl.wait()
|
||||
if os.path.exists(certName):
|
||||
derFiles.append(certName)
|
||||
idx = idx + 1
|
||||
|
||||
if os.path.exists("data/certs.ar"):
|
||||
os.unlink("data/certs.ar");
|
||||
|
||||
arCmd = ['ar', 'q', 'data/certs.ar'] + derFiles;
|
||||
call( arCmd )
|
||||
|
||||
for der in derFiles:
|
||||
os.unlink(der)
|
@ -1,7 +1,7 @@
|
||||
// Stress test the BearSSL connection options to determine
|
||||
// maximum memory use for different SSL connections and
|
||||
// SPIFFS certstore usage. Before running you need to run
|
||||
// certs-from-mozilla.py and upload the generated SPIFFS file.
|
||||
// filesystem certstore usage. Before running the test you need to
|
||||
// update them with certs-from-mozilla.py and upload the generated file.
|
||||
//
|
||||
// For more info on CertStores, see the BearSSL_CertStore example
|
||||
//
|
||||
@ -12,7 +12,7 @@
|
||||
#include <BSTest.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <CertStoreBearSSL.h>
|
||||
#include <FS.h>
|
||||
#include <LittleFS.h>
|
||||
#include <time.h>
|
||||
#include <StackThunk.h>
|
||||
|
||||
@ -45,11 +45,11 @@ bool pretest()
|
||||
delay(500);
|
||||
}
|
||||
setClock();
|
||||
SPIFFS.begin();
|
||||
int numCerts = certStore.initCertStore(SPIFFS, "/certs.idx", "/certs.ar");
|
||||
LittleFS.begin();
|
||||
int numCerts = certStore.initCertStore(LittleFS, "/certs.idx", "/certs.ar");
|
||||
Serial.printf("Number of CA certs read: %d\n", numCerts);
|
||||
if (numCerts == 0) {
|
||||
Serial.printf("No certs found. Did you run certs-from-mozill.py and upload the SPIFFS directory before running?\n");
|
||||
Serial.printf("No certs found. Did you run upload script?\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -3,51 +3,130 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define memcmp memcmp_P
|
||||
#define memcpy memcpy_P
|
||||
#define memmem memmem_P
|
||||
#define memchr memchr_P
|
||||
#define strcat strcat_P
|
||||
#define strncat strncat_P
|
||||
#define strcpy strcpy_P
|
||||
#define strncpy strncpy_P
|
||||
#define strlen strlen_P
|
||||
#define strnlen strnlen_P
|
||||
#define strcmp strcmp_P
|
||||
#define strncmp strncmp_P
|
||||
#include <sys/pgmspace.h>
|
||||
|
||||
_CONST char* it = "<UNSET>"; /* Routine name for message routines. */
|
||||
/* esp8266/Arduino note
|
||||
*
|
||||
* Prevent the compiler from
|
||||
* - solving test cases below at compile time, effectively removing any checks
|
||||
* - optimizing out libc func calls, replacing them with bytewise memory access
|
||||
*
|
||||
* Plus, test framework cannot pass -fno-builtin-... per-file, only globally
|
||||
*/
|
||||
|
||||
#define xDST_SRC_N(T, NAME)\
|
||||
static T* __attribute__((used, noinline)) x ## NAME (T* dst, const T* src, size_t n)\
|
||||
{\
|
||||
return NAME (dst, src, n);\
|
||||
}
|
||||
|
||||
xDST_SRC_N (void, memcpy)
|
||||
xDST_SRC_N (void, memmove)
|
||||
xDST_SRC_N (char, strncat)
|
||||
xDST_SRC_N (char, strncpy)
|
||||
|
||||
#define xDST_SRC(T, NAME)\
|
||||
static T* __attribute__((used, noinline)) x ## NAME (T* dst, const T* src)\
|
||||
{\
|
||||
return NAME (dst, src);\
|
||||
}
|
||||
|
||||
xDST_SRC (char, strcat)
|
||||
xDST_SRC (char, strcpy)
|
||||
|
||||
#define xS1_S2_N(RET, T, NAME)\
|
||||
static RET __attribute__((used, noinline)) x ## NAME (const T *s1, const T *s2, size_t n)\
|
||||
{\
|
||||
return NAME (s1, s2, n);\
|
||||
}
|
||||
|
||||
xS1_S2_N(int, void, memcmp)
|
||||
xS1_S2_N(int, char, strncmp)
|
||||
|
||||
static int __attribute__((used, noinline)) xstrcmp (const char *s1, const char *s2)
|
||||
{
|
||||
return strcmp (s1, s2);
|
||||
}
|
||||
|
||||
static void* __attribute__((used, noinline)) xmemchr (const void* s, int c, size_t n)
|
||||
{
|
||||
return memchr (s, c, n);
|
||||
}
|
||||
|
||||
static size_t __attribute__((used, noinline)) xstrlen (const char* s)
|
||||
{
|
||||
return strlen (s);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* TODO remove when libc supports pointers to flash */
|
||||
#undef PSTR
|
||||
#define PSTR(X) X
|
||||
|
||||
#define memcmp(s1,s2,n) xmemcmp(s1,PSTR(s2),n)
|
||||
#define memcpy(dest,src,n) xmemcpy(dest,PSTR(src),n)
|
||||
#define memmove(dest,src,n) xmemmove(dest,PSTR(src),n)
|
||||
#define memchr(s,c,n) xmemchr(PSTR(s),c,n)
|
||||
#define strcat(dst,src) xstrcat(dst,PSTR(src))
|
||||
#define strncat(dst,src,ssize) xstrncat(dst,PSTR(src),ssize)
|
||||
#define strcpy(dst,src) xstrcpy(dst,PSTR(src))
|
||||
#define strncpy(dst,src,dsize) xstrncpy(dst,PSTR(src),dsize)
|
||||
#define strlen(s) xstrlen(PSTR(s))
|
||||
#define strcmp(s1,s2) xstrcmp(s1,PSTR(s2))
|
||||
#define strncmp(s1,s2,n) xstrncmp(s1,PSTR(s2),n)
|
||||
|
||||
#else
|
||||
|
||||
/* in case wrapped calls are not required */
|
||||
|
||||
#define memcmp(s1,s2,n) memcmp_P(s1,PSTR(s2),n)
|
||||
#define memcpy(dest,src,n) memcpy_P(dest,PSTR(src),n)
|
||||
#define memmove(dest,src,n) memmove_P(dest,PSTR(src),n)
|
||||
#define memchr(s,c,n) memchr_P(PSTR(s),c,n)
|
||||
#define strcat(dst,src) strcat_P(dst,PSTR(src))
|
||||
#define strncat(dst,src,ssize) strncat_P(dst,PSTR(src),ssize)
|
||||
#define strcpy(dst,src) strcpy_P(dst,PSTR(src))
|
||||
#define strncpy(dst,src,dsize) strncpy_P(dst,PSTR(src),dsize)
|
||||
#define strlen(s) strlen_P(PSTR(s))
|
||||
#define strcmp(s1,s2) strcmp_P(s1,PSTR(s2))
|
||||
#define strncmp(s1,s2,n) strncmp_P(s1,PSTR(s2),n)
|
||||
|
||||
#endif
|
||||
|
||||
static const char Unset[] PROGMEM = "<UNSET>";
|
||||
|
||||
const char* it = Unset; /* Routine name for message routines. */
|
||||
static int errors = 0;
|
||||
|
||||
/* Complain if condition is not true. */
|
||||
#define check(thing) checkit(thing, __LINE__)
|
||||
|
||||
static void _DEFUN(checkit, (ok, l), int ok _AND int l)
|
||||
|
||||
static void checkit(int ok, int l)
|
||||
{
|
||||
// newfunc(it);
|
||||
// line(l);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
printf("string.c:%d %s\n", l, it);
|
||||
printf(PSTR("string.c:%d %s\n"), l, it);
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
|
||||
/* Complain if first two args don't strcmp as equal. */
|
||||
#define equal(a, b) funcqual(a, b, __LINE__);
|
||||
#define equal(a, b) funcqual(a, PSTR(b), __LINE__);
|
||||
|
||||
static void _DEFUN(funcqual, (a, b, l), char* a _AND char* b _AND int l)
|
||||
static void funcqual(const char *a, const char *b, int l)
|
||||
{
|
||||
// newfunc(it);
|
||||
|
||||
// line(l);
|
||||
if (a == NULL && b == NULL)
|
||||
return;
|
||||
if (strcmp(a, b))
|
||||
if (strcmp_P(a, b))
|
||||
{
|
||||
printf("string.c:%d (%s)\n", l, it);
|
||||
printf(PSTR("string.c:%d (%s)\n"), l, it);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +136,7 @@ static char two[50];
|
||||
void libm_test_string()
|
||||
{
|
||||
/* Test strcmp first because we use it to test other things. */
|
||||
it = "strcmp";
|
||||
it = PSTR("strcmp");
|
||||
check(strcmp("", "") == 0); /* Trivial case. */
|
||||
check(strcmp("a", "a") == 0); /* Identity. */
|
||||
check(strcmp("abc", "abc") == 0); /* Multicharacter. */
|
||||
@ -69,7 +148,7 @@ void libm_test_string()
|
||||
check(strcmp("a\103", "a\003") > 0);
|
||||
|
||||
/* Test strcpy next because we need it to set up other tests. */
|
||||
it = "strcpy";
|
||||
it = PSTR("strcpy");
|
||||
check(strcpy(one, "abcd") == one); /* Returned value. */
|
||||
equal(one, "abcd"); /* Basic test. */
|
||||
|
||||
@ -78,7 +157,7 @@ void libm_test_string()
|
||||
equal(one + 2, "cd"); /* Wrote too much? */
|
||||
|
||||
(void)strcpy(two, "hi there");
|
||||
(void)strcpy(one, two);
|
||||
(void)xstrcpy(one, two);
|
||||
equal(one, "hi there"); /* Basic test encore. */
|
||||
equal(two, "hi there"); /* Stomped on source? */
|
||||
|
||||
@ -86,7 +165,7 @@ void libm_test_string()
|
||||
equal(one, ""); /* Boundary condition. */
|
||||
|
||||
/* strcat. */
|
||||
it = "strcat";
|
||||
it = PSTR("strcat");
|
||||
(void)strcpy(one, "ijk");
|
||||
check(strcat(one, "lmn") == one); /* Returned value. */
|
||||
equal(one, "ijklmn"); /* Basic test. */
|
||||
@ -98,7 +177,7 @@ void libm_test_string()
|
||||
|
||||
(void)strcpy(one, "gh");
|
||||
(void)strcpy(two, "ef");
|
||||
(void)strcat(one, two);
|
||||
(void)xstrcpy(one, two);
|
||||
equal(one, "ghef"); /* Basic test encore. */
|
||||
equal(two, "ef"); /* Stomped on source? */
|
||||
|
||||
@ -114,42 +193,67 @@ void libm_test_string()
|
||||
|
||||
/* strncat - first test it as strcat, with big counts,
|
||||
then test the count mechanism. */
|
||||
it = "strncat";
|
||||
it = PSTR("strncat");
|
||||
(void)strcpy(one, "ijk");
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow="
|
||||
check(strncat(one, "lmn", 99) == one); /* Returned value. */
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "ijklmn"); /* Basic test. */
|
||||
|
||||
(void)strcpy(one, "x");
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow="
|
||||
(void)strncat(one, "yz", 99);
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "xyz"); /* Writeover. */
|
||||
equal(one + 4, "mn"); /* Wrote too much? */
|
||||
|
||||
(void)strcpy(one, "gh");
|
||||
(void)strcpy(two, "ef");
|
||||
(void)strncat(one, two, 99);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds="
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow="
|
||||
(void)xstrncat(one, two, 99);
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "ghef"); /* Basic test encore. */
|
||||
equal(two, "ef"); /* Stomped on source? */
|
||||
|
||||
(void)strcpy(one, "");
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow="
|
||||
(void)strncat(one, "", 99);
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, ""); /* Boundary conditions. */
|
||||
(void)strcpy(one, "ab");
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow="
|
||||
(void)strncat(one, "", 99);
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "ab");
|
||||
(void)strcpy(one, "");
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow="
|
||||
(void)strncat(one, "cd", 99);
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "cd");
|
||||
|
||||
(void)strcpy(one, "ab");
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
||||
(void)strncat(one, "cdef", 2);
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "abcd"); /* Count-limited. */
|
||||
|
||||
(void)strncat(one, "gh", 0);
|
||||
equal(one, "abcd"); /* Zero count. */
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
(void)strncat(one, "gh", 2);
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "abcdgh"); /* Count _AND length equal. */
|
||||
it = "strncmp";
|
||||
it = PSTR("strncmp");
|
||||
/* strncmp - first test as strcmp with big counts";*/
|
||||
check(strncmp("", "", 99) == 0); /* Trivial case. */
|
||||
check(strncmp("a", "a", 99) == 0); /* Identity. */
|
||||
@ -164,16 +268,22 @@ void libm_test_string()
|
||||
check(strncmp("abc", "def", 0) == 0); /* Zero count. */
|
||||
|
||||
/* strncpy - testing is a bit different because of odd semantics. */
|
||||
it = "strncpy";
|
||||
it = PSTR("strncpy");
|
||||
check(strncpy(one, "abc", 4) == one); /* Returned value. */
|
||||
equal(one, "abc"); /* Did the copy go right? */
|
||||
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
||||
(void)strncpy(one, "xyz", 2);
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "xycdefgh"); /* Copy cut by count. */
|
||||
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
||||
(void)strncpy(one, "xyz", 3); /* Copy cut just before NUL. */
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "xyzdefgh");
|
||||
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
@ -188,7 +298,10 @@ void libm_test_string()
|
||||
equal(one + 5, "fgh");
|
||||
|
||||
(void)strcpy(one, "abc");
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
||||
(void)strncpy(one, "xyz", 0); /* Zero-length copy. */
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "abc");
|
||||
|
||||
(void)strncpy(one, "", 2); /* Zero-length source. */
|
||||
@ -197,18 +310,18 @@ void libm_test_string()
|
||||
equal(one + 2, "c");
|
||||
|
||||
(void)strcpy(one, "hi there");
|
||||
(void)strncpy(two, one, 9);
|
||||
(void)xstrncpy(two, one, 9);
|
||||
equal(two, "hi there"); /* Just paranoia. */
|
||||
equal(one, "hi there"); /* Stomped on source? */
|
||||
|
||||
/* strlen. */
|
||||
it = "strlen";
|
||||
it = PSTR("strlen");
|
||||
check(strlen("") == 0); /* Empty. */
|
||||
check(strlen("a") == 1); /* Single char. */
|
||||
check(strlen("abcd") == 4); /* Multiple chars. */
|
||||
|
||||
/* strchr. */
|
||||
it = "strchr";
|
||||
it = PSTR("strchr");
|
||||
check(strchr("abcd", 'z') == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(strchr(one, 'c') == one + 2); /* Basic test. */
|
||||
@ -222,7 +335,7 @@ void libm_test_string()
|
||||
check(strchr(one, '\0') == one); /* NUL in empty string. */
|
||||
|
||||
/* index - just like strchr. */
|
||||
it = "index";
|
||||
it = PSTR("index");
|
||||
check(index("abcd", 'z') == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(index(one, 'c') == one + 2); /* Basic test. */
|
||||
@ -236,7 +349,7 @@ void libm_test_string()
|
||||
check(index(one, '\0') == one); /* NUL in empty string. */
|
||||
|
||||
/* strrchr. */
|
||||
it = "strrchr";
|
||||
it = PSTR("strrchr");
|
||||
check(strrchr("abcd", 'z') == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(strrchr(one, 'c') == one + 2); /* Basic test. */
|
||||
@ -250,7 +363,7 @@ void libm_test_string()
|
||||
check(strrchr(one, '\0') == one); /* NUL in empty string. */
|
||||
|
||||
/* rindex - just like strrchr. */
|
||||
it = "rindex";
|
||||
it = PSTR("rindex");
|
||||
check(rindex("abcd", 'z') == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(rindex(one, 'c') == one + 2); /* Basic test. */
|
||||
@ -264,7 +377,7 @@ void libm_test_string()
|
||||
check(rindex(one, '\0') == one); /* NUL in empty string. */
|
||||
|
||||
/* strpbrk - somewhat like strchr. */
|
||||
it = "strpbrk";
|
||||
it = PSTR("strpbrk");
|
||||
check(strpbrk("abcd", "z") == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(strpbrk(one, "c") == one + 2); /* Basic test. */
|
||||
@ -281,7 +394,7 @@ void libm_test_string()
|
||||
check(strpbrk(one, "") == NULL); /* Both strings empty. */
|
||||
|
||||
/* strstr - somewhat like strchr. */
|
||||
it = "strstr";
|
||||
it = PSTR("strstr");
|
||||
check(strstr("z", "abcd") == NULL); /* Not found. */
|
||||
check(strstr("abx", "abcd") == NULL); /* Dead end. */
|
||||
(void)strcpy(one, "abcd");
|
||||
@ -304,7 +417,7 @@ void libm_test_string()
|
||||
check(strstr(one, "bbca") == one + 1); /* With overlap. */
|
||||
|
||||
/* strspn. */
|
||||
it = "strspn";
|
||||
it = PSTR("strspn");
|
||||
check(strspn("abcba", "abc") == 5); /* Whole string. */
|
||||
check(strspn("abcba", "ab") == 2); /* Partial. */
|
||||
check(strspn("abc", "qx") == 0); /* None. */
|
||||
@ -312,7 +425,7 @@ void libm_test_string()
|
||||
check(strspn("abc", "") == 0); /* Null search list. */
|
||||
|
||||
/* strcspn. */
|
||||
it = "strcspn";
|
||||
it = PSTR("strcspn");
|
||||
check(strcspn("abcba", "qx") == 5); /* Whole string. */
|
||||
check(strcspn("abcba", "cx") == 2); /* Partial. */
|
||||
check(strcspn("abc", "abc") == 0); /* None. */
|
||||
@ -320,7 +433,7 @@ void libm_test_string()
|
||||
check(strcspn("abc", "") == 3); /* Null search list. */
|
||||
|
||||
/* strtok - the hard one. */
|
||||
it = "strtok";
|
||||
it = PSTR("strtok");
|
||||
(void)strcpy(one, "first, second, third");
|
||||
equal(strtok(one, ", "), "first"); /* Basic test. */
|
||||
equal(one, "first");
|
||||
@ -367,7 +480,7 @@ void libm_test_string()
|
||||
equal(one + 4, "c");
|
||||
|
||||
/* memcmp. */
|
||||
it = "memcmp";
|
||||
it = PSTR("memcmp");
|
||||
check(memcmp("a", "a", 1) == 0); /* Identity. */
|
||||
check(memcmp("abc", "abc", 3) == 0); /* Multicharacter. */
|
||||
check(memcmp("abcd", "abce", 4) < 0); /* Honestly unequal. */
|
||||
@ -379,25 +492,25 @@ void libm_test_string()
|
||||
/* memcmp should test strings as unsigned */
|
||||
one[0] = 0xfe;
|
||||
two[0] = 0x03;
|
||||
check(memcmp(one, two, 1) > 0);
|
||||
check(xmemcmp(one, two, 1) > 0);
|
||||
|
||||
/* memchr. */
|
||||
it = "memchr";
|
||||
it = PSTR("memchr");
|
||||
check(memchr("abcd", 'z', 4) == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(memchr(one, 'c', 4) == one + 2); /* Basic test. */
|
||||
check(memchr(one, 'd', 4) == one + 3); /* End of string. */
|
||||
check(memchr(one, 'a', 4) == one); /* Beginning. */
|
||||
check(memchr(one, '\0', 5) == one + 4); /* Finding NUL. */
|
||||
check(xmemchr(one, 'c', 4) == one + 2); /* Basic test. */
|
||||
check(xmemchr(one, 'd', 4) == one + 3); /* End of string. */
|
||||
check(xmemchr(one, 'a', 4) == one); /* Beginning. */
|
||||
check(xmemchr(one, '\0', 5) == one + 4); /* Finding NUL. */
|
||||
(void)strcpy(one, "ababa");
|
||||
check(memchr(one, 'b', 5) == one + 1); /* Finding first. */
|
||||
check(memchr(one, 'b', 0) == NULL); /* Zero count. */
|
||||
check(memchr(one, 'a', 1) == one); /* Singleton case. */
|
||||
check(xmemchr(one, 'b', 5) == one + 1); /* Finding first. */
|
||||
check(xmemchr(one, 'b', 0) == NULL); /* Zero count. */
|
||||
check(xmemchr(one, 'a', 1) == one); /* Singleton case. */
|
||||
(void)strcpy(one, "a\203b");
|
||||
check(memchr(one, 0203, 3) == one + 1); /* Unsignedness. */
|
||||
check(xmemchr(one, 0203, 3) == one + 1); /* Unsignedness. */
|
||||
|
||||
/* memcpy - need not work for overlap. */
|
||||
it = "memcpy";
|
||||
it = PSTR("memcpy");
|
||||
check(memcpy(one, "abc", 4) == one); /* Returned value. */
|
||||
equal(one, "abc"); /* Did the copy go right? */
|
||||
|
||||
@ -411,13 +524,13 @@ void libm_test_string()
|
||||
|
||||
(void)strcpy(one, "hi there");
|
||||
(void)strcpy(two, "foo");
|
||||
(void)memcpy(two, one, 9);
|
||||
(void)xmemcpy(two, one, 9);
|
||||
equal(two, "hi there"); /* Just paranoia. */
|
||||
equal(one, "hi there"); /* Stomped on source? */
|
||||
#if 0
|
||||
#if 1
|
||||
/* memmove - must work on overlap. */
|
||||
it = "memmove";
|
||||
check(memmove(one, "abc", 4) == one); /* Returned value. */
|
||||
it = PSTR("memmove");
|
||||
check(xmemmove(one, "abc", 4) == one); /* Returned value. */
|
||||
equal(one, "abc"); /* Did the copy go right? */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
@ -430,20 +543,20 @@ void libm_test_string()
|
||||
|
||||
(void) strcpy(one, "hi there");
|
||||
(void) strcpy(two, "foo");
|
||||
(void) memmove(two, one, 9);
|
||||
(void) xmemmove(two, one, 9);
|
||||
equal(two, "hi there"); /* Just paranoia. */
|
||||
equal(one, "hi there"); /* Stomped on source? */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) memmove(one+1, one, 9);
|
||||
(void) xmemmove(one+1, one, 9);
|
||||
equal(one, "aabcdefgh"); /* Overlap, right-to-left. */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) memmove(one+1, one+2, 7);
|
||||
(void) xmemmove(one+1, one+2, 7);
|
||||
equal(one, "acdefgh"); /* Overlap, left-to-right. */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) memmove(one, one, 9);
|
||||
(void) xmemmove(one, one, 9);
|
||||
equal(one, "abcdefgh"); /* 100% overlap. */
|
||||
#endif
|
||||
#if 0
|
||||
@ -451,7 +564,7 @@ void libm_test_string()
|
||||
The SVID, the only place where memccpy is mentioned, says
|
||||
overlap might fail, so we don't try it. Besides, it's hard
|
||||
to see the rationale for a non-left-to-right memccpy. */
|
||||
it = "memccpy";
|
||||
it = PSTR("memccpy");
|
||||
check(memccpy(one, "abc", 'q', 4) == NULL); /* Returned value. */
|
||||
equal(one, "abc"); /* Did the copy go right? */
|
||||
|
||||
@ -486,12 +599,15 @@ void libm_test_string()
|
||||
equal(two, "xbcdlebee");
|
||||
#endif
|
||||
/* memset. */
|
||||
it = "memset";
|
||||
it = PSTR("memset");
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
check(memset(one + 1, 'x', 3) == one + 1); /* Return value. */
|
||||
equal(one, "axxxefgh"); /* Basic test. */
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmemset-transposed-args"
|
||||
(void)memset(one + 2, 'y', 0);
|
||||
#pragma GCC diagnostic pop
|
||||
equal(one, "axxxefgh"); /* Zero-length set. */
|
||||
|
||||
(void)memset(one + 5, 0, 1);
|
||||
@ -503,7 +619,7 @@ void libm_test_string()
|
||||
|
||||
/* bcopy - much like memcpy.
|
||||
Berklix manual is silent about overlap, so don't test it. */
|
||||
it = "bcopy";
|
||||
it = PSTR("bcopy");
|
||||
(void)bcopy("abc", one, 4);
|
||||
equal(one, "abc"); /* Simple copy. */
|
||||
|
||||
@ -522,7 +638,7 @@ void libm_test_string()
|
||||
equal(one, "hi there"); /* Stomped on source? */
|
||||
|
||||
/* bzero. */
|
||||
it = "bzero";
|
||||
it = PSTR("bzero");
|
||||
(void)strcpy(one, "abcdef");
|
||||
bzero(one + 2, 2);
|
||||
equal(one, "ab"); /* Basic test. */
|
||||
@ -534,7 +650,7 @@ void libm_test_string()
|
||||
equal(one, "abcdef"); /* Zero-length copy. */
|
||||
|
||||
/* bcmp - somewhat like memcmp. */
|
||||
it = "bcmp";
|
||||
it = PSTR("bcmp");
|
||||
check(bcmp("a", "a", 1) == 0); /* Identity. */
|
||||
check(bcmp("abc", "abc", 3) == 0); /* Multicharacter. */
|
||||
check(bcmp("abcd", "abce", 4) != 0); /* Honestly unequal. */
|
||||
|
@ -62,6 +62,7 @@ int errors = 0;
|
||||
printf
|
||||
|
||||
/* A safe target-independent memmove. */
|
||||
void mymemmove(unsigned char* dest, unsigned char* src, size_t n) __attribute__((__noinline__));
|
||||
|
||||
void mymemmove(unsigned char* dest, unsigned char* src, size_t n)
|
||||
{
|
||||
|
@ -31,18 +31,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define memcmp memcmp_P
|
||||
#define memcpy memcpy_P
|
||||
#define memmem memmem_P
|
||||
#define memchr memchr_P
|
||||
#define strcat strcat_P
|
||||
#define strncat strncat_P
|
||||
#define strcpy strcpy_P
|
||||
#define strncpy strncpy_P
|
||||
#define strlen strlen_P
|
||||
#define strnlen strnlen_P
|
||||
#define strcmp strcmp_P
|
||||
#define strncmp strncmp_P
|
||||
|
||||
#define BUFF_SIZE 256
|
||||
|
||||
|
4
tests/device/test_libc/test_libc.ino.globals.h
Normal file
4
tests/device/test_libc/test_libc.ino.globals.h
Normal file
@ -0,0 +1,4 @@
|
||||
/*@create-file:build.opt@
|
||||
|
||||
-fno-builtin
|
||||
*/
|
@ -13,6 +13,7 @@
|
||||
#define MAX_1 50
|
||||
#define memcmp memcmp_P
|
||||
#define memcpy memcpy_P
|
||||
#define memmove memmove_P
|
||||
#define memmem memmem_P
|
||||
#define memchr memchr_P
|
||||
#define strcat strcat_P
|
||||
@ -86,6 +87,8 @@ void tstring_main(void)
|
||||
tmp2[0] = 'Z';
|
||||
tmp2[1] = '\0';
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmemset-transposed-args"
|
||||
if (memset(target, 'X', 0) != target || memcpy(target, "Y", 0) != target
|
||||
|| memmove(target, "K", 0) != target || strncpy(tmp2, "4", 0) != tmp2
|
||||
|| strncat(tmp2, "123", 0) != tmp2 || strcat(target, "") != target)
|
||||
@ -93,6 +96,7 @@ void tstring_main(void)
|
||||
eprintf(__LINE__, target, "A", 0);
|
||||
test_failed = 1;
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
if (strcmp(target, "A") || strlen(target) != 1 || memchr(target, 'A', 0) != NULL
|
||||
|| memcmp(target, "J", 0) || strncmp(target, "A", 1) || strncmp(target, "J", 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include "FS.h"
|
||||
#include <LittleFS.h>
|
||||
#include <BSTest.h>
|
||||
|
||||
BS_ENV_DECLARE();
|
||||
@ -18,17 +18,17 @@ bool pretest()
|
||||
|
||||
TEST_CASE("read-write test","[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
REQUIRE(LittleFS.begin());
|
||||
|
||||
String text = "write test";
|
||||
{
|
||||
File out = SPIFFS.open("/tmp.txt", "w");
|
||||
File out = LittleFS.open("/tmp.txt", "w");
|
||||
REQUIRE(out);
|
||||
out.print(text);
|
||||
}
|
||||
|
||||
{
|
||||
File in = SPIFFS.open("/tmp.txt", "r");
|
||||
File in = LittleFS.open("/tmp.txt", "r");
|
||||
REQUIRE(in);
|
||||
CHECK(in.size() == text.length());
|
||||
in.setTimeout(0);
|
||||
@ -39,14 +39,14 @@ TEST_CASE("read-write test","[fs]")
|
||||
|
||||
TEST_CASE("A bunch of files show up in openDir, and can be removed", "[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
REQUIRE(LittleFS.begin());
|
||||
const int n = 10;
|
||||
int found[n] = {0};
|
||||
|
||||
{
|
||||
Dir root = SPIFFS.openDir("");
|
||||
Dir root = LittleFS.openDir("");
|
||||
while (root.next()) {
|
||||
CHECK(SPIFFS.remove(root.fileName()));
|
||||
CHECK(LittleFS.remove(root.fileName()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,14 +55,14 @@ TEST_CASE("A bunch of files show up in openDir, and can be removed", "[fs]")
|
||||
name += i;
|
||||
name += ".txt";
|
||||
|
||||
File out = SPIFFS.open(name, "w");
|
||||
File out = LittleFS.open(name, "w");
|
||||
REQUIRE(out);
|
||||
|
||||
out.println(i);
|
||||
}
|
||||
|
||||
{
|
||||
Dir root = SPIFFS.openDir("/");
|
||||
Dir root = LittleFS.openDir("/");
|
||||
while (root.next()) {
|
||||
String fileName = root.fileName();
|
||||
CHECK(fileName.indexOf("/seq_") == 0);
|
||||
@ -77,35 +77,35 @@ TEST_CASE("A bunch of files show up in openDir, and can be removed", "[fs]")
|
||||
}
|
||||
|
||||
{
|
||||
Dir root = SPIFFS.openDir("/");
|
||||
Dir root = LittleFS.openDir("/");
|
||||
while (root.next()) {
|
||||
String fileName = root.fileName();
|
||||
CHECK(SPIFFS.remove(fileName));
|
||||
CHECK(LittleFS.remove(fileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("files can be renamed", "[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
REQUIRE(LittleFS.begin());
|
||||
{
|
||||
File tmp = SPIFFS.open("/tmp1.txt", "w");
|
||||
File tmp = LittleFS.open("/tmp1.txt", "w");
|
||||
tmp.println("rename test");
|
||||
}
|
||||
|
||||
{
|
||||
CHECK(SPIFFS.rename("/tmp1.txt", "/tmp2.txt"));
|
||||
CHECK(LittleFS.rename("/tmp1.txt", "/tmp2.txt"));
|
||||
|
||||
File tmp2 = SPIFFS.open("/tmp2.txt", "r");
|
||||
File tmp2 = LittleFS.open("/tmp2.txt", "r");
|
||||
CHECK(tmp2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("FS::info works","[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
REQUIRE(LittleFS.begin());
|
||||
FSInfo info;
|
||||
CHECK(SPIFFS.info(info));
|
||||
CHECK(LittleFS.info(info));
|
||||
|
||||
Serial.printf("Total: %u\nUsed: %u\nBlock: %u\nPage: %u\nMax open files: %u\nMax path len: %u\n",
|
||||
info.totalBytes,
|
||||
@ -119,10 +119,10 @@ TEST_CASE("FS::info works","[fs]")
|
||||
|
||||
TEST_CASE("FS is empty after format","[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
REQUIRE(SPIFFS.format());
|
||||
REQUIRE(LittleFS.begin());
|
||||
REQUIRE(LittleFS.format());
|
||||
|
||||
Dir root = SPIFFS.openDir("/");
|
||||
Dir root = LittleFS.openDir("/");
|
||||
int count = 0;
|
||||
while (root.next()) {
|
||||
++count;
|
||||
@ -132,12 +132,12 @@ TEST_CASE("FS is empty after format","[fs]")
|
||||
|
||||
TEST_CASE("Can reopen empty file","[fs]")
|
||||
{
|
||||
REQUIRE(SPIFFS.begin());
|
||||
REQUIRE(LittleFS.begin());
|
||||
{
|
||||
File tmp = SPIFFS.open("/tmp.txt", "w");
|
||||
File tmp = LittleFS.open("/tmp.txt", "w");
|
||||
}
|
||||
{
|
||||
File tmp = SPIFFS.open("/tmp.txt", "w");
|
||||
File tmp = LittleFS.open("/tmp.txt", "w");
|
||||
CHECK(tmp);
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ def find_core_files():
|
||||
)
|
||||
if file.is_file()
|
||||
and file.suffix in (".c", ".cpp", ".h", ".hpp")
|
||||
and not GIT_ROOT / "tests/device/test_libc" in file.parents
|
||||
and not GIT_ROOT / "tests/host/bin" in file.parents
|
||||
and not GIT_ROOT / "tests/host/common/catch.hpp" == file
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user