Skip to content

Commit dd6dd5d

Browse files
committed
rework the getenv test again
* use a virtual fat filesystem during the test * this makes the file I/O part more closely patch runtime which is nice * side-steps the need to add a special function for testing * but test still can't be run on a device, because the vfs calls are incompatible, and you intentionally can't remount "/" anyway * and side-steps problems with storing 'bad' toml files
1 parent 3ab71d7 commit dd6dd5d

File tree

11 files changed

+109
-92
lines changed

11 files changed

+109
-92
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ repos:
88
hooks:
99
- id: check-yaml
1010
- id: end-of-file-fixer
11-
exclude: '^(tests/.*\.toml|tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/espressif/esp-idf-config/.*|ports/espressif/boards/.*/sdkconfig)'
11+
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/espressif/esp-idf-config/.*|ports/espressif/boards/.*/sdkconfig)'
1212
- id: trailing-whitespace
13-
exclude: '^(tests/.*\.toml|tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|lib/mbedtls_errors/.*)'
13+
exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|lib/mbedtls_errors/.*)'
1414
- repo: local
1515
hooks:
1616
- id: translations

ports/unix/main.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -420,13 +420,6 @@ STATIC void set_sys_argv(char *argv[], int argc, int start_arg) {
420420
#define PATHLIST_SEP_CHAR ':'
421421
#endif
422422

423-
mp_obj_t common_hal_os_getenv_path(const char *path, const char *key, mp_obj_t default_);
424-
STATIC mp_obj_t getenv_from_file(mp_obj_t path_in, mp_obj_t key_to_get_in) {
425-
return common_hal_os_getenv_path(mp_obj_str_get_str(path_in),
426-
mp_obj_str_get_str(key_to_get_in), mp_const_none);
427-
}
428-
MP_DEFINE_CONST_FUN_OBJ_2(getenv_from_file_obj, getenv_from_file);
429-
430423
MP_NOINLINE int main_(int argc, char **argv);
431424

432425
int main(int argc, char **argv) {
@@ -547,7 +540,6 @@ MP_NOINLINE int main_(int argc, char **argv) {
547540
MP_DECLARE_CONST_FUN_OBJ_0(extra_cpp_coverage_obj);
548541
mp_store_global(MP_QSTR_extra_coverage, MP_OBJ_FROM_PTR(&extra_coverage_obj));
549542
mp_store_global(MP_QSTR_extra_cpp_coverage, MP_OBJ_FROM_PTR(&extra_cpp_coverage_obj));
550-
mp_store_global(MP_QSTR_getenv_from_file, MP_OBJ_FROM_PTR(&getenv_from_file_obj));
551543
}
552544
#endif
553545

ports/unix/modos.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,12 @@ STATIC mp_obj_t mod_os_system(mp_obj_t cmd_in) {
193193
}
194194
MP_DEFINE_CONST_FUN_OBJ_1(mod_os_system_obj, mod_os_system);
195195

196+
mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_);
196197
STATIC mp_obj_t mod_os_getenv(mp_obj_t var_in) {
198+
mp_obj_t result = common_hal_os_getenv(mp_obj_str_get_str(var_in), mp_const_none);
199+
if (result != mp_const_none) {
200+
return result;
201+
}
197202
const char *s = getenv(mp_obj_str_get_str(var_in));
198203
if (s == NULL) {
199204
return mp_const_none;

shared-module/os/getenv.c

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -39,43 +39,29 @@
3939
#include "supervisor/filesystem.h"
4040
#include "supervisor/memory.h"
4141

42-
#define GETENV_PATH "settings.toml"
42+
#define GETENV_PATH "/settings.toml"
4343

44-
#if defined(UNIX)
45-
typedef FILE *file_arg;
46-
STATIC bool open_file(const char *name, file_arg *active_file) {
47-
FILE *result = fopen(name, "r");
48-
if (result) {
49-
*active_file = result;
50-
}
51-
return result != NULL;
52-
}
53-
STATIC void close_file(file_arg *active_file) {
54-
fclose(*active_file);
55-
}
56-
STATIC bool is_eof(file_arg *active_file) {
57-
return feof(*active_file);
58-
}
59-
STATIC uint8_t get_next_byte(file_arg *active_file) {
60-
int value = fgetc(*active_file);
61-
if (value == EOF) {
62-
return 0;
63-
}
64-
return value;
65-
}
66-
__attribute__((unused))
67-
STATIC void seek_eof(file_arg *active_file) {
68-
fseek(*active_file, 0, SEEK_END);
69-
(void)fgetc(*active_file);
70-
}
71-
#else
7244
#include "extmod/vfs.h"
7345
#include "extmod/vfs_fat.h"
7446
typedef FIL file_arg;
7547
STATIC bool open_file(const char *name, file_arg *active_file) {
48+
#if defined(UNIX)
49+
nlr_buf_t nlr;
50+
if (nlr_push(&nlr) == 0) {
51+
mp_obj_t file_obj = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), mp_obj_new_str(name, strlen(name)), MP_ROM_QSTR(MP_QSTR_rb));
52+
mp_arg_validate_type(file_obj, &mp_type_vfs_fat_fileio, MP_QSTR_file);
53+
pyb_file_obj_t *file = MP_OBJ_TO_PTR(file_obj);
54+
*active_file = file->fp;
55+
nlr_pop();
56+
return true;
57+
} else {
58+
return false;
59+
}
60+
#else
7661
FATFS *fs = filesystem_circuitpy();
7762
FRESULT result = f_open(fs, active_file, name, FA_READ);
7863
return result == FR_OK;
64+
#endif
7965
}
8066
STATIC void close_file(file_arg *active_file) {
8167
// nothing
@@ -95,7 +81,6 @@ STATIC uint8_t get_next_byte(FIL *active_file) {
9581
STATIC void seek_eof(file_arg *active_file) {
9682
f_lseek(active_file, f_size(active_file));
9783
}
98-
#endif
9984

10085
// For a fixed buffer, record the required size rather than throwing
10186
STATIC void vstr_add_byte_nonstd(vstr_t *vstr, byte b) {
@@ -363,7 +348,7 @@ mp_obj_t common_hal_os_getenv_path(const char *path, const char *key, mp_obj_t d
363348

364349
vstr_init(&buf, 64);
365350
os_getenv_err_t result = os_getenv_vstr(path, key, &buf, &quoted);
366-
if (result == GETENV_ERR_NOT_FOUND) {
351+
if (result == GETENV_ERR_NOT_FOUND || result == GETENV_ERR_OPEN) {
367352
return default_;
368353
}
369354
throw_getenv_error(result);

tests/circuitpython/bad1.toml

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/circuitpython/bad2.toml

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/circuitpython/bad3.toml

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/circuitpython/bad4.toml

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/circuitpython/getenv_test.py

Lines changed: 73 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,78 @@
1-
def run_test(f, k=None):
1+
import uos
2+
3+
uos.umount("/")
4+
5+
6+
class RAMBlockDevice:
7+
ERASE_BLOCK_SIZE = 512
8+
9+
def __init__(self, blocks):
10+
self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE)
11+
12+
def readblocks(self, block, buf, off=0):
13+
addr = block * self.ERASE_BLOCK_SIZE + off
14+
for i in range(len(buf)):
15+
buf[i] = self.data[addr + i]
16+
17+
def writeblocks(self, block, buf, off=None):
18+
if off is None:
19+
# erase, then write
20+
off = 0
21+
addr = block * self.ERASE_BLOCK_SIZE + off
22+
for i in range(len(buf)):
23+
self.data[addr + i] = buf[i]
24+
25+
def ioctl(self, op, arg):
26+
if op == 4: # block count
27+
return len(self.data) // self.ERASE_BLOCK_SIZE
28+
if op == 5: # block size
29+
return self.ERASE_BLOCK_SIZE
30+
if op == 6: # erase block
31+
return 0
32+
33+
34+
bdev = RAMBlockDevice(64)
35+
uos.VfsFat.mkfs(bdev)
36+
uos.mount(uos.VfsFat(bdev), "/")
37+
38+
content_good = """
39+
# comment
40+
key0 = "hello world"
41+
key1 = 7
42+
cstring = "hello comment" # comment
43+
cnumber = 0x7f # comment
44+
key2= "\n"
45+
key3 ="\u00c1x"
46+
key4 = "\U000000c1x"
47+
key5 = "\f\"\\"
48+
key6 = "\t\r\b"
49+
key7 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
50+
key8 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
51+
[section]
52+
subvalue = "hi"
53+
"""
54+
55+
content_bad = [
56+
'key = "\n',
57+
'key = """\n',
58+
"key =\n",
59+
'key="',
60+
]
61+
62+
63+
def run_test(key, content):
64+
with open("/settings.toml", "w") as f:
65+
f.write(content)
66+
267
try:
3-
v = getenv_from_file(f"{BASE}/{f}.toml", k or f)
4-
print(f, k, repr(v))
68+
v = uos.getenv(key)
69+
print(key, repr(v))
570
except Exception as e:
6-
print(f, k, str(e))
71+
print(key, str(e))
772

873

9-
BASE = __file__.rpartition("/")[0] or "."
74+
for i in range(9):
75+
run_test(f"key{i}", content_good)
1076

11-
run_test("good", "notpresent")
12-
run_test("good", "string")
13-
run_test("good", "number")
14-
run_test("good", "cstring")
15-
run_test("good", "cnumber")
16-
run_test("good", "subvalue")
17-
for i in range(8):
18-
run_test("good", f"string{i}")
19-
for i in range(1, 5):
20-
run_test(f"bad{i}", f"string")
77+
for content in content_bad:
78+
run_test("key", content)
Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
1-
good.toml notpresent None
2-
good.toml string 'hello world'
3-
good.toml number 7
4-
good.toml cstring 'hello comment'
5-
good.toml cnumber 127
6-
good.toml subvalue None
7-
good.toml string0 None
8-
good.toml string1 '\n'
9-
good.toml string2 'Áx'
10-
good.toml string3 'Áx'
11-
good.toml string4 '\x0c"\\'
12-
good.toml string5 '\t\r\x08'
13-
good.toml string6 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
14-
good.toml string7 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
15-
bad1.toml.bin string Invalid byte '\n'
16-
bad2.toml.bin string Invalid byte '"'
17-
bad3.toml.bin string invalid syntax for integer with base 10: ''
18-
bad4.toml.bin string Invalid byte 'EOF'
1+
key0 'hello world'
2+
key1 7
3+
key2 Invalid byte '\n'
4+
key3 'Áx'
5+
key4 'Áx'
6+
key5 Invalid byte '\\'
7+
key6 '\t\r\x08'
8+
key7 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
9+
key8 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
10+
key Invalid byte '\n'
11+
key Invalid byte '"'
12+
key invalid syntax for integer with base 10: ''
13+
key Invalid byte 'EOF'

0 commit comments

Comments
 (0)