Skip to content

Commit d659499

Browse files
committed
Add tests for pico_flash provider
Adds a suite of test for the pico_flash provider using a mock esptool.sh to simulte devices needing reset and creating a mountpoint. Signed-off-by: Winford <winford@object.stream>
1 parent 8198785 commit d659499

File tree

5 files changed

+236
-2
lines changed

5 files changed

+236
-2
lines changed

test/driver/apps/rebar_overrides/rebar.config

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@
2727
{packbeam, [{start, start}]},
2828
{esp32_flash, [{chip, "esp32c3"}]},
2929
{stm32_flash, [{offset, "0x1234"}]},
30-
{uf2create, [{start, "0x10180800"}, {family_id, "rp2350"}]}
30+
{uf2create, [{start, "0x10180800"}, {family_id, "rp2350"}]},
31+
{pico_flash, [{reset, "/dev/FAKE0"}]}
3132
]}.

test/driver/scripts/picotool.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/sh
2+
##
3+
## Copyright (c) Winford (UncleGrumpy) <winford@object.stream>
4+
## All rights reserved.
5+
##
6+
## SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
7+
8+
set -e
9+
10+
Args="${@}"
11+
12+
while [ "${1}" != "" ]; do
13+
case ${1} in
14+
"reboot" )
15+
shift
16+
if ( [ ${1} = "-f" ] && [ ${2} = "-u" ] ) then
17+
if [ -L $TEST_MYAPP_LOCK ] then
18+
## Since we are locked make sure mount doesn't exist or contain test artifacts
19+
[-d $TEST_MYAPP_MOUNT] && rm -r $TEST_MYAPP_MOUNT
20+
rm $TEST_MYAPP_LOCK
21+
mkdir $TEST_MYAPP_MOUNT
22+
elif ([ -L $TEST_REBAR_OVERRIDES_LOCK ]) then
23+
[-d $TEST_REBAR_OVERRIDES_MOUNT] && rm -r $TEST_REBAR_OVERRIDES_MOUNT
24+
rm $TEST_REBAR_OVERRIDES_LOCK
25+
mkdir $TEST_REBAR_OVERRIDES_MOUNT
26+
else
27+
echo "No accessible RP-series devices in BOOTSEL mode were found."
28+
exit 1
29+
fi
30+
echo "The device was asked to reboot into BOOTSEL mode."
31+
fi
32+
break
33+
esac
34+
shift
35+
done
36+
37+
echo "${Args}"
38+
39+
exit 0
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
%%
2+
%% Copyright (c) 2023 <fred@dushin.net>
3+
%% All rights reserved.
4+
%%
5+
%% Licensed under the Apache License, Version 2.0 (the "License");
6+
%% you may not use this file except in compliance with the License.
7+
%% You may obtain a copy of the License at
8+
%%
9+
%% http://www.apache.org/licenses/LICENSE-2.0
10+
%%
11+
%% Unless required by applicable law or agreed to in writing, software
12+
%% distributed under the License is distributed on an "AS IS" BASIS,
13+
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
%% See the License for the specific language governing permissions and
15+
%% limitations under the License.
16+
%%
17+
%
18+
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
19+
%
20+
-module(pico_flash_tests).
21+
22+
-export([run/1]).
23+
24+
run(Opts) ->
25+
ok = test_flags(Opts),
26+
ok = test_env_overrides(Opts),
27+
ok = test_rebar_overrides(Opts),
28+
ok.
29+
30+
%% @private
31+
test_flags(Opts) ->
32+
%% test default options, and no device connected (this test wiill fail if a real pico is connected!)
33+
test_flags(Opts, [], [
34+
{"--path\n", ""},
35+
{"--reset\n", ""},
36+
{"Pico not mounted after 30 seconds.", "giving up..."}
37+
]),
38+
39+
%% Simulate a device that needs reset
40+
Reset1 = os:getenv("TEST_MYAPP_LOCK"),
41+
%% devices needing reset can only be device files or symlinks
42+
file:make_symlink("/dev/null", Reset1),
43+
Path1 = os:getenv("TEST_MYAPP_MOUNT"),
44+
%% make sure the mount is not present (picotool.sh will create the mount after removing lock dev)
45+
file:del_dir_r("TEST_MYAPP_MOUNT"),
46+
test_flags(
47+
Opts,
48+
[
49+
{"-r", Reset1},
50+
{"-p", Path1}
51+
],
52+
[
53+
{"--path", Path1},
54+
{"--reset", Reset1},
55+
{
56+
"Copying myapp.uf2 to " ++ Path1,
57+
"===> Successfully loaded myapp application to the device."
58+
}
59+
]
60+
),
61+
62+
ok.
63+
64+
%% @private
65+
test_flags(Opts, Flags, FlagExpectList) ->
66+
AppsDir = maps:get(apps_dir, Opts),
67+
AppDir = test:make_path([AppsDir, "myapp"]),
68+
69+
Cmd = create_pico_flash_cmd(AppDir, Flags, []),
70+
Output = test:execute_cmd(Cmd, Opts),
71+
test:debug(Output, Opts),
72+
73+
lists:foreach(
74+
fun({Flag, Value}) ->
75+
test:expect_contains(io_lib:format("~s ~s", [Flag, Value]), Output)
76+
end,
77+
FlagExpectList
78+
),
79+
80+
test:tick().
81+
82+
%% @private
83+
test_env_overrides(Opts) ->
84+
Reset = os:getenv("TEST_MYAPP_LOCK"),
85+
file:make_symlink("/dev/null", Reset),
86+
test_env_overrides(
87+
Opts, "ATOMVM_REBAR3_PLUGIN_PICO_RESET_DEV", Reset, "--reset"
88+
),
89+
90+
Path = os:getenv("TEST_MYAPP_MOUNT"),
91+
%% there is no dev lock, so we must make sure the mount exists and is empty
92+
file:del_dir_r(Path),
93+
file:make_dir(Path),
94+
test_env_overrides(Opts, "ATOMVM_REBAR3_PLUGIN_PICO_MOUNT_PATH", Path, "--path"),
95+
%% cleanup
96+
file:del_dir_r(Path),
97+
98+
file:make_dir(Path),
99+
test_env_overrides(
100+
Opts, "ATOMVM_REBAR3_PLUGIN_PICOTOOL", string:trim(os:cmd("which echo")), "--picotool"
101+
),
102+
%% cleanup
103+
file:del_dir_r(Path),
104+
ok.
105+
106+
%% @private
107+
test_env_overrides(Opts, EnvVar, Value, Flag) ->
108+
AppsDir = maps:get(apps_dir, Opts),
109+
AppDir = test:make_path([AppsDir, "myapp"]),
110+
%% if we are not testing path overrides use the test path since no device is present
111+
Flags =
112+
case Flag of
113+
"--path" ->
114+
[];
115+
_ ->
116+
[{"-p", os:getenv("TEST_MYAPP_MOUNT")}]
117+
end,
118+
Cmd = create_pico_flash_cmd(AppDir, Flags, [{EnvVar, Value}]),
119+
Output = test:execute_cmd(Cmd, Opts),
120+
test:debug(Output, Opts),
121+
122+
ok = test:expect_contains(io_lib:format("~s ~s", [Flag, Value]), Output),
123+
124+
test:tick().
125+
126+
%% @private
127+
test_rebar_overrides(Opts) ->
128+
%% the rebar_overrides rebar.config specifies reset /dev/FAKE0
129+
Path = os:getenv("TEST_REBAR_OVERRIDES_MOUNT"),
130+
file:del_dir_r(Path),
131+
file:make_dir(Path),
132+
test_rebar_overrides(
133+
Opts,
134+
[{"-p", Path}],
135+
"ATOMVM_REBAR3_PLUGIN_PICO_RESET_DEV",
136+
"/dev/ttyACM0",
137+
"--reset",
138+
"/dev/FAKE0"
139+
),
140+
%% cleanup
141+
file:del_dir_r(Path),
142+
143+
%% Simulate a device needing reset, the mock picotool.sh will create the mount matching the reset device.
144+
Reset = os:getenv("TEST_REBAR_OVERRIDES_LOCK"),
145+
file:make_symlink("/dev/null", Reset),
146+
test_rebar_overrides(
147+
Opts,
148+
[{"-r", Reset}, {"-p", Path}],
149+
"ATOMVM_REBAR3_PLUGIN_PICO_RESET_DEV",
150+
"/dev/tty.usbserial-0001",
151+
"--reset",
152+
Reset
153+
),
154+
%% cleanup
155+
file:del_dir_r(Path),
156+
157+
%% Simulte a device already in BOOTSEL mode
158+
file:make_dir(Path),
159+
test_rebar_overrides(
160+
Opts,
161+
[{"-p", Path}],
162+
"ATOMVM_REBAR3_PLUGIN_PICO_MOUNT_PATH",
163+
"/mnt/RP2350",
164+
"--path",
165+
Path
166+
),
167+
ok.
168+
169+
%% @private
170+
test_rebar_overrides(Opts, Flags, EnvVar, Value, Flag, ExpectedValue) ->
171+
AppsDir = maps:get(apps_dir, Opts),
172+
AppDir = test:make_path([AppsDir, "rebar_overrides"]),
173+
174+
Cmd = create_pico_flash_cmd(AppDir, Flags, [{EnvVar, Value}]),
175+
Output = test:execute_cmd(Cmd, Opts),
176+
test:debug(Output, Opts),
177+
178+
ok = test:expect_contains(io_lib:format("~s ~s", [Flag, ExpectedValue]), Output),
179+
180+
test:tick().
181+
182+
%% @private
183+
create_pico_flash_cmd(AppDir, Opts, Env) ->
184+
test:create_rebar3_cmd(AppDir, pico_flash, Opts, Env).

