Exemple #1
0
def test_force_flash_no_serial_connection():
    """
    If Mu cannot establish a serial connection to the micro:bit, BUT the path
    to the micro:bit on the filesystem is known, then fall back to old-school
    flashing of hex with script appended to the end.
    """
    mock_flasher = mock.MagicMock()
    mock_flasher_class = mock.MagicMock(return_value=mock_flasher)
    with mock.patch("mu.contrib.uflash.find_microbit",
                    return_value="/bar/microbit"), mock.patch(
                        "mu.contrib.microfs.get_serial"), mock.patch(
                            "mu.contrib.microfs.version",
                            side_effect=IOError("bang")), mock.patch(
                                "mu.logic.os.path.exists",
                                return_value=True), mock.patch(
                                    "mu.modes.microbit.DeviceFlasher",
                                    mock_flasher_class):
        view = mock.MagicMock()
        view.current_tab.text = mock.MagicMock(return_value="foo")
        view.show_message = mock.MagicMock()
        editor = mock.MagicMock()
        editor.minify = False
        editor.microbit_runtime = ""
        editor.current_device = None
        mm = MicrobitMode(editor, view)
        mm.flash_start = mock.MagicMock(side_effect=mm.flash_start)
        mm.flash()
        mm.flash_start.assert_called_once_with(b"foo",
                                               "/bar/microbit",
                                               None,
                                               serial_fs=False)
        mock_flasher_class.assert_called_once_with(["/bar/microbit"], b"foo",
                                                   None)
        mock_flasher.finished.connect.assert_called_once_with(
            mm.flash_finished)
Exemple #2
0
def test_flash_force_with_attached_device(microbit):
    """
    Ensure the expected calls are made to DeviceFlasher and a helpful status
    message is enacted.
    """
    version_info = {
        "sysname":
        "microbit",
        "nodename":
        "microbit",
        "release":
        "1.0",
        "version": ("micro:bit v0.0.9-b'e10a5ff' on 2018-6-8; MicroPython "
                    "v1.9.2-34-gd64154c73 on 2017-09-01"),
        "machine":
        "micro:bit with nRF51822",
    }
    mock_flasher = mock.MagicMock()
    mock_flasher_class = mock.MagicMock(return_value=mock_flasher)
    with mock.patch("mu.modes.microbit.uflash.find_microbit",
                    return_value="/foo/microbit/"), mock.patch(
                        "mu.modes.microbit.microfs.version",
                        return_value=version_info), mock.patch(
                            "mu.modes.microbit.os.path.exists",
                            return_value=True), mock.patch(
                                "mu.modes.microbit.DeviceFlasher",
                                mock_flasher_class):
        view = mock.MagicMock()
        view.current_tab.text = mock.MagicMock(return_value="foo")
        view.show_message = mock.MagicMock()
        editor = mock.MagicMock()
        editor.minify = False
        editor.microbit_runtime = "/foo/bar.hex"
        editor.current_device = microbit
        mm = MicrobitMode(editor, view)
        mm.set_buttons = mock.MagicMock()
        mm.flash_start = mock.MagicMock(side_effect=mm.flash_start)
        mm.flash()
        assert mm.flash_thread == mock_flasher
        assert editor.show_status_message.call_count == 1
        mm.set_buttons.assert_called_once_with(flash=False,
                                               repl=False,
                                               files=False,
                                               plotter=False)
        mm.flash_start.assert_called_once_with(b"foo", "/foo/microbit/",
                                               "/foo/bar.hex")
        mock_flasher_class.assert_called_once_with(["/foo/microbit/"], None,
                                                   "/foo/bar.hex")
        mock_flasher.finished.connect.assert_called_once_with(
            mm.flash_finished)
        mock_flasher.on_flash_fail.connect.assert_called_once_with(
            mm.flash_failed)
        mock_flasher.start.assert_called_once_with()
