From adb9a8e25a58932987a2a43a79f08d247397c300 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 1 Mar 2021 19:21:57 +0100 Subject: [PATCH 01/52] basic endpoint for wbconf --- ereuse_devicehub/resources/documents/documents.py | 10 ++++++++++ tests/test_documents.py | 9 ++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 692e6992..3a2f9b6a 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -291,6 +291,10 @@ class InternalStatsView(DeviceView): output.headers['Content-type'] = 'text/csv' return output +class WbConfDocumentView(DeviceView): + def get(self, wbtype: str): + return jsonify('') + class DocumentDef(Resource): __type__ = 'Document' @@ -358,3 +362,9 @@ class DocumentDef(Resource): auth=app.auth) actions_view = app.auth.requires_auth(actions_view) self.add_url_rule('/actions/', defaults=d, view_func=actions_view, methods=get) + + wbconf_view = ActionsDocumentView.as_view('WbConfDocumentView', + definition=self, + auth=app.auth) + wbconf_view = app.auth.requires_auth(wbconf_view) + self.add_url_rule('/wbconf/', defaults=d, view_func=wbconf_view, methods=get) diff --git a/tests/test_documents.py b/tests/test_documents.py index 5ac747b5..9639688a 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -465,7 +465,7 @@ def test_get_document_lots(user: UserClient, user2: UserClient): @pytest.mark.mvp def test_get_document_internal_stats(user: UserClient, user2: UserClient): - """Tests for get teh internal stats.""" + """Tests for get the internal stats.""" # csv_str, _ = user.get(res=documents.DocumentDef.t, # item='internalstats/') @@ -490,3 +490,10 @@ def test_get_document_internal_stats(user: UserClient, user2: UserClient): export_csv = list(obj_csv) assert csv_str.strip() == '""' + +@pytest.mark.mvp +def test_get_wbconf(user: UserClient): + """Tests for get env file for usb wb.""" + + csv_str, _ = user.get(res=documents.DocumentDef.t, + item='wbconf/') From 0d0005b31532f4d976c3524f16878ba5f3d536a1 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 2 Mar 2021 11:42:07 +0100 Subject: [PATCH 02/52] adding file env for download --- .../resources/documents/documents.py | 27 ++++++++++++++----- .../documents/templates/documents/env | 14 ++++++++++ tests/test_documents.py | 7 +++-- 3 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 ereuse_devicehub/resources/documents/templates/documents/env diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 3a2f9b6a..8aa345e4 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -1,7 +1,8 @@ import csv -import datetime import enum import uuid +import datetime +import pathlib from collections import OrderedDict from io import StringIO from typing import Callable, Iterable, Tuple @@ -251,7 +252,7 @@ class StampsView(View): url = urlutils.URL(request.url) url.normalize() url.path_parts = url.path_parts[:-2] + ['check', ''] - url_path = url.to_text() + url_path = url.to_text() return flask.render_template('documents/stamp.html', rq_url=url_path) @@ -291,9 +292,23 @@ class InternalStatsView(DeviceView): output.headers['Content-type'] = 'text/csv' return output -class WbConfDocumentView(DeviceView): + +class WbConfDocumentView(View): def get(self, wbtype: str): - return jsonify('') + if not wbtype.lower() in ['usodyrate', 'usodywipe']: + return jsonify('') + + data = {'token': '111', + 'host': 'localhost', + 'inventory': 'dbtest' + } + data['erase'] = False if wbtype == 'usodyrate' else True + + env = flask.render_template('documents/env', **data) + output = make_response(env) + output.headers['Content-Disposition'] = 'attachment; filename=.env' + output.headers['Content-type'] = 'text/plain' + return output class DocumentDef(Resource): @@ -363,8 +378,8 @@ class DocumentDef(Resource): actions_view = app.auth.requires_auth(actions_view) self.add_url_rule('/actions/', defaults=d, view_func=actions_view, methods=get) - wbconf_view = ActionsDocumentView.as_view('WbConfDocumentView', + wbconf_view = WbConfDocumentView.as_view('WbConfDocumentView', definition=self, auth=app.auth) wbconf_view = app.auth.requires_auth(wbconf_view) - self.add_url_rule('/wbconf/', defaults=d, view_func=wbconf_view, methods=get) + self.add_url_rule('/wbconf/', view_func=wbconf_view, methods=get) diff --git a/ereuse_devicehub/resources/documents/templates/documents/env b/ereuse_devicehub/resources/documents/templates/documents/env new file mode 100644 index 00000000..d7b43547 --- /dev/null +++ b/ereuse_devicehub/resources/documents/templates/documents/env @@ -0,0 +1,14 @@ +DH_TOKEN='{{token}}' +DH_HOST='{{host}}' +DH_INVENTORY='{{inventory}}' +DEVICEHUB_URL=https://${DB_HOST}/${DB_INVENTORY}/ + +WB_BENCHMARK = True +WB_STRESS_TEST = 0 +WB_SMART_TEST = 'short' + +WB_ERASE = {{erase}} +WB_ERASE_STEPS = 1 +WB_ERASE_LEADING_ZEROS = False + +WB_DEBUG = True diff --git a/tests/test_documents.py b/tests/test_documents.py index 9639688a..fc5df617 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -495,5 +495,8 @@ def test_get_document_internal_stats(user: UserClient, user2: UserClient): def test_get_wbconf(user: UserClient): """Tests for get env file for usb wb.""" - csv_str, _ = user.get(res=documents.DocumentDef.t, - item='wbconf/') + env, _ = user.get(res=documents.DocumentDef.t, item='wbconf/usodyrate', accept=ANY) + assert 'WB_ERASE = False' in env + + env, _ = user.get(res=documents.DocumentDef.t, item='wbconf/usodywipe', accept=ANY) + assert 'WB_ERASE = True' in env From f9ef2407496c29c6eb73dd62da42b867da7b17dd Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 2 Mar 2021 11:46:13 +0100 Subject: [PATCH 03/52] adding endpoint to test_basic --- tests/test_basic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_basic.py b/tests/test_basic.py index 11ffbb80..29d65f3e 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -40,6 +40,7 @@ def test_api_docs(client: Client): '/documents/erasures/', '/documents/devices/', '/documents/stamps/', + '/documents/wbconf/{wbtype}', '/documents/internalstats/', '/documents/stock/', '/documents/check/', From 8f3c9c33cba41439082a1581c1ce09d171883a4c Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 2 Mar 2021 17:11:34 +0100 Subject: [PATCH 04/52] adding the correct vars to env --- ereuse_devicehub/config.py | 1 + ereuse_devicehub/resources/documents/documents.py | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ereuse_devicehub/config.py b/ereuse_devicehub/config.py index beef8b25..5a37ace0 100644 --- a/ereuse_devicehub/config.py +++ b/ereuse_devicehub/config.py @@ -37,6 +37,7 @@ class DevicehubConfig(Config): DB_PASSWORD = config('DB_PASSWORD', 'ereuse') DB_HOST = config('DB_HOST', 'localhost') DB_DATABASE = config('DB_DATABASE', 'devicehub') + DB_SCHEMA = config('DB_SCHEMA', 'dbtest') SQLALCHEMY_DATABASE_URI = 'postgresql://{user}:{pw}@{host}/{db}'.format( user=DB_USER, pw=DB_PASSWORD, diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 8aa345e4..947ac85e 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -293,14 +293,14 @@ class InternalStatsView(DeviceView): return output -class WbConfDocumentView(View): +class WbConfDocumentView(DeviceView): def get(self, wbtype: str): if not wbtype.lower() in ['usodyrate', 'usodywipe']: return jsonify('') - data = {'token': '111', - 'host': 'localhost', - 'inventory': 'dbtest' + data = {'token': g.user.token, + 'host': app.config['DB_HOST'], + 'inventory': app.config['DB_SCHEMA'] } data['erase'] = False if wbtype == 'usodyrate' else True From 7e541f13a1398c1cff7ab41794656d91b0587be3 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 2 Mar 2021 21:27:14 +0100 Subject: [PATCH 05/52] change env file name --- ereuse_devicehub/resources/documents/documents.py | 4 ++-- .../templates/documents/{env => wbConfiguration.ini} | 0 ereuse_devicehub/resources/user/__init__.py | 4 +++- ereuse_devicehub/resources/user/views.py | 12 +++++++++++- 4 files changed, 16 insertions(+), 4 deletions(-) rename ereuse_devicehub/resources/documents/templates/documents/{env => wbConfiguration.ini} (100%) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 947ac85e..46e1cbf3 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -304,9 +304,9 @@ class WbConfDocumentView(DeviceView): } data['erase'] = False if wbtype == 'usodyrate' else True - env = flask.render_template('documents/env', **data) + env = flask.render_template('documents/wbConfiguration.ini', **data) output = make_response(env) - output.headers['Content-Disposition'] = 'attachment; filename=.env' + output.headers['Content-Disposition'] = 'attachment; filename=Configuration.ini' output.headers['Content-type'] = 'text/plain' return output diff --git a/ereuse_devicehub/resources/documents/templates/documents/env b/ereuse_devicehub/resources/documents/templates/documents/wbConfiguration.ini similarity index 100% rename from ereuse_devicehub/resources/documents/templates/documents/env rename to ereuse_devicehub/resources/documents/templates/documents/wbConfiguration.ini diff --git a/ereuse_devicehub/resources/user/__init__.py b/ereuse_devicehub/resources/user/__init__.py index ec9eed78..d4bf8354 100644 --- a/ereuse_devicehub/resources/user/__init__.py +++ b/ereuse_devicehub/resources/user/__init__.py @@ -7,7 +7,7 @@ from teal.resource import Converters, Resource from ereuse_devicehub.db import db from ereuse_devicehub.resources.user import schemas from ereuse_devicehub.resources.user.models import User -from ereuse_devicehub.resources.user.views import UserView, login +from ereuse_devicehub.resources.user.views import UserView, login, logout class UserDef(Resource): @@ -23,6 +23,8 @@ class UserDef(Resource): super().__init__(app, import_name, static_folder, static_url_path, template_folder, url_prefix, subdomain, url_defaults, root_path, cli_commands) self.add_url_rule('/login/', view_func=login, methods={'POST'}) + logout1 = app.auth.requires_auth(logout) + self.add_url_rule('/logout/', view_func=logout1, methods={'GET'}) @argument('email') @option('-i', '--inventory', diff --git a/ereuse_devicehub/resources/user/views.py b/ereuse_devicehub/resources/user/views.py index 7053eea7..e6376f3c 100644 --- a/ereuse_devicehub/resources/user/views.py +++ b/ereuse_devicehub/resources/user/views.py @@ -1,8 +1,10 @@ -from uuid import UUID +from uuid import UUID, uuid4 from flask import g, request +from flask.json import jsonify from teal.resource import View +from ereuse_devicehub.db import db from ereuse_devicehub.resources.user.exceptions import WrongCredentials from ereuse_devicehub.resources.user.models import User from ereuse_devicehub.resources.user.schemas import User as UserS @@ -24,3 +26,11 @@ def login(): return schema_with_token.jsonify(user) else: raise WrongCredentials() + + +def logout(): + # We use custom schema as we only want to parse a subset of user + g.user.token = uuid4() + db.session.add(g.user) + db.session.commit() + return jsonify('Ok') From 7dc88369a49fc52e0bf69341bb05557ae992c9b9 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 2 Mar 2021 21:53:15 +0100 Subject: [PATCH 06/52] adding logout in test_base --- tests/test_basic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_basic.py b/tests/test_basic.py index 29d65f3e..7de68b1a 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -56,7 +56,8 @@ def test_api_docs(client: Client): '/tags/', '/tags/{tag_id}/device/{device_id}', '/users/', - '/users/login/' + '/users/login/', + '/users/logout/', # '/devices/{dev1_id}/merge/{dev2_id}', # '/batteries/{dev1_id}/merge/{dev2_id}', # '/bikes/{dev1_id}/merge/{dev2_id}', From 5af22b6ec61fd1894200884347c5b840b0df1268 Mon Sep 17 00:00:00 2001 From: cayop <42643859+cayop@users.noreply.github.com> Date: Mon, 12 Apr 2021 11:47:18 +0200 Subject: [PATCH 07/52] Update ereuse_devicehub/resources/documents/documents.py Co-authored-by: Jordi Nadeu --- ereuse_devicehub/resources/documents/documents.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 1691f0ab..5fc51743 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -329,7 +329,7 @@ class WbConfDocumentView(DeviceView): } data['erase'] = False if wbtype == 'usodyrate' else True - env = flask.render_template('documents/wbConfiguration.ini', **data) + env = flask.render_template('documents/wbSettings.ini', **data) output = make_response(env) output.headers['Content-Disposition'] = 'attachment; filename=Configuration.ini' output.headers['Content-type'] = 'text/plain' From e40b297f3becdb8dcfbd0876dec22563515060b2 Mon Sep 17 00:00:00 2001 From: cayop <42643859+cayop@users.noreply.github.com> Date: Mon, 12 Apr 2021 11:47:26 +0200 Subject: [PATCH 08/52] Update ereuse_devicehub/resources/documents/documents.py Co-authored-by: Jordi Nadeu --- ereuse_devicehub/resources/documents/documents.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 5fc51743..b687dd82 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -331,7 +331,7 @@ class WbConfDocumentView(DeviceView): env = flask.render_template('documents/wbSettings.ini', **data) output = make_response(env) - output.headers['Content-Disposition'] = 'attachment; filename=Configuration.ini' + output.headers['Content-Disposition'] = 'attachment; filename=settings.ini' output.headers['Content-type'] = 'text/plain' return output From aa09413011d207b5df3e59f62fcac808c5e4ff4c Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 12 Apr 2021 12:05:52 +0200 Subject: [PATCH 09/52] fixing review comments --- .../resources/documents/documents.py | 7 ++++--- .../templates/documents/wbConfiguration.ini | 14 -------------- .../templates/documents/wbSettings.ini | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 17 deletions(-) delete mode 100644 ereuse_devicehub/resources/documents/templates/documents/wbConfiguration.ini create mode 100644 ereuse_devicehub/resources/documents/templates/documents/wbSettings.ini diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 1691f0ab..3eadfb4d 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -327,11 +327,12 @@ class WbConfDocumentView(DeviceView): 'host': app.config['DB_HOST'], 'inventory': app.config['DB_SCHEMA'] } - data['erase'] = False if wbtype == 'usodyrate' else True + data['erase'] = False + # data['erase'] = False if wbtype == 'usodyrate' else True - env = flask.render_template('documents/wbConfiguration.ini', **data) + env = flask.render_template('documents/wbSettings.ini', **data) output = make_response(env) - output.headers['Content-Disposition'] = 'attachment; filename=Configuration.ini' + output.headers['Content-Disposition'] = 'attachment; filename=settings.ini' output.headers['Content-type'] = 'text/plain' return output diff --git a/ereuse_devicehub/resources/documents/templates/documents/wbConfiguration.ini b/ereuse_devicehub/resources/documents/templates/documents/wbConfiguration.ini deleted file mode 100644 index d7b43547..00000000 --- a/ereuse_devicehub/resources/documents/templates/documents/wbConfiguration.ini +++ /dev/null @@ -1,14 +0,0 @@ -DH_TOKEN='{{token}}' -DH_HOST='{{host}}' -DH_INVENTORY='{{inventory}}' -DEVICEHUB_URL=https://${DB_HOST}/${DB_INVENTORY}/ - -WB_BENCHMARK = True -WB_STRESS_TEST = 0 -WB_SMART_TEST = 'short' - -WB_ERASE = {{erase}} -WB_ERASE_STEPS = 1 -WB_ERASE_LEADING_ZEROS = False - -WB_DEBUG = True diff --git a/ereuse_devicehub/resources/documents/templates/documents/wbSettings.ini b/ereuse_devicehub/resources/documents/templates/documents/wbSettings.ini new file mode 100644 index 00000000..c7156a65 --- /dev/null +++ b/ereuse_devicehub/resources/documents/templates/documents/wbSettings.ini @@ -0,0 +1,17 @@ +[settings] + +DH_TOKEN="{{token}}" + +DH_HOST="{{host}}" +DH_DATABASE="{{inventory}}" +DEVICEHUB_URL=https://${DB_HOST}/${DB_DATABASE}/ + +WB_BENCHMARK = False +WB_STRESS_TEST = 0 +WB_SMART_TEST = "" + +WB_ERASE = {{erase}} +WB_ERASE_STEPS = 1 +WB_ERASE_LEADING_ZEROS = False + +WB_DEBUG = True From 3be867832812edd6163f8bf8a2d7cc1ea23f7eb2 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 12 Apr 2021 12:10:57 +0200 Subject: [PATCH 10/52] resolve bad name of var logout1 --- ereuse_devicehub/resources/user/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ereuse_devicehub/resources/user/__init__.py b/ereuse_devicehub/resources/user/__init__.py index d4bf8354..1bbe508b 100644 --- a/ereuse_devicehub/resources/user/__init__.py +++ b/ereuse_devicehub/resources/user/__init__.py @@ -23,8 +23,8 @@ class UserDef(Resource): super().__init__(app, import_name, static_folder, static_url_path, template_folder, url_prefix, subdomain, url_defaults, root_path, cli_commands) self.add_url_rule('/login/', view_func=login, methods={'POST'}) - logout1 = app.auth.requires_auth(logout) - self.add_url_rule('/logout/', view_func=logout1, methods={'GET'}) + logout_view = app.auth.requires_auth(logout) + self.add_url_rule('/logout/', view_func=logout_view, methods={'GET'}) @argument('email') @option('-i', '--inventory', From 1620591deb31ee774f5b9754bc5721816bbe1814 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 12 Apr 2021 12:31:07 +0200 Subject: [PATCH 11/52] fixing test_get_wbconf --- tests/test_documents.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_documents.py b/tests/test_documents.py index 92eb1ded..527f6a63 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -654,4 +654,5 @@ def test_get_wbconf(user: UserClient): assert 'WB_ERASE = False' in env env, _ = user.get(res=documents.DocumentDef.t, item='wbconf/usodywipe', accept=ANY) - assert 'WB_ERASE = True' in env + assert 'WB_ERASE = False' in env + # assert 'WB_ERASE = True' in env From 4704045da81b36540550a5b8925718b437f7c2d9 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 12 Apr 2021 19:34:33 +0200 Subject: [PATCH 12/52] more easy to read --- ereuse_devicehub/resources/documents/documents.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 3eadfb4d..75210340 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -328,7 +328,7 @@ class WbConfDocumentView(DeviceView): 'inventory': app.config['DB_SCHEMA'] } data['erase'] = False - # data['erase'] = False if wbtype == 'usodyrate' else True + # data['erase'] = True if wbtype == 'usodywipe' else False env = flask.render_template('documents/wbSettings.ini', **data) output = make_response(env) From bfa9746de1ceb8a04dfefd637958991e3a669f4e Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 13 Apr 2021 18:33:15 +0200 Subject: [PATCH 13/52] session table and model --- .../versions/21afd375a654_session_table.py | 53 +++++++++++++++++++ ereuse_devicehub/resources/enums.py | 21 ++++++++ ereuse_devicehub/resources/user/models.py | 12 ++++- 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 ereuse_devicehub/migrations/versions/21afd375a654_session_table.py diff --git a/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py b/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py new file mode 100644 index 00000000..da370152 --- /dev/null +++ b/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py @@ -0,0 +1,53 @@ +"""session_table + +Revision ID: 21afd375a654 +Revises: 6a2a939d5668 +Create Date: 2021-04-13 11:18:27.720567 + +""" +from alembic import context +from alembic import op +from sqlalchemy.dialects import postgresql +import sqlalchemy as sa +import sqlalchemy_utils +import citext +import teal + +from ereuse_devicehub.resources.enums import SessionType + + +# revision identifiers, used by Alembic. +revision = '21afd375a654' +down_revision = '6a2a939d5668' +branch_labels = None +depends_on = None + + +def get_inv(): + INV = context.get_x_argument(as_dictionary=True).get('inventory') + if not INV: + raise ValueError("Inventory value is not specified") + return INV + +def upgrade(): + op.create_table('session', + sa.Column('updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False, comment='The last time Devicehub recorded a change for \n this thing.\n '), + sa.Column('created', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False, comment='When Devicehub created this.'), + sa.Column('id', sa.BigInteger(), nullable=False), + sa.Column('expired', sa.BigInteger(), nullable=True), + sa.Column('token', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('type', teal.db.IntEnum(SessionType), nullable=False), + sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=True), + sa.ForeignKeyConstraint(['user_id'], ['common.user.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('token'), + schema='common' + ) + op.create_index(op.f('ix_session_created'), 'session', ['created'], unique=False, schema='common') + op.create_index(op.f('ix_session_updated'), 'session', ['updated'], unique=False, schema='common') + + +def downgrade(): + op.drop_table('trade', schema=f'{get_inv()}') + op.drop_index(op.f('ix_session_created'), table_name='session', schema='common') + op.drop_index(op.f('ix_session_updated'), table_name='session', schema='common') diff --git a/ereuse_devicehub/resources/enums.py b/ereuse_devicehub/resources/enums.py index a07385d7..cff77056 100644 --- a/ereuse_devicehub/resources/enums.py +++ b/ereuse_devicehub/resources/enums.py @@ -393,3 +393,24 @@ class TransferState(IntEnum): def __str__(self): return self.name + + +@unique +class SessionType(IntEnum): + """ + Enumaration of types of sessions: + + * Internal: permanent Session for internal user. This is used in usb of WorkBench. + * External: permanent Session for external users. This is used in usb of WorkBench. + * Session: This is used for keep more than one session in the app frontend. + + Devicehub specially raises user awareness when an action + has a Severity of ``Warning`` or greater. + """ + + Internal = 0 + External = 1 + Session = 2 + + def __str__(self): + return self.name diff --git a/ereuse_devicehub/resources/user/models.py b/ereuse_devicehub/resources/user/models.py index 0ab670c8..324ee851 100644 --- a/ereuse_devicehub/resources/user/models.py +++ b/ereuse_devicehub/resources/user/models.py @@ -2,13 +2,15 @@ from uuid import uuid4 from citext import CIText from flask import current_app as app -from sqlalchemy import Column +from sqlalchemy import Column, BigInteger, Sequence from sqlalchemy.dialects.postgresql import UUID from sqlalchemy_utils import EmailType, PasswordType +from teal.db import IntEnum from ereuse_devicehub.db import db from ereuse_devicehub.resources.inventory.model import Inventory from ereuse_devicehub.resources.models import STR_SIZE, Thing +from ereuse_devicehub.resources.enums import SessionType class User(Thing): @@ -57,3 +59,11 @@ class UserInventory(db.Model): __table_args__ = {'schema': 'common'} user_id = db.Column(db.UUID(as_uuid=True), db.ForeignKey(User.id), primary_key=True) inventory_id = db.Column(db.Unicode(), db.ForeignKey(Inventory.id), primary_key=True) + + +class Session(Thing): + id = Column(BigInteger, Sequence('device_seq'), primary_key=True) + expired = Column(BigInteger, default=0) + token = Column(UUID(as_uuid=True), default=uuid4, unique=True, nullable=False) + type = Column(IntEnum(SessionType), default=SessionType.Internal, nullable=False) + user_id = db.Column(db.UUID(as_uuid=True), db.ForeignKey(User.id)) From 21f019dc141d64e72b9d90c8ca3e94168b7c9472 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 13 Apr 2021 18:33:49 +0200 Subject: [PATCH 14/52] useing session table in wbconf --- .../resources/documents/documents.py | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 75210340..7175ab06 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -20,6 +20,8 @@ from teal.cache import cache from teal.resource import Resource, View from ereuse_devicehub.db import db +from ereuse_devicehub.resources.user.models import Session +from ereuse_devicehub.resources.enums import SessionType from ereuse_devicehub.resources.action import models as evs from ereuse_devicehub.resources.device import models as devs from ereuse_devicehub.resources.deliverynote.models import Deliverynote @@ -323,7 +325,7 @@ class WbConfDocumentView(DeviceView): if not wbtype.lower() in ['usodyrate', 'usodywipe']: return jsonify('') - data = {'token': g.user.token, + data = {'token': self.get_token(), 'host': app.config['DB_HOST'], 'inventory': app.config['DB_SCHEMA'] } @@ -336,6 +338,28 @@ class WbConfDocumentView(DeviceView): output.headers['Content-type'] = 'text/plain' return output + def get_token(self): + internal_session = Session.query.filter_by(user_id=g.user.id, + type=SessionType.Internal).first() + if not internal_session: + internal_session = Session(user_id=g.user.id, type=SessionType.Internal) + db.session.add(internal_session) + + db.session.commit() + return internal_session.token + + # TODO @cayop for when in others iterations we need implement external token + # external_session = Session.query.filter_by(user_id=g.user.id, + # type=SessionType.Internal).first() + # if not external_session: + # external_session = Session(user_id=g.user.id, type=SessionType.External) + # external_session = Session(user_id=g.user.id, type=SessionType.External) + # db.session.add(external_session) + + # db.session.commit() + + # return external_session.token + class DocumentDef(Resource): __type__ = 'Document' From ca85a1f221d3863f3a29daf55d5e7149693ca9d9 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 13 Apr 2021 18:34:18 +0200 Subject: [PATCH 15/52] check the token in a test --- tests/test_documents.py | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/tests/test_documents.py b/tests/test_documents.py index a1a7b6d9..33f614a3 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -12,12 +12,14 @@ from ereuse_utils.test import ANY from ereuse_devicehub.client import Client, UserClient from ereuse_devicehub.devicehub import Devicehub +from ereuse_devicehub.resources.user.models import Session from ereuse_devicehub.resources.action.models import Snapshot, Allocate, Live from ereuse_devicehub.resources.documents import documents from ereuse_devicehub.resources.device import models as d from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.tag.model import Tag from ereuse_devicehub.resources.hash_reports import ReportHash +from ereuse_devicehub.resources.enums import SessionType from ereuse_devicehub.db import db from tests import conftest from tests.conftest import file @@ -200,7 +202,7 @@ def test_live_example2(user: UserClient, client: Client, app: Devicehub): assert str(action_live[0].snapshot_uuid) == acer['uuid'] -@pytest.mark.mvp +@pytest.mark.mvp def test_export_basic_snapshot(user: UserClient): """Test export device information in a csv file.""" snapshot, _ = user.post(file('basic.snapshot'), res=Snapshot) @@ -464,7 +466,7 @@ def test_get_document_lots(user: UserClient, user2: UserClient): assert export2_csv[1][3] == 'comments,lot3,testcomment-lot3,' -@pytest.mark.mvp +@pytest.mark.mvp def test_verify_stamp(user: UserClient, client: Client): """Test verify stamp of one export device information in a csv file.""" snapshot, _ = user.post(file('basic.snapshot'), res=Snapshot) @@ -472,12 +474,12 @@ def test_verify_stamp(user: UserClient, client: Client): item='devices/', accept='text/csv', query=[('filter', {'type': ['Computer']})]) - + response, _ = client.post(res=documents.DocumentDef.t, item='stamps/', content_type='multipart/form-data', accept='text/html', - data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), 'example.csv')]}, + data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), 'example.csv')]}, status=200) assert "alert alert-info" in response assert not "alert alert-danger" in response @@ -501,10 +503,10 @@ def test_verify_stamp(user: UserClient, client: Client): assert not "alert alert-danger" in response -@pytest.mark.mvp +@pytest.mark.mvp def test_verify_stamp_log_info(user: UserClient, client: Client): """Test verify stamp of one export lots-info in a csv file.""" - + l, _ = user.post({'name': 'Lot1', 'description': 'comments,lot1,testcomment-lot1,'}, res=Lot) l, _ = user.post({'name': 'Lot2', 'description': 'comments,lot2,testcomment-lot2,'}, res=Lot) @@ -516,8 +518,8 @@ def test_verify_stamp_log_info(user: UserClient, client: Client): item='stamps/', content_type='multipart/form-data', accept='text/html', - data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), - 'example.csv')]}, + data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), + 'example.csv')]}, status=200) assert "alert alert-info" in response @@ -538,7 +540,7 @@ def test_verify_stamp_devices_stock(user: UserClient, client: Client): content_type='multipart/form-data', accept='text/html', data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), - 'example.csv')]}, + 'example.csv')]}, status=200) assert "alert alert-info" in response @@ -573,8 +575,8 @@ def test_verify_stamp_csv_actions(user: UserClient, client: Client): item='stamps/', content_type='multipart/form-data', accept='text/html', - data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), - 'example.csv')]}, + data={'docUpload': [(BytesIO(bytes(csv_str, 'utf-8')), + 'example.csv')]}, status=200) assert "alert alert-info" in response @@ -594,8 +596,8 @@ def test_verify_stamp_erasure_certificate(user: UserClient, client: Client): item='stamps/', content_type='multipart/form-data', accept='text/html', - data={'docUpload': [(BytesIO(bytes(doc, 'utf-8')), - 'example.csv')]}, + data={'docUpload': [(BytesIO(bytes(doc, 'utf-8')), + 'example.csv')]}, status=200) assert "alert alert-danger" in response @@ -611,8 +613,8 @@ def test_verify_stamp_erasure_certificate(user: UserClient, client: Client): item='stamps/', content_type='multipart/form-data', accept='text/html', - data={'docUpload': [(BytesIO(doc), - 'example.csv')]}, + data={'docUpload': [(BytesIO(doc), + 'example.csv')]}, status=200) assert "alert alert-info" in response @@ -646,6 +648,7 @@ def test_get_document_internal_stats(user: UserClient, user2: UserClient): assert csv_str.strip() == '""' @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_get_wbconf(user: UserClient): """Tests for get env file for usb wb.""" @@ -655,3 +658,7 @@ def test_get_wbconf(user: UserClient): env, _ = user.get(res=documents.DocumentDef.t, item='wbconf/usodywipe', accept=ANY) assert 'WB_ERASE = False' in env # assert 'WB_ERASE = True' in env + + session = Session.query.filter_by(user_id=user.user['id'], + type=SessionType.Internal).first() + assert str(session.token) in env From 7ea3041aa064b26b6ca589558fc54bc1d4734367 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 14 Apr 2021 13:21:46 +0200 Subject: [PATCH 16/52] authorized up snapshots with new token --- tests/test_documents.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_documents.py b/tests/test_documents.py index 33f614a3..d3ad21a0 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -662,3 +662,5 @@ def test_get_wbconf(user: UserClient): session = Session.query.filter_by(user_id=user.user['id'], type=SessionType.Internal).first() assert str(session.token) in env + user.user['token'] = str(session.token) + snapshot, _ = user.post(file('basic.snapshot'), res=Snapshot) From 5cc64d2d28b3d3cadb29ec7073a27478200a8426 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 15 Apr 2021 21:16:04 +0200 Subject: [PATCH 17/52] fixing test --- tests/test_documents.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test_documents.py b/tests/test_documents.py index d3ad21a0..7699b468 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -10,6 +10,7 @@ from werkzeug.exceptions import Unauthorized import teal.marshmallow from ereuse_utils.test import ANY +from ereuse_devicehub import auth from ereuse_devicehub.client import Client, UserClient from ereuse_devicehub.devicehub import Devicehub from ereuse_devicehub.resources.user.models import Session @@ -647,6 +648,7 @@ def test_get_document_internal_stats(user: UserClient, user2: UserClient): assert csv_str.strip() == '""' + @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_get_wbconf(user: UserClient): @@ -661,6 +663,8 @@ def test_get_wbconf(user: UserClient): session = Session.query.filter_by(user_id=user.user['id'], type=SessionType.Internal).first() - assert str(session.token) in env - user.user['token'] = str(session.token) + token = session.token + token = auth.Auth.encode(session.token) + assert token in env + user.user['token'] = token snapshot, _ = user.post(file('basic.snapshot'), res=Snapshot) From 9c489c75641d9a5e0fda273d51542338dfe42e68 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 15 Apr 2021 21:16:32 +0200 Subject: [PATCH 18/52] fixing create new users --- ereuse_devicehub/dummy/dummy.py | 6 ++++++ tests/conftest.py | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/ereuse_devicehub/dummy/dummy.py b/ereuse_devicehub/dummy/dummy.py index e83a3577..bcd0a595 100644 --- a/ereuse_devicehub/dummy/dummy.py +++ b/ereuse_devicehub/dummy/dummy.py @@ -17,6 +17,8 @@ from ereuse_devicehub.resources.device.models import Device from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.tag.model import Tag from ereuse_devicehub.resources.user import User +from ereuse_devicehub.resources.user.models import Session +from ereuse_devicehub.resources.enums import SessionType class Dummy: @@ -193,6 +195,10 @@ class Dummy: user.individuals.add(Person(name=name)) db.session.add(user) + session_external = Session(user=user, type=SessionType.External) + session_internal = Session(user=user, type=SessionType.Internal) + db.session.add(session_internal) + db.session.add(session_external) db.session.commit() client = UserClient(self.app, user.email, password, diff --git a/tests/conftest.py b/tests/conftest.py index d0a0bdd2..4c45dc06 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,6 +17,8 @@ from ereuse_devicehub.devicehub import Devicehub from ereuse_devicehub.resources.agent.models import Person from ereuse_devicehub.resources.tag import Tag from ereuse_devicehub.resources.user.models import User +from ereuse_devicehub.resources.user.models import Session +from ereuse_devicehub.resources.enums import SessionType STARTT = datetime(year=2000, month=1, day=1, hour=1) """A dummy starting time to use in tests.""" @@ -111,7 +113,11 @@ def user2(app: Devicehub) -> UserClient: def create_user(email='foo@foo.com', password='foo') -> User: user = User(email=email, password=password) user.individuals.add(Person(name='Timmy')) + session_external = Session(user=user, type=SessionType.External) + session_internal = Session(user=user, type=SessionType.Internal) db.session.add(user) + db.session.add(session_internal) + db.session.add(session_external) db.session.commit() return user From bae5a1d2b1910ffa6ebd569beb1721520efa7c17 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 15 Apr 2021 21:17:24 +0200 Subject: [PATCH 19/52] add session schema --- ereuse_devicehub/resources/user/schemas.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ereuse_devicehub/resources/user/schemas.py b/ereuse_devicehub/resources/user/schemas.py index e8d0d768..220e193b 100644 --- a/ereuse_devicehub/resources/user/schemas.py +++ b/ereuse_devicehub/resources/user/schemas.py @@ -9,6 +9,10 @@ from ereuse_devicehub.resources.inventory.schema import Inventory from ereuse_devicehub.resources.schemas import Thing +class Session(Thing): + token = String(dump_only=True) + + class User(Thing): id = UUID(dump_only=True) email = Email(required=True) From b3d77ba212d9f4d8da0009a4cc09ede9d70100c7 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 15 Apr 2021 21:18:15 +0200 Subject: [PATCH 20/52] fixing model and migration --- .../versions/21afd375a654_session_table.py | 13 +++++++++++-- ereuse_devicehub/resources/user/models.py | 6 ++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py b/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py index da370152..4e121731 100644 --- a/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py +++ b/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py @@ -21,6 +21,7 @@ revision = '21afd375a654' down_revision = '6a2a939d5668' branch_labels = None depends_on = None +comment_update = 'The last time Devicehub recorded a change for this thing.\n' def get_inv(): @@ -29,10 +30,16 @@ def get_inv(): raise ValueError("Inventory value is not specified") return INV + def upgrade(): op.create_table('session', - sa.Column('updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False, comment='The last time Devicehub recorded a change for \n this thing.\n '), - sa.Column('created', sa.TIMESTAMP(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False, comment='When Devicehub created this.'), + sa.Column('updated', sa.TIMESTAMP(timezone=True), + server_default=sa.text('CURRENT_TIMESTAMP'), + nullable=False, + comment=comment_update), + sa.Column('created', sa.TIMESTAMP(timezone=True), + server_default=sa.text('CURRENT_TIMESTAMP'), + nullable=False, comment='When Devicehub created this.'), sa.Column('id', sa.BigInteger(), nullable=False), sa.Column('expired', sa.BigInteger(), nullable=True), sa.Column('token', postgresql.UUID(as_uuid=True), nullable=False), @@ -45,9 +52,11 @@ def upgrade(): ) op.create_index(op.f('ix_session_created'), 'session', ['created'], unique=False, schema='common') op.create_index(op.f('ix_session_updated'), 'session', ['updated'], unique=False, schema='common') + op.create_index(op.f('ix_session_token'), 'session', ['token'], unique=True, schema='common') def downgrade(): op.drop_table('trade', schema=f'{get_inv()}') op.drop_index(op.f('ix_session_created'), table_name='session', schema='common') op.drop_index(op.f('ix_session_updated'), table_name='session', schema='common') + op.drop_index(op.f('ix_session_token'), table_name='session', schema='common') diff --git a/ereuse_devicehub/resources/user/models.py b/ereuse_devicehub/resources/user/models.py index 324ee851..5923e35b 100644 --- a/ereuse_devicehub/resources/user/models.py +++ b/ereuse_devicehub/resources/user/models.py @@ -67,3 +67,9 @@ class Session(Thing): token = Column(UUID(as_uuid=True), default=uuid4, unique=True, nullable=False) type = Column(IntEnum(SessionType), default=SessionType.Internal, nullable=False) user_id = db.Column(db.UUID(as_uuid=True), db.ForeignKey(User.id)) + user = db.relationship(User, + backref=db.backref('sessions', lazy=True, collection_class=set), + collection_class=set) + + def __str__(self) -> str: + return '{0.token}'.format(self) From e1f8f89a9bbfd608fe7c24566c1aa3b6c9fff438 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 15 Apr 2021 21:19:20 +0200 Subject: [PATCH 21/52] fixing auth for token --- ereuse_devicehub/auth.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ereuse_devicehub/auth.py b/ereuse_devicehub/auth.py index 5820c326..19f6e5fa 100644 --- a/ereuse_devicehub/auth.py +++ b/ereuse_devicehub/auth.py @@ -3,12 +3,17 @@ from teal.auth import TokenAuth from teal.db import ResourceNotFound from werkzeug.exceptions import Unauthorized -from ereuse_devicehub.resources.user.models import User +from ereuse_devicehub.resources.user.models import User, Session class Auth(TokenAuth): def authenticate(self, token: str, *args, **kw) -> User: try: - return User.query.filter_by(token=token).one() + user = User.query.filter_by(token=token).first() + if user: + return user + + ses = Session.query.filter_by(token=token).one() + return ses.user except (ResourceNotFound, DataError): raise Unauthorized('Provide a suitable token.') From 3f423e771253a64440772768b7854a4989698f16 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 15 Apr 2021 21:20:08 +0200 Subject: [PATCH 22/52] drop schema users for view --- ereuse_devicehub/resources/user/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ereuse_devicehub/resources/user/views.py b/ereuse_devicehub/resources/user/views.py index e6376f3c..b9638e24 100644 --- a/ereuse_devicehub/resources/user/views.py +++ b/ereuse_devicehub/resources/user/views.py @@ -7,7 +7,6 @@ from teal.resource import View from ereuse_devicehub.db import db from ereuse_devicehub.resources.user.exceptions import WrongCredentials from ereuse_devicehub.resources.user.models import User -from ereuse_devicehub.resources.user.schemas import User as UserS class UserView(View): From 70188f43a2cfd83ca42852b171483ce963ed11a5 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 15 Apr 2021 21:21:41 +0200 Subject: [PATCH 23/52] simplify get_token method --- .../resources/documents/documents.py | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 7175ab06..8796efa6 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -19,8 +19,8 @@ from flask.json import jsonify from teal.cache import cache from teal.resource import Resource, View +from ereuse_devicehub import auth from ereuse_devicehub.db import db -from ereuse_devicehub.resources.user.models import Session from ereuse_devicehub.resources.enums import SessionType from ereuse_devicehub.resources.action import models as evs from ereuse_devicehub.resources.device import models as devs @@ -339,26 +339,9 @@ class WbConfDocumentView(DeviceView): return output def get_token(self): - internal_session = Session.query.filter_by(user_id=g.user.id, - type=SessionType.Internal).first() - if not internal_session: - internal_session = Session(user_id=g.user.id, type=SessionType.Internal) - db.session.add(internal_session) - - db.session.commit() - return internal_session.token - - # TODO @cayop for when in others iterations we need implement external token - # external_session = Session.query.filter_by(user_id=g.user.id, - # type=SessionType.Internal).first() - # if not external_session: - # external_session = Session(user_id=g.user.id, type=SessionType.External) - # external_session = Session(user_id=g.user.id, type=SessionType.External) - # db.session.add(external_session) - - # db.session.commit() - - # return external_session.token + tk = [s.token for s in g.user.sessions if s.type == SessionType.Internal][0] + token = auth.Auth.encode(tk) + return token class DocumentDef(Resource): From 7836f2fc8d9a9414e8834d80b8337ba5df008af5 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 15 Apr 2021 21:23:02 +0200 Subject: [PATCH 24/52] drop pdbs --- tests/test_action.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_action.py b/tests/test_action.py index 2f0a1ea4..01d824ec 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -750,7 +750,6 @@ def test_deallocate_bad_dates(user: UserClient): def test_trade(action_model_state: Tuple[Type[models.Action], states.Trading], user: UserClient): """Tests POSTing all Trade actions.""" # todo missing None states.Trading for after cancelling renting, for example - # import pdb; pdb.set_trace() # Remove this test action_model, state = action_model_state snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) From 68ffa0ddffeb027863a9a9e1ff379bcd5e5d8b84 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 16 Apr 2021 11:14:36 +0200 Subject: [PATCH 25/52] fixing tests --- tests/files/basic.csv | 2 +- tests/files/proposal_extended_csv_report.csv | 6 +++--- tests/test_action.py | 10 +++++----- tests/test_documents.py | 1 + tests/test_snapshot.py | 5 +++-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/files/basic.csv b/tests/files/basic.csv index c4962b4d..5255cd97 100644 --- a/tests/files/basic.csv +++ b/tests/files/basic.csv @@ -1,2 +1,2 @@ System ID;DocumentID;Public Link;Tag 1 Type;Tag 1 ID;Tag 1 Organization;Tag 2 Type;Tag 2 ID;Tag 2 Organization;Tag 3 Type;Tag 3 ID;Tag 3 Organization;Device Hardware ID;Device Type;Device Chassis;Device Serial Number;Device Model;Device Manufacturer;Registered in;Registered (process);Updated in (software);Updated in (web);Physical state;Trading state;Processor;RAM (MB);Data Storage Size (MB);Processor 1;Processor 1 Manufacturer;Processor 1 Model;Processor 1 Serial Number;Processor 1 Number of cores;Processor 1 Speed (GHz);Benchmark Processor 1 (points);Benchmark ProcessorSysbench Processor 1 (points);Processor 2;Processor 2 Manufacturer;Processor 2 Model;Processor 2 Serial Number;Processor 2 Number of cores;Processor 2 Speed (GHz);Benchmark Processor 2 (points);Benchmark ProcessorSysbench Processor 2 (points);RamModule 1;RamModule 1 Manufacturer;RamModule 1 Model;RamModule 1 Serial Number;RamModule 1 Size (MB);RamModule 1 Speed (MHz);RamModule 2;RamModule 2 Manufacturer;RamModule 2 Model;RamModule 2 Serial Number;RamModule 2 Size (MB);RamModule 2 Speed (MHz);RamModule 3;RamModule 3 Manufacturer;RamModule 3 Model;RamModule 3 Serial Number;RamModule 3 Size (MB);RamModule 3 Speed (MHz);RamModule 4;RamModule 4 Manufacturer;RamModule 4 Model;RamModule 4 Serial Number;RamModule 4 Size (MB);RamModule 4 Speed (MHz);DataStorage 1;DataStorage 1 Manufacturer;DataStorage 1 Model;DataStorage 1 Serial Number;DataStorage 1 Size (MB);Erasure DataStorage 1;Erasure DataStorage 1 Serial Number;Erasure DataStorage 1 Size (MB);Erasure DataStorage 1 Software;Erasure DataStorage 1 Result;Erasure DataStorage 1 Type;Erasure DataStorage 1 Method;Erasure DataStorage 1 Elapsed (hours);Erasure DataStorage 1 Date;Erasure DataStorage 1 Steps;Erasure DataStorage 1 Steps Start Time;Erasure DataStorage 1 Steps End Time;Benchmark DataStorage 1 Read Speed (MB/s);Benchmark DataStorage 1 Writing speed (MB/s);Test DataStorage 1 Software;Test DataStorage 1 Type;Test DataStorage 1 Result;Test DataStorage 1 Power on (hours used);Test DataStorage 1 Lifetime remaining (percentage);DataStorage 2;DataStorage 2 Manufacturer;DataStorage 2 Model;DataStorage 2 Serial Number;DataStorage 2 Size (MB);Erasure DataStorage 2;Erasure DataStorage 2 Serial Number;Erasure DataStorage 2 Size (MB);Erasure DataStorage 2 Software;Erasure DataStorage 2 Result;Erasure DataStorage 2 Type;Erasure DataStorage 2 Method;Erasure DataStorage 2 Elapsed (hours);Erasure DataStorage 2 Date;Erasure DataStorage 2 Steps;Erasure DataStorage 2 Steps Start Time;Erasure DataStorage 2 Steps End Time;Benchmark DataStorage 2 Read Speed (MB/s);Benchmark DataStorage 2 Writing speed (MB/s);Test DataStorage 2 Software;Test DataStorage 2 Type;Test DataStorage 2 Result;Test DataStorage 2 Power on (hours used);Test DataStorage 2 Lifetime remaining (percentage);DataStorage 3;DataStorage 3 Manufacturer;DataStorage 3 Model;DataStorage 3 Serial Number;DataStorage 3 Size (MB);Erasure DataStorage 3;Erasure DataStorage 3 Serial Number;Erasure DataStorage 3 Size (MB);Erasure DataStorage 3 Software;Erasure DataStorage 3 Result;Erasure DataStorage 3 Type;Erasure DataStorage 3 Method;Erasure DataStorage 3 Elapsed (hours);Erasure DataStorage 3 Date;Erasure DataStorage 3 Steps;Erasure DataStorage 3 Steps Start Time;Erasure DataStorage 3 Steps End Time;Benchmark DataStorage 3 Read Speed (MB/s);Benchmark DataStorage 3 Writing speed (MB/s);Test DataStorage 3 Software;Test DataStorage 3 Type;Test DataStorage 3 Result;Test DataStorage 3 Power on (hours used);Test DataStorage 3 Lifetime remaining (percentage);DataStorage 4;DataStorage 4 Manufacturer;DataStorage 4 Model;DataStorage 4 Serial Number;DataStorage 4 Size (MB);Erasure DataStorage 4;Erasure DataStorage 4 Serial Number;Erasure DataStorage 4 Size (MB);Erasure DataStorage 4 Software;Erasure DataStorage 4 Result;Erasure DataStorage 4 Type;Erasure DataStorage 4 Method;Erasure DataStorage 4 Elapsed (hours);Erasure DataStorage 4 Date;Erasure DataStorage 4 Steps;Erasure DataStorage 4 Steps Start Time;Erasure DataStorage 4 Steps End Time;Benchmark DataStorage 4 Read Speed (MB/s);Benchmark DataStorage 4 Writing speed (MB/s);Test DataStorage 4 Software;Test DataStorage 4 Type;Test DataStorage 4 Result;Test DataStorage 4 Power on (hours used);Test DataStorage 4 Lifetime remaining (percentage);Motherboard 1;Motherboard 1 Manufacturer;Motherboard 1 Model;Motherboard 1 Serial Number;Display 1;Display 1 Manufacturer;Display 1 Model;Display 1 Serial Number;GraphicCard 1;GraphicCard 1 Manufacturer;GraphicCard 1 Model;GraphicCard 1 Serial Number;GraphicCard 1 Memory (MB);GraphicCard 2;GraphicCard 2 Manufacturer;GraphicCard 2 Model;GraphicCard 2 Serial Number;GraphicCard 2 Memory (MB);NetworkAdapter 1;NetworkAdapter 1 Manufacturer;NetworkAdapter 1 Model;NetworkAdapter 1 Serial Number;NetworkAdapter 2;NetworkAdapter 2 Manufacturer;NetworkAdapter 2 Model;NetworkAdapter 2 Serial Number;SoundCard 1;SoundCard 1 Manufacturer;SoundCard 1 Model;SoundCard 1 Serial Number;SoundCard 2;SoundCard 2 Manufacturer;SoundCard 2 Model;SoundCard 2 Serial Number;Device Rate;Device Range;Processor Rate;Processor Range;RAM Rate;RAM Range;Data Storage Rate;Data Storage Range;Price;Benchmark RamSysbench (points) -1;;http://localhost/devices/1;;;;;;;;;;desktop-d1mr-d1ml-d1s;Desktop;Microtower;d1s;d1ml;d1mr;Thu Oct 22 15:36:47 2020;Workbench 11.0;2020-10-22 15:36:47.814316+02:00;;;;p1ml;0;0;Processor 4: model p1ml, S/N p1s;p1mr;p1ml;p1s;;1.6;2410.0;;;;;;;;;;RamModule 3: model rm1ml, S/N rm1s;rm1mr;rm1ml;rm1s;;1333;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GraphicCard 2: model gc1ml, S/N gc1s;gc1mr;gc1ml;gc1s;;;;;;;;;;;;;;;;;;;;;;;1.0;VERY_LOW;1.0;VERY_LOW;1.0;VERY_LOW;1.0;VERY_LOW;; +3;;http://localhost/devices/3;;;;;;;;;;desktop-d1mr-d1ml-d1s;Desktop;Microtower;d1s;d1ml;d1mr;Fri Apr 16 10:34:18 2021;Workbench 11.0;2021-04-16 10:34:18.540027+02:00;;;;p1ml;0;0;Processor 6: model p1ml, S/N p1s;p1mr;p1ml;p1s;;1.6;2410.0;;;;;;;;;;RamModule 5: model rm1ml, S/N rm1s;rm1mr;rm1ml;rm1s;;1333;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GraphicCard 4: model gc1ml, S/N gc1s;gc1mr;gc1ml;gc1s;;;;;;;;;;;;;;;;;;;;;;;1.0;VERY_LOW;1.0;VERY_LOW;1.0;VERY_LOW;1.0;VERY_LOW;; diff --git a/tests/files/proposal_extended_csv_report.csv b/tests/files/proposal_extended_csv_report.csv index cf1e88a7..3d0356bd 100644 --- a/tests/files/proposal_extended_csv_report.csv +++ b/tests/files/proposal_extended_csv_report.csv @@ -1,3 +1,3 @@ -System ID;DocumentID;Public Link;Tag 1 Type;Tag 1 ID;Tag 1 Organization;Tag 2 Type;Tag 2 ID;Tag 2 Organization;Tag 3 Type;Tag 3 ID;Tag 3 Organization;Device Hardware ID;Device Type;Device Chassis;Device Serial Number;Device Model;Device Manufacturer;Registered in;Registered (process);Updated in (software);Updated in (web);Physical state;Trading state;Processor;RAM (MB);Data Storage Size (MB);Processor 1;Processor 1 Manufacturer;Processor 1 Model;Processor 1 Serial Number;Processor 1 Number of cores;Processor 1 Speed (GHz);Benchmark Processor 1 (points);Benchmark ProcessorSysbench Processor 1 (points);Processor 2;Processor 2 Manufacturer;Processor 2 Model;Processor 2 Serial Number;Processor 2 Number of cores;Processor 2 Speed (GHz);Benchmark Processor 2 (points);Benchmark ProcessorSysbench Processor 2 (points);RamModule 1;RamModule 1 Manufacturer;RamModule 1 Model;RamModule 1 Serial Number;RamModule 1 Size (MB);RamModule 1 Speed (MHz);RamModule 2;RamModule 2 Manufacturer;RamModule 2 Model;RamModule 2 Serial Number;RamModule 2 Size (MB);RamModule 2 Speed (MHz);RamModule 3;RamModule 3 Manufacturer;RamModule 3 Model;RamModule 3 Serial Number;RamModule 3 Size (MB);RamModule 3 Speed (MHz);RamModule 4;RamModule 4 Manufacturer;RamModule 4 Model;RamModule 4 Serial Number;RamModule 4 Size (MB);RamModule 4 Speed (MHz);DataStorage 1;DataStorage 1 Manufacturer;DataStorage 1 Model;DataStorage 1 Serial Number;DataStorage 1 Size (MB);Erasure DataStorage 1;Erasure DataStorage 1 Serial Number;Erasure DataStorage 1 Size (MB);Erasure DataStorage 1 Software;Erasure DataStorage 1 Result;Erasure DataStorage 1 Type;Erasure DataStorage 1 Method;Erasure DataStorage 1 Elapsed (hours);Erasure DataStorage 1 Date;Erasure DataStorage 1 Steps;Erasure DataStorage 1 Steps Start Time;Erasure DataStorage 1 Steps End Time;Benchmark DataStorage 1 Read Speed (MB/s);Benchmark DataStorage 1 Writing speed (MB/s);Test DataStorage 1 Software;Test DataStorage 1 Type;Test DataStorage 1 Result;Test DataStorage 1 Power on (hours used);Test DataStorage 1 Lifetime remaining (percentage);DataStorage 2;DataStorage 2 Manufacturer;DataStorage 2 Model;DataStorage 2 Serial Number;DataStorage 2 Size (MB);Erasure DataStorage 2;Erasure DataStorage 2 Serial Number;Erasure DataStorage 2 Size (MB);Erasure DataStorage 2 Software;Erasure DataStorage 2 Result;Erasure DataStorage 2 Type;Erasure DataStorage 2 Method;Erasure DataStorage 2 Elapsed (hours);Erasure DataStorage 2 Date;Erasure DataStorage 2 Steps;Erasure DataStorage 2 Steps Start Time;Erasure DataStorage 2 Steps End Time;Benchmark DataStorage 2 Read Speed (MB/s);Benchmark DataStorage 2 Writing speed (MB/s);Test DataStorage 2 Software;Test DataStorage 2 Type;Test DataStorage 2 Result;Test DataStorage 2 Power on (hours used);Test DataStorage 2 Lifetime remaining (percentage);DataStorage 3;DataStorage 3 Manufacturer;DataStorage 3 Model;DataStorage 3 Serial Number;DataStorage 3 Size (MB);Erasure DataStorage 3;Erasure DataStorage 3 Serial Number;Erasure DataStorage 3 Size (MB);Erasure DataStorage 3 Software;Erasure DataStorage 3 Result;Erasure DataStorage 3 Type;Erasure DataStorage 3 Method;Erasure DataStorage 3 Elapsed (hours);Erasure DataStorage 3 Date;Erasure DataStorage 3 Steps;Erasure DataStorage 3 Steps Start Time;Erasure DataStorage 3 Steps End Time;Benchmark DataStorage 3 Read Speed (MB/s);Benchmark DataStorage 3 Writing speed (MB/s);Test DataStorage 3 Software;Test DataStorage 3 Type;Test DataStorage 3 Result;Test DataStorage 3 Power on (hours used);Test DataStorage 3 Lifetime remaining (percentage);DataStorage 4;DataStorage 4 Manufacturer;DataStorage 4 Model;DataStorage 4 Serial Number;DataStorage 4 Size (MB);Erasure DataStorage 4;Erasure DataStorage 4 Serial Number;Erasure DataStorage 4 Size (MB);Erasure DataStorage 4 Software;Erasure DataStorage 4 Result;Erasure DataStorage 4 Type;Erasure DataStorage 4 Method;Erasure DataStorage 4 Elapsed (hours);Erasure DataStorage 4 Date;Erasure DataStorage 4 Steps;Erasure DataStorage 4 Steps Start Time;Erasure DataStorage 4 Steps End Time;Benchmark DataStorage 4 Read Speed (MB/s);Benchmark DataStorage 4 Writing speed (MB/s);Test DataStorage 4 Software;Test DataStorage 4 Type;Test DataStorage 4 Result;Test DataStorage 4 Power on (hours used);Test DataStorage 4 Lifetime remaining (percentage);Motherboard 1;Motherboard 1 Manufacturer;Motherboard 1 Model;Motherboard 1 Serial Number;Display 1;Display 1 Manufacturer;Display 1 Model;Display 1 Serial Number;GraphicCard 1;GraphicCard 1 Manufacturer;GraphicCard 1 Model;GraphicCard 1 Serial Number;GraphicCard 1 Memory (MB);GraphicCard 2;GraphicCard 2 Manufacturer;GraphicCard 2 Model;GraphicCard 2 Serial Number;GraphicCard 2 Memory (MB);NetworkAdapter 1;NetworkAdapter 1 Manufacturer;NetworkAdapter 1 Model;NetworkAdapter 1 Serial Number;NetworkAdapter 2;NetworkAdapter 2 Manufacturer;NetworkAdapter 2 Model;NetworkAdapter 2 Serial Number;SoundCard 1;SoundCard 1 Manufacturer;SoundCard 1 Model;SoundCard 1 Serial Number;SoundCard 2;SoundCard 2 Manufacturer;SoundCard 2 Model;SoundCard 2 Serial Number;Device Rate;Device Range;Processor Rate;Processor Range;RAM Rate;RAM Range;Data Storage Rate;Data Storage Range;Price;Benchmark RamSysbench (points) -1;;http://localhost/devices/1;named;foo;FooOrg;;;;;;;laptop-asustek_computer_inc-1001pxd-b8oaas048285-14:da:e9:42:f6:7b;Laptop;Netbook;b8oaas048285;1001pxd;asustek computer inc.;Thu Nov 12 19:53:01 2020;Workbench 11.0a2;2020-11-12 19:54:03.959185+01:00;;;;intel atom cpu n455 @ 2.66ghz;1024;238475;Processor 4: model intel atom cpu n455 @ 2.66ghz, S/N None;intel corp.;intel atom cpu n455 @ 2.66ghz;;1;2.667;6666.24;164.0803;;;;;;;;;RamModule 8: model None, S/N None;;;;1024;667;;;;;;;;;;;;;;;;;;;HardDrive 9: model hts54322, S/N e2024242cv86mm;hitachi;hts54322;e2024242cv86mm;238475;harddrive-hitachi-hts54322-e2024242cv86mm;e2024242cv86mm;238475;Workbench 11.0a2;Success;EraseBasic;Shred;1:16:49;2020-11-12 19:53:01.899092+01:00;✓ – StepRandom 1:16:49;2018-07-03 11:15:22.257059+02:00;2018-07-03 12:32:11.843190+02:00;66.2;21.8;Workbench 11.0a2;Short;Failure;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Motherboard 10: model 1001pxd, S/N eee0123456720;asustek computer inc.;1001pxd;eee0123456720;;;;;GraphicCard 5: model atom processor d4xx/d5xx/n4xx/n5xx integrated graphics controller, S/N None;intel corporation;atom processor d4xx/d5xx/n4xx/n5xx integrated graphics controller;;256;;;;;;NetworkAdapter 2: model ar9285 wireless network adapter, S/N 74:2f:68:8b:fd:c9;qualcomm atheros;ar9285 wireless network adapter;74:2f:68:8b:fd:c9;NetworkAdapter 3: model ar8152 v2.0 fast ethernet, S/N 14:da:e9:42:f6:7b;qualcomm atheros;ar8152 v2.0 fast ethernet;14:da:e9:42:f6:7b;SoundCard 6: model nm10/ich7 family high definition audio controller, S/N None;intel corporation;nm10/ich7 family high definition audio controller;;;;;;1.75;LOW;1.55;LOW;1.53;LOW;3.76;HIGH;52.50 €;15.7188 -11;;http://localhost/devices/11;;;;;;;;;;laptop-asustek_computer_inc-1001pxd-b8oaas048287-14:da:e9:42:f6:7c;Laptop;Netbook;b8oaas048287;1001pxd;asustek computer inc.;Thu Nov 12 19:53:02 2020;Workbench 11.0b11;2020-11-12 19:53:02.225373+01:00;;;;intel atom cpu n455 @ 1.66ghz;2048;558558;Processor 15: model intel atom cpu n455 @ 1.66ghz, S/N None;intel corp.;intel atom cpu n455 @ 1.66ghz;;1;1.667;6666.24;164.0803;;;;;;;;;RamModule 18: model None, S/N None;;;;1024;667;RamModule 19: model 48594d503131325336344350362d53362020, S/N 4f43487b;hynix semiconductor;48594d503131325336344350362d53362020;4f43487b;1024;667;;;;;;;;;;;;;HardDrive 20: model hts54322, S/N e2024242cv86hj;hitachi;hts54322;e2024242cv86hj;238475;harddrive-hitachi-hts54322-e2024242cv86hj;e2024242cv86hj;238475;Workbench 11.0b11;Success;EraseBasic;Shred;1:16:49;2020-11-12 19:53:02.175189+01:00;✓ – StepRandom 1:16:49;2018-07-03 11:15:22.257059+02:00;2018-07-03 12:32:11.843190+02:00;66.2;21.8;Workbench 11.0b11;Extended;Failure;;;DataStorage 21: model wdc wd1600bevt-2, S/N wd-wx11a80w7430;western digital;wdc wd1600bevt-2;wd-wx11a80w7430;160041;datastorage-western_digital-wdc_wd1600bevt-2-wd-wx11a80w7430;wd-wx11a80w7430;160041;Workbench 11.0b11;Failure;EraseBasic;Shred;0:45:36;2020-11-12 19:53:02.176882+01:00;✓ – StepRandom 0:45:36;2019-10-23 09:49:54.410830+02:00;2019-10-23 10:35:31.400587+02:00;41.6;17.3;Workbench 11.0b11;Short;Success;5293;195 days, 12:00:00;SolidStateDrive 22: model wdc wd1600bevt-2, S/N wd-wx11a80w7430;western digital;wdc wd1600bevt-2;wd-wx11a80w7430;160042;solidstatedrive-western_digital-wdc_wd1600bevt-2-wd-wx11a80w7430;wd-wx11a80w7430;160042;Workbench 11.0b11;Success;EraseSectors;Badblocks;1:46:03;2020-11-12 19:53:02.180043+01:00;✓ – StepRandom 0:46:03,✓ – StepZero 1:00:00;2019-08-19 18:48:19.690458+02:00,2019-08-19 19:34:22.690458+02:00;2019-08-19 19:34:22.930562+02:00,2019-08-19 20:34:22.930562+02:00;41.1;17.1;Workbench 11.0b11;Short;Success;5231;194 days, 17:00:00;;;;;;;;;;;;;;;;;;;;;;;;;Motherboard 23: model 1001pxd, S/N eee0123456789;asustek computer inc.;1001pxd;eee0123456789;;"auo ""auo""";auo lcd monitor;;GraphicCard 16: model atom processor d4xx/d5xx/n4xx/n5xx integrated graphics controller, S/N None;intel corporation;atom processor d4xx/d5xx/n4xx/n5xx integrated graphics controller;;256;;;;;;NetworkAdapter 13: model ar9285 wireless network adapter, S/N 74:2f:68:8b:fd:c8;qualcomm atheros;ar9285 wireless network adapter;74:2f:68:8b:fd:c8;NetworkAdapter 14: model ar8152 v2.0 fast ethernet, S/N 14:da:e9:42:f6:7c;qualcomm atheros;ar8152 v2.0 fast ethernet;14:da:e9:42:f6:7c;SoundCard 7: model usb 2.0 uvc vga webcam, S/N 0x0001;azurewave;usb 2.0 uvc vga webcam;0x0001;SoundCard 17: model nm10/ich7 family high definition audio controller, S/N None;intel corporation;nm10/ich7 family high definition audio controller;;1.72;LOW;1.31;LOW;1.99;LOW;3.97;HIGH;51.60 €;15.7188 +System ID;DocumentID;Public Link;Tag 1 Type;Tag 1 ID;Tag 1 Organization;Tag 2 Type;Tag 2 ID;Tag 2 Organization;Tag 3 Type;Tag 3 ID;Tag 3 Organization;Device Hardware ID;Device Type;Device Chassis;Device Serial Number;Device Model;Device Manufacturer;Registered in;Registered (process);Updated in (software);Updated in (web);Physical state;Trading state;Processor;RAM (MB);Data Storage Size (MB);Processor 1;Processor 1 Manufacturer;Processor 1 Model;Processor 1 Serial Number;Processor 1 Number of cores;Processor 1 Speed (GHz);Benchmark Processor 1 (points);Benchmark ProcessorSysbench Processor 1 (points);Processor 2;Processor 2 Manufacturer;Processor 2 Model;Processor 2 Serial Number;Processor 2 Number of cores;Processor 2 Speed (GHz);Benchmark Processor 2 (points);Benchmark ProcessorSysbench Processor 2 (points);RamModule 1;RamModule 1 Manufacturer;RamModule 1 Model;RamModule 1 Serial Number;RamModule 1 Size (MB);RamModule 1 Speed (MHz);RamModule 2;RamModule 2 Manufacturer;RamModule 2 Model;RamModule 2 Serial Number;RamModule 2 Size (MB);RamModule 2 Speed (MHz);RamModule 3;RamModule 3 Manufacturer;RamModule 3 Model;RamModule 3 Serial Number;RamModule 3 Size (MB);RamModule 3 Speed (MHz);RamModule 4;RamModule 4 Manufacturer;RamModule 4 Model;RamModule 4 Serial Number;RamModule 4 Size (MB);RamModule 4 Speed (MHz);DataStorage 1;DataStorage 1 Manufacturer;DataStorage 1 Model;DataStorage 1 Serial Number;DataStorage 1 Size (MB);Erasure DataStorage 1;Erasure DataStorage 1 Serial Number;Erasure DataStorage 1 Size (MB);Erasure DataStorage 1 Software;Erasure DataStorage 1 Result;Erasure DataStorage 1 Type;Erasure DataStorage 1 Method;Erasure DataStorage 1 Elapsed (hours);Erasure DataStorage 1 Date;Erasure DataStorage 1 Steps;Erasure DataStorage 1 Steps Start Time;Erasure DataStorage 1 Steps End Time;Benchmark DataStorage 1 Read Speed (MB/s);Benchmark DataStorage 1 Writing speed (MB/s);Test DataStorage 1 Software;Test DataStorage 1 Type;Test DataStorage 1 Result;Test DataStorage 1 Power on (hours used);Test DataStorage 1 Lifetime remaining (percentage);DataStorage 2;DataStorage 2 Manufacturer;DataStorage 2 Model;DataStorage 2 Serial Number;DataStorage 2 Size (MB);Erasure DataStorage 2;Erasure DataStorage 2 Serial Number;Erasure DataStorage 2 Size (MB);Erasure DataStorage 2 Software;Erasure DataStorage 2 Result;Erasure DataStorage 2 Type;Erasure DataStorage 2 Method;Erasure DataStorage 2 Elapsed (hours);Erasure DataStorage 2 Date;Erasure DataStorage 2 Steps;Erasure DataStorage 2 Steps Start Time;Erasure DataStorage 2 Steps End Time;Benchmark DataStorage 2 Read Speed (MB/s);Benchmark DataStorage 2 Writing speed (MB/s);Test DataStorage 2 Software;Test DataStorage 2 Type;Test DataStorage 2 Result;Test DataStorage 2 Power on (hours used);Test DataStorage 2 Lifetime remaining (percentage);DataStorage 3;DataStorage 3 Manufacturer;DataStorage 3 Model;DataStorage 3 Serial Number;DataStorage 3 Size (MB);Erasure DataStorage 3;Erasure DataStorage 3 Serial Number;Erasure DataStorage 3 Size (MB);Erasure DataStorage 3 Software;Erasure DataStorage 3 Result;Erasure DataStorage 3 Type;Erasure DataStorage 3 Method;Erasure DataStorage 3 Elapsed (hours);Erasure DataStorage 3 Date;Erasure DataStorage 3 Steps;Erasure DataStorage 3 Steps Start Time;Erasure DataStorage 3 Steps End Time;Benchmark DataStorage 3 Read Speed (MB/s);Benchmark DataStorage 3 Writing speed (MB/s);Test DataStorage 3 Software;Test DataStorage 3 Type;Test DataStorage 3 Result;Test DataStorage 3 Power on (hours used);Test DataStorage 3 Lifetime remaining (percentage);DataStorage 4;DataStorage 4 Manufacturer;DataStorage 4 Model;DataStorage 4 Serial Number;DataStorage 4 Size (MB);Erasure DataStorage 4;Erasure DataStorage 4 Serial Number;Erasure DataStorage 4 Size (MB);Erasure DataStorage 4 Software;Erasure DataStorage 4 Result;Erasure DataStorage 4 Type;Erasure DataStorage 4 Method;Erasure DataStorage 4 Elapsed (hours);Erasure DataStorage 4 Date;Erasure DataStorage 4 Steps;Erasure DataStorage 4 Steps Start Time;Erasure DataStorage 4 Steps End Time;Benchmark DataStorage 4 Read Speed (MB/s);Benchmark DataStorage 4 Writing speed (MB/s);Test DataStorage 4 Software;Test DataStorage 4 Type;Test DataStorage 4 Result;Test DataStorage 4 Power on (hours used);Test DataStorage 4 Lifetime remaining (percentage);Motherboard 1;Motherboard 1 Manufacturer;Motherboard 1 Model;Motherboard 1 Serial Number;Display 1;Display 1 Manufacturer;Display 1 Model;Display 1 Serial Number;GraphicCard 1;GraphicCard 1 Manufacturer;GraphicCard 1 Model;GraphicCard 1 Serial Number;GraphicCard 1 Memory (MB);GraphicCard 2;GraphicCard 2 Manufacturer;GraphicCard 2 Model;GraphicCard 2 Serial Number;GraphicCard 2 Memory (MB);NetworkAdapter 1;NetworkAdapter 1 Manufacturer;NetworkAdapter 1 Model;NetworkAdapter 1 Serial Number;NetworkAdapter 2;NetworkAdapter 2 Manufacturer;NetworkAdapter 2 Model;NetworkAdapter 2 Serial Number;SoundCard 1;SoundCard 1 Manufacturer;SoundCard 1 Model;SoundCard 1 Serial Number;SoundCard 2;SoundCard 2 Manufacturer;SoundCard 2 Model;SoundCard 2 Serial Number;Device Rate;Device Range;Processor Rate;Processor Range;RAM Rate;RAM Range;Data Storage Rate;Data Storage Range;Price;Benchmark RamSysbench (points) +3;;http://localhost/devices/3;named;foo;FooOrg;;;;;;;laptop-asustek_computer_inc-1001pxd-b8oaas048285-14:da:e9:42:f6:7b;Laptop;Netbook;b8oaas048285;1001pxd;asustek computer inc.;Fri Apr 16 10:42:21 2021;Workbench 11.0a2;2021-04-16 10:42:21.737031+02:00;;;;intel atom cpu n455 @ 2.66ghz;1024;238475;Processor 6: model intel atom cpu n455 @ 2.66ghz, S/N None;intel corp.;intel atom cpu n455 @ 2.66ghz;;1;2.667;6666.24;164.0803;;;;;;;;;RamModule 10: model None, S/N None;;;;1024;667;;;;;;;;;;;;;;;;;;;HardDrive 11: model hts54322, S/N e2024242cv86mm;hitachi;hts54322;e2024242cv86mm;238475;harddrive-hitachi-hts54322-e2024242cv86mm;e2024242cv86mm;238475;Workbench 11.0a2;Success;EraseBasic;Shred;1:16:49;2021-04-16 10:42:21.171908+02:00;✓ – StepRandom 1:16:49;2018-07-03 11:15:22.257059+02:00;2018-07-03 12:32:11.843190+02:00;66.2;21.8;Workbench 11.0a2;Short;Failure;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Motherboard 12: model 1001pxd, S/N eee0123456720;asustek computer inc.;1001pxd;eee0123456720;;;;;GraphicCard 7: model atom processor d4xx/d5xx/n4xx/n5xx integrated graphics controller, S/N None;intel corporation;atom processor d4xx/d5xx/n4xx/n5xx integrated graphics controller;;256;;;;;;NetworkAdapter 4: model ar9285 wireless network adapter, S/N 74:2f:68:8b:fd:c9;qualcomm atheros;ar9285 wireless network adapter;74:2f:68:8b:fd:c9;NetworkAdapter 5: model ar8152 v2.0 fast ethernet, S/N 14:da:e9:42:f6:7b;qualcomm atheros;ar8152 v2.0 fast ethernet;14:da:e9:42:f6:7b;SoundCard 8: model nm10/ich7 family high definition audio controller, S/N None;intel corporation;nm10/ich7 family high definition audio controller;;;;;;1.75;LOW;1.55;LOW;1.53;LOW;3.76;HIGH;52.50 €;15.7188 +13;;http://localhost/devices/13;;;;;;;;;;laptop-asustek_computer_inc-1001pxd-b8oaas048287-14:da:e9:42:f6:7c;Laptop;Netbook;b8oaas048287;1001pxd;asustek computer inc.;Fri Apr 16 10:42:21 2021;Workbench 11.0b11;2021-04-16 10:42:21.565046+02:00;;;;intel atom cpu n455 @ 1.66ghz;2048;558558;Processor 17: model intel atom cpu n455 @ 1.66ghz, S/N None;intel corp.;intel atom cpu n455 @ 1.66ghz;;1;1.667;6666.24;164.0803;;;;;;;;;RamModule 20: model None, S/N None;;;;1024;667;RamModule 21: model 48594d503131325336344350362d53362020, S/N 4f43487b;hynix semiconductor;48594d503131325336344350362d53362020;4f43487b;1024;667;;;;;;;;;;;;;HardDrive 22: model hts54322, S/N e2024242cv86hj;hitachi;hts54322;e2024242cv86hj;238475;harddrive-hitachi-hts54322-e2024242cv86hj;e2024242cv86hj;238475;Workbench 11.0b11;Success;EraseBasic;Shred;1:16:49;2021-04-16 10:42:21.496034+02:00;✓ – StepRandom 1:16:49;2018-07-03 11:15:22.257059+02:00;2018-07-03 12:32:11.843190+02:00;66.2;21.8;Workbench 11.0b11;Extended;Failure;;;DataStorage 23: model wdc wd1600bevt-2, S/N wd-wx11a80w7430;western digital;wdc wd1600bevt-2;wd-wx11a80w7430;160041;datastorage-western_digital-wdc_wd1600bevt-2-wd-wx11a80w7430;wd-wx11a80w7430;160041;Workbench 11.0b11;Failure;EraseBasic;Shred;0:45:36;2021-04-16 10:42:21.498207+02:00;✓ – StepRandom 0:45:36;2019-10-23 09:49:54.410830+02:00;2019-10-23 10:35:31.400587+02:00;41.6;17.3;Workbench 11.0b11;Short;Success;5293;195 days, 12:00:00;SolidStateDrive 24: model wdc wd1600bevt-2, S/N wd-wx11a80w7430;western digital;wdc wd1600bevt-2;wd-wx11a80w7430;160042;solidstatedrive-western_digital-wdc_wd1600bevt-2-wd-wx11a80w7430;wd-wx11a80w7430;160042;Workbench 11.0b11;Success;EraseSectors;Badblocks;1:46:03;2021-04-16 10:42:21.503229+02:00;✓ – StepRandom 0:46:03,✓ – StepZero 1:00:00;2019-08-19 18:48:19.690458+02:00,2019-08-19 19:34:22.690458+02:00;2019-08-19 19:34:22.930562+02:00,2019-08-19 20:34:22.930562+02:00;41.1;17.1;Workbench 11.0b11;Short;Success;5231;194 days, 17:00:00;;;;;;;;;;;;;;;;;;;;;;;;;Motherboard 25: model 1001pxd, S/N eee0123456789;asustek computer inc.;1001pxd;eee0123456789;;"auo ""auo""";auo lcd monitor;;GraphicCard 18: model atom processor d4xx/d5xx/n4xx/n5xx integrated graphics controller, S/N None;intel corporation;atom processor d4xx/d5xx/n4xx/n5xx integrated graphics controller;;256;;;;;;NetworkAdapter 15: model ar9285 wireless network adapter, S/N 74:2f:68:8b:fd:c8;qualcomm atheros;ar9285 wireless network adapter;74:2f:68:8b:fd:c8;NetworkAdapter 16: model ar8152 v2.0 fast ethernet, S/N 14:da:e9:42:f6:7c;qualcomm atheros;ar8152 v2.0 fast ethernet;14:da:e9:42:f6:7c;SoundCard 9: model usb 2.0 uvc vga webcam, S/N 0x0001;azurewave;usb 2.0 uvc vga webcam;0x0001;SoundCard 19: model nm10/ich7 family high definition audio controller, S/N None;intel corporation;nm10/ich7 family high definition audio controller;;1.72;LOW;1.31;LOW;1.99;LOW;3.97;HIGH;51.60 €;15.7188 diff --git a/tests/test_action.py b/tests/test_action.py index 01d824ec..ee784372 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -382,7 +382,7 @@ def test_live_without_TestDataStorage(user: UserClient, client: Client, app: Dev acer = file('acer.happy.battery.snapshot') snapshot, _ = user.post(acer, res=models.Snapshot) device_id = snapshot['device']['id'] - db_device = Device.query.filter_by(id=1).one() + db_device = Device.query.filter_by(id=device_id).one() post_request = {"transaction": "ccc", "name": "John", "endUsers": 1, "devices": [device_id], "description": "aaa", "finalUserCode": "abcdefjhi", @@ -415,7 +415,7 @@ def test_live_without_hdd_1(user: UserClient, client: Client, app: Devicehub): acer = file('acer.happy.battery.snapshot') snapshot, _ = user.post(acer, res=models.Snapshot) device_id = snapshot['device']['id'] - db_device = Device.query.filter_by(id=1).one() + db_device = Device.query.filter_by(id=device_id).one() post_request = {"transaction": "ccc", "name": "John", "endUsers": 1, "devices": [device_id], "description": "aaa", "finalUserCode": "abcdefjhi", @@ -446,7 +446,7 @@ def test_live_without_hdd_2(user: UserClient, client: Client, app: Devicehub): acer['components'] = components snapshot, _ = user.post(acer, res=models.Snapshot) device_id = snapshot['device']['id'] - db_device = Device.query.filter_by(id=1).one() + db_device = Device.query.filter_by(id=device_id).one() post_request = {"transaction": "ccc", "name": "John", "endUsers": 1, "devices": [device_id], "description": "aaa", "finalUserCode": "abcdefjhi", @@ -477,7 +477,7 @@ def test_live_without_hdd_3(user: UserClient, client: Client, app: Devicehub): acer['components'] = components snapshot, _ = user.post(acer, res=models.Snapshot) device_id = snapshot['device']['id'] - db_device = Device.query.filter_by(id=1).one() + db_device = Device.query.filter_by(id=device_id).one() post_request = {"transaction": "ccc", "name": "John", "endUsers": 1, "devices": [device_id], "description": "aaa", "finalUserCode": "abcdefjhi", @@ -510,7 +510,7 @@ def test_live_with_hdd_with_old_time(user: UserClient, client: Client, app: Devi acer = file('acer.happy.battery.snapshot') snapshot, _ = user.post(acer, res=models.Snapshot) device_id = snapshot['device']['id'] - db_device = Device.query.filter_by(id=1).one() + db_device = Device.query.filter_by(id=device_id).one() post_request = {"transaction": "ccc", "name": "John", "endUsers": 1, "devices": [device_id], "description": "aaa", "finalUserCode": "abcdefjhi", diff --git a/tests/test_documents.py b/tests/test_documents.py index 7699b468..fe254b33 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -265,6 +265,7 @@ def test_export_extended(app: Devicehub, user: UserClient): pc.tags.add(tag) db.session.add(pc) db.session.commit() + csv_str, _ = user.get(res=documents.DocumentDef.t, item='devices/', accept='text/csv', diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py index a653e95b..ac0f65be 100644 --- a/tests/test_snapshot.py +++ b/tests/test_snapshot.py @@ -37,6 +37,7 @@ from tests import conftest @pytest.mark.mvp @pytest.mark.usefixtures('auth_app_context') +# cayop def test_snapshot_model(): """Tests creating a Snapshot with its relationships ensuring correct DB mapping. @@ -63,7 +64,7 @@ def test_snapshot_model(): assert m.Desktop.query.one_or_none() is None assert m.Device.query.one_or_none() is None # Check properties - assert device.url == urlutils.URL('http://localhost/devices/1') + assert device.url == urlutils.URL('http://localhost/devices/3') @pytest.mark.mvp @@ -315,7 +316,7 @@ def test_snapshot_tag_inner_tag(user: UserClient, tag_id: str, app: Devicehub): action_types=(RateComputer.t, BenchmarkProcessor.t, VisualTest.t)) with app.app_context(): tag = Tag.query.one() # type: Tag - assert tag.device_id == 1, 'Tag should be linked to the first device' + assert tag.device_id == 3, 'Tag should be linked to the first device' @pytest.mark.mvp From 4122ac165e65d5dfb21bfdb66817d984b82d2175 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 16 Apr 2021 12:45:14 +0200 Subject: [PATCH 26/52] fixing tests --- tests/test_device.py | 149 ++++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 74 deletions(-) diff --git a/tests/test_device.py b/tests/test_device.py index 851698fb..510a3a37 100644 --- a/tests/test_device.py +++ b/tests/test_device.py @@ -65,13 +65,13 @@ def test_device_model(): gcard = d.GraphicCard.query.one() db.session.delete(pc) db.session.flush() - assert pc.id == 1 + assert pc.id == 3 assert d.Desktop.query.first() is None db.session.commit() assert d.Desktop.query.first() is None - assert network_adapter.id == 2 + assert network_adapter.id == 4 assert d.NetworkAdapter.query.first() is not None, 'We removed the network adaptor' - assert gcard.id == 3, 'We should still hold a reference to a zombie graphic card' + assert gcard.id == 5, 'We should still hold a reference to a zombie graphic card' assert d.GraphicCard.query.first() is None, 'We should have deleted it –it was inside the pc' @@ -396,72 +396,73 @@ def test_sync_execute_register_mismatch_between_tags_and_hid(): @pytest.mark.mvp -def test_get_device(app: Devicehub, user: UserClient): +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_get_device(user: UserClient): """Checks GETting a d.Desktop with its components.""" - with app.app_context(): - pc = d.Desktop(model='p1mo', - manufacturer='p1ma', - serial_number='p1s', - chassis=ComputerChassis.Tower, - owner_id=user.user['id']) - pc.components = OrderedSet([ - d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s', - owner_id=user.user['id']), - d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500, owner_id=user.user['id']) - ]) - db.session.add(pc) - # todo test is an abstract class. replace with another one - db.session.add(TestConnectivity(device=pc, - severity=Severity.Info, - agent=Person(name='Timmy'), - author=User(email='bar@bar.com'))) - db.session.commit() - pc, _ = user.get(res=d.Device, item=1) - assert len(pc['actions']) == 1 - assert pc['actions'][0]['type'] == 'TestConnectivity' - assert pc['actions'][0]['device'] == 1 - assert pc['actions'][0]['severity'] == 'Info' - assert UUID(pc['actions'][0]['author']) - assert 'actions_components' not in pc, 'actions_components are internal use only' - assert 'actions_one' not in pc, 'they are internal use only' - assert 'author' not in pc - assert tuple(c['id'] for c in pc['components']) == (2, 3) - assert pc['hid'] == 'desktop-p1ma-p1mo-p1s' - assert pc['model'] == 'p1mo' - assert pc['manufacturer'] == 'p1ma' - assert pc['serialNumber'] == 'p1s' - assert pc['type'] == d.Desktop.t + pc = d.Desktop(model='p1mo', + manufacturer='p1ma', + serial_number='p1s', + chassis=ComputerChassis.Tower, + owner_id=user.user['id']) + pc.components = OrderedSet([ + d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s', + owner_id=user.user['id']), + d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500, owner_id=user.user['id']) + ]) + db.session.add(pc) + # todo test is an abstract class. replace with another one + db.session.add(TestConnectivity(device=pc, + severity=Severity.Info, + agent=Person(name='Timmy'), + author=User(email='bar@bar.com'))) + db.session.commit() + pc_api, _ = user.get(res=d.Device, item=pc.id) + assert len(pc_api['actions']) == 1 + assert pc_api['actions'][0]['type'] == 'TestConnectivity' + assert pc_api['actions'][0]['device'] == pc.id + assert pc_api['actions'][0]['severity'] == 'Info' + assert UUID(pc_api['actions'][0]['author']) + assert 'actions_components' not in pc_api, 'actions_components are internal use only' + assert 'actions_one' not in pc_api, 'they are internal use only' + assert 'author' not in pc_api + assert tuple(c['id'] for c in pc_api['components']) == tuple(c.id for c in pc.components) + assert pc_api['hid'] == 'desktop-p1ma-p1mo-p1s' + assert pc_api['model'] == 'p1mo' + assert pc_api['manufacturer'] == 'p1ma' + assert pc_api['serialNumber'] == 'p1s' + assert pc_api['type'] == d.Desktop.t @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_get_devices(app: Devicehub, user: UserClient): """Checks GETting multiple devices.""" - with app.app_context(): - pc = d.Desktop(model='p1mo', - manufacturer='p1ma', - serial_number='p1s', - chassis=ComputerChassis.Tower, - owner_id=user.user['id']) - pc.components = OrderedSet([ - d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s', - owner_id=user.user['id']), - d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500, - owner_id=user.user['id']) - ]) - pc1 = d.Desktop(model='p2mo', - manufacturer='p2ma', - serial_number='p2s', - chassis=ComputerChassis.Tower, - owner_id=user.user['id']) - pc2 = d.Laptop(model='p3mo', - manufacturer='p3ma', - serial_number='p3s', - chassis=ComputerChassis.Netbook, - owner_id=user.user['id']) - db.session.add_all((pc, pc1, pc2)) - db.session.commit() + pc = d.Desktop(model='p1mo', + manufacturer='p1ma', + serial_number='p1s', + chassis=ComputerChassis.Tower, + owner_id=user.user['id']) + pc.components = OrderedSet([ + d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s', + owner_id=user.user['id']), + d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500, + owner_id=user.user['id']) + ]) + pc1 = d.Desktop(model='p2mo', + manufacturer='p2ma', + serial_number='p2s', + chassis=ComputerChassis.Tower, + owner_id=user.user['id']) + pc2 = d.Laptop(model='p3mo', + manufacturer='p3ma', + serial_number='p3s', + chassis=ComputerChassis.Netbook, + owner_id=user.user['id']) + db.session.add_all((pc, pc1, pc2)) + db.session.commit() devices, _ = user.get(res=d.Device) - assert tuple(dev['id'] for dev in devices['items']) == (1, 2, 3, 4, 5) + ids = (pc.id, pc1.id, pc2.id, pc.components[0].id, pc.components[1].id) + assert tuple(dev['id'] for dev in devices['items']) == ids assert tuple(dev['type'] for dev in devices['items']) == ( d.Desktop.t, d.Desktop.t, d.Laptop.t, d.NetworkAdapter.t, d.GraphicCard.t ) @@ -534,7 +535,7 @@ def test_device_properties_format(app: Devicehub, user: UserClient): user.post(file('asus-eee-1000h.snapshot.11'), res=m.Snapshot) with app.app_context(): pc = d.Laptop.query.one() # type: d.Laptop - assert format(pc) == 'Laptop 1: model 1000h, S/N 94oaaq021116' + assert format(pc) == 'Laptop 3: model 1000h, S/N 94oaaq021116' assert format(pc, 't') == 'Netbook 1000h' assert format(pc, 's') == '(asustek computer inc.) S/N 94OAAQ021116' assert pc.ram_size == 1024 @@ -542,12 +543,12 @@ def test_device_properties_format(app: Devicehub, user: UserClient): assert pc.graphic_card_model == 'mobile 945gse express integrated graphics controller' assert pc.processor_model == 'intel atom cpu n270 @ 1.60ghz' net = next(c for c in pc.components if isinstance(c, d.NetworkAdapter)) - assert format(net) == 'NetworkAdapter 2: model ar8121/ar8113/ar8114 ' \ + assert format(net) == 'NetworkAdapter 4: model ar8121/ar8113/ar8114 ' \ 'gigabit or fast ethernet, S/N 00:24:8c:7f:cf:2d' assert format(net, 't') == 'NetworkAdapter ar8121/ar8113/ar8114 gigabit or fast ethernet' assert format(net, 's') == 'qualcomm atheros 00:24:8C:7F:CF:2D – 100 Mbps' hdd = next(c for c in pc.components if isinstance(c, d.DataStorage)) - assert format(hdd) == 'HardDrive 7: model st9160310as, S/N 5sv4tqa6' + assert format(hdd) == 'HardDrive 9: model st9160310as, S/N 5sv4tqa6' assert format(hdd, 't') == 'HardDrive st9160310as' assert format(hdd, 's') == 'seagate 5SV4TQA6 – 152 GB' @@ -615,7 +616,7 @@ def test_hid_with_mac(app: Devicehub, user: UserClient): """Checks hid with mac.""" snapshot = file('asus-eee-1000h.snapshot.11') user.post(snapshot, res=m.Snapshot) - pc, _ = user.get(res=d.Device, item=1) + pc, _ = user.get(res=d.Device, item=3) assert pc['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d' @@ -624,8 +625,8 @@ def test_hid_without_mac(app: Devicehub, user: UserClient): """Checks hid without mac.""" snapshot = file('asus-eee-1000h.snapshot.11') snapshot['components'] = [c for c in snapshot['components'] if c['type'] != 'NetworkAdapter'] - user.post(snapshot, res=m.Snapshot) - pc, _ = user.get(res=d.Device, item=1) + snap, _ = user.post(snapshot, res=m.Snapshot) + pc, _ = user.get(res=d.Device, item=snap['device']['id']) assert pc['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116' @@ -635,8 +636,8 @@ def test_hid_with_mac_none(app: Devicehub, user: UserClient): snapshot = file('asus-eee-1000h.snapshot.11') network = [c for c in snapshot['components'] if c['type'] == 'NetworkAdapter'][0] network['serialNumber'] = None - user.post(snapshot, res=m.Snapshot) - pc, _ = user.get(res=d.Device, item=1) + snap, _ = user.post(snapshot, res=m.Snapshot) + pc, _ = user.get(res=d.Device, item=snap['device']['id']) assert pc['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116' @@ -664,8 +665,8 @@ def test_hid_with_2network_and_drop_no_mac_in_hid(app: Devicehub, user: UserClie network2 = copy.copy(network) snapshot['components'].append(network2) network['serialNumber'] = 'a0:24:8c:7f:cf:2d' - user.post(snapshot, res=m.Snapshot) - pc, _ = user.get(res=d.Device, item=1) + snap, _ = user.post(snapshot, res=m.Snapshot) + pc, _ = user.get(res=d.Device, item=snap['device']['id']) assert pc['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d' snapshot['uuid'] = 'd1b70cb8-8929-4f36-99b7-fe052cec0abb' @@ -687,8 +688,8 @@ def test_hid_with_2network_and_drop_mac_in_hid(app: Devicehub, user: UserClient) network2 = copy.copy(network) snapshot['components'].append(network2) network['serialNumber'] = 'a0:24:8c:7f:cf:2d' - user.post(snapshot, res=m.Snapshot) - pc, _ = user.get(res=d.Device, item=1) + snap, _ = user.post(snapshot, res=m.Snapshot) + pc, _ = user.get(res=d.Device, item=snap['device']['id']) assert pc['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d' # we drop the network card then is used for to build the hid From ebe089499d7b51e7980264d022bd890df9c5402a Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 16 Apr 2021 13:25:41 +0200 Subject: [PATCH 27/52] fixing tests --- tests/test_device_find.py | 10 +++++----- tests/test_tag.py | 2 +- tests/test_workbench.py | 28 ++++++++++++++++------------ 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/tests/test_device_find.py b/tests/test_device_find.py index 7e9ac291..82716719 100644 --- a/tests/test_device_find.py +++ b/tests/test_device_find.py @@ -176,10 +176,10 @@ def test_device_query_filter_lots(user: UserClient): @pytest.mark.mvp def test_device_query(user: UserClient): """Checks result of inventory.""" - user.post(conftest.file('basic.snapshot'), res=Snapshot) + snapshot, _ = user.post(conftest.file('basic.snapshot'), res=Snapshot) i, _ = user.get(res=Device) assert i['url'] == '/devices/' - assert i['items'][0]['url'] == '/devices/1' + assert i['items'][0]['url'] == '/devices/{}'.format(snapshot['device']['id']) pc = next(d for d in i['items'] if d['type'] == 'Desktop') assert len(pc['actions']) == 4 assert len(pc['components']) == 3 @@ -241,14 +241,14 @@ def test_device_search_regenerate_table(app: DeviceSearch, user: UserClient): @pytest.mark.mvp def test_device_query_search(user: UserClient): # todo improve - user.post(file('basic.snapshot'), res=Snapshot) + snapshot, _ = user.post(file('basic.snapshot'), res=Snapshot) user.post(file('computer-monitor.snapshot'), res=Snapshot) user.post(file('real-eee-1001pxd.snapshot.11'), res=Snapshot) i, _ = user.get(res=Device, query=[('search', 'desktop')]) - assert i['items'][0]['id'] == 1 + assert i['items'][0]['id'] == snapshot['device']['id'] i, _ = user.get(res=Device, query=[('search', 'intel')]) assert len(i['items']) == 1 - i, _ = user.get(res=Device, query=[('search', '1')]) + i, _ = user.get(res=Device, query=[('search', snapshot['device']['id'])]) assert len(i['items']) == 1 diff --git a/tests/test_tag.py b/tests/test_tag.py index f6402bd4..5e8d6648 100644 --- a/tests/test_tag.py +++ b/tests/test_tag.py @@ -282,7 +282,7 @@ def test_tag_manual_link_search(app: Devicehub, user: UserClient): db.session.commit() desktop_id = desktop.id user.put({}, res=Tag, item='foo-bar/device/{}'.format(desktop_id), status=204) - device, _ = user.get(res=Device, item=1) + device, _ = user.get(res=Device, item=desktop_id) assert device['tags'][0]['id'] == 'foo-bar' # Device already linked diff --git a/tests/test_workbench.py b/tests/test_workbench.py index e2d5ce9a..6f453739 100644 --- a/tests/test_workbench.py +++ b/tests/test_workbench.py @@ -32,20 +32,24 @@ def test_workbench_server_condensed(user: UserClient): user.post({'id': t['id']}, res=Tag) snapshot, _ = user.post(res=em.Snapshot, data=s) + pc_id = snapshot['device']['id'] + cpu_id = snapshot['components'][3]['id'] + ssd_id= snapshot['components'][4]['id'] + hdd_id = snapshot['components'][5]['id'] actions = snapshot['actions'] assert {(action['type'], action['device']) for action in actions} == { - ('BenchmarkProcessorSysbench', 5), - ('StressTest', 1), - ('EraseSectors', 6), - ('EreusePrice', 1), - ('BenchmarkRamSysbench', 1), - ('BenchmarkProcessor', 5), - ('Install', 6), - ('EraseSectors', 7), - ('BenchmarkDataStorage', 6), - ('BenchmarkDataStorage', 7), - ('TestDataStorage', 6), - ('RateComputer', 1) + ('BenchmarkProcessorSysbench', cpu_id), + ('StressTest', pc_id), + ('EraseSectors', ssd_id), + ('EreusePrice', pc_id), + ('BenchmarkRamSysbench', pc_id), + ('BenchmarkProcessor', cpu_id), + ('Install', ssd_id), + ('EraseSectors', hdd_id), + ('BenchmarkDataStorage', ssd_id), + ('BenchmarkDataStorage', hdd_id), + ('TestDataStorage', ssd_id), + ('RateComputer', pc_id) } assert snapshot['closed'] assert snapshot['severity'] == 'Info' From f6205912fbb8706a9181ac2d55776deb9c423ab7 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 10 May 2021 12:10:57 +0200 Subject: [PATCH 28/52] fixing test renders --- tests/test_basic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_basic.py b/tests/test_basic.py index 00c9cf93..244e84ea 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -119,4 +119,4 @@ def test_api_docs(client: Client): 'scheme': 'basic', 'name': 'Authorization' } - assert len(docs['definitions']) == 120 + assert len(docs['definitions']) == 121 From 5b6073de7e2538880da720bf99f1b98f5c466353 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 12 May 2021 12:24:22 +0200 Subject: [PATCH 29/52] adding test about this bug --- .../files/2021-5-4-13-41_time_out_test_datastorage.yaml | 1 + tests/test_snapshot.py | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 tests/files/2021-5-4-13-41_time_out_test_datastorage.yaml diff --git a/tests/files/2021-5-4-13-41_time_out_test_datastorage.yaml b/tests/files/2021-5-4-13-41_time_out_test_datastorage.yaml new file mode 100644 index 00000000..c0489053 --- /dev/null +++ b/tests/files/2021-5-4-13-41_time_out_test_datastorage.yaml @@ -0,0 +1 @@ +{"closed": true, "components": [{"actions": [], "manufacturer": "SEC", "model": "LCD Monitor", "productionDate": "2012-01-01T00:00:00", "refreshRate": 60, "resolutionHeight": 768, "resolutionWidth": 1366, "serialNumber": null, "size": 15.548539594256658, "technology": "LCD", "type": "Display"}, {"actions": [], "manufacturer": "Realtek Semiconductor Co., Ltd.", "model": "RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller", "serialNumber": "c8:cb:b8:5a:5a:bb", "speed": 1000.0, "type": "NetworkAdapter", "variant": "07", "wireless": false}, {"actions": [], "manufacturer": "Ralink corp.", "model": "RT3290 Wireless 802.11n 1T/1R PCIe", "serialNumber": "a4:17:31:2b:c9:99", "speed": null, "type": "NetworkAdapter", "variant": "00", "wireless": true}, {"actions": [], "manufacturer": "Intel Corporation", "model": "7 Series/C216 Chipset Family High Definition Audio Controller", "serialNumber": null, "type": "SoundCard"}, {"actions": [], "manufacturer": "Chicony Electronics Co.,Ltd.", "model": "HP Truevision HD", "serialNumber": "0x0001", "type": "SoundCard"}, {"actions": [], "format": "SODIMM", "interface": "DDR3", "manufacturer": "Kingston", "model": "HP536727-H41-ELD", "serialNumber": "552AE579", "size": 4096.0, "speed": 1333.0, "type": "RamModule"}, {"actions": [], "format": "SODIMM", "interface": "DDR3", "manufacturer": null, "model": "F3-12800CL11-4GBSQ", "serialNumber": null, "size": 4096.0, "speed": 1333.0, "type": "RamModule"}, {"actions": [{"elapsed": 15, "readSpeed": 98.7, "type": "BenchmarkDataStorage", "writeSpeed": 22.2}, {"assessment": false, "commandTimeout": 4295819304, "currentPendingSectorCount": 0, "elapsed": 119, "length": "Short", "lifetime": 8766, "offlineUncorrectable": 0, "powerCycleCount": 2280, "reallocatedSectorCount": 0, "reportedUncorrectableErrors": 171, "severity": "Info", "status": "Completed without error", "type": "TestDataStorage"}], "interface": "ATA", "manufacturer": "Seagate", "model": "ST500LT012-9WS14", "serialNumber": "W0V3SHRV", "size": 500107.86201599997, "type": "HardDrive", "variant": "YAM1"}, {"actions": [{"elapsed": 21, "rate": 21.3131, "type": "BenchmarkProcessorSysbench"}, {"elapsed": 0, "rate": 17561.92, "type": "BenchmarkProcessor"}], "address": 64, "brand": "Core i3", "cores": 2, "generation": 2, "manufacturer": "Intel Corp.", "model": "Intel Core i3-2328M CPU @ 2.20GHz", "serialNumber": null, "speed": 0.800964, "threads": 4, "type": "Processor"}, {"actions": [], "manufacturer": "Intel Corporation", "memory": null, "model": "2nd Generation Core Processor Family Integrated Graphics Controller", "serialNumber": null, "type": "GraphicCard"}, {"actions": [], "biosDate": "2014-05-13T00:00:00", "firewire": 0, "manufacturer": "Hewlett-Packard", "model": "1858", "pcmcia": 0, "ramMaxSize": 16, "ramSlots": 2, "serial": 1, "serialNumber": "PCTVLB47V3O95U", "slots": 2, "type": "Motherboard", "usb": 2, "version": "F.39"}], "debug": {"battery": null, "hwinfo": "01: None 00.0: 10105 BIOS\n [Created at bios.186]\n Unique ID: rdCR.lZF+r4EgHp4\n Hardware Class: bios\n BIOS Keyboard LED Status:\n Scroll Lock: off\n Num Lock: off\n Caps Lock: off\n Base Memory: 629 kB\n PnP BIOS: SST2400\n MP spec rev 1.4 info:\n OEM id: \"Insyde\"\n Product id: \"Calpella\"\n 1 CPUs (0 disabled)\n BIOS32 Service Directory Entry: 0xef725\n SMBIOS Version: 2.7\n Physical Memory Array: #0\n Use: 0x03 (System memory)\n Location: 0x03 (Motherboard)\n Slots: 2\n Max. Size: 16 GB\n ECC: 0x03 (None)\n Error Info: #9\n Memory Device: #1\n Location: \"Bottom-Slot 2(under)\"\n Bank: \"BANK 0\"\n Manufacturer: \"Kingston\"\n Serial: \"552AE579\"\n Asset Tag: \"Unknown\"\n Part Number: \"HP536727-H41-ELD\"\n Memory Array: #0\n Error Info: #3\n Form Factor: 0x0d (SODIMM)\n Type: 0x18 (Other)\n Type Detail: 0x0080 (Synchronous)\n Data Width: 64 bits\n Size: 4 GB\n Speed: 1333 MHz\n 32bit-Memory Error Info: #3\n Type: 0x03 (OK)\n Granularity: 0x02 (Unknown)\n Operation: 0x02 (Unknown)\n Memory Device Mapping: #4\n Memory Device: #1\n Array Mapping: #10\n Row: 1\n Interleave Pos: 1\n Interleaved Depth: 1\n Start Address: 0x0000000000000000\n End Address: 0x0000000100000000\n Memory Device: #5\n Location: \"Bottom-Slot 1(top)\"\n Bank: \"BANK 2\"\n Manufacturer: \"Unknown\"\n Serial: \"00000000\"\n Asset Tag: \"Unknown\"\n Part Number: \"F3-12800CL11-4GBSQ\"\n Memory Array: #0\n Error Info: #7\n Form Factor: 0x0d (SODIMM)\n Type: 0x18 (Other)\n Type Detail: 0x0080 (Synchronous)\n Data Width: 64 bits\n Size: 4 GB\n Speed: 1333 MHz\n 32bit-Memory Error Info: #7\n Type: 0x03 (OK)\n Granularity: 0x02 (Unknown)\n Operation: 0x02 (Unknown)\n Memory Device Mapping: #8\n Memory Device: #5\n Array Mapping: #10\n Row: 1\n Interleave Pos: 2\n Interleaved Depth: 1\n Start Address: 0x0000000000000000\n End Address: 0x0000000100000000\n 32bit-Memory Error Info: #9\n Type: 0x03 (OK)\n Granularity: 0x02 (Unknown)\n Operation: 0x02 (Unknown)\n Memory Array Mapping: #10\n Memory Array: #0\n Partition Width: 2\n Start Address: 0x0000000000000000\n End Address: 0x0000000200000000\n BIOS Info: #12\n Vendor: \"Insyde\"\n Version: \"F.39\"\n Date: \"05/13/2014\"\n Start Address: 0xe0000\n ROM Size: 2560 kB\n Features: 0x0d03005000014bf99880\n PCI supported\n BIOS flashable\n BIOS shadowing allowed\n CD boot supported\n Selectable boot supported\n EDD spec supported\n 1.2MB NEC 9800 Japanese Floppy supported\n 1.2MB Toshiba Japanese Floppy supported\n 360kB Floppy supported\n 1.2MB Floppy supported\n 720kB Floppy supported\n 2.88MB Floppy supported\n 8042 Keyboard Services supported\n CGA/Mono Video supported\n ACPI supported\n USB Legacy supported\n BIOS Boot Spec supported\n System Info: #13\n Manufacturer: \"Hewlett-Packard\"\n Product: \"HP 650 Notebook PC\"\n Version: \"087F110000305B10002620110\"\n Serial: \"5CB2452RGJ\"\n UUID: undefined, but settable\n Wake-up: 0x06 (Power Switch)\n Board Info: #14\n Manufacturer: \"Hewlett-Packard\"\n Product: \"1858\"\n Version: \"65.34\"\n Serial: \"PCTVLB47V3O95U\"\n Asset Tag: \"Type2 - Board Asset Tag\"\n Type: 0x0a (Motherboard)\n Features: 0x09\n Hosting Board\n Replaceable\n Location: \"Type2 - Board Chassis Location\"\n Chassis: #15\n Chassis Info: #15\n Manufacturer: \"Hewlett-Packard\"\n Version: \"Chassis Version\"\n Serial: \"Chassis Serial Number\"\n Asset Tag: \"Chassis Asset Tag\"\n Type: 0x0a (Notebook)\n Bootup State: 0x03 (Safe)\n Power Supply State: 0x03 (Safe)\n Thermal State: 0x03 (Safe)\n Security Status: 0x03 (None)\n OEM Info: 0x0000015b\n Port Connector: #16\n Type: 0x10 (USB)\n Internal Designator: \"J3A1\"\n External Designator: \"USB\"\n External Connector: 0x12 (Access Bus [USB])\n Port Connector: #17\n Type: 0x10 (USB)\n Internal Designator: \"J3A1\"\n External Designator: \"USB\"\n External Connector: 0x12 (Access Bus [USB])\n Port Connector: #18\n Type: 0x10 (USB)\n Internal Designator: \"J3A1\"\n External Designator: \"USB\"\n External Connector: 0x12 (Access Bus [USB])\n Port Connector: #19\n Type: 0x1f (Network Port)\n Internal Designator: \"J5A1\"\n External Designator: \"Network\"\n External Connector: 0x0b (RJ-45)\n Port Connector: #20\n Type: 0x1c (Video Port)\n Internal Designator: \"J2A2\"\n External Designator: \"CRT\"\n External Connector: 0x07 (DB-15 pin female)\n Port Connector: #21\n Type: 0x1c (Video Port)\n Internal Designator: \"J2A3\"\n External Designator: \"HDMI\"\n External Connector: 0xff (Other)\n Port Connector: #22\n Type: 0x1d (Audio Port)\n Internal Designator: \"J30\"\n External Designator: \"Line In\"\n External Connector: 0x1f (Mini-jack [headphones])\n Port Connector: #23\n Type: 0x1d (Audio Port)\n Internal Designator: \"J30\"\n External Designator: \"Speaker Out\"\n External Connector: 0x1f (Mini-jack [headphones])\n System Slot: #24\n Designation: \"J5C1\"\n Type: 0xaa (Other)\n Bus Width: 0x0d (Other)\n Status: 0x03 (Available)\n Length: 0x01 (Other)\n Slot ID: 1\n Characteristics: 0x0300 (PME#, Hot-Plug)\n System Slot: #25\n Designation: \"J6C1\"\n Type: 0xa8 (Other)\n Bus Width: 0x0a (Other)\n Status: 0x03 (Available)\n Length: 0x01 (Other)\n Slot ID: 2\n Characteristics: 0x0300 (PME#, Hot-Plug)\n System Slot: #26\n Designation: \"J6C2\"\n Type: 0xa6 (Other)\n Bus Width: 0x08 (Other)\n Status: 0x03 (Available)\n Length: 0x01 (Other)\n Slot ID: 3\n Characteristics: 0x0300 (PME#, Hot-Plug)\n System Slot: #27\n Designation: \"J6D2\"\n Type: 0xa6 (Other)\n Bus Width: 0x08 (Other)\n Status: 0x03 (Available)\n Length: 0x01 (Other)\n Slot ID: 4\n Characteristics: 0x0300 (PME#, Hot-Plug)\n System Slot: #28\n Designation: \"J7C1\"\n Type: 0xa6 (Other)\n Bus Width: 0x08 (Other)\n Status: 0x03 (Available)\n Length: 0x01 (Other)\n Slot ID: 5\n Characteristics: 0x0300 (PME#, Hot-Plug)\n System Slot: #29\n Designation: \"J7D2\"\n Type: 0xa6 (Other)\n Bus Width: 0x08 (Other)\n Status: 0x03 (Available)\n Length: 0x01 (Other)\n Slot ID: 6\n Characteristics: 0x0300 (PME#, Hot-Plug)\n System Slot: #30\n Designation: \"J8C1\"\n Type: 0xa6 (Other)\n Bus Width: 0x08 (Other)\n Status: 0x03 (Available)\n Length: 0x01 (Other)\n Slot ID: 7\n Characteristics: 0x0300 (PME#, Hot-Plug)\n System Slot: #31\n Designation: \"J8C2\"\n Type: 0xaa (Other)\n Bus Width: 0x0d (Other)\n Status: 0x03 (Available)\n Length: 0x01 (Other)\n Slot ID: 8\n Characteristics: 0x0300 (PME#, Hot-Plug)\n OEM Strings: #32\n $HP$\n LOC#ABE\n ABS 70/71 78 79 7A 7B\n CNB1 087F110000305B10002620110\n String6 for Original Equipment Manufacturer\n String7 for Original Equipment Manufacturer\n String8 for Original Equipment Manufacturer\n Language Info: #34\n Languages: en|US|iso8859-1, fr|CA|iso8859-1, es|ES|iso8859-1, zh|TW|unicode\n Current: es|ES|iso8859-1\n Type 22 Record: #37\n Data 00: 16 1a 25 00 01 02 00 00 03 06 a0 b9 30 2a 04 00\n Data 10: 99 20 30 42 05 01 ff ff 00 00\n String 1: \"Primary\"\n String 2: \"11-85\"\n String 3: \"MU06047\"\n String 4: \"v1.1\"\n String 5: \"Li-ion\"\n Type 32 Record: #41\n Data 00: 20 14 29 00 00 00 00 00 00 00 00 00 00 00 00 00\n Data 10: 00 00 00 00\n Type 41 Record: #44\n Data 00: 29 0b 2c 00 01 83 01 00 00 00 10\n String 1: \"Intel VGA Compatible Controller\"\n Type 41 Record: #49\n Data 00: 29 0b 31 00 01 85 01 00 00 01 00\n String 1: \"Realtek PCIe GBE Family Controller\"\n Type 41 Record: #50\n Data 00: 29 0b 32 00 01 81 01 00 00 02 00\n String 1: \"Ralink RT3290LE 802.11bgn 1x1 Wi-Fi\"\n Processor Info: #51\n Socket: \"U3E1\"\n Socket Type: 0x21 (Other)\n Socket Status: Populated\n Type: 0x03 (CPU)\n Family: 0xce (Other)\n Manufacturer: \"Intel(R) Corporation\"\n Version: \"Intel(R) Core(TM) i3-2328M CPU @ 2.20GHz\"\n Serial: \"To Be Filled By O.E.M.\"\n Asset Tag: \"To Be Filled By O.E.M.\"\n Part Number: \"To Be Filled By O.E.M.\"\n Processor ID: 0xbfebfbff000206a7\n Status: 0x01 (Enabled)\n Voltage: 1.1 V\n External Clock: 100 MHz\n Max. Speed: 4000 MHz\n Current Speed: 2200 MHz\n L1 Cache: #53\n L2 Cache: #54\n L3 Cache: #55\n Cache Info: #52\n Designation: \"L1 Cache\"\n Level: L1\n State: Enabled\n Mode: 0x00 (Write Through)\n Location: 0x00 (Internal, Not Socketed)\n ECC: 0x04 (Parity)\n Type: 0x04 (Data)\n Associativity: 0x07 (8-way Set-Associative)\n Max. Size: 32 kB\n Current Size: 32 kB\n Supported SRAM Types: 0x0002 (Unknown)\n Current SRAM Type: 0x0002 (Unknown)\n Cache Info: #53\n Designation: \"L1 Cache\"\n Level: L1\n State: Enabled\n Mode: 0x00 (Write Through)\n Location: 0x00 (Internal, Not Socketed)\n ECC: 0x04 (Parity)\n Type: 0x03 (Instruction)\n Associativity: 0x07 (8-way Set-Associative)\n Max. Size: 32 kB\n Current Size: 32 kB\n Supported SRAM Types: 0x0002 (Unknown)\n Current SRAM Type: 0x0002 (Unknown)\n Cache Info: #54\n Designation: \"L2 Cache\"\n Level: L2\n State: Enabled\n Mode: 0x00 (Write Through)\n Location: 0x00 (Internal, Not Socketed)\n ECC: 0x06 (Multi-bit)\n Type: 0x05 (Unified)\n Associativity: 0x07 (8-way Set-Associative)\n Max. Size: 256 kB\n Current Size: 256 kB\n Supported SRAM Types: 0x0002 (Unknown)\n Current SRAM Type: 0x0002 (Unknown)\n Cache Info: #55\n Designation: \"L3 Cache\"\n Level: L3\n State: Enabled\n Mode: 0x01 (Write Back)\n Location: 0x00 (Internal, Not Socketed)\n ECC: 0x06 (Multi-bit)\n Type: 0x05 (Unified)\n Associativity: 0x09 (Other)\n Max. Size: 3072 kB\n Current Size: 3072 kB\n Supported SRAM Types: 0x0002 (Unknown)\n Current SRAM Type: 0x0002 (Unknown)\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n02: None 00.0: 10107 System\n [Created at sys.63]\n Unique ID: rdCR.n_7QNeEnh23\n Hardware Class: system\n Model: \"System\"\n Formfactor: \"laptop\"\n Driver Info #0:\n Driver Status: thermal,fan are not active\n Driver Activation Cmd: \"modprobe thermal; modprobe fan\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n03: None 00.0: 10104 FPU\n [Created at misc.191]\n Unique ID: rdCR.EMpH5pjcahD\n Hardware Class: unknown\n Model: \"FPU\"\n I/O Ports: 0xf0-0xff (rw)\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n04: None 00.0: 0801 DMA controller (8237)\n [Created at misc.205]\n Unique ID: rdCR.f5u1ucRm+H9\n Hardware Class: unknown\n Model: \"DMA controller\"\n I/O Ports: 0x00-0xcf7 (rw)\n I/O Ports: 0xc0-0xdf (rw)\n I/O Ports: 0x80-0x8f (rw)\n DMA: 4\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n05: None 00.0: 0800 PIC (8259)\n [Created at misc.218]\n Unique ID: rdCR.8uRK7LxiIA2\n Hardware Class: unknown\n Model: \"PIC\"\n I/O Ports: 0x20-0x21 (rw)\n I/O Ports: 0xa0-0xa1 (rw)\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n06: None 00.0: 0900 Keyboard controller\n [Created at misc.250]\n Unique ID: rdCR.9N+EecqykME\n Hardware Class: unknown\n Model: \"Keyboard controller\"\n I/O Port: 0x60 (rw)\n I/O Port: 0x64 (rw)\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n07: None 00.0: 10400 PS/2 Controller\n [Created at misc.303]\n Unique ID: rdCR.DziBbWO85o5\n Hardware Class: unknown\n Model: \"PS/2 Controller\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n12: None 00.0: 10102 Main Memory\n [Created at memory.74]\n Unique ID: rdCR.CxwsZFjVASF\n Hardware Class: memory\n Model: \"Main Memory\"\n Memory Range: 0x00000000-0x1efa48fff (rw)\n Memory Size: 7 GB + 512 MB\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n13: PCI 1c.3: 0604 PCI bridge (Normal decode)\n [Created at pci.378]\n Unique ID: Z7uZ.u7w9tKvRfT3\n SysFS ID: /devices/pci0000:00/0000:00:1c.3\n SysFS BusID: 0000:00:1c.3\n Hardware Class: bridge\n Model: \"Intel 7 Series/C216 Chipset Family PCI Express Root Port 4\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x1e16 \"7 Series/C216 Chipset Family PCI Express Root Port 4\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0xc4\n Driver: \"pcieport\"\n IRQ: 19 (no events)\n Module Alias: \"pci:v00008086d00001E16sv0000103Csd00001858bc06sc04i00\"\n Driver Info #0:\n Driver Status: shpchp is active\n Driver Activation Cmd: \"modprobe shpchp\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n14: PCI 1f.3: 0c05 SMBus\n [Created at pci.378]\n Unique ID: nS1_.hgYEEmUINm7\n SysFS ID: /devices/pci0000:00/0000:00:1f.3\n SysFS BusID: 0000:00:1f.3\n Hardware Class: unknown\n Model: \"Intel 7 Series/C216 Chipset Family SMBus Controller\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x1e22 \"7 Series/C216 Chipset Family SMBus Controller\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x04\n Driver: \"i801_smbus\"\n Driver Modules: \"i2c_i801\"\n Memory Range: 0xc2605000-0xc26050ff (rw,non-prefetchable)\n I/O Ports: 0x4040-0x405f (rw)\n IRQ: 19 (no events)\n Module Alias: \"pci:v00008086d00001E22sv0000103Csd00001858bc0Csc05i00\"\n Driver Info #0:\n Driver Status: i2c_i801 is active\n Driver Activation Cmd: \"modprobe i2c_i801\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n15: PCI 00.0: 0600 Host bridge\n [Created at pci.378]\n Unique ID: qLht.YD_egPPIpv4\n SysFS ID: /devices/pci0000:00/0000:00:00.0\n SysFS BusID: 0000:00:00.0\n Hardware Class: bridge\n Model: \"Intel 2nd Generation Core Processor Family DRAM Controller\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x0104 \"2nd Generation Core Processor Family DRAM Controller\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x09\n Module Alias: \"pci:v00008086d00000104sv0000103Csd00001858bc06sc00i00\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n16: PCI 200.1: 0d11 Bluetooth\n [Created at pci.378]\n Unique ID: 2Oa+.OjlkIcR5cH9\n Parent ID: hoOk.sI1gvBg1ci2\n SysFS ID: /devices/pci0000:00/0000:00:1c.2/0000:02:00.1\n SysFS BusID: 0000:02:00.1\n Hardware Class: unknown\n Model: \"Hewlett-Packard Company Ralink RT3290LE 802.11bgn 1x1 Wi-Fi and Bluetooth 4.0 Combo Adapter\"\n Vendor: pci 0x1814 \"Ralink corp.\"\n Device: pci 0x3298 \"RT3290 Bluetooth\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x18ec \"Ralink RT3290LE 802.11bgn 1x1 Wi-Fi and Bluetooth 4.0 Combo Adapter\"\n Memory Range: 0xc2500000-0xc250ffff (rw,non-prefetchable)\n IRQ: 11 (no events)\n Module Alias: \"pci:v00001814d00003298sv0000103Csd000018ECbc0Dsc11i00\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #20 (PCI bridge)\n\n17: PCI 1a.0: 0c03 USB Controller (EHCI)\n [Created at pci.378]\n Unique ID: pwJ7.qpeEHYGiHa2\n SysFS ID: /devices/pci0000:00/0000:00:1a.0\n SysFS BusID: 0000:00:1a.0\n Hardware Class: usb controller\n Model: \"Intel 7 Series/C216 Chipset Family USB Enhanced Host Controller #2\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x1e2d \"7 Series/C216 Chipset Family USB Enhanced Host Controller #2\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x04\n Driver: \"ehci-pci\"\n Driver Modules: \"ehci_pci\"\n Memory Range: 0xc2609000-0xc26093ff (rw,non-prefetchable)\n IRQ: 16 (29 events)\n Module Alias: \"pci:v00008086d00001E2Dsv0000103Csd00001858bc0Csc03i20\"\n Driver Info #0:\n Driver Status: ehci-hcd is active\n Driver Activation Cmd: \"modprobe ehci-hcd\"\n Driver Info #1:\n Driver Status: ehci_pci is active\n Driver Activation Cmd: \"modprobe ehci_pci\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n18: PCI 1d.0: 0c03 USB Controller (EHCI)\n [Created at pci.378]\n Unique ID: 1GTX.Dw1+vYRmbuF\n SysFS ID: /devices/pci0000:00/0000:00:1d.0\n SysFS BusID: 0000:00:1d.0\n Hardware Class: usb controller\n Model: \"Intel 7 Series/C216 Chipset Family USB Enhanced Host Controller #1\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x1e26 \"7 Series/C216 Chipset Family USB Enhanced Host Controller #1\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x04\n Driver: \"ehci-pci\"\n Driver Modules: \"ehci_pci\"\n Memory Range: 0xc2608000-0xc26083ff (rw,non-prefetchable)\n IRQ: 23 (9425 events)\n Module Alias: \"pci:v00008086d00001E26sv0000103Csd00001858bc0Csc03i20\"\n Driver Info #0:\n Driver Status: ehci-hcd is active\n Driver Activation Cmd: \"modprobe ehci-hcd\"\n Driver Info #1:\n Driver Status: ehci_pci is active\n Driver Activation Cmd: \"modprobe ehci_pci\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n19: PCI 02.0: 0300 VGA compatible controller (VGA)\n [Created at pci.378]\n Unique ID: _Znp.nDJOnrrEzD7\n SysFS ID: /devices/pci0000:00/0000:00:02.0\n SysFS BusID: 0000:00:02.0\n Hardware Class: graphics card\n Device Name: \"Intel VGA Compatible Controller\"\n Model: \"Intel 2nd Generation Core Processor Family Integrated Graphics Controller\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x0116 \"2nd Generation Core Processor Family Integrated Graphics Controller\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x09\n Driver: \"i915\"\n Driver Modules: \"i915\"\n Memory Range: 0xc2000000-0xc23fffff (rw,non-prefetchable)\n Memory Range: 0xb0000000-0xbfffffff (ro,non-prefetchable)\n I/O Ports: 0x4000-0x403f (rw)\n Memory Range: 0x000c0000-0x000dffff (rw,non-prefetchable,disabled)\n IRQ: 27 (60 events)\n Module Alias: \"pci:v00008086d00000116sv0000103Csd00001858bc03sc00i00\"\n Driver Info #0:\n Driver Status: i915 is active\n Driver Activation Cmd: \"modprobe i915\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n20: PCI 1c.2: 0604 PCI bridge (Normal decode)\n [Created at pci.378]\n Unique ID: hoOk.sI1gvBg1ci2\n SysFS ID: /devices/pci0000:00/0000:00:1c.2\n SysFS BusID: 0000:00:1c.2\n Hardware Class: bridge\n Model: \"Intel 7 Series/C210 Series Chipset Family PCI Express Root Port 3\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x1e14 \"7 Series/C210 Series Chipset Family PCI Express Root Port 3\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0xc4\n Driver: \"pcieport\"\n IRQ: 18 (no events)\n Module Alias: \"pci:v00008086d00001E14sv0000103Csd00001858bc06sc04i00\"\n Driver Info #0:\n Driver Status: shpchp is active\n Driver Activation Cmd: \"modprobe shpchp\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n21: PCI 1f.2: 0106 SATA controller (AHCI 1.0)\n [Created at pci.378]\n Unique ID: w7Y8.3v_DiuY8eC2\n SysFS ID: /devices/pci0000:00/0000:00:1f.2\n SysFS BusID: 0000:00:1f.2\n Hardware Class: storage\n Model: \"Intel 7 Series Chipset Family 6-port SATA Controller [AHCI mode]\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x1e03 \"7 Series Chipset Family 6-port SATA Controller [AHCI mode]\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x04\n Driver: \"ahci\"\n Driver Modules: \"ahci\"\n I/O Ports: 0x4088-0x408f (rw)\n I/O Ports: 0x4094-0x4097 (rw)\n I/O Ports: 0x4080-0x4087 (rw)\n I/O Ports: 0x4090-0x4093 (rw)\n I/O Ports: 0x4060-0x407f (rw)\n Memory Range: 0xc2607000-0xc26077ff (rw,non-prefetchable)\n IRQ: 26 (479 events)\n Module Alias: \"pci:v00008086d00001E03sv0000103Csd00001858bc01sc06i01\"\n Driver Info #0:\n Driver Status: ahci is active\n Driver Activation Cmd: \"modprobe ahci\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n22: PCI 300.0: ff00 Unclassified device\n [Created at pci.378]\n Unique ID: svHJ.7DXcN_jgPlC\n Parent ID: Z7uZ.u7w9tKvRfT3\n SysFS ID: /devices/pci0000:00/0000:00:1c.3/0000:03:00.0\n SysFS BusID: 0000:03:00.0\n Hardware Class: unknown\n Model: \"Realtek RTS5229 PCI Express Card Reader\"\n Vendor: pci 0x10ec \"Realtek Semiconductor Co., Ltd.\"\n Device: pci 0x5229 \"RTS5229 PCI Express Card Reader\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x01\n Driver: \"rtsx_pci\"\n Driver Modules: \"rtsx_pci\"\n Memory Range: 0xc1000000-0xc1000fff (rw,non-prefetchable)\n IRQ: 25 (22 events)\n Module Alias: \"pci:v000010ECd00005229sv0000103Csd00001858bcFFsc00i00\"\n Driver Info #0:\n Driver Status: rtsx_pci is active\n Driver Activation Cmd: \"modprobe rtsx_pci\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #13 (PCI bridge)\n\n23: PCI 1c.0: 0604 PCI bridge (Normal decode)\n [Created at pci.378]\n Unique ID: z8Q3.oeFg_vBDVA1\n SysFS ID: /devices/pci0000:00/0000:00:1c.0\n SysFS BusID: 0000:00:1c.0\n Hardware Class: bridge\n Model: \"Intel 7 Series/C216 Chipset Family PCI Express Root Port 1\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x1e10 \"7 Series/C216 Chipset Family PCI Express Root Port 1\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0xc4\n Driver: \"pcieport\"\n IRQ: 17 (no events)\n Module Alias: \"pci:v00008086d00001E10sv0000103Csd00001858bc06sc04i00\"\n Driver Info #0:\n Driver Status: shpchp is active\n Driver Activation Cmd: \"modprobe shpchp\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n24: PCI 1f.0: 0601 ISA bridge\n [Created at pci.378]\n Unique ID: BUZT.yM96SWmd_t5\n SysFS ID: /devices/pci0000:00/0000:00:1f.0\n SysFS BusID: 0000:00:1f.0\n Hardware Class: bridge\n Model: \"Intel HM75 Express Chipset LPC Controller\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x1e5d \"HM75 Express Chipset LPC Controller\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x04\n Driver: \"lpc_ich\"\n Driver Modules: \"lpc_ich\"\n Module Alias: \"pci:v00008086d00001E5Dsv0000103Csd00001858bc06sc01i00\"\n Driver Info #0:\n Driver Status: lpc_ich is active\n Driver Activation Cmd: \"modprobe lpc_ich\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n25: PCI 200.0: 0282 WLAN controller\n [Created at pci.378]\n Unique ID: S6TQ.MxvvoCwdjwB\n Parent ID: hoOk.sI1gvBg1ci2\n SysFS ID: /devices/pci0000:00/0000:00:1c.2/0000:02:00.0\n SysFS BusID: 0000:02:00.0\n Hardware Class: network\n Device Name: \"Ralink RT3290LE 802.11bgn 1x1 Wi-Fi\"\n Model: \"Hewlett-Packard Company Ralink RT3290LE 802.11bgn 1x1 Wi-Fi and Bluetooth 4.0 Combo Adapter\"\n Vendor: pci 0x1814 \"Ralink corp.\"\n Device: pci 0x3290 \"RT3290 Wireless 802.11n 1T/1R PCIe\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x18ec \"Ralink RT3290LE 802.11bgn 1x1 Wi-Fi and Bluetooth 4.0 Combo Adapter\"\n Driver: \"rt2800pci\"\n Driver Modules: \"rt2800pci\"\n Device File: wlo1\n Features: WLAN\n Memory Range: 0xc2510000-0xc251ffff (rw,non-prefetchable)\n IRQ: 18 (no events)\n HW Address: a4:17:31:2b:c9:99\n Permanent HW Address: a4:17:31:2b:c9:99\n Link detected: no\n WLAN channels: 1 2 3 4 5 6 7 8 9 10 11 12 13 14\n WLAN frequencies: 2.412 2.417 2.422 2.427 2.432 2.437 2.442 2.447 2.452 2.457 2.462 2.467 2.472 2.484\n WLAN encryption modes: WEP40 WEP104 TKIP CCMP\n WLAN authentication modes: open sharedkey wpa-psk wpa-eap\n Module Alias: \"pci:v00001814d00003290sv0000103Csd000018ECbc02sc80i00\"\n Driver Info #0:\n Driver Status: rt2800pci is active\n Driver Activation Cmd: \"modprobe rt2800pci\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #20 (PCI bridge)\n\n26: PCI 16.0: 0780 Communication controller\n [Created at pci.378]\n Unique ID: WnlC.PAfzourt1C4\n SysFS ID: /devices/pci0000:00/0000:00:16.0\n SysFS BusID: 0000:00:16.0\n Hardware Class: unknown\n Model: \"Intel 7 Series/C216 Chipset Family MEI Controller #1\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x1e3a \"7 Series/C216 Chipset Family MEI Controller #1\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x04\n Driver: \"mei_me\"\n Driver Modules: \"mei_me\"\n Memory Range: 0xc2604000-0xc260400f (rw,non-prefetchable)\n IRQ: 28 (15 events)\n Module Alias: \"pci:v00008086d00001E3Asv0000103Csd00001858bc07sc80i00\"\n Driver Info #0:\n Driver Status: mei_me is active\n Driver Activation Cmd: \"modprobe mei_me\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n27: PCI 100.0: 0200 Ethernet controller\n [Created at pci.378]\n Unique ID: wcdH.sjC_dQ9MUK2\n Parent ID: z8Q3.oeFg_vBDVA1\n SysFS ID: /devices/pci0000:00/0000:00:1c.0/0000:01:00.0\n SysFS BusID: 0000:01:00.0\n Hardware Class: network\n Device Name: \"Realtek PCIe GBE Family Controller\"\n Model: \"Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller\"\n Vendor: pci 0x10ec \"Realtek Semiconductor Co., Ltd.\"\n Device: pci 0x8168 \"RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x07\n Driver: \"r8169\"\n Driver Modules: \"r8169\"\n Device File: eno1\n I/O Ports: 0x3000-0x3fff (rw)\n Memory Range: 0xc2404000-0xc2404fff (ro,non-prefetchable)\n Memory Range: 0xc2400000-0xc2403fff (ro,non-prefetchable)\n IRQ: 24 (33 events)\n HW Address: c8:cb:b8:5a:5a:bb\n Permanent HW Address: c8:cb:b8:5a:5a:bb\n Link detected: yes\n Module Alias: \"pci:v000010ECd00008168sv0000103Csd00001858bc02sc00i00\"\n Driver Info #0:\n Driver Status: r8169 is active\n Driver Activation Cmd: \"modprobe r8169\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #23 (PCI bridge)\n\n28: PCI 1b.0: 0403 Audio device\n [Created at pci.378]\n Unique ID: u1Nb.VYL+dt4oNC7\n SysFS ID: /devices/pci0000:00/0000:00:1b.0\n SysFS BusID: 0000:00:1b.0\n Hardware Class: sound\n Model: \"Intel 7 Series/C216 Chipset Family High Definition Audio Controller\"\n Vendor: pci 0x8086 \"Intel Corporation\"\n Device: pci 0x1e20 \"7 Series/C216 Chipset Family High Definition Audio Controller\"\n SubVendor: pci 0x103c \"Hewlett-Packard Company\"\n SubDevice: pci 0x1858 \n Revision: 0x04\n Driver: \"snd_hda_intel\"\n Driver Modules: \"snd_hda_intel\"\n Memory Range: 0xc2600000-0xc2603fff (rw,non-prefetchable)\n IRQ: 29 (422 events)\n Module Alias: \"pci:v00008086d00001E20sv0000103Csd00001858bc04sc03i00\"\n Driver Info #0:\n Driver Status: snd_hda_intel is active\n Driver Activation Cmd: \"modprobe snd_hda_intel\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n29: None 00.0: 10002 LCD Monitor\n [Created at monitor.125]\n Unique ID: rdCR.w6MDDLMZW2E\n Parent ID: _Znp.nDJOnrrEzD7\n Hardware Class: monitor\n Model: \"LCD Monitor\"\n Vendor: SEC \n Device: eisa 0x325a \n Resolution: 1366x768@60Hz\n Size: 344x194 mm\n Year of Manufacture: 2012\n Week of Manufacture: 0\n Detailed Timings #0:\n Resolution: 1366x768\n Horizontal: 1366 1430 1478 1606 (+64 +112 +240) -hsync\n Vertical: 768 770 775 792 (+2 +7 +24) -vsync\n Frequencies: 50.80 MHz, 31.63 kHz, 39.94 Hz\n Year of Manufacture: 2012\n Week of Manufacture: 0\n Detailed Timings #1:\n Resolution: 1366x768\n Horizontal: 1366 1430 1478 1606 (+64 +112 +240) -hsync\n Vertical: 768 770 775 792 (+2 +7 +24) -vsync\n Frequencies: 76.30 MHz, 47.51 kHz, 59.99 Hz\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #19 (VGA compatible controller)\n\n30: ISA(PnP) 00.0: 0000 Unclassified device\n [Created at isapnp.142]\n Unique ID: z9pp.B+yZ9Ve8gC1\n SysFS ID: /devices/pnp0/00:00\n SysFS BusID: 00:00\n Hardware Class: unknown\n Model: \"Unclassified device\"\n SubVendor: PNP \"PnP\"\n SubDevice: eisa 0x0c02 \n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n31: ISA(PnP) 00.0: 0000 Unclassified device\n [Created at isapnp.142]\n Unique ID: E349.B+yZ9Ve8gC1\n SysFS ID: /devices/pnp0/00:05\n SysFS BusID: 00:05\n Hardware Class: unknown\n Model: \"Unclassified device\"\n SubVendor: PNP \"PnP\"\n SubDevice: eisa 0x0c02 \n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n32: ISA(PnP) 00.0: 0000 Unclassified device\n [Created at isapnp.142]\n Unique ID: KiZ0.ealKjhMMg54\n SysFS ID: /devices/pnp0/00:03\n SysFS BusID: 00:03\n Hardware Class: unknown\n Model: \"Unclassified device\"\n SubVendor: HPQ \n SubDevice: eisa 0x8001 \n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n33: ISA(PnP) 00.0: 0000 Unclassified device\n [Created at isapnp.142]\n Unique ID: QL3u.WYwRElrJa93\n SysFS ID: /devices/pnp0/00:01\n SysFS BusID: 00:01\n Hardware Class: unknown\n Model: \"Unclassified device\"\n SubVendor: PNP \"PnP\"\n SubDevice: eisa 0x0b00 \n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n34: ISA(PnP) 00.0: 0000 Unclassified device\n [Created at isapnp.142]\n Unique ID: hEKD.gNN83gfynbD\n SysFS ID: /devices/pnp0/00:06\n SysFS BusID: 00:06\n Hardware Class: unknown\n Model: \"Unclassified device\"\n SubVendor: PNP \"PnP\"\n SubDevice: eisa 0x0c01 \n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n35: ISA(PnP) 00.0: 0000 Unclassified device\n [Created at isapnp.142]\n Unique ID: ntp4.lcHkZueIptF\n SysFS ID: /devices/pnp0/00:04\n SysFS BusID: 00:04\n Hardware Class: unknown\n Model: \"Unclassified device\"\n SubVendor: SYN \n SubDevice: eisa 0x1e68 \n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n36: ISA(PnP) 00.0: 0000 Unclassified device\n [Created at isapnp.142]\n Unique ID: tWJy.fzmL0Yx8Ld7\n SysFS ID: /devices/pnp0/00:02\n SysFS BusID: 00:02\n Hardware Class: unknown\n Model: \"Unclassified device\"\n SubVendor: INT \n SubDevice: eisa 0x3f0d \n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n37: SCSI 600.0: 10600 Disk\n [Created at block.245]\n Unique ID: tGrL.VJYcNaX5Ib0\n Parent ID: 1GTX.Dw1+vYRmbuF\n SysFS ID: /class/block/sdb\n SysFS BusID: 6:0:0:0\n SysFS Device Link: /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/host6/target6:0:0/6:0:0:0\n Hardware Class: disk\n Model: \"TOSHIBA TransMemory\"\n Vendor: usb 0x0930 \"TOSHIBA\"\n Device: usb 0x6544 \"TransMemory\"\n Revision: \"1.00\"\n Serial ID: \"B\"\n Driver: \"usb-storage\", \"sd\"\n Driver Modules: \"usb_storage\", \"sd_mod\"\n Device File: /dev/sdb (/dev/sg2)\n Device Files: /dev/sdb, /dev/disk/by-id/usb-TOSHIBA_TransMemory_B2910FB31BD7CEA033DE686E-0:0, /dev/disk/by-path/pci-0000:00:1d.0-usb-0:1.2:1.0-scsi-0:0:0:0\n Device Number: block 8:16-8:31 (char 21:2)\n Geometry (Logical): CHS 1022/239/62\n Size: 15155200 sectors a 512 bytes\n Capacity: 7 GB (7759462400 bytes)\n Speed: 480 Mbps\n Module Alias: \"usb:v0930p6544d0100dc00dsc00dp00ic08isc06ip50in00\"\n Driver Info #0:\n Driver Status: uas is active\n Driver Activation Cmd: \"modprobe uas\"\n Driver Info #1:\n Driver Status: usb_storage is active\n Driver Activation Cmd: \"modprobe usb_storage\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #18 (USB Controller)\n\n38: None 00.0: 11300 Partition\n [Created at block.434]\n Unique ID: h4pj.SE1wIdpsiiC\n Parent ID: tGrL.VJYcNaX5Ib0\n SysFS ID: /class/block/sdb/sdb1\n Hardware Class: partition\n Model: \"Partition\"\n Device File: /dev/sdb1\n Device Files: /dev/sdb1, /dev/disk/by-id/usb-TOSHIBA_TransMemory_B2910FB31BD7CEA033DE686E-0:0-part1, /dev/disk/by-label/ISOIMAGE, /dev/disk/by-partuuid/00de13ce-01, /dev/disk/by-path/pci-0000:00:1d.0-usb-0:1.2:1.0-scsi-0:0:0:0-part1, /dev/disk/by-uuid/3695-7B86\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #37 (Disk)\n\n39: SCSI 200.0: 10602 CD-ROM (DVD)\n [Created at block.249]\n Unique ID: KD9E.me6G04CQ0G1\n Parent ID: w7Y8.3v_DiuY8eC2\n SysFS ID: /class/block/sr0\n SysFS BusID: 2:0:0:0\n SysFS Device Link: /devices/pci0000:00/0000:00:1f.2/ata3/host2/target2:0:0/2:0:0:0\n Hardware Class: cdrom\n Model: \"hp DVD A DS8A8SH\"\n Vendor: \"hp\"\n Device: \"DVD A DS8A8SH\"\n Revision: \"KH63\"\n Driver: \"ahci\", \"sr\"\n Driver Modules: \"ahci\", \"sr_mod\"\n Device File: /dev/sr0 (/dev/sg1)\n Device Files: /dev/sr0, /dev/cdrom, /dev/cdrw, /dev/disk/by-id/ata-hp_DVD_A_DS8A8SH_656243044983, /dev/disk/by-path/pci-0000:00:1f.2-ata-3, /dev/dvd, /dev/dvdrw\n Device Number: block 11:0 (char 21:1)\n Features: CD-R, CD-RW, DVD, DVD-R, DVD-RW, DVD-R DL, DVD+R, DVD+RW, DVD+R DL, DVD-RAM, MRW, MRW-W\n Drive status: no medium\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #21 (SATA controller)\n Drive Speed: 24\n\n40: IDE 00.0: 10600 Disk\n [Created at block.245]\n Unique ID: 3OOL.cpntrRN2+88\n Parent ID: w7Y8.3v_DiuY8eC2\n SysFS ID: /class/block/sda\n SysFS BusID: 0:0:0:0\n SysFS Device Link: /devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0\n Hardware Class: disk\n Model: \"ST500LT012-9WS14\"\n Device: \"ST500LT012-9WS14\"\n Revision: \"YAM1\"\n Serial ID: \"W0V3SHRV\"\n Driver: \"ahci\", \"sd\"\n Driver Modules: \"ahci\", \"sd_mod\"\n Device File: /dev/sda\n Device Files: /dev/sda, /dev/disk/by-id/ata-ST500LT012-9WS142_W0V3SHRV, /dev/disk/by-id/wwn-0x5000c5005ce5d111, /dev/disk/by-path/pci-0000:00:1f.2-ata-1\n Device Number: block 8:0-8:15\n Geometry (Logical): CHS 60801/255/63\n Size: 976773168 sectors a 512 bytes\n Capacity: 465 GB (500107862016 bytes)\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #21 (SATA controller)\n\n41: USB 00.1: 0000 Unclassified device\n [Created at usb.122]\n Unique ID: maja.+kCojFDUyKC\n Parent ID: FKGF.4Nx_qoDfSd7\n SysFS ID: /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1\n SysFS BusID: 2-1.3:1.1\n Hardware Class: unknown\n Model: \"Chicony Electronics HP Truevision HD\"\n Hotplug: USB\n Vendor: usb 0x04f2 \"Chicony Electronics Co., Ltd\"\n Device: usb 0xb34f \"HP Truevision HD\"\n Revision: \"60.47\"\n Serial ID: \"0x0001\"\n Driver: \"uvcvideo\"\n Driver Modules: \"uvcvideo\"\n Speed: 480 Mbps\n Module Alias: \"usb:v04F2pB34Fd6047dcEFdsc02dp01ic0Eisc02ip00in01\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #42 (Hub)\n\n42: USB 00.0: 10a00 Hub\n [Created at usb.122]\n Unique ID: FKGF.4Nx_qoDfSd7\n Parent ID: pBe4.oLWCeziExdF\n SysFS ID: /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0\n SysFS BusID: 2-1:1.0\n Hardware Class: hub\n Model: \"Intel Integrated Rate Matching Hub\"\n Hotplug: USB\n Vendor: usb 0x8087 \"Intel Corp.\"\n Device: usb 0x0024 \"Integrated Rate Matching Hub\"\n Driver: \"hub\"\n Driver Modules: \"usbcore\"\n Speed: 480 Mbps\n Module Alias: \"usb:v8087p0024d0000dc09dsc00dp01ic09isc00ip00in00\"\n Driver Info #0:\n Driver Status: usbcore is active\n Driver Activation Cmd: \"modprobe usbcore\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #47 (Hub)\n\n44: USB 00.0: 10a00 Hub\n [Created at usb.122]\n Unique ID: k4bc.FHd55n4xKo7\n Parent ID: pwJ7.qpeEHYGiHa2\n SysFS ID: /devices/pci0000:00/0000:00:1a.0/usb1/1-0:1.0\n SysFS BusID: 1-0:1.0\n Hardware Class: hub\n Model: \"Linux Foundation 2.0 root hub\"\n Hotplug: USB\n Vendor: usb 0x1d6b \"Linux Foundation\"\n Device: usb 0x0002 \"2.0 root hub\"\n Revision: \"4.09\"\n Serial ID: \"0000:00:1a.0\"\n Driver: \"hub\"\n Driver Modules: \"usbcore\"\n Speed: 480 Mbps\n Module Alias: \"usb:v1D6Bp0002d0409dc09dsc00dp00ic09isc00ip00in00\"\n Driver Info #0:\n Driver Status: usbcore is active\n Driver Activation Cmd: \"modprobe usbcore\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #17 (USB Controller)\n\n46: USB 00.0: 10a00 Hub\n [Created at usb.122]\n Unique ID: ADDn.4Nx_qoDfSd7\n Parent ID: k4bc.FHd55n4xKo7\n SysFS ID: /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1:1.0\n SysFS BusID: 1-1:1.0\n Hardware Class: hub\n Model: \"Intel Integrated Rate Matching Hub\"\n Hotplug: USB\n Vendor: usb 0x8087 \"Intel Corp.\"\n Device: usb 0x0024 \"Integrated Rate Matching Hub\"\n Driver: \"hub\"\n Driver Modules: \"usbcore\"\n Speed: 480 Mbps\n Module Alias: \"usb:v8087p0024d0000dc09dsc00dp01ic09isc00ip00in00\"\n Driver Info #0:\n Driver Status: usbcore is active\n Driver Activation Cmd: \"modprobe usbcore\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #44 (Hub)\n\n47: USB 00.0: 10a00 Hub\n [Created at usb.122]\n Unique ID: pBe4.oLWCeziExdF\n Parent ID: 1GTX.Dw1+vYRmbuF\n SysFS ID: /devices/pci0000:00/0000:00:1d.0/usb2/2-0:1.0\n SysFS BusID: 2-0:1.0\n Hardware Class: hub\n Model: \"Linux Foundation 2.0 root hub\"\n Hotplug: USB\n Vendor: usb 0x1d6b \"Linux Foundation\"\n Device: usb 0x0002 \"2.0 root hub\"\n Revision: \"4.09\"\n Serial ID: \"0000:00:1d.0\"\n Driver: \"hub\"\n Driver Modules: \"usbcore\"\n Speed: 480 Mbps\n Module Alias: \"usb:v1D6Bp0002d0409dc09dsc00dp00ic09isc00ip00in00\"\n Driver Info #0:\n Driver Status: usbcore is active\n Driver Activation Cmd: \"modprobe usbcore\"\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #18 (USB Controller)\n\n48: PS/2 00.0: 10800 Keyboard\n [Created at input.226]\n Unique ID: nLyy.+49ps10DtUF\n Hardware Class: keyboard\n Model: \"AT Translated Set 2 keyboard\"\n Vendor: 0x0001 \n Device: 0x0001 \"AT Translated Set 2 keyboard\"\n Compatible to: int 0x0211 0x0001\n Device File: /dev/input/event0\n Device Number: char 13:64\n Driver Info #0:\n XkbRules: xfree86\n XkbModel: pc104\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n49: PS/2 00.0: 10500 PS/2 Mouse\n [Created at input.249]\n Unique ID: AH6Q.ZHI3OT7LsxA\n Hardware Class: mouse\n Model: \"SynPS/2 Synaptics TouchPad\"\n Vendor: 0x0002 \n Device: 0x0007 \"SynPS/2 Synaptics TouchPad\"\n Compatible to: int 0x0210 0x0002\n Device File: /dev/input/mice (/dev/input/mouse0)\n Device Files: /dev/input/mice, /dev/input/mouse0, /dev/input/event5\n Device Number: char 13:63 (char 13:32)\n Driver Info #0:\n Buttons: 2\n Wheels: 0\n XFree86 Protocol: explorerps/2\n GPM Protocol: exps2\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n50: None 00.0: 10103 CPU\n [Created at cpu.460]\n Unique ID: rdCR.j8NaKXDZtZ6\n Hardware Class: cpu\n Arch: Intel\n Vendor: \"GenuineIntel\"\n Model: 6.42.7 \"Intel(R) Core(TM) i3-2328M CPU @ 2.20GHz\"\n Features: fpu,vme,de,pse,tsc,msr,pae,mce,cx8,apic,sep,mtrr,pge,mca,cmov,pat,pse36,clflush,dts,acpi,mmx,fxsr,sse,sse2,ss,ht,tm,pbe,nx,rdtscp,lm,constant_tsc,arch_perfmon,pebs,bts,xtopology,nonstop_tsc,aperfmperf,pni,pclmulqdq,dtes64,monitor,ds_cpl,vmx,est,tm2,ssse3,cx16,xtpr,pdcm,sse4_1,sse4_2,x2apic,popcnt,tsc_deadline_timer,xsave,avx,lahf_lm,epb,ssbd,ibrs,ibpb,stibp,tpr_shadow,vnmi,flexpriority,ept,vpid,xsaveopt,dtherm,arat,pln,pts,md_clear,flush_l1d\n Clock: 1106 MHz\n BogoMips: 4390.48\n Cache: 3072 kb\n Units/Processor: 16\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n51: None 01.0: 10103 CPU\n [Created at cpu.460]\n Unique ID: wkFv.j8NaKXDZtZ6\n Hardware Class: cpu\n Arch: Intel\n Vendor: \"GenuineIntel\"\n Model: 6.42.7 \"Intel(R) Core(TM) i3-2328M CPU @ 2.20GHz\"\n Features: fpu,vme,de,pse,tsc,msr,pae,mce,cx8,apic,sep,mtrr,pge,mca,cmov,pat,pse36,clflush,dts,acpi,mmx,fxsr,sse,sse2,ss,ht,tm,pbe,nx,rdtscp,lm,constant_tsc,arch_perfmon,pebs,bts,xtopology,nonstop_tsc,aperfmperf,pni,pclmulqdq,dtes64,monitor,ds_cpl,vmx,est,tm2,ssse3,cx16,xtpr,pdcm,sse4_1,sse4_2,x2apic,popcnt,tsc_deadline_timer,xsave,avx,lahf_lm,epb,ssbd,ibrs,ibpb,stibp,tpr_shadow,vnmi,flexpriority,ept,vpid,xsaveopt,dtherm,arat,pln,pts,md_clear,flush_l1d\n Clock: 833 MHz\n BogoMips: 4390.48\n Cache: 3072 kb\n Units/Processor: 16\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n52: None 02.0: 10103 CPU\n [Created at cpu.460]\n Unique ID: +rIN.j8NaKXDZtZ6\n Hardware Class: cpu\n Arch: Intel\n Vendor: \"GenuineIntel\"\n Model: 6.42.7 \"Intel(R) Core(TM) i3-2328M CPU @ 2.20GHz\"\n Features: fpu,vme,de,pse,tsc,msr,pae,mce,cx8,apic,sep,mtrr,pge,mca,cmov,pat,pse36,clflush,dts,acpi,mmx,fxsr,sse,sse2,ss,ht,tm,pbe,nx,rdtscp,lm,constant_tsc,arch_perfmon,pebs,bts,xtopology,nonstop_tsc,aperfmperf,pni,pclmulqdq,dtes64,monitor,ds_cpl,vmx,est,tm2,ssse3,cx16,xtpr,pdcm,sse4_1,sse4_2,x2apic,popcnt,tsc_deadline_timer,xsave,avx,lahf_lm,epb,ssbd,ibrs,ibpb,stibp,tpr_shadow,vnmi,flexpriority,ept,vpid,xsaveopt,dtherm,arat,pln,pts,md_clear,flush_l1d\n Clock: 1333 MHz\n BogoMips: 4390.48\n Cache: 3072 kb\n Units/Processor: 16\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n53: None 03.0: 10103 CPU\n [Created at cpu.460]\n Unique ID: 4zLr.j8NaKXDZtZ6\n Hardware Class: cpu\n Arch: Intel\n Vendor: \"GenuineIntel\"\n Model: 6.42.7 \"Intel(R) Core(TM) i3-2328M CPU @ 2.20GHz\"\n Features: fpu,vme,de,pse,tsc,msr,pae,mce,cx8,apic,sep,mtrr,pge,mca,cmov,pat,pse36,clflush,dts,acpi,mmx,fxsr,sse,sse2,ss,ht,tm,pbe,nx,rdtscp,lm,constant_tsc,arch_perfmon,pebs,bts,xtopology,nonstop_tsc,aperfmperf,pni,pclmulqdq,dtes64,monitor,ds_cpl,vmx,est,tm2,ssse3,cx16,xtpr,pdcm,sse4_1,sse4_2,x2apic,popcnt,tsc_deadline_timer,xsave,avx,lahf_lm,epb,ssbd,ibrs,ibpb,stibp,tpr_shadow,vnmi,flexpriority,ept,vpid,xsaveopt,dtherm,arat,pln,pts,md_clear,flush_l1d\n Clock: 1292 MHz\n BogoMips: 4390.48\n Cache: 3072 kb\n Units/Processor: 16\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n\n54: None 01.0: 10701 Ethernet\n [Created at net.126]\n Unique ID: VnCh.ndpeucax6V1\n Parent ID: S6TQ.MxvvoCwdjwB\n SysFS ID: /class/net/wlo1\n SysFS Device Link: /devices/pci0000:00/0000:00:1c.2/0000:02:00.0\n Hardware Class: network interface\n Model: \"Ethernet network interface\"\n Driver: \"rt2800pci\"\n Driver Modules: \"rt2800pci\"\n Device File: wlo1\n HW Address: a4:17:31:2b:c9:99\n Permanent HW Address: a4:17:31:2b:c9:99\n Link detected: no\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #25 (WLAN controller)\n\n55: None 01.0: 10701 Ethernet\n [Created at net.126]\n Unique ID: zHNY.ndpeucax6V1\n Parent ID: wcdH.sjC_dQ9MUK2\n SysFS ID: /class/net/eno1\n SysFS Device Link: /devices/pci0000:00/0000:00:1c.0/0000:01:00.0\n Hardware Class: network interface\n Model: \"Ethernet network interface\"\n Driver: \"r8169\"\n Driver Modules: \"r8169\"\n Device File: eno1\n HW Address: c8:cb:b8:5a:5a:bb\n Permanent HW Address: c8:cb:b8:5a:5a:bb\n Link detected: yes\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n Attached to: #27 (Ethernet controller)\n\n56: None 00.0: 10700 Loopback\n [Created at net.126]\n Unique ID: ZsBS.GQNx7L4uPNA\n SysFS ID: /class/net/lo\n Hardware Class: network interface\n Model: \"Loopback network interface\"\n Device File: lo\n Link detected: yes\n Config Status: cfg=new, avail=yes, need=no, active=unknown\n", "lshw": {"capabilities": {"dmi-2.7": "DMI version 2.7", "smbios-2.7": "SMBIOS version 2.7", "smp": "Symmetric Multi-Processing", "smp-1.4": "SMP specification v1.4"}, "children": [{"children": [{"children": [{"claimed": true, "class": "memory", "clock": 1333000000, "description": "SODIMM DDR3 Synchronous 1333 MHz (0.8 ns)", "handle": "DMI:0001", "id": "bank:0", "physid": "0", "product": "HP536727-H41-ELD", "serial": "552AE579", "size": 4294967296, "slot": "Bottom-Slot 2(under)", "units": "bytes", "vendor": "Kingston", "width": 64}, {"claimed": true, "class": "memory", "clock": 1333000000, "description": "SODIMM DDR3 Synchronous 1333 MHz (0.8 ns)", "handle": "DMI:0005", "id": "bank:1", "physid": "1", "product": "F3-12800CL11-4GBSQ", "serial": "00000000", "size": 4294967296, "slot": "Bottom-Slot 1(top)", "units": "bytes", "vendor": "Unknown", "width": 64}], "claimed": true, "class": "memory", "description": "System Memory", "handle": "DMI:0000", "id": "memory", "physid": "0", "size": 8589934592, "slot": "System board or motherboard", "units": "bytes"}, {"capabilities": {"acpi": "ACPI", "biosbootspecification": "BIOS boot specification", "bootselect": "Selectable boot path", "cdboot": "Booting from CD-ROM/DVD", "edd": "Enhanced Disk Drive extensions", "int10video": "INT10 CGA/Mono video", "int13floppy1200": "5.25\" 1.2MB floppy", "int13floppy2880": "3.5\" 2.88MB floppy", "int13floppy360": "5.25\" 360KB floppy", "int13floppy720": "3.5\" 720KB floppy", "int13floppynec": "NEC 9800 floppy", "int13floppytoshiba": "Toshiba floppy", "int9keyboard": "i8042 keyboard controller", "pci": "PCI bus", "shadowing": "BIOS shadowing", "uefi": "UEFI specification is supported", "upgrade": "BIOS EEPROM can be upgraded", "usb": "USB legacy emulation"}, "capacity": 2555904, "claimed": true, "class": "memory", "date": "05/13/2014", "description": "BIOS", "id": "firmware", "physid": "c", "size": 131072, "units": "bytes", "vendor": "Insyde", "version": "F.39"}, {"businfo": "cpu@0", "capabilities": {"acpi": "thermal control (ACPI)", "aperfmperf": true, "apic": "on-chip advanced programmable interrupt controller (APIC)", "arat": true, "arch_perfmon": true, "avx": true, "boot": "boot processor", "bts": true, "clflush": true, "cmov": "conditional move instruction", "constant_tsc": true, "cpufreq": "CPU Frequency scaling", "cx16": true, "cx8": "compare and exchange 8-byte", "de": "debugging extensions", "ds_cpl": true, "dtes64": true, "dtherm": true, "dts": "debug trace and EMON store MSRs", "epb": true, "ept": true, "est": true, "flexpriority": true, "flush_l1d": true, "fpu": "mathematical co-processor", "fpu_exception": "FPU exceptions reporting", "fxsr": "fast floating point save/restore", "ht": "HyperThreading", "ibpb": true, "ibrs": true, "lahf_lm": true, "mca": "machine check architecture", "mce": "machine check exceptions", "md_clear": true, "mmx": "multimedia extensions (MMX)", "monitor": true, "msr": "model-specific registers", "mtrr": "memory type range registers", "nonstop_tsc": true, "nx": "no-execute bit (NX)", "pae": "4GB+ memory addressing (Physical Address Extension)", "pat": "page attribute table", "pbe": "pending break event", "pclmulqdq": true, "pdcm": true, "pebs": true, "pge": "page global enable", "pln": true, "pni": true, "popcnt": true, "pse": "page size extensions", "pse36": "36-bit page size extensions", "pts": true, "rdtscp": true, "sep": "fast system calls", "ss": "self-snoop", "ssbd": true, "sse": "streaming SIMD extensions (SSE)", "sse2": "streaming SIMD extensions (SSE2)", "sse4_1": true, "sse4_2": true, "ssse3": true, "stibp": true, "tm": "thermal interrupt and status", "tm2": true, "tpr_shadow": true, "tsc": "time stamp counter", "tsc_deadline_timer": true, "vme": "virtual mode extensions", "vmx": "CPU virtualization (Vanderpool)", "vnmi": true, "vpid": true, "wp": true, "x2apic": true, "x86-64": "64bits extensions (x86-64)", "xsave": true, "xsaveopt": true, "xtopology": true, "xtpr": true}, "capacity": 4000000000, "children": [{"capabilities": {"instruction": "Instruction cache", "internal": "Internal", "write-through": "Write-trough"}, "capacity": 32768, "claimed": true, "class": "memory", "configuration": {"level": "1"}, "description": "L1 cache", "handle": "DMI:0035", "id": "cache:0", "physid": "35", "size": 32768, "slot": "L1 Cache", "units": "bytes"}, {"capabilities": {"internal": "Internal", "unified": "Unified cache", "write-through": "Write-trough"}, "capacity": 262144, "claimed": true, "class": "memory", "configuration": {"level": "2"}, "description": "L2 cache", "handle": "DMI:0036", "id": "cache:1", "physid": "36", "size": 262144, "slot": "L2 Cache", "units": "bytes"}, {"capabilities": {"internal": "Internal", "unified": "Unified cache", "write-back": "Write-back"}, "capacity": 3145728, "claimed": true, "class": "memory", "configuration": {"level": "3"}, "description": "L3 cache", "handle": "DMI:0037", "id": "cache:2", "physid": "37", "size": 3145728, "slot": "L3 Cache", "units": "bytes"}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.0", "id": "logicalcpu:0", "physid": "2.1", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.1", "id": "logicalcpu:1", "physid": "2.2", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.2", "id": "logicalcpu:2", "physid": "2.3", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.3", "id": "logicalcpu:3", "physid": "2.4", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.4", "id": "logicalcpu:4", "physid": "2.5", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.5", "id": "logicalcpu:5", "physid": "2.6", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.6", "id": "logicalcpu:6", "physid": "2.7", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.7", "id": "logicalcpu:7", "physid": "2.8", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.8", "id": "logicalcpu:8", "physid": "2.9", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.9", "id": "logicalcpu:9", "physid": "2.a", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.10", "id": "logicalcpu:10", "physid": "2.b", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.11", "id": "logicalcpu:11", "physid": "2.c", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.12", "id": "logicalcpu:12", "physid": "2.d", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.13", "id": "logicalcpu:13", "physid": "2.e", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.14", "id": "logicalcpu:14", "physid": "2.f", "width": 64}, {"capabilities": {"logical": "Logical CPU"}, "claimed": true, "class": "processor", "description": "Logical CPU", "handle": "CPU:2.15", "id": "logicalcpu:15", "physid": "2.10", "width": 64}], "claimed": true, "class": "processor", "clock": 100000000, "configuration": {"cores": "2", "enabledcores": "2", "id": "2", "threads": "4"}, "description": "CPU", "handle": "DMI:0033", "id": "cpu", "physid": "33", "product": "Intel(R) Core(TM) i3-2328M CPU @ 2.20GHz", "serial": "0002-06A7-0000-0000-0000-0000", "size": 800964000, "slot": "U3E1", "units": "Hz", "vendor": "Intel Corp.", "version": "6.10.7", "width": 64}, {"capabilities": {"data": "Data cache", "internal": "Internal", "write-through": "Write-trough"}, "capacity": 32768, "claimed": true, "class": "memory", "configuration": {"level": "1"}, "description": "L1 cache", "handle": "DMI:0034", "id": "cache", "physid": "34", "size": 32768, "slot": "L1 Cache", "units": "bytes"}, {"businfo": "pci@0000:00:00.0", "children": [{"businfo": "pci@0000:00:02.0", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "msi": "Message Signalled Interrupts", "pm": "Power Management", "rom": "extension ROM", "vga_controller": true}, "claimed": true, "class": "display", "clock": 33000000, "configuration": {"driver": "i915", "latency": "0"}, "description": "VGA compatible controller", "handle": "PCI:0000:00:02.0", "id": "display", "physid": "2", "product": "2nd Generation Core Processor Family Integrated Graphics Controller", "vendor": "Intel Corporation", "version": "09", "width": 64}, {"businfo": "pci@0000:00:16.0", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "msi": "Message Signalled Interrupts", "pm": "Power Management"}, "claimed": true, "class": "communication", "clock": 33000000, "configuration": {"driver": "mei_me", "latency": "0"}, "description": "Communication controller", "handle": "PCI:0000:00:16.0", "id": "communication", "physid": "16", "product": "7 Series/C216 Chipset Family MEI Controller #1", "vendor": "Intel Corporation", "version": "04", "width": 64}, {"businfo": "pci@0000:00:1a.0", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "debug": "Debug port", "ehci": "Enhanced Host Controller Interface (USB2)", "pm": "Power Management"}, "children": [{"businfo": "usb@1", "capabilities": {"usb-2.00": "USB 2.0"}, "children": [{"businfo": "usb@1:1", "capabilities": {"usb-2.00": "USB 2.0"}, "claimed": true, "class": "bus", "configuration": {"driver": "hub", "slots": "6", "speed": "480Mbit/s"}, "description": "USB hub", "handle": "USB:1:2", "id": "usb", "physid": "1", "product": "Integrated Rate Matching Hub", "vendor": "Intel Corp.", "version": "0.00"}], "claimed": true, "class": "bus", "configuration": {"driver": "hub", "slots": "2", "speed": "480Mbit/s"}, "handle": "USB:1:1", "id": "usbhost", "logicalname": "usb1", "physid": "1", "product": "EHCI Host Controller", "vendor": "Linux 4.9.0-14-686-pae ehci_hcd", "version": "4.09"}], "claimed": true, "class": "bus", "clock": 33000000, "configuration": {"driver": "ehci-pci", "latency": "0"}, "description": "USB controller", "handle": "PCI:0000:00:1a.0", "id": "usb:0", "physid": "1a", "product": "7 Series/C216 Chipset Family USB Enhanced Host Controller #2", "vendor": "Intel Corporation", "version": "04", "width": 32}, {"businfo": "pci@0000:00:1b.0", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "msi": "Message Signalled Interrupts", "pciexpress": "PCI Express", "pm": "Power Management"}, "claimed": true, "class": "multimedia", "clock": 33000000, "configuration": {"driver": "snd_hda_intel", "latency": "0"}, "description": "Audio device", "handle": "PCI:0000:00:1b.0", "id": "multimedia", "physid": "1b", "product": "7 Series/C216 Chipset Family High Definition Audio Controller", "vendor": "Intel Corporation", "version": "04", "width": 64}, {"businfo": "pci@0000:00:1c.0", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "msi": "Message Signalled Interrupts", "normal_decode": true, "pci": true, "pciexpress": "PCI Express", "pm": "Power Management"}, "children": [{"businfo": "pci@0000:01:00.0", "capabilities": {"1000bt": "1Gbit/s", "1000bt-fd": "1Gbit/s (full duplex)", "100bt": "100Mbit/s", "100bt-fd": "100Mbit/s (full duplex)", "10bt": "10Mbit/s", "10bt-fd": "10Mbit/s (full duplex)", "autonegotiation": "Auto-negotiation", "bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "ethernet": true, "mii": "Media Independent Interface", "msi": "Message Signalled Interrupts", "msix": "MSI-X", "pciexpress": "PCI Express", "physical": "Physical interface", "pm": "Power Management", "tp": "twisted pair", "vpd": "Vital Product Data"}, "capacity": 1000000000, "claimed": true, "class": "network", "clock": 33000000, "configuration": {"autonegotiation": "on", "broadcast": "yes", "driver": "r8169", "driverversion": "2.3LK-NAPI", "duplex": "full", "firmware": "rtl8168e-3_0.0.4 03/27/12", "ip": "192.168.5.40", "latency": "0", "link": "yes", "multicast": "yes", "port": "MII", "speed": "100Mbit/s"}, "description": "Ethernet interface", "handle": "PCI:0000:01:00.0", "id": "network", "logicalname": "eno1", "physid": "0", "product": "RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller", "serial": "c8:cb:b8:5a:5a:bb", "size": 100000000, "units": "bit/s", "vendor": "Realtek Semiconductor Co., Ltd.", "version": "07", "width": 64}], "claimed": true, "class": "bridge", "clock": 33000000, "configuration": {"driver": "pcieport"}, "description": "PCI bridge", "handle": "PCIBUS:0000:01", "id": "pci:0", "physid": "1c", "product": "7 Series/C216 Chipset Family PCI Express Root Port 1", "vendor": "Intel Corporation", "version": "c4", "width": 32}, {"businfo": "pci@0000:00:1c.2", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "msi": "Message Signalled Interrupts", "normal_decode": true, "pci": true, "pciexpress": "PCI Express", "pm": "Power Management"}, "children": [{"businfo": "pci@0000:02:00.0", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "ethernet": true, "msi": "Message Signalled Interrupts", "pciexpress": "PCI Express", "physical": "Physical interface", "pm": "Power Management", "wireless": "Wireless-LAN"}, "claimed": true, "class": "network", "clock": 33000000, "configuration": {"broadcast": "yes", "driver": "rt2800pci", "driverversion": "4.9.0-14-686-pae", "firmware": "N/A", "latency": "0", "link": "no", "multicast": "yes", "wireless": "IEEE 802.11"}, "description": "Wireless interface", "disabled": true, "handle": "PCI:0000:02:00.0", "id": "network", "logicalname": "wlo1", "physid": "0", "product": "RT3290 Wireless 802.11n 1T/1R PCIe", "serial": "a4:17:31:2b:c9:99", "vendor": "Ralink corp.", "version": "00", "width": 32}, {"businfo": "pci@0000:02:00.1", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "msi": "Message Signalled Interrupts", "pciexpress": "PCI Express", "pm": "Power Management"}, "class": "generic", "clock": 33000000, "configuration": {"latency": "0"}, "description": "Bluetooth", "handle": "PCI:0000:02:00.1", "id": "generic", "physid": "0.1", "product": "RT3290 Bluetooth", "vendor": "Ralink corp.", "version": "00", "width": 32}], "claimed": true, "class": "bridge", "clock": 33000000, "configuration": {"driver": "pcieport"}, "description": "PCI bridge", "handle": "PCIBUS:0000:02", "id": "pci:1", "physid": "1c.2", "product": "7 Series/C210 Series Chipset Family PCI Express Root Port 3", "vendor": "Intel Corporation", "version": "c4", "width": 32}, {"businfo": "pci@0000:00:1c.3", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "msi": "Message Signalled Interrupts", "normal_decode": true, "pci": true, "pciexpress": "PCI Express", "pm": "Power Management"}, "children": [{"businfo": "pci@0000:03:00.0", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "msi": "Message Signalled Interrupts", "pciexpress": "PCI Express", "pm": "Power Management"}, "claimed": true, "class": "generic", "clock": 33000000, "configuration": {"driver": "rtsx_pci", "latency": "0"}, "description": "Unassigned class", "handle": "PCI:0000:03:00.0", "id": "generic", "physid": "0", "product": "RTS5229 PCI Express Card Reader", "vendor": "Realtek Semiconductor Co., Ltd.", "version": "01", "width": 32}], "claimed": true, "class": "bridge", "clock": 33000000, "configuration": {"driver": "pcieport"}, "description": "PCI bridge", "handle": "PCIBUS:0000:03", "id": "pci:2", "physid": "1c.3", "product": "7 Series/C216 Chipset Family PCI Express Root Port 4", "vendor": "Intel Corporation", "version": "c4", "width": 32}, {"businfo": "pci@0000:00:1d.0", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "debug": "Debug port", "ehci": "Enhanced Host Controller Interface (USB2)", "pm": "Power Management"}, "children": [{"businfo": "usb@2", "capabilities": {"usb-2.00": "USB 2.0"}, "children": [{"businfo": "usb@2:1", "capabilities": {"usb-2.00": "USB 2.0"}, "children": [{"businfo": "usb@2:1.2", "capabilities": {"emulated": "Emulated device", "scsi": "SCSI", "usb-2.00": "USB 2.0"}, "children": [{"businfo": "scsi@6:0.0.0", "capabilities": {"removable": "support is removable"}, "children": [{"capabilities": {"partitioned": "Partitioned disk", "partitioned:dos": "MS-DOS partition table"}, "children": [{"capabilities": {"bootable": "Bootable partition (active)", "fat": "Windows FAT", "initialized": "initialized volume", "primary": "Primary partition"}, "capacity": 7758413824, "claimed": true, "class": "volume", "configuration": {"FATs": "2", "filesystem": "fat", "label": "ISOIMAGE", "mount.fstype": "vfat", "mount.options": "ro,noatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro", "state": "mounted"}, "description": "Windows FAT volume", "dev": "8:17", "id": "volume", "logicalname": ["/dev/sdb1", "/lib/live/mount/medium"], "physid": "1", "serial": "3695-7b86", "size": 7755709440, "vendor": "SYSLINUX", "version": "FAT32"}], "claimed": true, "class": "disk", "configuration": {"signature": "00de13ce"}, "dev": "8:16", "id": "medium", "logicalname": "/dev/sdb", "physid": "0", "size": 7759462400, "units": "bytes"}], "claimed": true, "class": "disk", "configuration": {"ansiversion": "4", "logicalsectorsize": "512", "sectorsize": "512"}, "description": "SCSI Disk", "dev": "8:16", "handle": "SCSI:06:00:00:00", "id": "disk", "logicalname": "/dev/sdb", "physid": "0.0.0", "product": "TransMemory", "serial": "B", "size": 7759462400, "units": "bytes", "vendor": "TOSHIBA", "version": "1.00"}], "claimed": true, "class": "storage", "configuration": {"driver": "usb-storage", "maxpower": "200mA", "speed": "480Mbit/s"}, "description": "Mass storage device", "handle": "USB:2:3", "id": "usb:0", "logicalname": "scsi6", "physid": "2", "product": "TransMemory", "serial": "B2910FB31BD7CEA033DE686E", "vendor": "TOSHIBA", "version": "1.00"}, {"businfo": "usb@2:1.3", "capabilities": {"usb-2.00": "USB 2.0"}, "claimed": true, "class": "multimedia", "configuration": {"driver": "uvcvideo", "maxpower": "500mA", "speed": "480Mbit/s"}, "description": "Video", "handle": "USB:2:4", "id": "usb:1", "physid": "3", "product": "HP Truevision HD", "serial": "0x0001", "vendor": "Chicony Electronics Co.,Ltd.", "version": "60.47"}], "claimed": true, "class": "bus", "configuration": {"driver": "hub", "slots": "6", "speed": "480Mbit/s"}, "description": "USB hub", "handle": "USB:2:2", "id": "usb", "physid": "1", "product": "Integrated Rate Matching Hub", "vendor": "Intel Corp.", "version": "0.00"}], "claimed": true, "class": "bus", "configuration": {"driver": "hub", "slots": "2", "speed": "480Mbit/s"}, "handle": "USB:2:1", "id": "usbhost", "logicalname": "usb2", "physid": "1", "product": "EHCI Host Controller", "vendor": "Linux 4.9.0-14-686-pae ehci_hcd", "version": "4.09"}], "claimed": true, "class": "bus", "clock": 33000000, "configuration": {"driver": "ehci-pci", "latency": "0"}, "description": "USB controller", "handle": "PCI:0000:00:1d.0", "id": "usb:1", "physid": "1d", "product": "7 Series/C216 Chipset Family USB Enhanced Host Controller #1", "vendor": "Intel Corporation", "version": "04", "width": 32}, {"businfo": "pci@0000:00:1f.0", "capabilities": {"bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "isa": true}, "claimed": true, "class": "bridge", "clock": 33000000, "configuration": {"driver": "lpc_ich", "latency": "0"}, "description": "ISA bridge", "handle": "PCI:0000:00:1f.0", "id": "isa", "physid": "1f", "product": "HM75 Express Chipset LPC Controller", "vendor": "Intel Corporation", "version": "04", "width": 32}, {"businfo": "pci@0000:00:1f.2", "capabilities": {"ahci_1.0": true, "bus_master": "bus mastering", "cap_list": "PCI capabilities listing", "msi": "Message Signalled Interrupts", "pm": "Power Management", "storage": true}, "claimed": true, "class": "storage", "clock": 66000000, "configuration": {"driver": "ahci", "latency": "0"}, "description": "SATA controller", "handle": "PCI:0000:00:1f.2", "id": "storage", "physid": "1f.2", "product": "7 Series Chipset Family 6-port SATA Controller [AHCI mode]", "vendor": "Intel Corporation", "version": "04", "width": 32}, {"businfo": "pci@0000:00:1f.3", "claimed": true, "class": "bus", "clock": 33000000, "configuration": {"driver": "i801_smbus", "latency": "0"}, "description": "SMBus", "handle": "PCI:0000:00:1f.3", "id": "serial", "physid": "1f.3", "product": "7 Series/C216 Chipset Family SMBus Controller", "vendor": "Intel Corporation", "version": "04", "width": 64}], "claimed": true, "class": "bridge", "clock": 33000000, "description": "Host bridge", "handle": "PCIBUS:0000:00", "id": "pci", "physid": "100", "product": "2nd Generation Core Processor Family DRAM Controller", "vendor": "Intel Corporation", "version": "09", "width": 32}, {"capabilities": {"emulated": "Emulated device"}, "children": [{"businfo": "scsi@0:0.0.0", "claimed": true, "class": "disk", "configuration": {"ansiversion": "5", "logicalsectorsize": "512", "sectorsize": "4096"}, "description": "ATA Disk", "dev": "8:0", "handle": "SCSI:00:00:00:00", "id": "disk", "logicalname": "/dev/sda", "physid": "0.0.0", "product": "ST500LT012-9WS14", "serial": "W0V3SHRV", "size": 500107862016, "units": "bytes", "vendor": "Seagate", "version": "YAM1"}], "claimed": true, "class": "storage", "id": "scsi:0", "logicalname": "scsi0", "physid": "1"}, {"capabilities": {"emulated": "Emulated device"}, "children": [{"businfo": "scsi@2:0.0.0", "capabilities": {"audio": "Audio CD playback", "cd-r": "CD-R burning", "cd-rw": "CD-RW burning", "dvd": "DVD playback", "dvd-r": "DVD-R burning", "dvd-ram": "DVD-RAM burning", "removable": "support is removable"}, "claimed": true, "class": "disk", "configuration": {"ansiversion": "5", "status": "nodisc"}, "description": "DVD-RAM writer", "dev": "11:0", "handle": "SCSI:02:00:00:00", "id": "cdrom", "logicalname": ["/dev/cdrom", "/dev/cdrw", "/dev/dvd", "/dev/dvdrw", "/dev/sr0"], "physid": "0.0.0", "product": "DVD A DS8A8SH", "vendor": "hp", "version": "KH63"}], "claimed": true, "class": "storage", "id": "scsi:1", "logicalname": "scsi2", "physid": "2"}], "claimed": true, "class": "bus", "description": "Motherboard", "handle": "DMI:000E", "id": "core", "physid": "0", "product": "1858", "serial": "PCTVLB47V3O95U", "slot": "Type2 - Board Chassis Location", "vendor": "Hewlett-Packard", "version": "65.34"}, {"capacity": 47520, "claimed": true, "class": "power", "configuration": {"voltage": "10.8V"}, "description": "Lithium Ion Battery", "handle": "DMI:0025", "id": "battery", "physid": "1", "product": "MU06047", "slot": "Primary", "units": "mWh", "vendor": "11-85"}], "claimed": true, "class": "system", "configuration": {"boot": "normal", "chassis": "notebook", "cpus": "1", "family": "103C_5336AN G=N L=SMB B=HP S=650", "sku": "C1N10EA#ABE", "uuid": "114DB646-9E6A-775D-65F0-C8CBB85A5ABB"}, "description": "Notebook", "handle": "DMI:000D", "id": "debian", "product": "HP 650 Notebook PC (C1N10EA#ABE)", "serial": "5CB2452RGJ", "vendor": "Hewlett-Packard", "version": "087F110000305B10002620110", "width": 32}}, "device": {"actions": [{"elapsed": 1, "rate": 1.0979, "type": "BenchmarkRamSysbench"}, {"elapsed": 240, "severity": "Info", "type": "StressTest"}], "chassis": "Netbook", "manufacturer": "Hewlett-Packard", "model": "HP 650 Notebook", "serialNumber": "5CB2452RGJ", "sku": "C1N10EA#ABE", "type": "Laptop", "version": "087F110000305B10002620110"}, "elapsed": -6514, "endTime": "2021-05-04T15:30:14.711668+00:00", "software": "Workbench", "type": "Snapshot", "uuid": "ff194372-52f3-4f31-954e-90a4f02922fa", "version": "11.0b11"} diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py index a4f8ec79..f3d0905c 100644 --- a/tests/test_snapshot.py +++ b/tests/test_snapshot.py @@ -838,3 +838,12 @@ def test_snapshot_mobil(app: Devicehub, user: UserClient): tmp_snapshots = app.config['TMP_SNAPSHOTS'] shutil.rmtree(tmp_snapshots) + + +@pytest.mark.mvp +def test_bug_141(user: UserClient): + """This test check one bug that create a problem when try to up one snapshot + with a big number in the parameter command_timeout of the DataStorage + + """ + user.post(file('2021-5-4-13-41_time_out_test_datastorage'), res=Snapshot) From c7ff58273f8dd9d992439170d69c862f38f257a1 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 12 May 2021 13:02:36 +0200 Subject: [PATCH 30/52] fixing bug changing database model --- ...398826453b39_change_command_timeout_of_.py | 30 +++++++++++++++++++ .../8d34480c82c4_add_code_device_search.py | 2 +- ereuse_devicehub/resources/action/models.py | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 ereuse_devicehub/migrations/versions/398826453b39_change_command_timeout_of_.py diff --git a/ereuse_devicehub/migrations/versions/398826453b39_change_command_timeout_of_.py b/ereuse_devicehub/migrations/versions/398826453b39_change_command_timeout_of_.py new file mode 100644 index 00000000..b55d91d1 --- /dev/null +++ b/ereuse_devicehub/migrations/versions/398826453b39_change_command_timeout_of_.py @@ -0,0 +1,30 @@ +"""change command_timeout of TestDataStorage Action + +Revision ID: 398826453b39 +Revises: 8d34480c82c4 +Create Date: 2021-05-12 12:41:02.808311 + +""" +from alembic import op, context +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '398826453b39' +down_revision = '8d34480c82c4' +branch_labels = None +depends_on = None + + +def get_inv(): + INV = context.get_x_argument(as_dictionary=True).get('inventory') + if not INV: + raise ValueError("Inventory value is not specified") + return INV + +def upgrade(): + op.alter_column('test_data_storage', 'command_timeout', type_=sa.BigInteger(), schema=f'{get_inv()}') + + +def downgrade(): + op.alter_column('test_data_storage', 'command_timeout', type_=sa.Integer(), schema=f'{get_inv()}') diff --git a/ereuse_devicehub/migrations/versions/8d34480c82c4_add_code_device_search.py b/ereuse_devicehub/migrations/versions/8d34480c82c4_add_code_device_search.py index fbc5e3b0..8c419f0a 100644 --- a/ereuse_devicehub/migrations/versions/8d34480c82c4_add_code_device_search.py +++ b/ereuse_devicehub/migrations/versions/8d34480c82c4_add_code_device_search.py @@ -10,7 +10,7 @@ from alembic import context import sqlalchemy as sa from sqlalchemy.dialects import postgresql -from ereuse_devicehub.resources.device.search import DeviceSearch +# from ereuse_devicehub.resources.device.search import DeviceSearch # revision identifiers, used by Alembic. diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index 1211825b..01edae95 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -742,7 +742,7 @@ class TestDataStorage(TestMixin, Test): reallocated_sector_count = Column(SmallInteger) power_cycle_count = Column(SmallInteger) _reported_uncorrectable_errors = Column('reported_uncorrectable_errors', Integer) - command_timeout = Column(Integer) + command_timeout = Column(BigInteger) current_pending_sector_count = Column(Integer) offline_uncorrectable = Column(Integer) remaining_lifetime_percentage = Column(SmallInteger) From 015a886c1a5986261046d458451495901b16d443 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 12 May 2021 13:21:40 +0200 Subject: [PATCH 31/52] changelog --- CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3213330a..d393ec9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ml). ## master - [1.0.5-beta] - -## testing [1.0.6-beta] +## testing + [1.0.7-beta] + ## [1.0.6-beta] +- [bugfix] #143 biginteger instead of integer in TestDataStorage ## [1.0.5-beta] - [addend] #124 adding endpoint for extract the internal stats of use From 3fc3828326239ff35740aee5ea1163c1213a23a3 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 12 May 2021 17:31:44 +0200 Subject: [PATCH 32/52] up version --- ereuse_devicehub/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ereuse_devicehub/__init__.py b/ereuse_devicehub/__init__.py index eeacf9dd..65284dcc 100644 --- a/ereuse_devicehub/__init__.py +++ b/ereuse_devicehub/__init__.py @@ -1 +1 @@ -__version__ = "1.0.6-beta" +__version__ = "1.0.7-beta" From c1008ae6539eea07e2d7fe300b88e766bace7152 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 12 May 2021 18:55:07 +0200 Subject: [PATCH 33/52] change CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d393ec9e..5bfc15b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ ml). ## testing [1.0.7-beta] +## [1.0.7-beta] +- [addend] #140 adding endpoint for download the settings for usb workbench + ## [1.0.6-beta] - [bugfix] #143 biginteger instead of integer in TestDataStorage From a3f5401e1f894947b8b0a1dbb0e46d79e047dd73 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 13 May 2021 17:27:19 +0200 Subject: [PATCH 34/52] fixing versions of alembic --- .../migrations/versions/21afd375a654_session_table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py b/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py index 4e121731..97a50435 100644 --- a/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py +++ b/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py @@ -18,7 +18,7 @@ from ereuse_devicehub.resources.enums import SessionType # revision identifiers, used by Alembic. revision = '21afd375a654' -down_revision = '6a2a939d5668' +down_revision = '398826453b39' branch_labels = None depends_on = None comment_update = 'The last time Devicehub recorded a change for this thing.\n' From b34feee80056c73b1f18ff9ecdf99e7297c8bb9f Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 24 May 2021 13:00:03 +0200 Subject: [PATCH 35/52] fixing bug --- ereuse_devicehub/resources/user/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ereuse_devicehub/resources/user/models.py b/ereuse_devicehub/resources/user/models.py index 5923e35b..8ddb7c11 100644 --- a/ereuse_devicehub/resources/user/models.py +++ b/ereuse_devicehub/resources/user/models.py @@ -62,6 +62,7 @@ class UserInventory(db.Model): class Session(Thing): + __table_args__ = {'schema': 'common'} id = Column(BigInteger, Sequence('device_seq'), primary_key=True) expired = Column(BigInteger, default=0) token = Column(UUID(as_uuid=True), default=uuid4, unique=True, nullable=False) From 5e97cdf8634bae85a3b1c1cb2ca5a0cf3c5d4dd6 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 25 May 2021 11:35:03 +0200 Subject: [PATCH 36/52] less fixing tests --- tests/test_action.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_action.py b/tests/test_action.py index 99b27e6a..4bf68d10 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -1168,7 +1168,7 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): query=devices[:7]) # the manager shares the temporary lot with the SCRAP as an incoming lot - # for the CRAP to confirm it + # for the SCRAP to confirm it request_post = { 'type': 'Trade', 'devices': [], @@ -1279,6 +1279,7 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): assert device_10.actions[-1].t == 'ConfirmRevoke' assert device_10.actions[-2].t == 'Revoke' + # check validation error request_confirm_revoke = { 'type': 'ConfirmRevoke', 'action': device_10.actions[-1].id, @@ -1287,7 +1288,6 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): ] } - # check validation error user2.post(res=models.Action, data=request_confirm_revoke, status=422) From dd03b4d203de1b17a5ac1a47f557609138962244 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 25 May 2021 11:46:13 +0200 Subject: [PATCH 37/52] change id of migration fixied --- .../migrations/versions/51439cf24be8_change_trade_action.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ereuse_devicehub/migrations/versions/51439cf24be8_change_trade_action.py b/ereuse_devicehub/migrations/versions/51439cf24be8_change_trade_action.py index b5939e2d..1f1a5de9 100644 --- a/ereuse_devicehub/migrations/versions/51439cf24be8_change_trade_action.py +++ b/ereuse_devicehub/migrations/versions/51439cf24be8_change_trade_action.py @@ -14,7 +14,7 @@ import citext # revision identifiers, used by Alembic. revision = '51439cf24be8' -down_revision = '8d34480c82c4' +down_revision = '21afd375a654' branch_labels = None depends_on = None From ef2e800281338d6fb0db9937bfb2dbfa77e9d466 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 27 May 2021 15:55:24 +0200 Subject: [PATCH 38/52] change confirm for confirms field --- ereuse_devicehub/resources/action/schemas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index 9808d3ce..72d2d025 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -507,7 +507,7 @@ class Trade(ActionWithMultipleDevices): user_from_id = SanitizedStr(validate=Length(max=STR_SIZE), data_key='userFrom', missing='', required=False) code = SanitizedStr(validate=Length(max=STR_SIZE), data_key='code', required=False) - confirm = Boolean(missing=False, description="""If you need confirmation of the user + confirm = Boolean(data_key='confirms', missing=False, description="""If you need confirmation of the user you need actevate this field""") lot = NestedOn('Lot', many=False, From f8944df3121724127cbb1e8c11e51a9f0f67acfc Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 27 May 2021 15:55:39 +0200 Subject: [PATCH 39/52] fixed tests --- tests/test_action.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/test_action.py b/tests/test_action.py index 4bf68d10..0ae1137b 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -791,7 +791,7 @@ def test_offer_without_to(user: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot['id'], - 'confirm': False, + 'confirms': False, 'code': 'MAX' } user.post(res=models.Action, data=request_post) @@ -819,7 +819,7 @@ def test_offer_without_to(user: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot['id'], - 'confirm': False, + 'confirms': False, 'code': 'MAX' } user.post(res=models.Action, data=request_post, status=422) @@ -842,7 +842,7 @@ def test_offer_without_to(user: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot2.id, - 'confirm': False, + 'confirms': False, 'code': 'MAX' } user.post(res=models.Action, data=request_post2) @@ -873,7 +873,7 @@ def test_offer_without_from(user: UserClient, user2: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot.id, - 'confirm': False, + 'confirms': False, 'code': 'MAX' } action, _ = user2.post(res=models.Action, data=request_post, status=422) @@ -918,7 +918,7 @@ def test_offer_without_users(user: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot.id, - 'confirm': False, + 'confirms': False, 'code': 'MAX' } action, response = user.post(res=models.Action, data=request_post, status=422) @@ -952,7 +952,7 @@ def test_offer(user: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot.id, - 'confirm': True, + 'confirms': True, } action, _ = user.post(res=models.Action, data=request_post) @@ -979,7 +979,7 @@ def test_offer_without_devices(user: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot['id'], - 'confirm': True, + 'confirms': True, } user.post(res=models.Action, data=request_post) @@ -1058,7 +1058,7 @@ def test_endpoint_confirm(user: UserClient, user2: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot['id'], - 'confirm': True, + 'confirms': True, } user.post(res=models.Action, data=request_post) @@ -1099,7 +1099,7 @@ def test_confirm_revoke(user: UserClient, user2: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot['id'], - 'confirm': True, + 'confirms': True, } user.post(res=models.Action, data=request_post) @@ -1178,7 +1178,7 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot['id'], - 'confirm': True, + 'confirms': True, } user.post(res=models.Action, data=request_post) @@ -1366,7 +1366,7 @@ def test_confirmRevoke(user: UserClient, user2: UserClient): 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', 'lot': lot['id'], - 'confirm': True, + 'confirms': True, } user.post(res=models.Action, data=request_post) From 6142b89f41c45fb2d8d102a7237ea8ba29181eae Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 27 May 2021 15:56:10 +0200 Subject: [PATCH 40/52] adding confirm_status in devices --- ereuse_devicehub/resources/device/models.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index bf43a356..65aa5669 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -262,6 +262,13 @@ class Device(Thing): action = self.last_action_of(*states.Trading.actions()) return states.Trading(action.__class__) + @property + def confirm_status(self): + """The actual state of confirmation of one Trade, or None if no Trade action + has ever been performed to this device.""" + # TODO @cayop we need implement this functionality + return None + @property def physical(self): """The actual physical state, None otherwise.""" From e1348e3809c46621d3d06a3c484e226cc6479d8e Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 31 May 2021 11:34:46 +0200 Subject: [PATCH 41/52] adding isTemporary lot --- ereuse_devicehub/resources/lot/models.py | 4 ++++ ereuse_devicehub/resources/lot/schemas.py | 1 + ereuse_devicehub/resources/lot/views.py | 1 + 3 files changed, 6 insertions(+) diff --git a/ereuse_devicehub/resources/lot/models.py b/ereuse_devicehub/resources/lot/models.py index f8a9066b..9699c969 100644 --- a/ereuse_devicehub/resources/lot/models.py +++ b/ereuse_devicehub/resources/lot/models.py @@ -99,6 +99,10 @@ class Lot(Thing): def descendants(self): return self.descendantsq(self.id) + @property + def is_temporary(self): + return False if self.trade else True + @classmethod def descendantsq(cls, id): _id = UUIDLtree.convert(id) diff --git a/ereuse_devicehub/resources/lot/schemas.py b/ereuse_devicehub/resources/lot/schemas.py index 72e49efe..e92de60b 100644 --- a/ereuse_devicehub/resources/lot/schemas.py +++ b/ereuse_devicehub/resources/lot/schemas.py @@ -26,3 +26,4 @@ class Lot(Thing): transfer_state = EnumField(TransferState, description=m.Lot.transfer_state.comment) receiver_address = SanitizedStr(validate=f.validate.Length(max=42)) deliverynote = NestedOn(s_deliverynote.Deliverynote, dump_only=True) + is_temporary = f.Boolean(missing=True, data_key='isTemporary') diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 295f63e1..744297b9 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -32,6 +32,7 @@ class LotView(View): def post(self): l = request.get_json() + l.pop('is_temporary', '') lot = Lot(**l) db.session.add(lot) db.session().final_flush() From 6c689878a49004241919033814d348716564cce9 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 1 Jun 2021 15:59:54 +0200 Subject: [PATCH 42/52] Fixing schema trade --- ereuse_devicehub/resources/action/schemas.py | 38 +++++++++++-------- .../resources/action/views/trade.py | 17 +++++---- ereuse_devicehub/resources/lot/schemas.py | 2 + tests/test_action.py | 36 +++++++++--------- 4 files changed, 53 insertions(+), 40 deletions(-) diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index 72d2d025..09c8abcd 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -502,10 +502,20 @@ class Trade(ActionWithMultipleDevices): document_id = SanitizedStr(validate=Length(max=STR_SIZE), data_key='documentID', required=False) date = DateTime(data_key='date', required=False) price = Float(required=False, data_key='price') - user_to_id = SanitizedStr(validate=Length(max=STR_SIZE), data_key='userTo', missing='', - required=False) - user_from_id = SanitizedStr(validate=Length(max=STR_SIZE), data_key='userFrom', missing='', - required=False) + user_to_email = SanitizedStr( + validate=Length(max=STR_SIZE), + data_key='userToEmail', + missing='', + required=False + ) + user_to = NestedOn(s_user.User, dump_only=True, data_key='userTo') + user_from_email = SanitizedStr( + validate=Length(max=STR_SIZE), + data_key='userFromEmail', + missing='', + required=False + ) + user_from = NestedOn(s_user.User, dump_only=True, data_key='userFrom') code = SanitizedStr(validate=Length(max=STR_SIZE), data_key='code', required=False) confirm = Boolean(data_key='confirms', missing=False, description="""If you need confirmation of the user you need actevate this field""") @@ -516,7 +526,7 @@ class Trade(ActionWithMultipleDevices): @validates_schema def validate_lot(self, data: dict): - if not g.user.email in [data['user_from_id'], data['user_to_id']]: + if not g.user.email in [data['user_from_email'], data['user_to_email']]: txt = "you need to be one of the users of involved in the Trade" raise ValidationError(txt) @@ -532,7 +542,7 @@ class Trade(ActionWithMultipleDevices): data['devices'] = data['lot'].devices @validates_schema - def validate_user_to_id(self, data: dict): + def validate_user_to_email(self, data: dict): """ - if user_to exist * confirmation @@ -541,15 +551,14 @@ class Trade(ActionWithMultipleDevices): * without confirmation """ - if data['user_to_id']: - user_to = User.query.filter_by(email=data['user_to_id']).one() - data['user_to_id'] = user_to.id + if data['user_to_email']: + user_to = User.query.filter_by(email=data['user_to_email']).one() data['user_to'] = user_to else: data['confirm'] = False @validates_schema - def validate_user_from_id(self, data: dict): + def validate_user_from_email(self, data: dict): """ - if user_from exist * confirmation @@ -558,13 +567,12 @@ class Trade(ActionWithMultipleDevices): * without confirmation """ - if not (data['user_from_id'] or data['user_to_id']): + if not (data['user_from_email'] or data['user_to_email']): txt = "you need one user from or user to for to do a offer" raise ValidationError(txt) - if data['user_from_id']: - user_from = User.query.filter_by(email=data['user_from_id']).one() - data['user_from_id'] = user_from.id + if data['user_from_email']: + user_from = User.query.filter_by(email=data['user_from_email']).one() data['user_from'] = user_from else: data['confirm'] = False @@ -572,7 +580,7 @@ class Trade(ActionWithMultipleDevices): @validates_schema def validate_code(self, data: dict): """If the user not exist, you need a code to be able to do the traceability""" - if data['user_from_id'] and data['user_to_id']: + if data['user_from_email'] and data['user_to_email']: return if not data.get('code'): diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index 57ecc665..d5aa3d96 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -29,6 +29,8 @@ class TradeView(): def __init__(self, data, resource_def, schema): self.schema = schema a = resource_def.schema.load(data) + a.pop('user_to_email', '') + a.pop('user_from_email', '') self.trade = Trade(**a) self.create_phantom_account() db.session.add(self.trade) @@ -36,7 +38,6 @@ class TradeView(): self.create_confirmations() def post(self): - # import pdb; pdb.set_trace() db.session().final_flush() ret = self.schema.jsonify(self.trade) ret.status_code = 201 @@ -57,7 +58,7 @@ class TradeView(): # check than the user than want to do the action is one of the users # involved in the action - assert g.user.id in [self.trade.user_from_id, self.trade.user_to_id] + assert g.user in [self.trade.user_from, self.trade.user_to] confirm_from = Confirm(user=self.trade.user_from, action=self.trade, @@ -78,12 +79,12 @@ class TradeView(): The same if exist to but not from """ - if self.trade.user_from_id and self.trade.user_to_id: + if self.trade.user_from and self.trade.user_to: return - if self.trade.user_from_id and not self.trade.user_to_id: - assert g.user.id == self.trade.user_from_id - email = "{}_{}@dhub.com".format(str(self.trade.user_from_id), self.trade.code) + if self.trade.user_from and not self.trade.user_to: + assert g.user == self.trade.user_from + email = "{}_{}@dhub.com".format(str(self.trade.user_from.id), self.trade.code) users = User.query.filter_by(email=email) if users.first(): user = users.first() @@ -94,8 +95,8 @@ class TradeView(): db.session.add(user) self.trade.user_to = user - if not self.trade.user_from_id and self.trade.user_to_id: - email = "{}_{}@dhub.com".format(str(self.trade.user_to_id), self.trade.code) + if not self.trade.user_from and self.trade.user_to: + email = "{}_{}@dhub.com".format(str(self.trade.user_to.id), self.trade.code) users = User.query.filter_by(email=email) if users.first(): user = users.first() diff --git a/ereuse_devicehub/resources/lot/schemas.py b/ereuse_devicehub/resources/lot/schemas.py index e92de60b..0d584ca7 100644 --- a/ereuse_devicehub/resources/lot/schemas.py +++ b/ereuse_devicehub/resources/lot/schemas.py @@ -4,6 +4,7 @@ from teal.marshmallow import SanitizedStr, URL, EnumField from ereuse_devicehub.marshmallow import NestedOn from ereuse_devicehub.resources.deliverynote import schemas as s_deliverynote from ereuse_devicehub.resources.device import schemas as s_device +from ereuse_devicehub.resources.action import schemas as s_action from ereuse_devicehub.resources.enums import TransferState from ereuse_devicehub.resources.lot import models as m from ereuse_devicehub.resources.models import STR_SIZE @@ -26,4 +27,5 @@ class Lot(Thing): transfer_state = EnumField(TransferState, description=m.Lot.transfer_state.comment) receiver_address = SanitizedStr(validate=f.validate.Length(max=42)) deliverynote = NestedOn(s_deliverynote.Deliverynote, dump_only=True) + trade = NestedOn(s_action.Trade, dump_only=True) is_temporary = f.Boolean(missing=True, data_key='isTemporary') diff --git a/tests/test_action.py b/tests/test_action.py index 0ae1137b..68fcfbb8 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -786,7 +786,7 @@ def test_offer_without_to(user: UserClient): request_post = { 'type': 'Trade', 'devices': [device.id], - 'userFrom': user.email, + 'userFromEmail': user.email, 'price': 10, 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', @@ -814,7 +814,7 @@ def test_offer_without_to(user: UserClient): request_post = { 'type': 'Trade', 'devices': [device.id], - 'userFrom': user.email, + 'userFromEmail': user.email, 'price': 10, 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', @@ -837,7 +837,7 @@ def test_offer_without_to(user: UserClient): request_post2 = { 'type': 'Trade', 'devices': [device2.id], - 'userFrom': user.email, + 'userFromEmail': user.email, 'price': 10, 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', @@ -868,7 +868,7 @@ def test_offer_without_from(user: UserClient, user2: UserClient): request_post = { 'type': 'Trade', 'devices': [device.id], - 'userTo': user2.email, + 'userToEmail': user2.email, 'price': 10, 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', @@ -878,7 +878,7 @@ def test_offer_without_from(user: UserClient, user2: UserClient): } action, _ = user2.post(res=models.Action, data=request_post, status=422) - request_post['userTo'] = user.email + request_post['userToEmail'] = user.email action, _ = user.post(res=models.Action, data=request_post) trade = models.Trade.query.one() @@ -946,8 +946,8 @@ def test_offer(user: UserClient): request_post = { 'type': 'Trade', 'devices': [], - 'userFrom': user.email, - 'userTo': user2.email, + 'userFromEmail': user.email, + 'userToEmail': user2.email, 'price': 10, 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', @@ -973,8 +973,8 @@ def test_offer_without_devices(user: UserClient): request_post = { 'type': 'Trade', 'devices': [], - 'userFrom': user.email, - 'userTo': user2.email, + 'userFromEmail': user.email, + 'userToEmail': user2.email, 'price': 10, 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', @@ -1052,8 +1052,8 @@ def test_endpoint_confirm(user: UserClient, user2: UserClient): request_post = { 'type': 'Trade', 'devices': [device_id], - 'userFrom': user.email, - 'userTo': user2.email, + 'userFromEmail': user.email, + 'userToEmail': user2.email, 'price': 10, 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', @@ -1093,8 +1093,8 @@ def test_confirm_revoke(user: UserClient, user2: UserClient): request_post = { 'type': 'Trade', 'devices': [device_id], - 'userFrom': user.email, - 'userTo': user2.email, + 'userFromEmail': user.email, + 'userToEmail': user2.email, 'price': 10, 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', @@ -1172,8 +1172,8 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): request_post = { 'type': 'Trade', 'devices': [], - 'userFrom': user2.email, - 'userTo': user.email, + 'userFromEmail': user2.email, + 'userToEmail': user.email, 'price': 10, 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', @@ -1183,6 +1183,8 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): user.post(res=models.Action, data=request_post) trade = models.Trade.query.one() + # l_after, _ = user.get(res=Lot, item=lot['id']) + # import pdb; pdb.set_trace() # the SCRAP confirms 3 of the 10 devices in its outgoing lot request_confirm = { @@ -1360,8 +1362,8 @@ def test_confirmRevoke(user: UserClient, user2: UserClient): request_post = { 'type': 'Trade', 'devices': [], - 'userFrom': user2.email, - 'userTo': user.email, + 'userFromEmail': user2.email, + 'userToEmail': user.email, 'price': 10, 'date': "2020-12-01T02:00:00+00:00", 'documentID': '1', From 57c926990702f8b244e6c3cd0095176371ef8f4d Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 2 Jun 2021 10:10:36 +0200 Subject: [PATCH 43/52] add trade instead of deliverynote in lots view --- ereuse_devicehub/resources/lot/views.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 744297b9..91ed267b 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -12,9 +12,8 @@ from teal.resource import View from ereuse_devicehub.db import db from ereuse_devicehub.query import things_response -from ereuse_devicehub.resources.deliverynote.models import Deliverynote from ereuse_devicehub.resources.device.models import Device, Computer -from ereuse_devicehub.resources.action.models import Confirm, Revoke +from ereuse_devicehub.resources.action.models import Trade, Confirm, Revoke from ereuse_devicehub.resources.lot.models import Lot, Path @@ -99,9 +98,9 @@ class LotView(View): return jsonify(ret) def visibility_filter(self, query): - query = query.outerjoin(Deliverynote) \ - .filter(or_(Deliverynote.receiver_address == g.user.email, - Deliverynote.supplier_email == g.user.email, + query = query.outerjoin(Trade) \ + .filter(or_(Trade.user_from == g.user, + Trade.user_to == g.user, Lot.owner_id == g.user.id)) return query @@ -110,7 +109,7 @@ class LotView(View): return query def delete(self, id): - lot = Lot.query.filter_by(id=id).one() + lot = Lot.query.filter_by(id=id,).one() lot.delete() db.session.commit() return Response(status=204) From 20e029b359f10a17c7d46278073f02a0f2eb3f56 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 2 Jun 2021 10:11:20 +0200 Subject: [PATCH 44/52] bugfix: restriction delete lot by the owner --- ereuse_devicehub/resources/lot/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 91ed267b..35a82a16 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -109,7 +109,7 @@ class LotView(View): return query def delete(self, id): - lot = Lot.query.filter_by(id=id,).one() + lot = Lot.query.filter_by(id=id, owner=g.user).one() lot.delete() db.session.commit() return Response(status=204) From 0c99a85361f469857c84d50f7ba8085023f4e00d Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 2 Jun 2021 13:46:28 +0200 Subject: [PATCH 45/52] add raise instead of assert --- ereuse_devicehub/resources/action/views/trade.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index d5aa3d96..7b92673c 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -58,7 +58,9 @@ class TradeView(): # check than the user than want to do the action is one of the users # involved in the action - assert g.user in [self.trade.user_from, self.trade.user_to] + if not g.user in [self.trade.user_from, self.trade.user_to]: + txt = "You do not participate in this trading" + raise ValidationError(txt) confirm_from = Confirm(user=self.trade.user_from, action=self.trade, From e4554a9e274aa3ef60a92320e236ca96e19bd8db Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 2 Jun 2021 15:33:03 +0200 Subject: [PATCH 46/52] use open filter for checke frontend trade --- ereuse_devicehub/resources/action/schemas.py | 13 ++++++++----- ereuse_devicehub/resources/device/views.py | 4 +++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index 09c8abcd..37adf81f 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -503,22 +503,25 @@ class Trade(ActionWithMultipleDevices): date = DateTime(data_key='date', required=False) price = Float(required=False, data_key='price') user_to_email = SanitizedStr( - validate=Length(max=STR_SIZE), - data_key='userToEmail', + validate=Length(max=STR_SIZE), + data_key='userToEmail', missing='', required=False ) user_to = NestedOn(s_user.User, dump_only=True, data_key='userTo') user_from_email = SanitizedStr( validate=Length(max=STR_SIZE), - data_key='userFromEmail', + data_key='userFromEmail', missing='', required=False ) user_from = NestedOn(s_user.User, dump_only=True, data_key='userFrom') code = SanitizedStr(validate=Length(max=STR_SIZE), data_key='code', required=False) - confirm = Boolean(data_key='confirms', missing=False, description="""If you need confirmation of the user - you need actevate this field""") + confirm = Boolean( + data_key='confirms', + missing=True, + description="""If you need confirmation of the user you need actevate this field""" + ) lot = NestedOn('Lot', many=False, required=True, diff --git a/ereuse_devicehub/resources/device/views.py b/ereuse_devicehub/resources/device/views.py index 8e032fc7..8c1cc149 100644 --- a/ereuse_devicehub/resources/device/views.py +++ b/ereuse_devicehub/resources/device/views.py @@ -150,7 +150,9 @@ class DeviceView(View): ) def query(self, args): - query = Device.query.filter((Device.owner_id == g.user.id)).distinct() + query = Device.query.filter().distinct() + # import pdb; pdb.set_trace() + # query = Device.query.filter((Device.owner_id == g.user.id)).distinct() search_p = args.get('search', None) if search_p: properties = DeviceSearch.properties From 8d1e6bb2d70a765a9198584b57d22fb930c831f3 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 3 Jun 2021 12:11:14 +0200 Subject: [PATCH 47/52] drop istemporary lot --- ereuse_devicehub/resources/lot/schemas.py | 1 - ereuse_devicehub/resources/lot/views.py | 1 - 2 files changed, 2 deletions(-) diff --git a/ereuse_devicehub/resources/lot/schemas.py b/ereuse_devicehub/resources/lot/schemas.py index 0d584ca7..2119c048 100644 --- a/ereuse_devicehub/resources/lot/schemas.py +++ b/ereuse_devicehub/resources/lot/schemas.py @@ -28,4 +28,3 @@ class Lot(Thing): receiver_address = SanitizedStr(validate=f.validate.Length(max=42)) deliverynote = NestedOn(s_deliverynote.Deliverynote, dump_only=True) trade = NestedOn(s_action.Trade, dump_only=True) - is_temporary = f.Boolean(missing=True, data_key='isTemporary') diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 35a82a16..7e7169ba 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -31,7 +31,6 @@ class LotView(View): def post(self): l = request.get_json() - l.pop('is_temporary', '') lot = Lot(**l) db.session.add(lot) db.session().final_flush() From a0824f986be139e4a083add53e0d8269e4e9af7d Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 3 Jun 2021 19:05:57 +0200 Subject: [PATCH 48/52] not allow than other users can insert devices, show better the status of trade for devices --- .../resources/action/views/trade.py | 13 ++-- ereuse_devicehub/resources/device/models.py | 77 ++++++++++++++++++- ereuse_devicehub/resources/device/schemas.py | 2 + ereuse_devicehub/resources/device/states.py | 3 + ereuse_devicehub/resources/lot/views.py | 9 ++- 5 files changed, 92 insertions(+), 12 deletions(-) diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index 7b92673c..5f5efd31 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -290,15 +290,18 @@ class ConfirmRevokeView(ConfirmMixin): # then g.user can not to do the ConfirmRevoke more break - data['devices'] = OrderedSet(real_devices) + devices = OrderedSet(real_devices) + data['devices'] = devices # Change the owner for every devices - trade = data['action'] - for dev in data['devices']: - # TODO @cayop this should be the author of confirm actions instead of - # author of trade + # data['action'] == 'Revoke' + + trade = data['action'].action + for dev in devices: + # TODO @cayop if it's possible the both users insert devices into a lot, then there are problems dev.owner = trade.author if hasattr(dev, 'components'): for c in dev.components: c.owner = trade.author + trade.lot.devices.difference_update(devices) diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 65aa5669..1833b027 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -1,5 +1,6 @@ import pathlib import copy +from flask import g from contextlib import suppress from fractions import Fraction from itertools import chain @@ -255,12 +256,82 @@ class Device(Thing): @property def trading(self): - """The actual trading state, or None if no Trade action has - ever been performed to this device.""" + """The trading state, or None if no Trade action has + ever been performed to this device. This extract the posibilities for to do""" + + # import pdb; pdb.set_trace() + trade = 'Trade' + confirm = 'Confirm' + revoke = 'Revoke' + revoke_pending = 'RevokePending' + confirm_revoke = 'ConfirmRevoke' + revoke_confirmed = 'RevokeConfirmed' + + types = [trade, confirm, revoke, confirm_revoke] + actions = copy.copy(self.actions) + actions.sort(key=lambda x: x.created) + actions.reverse() + + actions_trade = [] + + # get only the actions trade of the last trade + for ac in actions: + if ac.type in types: + actions_trade.append(ac) + + if ac.type == trade: + break + + # return the correct status of trade depending of the user + + ##### CASES ##### + ## User1 == owner of trade (This user have automatic Confirmation) + ## ======================= + ## Confirmation not User1 => Revoke + ## Confirmation User1 => Revoke + ## Revoke not User1 => ConfirmRevoke + ## Revoke User1 => RevokePending + ## RevokeConfirmation => RevokeConfirmed + ## + ## + ## User2 == Not owner of trade + ## ======================= + ## Confirmation not User2 => Confirm + ## Confirmation User2 => Revoke + ## Revoke not User2 => ConfirmRevoke + ## Revoke User2 => RevokePending + ## RevokeConfirmation => RevokeConfirmed + + for ac in actions_trade: + if ac.type == confirm_revoke: + # can to do revoke_confirmed + return confirm_revoke + + if ac.type == revoke and ac.user == g.user: + # can todo revoke_pending + return revoke_pending + + if ac.type == revoke and ac.user != g.user: + # can to do confirm_revoke + return revoke + + if ac.type == confirm and (ac.user == g.user or ac.action.author == g.user): + # can to do revoke + return confirm + + if ac.type == confirm and ac.user != g.user: + # can to do confirm + return trade + + @property + def revoke(self): + """If the actual trading state is an revoke action, this property show + the id of that revoke""" from ereuse_devicehub.resources.device import states with suppress(LookupError, ValueError): action = self.last_action_of(*states.Trading.actions()) - return states.Trading(action.__class__) + if action.type == 'Revoke': + return action.id @property def confirm_status(self): diff --git a/ereuse_devicehub/resources/device/schemas.py b/ereuse_devicehub/resources/device/schemas.py index 9a97d72d..828c9827 100644 --- a/ereuse_devicehub/resources/device/schemas.py +++ b/ereuse_devicehub/resources/device/schemas.py @@ -51,9 +51,11 @@ class Device(Thing): rate = NestedOn('Rate', dump_only=True, description=m.Device.rate.__doc__) price = NestedOn('Price', dump_only=True, description=m.Device.price.__doc__) trading = EnumField(states.Trading, dump_only=True, description=m.Device.trading.__doc__) + trading = SanitizedStr(dump_only=True, description='') physical = EnumField(states.Physical, dump_only=True, description=m.Device.physical.__doc__) traking= EnumField(states.Traking, dump_only=True, description=m.Device.physical.__doc__) usage = EnumField(states.Usage, dump_only=True, description=m.Device.physical.__doc__) + revoke = UUID(dump_only=True) physical_possessor = NestedOn('Agent', dump_only=True, data_key='physicalPossessor') production_date = DateTime('iso', description=m.Device.updated.comment, diff --git a/ereuse_devicehub/resources/device/states.py b/ereuse_devicehub/resources/device/states.py index bdfd1a03..f6ad1761 100644 --- a/ereuse_devicehub/resources/device/states.py +++ b/ereuse_devicehub/resources/device/states.py @@ -35,6 +35,9 @@ class Trading(State): """ Reserved = e.Reserve Trade = e.Trade + Confirm = e.Confirm + Revoke = e.Revoke + ConfirmRevoke = e.ConfirmRevoke Cancelled = e.CancelTrade Sold = e.Sell Donated = e.Donate diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 7e7169ba..0a3ae13b 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -230,11 +230,12 @@ class LotDeviceView(LotBaseChildrenView): return users = [g.user.id] - if lot.trade: + # Not for the moment + # if lot.trade: # all users involved in the trade action can modify the lot - trade_users = [lot.trade.user_from.id, lot.trade.user_to.id] - if g.user in trade_users: - users = trade_users + # trade_users = [lot.trade.user_from.id, lot.trade.user_to.id] + # if g.user in trade_users: + # users = trade_users devices = set(Device.query.filter(Device.id.in_(ids)).filter( Device.owner_id.in_(users))) From 80e74b6d3d62ed06c5c56642104aba11765d3ef4 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 4 Jun 2021 19:27:01 +0200 Subject: [PATCH 49/52] fixing supplier and receiver --- .../resources/action/views/trade.py | 56 ++++++++++++----- ereuse_devicehub/resources/device/models.py | 62 +++++++++---------- ereuse_devicehub/resources/lot/views.py | 39 ++++++++++-- 3 files changed, 104 insertions(+), 53 deletions(-) diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index 5f5efd31..b0569caf 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -7,6 +7,7 @@ from teal.marshmallow import ValidationError from ereuse_devicehub.db import db from ereuse_devicehub.resources.action.models import Trade, Confirm, ConfirmRevoke, Revoke from ereuse_devicehub.resources.user.models import User +from ereuse_devicehub.resources.lot.models import Lot class TradeView(): @@ -221,28 +222,55 @@ class RevokeView(ConfirmMixin): Model = Revoke + def __init__(self, data, resource_def, schema): + self.schema = schema + a = resource_def.schema.load(data) + self.validate(a) + def validate(self, data): """If there are one device than have one confirmation, then remove the list this device of the list of devices of this action """ - real_devices = [] + ### check ### + devs_confirm = [] + if not data['devices']: + raise ValidationError('Devices not exist.') + for dev in data['devices']: - actions = copy.copy(dev.actions) - actions.reverse() - for ac in actions: - if ac == data['action']: - # data['action'] is a Trade action, if this is the first action - # to find mean that this devices dont have a confirmation - break + if dev.last_action_trading.type == 'Confirm': + devs_confirm.append(dev) - if ac.t == 'Revoke' and ac.user == g.user: - break + if not len(data['devices']) == len(devs_confirm): + txt = "Some of this devices can't be reboked" + raise ValidationError(txt) + ### End check ### - if ac.t == Confirm.t and ac.user == g.user: - real_devices.append(dev) - break + lot = data['action'].lot + devices = set(data['devices']) + without_confirms = set() # set of devs without confirms of user2 - data['devices'] = OrderedSet(real_devices) + if g.user == lot.trade.author: + for dev in devices: + ac = dev.last_action_trading + if ac.type == 'Confirm' and ac.user == g.user: + without_confirms.add(dev) + + # we need to mark one revoke for every devs + revoke = Revoke(action=lot.trade, user=g.user, devices=devices) + db.session.add(revoke) + + if without_confirms: + confirm_revoke = ConfirmRevoke( + action=revoke, + user=g.user, + devices=without_confirms + ) + db.session.add(confirm_revoke) + + lot.devices.difference_update(without_confirms) + lot.trade.devices = lot.devices + + self.model = revoke class ConfirmRevokeView(ConfirmMixin): diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 1833b027..852ed4ca 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -254,39 +254,32 @@ class Device(Thing): from ereuse_devicehub.resources.action.models import Price return self.last_action_of(Price) + @property + def last_action_trading(self): + """which is the last action trading""" + from ereuse_devicehub.resources.device import states + with suppress(LookupError, ValueError): + return self.last_action_of(*states.Trading.actions()) + @property def trading(self): """The trading state, or None if no Trade action has ever been performed to this device. This extract the posibilities for to do""" - # import pdb; pdb.set_trace() trade = 'Trade' confirm = 'Confirm' revoke = 'Revoke' revoke_pending = 'RevokePending' confirm_revoke = 'ConfirmRevoke' - revoke_confirmed = 'RevokeConfirmed' - - types = [trade, confirm, revoke, confirm_revoke] - actions = copy.copy(self.actions) - actions.sort(key=lambda x: x.created) - actions.reverse() - - actions_trade = [] - - # get only the actions trade of the last trade - for ac in actions: - if ac.type in types: - actions_trade.append(ac) - - if ac.type == trade: - break + # revoke_confirmed = 'RevokeConfirmed' # return the correct status of trade depending of the user ##### CASES ##### ## User1 == owner of trade (This user have automatic Confirmation) ## ======================= + ## if the last action is => only allow to do + ## ========================================== ## Confirmation not User1 => Revoke ## Confirmation User1 => Revoke ## Revoke not User1 => ConfirmRevoke @@ -296,32 +289,35 @@ class Device(Thing): ## ## User2 == Not owner of trade ## ======================= + ## if the last action is => only allow to do + ## ========================================== ## Confirmation not User2 => Confirm ## Confirmation User2 => Revoke ## Revoke not User2 => ConfirmRevoke ## Revoke User2 => RevokePending ## RevokeConfirmation => RevokeConfirmed - for ac in actions_trade: - if ac.type == confirm_revoke: - # can to do revoke_confirmed - return confirm_revoke + ac = self.last_action_trading - if ac.type == revoke and ac.user == g.user: - # can todo revoke_pending - return revoke_pending + if ac.type == confirm_revoke: + # can to do revoke_confirmed + return confirm_revoke - if ac.type == revoke and ac.user != g.user: - # can to do confirm_revoke - return revoke + if ac.type == revoke and ac.user == g.user: + # can todo revoke_pending + return revoke_pending - if ac.type == confirm and (ac.user == g.user or ac.action.author == g.user): - # can to do revoke - return confirm + if ac.type == revoke and ac.user != g.user: + # can to do confirm_revoke + return revoke - if ac.type == confirm and ac.user != g.user: - # can to do confirm - return trade + if ac.type == confirm and (ac.user == g.user or ac.action.author == g.user): + # can to do revoke + return confirm + + if ac.type == confirm and ac.user != g.user: + # can to do confirm + return trade @property def revoke(self): diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 0a3ae13b..16e27bbe 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -13,7 +13,7 @@ from teal.resource import View from ereuse_devicehub.db import db from ereuse_devicehub.query import things_response from ereuse_devicehub.resources.device.models import Device, Computer -from ereuse_devicehub.resources.action.models import Trade, Confirm, Revoke +from ereuse_devicehub.resources.action.models import Trade, Confirm, Revoke, ConfirmRevoke from ereuse_devicehub.resources.lot.models import Lot, Path @@ -254,6 +254,7 @@ class LotDeviceView(LotBaseChildrenView): return users = [g.user.id] + # import pdb; pdb.set_trace() if lot.trade: # all users involved in the trade action can modify the lot trade_users = [lot.trade.user_from.id, lot.trade.user_to.id] @@ -263,10 +264,36 @@ class LotDeviceView(LotBaseChildrenView): devices = set(Device.query.filter(Device.id.in_(ids)).filter( Device.owner_id.in_(users))) - lot.devices.difference_update(devices) + if not lot.trade: + lot.devices.difference_update(devices) + return - if lot.trade: + # if is a trade + if not g.user in [lot.trade.user_from, lot.trade.user_to]: + # theoretically this case is impossible + return + + + # Now we need to know which devices we need extract of the lot + without_confirms = set() # set of devs without confirms of user2 + + if g.user == lot.trade.author: + for dev in devices: + ac = dev.last_action_trading + if ac.type == 'Confirm' and ac.user == g.user: + without_confirms.add(dev) + + # we need to mark one revoke for every devs + revoke = Revoke(action=lot.trade, user=g.user, devices=devices) + db.session.add(revoke) + + if without_confirms: + confirm_revoke = ConfirmRevoke( + action=revoke, + user=g.user, + devices=without_confirms + ) + db.session.add(confirm_revoke) + + lot.devices.difference_update(without_confirms) lot.trade.devices = lot.devices - if g.user in [lot.trade.user_from, lot.trade.user_to]: - revoke = Revoke(action=lot.trade, user=g.user, devices=devices) - db.session.add(revoke) From 6dc7fb830be1e5c57c8f3d032843480a9be2055a Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Sun, 6 Jun 2021 10:02:24 +0200 Subject: [PATCH 50/52] fixing bug of filter devices --- ereuse_devicehub/resources/device/views.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ereuse_devicehub/resources/device/views.py b/ereuse_devicehub/resources/device/views.py index 8c1cc149..20982430 100644 --- a/ereuse_devicehub/resources/device/views.py +++ b/ereuse_devicehub/resources/device/views.py @@ -24,6 +24,7 @@ from ereuse_devicehub.resources.device.models import Device, Manufacturer, Compu from ereuse_devicehub.resources.device.search import DeviceSearch from ereuse_devicehub.resources.enums import SnapshotSoftware from ereuse_devicehub.resources.lot.models import LotDeviceDescendants +from ereuse_devicehub.resources.action.models import Trade from ereuse_devicehub.resources.tag.model import Tag @@ -150,9 +151,16 @@ class DeviceView(View): ) def query(self, args): - query = Device.query.filter().distinct() - # import pdb; pdb.set_trace() - # query = Device.query.filter((Device.owner_id == g.user.id)).distinct() + trades = Trade.query.filter( + (Trade.user_from == g.user) | (Trade.user_to == g.user) + ).distinct() + + trades_dev_ids = {d.id for t in trades for d in t.devices} + + query = Device.query.filter( + (Device.owner_id == g.user.id) | (Device.id.in_(trades_dev_ids)) + ).distinct() + search_p = args.get('search', None) if search_p: properties = DeviceSearch.properties From 21cdcb5350f7ce8bdd5b8f597872f99165db3a8e Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 7 Jun 2021 10:50:08 +0200 Subject: [PATCH 51/52] simplify the algorithm for to manager the confirms flow --- .../resources/action/views/trade.py | 142 ++++++------------ ereuse_devicehub/resources/device/models.py | 68 +++++++-- ereuse_devicehub/resources/lot/views.py | 90 ++++++----- 3 files changed, 150 insertions(+), 150 deletions(-) diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index b0569caf..4054b624 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -7,7 +7,7 @@ from teal.marshmallow import ValidationError from ereuse_devicehub.db import db from ereuse_devicehub.resources.action.models import Trade, Confirm, ConfirmRevoke, Revoke from ereuse_devicehub.resources.user.models import User -from ereuse_devicehub.resources.lot.models import Lot +from ereuse_devicehub.resources.lot.views import delete_from_trade class TradeView(): @@ -172,41 +172,16 @@ class ConfirmView(ConfirmMixin): # import pdb; pdb.set_trace() real_devices = [] for dev in data['devices']: - actions = copy.copy(dev.actions) - actions.reverse() - for ac in actions: - if ac == data['action']: - # If device have the last action the action Trade - real_devices.append(dev) - break - - if ac.t == Confirm.t and not ac.user == g.user: - # If device is confirmed we don't need confirmed again - real_devices.append(dev) - break - - if ac.t == 'Revoke' and not ac.user == g.user: - # If device is revoke before from other user - # it's not possible confirm now - break - - if ac.t == 'ConfirmRevoke' and ac.user == g.user: - # if the last action is a ConfirmRevoke this mean than not there are - # other confirmation from the real owner of the trade - break - - if ac.t == Confirm.t and ac.user == g.user: - # If device is confirmed we don't need confirmed again - break + ac = dev.last_action_trading + if ac.type == Confirm.t and not ac.user == g.user: + real_devices.append(dev) data['devices'] = OrderedSet(real_devices) # Change the owner for every devices for dev in data['devices']: - dev.owner = data['action'].user_to - if hasattr(dev, 'components'): - for c in dev.components: - c.owner = data['action'].user_to + user_to = data['action'].user_to + dev.change_owner(user_to) class RevokeView(ConfirmMixin): @@ -228,49 +203,48 @@ class RevokeView(ConfirmMixin): self.validate(a) def validate(self, data): - """If there are one device than have one confirmation, - then remove the list this device of the list of devices of this action - """ + """All devices need to have the status of DoubleConfirmation.""" + ### check ### - devs_confirm = [] if not data['devices']: raise ValidationError('Devices not exist.') for dev in data['devices']: - if dev.last_action_trading.type == 'Confirm': - devs_confirm.append(dev) - - if not len(data['devices']) == len(devs_confirm): - txt = "Some of this devices can't be reboked" - raise ValidationError(txt) + if not dev.trading == 'TradeConfirmed': + txt = 'Some of devices do not have enough to confirm for to do a revoke' + ValidationError(txt) ### End check ### + ids = {d.id for d in data['devices']} lot = data['action'].lot - devices = set(data['devices']) - without_confirms = set() # set of devs without confirms of user2 + # import pdb; pdb.set_trace() + self.model = delete_from_trade(lot, ids) - if g.user == lot.trade.author: - for dev in devices: - ac = dev.last_action_trading - if ac.type == 'Confirm' and ac.user == g.user: - without_confirms.add(dev) + # devices = set(data['devices']) + # without_confirms = set() # set of devs without confirms of user2 - # we need to mark one revoke for every devs - revoke = Revoke(action=lot.trade, user=g.user, devices=devices) - db.session.add(revoke) + # if g.user == lot.trade.author: + # for dev in devices: + # ac = dev.last_action_trading + # if ac.type == 'Confirm' and ac.user == g.user: + # without_confirms.add(dev) - if without_confirms: - confirm_revoke = ConfirmRevoke( - action=revoke, - user=g.user, - devices=without_confirms - ) - db.session.add(confirm_revoke) + # # we need to mark one revoke for every devs + # revoke = Revoke(action=lot.trade, user=g.user, devices=devices) + # db.session.add(revoke) - lot.devices.difference_update(without_confirms) - lot.trade.devices = lot.devices + # if without_confirms: + # confirm_revoke = ConfirmRevoke( + # action=revoke, + # user=g.user, + # devices=without_confirms + # ) + # db.session.add(confirm_revoke) - self.model = revoke + # lot.devices.difference_update(without_confirms) + # lot.trade.devices = lot.devices + + # self.model = revoke class ConfirmRevokeView(ConfirmMixin): @@ -287,38 +261,18 @@ class ConfirmRevokeView(ConfirmMixin): Model = ConfirmRevoke def validate(self, data): - """If there are one device than have one confirmation, - then remove the list this device of the list of devices of this action - """ - real_devices = [] + """All devices need to have the status of revoke.""" + + if not data['action'].type == 'Revoke': + txt = 'Error: this action is not a revoke action' + ValidationError(txt) + for dev in data['devices']: - actions = copy.copy(dev.actions) - actions.reverse() - for ac in actions: - if ac == data['action']: - # If device have the last action the action for confirm - real_devices.append(dev) - break + if not dev.trading == 'Revoke': + txt = 'Some of devices do not have revoke to confirm' + ValidationError(txt) - if ac.t == 'Revoke' and not ac.user == g.user: - # If device is revoke before you can Confirm now - # and revoke is an action of one other user - real_devices.append(dev) - break - - if ac.t == ConfirmRevoke.t and ac.user == g.user: - # If device is confirmed we don't need confirmed again - break - - if ac.t == Confirm.t: - # if onwer of trade confirm again before than this user Confirm the - # revoke, then is not possible confirm the revoke - # - # If g.user confirm the trade before do a ConfirmRevoke - # then g.user can not to do the ConfirmRevoke more - break - - devices = OrderedSet(real_devices) + devices = OrderedSet(data['devices']) data['devices'] = devices # Change the owner for every devices @@ -326,10 +280,6 @@ class ConfirmRevokeView(ConfirmMixin): trade = data['action'].action for dev in devices: - # TODO @cayop if it's possible the both users insert devices into a lot, then there are problems - dev.owner = trade.author - if hasattr(dev, 'components'): - for c in dev.components: - c.owner = trade.author + dev.reset_owner() trade.lot.devices.difference_update(devices) diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 852ed4ca..61363ed8 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -266,8 +266,10 @@ class Device(Thing): """The trading state, or None if no Trade action has ever been performed to this device. This extract the posibilities for to do""" - trade = 'Trade' + # trade = 'Trade' confirm = 'Confirm' + need_confirm = 'NeedConfirmation' + double_confirm = 'TradeConfirmed' revoke = 'Revoke' revoke_pending = 'RevokePending' confirm_revoke = 'ConfirmRevoke' @@ -298,26 +300,37 @@ class Device(Thing): ## RevokeConfirmation => RevokeConfirmed ac = self.last_action_trading + if not ac: + return + + first_owner = self.which_user_put_this_device_in_trace() if ac.type == confirm_revoke: # can to do revoke_confirmed return confirm_revoke - if ac.type == revoke and ac.user == g.user: - # can todo revoke_pending - return revoke_pending + if ac.type == revoke: + if ac.user == g.user: + # can todo revoke_pending + return revoke_pending + else: + # can to do confirm_revoke + return revoke - if ac.type == revoke and ac.user != g.user: - # can to do confirm_revoke - return revoke + if ac.type == confirm: + if not first_owner: + return - if ac.type == confirm and (ac.user == g.user or ac.action.author == g.user): - # can to do revoke - return confirm - - if ac.type == confirm and ac.user != g.user: - # can to do confirm - return trade + if ac.user == first_owner: + if first_owner == g.user: + # can to do revoke + return confirm + else: + # can to do confirm + return need_confirm + else: + # can to do revoke + return double_confirm @property def revoke(self): @@ -421,12 +434,37 @@ class Device(Thing): """ try: # noinspection PyTypeHints - actions = self.actions + actions = copy.copy(self.actions) actions.sort(key=lambda x: x.created) return next(e for e in reversed(actions) if isinstance(e, types)) except StopIteration: raise LookupError('{!r} does not contain actions of types {}.'.format(self, types)) + def which_user_put_this_device_in_trace(self): + """which is the user than put this device in this trade""" + actions = copy.copy(self.actions) + actions.sort(key=lambda x: x.created) + actions.reverse() + last_ac = None + # search the automatic Confirm + for ac in actions: + if ac.type == 'Trade': + return last_ac.user + if ac.type == 'Confirm': + last_ac = ac + + def change_owner(self, new_user): + """util for change the owner one device""" + self.owner = new_user + if hasattr(self, 'components'): + for c in self.components: + c.owner = new_user + + def reset_owner(self): + """Change the owner with the user put the device into the trade""" + user = self.which_user_put_this_device_in_trace() + self.change_owner(user) + def _warning_actions(self, actions): return sorted(ev for ev in actions if ev.severity >= Severity.Warning) diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 16e27bbe..c75291dc 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -230,12 +230,11 @@ class LotDeviceView(LotBaseChildrenView): return users = [g.user.id] - # Not for the moment - # if lot.trade: + if lot.trade: # all users involved in the trade action can modify the lot - # trade_users = [lot.trade.user_from.id, lot.trade.user_to.id] - # if g.user in trade_users: - # users = trade_users + trade_users = [lot.trade.user_from.id, lot.trade.user_to.id] + if g.user in trade_users: + users = trade_users devices = set(Device.query.filter(Device.id.in_(ids)).filter( Device.owner_id.in_(users))) @@ -253,47 +252,60 @@ class LotDeviceView(LotBaseChildrenView): if not ids.issubset({x.id for x in lot.devices}): return - users = [g.user.id] - # import pdb; pdb.set_trace() if lot.trade: - # all users involved in the trade action can modify the lot - trade_users = [lot.trade.user_from.id, lot.trade.user_to.id] - if g.user in trade_users: - users = trade_users + return delete_from_trade(lot, ids) + if not g.user in lot.owner: + txt = 'This is not your trade' + raise ma.ValidationError(txt) devices = set(Device.query.filter(Device.id.in_(ids)).filter( - Device.owner_id.in_(users))) + Device.owner_id.in_(g.user.id))) - if not lot.trade: - lot.devices.difference_update(devices) - return - - # if is a trade - if not g.user in [lot.trade.user_from, lot.trade.user_to]: - # theoretically this case is impossible - return + lot.devices.difference_update(devices) - # Now we need to know which devices we need extract of the lot - without_confirms = set() # set of devs without confirms of user2 +def delete_from_trade(lot: Lot, ids: Set[int]): + users = [lot.trade.user_from.id, lot.trade.user_to.id] + if not g.user.id in users: + # theoretically this case is impossible + txt = 'This is not your trade' + raise ma.ValidationError(txt) - if g.user == lot.trade.author: - for dev in devices: - ac = dev.last_action_trading - if ac.type == 'Confirm' and ac.user == g.user: - without_confirms.add(dev) + # import pdb; pdb.set_trace() + devices = set(Device.query.filter(Device.id.in_(ids)).filter( + Device.owner_id.in_(users))) - # we need to mark one revoke for every devs - revoke = Revoke(action=lot.trade, user=g.user, devices=devices) - db.session.add(revoke) + # Now we need to know which devices we need extract of the lot + without_confirms = set() # set of devs without confirms of user2 - if without_confirms: - confirm_revoke = ConfirmRevoke( - action=revoke, - user=g.user, - devices=without_confirms - ) - db.session.add(confirm_revoke) + # if the trade need confirmation, then extract all devs than + # have only one confirmation and is from the same user than try to do + # now the revoke action + if lot.trade.confirm: + for dev in devices: + # if have only one confirmation + # then can be revoked and deleted of the lot + if dev.trading == 'NeedConfirmation': + without_confirms.add(dev) + dev.reset_owner() - lot.devices.difference_update(without_confirms) - lot.trade.devices = lot.devices + # we need to mark one revoke for every devs + revoke = Revoke(action=lot.trade, user=g.user, devices=devices) + db.session.add(revoke) + + if not lot.trade.confirm: + # if the trade is with phantom account + without_confirms = devices + + if without_confirms: + confirm_revoke = ConfirmRevoke( + action=revoke, + user=g.user, + devices=without_confirms + ) + db.session.add(confirm_revoke) + + lot.devices.difference_update(without_confirms) + lot.trade.devices = lot.devices + + return revoke From 289126a8a721679c2550e4877f78d2d837ef55a9 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Mon, 7 Jun 2021 11:48:50 +0200 Subject: [PATCH 52/52] fixing revoke --- ereuse_devicehub/resources/lot/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index c75291dc..484d9c3a 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -285,7 +285,9 @@ def delete_from_trade(lot: Lot, ids: Set[int]): for dev in devices: # if have only one confirmation # then can be revoked and deleted of the lot - if dev.trading == 'NeedConfirmation': + # Confirm of dev.trading mean that there are only one confirmation + # and the first user than put this device in trade is the actual g.user + if dev.trading == 'Confirm': without_confirms.add(dev) dev.reset_owner()