test/driver/src/test.erl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ run_tests(Opts) ->
6363
ok = esp32_flash_tests:run(Opts),
6464
io:put_chars("\n"),
6565

66+
io:put_chars("pico_flash_tests: "),
67+
ok = pico_flash_tests:run(Opts),
68+
io:put_chars("\n"),
69+
6670
io:put_chars("stm32_flash_tests: "),
6771
ok = stm32_flash_tests:run(Opts),
6872
io:put_chars("\n"),

test/run.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,15 @@ unset ATOMVM_REBAR3_PLUGIN_PICO_RESET_DEV
2525
unset ATOMVM_REBAR3_PLUGIN_UF2CREATE_START
2626

2727
export ATOMVM_REBAR3_TEST_MODE="true"
28+
export ATOMVM_PICOTOOL="${test_dir}/scripts/picotool.sh"
29+
export TEST_MYAPP_LOCK="${test_dir}/apps/myapp/_build/default/dev0"
30+
export TEST_MYAPP_MOUNT="${test_dir}/apps/myapp/_build/default/rp2040"
31+
export TEST_REBAR_OVERRIDES_LOCK="${test_dir}/apps/rebar_overrides/_build/default/dev0"
32+
export TEST_REBAR_OVERRIDES_MOUNT="${test_dir}/apps/rebar_overrides/_build/default/rp2350"
2833

2934
cd "${test_dir}"
3035
rebar3 escriptize
3136
./_build/default/bin/driver -r "$(pwd)" "$@"
3237

33-
unset ATOMVM_REBAR3_TEST_MODE
38+
unset ATOMVM_REBAR3_TEST_MODE ATOMVM_PICOTOOL
39+
unset TEST_MYAPP_LOCK TEST_MYAPP_MOUNT TEST_REBAR_OVERRIDES_LOCK TEST_REBAR_OVERRIDES_MOUNT

0 commit comments

Comments
 (0)