Exemple #3
0
def test_flash_device_has_latest_firmware_encounters_serial_problem(
    microbit, ):
    """
    If copy_main encounters an IOError (likely on Windows), revert to
    old-school flashing.
    """
    version_info = {
        "sysname":
        "microbit",
        "nodename":
        "microbit",
        "release":
        uflash.MICROPYTHON_VERSION,
        "version": ("micro:bit v0.1.0-b'e10a5ff' on 2018-6-8; MicroPython "
                    "v1.9.2-34-gd64154c73 on 2017-09-01"),
        "machine":
        "micro:bit with nRF51822",
    }
    mock_flasher = mock.MagicMock()
    mock_flasher_class = mock.MagicMock(return_value=mock_flasher)
    with mock.patch("mu.modes.microbit.uflash.find_microbit",
                    return_value="bar"), mock.patch(
                        "mu.modes.microbit.microfs.version",
                        return_value=version_info), mock.patch(
                            "mu.modes.microbit.os.path.exists",
                            return_value=True), mock.patch(
                                "mu.modes.microbit.DeviceFlasher",
                                mock_flasher_class):
        view = mock.MagicMock()
        view.current_tab.text = mock.MagicMock(return_value="foo")
        view.show_message = mock.MagicMock()
        editor = mock.MagicMock()
        editor.minify = False
        editor.microbit_runtime = ""
        editor.current_device = microbit
        mm = MicrobitMode(editor, view)
        mm.flash_failed = mock.MagicMock()
        error = IOError("bang")
        mm.copy_main = mock.MagicMock(side_effect=error)
        mm.set_buttons = mock.MagicMock()
        mm.flash_start = mock.MagicMock(side_effect=mm.flash_start)
        mm.flash()
        mm.copy_main.assert_called_once_with(b"foo")
        mm.flash_start.assert_called_once_with(b"foo",
                                               "bar",
                                               None,
                                               serial_fs=False)
        mock_flasher_class.assert_called_once_with(["bar"], b"foo", None)
        mock_flasher.finished.connect.assert_called_once_with(
            mm.flash_finished)
        mock_flasher.on_flash_fail.connect.assert_called_once_with(
            mm.flash_failed)
        mock_flasher.start.assert_called_once_with()
Exemple #4
0
def test_force_flash_user_specified_device_path():
    """
    Ensure that if a micro:bit is not automatically found by uflash then it
    prompts the user to locate the device and, assuming a path was given,
    saves the hex in the expected location.
    """
    version_info = {
        "sysname":
        "microbit",
        "nodename":
        "microbit",
        "release":
        uflash.MICROPYTHON_VERSION,
        "version": ("micro:bit v0.1.0-b'e10a5ff' on 2018-6-8; MicroPython "
                    "v1.9.2-34-gd64154c73 on 2017-09-01"),
        "machine":
        "micro:bit with nRF51822",
    }
    mock_flasher = mock.MagicMock()
    mock_flasher_class = mock.MagicMock(return_value=mock_flasher)
    with mock.patch("mu.contrib.uflash.find_microbit",
                    return_value=None), mock.patch(
                        "mu.contrib.microfs.get_serial"), mock.patch(
                            "mu.contrib.microfs.version",
                            return_value=version_info), mock.patch(
                                "mu.logic.os.path.exists",
                                return_value=True), mock.patch(
                                    "mu.modes.microbit.DeviceFlasher",
                                    mock_flasher_class):
        view = mock.MagicMock()
        view.get_microbit_path = mock.MagicMock(return_value="/bar/microbit")
        view.current_tab.text = mock.MagicMock(return_value="foo")
        view.show_message = mock.MagicMock()
        editor = mock.MagicMock()
        editor.minify = False
        editor.microbit_runtime = ""
        editor.current_device = None
        mm = MicrobitMode(editor, view)
        mm.flash_start = mock.MagicMock(side_effect=mm.flash_start)
        mm.flash()
        home = HOME_DIRECTORY
        view.get_microbit_path.assert_called_once_with(home)
        mm.flash_start.assert_called_once_with(b"foo",
                                               "/bar/microbit",
                                               None,
                                               serial_fs=False)
        mock_flasher_class.assert_called_once_with(["/bar/microbit"], b"foo",
                                                   None)
        mock_flasher.finished.connect.assert_called_once_with(
            mm.flash_finished)
Exemple #5
0
def test_flash_with_attached_device_has_old_firmware(microbit):
    """
    If the device has some unknown old firmware, force flash it.
    """
    version_info = {
        "sysname": "microbit",
        "nodename": "microbit",
        "release": "1.0",
        "version": ("v1.9.2-34-gd64154c73 on 2017-09-01"),
        "machine": "micro:bit with nRF51822",
    }
    mock_flasher = mock.MagicMock()
    mock_flasher_class = mock.MagicMock(return_value=mock_flasher)
    with mock.patch("mu.modes.microbit.uflash.find_microbit",
                    return_value="/foo/bar"), mock.patch(
                        "mu.modes.microbit.microfs.version",
                        return_value=version_info), mock.patch(
                            "mu.modes.microbit.os.path.exists",
                            return_value=True), mock.patch(
                                "mu.modes.microbit.DeviceFlasher",
                                mock_flasher_class):
        view = mock.MagicMock()
        view.current_tab.text = mock.MagicMock(return_value="foo")
        view.show_message = mock.MagicMock()
        editor = mock.MagicMock()
        editor.minify = False
        editor.microbit_runtime = ""
        editor.current_device = microbit
        mm = MicrobitMode(editor, view)
        mm.copy_main = mock.MagicMock()
        mm.set_buttons = mock.MagicMock()
        mm.flash_start = mock.MagicMock(side_effect=mm.flash_start)
        mm.flash()
        assert mm.flash_thread == mock_flasher
        assert editor.show_status_message.call_count == 1
        mm.set_buttons.assert_called_once_with(flash=False,
                                               repl=False,
                                               files=False,
                                               plotter=False)
        mm.flash_start.assert_called_once_with(b"foo", "/foo/bar", None)
        mock_flasher_class.assert_called_once_with(["/foo/bar"], None, None)
        mock_flasher.finished.connect.assert_called_once_with(
            mm.flash_finished)
        mock_flasher.on_flash_fail.connect.assert_called_once_with(
            mm.flash_failed)
        mock_flasher.start.assert_called_once_with()
