forked from Open-MSS/MSS
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Updater Step 1 * Better workflow * Finish updater * Add tests * Add backups, use environment only as last resort * Mock Worker, test environment code * Make process more transparent and safe * Backup only at replacement, warn user on replacement * Warn the user even more in case of environment replacement * More tests * Remove environment replacement * Make restarter work on windows * Move updater to utils * Add command line update arguments Co-authored-by: ReimarBauer <rb.proj@gmail.com>
- Loading branch information
1 parent
5262631
commit 890ef74
Showing
13 changed files
with
642 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
mslib.msui._tests.test_updater | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
This module provides pytest functions to tests msui.updater | ||
This file is part of mss. | ||
:copyright: Copyright 2021 May Bär | ||
:copyright: Copyright 2021 by the mss team, see AUTHORS. | ||
:license: APACHE-2.0, see LICENSE for details. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
""" | ||
import sys | ||
import mock | ||
from PyQt5 import QtWidgets, QtTest | ||
|
||
from mslib.msui.updater import UpdaterUI, Updater | ||
from mslib.utils import Worker | ||
|
||
|
||
def no_conda(args=None, **named_args): | ||
raise FileNotFoundError | ||
|
||
|
||
class SubprocessDifferentVersionMock: | ||
def __init__(self, args=None, **named_args): | ||
self.returncode = 0 | ||
self.args = args | ||
if args and "list" in args and "mss" in args: | ||
self.stdout = "*mss 0.0.0\n" | ||
else: | ||
self.stdout = "*mss 999.999.999\n" | ||
|
||
|
||
class SubprocessSameMock: | ||
def __init__(self, args=None, **named_args): | ||
self.stdout = "*mss 999.999.999\n" | ||
self.returncode = 0 | ||
self.args = args | ||
|
||
|
||
def create_mock(function, on_success=None, on_failure=None, start=True): | ||
worker = Worker(function) | ||
if on_success: | ||
worker.finished.connect(on_success) | ||
if on_failure: | ||
worker.failed.connect(on_failure) | ||
if start: | ||
worker.run() | ||
return worker | ||
|
||
|
||
class Test_MSS_ShortcutDialog: | ||
def setup(self): | ||
self.updater = Updater() | ||
self.status = "" | ||
self.update_available = False | ||
self.update_finished = False | ||
|
||
def update_signal(old, new): | ||
self.update_available = True | ||
|
||
def update_finished_signal(): | ||
self.update_finished = True | ||
|
||
def status_signal(s): | ||
self.status = s | ||
|
||
self.updater.on_update_available.connect(update_signal) | ||
self.updater.on_status_update.connect(status_signal) | ||
self.updater.on_update_finished.connect(update_finished_signal) | ||
self.application = QtWidgets.QApplication(sys.argv) | ||
|
||
def teardown(self): | ||
self.application.quit() | ||
QtWidgets.QApplication.processEvents() | ||
|
||
@mock.patch("subprocess.Popen", new=SubprocessDifferentVersionMock) | ||
@mock.patch("subprocess.run", new=SubprocessDifferentVersionMock) | ||
@mock.patch("mslib.utils.Worker.create", create_mock) | ||
def test_update_recognised(self): | ||
self.updater.run() | ||
|
||
assert self.updater.new_version == "999.999.999" | ||
assert self.update_available | ||
self.updater.new_version = "0.0.0" | ||
|
||
self.updater.update_mss() | ||
assert self.status == "Update successful. Please restart MSS." | ||
assert self.update_finished | ||
|
||
@mock.patch("subprocess.Popen", new=SubprocessSameMock) | ||
@mock.patch("subprocess.run", new=SubprocessSameMock) | ||
@mock.patch("mslib.utils.Worker.create", create_mock) | ||
def test_no_update(self): | ||
self.updater.run() | ||
assert self.status == "Your MSS is up to date." | ||
assert not self.update_available | ||
assert not self.update_finished | ||
|
||
@mock.patch("subprocess.Popen", new=SubprocessDifferentVersionMock) | ||
@mock.patch("subprocess.run", new=SubprocessDifferentVersionMock) | ||
@mock.patch("mslib.utils.Worker.create", create_mock) | ||
def test_update_failed(self): | ||
self.updater.run() | ||
assert self.updater.new_version == "999.999.999" | ||
assert self.update_available | ||
self.updater.new_version = "1000.1000.1000" | ||
self.updater.update_mss() | ||
assert self.status == "Update failed. Please try it manually or " \ | ||
"by creating a new environment!" | ||
|
||
@mock.patch("subprocess.Popen", new=no_conda) | ||
@mock.patch("subprocess.run", new=no_conda) | ||
@mock.patch("mslib.utils.Worker.create", create_mock) | ||
def test_no_conda(self): | ||
self.updater.run() | ||
assert self.updater.new_version is None and self.updater.old_version is None | ||
assert not self.update_available | ||
assert not self.update_finished | ||
|
||
@mock.patch("subprocess.Popen", new=no_conda) | ||
@mock.patch("subprocess.run", new=no_conda) | ||
@mock.patch("mslib.utils.Worker.create", create_mock) | ||
def test_exception(self): | ||
self.updater.new_version = "999.999.999" | ||
self.updater.old_version = "999.999.999" | ||
self.updater.update_mss() | ||
assert self.status == "Update failed, please do it manually." | ||
assert not self.update_finished | ||
|
||
@mock.patch("subprocess.Popen", new=SubprocessSameMock) | ||
@mock.patch("subprocess.run", new=SubprocessSameMock) | ||
@mock.patch("PyQt5.QtWidgets.QMessageBox.information", return_value=QtWidgets.QMessageBox.Yes) | ||
@mock.patch("mslib.utils.Worker.create", create_mock) | ||
def test_ui(self, mock): | ||
ui = UpdaterUI() | ||
ui.updater.on_update_available.emit("", "") | ||
QtTest.QTest.qWait(100) | ||
assert ui.statusLabel.text() == "Update successful. Please restart MSS." | ||
assert ui.btRestart.isEnabled() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
# Form implementation generated from reading ui file 'mslib/msui/ui/ui_updater_dialog.ui' | ||
# | ||
# Created by: PyQt5 UI code generator 5.12.3 | ||
# | ||
# WARNING! All changes made in this file will be lost! | ||
|
||
|
||
from PyQt5 import QtCore, QtGui, QtWidgets | ||
|
||
|
||
class Ui_Updater(object): | ||
def setupUi(self, Updater): | ||
Updater.setObjectName("Updater") | ||
Updater.setWindowModality(QtCore.Qt.NonModal) | ||
Updater.resize(854, 338) | ||
self.verticalLayout = QtWidgets.QVBoxLayout(Updater) | ||
self.verticalLayout.setObjectName("verticalLayout") | ||
self.horizontalLayout = QtWidgets.QHBoxLayout() | ||
self.horizontalLayout.setObjectName("horizontalLayout") | ||
self.labelVersion = QtWidgets.QLabel(Updater) | ||
self.labelVersion.setObjectName("labelVersion") | ||
self.horizontalLayout.addWidget(self.labelVersion) | ||
self.btUpdate = QtWidgets.QPushButton(Updater) | ||
self.btUpdate.setEnabled(False) | ||
self.btUpdate.setObjectName("btUpdate") | ||
self.horizontalLayout.addWidget(self.btUpdate) | ||
self.btRestart = QtWidgets.QPushButton(Updater) | ||
self.btRestart.setEnabled(False) | ||
self.btRestart.setObjectName("btRestart") | ||
self.horizontalLayout.addWidget(self.btRestart) | ||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) | ||
self.horizontalLayout.addItem(spacerItem) | ||
self.label = QtWidgets.QLabel(Updater) | ||
self.label.setOpenExternalLinks(True) | ||
self.label.setObjectName("label") | ||
self.horizontalLayout.addWidget(self.label) | ||
self.verticalLayout.addLayout(self.horizontalLayout) | ||
self.statusLabel = QtWidgets.QLabel(Updater) | ||
self.statusLabel.setObjectName("statusLabel") | ||
self.verticalLayout.addWidget(self.statusLabel) | ||
self.output = QtWidgets.QPlainTextEdit(Updater) | ||
font = QtGui.QFont() | ||
font.setFamily("Sans Serif") | ||
font.setStyleStrategy(QtGui.QFont.PreferDefault) | ||
self.output.setFont(font) | ||
self.output.setLineWrapMode(QtWidgets.QPlainTextEdit.NoWrap) | ||
self.output.setReadOnly(True) | ||
self.output.setPlainText("") | ||
self.output.setCenterOnScroll(False) | ||
self.output.setObjectName("output") | ||
self.verticalLayout.addWidget(self.output) | ||
|
||
self.retranslateUi(Updater) | ||
QtCore.QMetaObject.connectSlotsByName(Updater) | ||
|
||
def retranslateUi(self, Updater): | ||
_translate = QtCore.QCoreApplication.translate | ||
Updater.setWindowTitle(_translate("Updater", "Updater")) | ||
self.labelVersion.setText(_translate("Updater", "Newest Version: x.x.x")) | ||
self.btUpdate.setText(_translate("Updater", "Update")) | ||
self.btRestart.setText(_translate("Updater", "Restart MSS")) | ||
self.label.setText(_translate("Updater", "<html><head/><body><p><a href=\"https://mss.readthedocs.io/en/stable/installation.html#install\"><span style=\" text-decoration: underline; color:#0000ff;\">Manual update instructions</span></a></p></body></html>")) | ||
self.statusLabel.setText(_translate("Updater", "Nothing to do")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.