diff --git a/CHANGELOG.md b/CHANGELOG.md index 3213330a..5bfc15b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,16 @@ 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.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 ## [1.0.5-beta] - [addend] #124 adding endpoint for extract the internal stats of use 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" 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.') diff --git a/ereuse_devicehub/config.py b/ereuse_devicehub/config.py index e9d1373d..74526179 100644 --- a/ereuse_devicehub/config.py +++ b/ereuse_devicehub/config.py @@ -39,6 +39,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/dummy/dummy.py b/ereuse_devicehub/dummy/dummy.py index da0fe385..183dbb9f 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: @@ -194,6 +196,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/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py b/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py new file mode 100644 index 00000000..97a50435 --- /dev/null +++ b/ereuse_devicehub/migrations/versions/21afd375a654_session_table.py @@ -0,0 +1,62 @@ +"""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 = '398826453b39' +branch_labels = None +depends_on = None +comment_update = 'The last time Devicehub recorded a change for this thing.\n' + + +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=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), + 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') + 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/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/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 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 5250469d..3d12bfda 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -757,7 +757,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) diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index 3c99c3ef..bb90af09 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -640,13 +640,26 @@ class Trade(ActionWithMultipleDevices): __doc__ = m.Trade.__doc__ 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(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, @@ -654,7 +667,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) @@ -676,7 +689,7 @@ class Trade(ActionWithMultipleDevices): data['documents'] = data['lot'].documents @validates_schema - def validate_user_to_id(self, data: dict): + def validate_user_to_email(self, data: dict): """ - if user_to exist * confirmation @@ -685,15 +698,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 @@ -702,13 +714,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 @@ -716,7 +727,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 522b323d..eaf3a352 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.views import delete_from_trade class TradeView(): @@ -29,6 +30,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) @@ -63,7 +66,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.id in [self.trade.user_from_id, self.trade.user_to_id] + if not g.user in [self.trade.user_from, self.trade.user_to]: + txt = "You do not participate in this trading" + raise ValidationError(txt) if self.trade.user_from == g.user or self.trade.user_from.phantom: confirm_from = Confirm(user=self.trade.user_from, @@ -87,12 +92,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() @@ -103,8 +108,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() @@ -176,41 +181,16 @@ class ConfirmView(ConfirmMixin): """ 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 but is not for g.user, then need confirm - 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): @@ -226,28 +206,54 @@ 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 = [] + """All devices need to have the status of DoubleConfirmation.""" + + ### check ### + 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 not dev.trading == 'TradeConfirmed': + txt = 'Some of devices do not have enough to confirm for to do a revoke' + ValidationError(txt) + ### End check ### - if ac.t == 'Revoke' and ac.user == g.user: - break + ids = {d.id for d in data['devices']} + lot = data['action'].lot + # import pdb; pdb.set_trace() + self.model = delete_from_trade(lot, ids) - if ac.t == Confirm.t and ac.user == g.user: - real_devices.append(dev) - break + # 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): @@ -264,46 +270,25 @@ 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 - - data['devices'] = OrderedSet(real_devices) + devices = OrderedSet(data['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 - dev.owner = trade.author - if hasattr(dev, 'components'): - for c in dev.components: - c.owner = trade.author + # data['action'] == 'Revoke' + trade = data['action'].action + for dev in devices: + 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 bf43a356..61363ed8 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 @@ -253,14 +254,100 @@ 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 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""" + + # trade = 'Trade' + confirm = 'Confirm' + need_confirm = 'NeedConfirmation' + double_confirm = 'TradeConfirmed' + revoke = 'Revoke' + revoke_pending = 'RevokePending' + confirm_revoke = 'ConfirmRevoke' + # 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 + ## Revoke User1 => RevokePending + ## RevokeConfirmation => RevokeConfirmed + ## + ## + ## 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 + + 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: + if ac.user == g.user: + # can todo revoke_pending + return revoke_pending + else: + # can to do confirm_revoke + return revoke + + if ac.type == confirm: + if not first_owner: + return + + 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): + """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): + """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): @@ -347,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/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/device/views.py b/ereuse_devicehub/resources/device/views.py index 8e032fc7..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,7 +151,16 @@ class DeviceView(View): ) def query(self, args): - 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 diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index 82008c69..3b72d85d 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 @@ -18,7 +19,9 @@ 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.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 @@ -253,7 +256,7 @@ class StampsView(View): url = urlutils.URL(request.url) url.normalize() url.path_parts = url.path_parts[:-2] + ['check', ''] - return url.to_text() + return url.to_text() def get(self): result = ('', '') @@ -314,6 +317,30 @@ class InternalStatsView(DeviceView): return output +class WbConfDocumentView(DeviceView): + def get(self, wbtype: str): + if not wbtype.lower() in ['usodyrate', 'usodywipe']: + return jsonify('') + + data = {'token': self.get_token(), + 'host': app.config['DB_HOST'], + 'inventory': app.config['DB_SCHEMA'] + } + data['erase'] = False + # data['erase'] = True if wbtype == 'usodywipe' else False + + env = flask.render_template('documents/wbSettings.ini', **data) + output = make_response(env) + output.headers['Content-Disposition'] = 'attachment; filename=settings.ini' + output.headers['Content-type'] = 'text/plain' + return output + + def get_token(self): + 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): __type__ = 'Document' SCHEMA = None @@ -380,3 +407,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 = WbConfDocumentView.as_view('WbConfDocumentView', + definition=self, + auth=app.auth) + wbconf_view = app.auth.requires_auth(wbconf_view) + self.add_url_rule('/wbconf/', view_func=wbconf_view, methods=get) 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 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/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..2119c048 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,3 +27,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) + trade = NestedOn(s_action.Trade, dump_only=True) diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 295f63e1..484d9c3a 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, ConfirmRevoke from ereuse_devicehub.resources.lot.models import Lot, Path @@ -98,9 +97,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 @@ -109,7 +108,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) @@ -253,20 +252,62 @@ class LotDeviceView(LotBaseChildrenView): if not ids.issubset({x.id for x in lot.devices}): return - users = [g.user.id] 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))) lot.devices.difference_update(devices) - if lot.trade: - 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) + +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) + + # import pdb; pdb.set_trace() + devices = set(Device.query.filter(Device.id.in_(ids)).filter( + Device.owner_id.in_(users))) + + # Now we need to know which devices we need extract of the lot + without_confirms = set() # set of devs without confirms of user2 + + # 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 + # 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() + + # 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 diff --git a/ereuse_devicehub/resources/user/__init__.py b/ereuse_devicehub/resources/user/__init__.py index ec9eed78..1bbe508b 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'}) + logout_view = app.auth.requires_auth(logout) + self.add_url_rule('/logout/', view_func=logout_view, methods={'GET'}) @argument('email') @option('-i', '--inventory', diff --git a/ereuse_devicehub/resources/user/models.py b/ereuse_devicehub/resources/user/models.py index 18e4efc8..f1690156 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, Boolean +from sqlalchemy import Column, Boolean, 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): @@ -63,3 +65,18 @@ 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): + __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) + 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) 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) diff --git a/ereuse_devicehub/resources/user/views.py b/ereuse_devicehub/resources/user/views.py index 8eadc863..2fc8fc31 100644 --- a/ereuse_devicehub/resources/user/views.py +++ b/ereuse_devicehub/resources/user/views.py @@ -1,11 +1,12 @@ -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 class UserView(View): @@ -24,3 +25,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') diff --git a/tests/conftest.py b/tests/conftest.py index 94abed59..9dd556eb 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.""" @@ -112,7 +114,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 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/files/basic.csv b/tests/files/basic.csv index a5370449..5b66408b 100644 --- a/tests/files/basic.csv +++ b/tests/files/basic.csv @@ -1,2 +1,2 @@ DevicehubID;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) -93652;;http://localhost/devices/93652;;;;;;;;;;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;; +93652;;http://localhost/devices/93652;;;;;;;;;;desktop-d1mr-d1ml-d1s;Desktop;Microtower;d1s;d1ml;d1mr;Fri Apr 16 18:13:33 2021;Workbench 11.0;2021-04-16 18:13:33.731090+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 2984ace0..473fc81e 100644 --- a/tests/files/proposal_extended_csv_report.csv +++ b/tests/files/proposal_extended_csv_report.csv @@ -1,3 +1,3 @@ -DevicehubID;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) -93652;;http://localhost/devices/93652;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 -64K64;;http://localhost/devices/64K64;;;;;;;;;;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 +DevicehubID;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) +93652;;http://localhost/devices/93652;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 18:14:56 2021;Workbench 11.0a2;2021-04-16 18:14:57.353702+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 18:14:56.819171+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 +J2MA2;;http://localhost/devices/J2MA2;;;;;;;;;;laptop-asustek_computer_inc-1001pxd-b8oaas048287-14:da:e9:42:f6:7c;Laptop;Netbook;b8oaas048287;1001pxd;asustek computer inc.;Fri Apr 16 18:14:57 2021;Workbench 11.0b11;2021-04-16 18:14:57.160888+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 18:14:57.093108+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 18:14:57.095327+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 18:14:57.099341+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 40b1c886..f843eb44 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -387,7 +387,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", @@ -420,7 +420,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", @@ -451,7 +451,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", @@ -482,7 +482,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", @@ -515,7 +515,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", @@ -765,6 +765,227 @@ def test_trade_endpoint(user: UserClient, user2: UserClient): device2, _ = user2.get(res=Device, item=device['id']) assert device2['id'] == device['id'] +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_offer_without_to(user: UserClient): + """Test one offer with automatic confirmation and without user to""" + snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + device = Device.query.filter_by(id=snapshot['device']['id']).one() + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=[('id', device.id)]) + + # check the owner of the device + assert device.owner.email == user.email + for c in device.components: + assert c.owner.email == user.email + + request_post = { + 'type': 'Trade', + 'devices': [device.id], + 'userFromEmail': user.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot['id'], + 'confirms': False, + 'code': 'MAX' + } + user.post(res=models.Action, data=request_post) + + trade = models.Trade.query.one() + assert device in trade.devices + # assert trade.confirm_transfer + users = [ac.user for ac in trade.acceptances] + assert trade.user_to == device.owner + assert request_post['code'].lower() in device.owner.email + assert device.owner.active == False + assert device.owner.phantom == True + assert trade.user_to in users + assert trade.user_from in users + assert device.owner.email != user.email + for c in device.components: + assert c.owner.email != user.email + + # check if the user_from is owner of the devices + request_post = { + 'type': 'Trade', + 'devices': [device.id], + 'userFromEmail': user.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot['id'], + 'confirms': False, + 'code': 'MAX' + } + user.post(res=models.Action, data=request_post, status=422) + trade = models.Trade.query.one() + + # Check if the new phantom account is reused and not duplicated + computer = file('1-device-with-components.snapshot') + snapshot2, _ = user.post(computer, res=models.Snapshot) + device2 = Device.query.filter_by(id=snapshot2['device']['id']).one() + lot2 = Lot('MyLot2') + lot2.owner_id = user.user['id'] + lot2.devices.add(device2) + db.session.add(lot2) + db.session.flush() + request_post2 = { + 'type': 'Trade', + 'devices': [device2.id], + 'userFromEmail': user.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot2.id, + 'confirms': False, + 'code': 'MAX' + } + user.post(res=models.Action, data=request_post2) + assert User.query.filter_by(email=device.owner.email).count() == 1 + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_offer_without_from(user: UserClient, user2: UserClient): + """Test one offer without confirmation and without user from""" + snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + lot = Lot('MyLot') + lot.owner_id = user.user['id'] + device = Device.query.filter_by(id=snapshot['device']['id']).one() + + # check the owner of the device + assert device.owner.email == user.email + assert device.owner.email != user2.email + + lot.devices.add(device) + db.session.add(lot) + db.session.flush() + request_post = { + 'type': 'Trade', + 'devices': [device.id], + 'userToEmail': user2.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot.id, + 'confirms': False, + 'code': 'MAX' + } + action, _ = user2.post(res=models.Action, data=request_post, status=422) + + request_post['userToEmail'] = user.email + action, _ = user.post(res=models.Action, data=request_post) + trade = models.Trade.query.one() + + phantom_user = trade.user_from + assert request_post['code'].lower() in phantom_user.email + assert phantom_user.active == False + assert phantom_user.phantom == True + # assert trade.confirm_transfer + + users = [ac.user for ac in trade.acceptances] + assert trade.user_to in users + assert trade.user_from in users + assert user.email in trade.devices[0].owner.email + assert device.owner.email != user2.email + assert device.owner.email == user.email + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_offer_without_users(user: UserClient): + """Test one offer with doble confirmation""" + user2 = User(email='baz@baz.cxm', password='baz') + user2.individuals.add(Person(name='Tommy')) + db.session.add(user2) + db.session.commit() + snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + lot = Lot('MyLot') + lot.owner_id = user.user['id'] + device = Device.query.filter_by(id=snapshot['device']['id']).one() + lot.devices.add(device) + db.session.add(lot) + db.session.flush() + request_post = { + 'type': 'Trade', + 'devices': [device.id], + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot.id, + 'confirms': False, + 'code': 'MAX' + } + action, response = user.post(res=models.Action, data=request_post, status=422) + txt = 'you need one user from or user to for to do a offer' + assert txt in action['message']['_schema'] + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_offer(user: UserClient): + """Test one offer with doble confirmation""" + user2 = User(email='baz@baz.cxm', password='baz') + user2.individuals.add(Person(name='Tommy')) + db.session.add(user2) + db.session.commit() + snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + lot = Lot('MyLot') + lot.owner_id = user.user['id'] + device = Device.query.filter_by(id=snapshot['device']['id']).one() + assert device.owner.email == user.email + assert device.owner.email != user2.email + lot.devices.add(device) + db.session.add(lot) + db.session.flush() + request_post = { + 'type': 'Trade', + 'devices': [], + 'userFromEmail': user.email, + 'userToEmail': user2.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot.id, + 'confirms': True, + } + + action, _ = user.post(res=models.Action, data=request_post) + # no there are transfer of devices + assert device.owner.email == user.email + assert device.owner.email != user2.email + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_offer_without_devices(user: UserClient): + """Test one offer with doble confirmation""" + user2 = User(email='baz@baz.cxm', password='baz') + user2.individuals.add(Person(name='Tommy')) + db.session.add(user2) + db.session.commit() + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + request_post = { + 'type': 'Trade', + 'devices': [], + 'userFromEmail': user.email, + 'userToEmail': user2.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot['id'], + 'confirms': True, + } + + user.post(res=models.Action, data=request_post) + # no there are transfer of devices + + +>>>>>>> feature/endpoint-confirm @pytest.mark.mvp @pytest.mark.usefixtures(conftest.auth_app_context.__name__) def test_price_custom(): @@ -815,3 +1036,420 @@ def test_erase_physical(): db.session.add(erasure) db.session.commit() +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_endpoint_confirm(user: UserClient, user2: UserClient): + """Check the normal creation and visualization of one confirmation trade""" + snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + device_id = snapshot['device']['id'] + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=[('id', device_id)]) + + request_post = { + 'type': 'Trade', + 'devices': [device_id], + 'userFromEmail': user.email, + 'userToEmail': user2.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot['id'], + 'confirms': True, + } + + user.post(res=models.Action, data=request_post) + trade = models.Trade.query.one() + + assert trade.devices[0].owner.email == user.email + + request_confirm = { + 'type': 'Confirm', + 'action': trade.id, + 'devices': [device_id] + } + + user2.post(res=models.Action, data=request_confirm) + user2.post(res=models.Action, data=request_confirm, status=422) + assert len(trade.acceptances) == 2 + assert trade.devices[0].owner.email == user2.email + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_confirm_revoke(user: UserClient, user2: UserClient): + """Check the normal revoke of one confirmation""" + snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + device_id = snapshot['device']['id'] + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=[('id', device_id)]) + + request_post = { + 'type': 'Trade', + 'devices': [device_id], + 'userFromEmail': user.email, + 'userToEmail': user2.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot['id'], + 'confirms': True, + } + + user.post(res=models.Action, data=request_post) + trade = models.Trade.query.one() + + request_confirm = { + 'type': 'Confirm', + 'action': trade.id, + 'devices': [device_id] + } + + request_revoke = { + 'type': 'Revoke', + 'action': trade.id, + 'devices': [device_id], + } + + + # Normal confirmation + user2.post(res=models.Action, data=request_confirm) + + # Normal revoke + user2.post(res=models.Action, data=request_revoke) + + # Error for try duplicate revoke + user2.post(res=models.Action, data=request_revoke, status=422) + assert len(trade.acceptances) == 3 + + # You can not to do one confirmation next of one revoke + user2.post(res=models.Action, data=request_confirm, status=422) + assert len(trade.acceptances) == 3 + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_usecase_confirmation(user: UserClient, user2: UserClient): + """Example of one usecase about confirmation""" + # the pRp (manatest_usecase_confirmationger) creates a temporary lot + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + # The manager add 7 device into the lot + snap1, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + snap2, _ = user.post(file('acer.happy.battery.snapshot'), res=models.Snapshot) + snap3, _ = user.post(file('asus-1001pxd.snapshot'), res=models.Snapshot) + snap4, _ = user.post(file('desktop-9644w8n-lenovo-0169622.snapshot'), res=models.Snapshot) + snap5, _ = user.post(file('laptop-hp_255_g3_notebook-hewlett-packard-cnd52270fw.snapshot'), res=models.Snapshot) + snap6, _ = user.post(file('1-device-with-components.snapshot'), res=models.Snapshot) + snap7, _ = user.post(file('asus-eee-1000h.snapshot.11'), res=models.Snapshot) + snap8, _ = user.post(file('complete.export.snapshot'), res=models.Snapshot) + snap9, _ = user.post(file('real-hp-quad-core.snapshot.11'), res=models.Snapshot) + snap10, _ = user.post(file('david.lshw.snapshot'), res=models.Snapshot) + + devices = [('id', snap1['device']['id']), + ('id', snap2['device']['id']), + ('id', snap3['device']['id']), + ('id', snap4['device']['id']), + ('id', snap5['device']['id']), + ('id', snap6['device']['id']), + ('id', snap7['device']['id']), + ('id', snap8['device']['id']), + ('id', snap9['device']['id']), + ('id', snap10['device']['id']), + ] + lot, _ = user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices[:7]) + + # the manager shares the temporary lot with the SCRAP as an incoming lot + # for the SCRAP to confirm it + request_post = { + 'type': 'Trade', + 'devices': [], + 'userFromEmail': user2.email, + 'userToEmail': user.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot['id'], + 'confirms': True, + } + + 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 = { + 'type': 'Confirm', + 'action': trade.id, + 'devices': [snap1['device']['id'], snap2['device']['id'], snap3['device']['id']] + } + assert trade.devices[0].actions[-2].t == 'Trade' + assert trade.devices[0].actions[-1].t == 'Confirm' + assert trade.devices[0].actions[-1].user == trade.user_to + + user2.post(res=models.Action, data=request_confirm) + assert trade.devices[0].actions[-1].t == 'Confirm' + assert trade.devices[0].actions[-1].user == trade.user_from + n_actions = len(trade.devices[0].actions) + + # check validation error + request_confirm = { + 'type': 'Confirm', + 'action': trade.id, + 'devices': [ + snap10['device']['id'] + ] + } + + user2.post(res=models.Action, data=request_confirm, status=422) + + + # The manager add 3 device more into the lot + lot, _ = user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices[7:]) + + assert trade.devices[-1].actions[-2].t == 'Trade' + assert trade.devices[-1].actions[-1].t == 'Confirm' + assert trade.devices[-1].actions[-1].user == trade.user_to + assert len(trade.devices[0].actions) == n_actions + + + # the SCRAP confirms the rest of devices + request_confirm = { + 'type': 'Confirm', + 'action': trade.id, + 'devices': [ + snap1['device']['id'], + snap2['device']['id'], + snap3['device']['id'], + snap4['device']['id'], + snap5['device']['id'], + snap6['device']['id'], + snap7['device']['id'], + snap8['device']['id'], + snap9['device']['id'], + snap10['device']['id'] + ] + } + + user2.post(res=models.Action, data=request_confirm) + assert trade.devices[-1].actions[-3].t == 'Trade' + assert trade.devices[-1].actions[-1].t == 'Confirm' + assert trade.devices[-1].actions[-1].user == trade.user_from + assert len(trade.devices[0].actions) == n_actions + + # The manager remove one device of the lot and automaticaly + # is create one revoke action + device_10 = trade.devices[-1] + lot, _ = user.delete({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices[-1:], status=200) + assert len(trade.lot.devices) == len(trade.devices) == 9 + assert not device_10 in trade.devices + assert device_10.actions[-1].t == 'Revoke' + + lot, _ = user.delete({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices[-1:], status=200) + + assert device_10.actions[-1].t == 'Revoke' + assert device_10.actions[-2].t == 'Confirm' + + # the SCRAP confirms the revoke action + request_confirm_revoke = { + 'type': 'ConfirmRevoke', + 'action': device_10.actions[-1].id, + 'devices': [ + snap10['device']['id'] + ] + } + + user2.post(res=models.Action, data=request_confirm_revoke) + 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, + 'devices': [ + snap9['device']['id'] + ] + } + + user2.post(res=models.Action, data=request_confirm_revoke, status=422) + + + # The manager add again device_10 + assert len(trade.devices) == 9 + lot, _ = user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices[-1:]) + + assert device_10.actions[-1].t == 'Confirm' + assert device_10 in trade.devices + assert len(trade.devices) == 10 + + + # the SCRAP confirms the action trade for device_10 + request_reconfirm = { + 'type': 'Confirm', + 'action': trade.id, + 'devices': [ + snap10['device']['id'] + ] + } + # import pdb; pdb.set_trace() + user2.post(res=models.Action, data=request_reconfirm) + assert device_10.actions[-1].t == 'Confirm' + assert device_10.actions[-1].user == trade.user_from + assert device_10.actions[-2].t == 'Confirm' + assert device_10.actions[-2].user == trade.user_to + assert device_10.actions[-3].t == 'ConfirmRevoke' + assert len(device_10.actions) == 13 + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_confirmRevoke(user: UserClient, user2: UserClient): + """Example of one usecase about confirmation""" + # the pRp (manatest_usecase_confirmationger) creates a temporary lot + lot, _ = user.post({'name': 'MyLot'}, res=Lot) + # The manager add 7 device into the lot + snap1, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + snap2, _ = user.post(file('acer.happy.battery.snapshot'), res=models.Snapshot) + snap3, _ = user.post(file('asus-1001pxd.snapshot'), res=models.Snapshot) + snap4, _ = user.post(file('desktop-9644w8n-lenovo-0169622.snapshot'), res=models.Snapshot) + snap5, _ = user.post(file('laptop-hp_255_g3_notebook-hewlett-packard-cnd52270fw.snapshot'), res=models.Snapshot) + snap6, _ = user.post(file('1-device-with-components.snapshot'), res=models.Snapshot) + snap7, _ = user.post(file('asus-eee-1000h.snapshot.11'), res=models.Snapshot) + snap8, _ = user.post(file('complete.export.snapshot'), res=models.Snapshot) + snap9, _ = user.post(file('real-hp-quad-core.snapshot.11'), res=models.Snapshot) + snap10, _ = user.post(file('david.lshw.snapshot'), res=models.Snapshot) + + devices = [('id', snap1['device']['id']), + ('id', snap2['device']['id']), + ('id', snap3['device']['id']), + ('id', snap4['device']['id']), + ('id', snap5['device']['id']), + ('id', snap6['device']['id']), + ('id', snap7['device']['id']), + ('id', snap8['device']['id']), + ('id', snap9['device']['id']), + ('id', snap10['device']['id']), + ] + lot, _ = user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices) + + # the manager shares the temporary lot with the SCRAP as an incoming lot + # for the CRAP to confirm it + request_post = { + 'type': 'Trade', + 'devices': [], + 'userFromEmail': user2.email, + 'userToEmail': user.email, + 'price': 10, + 'date': "2020-12-01T02:00:00+00:00", + 'documentID': '1', + 'lot': lot['id'], + 'confirms': True, + } + + user.post(res=models.Action, data=request_post) + trade = models.Trade.query.one() + + # the SCRAP confirms all of devices + request_confirm = { + 'type': 'Confirm', + 'action': trade.id, + 'devices': [ + snap1['device']['id'], + snap2['device']['id'], + snap3['device']['id'], + snap4['device']['id'], + snap5['device']['id'], + snap6['device']['id'], + snap7['device']['id'], + snap8['device']['id'], + snap9['device']['id'], + snap10['device']['id'] + ] + } + + user2.post(res=models.Action, data=request_confirm) + assert trade.devices[-1].actions[-3].t == 'Trade' + assert trade.devices[-1].actions[-1].t == 'Confirm' + assert trade.devices[-1].actions[-1].user == trade.user_from + + # The manager remove one device of the lot and automaticaly + # is create one revoke action + device_10 = trade.devices[-1] + lot, _ = user.delete({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices[-1:], status=200) + assert len(trade.lot.devices) == len(trade.devices) == 9 + assert not device_10 in trade.devices + assert device_10.actions[-1].t == 'Revoke' + + lot, _ = user.delete({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices[-1:], status=200) + + assert device_10.actions[-1].t == 'Revoke' + assert device_10.actions[-2].t == 'Confirm' + + # The manager add again device_10 + assert len(trade.devices) == 9 + lot, _ = user.post({}, + res=Lot, + item='{}/devices'.format(lot['id']), + query=devices[-1:]) + + assert device_10.actions[-1].t == 'Confirm' + assert device_10 in trade.devices + assert len(trade.devices) == 10 + + # the SCRAP confirms the revoke action + request_confirm_revoke = { + 'type': 'ConfirmRevoke', + 'action': device_10.actions[-2].id, + 'devices': [ + snap10['device']['id'] + ] + } + + # check validation error + user2.post(res=models.Action, data=request_confirm_revoke, status=422) + + # the SCRAP confirms the action trade for device_10 + request_reconfirm = { + 'type': 'Confirm', + 'action': trade.id, + 'devices': [ + snap10['device']['id'] + ] + } + user2.post(res=models.Action, data=request_reconfirm) + assert device_10.actions[-1].t == 'Confirm' + assert device_10.actions[-1].user == trade.user_from + assert device_10.actions[-2].t == 'Confirm' + assert device_10.actions[-2].user == trade.user_to + assert device_10.actions[-3].t == 'Revoke' +>>>>>>> feature/endpoint-confirm diff --git a/tests/test_basic.py b/tests/test_basic.py index 32125937..010a4d42 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/', @@ -56,7 +57,8 @@ def test_api_docs(client: Client): '/tags/{tag_id}/device/{device_id}', '/trade-documents/', '/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}', diff --git a/tests/test_device.py b/tests/test_device.py index 7d8cc374..4a058284 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,74 +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() - devicehub_id = pc.devicehub_id - - pc, _ = user.get(res=d.Device, item=devicehub_id) - 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.devicehub_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 ) @@ -536,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 @@ -544,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' diff --git a/tests/test_device_find.py b/tests/test_device_find.py index 476ec36d..fa6cd83d 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.""" - snap, _ = 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/%s' % snap['device']['devicehubID'] + assert i['items'][0]['url'] == '/devices/%s' % snapshot['device']['devicehubID'] pc = next(d for d in i['items'] if d['type'] == 'Desktop') assert len(pc['actions']) == 4 assert len(pc['components']) == 3 @@ -241,16 +241,16 @@ 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', i['items'][0]['devicehubID'])]) 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_documents.py b/tests/test_documents.py index c0c92cf2..45e6cb95 100644 --- a/tests/test_documents.py +++ b/tests/test_documents.py @@ -10,14 +10,17 @@ 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 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 @@ -262,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', @@ -464,7 +468,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 +476,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 +505,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 +520,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 +542,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 +577,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 +598,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,15 +615,15 @@ 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 @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/') @@ -644,3 +648,24 @@ def test_get_document_internal_stats(user: UserClient, user2: UserClient): export_csv = list(obj_csv) 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.""" + + 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 = False' in env + # assert 'WB_ERASE = True' in env + + session = Session.query.filter_by(user_id=user.user['id'], + type=SessionType.Internal).first() + 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) diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py index 4ab6dd95..82989f17 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. @@ -318,7 +319,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 @@ -838,3 +839,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) diff --git a/tests/test_workbench.py b/tests/test_workbench.py index 3a38b1ae..b2952f13 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'