From 20b09f7b39e3cfec6d8f7a8f90c972a07e662c5b Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 23 May 2022 13:03:00 +0200 Subject: [PATCH 01/17] add selenium un requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 56dbf2be..0f5fc8ec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,3 +43,4 @@ tqdm==4.32.2 python-decouple==3.3 python-dotenv==0.14.0 pyjwt==2.0.0a1 +selenium==4.1.5 From af470c0ecd7112f96d3554cca8fe453091d6daa7 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 24 May 2022 16:41:23 +0200 Subject: [PATCH 02/17] add selenium test --- .github/workflows/flask.yml | 6 +++ tests/test_selenium.py | 90 +++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 tests/test_selenium.py diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index 16086b5b..f0a59be7 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -49,6 +49,11 @@ jobs: python -m pip install --upgrade pip pip install flake8 pytest coverage pip install -r requirements.txt + alembic -x inventory=dbtest upgrade head + dh dummy --yes + mkdir bin + wget https://github.com/mozilla/geckodriver/releases/download/v0.30.0/geckodriver-v0.30.0-linux64.tar.gz + tar xf geckodriver-v0.30.0-linux64.tar.gz -C bin/ - name: Prepare database env: @@ -79,6 +84,7 @@ jobs: coverage run --source='ereuse_devicehub' -m pytest -m mvp --maxfail=5 tests/ coverage report --include='ereuse_devicehub/*' coverage xml + flask run & pytest tests/test_selenium.py - name: Upload coverage to Codecov uses: codecov/codecov-action@v1 diff --git a/tests/test_selenium.py b/tests/test_selenium.py new file mode 100644 index 00000000..866c2321 --- /dev/null +++ b/tests/test_selenium.py @@ -0,0 +1,90 @@ +# Generated by Selenium IDE +import time + +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.firefox.options import Options + + +class TestSelenium: + def setup_method(self, method): + options = Options() + options.add_argument("--headless") + self.driver = webdriver.Firefox( + options=options, executable_path=r'./bin/geckodriver' + ) + self.vars = {} + + def teardown_method(self, method): + self.driver.quit() + + def test_selenium(self): + # setup + self.driver.get("http://localhost:5000/login/") + self.driver.set_window_size(1920, 1063) + + # login + self.driver.find_element(By.ID, "yourEmail").click() + self.driver.implicitly_wait(3) + self.driver.find_element(By.ID, "yourPassword").send_keys("1234") + self.driver.find_element(By.ID, "yourEmail").send_keys("user@dhub.com") + self.driver.find_element(By.CSS_SELECTOR, ".btn").click() + self.driver.implicitly_wait(3) + + # select the first lot and get the ID of it + self.driver.find_element(By.LINK_TEXT, "Temporary Lots").click() + self.driver.implicitly_wait(3) + self.driver.find_element( + By.CSS_SELECTOR, "#temporal-lots-nav > li:nth-child(2) span" + ).click() + self.driver.implicitly_wait(3) + lot_id = self.driver.current_url.split("/")[5] + + # go to unassigned + self.driver.find_element(By.CSS_SELECTOR, ".nav-item:nth-child(3) span").click() + self.driver.implicitly_wait(3) + + # select the first device + self.driver.find_element( + By.CSS_SELECTOR, "tr:nth-child(1) .deviceSelect" + ).click() + self.driver.implicitly_wait(3) + + # add to new selenium_lot + self.driver.find_element(By.ID, "btnLots").click() + self.driver.implicitly_wait(3) + self.driver.find_element(By.ID, lot_id).click() + self.driver.implicitly_wait(3) + self.driver.find_element(By.ID, "ApplyDeviceLots").click() + time.sleep(3) + self.driver.find_element(By.ID, "SaveAllActions").click() + time.sleep(3) + + # go to selenium lot + self.driver.find_element(By.LINK_TEXT, "Temporary Lots").click() + self.driver.implicitly_wait(3) + self.driver.find_element( + By.CSS_SELECTOR, "#temporal-lots-nav > li:nth-child(2) span" + ).click() + self.driver.implicitly_wait(3) + + # select the first device + self.driver.find_element(By.CSS_SELECTOR, ".deviceSelect").click() + + # remove to new selenium_lot + self.driver.find_element(By.ID, "btnLots").click() + self.driver.implicitly_wait(3) + self.driver.find_element(By.ID, lot_id).click() + self.driver.implicitly_wait(3) + self.driver.find_element(By.ID, "ApplyDeviceLots").click() + time.sleep(3) + self.driver.find_element(By.ID, "SaveAllActions").click() + time.sleep(3) + + self.driver.find_element(By.CSS_SELECTOR, ".nav-item:nth-child(3) span").click() + self.driver.implicitly_wait(3) + + # logout + self.driver.find_element(By.CSS_SELECTOR, ".d-md-block").click() + self.driver.implicitly_wait(3) + self.driver.find_element(By.LINK_TEXT, "Sign Out").click() From 7ce18e148242dc1a6243ef4f486176ccec2b74cf Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 24 May 2022 16:52:19 +0200 Subject: [PATCH 03/17] add new process for check --- .github/workflows/flask.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index f0a59be7..ef68be92 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -49,8 +49,6 @@ jobs: python -m pip install --upgrade pip pip install flake8 pytest coverage pip install -r requirements.txt - alembic -x inventory=dbtest upgrade head - dh dummy --yes mkdir bin wget https://github.com/mozilla/geckodriver/releases/download/v0.30.0/geckodriver-v0.30.0-linux64.tar.gz tar xf geckodriver-v0.30.0-linux64.tar.gz -C bin/ @@ -67,6 +65,11 @@ jobs: psql -h "localhost" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "CREATE EXTENSION citext SCHEMA public;" psql -h "localhost" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "CREATE EXTENSION pg_trgm SCHEMA public;" + - name: Adding minimum datas + run: | + alembic -x inventory=dbtest upgrade head + dh dummy --yes + - name: Lint with flake8 run: | # stop the build if: From 7299ce15cfbab5685874341cd9ab3b7cd3a470c8 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 24 May 2022 16:57:42 +0200 Subject: [PATCH 04/17] fix pip --- .github/workflows/flask.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index ef68be92..74965db1 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -49,6 +49,7 @@ jobs: python -m pip install --upgrade pip pip install flake8 pytest coverage pip install -r requirements.txt + pip install -e . mkdir bin wget https://github.com/mozilla/geckodriver/releases/download/v0.30.0/geckodriver-v0.30.0-linux64.tar.gz tar xf geckodriver-v0.30.0-linux64.tar.gz -C bin/ From a6b3e725be8336ce1fe367dd6492b25b7843e318 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 24 May 2022 17:02:33 +0200 Subject: [PATCH 05/17] fix pip --- .github/workflows/flask.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index 74965db1..079835ad 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -67,6 +67,8 @@ jobs: psql -h "localhost" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "CREATE EXTENSION pg_trgm SCHEMA public;" - name: Adding minimum datas + env: + SECRET_KEY = 'f00046306835001b55c230092e3a7990485beda0bc3bf732088d1ba1b5b74110e22e3f9ec3a24890272554b37d4' run: | alembic -x inventory=dbtest upgrade head dh dummy --yes From 0530fef4149be874ad292a86ee08ad6062d80ad7 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 24 May 2022 17:03:41 +0200 Subject: [PATCH 06/17] fix env vars --- .github/workflows/flask.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index 079835ad..d08a5cb7 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -68,7 +68,7 @@ jobs: - name: Adding minimum datas env: - SECRET_KEY = 'f00046306835001b55c230092e3a7990485beda0bc3bf732088d1ba1b5b74110e22e3f9ec3a24890272554b37d4' + SECRET_KEY: 'f00046306835001b55c230092e3a7990485beda0bc3bf732088d1ba1b5b74110e22e3f9ec3a24890272554b37d4' run: | alembic -x inventory=dbtest upgrade head dh dummy --yes From ab20cdd1d0f795af39fbfb0f326cc2d1b204013d Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 24 May 2022 17:12:53 +0200 Subject: [PATCH 07/17] fix env vars --- .github/workflows/flask.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index d08a5cb7..3d8acf69 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -66,9 +66,10 @@ jobs: psql -h "localhost" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "CREATE EXTENSION citext SCHEMA public;" psql -h "localhost" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "CREATE EXTENSION pg_trgm SCHEMA public;" - - name: Adding minimum datas + - name: Selenium tests env: SECRET_KEY: 'f00046306835001b55c230092e3a7990485beda0bc3bf732088d1ba1b5b74110e22e3f9ec3a24890272554b37d4' + DB_DATABASE: dh_test run: | alembic -x inventory=dbtest upgrade head dh dummy --yes From a5d397627467e0d452908398efad4bcab537fb3a Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 24 May 2022 17:16:50 +0200 Subject: [PATCH 08/17] fix env vars --- .github/workflows/flask.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index 3d8acf69..2b6ef986 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -70,6 +70,7 @@ jobs: env: SECRET_KEY: 'f00046306835001b55c230092e3a7990485beda0bc3bf732088d1ba1b5b74110e22e3f9ec3a24890272554b37d4' DB_DATABASE: dh_test + dhi: dbtest run: | alembic -x inventory=dbtest upgrade head dh dummy --yes From ef570232e7ea7ac80fccd572f236a3cfe9b6d0e6 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 24 May 2022 17:20:17 +0200 Subject: [PATCH 09/17] fix env vars --- .github/workflows/flask.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index 2b6ef986..c899a218 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -74,6 +74,7 @@ jobs: run: | alembic -x inventory=dbtest upgrade head dh dummy --yes + flask run & pytest tests/test_selenium.py - name: Lint with flake8 run: | @@ -92,7 +93,6 @@ jobs: coverage run --source='ereuse_devicehub' -m pytest -m mvp --maxfail=5 tests/ coverage report --include='ereuse_devicehub/*' coverage xml - flask run & pytest tests/test_selenium.py - name: Upload coverage to Codecov uses: codecov/codecov-action@v1 From 5f025ff86988bdfdab900f66fcd00472e3b86d6e Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 25 May 2022 09:56:47 +0200 Subject: [PATCH 10/17] fix env vars --- .github/workflows/flask.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index c899a218..ec42536f 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -70,6 +70,7 @@ jobs: env: SECRET_KEY: 'f00046306835001b55c230092e3a7990485beda0bc3bf732088d1ba1b5b74110e22e3f9ec3a24890272554b37d4' DB_DATABASE: dh_test + FLASK_APP: examples/app.py dhi: dbtest run: | alembic -x inventory=dbtest upgrade head From c3ee749fe415e44e67a2fc9d8293c5097fe1ac10 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 27 Jun 2022 11:42:16 +0200 Subject: [PATCH 11/17] add sentry to app --- examples/app.py | 22 ++++++++++++++++++++++ requirements.txt | 1 + 2 files changed, 23 insertions(+) diff --git a/examples/app.py b/examples/app.py index 5a7e9fbb..690ff9f9 100644 --- a/examples/app.py +++ b/examples/app.py @@ -3,7 +3,11 @@ Example app with minimal configuration. Use this as a starting point. """ +import sentry_sdk +from decouple import config from flask_wtf.csrf import CSRFProtect +from sentry_sdk.integrations.flask import FlaskIntegration +from werkzeug.contrib.profiler import ProfilerMiddleware from ereuse_devicehub.api.views import api from ereuse_devicehub.config import DevicehubConfig @@ -13,6 +17,20 @@ from ereuse_devicehub.labels.views import labels from ereuse_devicehub.views import core from ereuse_devicehub.workbench.views import workbench +SENTRY_DSN = config('SENTRY_DSN', None) +if SENTRY_DSN: + sentry_sdk.init( + dsn=SENTRY_DSN, + integrations=[ + FlaskIntegration(), + ], + # Set traces_sample_rate to 1.0 to capture 100% + # of transactions for performance monitoring. + # We recommend adjusting this value in production. + traces_sample_rate=1.0, + ) + + app = Devicehub(inventory=DevicehubConfig.DB_SCHEMA) app.register_blueprint(core) app.register_blueprint(devices) @@ -26,3 +44,7 @@ app.register_blueprint(workbench) csrf = CSRFProtect(app) # csrf.protect(core) # csrf.protect(devices) +app.config["SQLALCHEMY_RECORD_QUERIES"] = True +app.config['PROFILE'] = True +app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[30]) +app.run(debug=True) diff --git a/requirements.txt b/requirements.txt index a72507d0..aec82953 100644 --- a/requirements.txt +++ b/requirements.txt @@ -45,3 +45,4 @@ python-dotenv==0.14.0 pyjwt==2.4.0 pint==0.9 py-dmidecode==0.1.0 +sentry_sdk==1.6.0 From 5c5d1c1a641ac043b487648ea1cfad82b77e7123 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 27 Jun 2022 12:35:52 +0200 Subject: [PATCH 12/17] change changelog --- CHANGELOG.md | 3 ++- requirements.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3193c889..a7a5343c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ ml). ## testing - [add] #305 add button download iso Workbench. -- [add] #306 add link for download json snapshot +- [add] #306 add link for download json snapshot. +- [add] #308 add sentry. - [changed] #302 add system uuid for check the identity of one device. ## [2.2.0] - 2022-06-24 diff --git a/requirements.txt b/requirements.txt index aec82953..6f4bb6d9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -46,3 +46,4 @@ pyjwt==2.4.0 pint==0.9 py-dmidecode==0.1.0 sentry_sdk==1.6.0 +blinker==1.4 From fa45080a44611968f7ab870d30b9fb9bc77ca69d Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 8 Jul 2022 12:21:07 +0200 Subject: [PATCH 13/17] fixed --- .../resources/documents/device_row.py | 165 +++++++++--------- 1 file changed, 83 insertions(+), 82 deletions(-) diff --git a/ereuse_devicehub/resources/documents/device_row.py b/ereuse_devicehub/resources/documents/device_row.py index 5f48eaa3..867e707f 100644 --- a/ereuse_devicehub/resources/documents/device_row.py +++ b/ereuse_devicehub/resources/documents/device_row.py @@ -1,13 +1,18 @@ """ This file frame a correct row for csv report """ from collections import OrderedDict + from flask import url_for -from ereuse_devicehub.resources.enums import Severity -from ereuse_devicehub.resources.device import models as d, states from ereuse_devicehub.resources.action import models as da -from ereuse_devicehub.resources.action.models import (BenchmarkDataStorage, RateComputer, - TestDataStorage) +from ereuse_devicehub.resources.action.models import ( + BenchmarkDataStorage, + RateComputer, + TestDataStorage, +) +from ereuse_devicehub.resources.device import models as d +from ereuse_devicehub.resources.device import states +from ereuse_devicehub.resources.enums import Severity class DeviceRow(OrderedDict): @@ -40,20 +45,20 @@ class DeviceRow(OrderedDict): software = '' if snapshot: software = "{software} {version}".format( - software=snapshot.software.name, version=snapshot.version) + software=snapshot.software.name, version=snapshot.version + ) # General information about device self['DHID'] = device.devicehub_id self['DocumentID'] = self.document_id self['Public Link'] = '{url}{id}'.format( - url=url_for('Device.main', _external=True), - id=device.devicehub_id) + url=url_for('Device.main', _external=True), id=device.devicehub_id + ) self['Lots'] = ', '.join([x.name for x in self.device.lots]) self['Tag 1 Type'] = self['Tag 1 ID'] = self['Tag 1 Organization'] = '' self['Tag 2 Type'] = self['Tag 2 ID'] = self['Tag 2 Organization'] = '' self['Tag 3 Type'] = self['Tag 3 ID'] = self['Tag 3 Organization'] = '' for i, tag in zip(range(1, 3), device.tags): - self['Tag {} Type'.format( - i)] = 'unamed' if tag.provider else 'named' + self['Tag {} Type'.format(i)] = 'unamed' if tag.provider else 'named' self['Tag {} ID'.format(i)] = tag.id self['Tag {} Organization'.format(i)] = tag.org.name @@ -79,8 +84,7 @@ class DeviceRow(OrderedDict): self['Allocate state'] = device.allocated_status.type try: - self['Lifecycle state'] = device.last_action_of( - *states.Trading.actions()).t + self['Lifecycle state'] = device.last_action_of(*states.Status.actions()).t except LookupError: self['Lifecycle state'] = '' if isinstance(device, d.Computer): @@ -155,10 +159,12 @@ class DeviceRow(OrderedDict): self['{} {} Serial Number'.format(ctype, i)] = '' else: self['{} {} Manufacturer'.format(ctype, i)] = none2str( - component.manufacturer) + component.manufacturer + ) self['{} {} Model'.format(ctype, i)] = none2str(component.model) self['{} {} Serial Number'.format(ctype, i)] = none2str( - component.serial_number) + component.serial_number + ) if ctype == d.Processor.t: self.get_processor(ctype, i, component) @@ -178,12 +184,10 @@ class DeviceRow(OrderedDict): self['{} {} Number of cores'.format(ctype, i)] = '' self['{} {} Speed (GHz)'.format(ctype, i)] = '' self['Benchmark {} {} (points)'.format(ctype, i)] = '' - self['Benchmark ProcessorSysbench {} {} (points)'.format( - ctype, i)] = '' + self['Benchmark ProcessorSysbench {} {} (points)'.format(ctype, i)] = '' return - self['{} {} Number of cores'.format( - ctype, i)] = none2str(component.cores) + self['{} {} Number of cores'.format(ctype, i)] = none2str(component.cores) self['{} {} Speed (GHz)'.format(ctype, i)] = none2str(component.speed) benchmark = get_action(component, 'BenchmarkProcessor') @@ -194,11 +198,11 @@ class DeviceRow(OrderedDict): sysbench = get_action(component, 'BenchmarkProcessorSysbench') if not sysbench: - self['Benchmark ProcessorSysbench {} {} (points)'.format( - ctype, i)] = '' + self['Benchmark ProcessorSysbench {} {} (points)'.format(ctype, i)] = '' return - self['Benchmark ProcessorSysbench {} {} (points)'.format( - ctype, i)] = sysbench.rate + self[ + 'Benchmark ProcessorSysbench {} {} (points)'.format(ctype, i) + ] = sysbench.rate def get_ram(self, ctype, i, component): """Particular fields for component Ram Module.""" @@ -212,7 +216,7 @@ class DeviceRow(OrderedDict): def get_datastorage(self, ctype, i, component): """Particular fields for component DataStorage. - A DataStorage can be HardDrive or SolidStateDrive. + A DataStorage can be HardDrive or SolidStateDrive. """ if component is None: @@ -244,21 +248,23 @@ class DeviceRow(OrderedDict): software = '' if snapshot: software = "{software} {version}".format( - software=snapshot.software.name, version=snapshot.version) + software=snapshot.software.name, version=snapshot.version + ) self['{} {} Size (MB)'.format(ctype, i)] = none2str(component.size) component_actions = sorted(component.actions, key=lambda x: x.created) - erasures = [a for a in component_actions if a.type in [ - 'EraseBasic', 'EraseSectors', 'DataWipe']] + erasures = [ + a + for a in component_actions + if a.type in ['EraseBasic', 'EraseSectors', 'DataWipe'] + ] erasure = erasures[-1] if erasures else None if not erasure: self['Erasure {} {}'.format(ctype, i)] = none2str(component.hid) serial_number = none2str(component.serial_number) - self['Erasure {} {} Serial Number'.format( - ctype, i)] = serial_number - self['Erasure {} {} Size (MB)'.format( - ctype, i)] = none2str(component.size) + self['Erasure {} {} Serial Number'.format(ctype, i)] = serial_number + self['Erasure {} {} Size (MB)'.format(ctype, i)] = none2str(component.size) self['Erasure {} {} Software'.format(ctype, i)] = '' self['Erasure {} {} Result'.format(ctype, i)] = '' self['Erasure {} {} Certificate URL'.format(ctype, i)] = '' @@ -272,15 +278,13 @@ class DeviceRow(OrderedDict): elif hasattr(erasure, 'type') and erasure.type == 'DataWipe': self['Erasure {} {}'.format(ctype, i)] = none2str(component.hid) serial_number = none2str(component.serial_number) - self['Erasure {} {} Serial Number'.format( - ctype, i)] = serial_number - self['Erasure {} {} Size (MB)'.format( - ctype, i)] = none2str(component.size) - self['Erasure {} {} Software'.format( - ctype, i)] = erasure.document.software + self['Erasure {} {} Serial Number'.format(ctype, i)] = serial_number + self['Erasure {} {} Size (MB)'.format(ctype, i)] = none2str(component.size) + self['Erasure {} {} Software'.format(ctype, i)] = erasure.document.software self['Erasure {} {} Result'.format(ctype, i)] = get_result(erasure) - self['Erasure {} {} Certificate URL'.format( - ctype, i)] = erasure.document.url and erasure.document.url.to_text() or '' + self['Erasure {} {} Certificate URL'.format(ctype, i)] = ( + erasure.document.url and erasure.document.url.to_text() or '' + ) self['Erasure {} {} Type'.format(ctype, i)] = '' self['Erasure {} {} Method'.format(ctype, i)] = '' self['Erasure {} {} Elapsed (hours)'.format(ctype, i)] = '' @@ -291,10 +295,8 @@ class DeviceRow(OrderedDict): else: self['Erasure {} {}'.format(ctype, i)] = none2str(component.hid) serial_number = none2str(component.serial_number) - self['Erasure {} {} Serial Number'.format( - ctype, i)] = serial_number - self['Erasure {} {} Size (MB)'.format( - ctype, i)] = none2str(component.size) + self['Erasure {} {} Serial Number'.format(ctype, i)] = serial_number + self['Erasure {} {} Size (MB)'.format(ctype, i)] = none2str(component.size) self['Erasure {} {} Software'.format(ctype, i)] = software result = get_result(erasure) @@ -302,20 +304,16 @@ class DeviceRow(OrderedDict): self['Erasure {} {} Certificate URL'.format(ctype, i)] = '' self['Erasure {} {} Type'.format(ctype, i)] = erasure.type self['Erasure {} {} Method'.format(ctype, i)] = erasure.method - self['Erasure {} {} Elapsed (hours)'.format( - ctype, i)] = format(erasure.elapsed) - self['Erasure {} {} Date'.format( - ctype, i)] = format(erasure.created) + self['Erasure {} {} Elapsed (hours)'.format(ctype, i)] = format( + erasure.elapsed + ) + self['Erasure {} {} Date'.format(ctype, i)] = format(erasure.created) steps = ','.join((format(x) for x in erasure.steps)) self['Erasure {} {} Steps'.format(ctype, i)] = steps - steps_start_time = ','.join( - (format(x.start_time) for x in erasure.steps)) - self['Erasure {} {} Steps Start Time'.format( - ctype, i)] = steps_start_time - steps_end_time = ','.join((format(x.end_time) - for x in erasure.steps)) - self['Erasure {} {} Steps End Time'.format( - ctype, i)] = steps_end_time + steps_start_time = ','.join((format(x.start_time) for x in erasure.steps)) + self['Erasure {} {} Steps Start Time'.format(ctype, i)] = steps_start_time + steps_end_time = ','.join((format(x.end_time) for x in erasure.steps)) + self['Erasure {} {} Steps End Time'.format(ctype, i)] = steps_end_time benchmark = get_action(component, 'BenchmarkDataStorage') if not benchmark: @@ -323,9 +321,11 @@ class DeviceRow(OrderedDict): self['Benchmark {} {} Writing speed (MB/s)'.format(ctype, i)] = '' else: self['Benchmark {} {} Read Speed (MB/s)'.format(ctype, i)] = none2str( - benchmark.read_speed) + benchmark.read_speed + ) self['Benchmark {} {} Writing speed (MB/s)'.format(ctype, i)] = none2str( - benchmark.write_speed) + benchmark.write_speed + ) test_storage = get_action(component, 'TestDataStorage') if not test_storage: @@ -339,14 +339,16 @@ class DeviceRow(OrderedDict): self['Test {} {} Software'.format(ctype, i)] = software self['Test {} {} Type'.format(ctype, i)] = test_storage.length.value - self['Test {} {} Result'.format(ctype, i)] = get_result( - test_storage) + self['Test {} {} Result'.format(ctype, i)] = get_result(test_storage) self['Test {} {} Power cycle count'.format(ctype, i)] = none2str( - test_storage.power_cycle_count) + test_storage.power_cycle_count + ) self['Test {} {} Lifetime (days)'.format(ctype, i)] = none2str( - test_storage.lifetime) + test_storage.lifetime + ) self['Test {} {} Power on hours'.format(ctype, i)] = none2str( - test_storage.power_on_hours) + test_storage.power_on_hours + ) def get_graphic_card(self, ctype, i, component): """Particular fields for component GraphicCard.""" @@ -400,39 +402,36 @@ class StockRow(OrderedDict): def get_result(erasure): - """ For the csv is necessary simplify the message of results """ + """For the csv is necessary simplify the message of results""" if hasattr(erasure, 'type') and erasure.type == 'DataWipe': if erasure.document.success: return 'Success' return 'Failure' - type_of_results = { Severity.Error: 'Failure', Severity.Warning: 'Success with Warnings', Severity.Notice: 'Success', - Severity.Info: 'Success' - } + Severity.Info: 'Success', + } return type_of_results[erasure.severity] def none2str(string): - """ convert none to empty str """ + """convert none to empty str""" if string is None: return '' return format(string) - def get_action(component, action): - """ Filter one action from a component or return None """ + """Filter one action from a component or return None""" result = [a for a in component.actions if a.type == action] return result[-1] if result else None class ActionRow(OrderedDict): - - def __init__(self, allocate): + def __init__(self, allocate): super().__init__() # General information about allocates, deallocate and lives self['DHID'] = allocate['devicehubID'] @@ -459,7 +458,6 @@ class ActionRow(OrderedDict): class InternalStatsRow(OrderedDict): - def __init__(self, user, create, actions): super().__init__() # General information about all internal stats @@ -488,13 +486,7 @@ class InternalStatsRow(OrderedDict): def count_actions(self): for ac in self.actions: - self.is_snapshot( - self.is_deallocate( - self.is_live( - self.is_allocate(ac) - ) - ) - ) + self.is_snapshot(self.is_deallocate(self.is_live(self.is_allocate(ac)))) def is_allocate(self, ac): if ac.type == 'Allocate': @@ -531,9 +523,18 @@ class InternalStatsRow(OrderedDict): self['Snapshot (Registers)'] += 1 def quarter(self, month): - q = {1: 'Q1', 2: 'Q1', 3: 'Q1', - 4: 'Q2', 5: 'Q2', 6: 'Q2', - 7: 'Q3', 8: 'Q3', 9: 'Q3', - 10: 'Q4', 11: 'Q4', 12: 'Q4', - } + q = { + 1: 'Q1', + 2: 'Q1', + 3: 'Q1', + 4: 'Q2', + 5: 'Q2', + 6: 'Q2', + 7: 'Q3', + 8: 'Q3', + 9: 'Q3', + 10: 'Q4', + 11: 'Q4', + 12: 'Q4', + } return q[int(month)] From acc8015b92ccbdbc8cb4e3e52ca9c81f8d0be221 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 8 Jul 2022 12:46:46 +0200 Subject: [PATCH 14/17] changelog --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7a5343c..d0159c29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ml). - [add] #306 add link for download json snapshot. - [add] #308 add sentry. - [changed] #302 add system uuid for check the identity of one device. +- [fixed] #309 column lifecycle status is always empty. ## [2.2.0] - 2022-06-24 - [changed] #304 change anchor of link devices lots. @@ -158,3 +159,17 @@ First server render HTML version. Completely rewrites views of angular JS client - [added] #83 add owner_id in all kind of device - [fixed] #89 save json on disk only for shapshots - [fixed] #91 The most old time allow is 1970-01-01 + + +# Release notes + +## [2.2.1] +The pr #302 involves some changes in the deployment process +For to do the deployment you need to do run the script extract_uuids.sh before to run alembic. +This is the correct secuence if the schema of you proyect is *dbtest* +``` +git pull +sh examples/extract_uuids.sh +alembic -x inventory=dbtest upgrade head +``` +If you forget to run this script the migration is do it but not modify any device data. From cfb8706598ce404635350c7c4272864655adbfb4 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 8 Jul 2022 18:55:32 +0200 Subject: [PATCH 15/17] fix test selenium --- tests/test_selenium.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/test_selenium.py b/tests/test_selenium.py index 866c2321..b4c7c79d 100644 --- a/tests/test_selenium.py +++ b/tests/test_selenium.py @@ -2,6 +2,7 @@ import time from selenium import webdriver +from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.firefox.options import Options @@ -19,6 +20,7 @@ class TestSelenium: self.driver.quit() def test_selenium(self): + # import pdb; pdb.set_trace() # setup self.driver.get("http://localhost:5000/login/") self.driver.set_window_size(1920, 1063) @@ -41,7 +43,7 @@ class TestSelenium: lot_id = self.driver.current_url.split("/")[5] # go to unassigned - self.driver.find_element(By.CSS_SELECTOR, ".nav-item:nth-child(3) span").click() + self.driver.find_element(By.CSS_SELECTOR, ".nav-item:nth-child(5) span").click() self.driver.implicitly_wait(3) # select the first device @@ -57,6 +59,19 @@ class TestSelenium: self.driver.implicitly_wait(3) self.driver.find_element(By.ID, "ApplyDeviceLots").click() time.sleep(3) + element = self.driver.find_element(By.ID, "ApplyDeviceLots") + time.sleep(3) + actions = ActionChains(self.driver) + time.sleep(3) + actions.move_to_element(element).perform() + time.sleep(3) + element = self.driver.find_element(By.CSS_SELECTOR, "body") + time.sleep(3) + actions = ActionChains(self.driver) + time.sleep(3) + # actions.move_to_element(element, 0, 0).perform() + actions.move_to_element(element).perform() + time.sleep(3) self.driver.find_element(By.ID, "SaveAllActions").click() time.sleep(3) @@ -81,10 +96,10 @@ class TestSelenium: self.driver.find_element(By.ID, "SaveAllActions").click() time.sleep(3) - self.driver.find_element(By.CSS_SELECTOR, ".nav-item:nth-child(3) span").click() + self.driver.find_element(By.CSS_SELECTOR, ".nav-item:nth-child(5) span").click() self.driver.implicitly_wait(3) # logout - self.driver.find_element(By.CSS_SELECTOR, ".d-md-block").click() + self.driver.find_element(By.CSS_SELECTOR, ".d-md-block:nth-child(2)").click() self.driver.implicitly_wait(3) self.driver.find_element(By.LINK_TEXT, "Sign Out").click() From d028cd3c794a56c1929850c12b75225aeed9f372 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 8 Jul 2022 18:55:50 +0200 Subject: [PATCH 16/17] fix test selenium --- tests/test_selenium.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_selenium.py b/tests/test_selenium.py index b4c7c79d..33cd8c79 100644 --- a/tests/test_selenium.py +++ b/tests/test_selenium.py @@ -20,7 +20,6 @@ class TestSelenium: self.driver.quit() def test_selenium(self): - # import pdb; pdb.set_trace() # setup self.driver.get("http://localhost:5000/login/") self.driver.set_window_size(1920, 1063) From f60fdfe7a158331872ee0756cc276cb73fb5c53b Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Sun, 10 Jul 2022 07:21:11 +0200 Subject: [PATCH 17/17] add selenium test --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0159c29..e4f819c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ml). ## master ## testing +- [add] #281 add selenium test. - [add] #305 add button download iso Workbench. - [add] #306 add link for download json snapshot. - [add] #308 add sentry.