Exemple #6
0
def test_force_flash_empty_script(microbit_v1_5):
    """
    If the script to be flashed onto the device is empty, this is a signal to
    force a full flash of the "vanilla" / empty MicroPython runtime onto the
    device.
    """
    version_info = {
        "sysname":
        "microbit",
        "nodename":
        "microbit",
        "release":
        uflash.MICROPYTHON_VERSION,
        "version": ("micro:bit v0.1.0-b'e10a5ff' on 2018-6-8; MicroPython "
                    "v1.9.2-34-gd64154c73 on 2017-09-01"),
        "machine":
        "micro:bit with nRF51822",
    }
    mock_flasher = mock.MagicMock()
    mock_flasher_class = mock.MagicMock(return_value=mock_flasher)
    with mock.patch("mu.contrib.uflash.find_microbit",
                    return_value="/bar/microbit"), mock.patch(
                        "mu.contrib.microfs.get_serial"), mock.patch(
                            "mu.contrib.microfs.version",
                            return_value=version_info), mock.patch(
                                "mu.logic.os.path.exists",
                                return_value=True), mock.patch(
                                    "mu.modes.microbit.DeviceFlasher",
                                    mock_flasher_class):
        view = mock.MagicMock()
        view.current_tab.text = mock.MagicMock(return_value="   ")
        view.show_message = mock.MagicMock()
        editor = mock.MagicMock()
        editor.minify = False
        editor.microbit_runtime = ""
        editor.current_device = microbit_v1_5
        mm = MicrobitMode(editor, view)
        mm.flash_start = mock.MagicMock(side_effect=mm.flash_start)
        mm.flash()
        mm.flash_start.assert_called_once_with(b"   ", "/bar/microbit", None)
        mock_flasher_class.assert_called_once_with(["/bar/microbit"], None,
                                                   None)
        mock_flasher.finished.connect.assert_called_once_with(
            mm.flash_finished)
Exemple #7
0
def test_flash_with_attached_device_and_custom_runtime(microbit_v1_5):
    """
    Ensure the custom runtime is passed into the DeviceFlasher thread.
    """
    mock_flasher = mock.MagicMock()
    mock_flasher_class = mock.MagicMock(return_value=mock_flasher)
    with mock.patch("mu.modes.base.BaseMode.workspace_dir",
                    return_value=TEST_ROOT), mock.patch(
                        "mu.modes.microbit.uflash.find_microbit",
                        return_value="/foo/microbit/"), mock.patch(
                            "mu.modes.microbit.os.path.exists",
                            return_value=True), mock.patch(
                                "mu.modes.microbit.DeviceFlasher",
                                mock_flasher_class):
        view = mock.MagicMock()
        view.current_tab.text = mock.MagicMock(return_value="foo")
        view.show_message = mock.MagicMock()
        editor = mock.MagicMock()
        editor.minify = True
        editor.current_device = microbit_v1_5
        editor.microbit_runtime = os.path.join("tests", "customhextest.hex")
        mm = MicrobitMode(editor, view)
        mm.flash_start = mock.MagicMock(side_effect=mm.flash_start)
        mm.flash()
        assert editor.show_status_message.call_count == 1
        assert (os.path.join("tests", "customhextest.hex")
                in editor.show_status_message.call_args[0][0])
        assert mock_flasher_class.call_count == 1
        mm.flash_start.assert_called_once_with(
            b"foo",
            "/foo/microbit/",
            os.path.join("tests", "customhextest.hex"),
        )
        mock_flasher_class.assert_called_once_with(
            ["/foo/microbit/"],
            None,
            os.path.join("tests", "customhextest.hex"),
        )
        mock_flasher.finished.connect.assert_called_once_with(
            mm.flash_finished)
        mock_flasher.on_flash_fail.connect.assert_called_once_with(
            mm.flash_failed)
        mock_flasher.start.assert_called_once_with()
