mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-15 20:19:23 +00:00
feat(core/sdbackup): improve handling of mocked SD
By default, unit tests and Emulator starts without virtual SD card. A card must be explicitly inserted in test setup.
This commit is contained in:
parent
3915171625
commit
a429da5b0e
@ -17,6 +17,9 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include "common.h"
|
||||
#include "embed/extmod/trezorobj.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "sdcard.h"
|
||||
@ -70,7 +73,7 @@ STATIC mp_obj_t mod_trezorio_sdcard_switcher_insert(size_t n_args,
|
||||
1024 * ONE_MEBIBYTE) // capacity between 1 MiB and 1 GiB
|
||||
|
||||
sdcard_mock.inserted = sectrue;
|
||||
set_sdcard_mock_filename(&sdcard_mock, (int)card_sn);
|
||||
set_sdcard_mock_filename((int)card_sn);
|
||||
sdcard_mock.buffer = NULL;
|
||||
sdcard_mock.serial_number = card_sn;
|
||||
sdcard_mock.capacity_bytes = capacity_bytes;
|
||||
@ -87,7 +90,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_trezorio_sdcard_switcher_insert_obj, 1,
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorio_sdcard_switcher_eject() {
|
||||
sdcard_mock.inserted = secfalse;
|
||||
sdcard_mock.buffer = NULL;
|
||||
|
||||
if (sdcard_mock.buffer != NULL) {
|
||||
// TODO repetion with unix/sdcard.c code
|
||||
int r = munmap(sdcard_mock.buffer, sdcard_mock.capacity_bytes);
|
||||
ensure(sectrue * (r == 0), "munmap failed");
|
||||
sdcard_mock.buffer = NULL;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_sdcard_switcher_eject_obj,
|
||||
|
@ -35,9 +35,10 @@
|
||||
#define SDCARD_SIZE sdcard_mock.capacity_bytes
|
||||
#define SDCARD_BLOCKS (SDCARD_SIZE / SDCARD_BLOCK_SIZE)
|
||||
|
||||
static secbool sdcard_powered = secfalse;
|
||||
|
||||
static void sdcard_exit(void) {
|
||||
if (SDCARD_BUFFER == NULL) {
|
||||
return;
|
||||
}
|
||||
int r = munmap(SDCARD_BUFFER, SDCARD_SIZE);
|
||||
ensure(sectrue * (r == 0), "munmap failed");
|
||||
SDCARD_BUFFER = NULL;
|
||||
@ -78,7 +79,7 @@ void sdcard_init(void) {
|
||||
for (int i = 0; i < SDCARD_SIZE; ++i) SDCARD_BUFFER[i] = 0xFF;
|
||||
}
|
||||
|
||||
sdcard_powered = secfalse;
|
||||
sdcard_mock.powered = secfalse;
|
||||
|
||||
atexit(sdcard_exit);
|
||||
}
|
||||
@ -90,19 +91,19 @@ secbool sdcard_power_on(void) {
|
||||
return secfalse;
|
||||
}
|
||||
sdcard_init();
|
||||
sdcard_powered = sectrue;
|
||||
sdcard_mock.powered = sectrue;
|
||||
return sectrue;
|
||||
}
|
||||
|
||||
void sdcard_power_off(void) { sdcard_powered = secfalse; }
|
||||
void sdcard_power_off(void) { sdcard_mock.powered = secfalse; }
|
||||
|
||||
uint64_t sdcard_get_capacity_in_bytes(void) {
|
||||
return sdcard_powered == sectrue ? SDCARD_SIZE : 0;
|
||||
return sdcard_mock.powered == sectrue ? SDCARD_SIZE : 0;
|
||||
}
|
||||
|
||||
secbool sdcard_read_blocks(uint32_t *dest, uint32_t block_num,
|
||||
uint32_t num_blocks) {
|
||||
if (sectrue != sdcard_powered) {
|
||||
if (sectrue != sdcard_mock.powered) {
|
||||
return secfalse;
|
||||
}
|
||||
if (block_num >= SDCARD_BLOCKS) {
|
||||
@ -118,7 +119,7 @@ secbool sdcard_read_blocks(uint32_t *dest, uint32_t block_num,
|
||||
|
||||
secbool sdcard_write_blocks(const uint32_t *src, uint32_t block_num,
|
||||
uint32_t num_blocks) {
|
||||
if (sectrue != sdcard_powered) {
|
||||
if (sectrue != sdcard_mock.powered) {
|
||||
return secfalse;
|
||||
}
|
||||
if (block_num >= SDCARD_BLOCKS) {
|
||||
|
@ -1,38 +1,26 @@
|
||||
#include "sdcard_emu_mock.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "profile.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
// default SD Card filename serves for unit testing logic which requires SD card
|
||||
// tests with emulator should call debuglink.insert_sdcard(...)
|
||||
#define SDCARD_FILENAME_DEFAULT PROFILE_DIR_DEFAULT "/trezor.sdcard_def"
|
||||
|
||||
// default SD card data
|
||||
// By default, Emulator starts without mocked SD card, i.e. initially
|
||||
// sdcard.is_present() == False
|
||||
SDCardMock sdcard_mock = {
|
||||
.inserted = sectrue,
|
||||
.filename = SDCARD_FILENAME_DEFAULT,
|
||||
.inserted = secfalse,
|
||||
.powered = secfalse,
|
||||
.filename = NULL,
|
||||
.buffer = NULL,
|
||||
.serial_number = 1,
|
||||
.capacity_bytes = 64 * ONE_MEBIBYTE,
|
||||
.blocks = (64 * ONE_MEBIBYTE) / SDCARD_BLOCK_SIZE,
|
||||
.manuf_ID = 1,
|
||||
.serial_number = 0,
|
||||
.capacity_bytes = 0,
|
||||
.blocks = 0 / SDCARD_BLOCK_SIZE,
|
||||
.manuf_ID = 0,
|
||||
};
|
||||
|
||||
// "not inserted" SD card data
|
||||
/* SDCardMock sdcard_mock = { */
|
||||
/* .inserted = secfalse, */
|
||||
/* .filename = NULL, */
|
||||
/* .buffer = NULL, */
|
||||
/* .serial_number = 0, */
|
||||
/* .capacity_bytes = 0, */
|
||||
/* .blocks = 0 / SDCARD_BLOCK_SIZE, */
|
||||
/* .manuf_ID = 0, */
|
||||
/* }; */
|
||||
|
||||
void set_sdcard_mock_filename(SDCardMock *card, int serial_number) {
|
||||
if (card == NULL) {
|
||||
void set_sdcard_mock_filename(int serial_number) {
|
||||
if (sdcard_mock.serial_number == serial_number) {
|
||||
// serial_number determines the filename, so assuming the PROFILE_DIR
|
||||
// doesn't change during a lifetime of the emulator, we can skip the rename
|
||||
return;
|
||||
}
|
||||
|
||||
@ -58,11 +46,10 @@ void set_sdcard_mock_filename(SDCardMock *card, int serial_number) {
|
||||
serial_number);
|
||||
|
||||
// free the old filename
|
||||
if (card->filename != NULL &&
|
||||
strcmp(card->filename, SDCARD_FILENAME_DEFAULT) != 0) {
|
||||
free(card->filename);
|
||||
card->filename = NULL;
|
||||
if (sdcard_mock.filename != NULL) {
|
||||
free(sdcard_mock.filename);
|
||||
sdcard_mock.filename = NULL;
|
||||
}
|
||||
|
||||
card->filename = new_filename;
|
||||
sdcard_mock.filename = new_filename;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
typedef struct {
|
||||
secbool inserted;
|
||||
secbool powered;
|
||||
char *filename;
|
||||
uint8_t *buffer;
|
||||
uint32_t serial_number;
|
||||
@ -20,6 +21,6 @@ typedef struct {
|
||||
|
||||
extern SDCardMock sdcard_mock;
|
||||
|
||||
void set_sdcard_mock_filename(SDCardMock *card, int serial_number);
|
||||
void set_sdcard_mock_filename(int serial_number);
|
||||
|
||||
#endif // __TREZOR_SDCARD_EMULATOR_MOCK_H__
|
||||
|
@ -118,11 +118,12 @@ def _from_env(name: str) -> bool:
|
||||
@click.option("-r", "--record-dir", help="Directory where to record screen changes")
|
||||
@click.option("-s", "--slip0014", is_flag=True, help="Initialize device with SLIP-14 seed (all all all...)")
|
||||
@click.option("-S", "--script-gdb-file", type=click.Path(exists=True, dir_okay=False), help="Run gdb with an init file")
|
||||
@click.option("--sdcard", "sdcard_present", is_flag=True, default=False, help="Run emulator with SD card inserted")
|
||||
@click.option("-t", "--temporary-profile", is_flag=True, help="Create an empty temporary profile")
|
||||
@click.option("-w", "--watch", is_flag=True, help="Restart emulator if sources change")
|
||||
@click.option("-X", "--extra-arg", "extra_args", multiple=True, help="Extra argument to pass to micropython")
|
||||
# fmt: on
|
||||
@click.argument("command", nargs=-1, type=click.UNPROCESSED)
|
||||
# fmt: on
|
||||
def cli(
|
||||
disable_animation: bool,
|
||||
run_command: bool,
|
||||
@ -144,6 +145,7 @@ def cli(
|
||||
record_dir: Optional[str],
|
||||
slip0014: bool,
|
||||
script_gdb_file: str | Path | None,
|
||||
sdcard_present: bool,
|
||||
temporary_profile: bool,
|
||||
watch: bool,
|
||||
extra_args: list[str],
|
||||
@ -240,6 +242,7 @@ def cli(
|
||||
extra_args=extra_args,
|
||||
main_args=main_args,
|
||||
heap_size=heap_size,
|
||||
sdcard_present=sdcard_present,
|
||||
disable_animation=disable_animation,
|
||||
workdir=SRC_DIR,
|
||||
)
|
||||
|
@ -9,10 +9,14 @@ class TestStorageSdSeedBackup(unittest.TestCase):
|
||||
# TODO add more tests, also for repairing the backup card
|
||||
|
||||
def setUp(self):
|
||||
io.sdcard_switcher.insert(1)
|
||||
self.mnemonic = (
|
||||
b"crane mesh that gain predict open dice defy lottery toddler coin upgrade"
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
io.sdcard_switcher.eject()
|
||||
|
||||
def test_backup_and_restore(self):
|
||||
io.sdcard.power_on()
|
||||
io.fatfs.mkfs(True)
|
||||
|
@ -4,6 +4,11 @@ from trezor import io
|
||||
|
||||
|
||||
class TestTrezorIoSdcard(unittest.TestCase):
|
||||
def setUp(self):
|
||||
io.sdcard_switcher.insert(1)
|
||||
|
||||
def tearDown(self):
|
||||
io.sdcard_switcher.eject()
|
||||
|
||||
def test_start(self):
|
||||
self.assertTrue(io.sdcard.is_present())
|
||||
@ -31,8 +36,8 @@ class TestTrezorIoSdcard(unittest.TestCase):
|
||||
|
||||
def test_read_write(self):
|
||||
r = bytearray(8 * 512)
|
||||
w0 = bytearray(b'0' * (8 * 512))
|
||||
w1 = bytearray(b'1' * (8 * 512))
|
||||
w0 = bytearray(b"0" * (8 * 512))
|
||||
w1 = bytearray(b"1" * (8 * 512))
|
||||
io.sdcard.power_on()
|
||||
io.sdcard.write(0, w0)
|
||||
io.sdcard.read(0, r)
|
||||
@ -43,5 +48,5 @@ class TestTrezorIoSdcard(unittest.TestCase):
|
||||
io.sdcard.power_off()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
@ -4,7 +4,14 @@ from trezor import io, sdcard
|
||||
|
||||
fatfs = io.fatfs
|
||||
|
||||
|
||||
class TestTrezorSdcard(unittest.TestCase):
|
||||
def setUp(self):
|
||||
io.sdcard_switcher.insert(1)
|
||||
|
||||
def tearDown(self):
|
||||
io.sdcard_switcher.eject()
|
||||
|
||||
def test_power(self):
|
||||
# sdcard.capacity() will return 0 if the card is not powered,
|
||||
# non-zero value otherwise
|
||||
|
@ -232,25 +232,21 @@ class CoreEmulator(Emulator):
|
||||
port: Optional[int] = None,
|
||||
main_args: Sequence[str] = ("-m", "main"),
|
||||
workdir: Optional[Path] = None,
|
||||
sdcard: Optional[bytes] = None,
|
||||
disable_animation: bool = True,
|
||||
heap_size: str = "20M",
|
||||
sdcard_present: bool = False,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
if workdir is not None:
|
||||
self.workdir = Path(workdir).resolve()
|
||||
|
||||
# FIXME does not work with switchable SD cards
|
||||
# self.sdcard = self.profile_dir / "trezor.sdcard"
|
||||
# if sdcard is not None:
|
||||
# self.sdcard.write_bytes(sdcard)
|
||||
|
||||
if port:
|
||||
self.port = port
|
||||
self.disable_animation = disable_animation
|
||||
self.main_args = list(main_args)
|
||||
self.heap_size = heap_size
|
||||
self.sdcard_present = sdcard_present
|
||||
|
||||
def make_env(self) -> Dict[str, str]:
|
||||
env = super().make_env()
|
||||
@ -275,6 +271,11 @@ class CoreEmulator(Emulator):
|
||||
+ self.extra_args
|
||||
)
|
||||
|
||||
def start(self) -> None:
|
||||
super().start()
|
||||
if self.sdcard_present:
|
||||
self.client.debug.insert_sd_card()
|
||||
|
||||
def stop(self) -> None:
|
||||
super().stop()
|
||||
for i in range(1, 17):
|
||||
|
Loading…
Reference in New Issue
Block a user