Browse Source

test: allow to run a single configuration test, improve commandline handling

pull/1951/head
Maxim Prokhorov 4 years ago
parent
commit
b36e5ee396
8 changed files with 168 additions and 44 deletions
  1. +3
    -0
      .bandit
  2. +1
    -1
      .travis.yml
  3. +21
    -0
      code/scripts/espurna_utils/__init__.py
  4. +9
    -3
      code/scripts/espurna_utils/display.py
  5. +133
    -0
      code/scripts/test_build.py
  6. +0
    -0
      code/test/build/extra/secure_client.h
  7. +0
    -39
      code/test_build.sh
  8. +1
    -1
      travis_script.sh

+ 3
- 0
.bandit View File

@ -0,0 +1,3 @@
# Ignore B404 "Avoid importing subprocess"
# Ignore B603 "Subprocess without shell equals true"
skips: ['B404', 'B603']

+ 1
- 1
.travis.yml View File

@ -26,7 +26,7 @@ jobs:
- stage: Test
env: BUILDER_ENV=travis-2_3_0
- env: BUILDER_ENV=travis-latest
- env: BUILDER_ENV=travis-git BUILDER_EXTRA=secure_client
- env: BUILDER_ENV=travis-git BUILDER_EXTRA="-a test/build/extra/secure_client.h"
- stage: Release
env: BUILDER_THREAD=0
- env: BUILDER_THREAD=1


+ 21
- 0
code/scripts/espurna_utils/__init__.py View File

@ -1,3 +1,24 @@
# coding=utf-8
#
# Original extra_scripts.py
# Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
#
# ldscripts, lwip patching, updated postmortem flags and git support
# Copyright (C) 2019 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from .checks import check_cppcheck, check_printsize
from .float_support import remove_float_support
from .ldscripts import ldscripts_inject_libpath


+ 9
- 3
code/scripts/espurna_utils/display.py View File

@ -1,10 +1,11 @@
from __future__ import print_function
import os
import sys
import click
class Color(object):
BOLD = "\x1b[1;1m"
BLACK = "\x1b[1;30m"
RED = "\x1b[1;31m"
GREEN = "\x1b[1;32m"
@ -31,8 +32,13 @@ def print_warning(message, color=Color.LIGHT_YELLOW):
print(clr(color, message), file=sys.stderr)
def print_filler(fill, color=Color.WHITE, err=False):
width, _ = click.get_terminal_size()
def print_filler(fill, color=Color.WHITE, err=False, width_default=80):
width = width_default
try:
width = int(os.environ["COLUMNS"])
except (KeyError, ValueError):
pass
if len(fill) > 1:
fill = fill[0]


+ 133
- 0
code/scripts/test_build.py View File

@ -0,0 +1,133 @@
#!/usr/bin/env python
#
# Copyright (C) 2019 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import time
import glob
import argparse
import atexit
import subprocess
import os
import sys
import datetime
from espurna_utils.display import Color, clr, print_warning
CUSTOM_HEADER = "espurna/config/custom.h"
if os.path.exists(CUSTOM_HEADER):
raise SystemExit(
clr(
Color.YELLOW,
"{} already exists, please run this script in a git-worktree(1) or a separate directory".format(
CUSTOM_HEADER
),
)
)
def try_remove(path):
try:
os.remove(path)
except: # pylint: disable=bare-except
print_warning("Please manually remove the file `{}`".format(path))
atexit.register(try_remove, CUSTOM_HEADER)
def main(args):
configurations = []
if not args.no_default:
configurations = list(glob.glob(args.default_configurations))
configurations.extend(x for x in (args.add or []))
if not configurations:
raise SystemExit(clr(Color.YELLOW, "No configurations selected"))
print(clr(Color.BOLD, "> Selected configurations:"))
for cfg in configurations:
print(cfg)
if args.list:
return
if not args.environment:
raise SystemExit(clr(Color.YELLOW, "No environment selected"))
print(clr(Color.BOLD, "> Selected environment: {}".format(args.environment)))
for cfg in configurations:
print(clr(Color.BOLD, "> Building {}".format(cfg)))
with open(CUSTOM_HEADER, "w") as custom_h:
def write(line):
sys.stdout.write(line)
custom_h.write(line)
name, _ = os.path.splitext(cfg)
name = os.path.basename(name)
write('#define MANUFACTURER "TEST_BUILD"\n')
write('#define DEVICE "{}"\n'.format(name.upper()))
with open(cfg, "r") as cfg_file:
for line in cfg_file:
write(line)
os_env = os.environ.copy()
os_env["PLATFORMIO_SRC_BUILD_FLAGS"] = "-DUSE_CUSTOM_H"
os_env["PLATFORMIO_BUILD_CACHE_DIR"] = "test/pio_cache"
cmd = ["platformio", "run", "-s", "-e", args.environment]
start = time.time()
subprocess.check_call(cmd, env=os_env)
end = time.time()
print(
clr(
Color.BOLD,
"> {}: {} bytes, {}".format(
cfg,
os.stat(
os.path.join(".pio", "build", args.environment, "firmware.bin")
).st_size,
datetime.timedelta(seconds=(end - start)),
),
)
)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"-l", "--list", action="store_true", help="List selected configurations"
)
parser.add_argument(
"-n",
"--no-default",
action="store_true",
help="Do not use default configurations (--default-configurations=...)",
)
parser.add_argument(
"-a",
"--add",
action="append",
help="Add path to selected configurations (can specify multiple times)",
)
parser.add_argument("-e", "--environment", help="PIO environment")
parser.add_argument(
"--default-configurations",
default="test/build/*.h",
help="(glob) default configuration headers",
)
main(parser.parse_args())

code/test/build/secure_client.h → code/test/build/extra/secure_client.h View File


+ 0
- 39
code/test_build.sh View File

@ -1,39 +0,0 @@
#!/bin/bash
set -eu -o pipefail
CUSTOM_HEADER="espurna/config/custom.h"
TARGET_ENVIRONMENT=${1:?"pio env name"}
shift 1
CONFIGURATIONS=(
basic
sensor
emon
light_my92xx
light_dimmer
nondefault
)
if [ $# > 0 ] ; then
CONFIGURATIONS=("${CONFIGURATIONS[@]}" "$@")
fi
trap 'rm -f ${CUSTOM_HEADER}' EXIT
for cfg in "${CONFIGURATIONS[@]}" ; do
echo "travis_fold:start:build_${cfg}"
echo "- building ${cfg}"
printf "#define MANUFACTURER \"%s\"\n" "TEST_BUILD" \
| tee ${CUSTOM_HEADER}
printf "#define DEVICE \"%s\"\n" "${cfg^^}" \
| tee --append ${CUSTOM_HEADER}
tee --append ${CUSTOM_HEADER} < "test/build/${cfg}.h"
export PLATFORMIO_SRC_BUILD_FLAGS="-DUSE_CUSTOM_H"
export PLATFORMIO_BUILD_CACHE_DIR="test/pio_cache"
time pio run -s -e "$TARGET_ENVIRONMENT"
echo "travis_fold:end:build_${cfg}"
done

+ 1
- 1
travis_script.sh View File

@ -5,7 +5,7 @@ set -e -v
cd code
if [ ${TRAVIS_BUILD_STAGE_NAME} = "Test" ]; then
./test_build.sh $BUILDER_ENV $BUILDER_EXTRA
scripts/test_build.py -e $BUILDER_ENV $BUILDER_EXTRA
else
./build.sh -p
fi

Loading…
Cancel
Save