Exemple #8
0
def test_flash_with_attached_known_device_and_forced(microbit_v1_5):
    """
    If the runtime must be flashed, and the serial number for the device is
    supported, then flash the built-in MicroPython runtime.
    """
    version_info = {
        "sysname":
        "microbit",
        "nodename":
        "microbit",
        "release":
        "1.0.0",
        "version": ("micro:bit v0.0.9-b'e10a5ff' on 2018-6-8; MicroPython "
                    "v1.9.2-34-gd64154c73 on 2017-09-01"),
        "machine":
        "micro:bit with nRF51822",
    }
    mock_flasher = mock.MagicMock()
    mock_flasher_class = mock.MagicMock(return_value=mock_flasher)
    with mock.patch("mu.modes.microbit.uflash.find_microbit",
                    return_value="/bar/microbit"), mock.patch(
                        "mu.modes.microbit.microfs.version",
                        return_value=version_info), mock.patch(
                            "mu.modes.microbit.os.path.exists",
                            return_value=True), mock.patch(
                                "mu.modes.microbit.DeviceFlasher",
                                mock_flasher_class):
        view = mock.MagicMock()
        # Trigger force flash with an empty file.
        view.current_tab.text = mock.MagicMock(return_value="")
        editor = mock.MagicMock()
        editor.minify = False
        editor.microbit_runtime = ""
        editor.current_device = microbit_v1_5
        mm = MicrobitMode(editor, view)
        mm.flash_start = mock.MagicMock(side_effect=mm.flash_start)
        mm.flash()
        assert mock_flasher_class.call_count == 1
        mm.flash_start.assert_called_once_with(b"", "/bar/microbit", None)
        mock_flasher_class.assert_called_once_with(["/bar/microbit"], None,
                                                   None)
Exemple #9
0
def test_flash_force_with_no_micropython(microbit):
    """
    Ensure the expected calls are made to DeviceFlasher and a helpful status
    message is enacted if there is no MicroPython firmware on the device.
    """
    mock_flasher = mock.MagicMock()
    mock_flasher_class = mock.MagicMock(return_value=mock_flasher)
    with mock.patch("mu.modes.microbit.uflash.find_microbit",
                    return_value="bar"), mock.patch(
                        "mu.modes.microbit.microfs.version",
                        side_effect=ValueError("bang")), mock.patch(
                            "mu.modes.microbit.os.path.exists",
                            return_value=True), mock.patch(
                                "mu.modes.microbit.DeviceFlasher",
                                mock_flasher_class):
        view = mock.MagicMock()
        view.current_tab.text = mock.MagicMock(return_value="foo")
        view.show_message = mock.MagicMock()
        editor = mock.MagicMock()
        editor.minify = False
        editor.microbit_runtime = "/foo/bar"
        editor.current_device = microbit
        mm = MicrobitMode(editor, view)
        mm.set_buttons = mock.MagicMock()
        mm.flash_start = mock.MagicMock(side_effect=mm.flash_start)
        mm.flash()
        assert mm.flash_thread == mock_flasher
        assert editor.show_status_message.call_count == 1
        mm.set_buttons.assert_called_once_with(flash=False,
                                               repl=False,
                                               files=False,
                                               plotter=False)
        mm.flash_start.assert_called_once_with(b"foo", "bar", "/foo/bar")
        mock_flasher_class.assert_called_once_with(["bar"], None, "/foo/bar")
        mock_flasher.finished.connect.assert_called_once_with(
            mm.flash_finished)
        mock_flasher.on_flash_fail.connect.assert_called_once_with(
            mm.flash_failed)
        mock_flasher.start.assert_called_once_with()
Exemple #10
0
def test_flash_with_attached_device_has_latest_firmware_v2(microbit):
    """
    There's NO need to use the DeviceFlasher if the board already has the
    latest firmware. In which case, just call copy_main.
    """
    version_info = {
        "sysname":
        "microbit",
        "nodename":
        "microbit",
        "release":
        uflash.MICROPYTHON_V2_VERSION,
        "version": ("micro:bit v2.0.0-beta.3+d6c01d0 on 2020-12-21; "
                    "MicroPython v1.13 on 2020-12-21"),
        "machine":
        "micro:bit with nRF52833",
    }
    with mock.patch("mu.modes.microbit.uflash.find_microbit",
                    return_value="/path/microbit"), mock.patch(
                        "mu.modes.microbit.microfs.version",
                        return_value=version_info), mock.patch(
                            "mu.modes.microbit.os.path.exists",
                            return_value=True):
        view = mock.MagicMock()
        view.current_tab.text = mock.MagicMock(return_value="foo")
        view.show_message = mock.MagicMock()
        editor = mock.MagicMock()
        editor.minify = False
        editor.microbit_runtime = ""
        editor.current_device = microbit
        mm = MicrobitMode(editor, view)
        mm.copy_main = mock.MagicMock()
        mm.set_buttons = mock.MagicMock()
        mm.flash_start = mock.MagicMock()
        mm.flash()
        assert mm.flash_start.call_count == 0
        mm.copy_main.assert_called_once_with(b"foo")