diff --git a/ereuse_devicehub/api/views.py b/ereuse_devicehub/api/views.py index c566be00..23414b38 100644 --- a/ereuse_devicehub/api/views.py +++ b/ereuse_devicehub/api/views.py @@ -58,6 +58,8 @@ class InventoryView(LoginMixin, SnapshotMixin): self.snapshot_json = ParseSnapshotLsHw(snapshot_json).get_snapshot() snapshot = self.build() + snapshot.device.set_hid() + snapshot.device.binding.device.set_hid() db.session.add(snapshot) snap_log = SnapshotsLog( diff --git a/ereuse_devicehub/dummy/dummy.py b/ereuse_devicehub/dummy/dummy.py index ee7f7c15..ec276de4 100644 --- a/ereuse_devicehub/dummy/dummy.py +++ b/ereuse_devicehub/dummy/dummy.py @@ -1,5 +1,6 @@ import itertools import json +import uuid from pathlib import Path import click @@ -113,6 +114,8 @@ class Dummy: for path in bar: with path.open() as f: snapshot = yaml.load(f) + if snapshot['device']['type'] in ['Desktop', 'Laptop']: + snapshot['device']['system_uuid'] = uuid.uuid4() s, _ = user1.post(res=m.Snapshot, data=self.json_encode(snapshot)) if s.get('uuid', None) == 'ec23c11b-80b6-42cd-ac5c-73ba7acddbc4': sample_pc = s['device']['id'] diff --git a/ereuse_devicehub/dummy/files/asus-1001pxd.snapshot.11.yaml b/ereuse_devicehub/dummy/files/asus-1001pxd.snapshot.11.yaml index f3f907fa..866fc8cc 100644 --- a/ereuse_devicehub/dummy/files/asus-1001pxd.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/asus-1001pxd.snapshot.11.yaml @@ -178,6 +178,7 @@ ], "type": "Laptop" }, + "debug": {"lshw": {"configuration": {"uuid": "79c5098f-bc44-4834-8a59-9ea61d956c31"}}}, "elapsed": 14725, "endTime": "2018-11-24T18:06:37.611704+00:00", "software": "Workbench", diff --git a/ereuse_devicehub/dummy/files/asus-eee-1000h.snapshot.11.yaml b/ereuse_devicehub/dummy/files/asus-eee-1000h.snapshot.11.yaml index f3c848e1..ae5a268e 100644 --- a/ereuse_devicehub/dummy/files/asus-eee-1000h.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/asus-eee-1000h.snapshot.11.yaml @@ -119,6 +119,7 @@ "manufacturer": "ASUSTeK Computer INC." } ], + "debug": {"lshw": {"configuration": {"uuid": "645f00bf-1ec0-4fdb-9608-b5ac73e285f6"}}}, "version": "11.0a4", "elapsed": 6, "endTime": "2016-11-03T17:17:17.266543+00:00" diff --git a/ereuse_devicehub/dummy/files/dell-optiplexgx520.snapshot.11.yaml b/ereuse_devicehub/dummy/files/dell-optiplexgx520.snapshot.11.yaml index 98b23bb8..625884b3 100644 --- a/ereuse_devicehub/dummy/files/dell-optiplexgx520.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/dell-optiplexgx520.snapshot.11.yaml @@ -148,6 +148,7 @@ "model": "0UG982" } ], + "debug": {"lshw": {"configuration": {"uuid": "5dcdd380-5a54-48bc-99bf-aff6019e8491"}}}, "version": "11.0a3", "closed": false, "elapsed": 1512, diff --git a/ereuse_devicehub/dummy/files/hp1.snapshot.11.yaml b/ereuse_devicehub/dummy/files/hp1.snapshot.11.yaml index 86489428..95311cbe 100644 --- a/ereuse_devicehub/dummy/files/hp1.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/hp1.snapshot.11.yaml @@ -132,5 +132,6 @@ "model": "HP Compaq 8100 Elite SFF", "manufacturer": "Hewlett-Packard" }, + "debug": {"lshw": {"configuration": {"uuid": "f6cfe48a-93d5-4e94-ab7b-3ee371e4d048"}}}, "version": "11.0a3" } diff --git a/ereuse_devicehub/dummy/files/hp2.snapshot.11.yaml b/ereuse_devicehub/dummy/files/hp2.snapshot.11.yaml index 80591b42..1e263ce6 100644 --- a/ereuse_devicehub/dummy/files/hp2.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/hp2.snapshot.11.yaml @@ -170,5 +170,6 @@ }, "software": "Workbench", "endTime": "2018-07-11T10:30:22.395958+00:00", + "debug": {"lshw": {"configuration": {"uuid": "75dcb454-ae80-4a87-a192-185d3b0250c0"}}}, "elapsed": 2766 } diff --git a/ereuse_devicehub/dummy/files/laptop-with-2-hid.snapshot.11.yaml b/ereuse_devicehub/dummy/files/laptop-with-2-hid.snapshot.11.yaml index 8cf37d51..8ca0798a 100644 --- a/ereuse_devicehub/dummy/files/laptop-with-2-hid.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/laptop-with-2-hid.snapshot.11.yaml @@ -146,6 +146,7 @@ "pcmcia": 0 } ], + "debug": {"lshw": {"configuration": {"uuid": "fcaf784e-5e57-43a2-b03f-8c56dabd0415"}}}, "uuid": "a01eacdb-db01-43ec-b6fb-a9b8cd21492d", "type": "Snapshot", "version": "11.0a4", diff --git a/ereuse_devicehub/dummy/files/lenovo-3493BAG.snapshot.11.yaml b/ereuse_devicehub/dummy/files/lenovo-3493BAG.snapshot.11.yaml index c73871ad..e7fb82f0 100644 --- a/ereuse_devicehub/dummy/files/lenovo-3493BAG.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/lenovo-3493BAG.snapshot.11.yaml @@ -4,6 +4,7 @@ "closed": false, "endTime": "2018-07-11T13:26:29.365504+00:00", "type": "Snapshot", + "debug": {"lshw": {"configuration": {"uuid": "4f256440-e43f-429a-a2c6-1e8f3365de56"}}}, "device": { "serialNumber": "PB357N0", "actions": [ diff --git a/ereuse_devicehub/dummy/files/nec.snapshot.11.yaml b/ereuse_devicehub/dummy/files/nec.snapshot.11.yaml index d846eb7a..5ec32875 100644 --- a/ereuse_devicehub/dummy/files/nec.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/nec.snapshot.11.yaml @@ -148,6 +148,7 @@ "slots": 4 } ], + "debug": {"lshw": {"configuration": {"uuid": "077cad5d-ae1b-4156-a9a1-98bca6fa5c35"}}}, "version": "11.0a3", "endTime": "2018-07-11T10:28:55.879745+00:00", "type": "Snapshot", diff --git a/ereuse_devicehub/dummy/files/oreo.snapshot.yaml b/ereuse_devicehub/dummy/files/oreo.snapshot.yaml index 348c9420..1e3da274 100644 --- a/ereuse_devicehub/dummy/files/oreo.snapshot.yaml +++ b/ereuse_devicehub/dummy/files/oreo.snapshot.yaml @@ -136,8 +136,8 @@ ], "elapsed": 203, "device": { - "manufacturer": null, - "model": null, + "manufacturer": "Asus", + "model": "P7P55D", "chassis": "Tower", "type": "Desktop", "serialNumber": null, @@ -158,7 +158,7 @@ ] }, "version": "11.0a6", - + "debug": {"lshw": {"configuration": {"uuid": "59ca9a2a-65bd-4802-89bb-315156a9352b"}}}, "type": "Snapshot", "closed": true, "software": "Workbench" diff --git a/ereuse_devicehub/dummy/files/pc-laudem.snapshot.11.yaml b/ereuse_devicehub/dummy/files/pc-laudem.snapshot.11.yaml index a4f76e6f..86127bc1 100644 --- a/ereuse_devicehub/dummy/files/pc-laudem.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/pc-laudem.snapshot.11.yaml @@ -142,7 +142,7 @@ }, "elapsed": 238, "endTime": "2018-10-15T13:59:37.431309+00:00", - + "debug": {"lshw": {"configuration": {"uuid": "43686b8e-e1ae-4e4e-bc51-f98f51e97c2d"}}}, "software": "Workbench", "type": "Snapshot", "uuid": "ec23c11b-80b6-42cd-ac5c-73ba7acddbc4", diff --git a/ereuse_devicehub/dummy/files/real-eee-1001pxd.snapshot.11.yaml b/ereuse_devicehub/dummy/files/real-eee-1001pxd.snapshot.11.yaml index a807c7f0..5a90e00a 100644 --- a/ereuse_devicehub/dummy/files/real-eee-1001pxd.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/real-eee-1001pxd.snapshot.11.yaml @@ -158,5 +158,6 @@ } ] }, + "debug": {"lshw": {"configuration": {"uuid": "a0cef731-9a78-4087-889c-dfb6ba5c2e9b"}}}, "closed": false } diff --git a/ereuse_devicehub/dummy/files/real-hp-quad-core.snapshot.11.yaml b/ereuse_devicehub/dummy/files/real-hp-quad-core.snapshot.11.yaml index 91aa12d6..8d921acd 100644 --- a/ereuse_devicehub/dummy/files/real-hp-quad-core.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/real-hp-quad-core.snapshot.11.yaml @@ -114,6 +114,7 @@ } ], "version": "11.0a3", + "debug": {"lshw": {"configuration": {"uuid": "f2c50acd-501a-4f0b-b07c-58254b2ab8c9"}}}, "device": { "type": "Desktop", "model": "HP Compaq 8000 Elite SFF", diff --git a/ereuse_devicehub/dummy/files/real-hp.snapshot.11.yaml b/ereuse_devicehub/dummy/files/real-hp.snapshot.11.yaml index 7158225e..8f9b2333 100644 --- a/ereuse_devicehub/dummy/files/real-hp.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/real-hp.snapshot.11.yaml @@ -1,6 +1,7 @@ { "closed": false, "uuid": "f9e5e587-baee-44e1-9a94-255d216bbda9", + "debug": {"lshw": {"configuration": {"uuid": "4d21dd26-aa45-4902-a5f2-8a06e364cf25"}}}, "components": [ { "actions": [], diff --git a/ereuse_devicehub/dummy/files/real-toshiba.snapshot.11.yaml b/ereuse_devicehub/dummy/files/real-toshiba.snapshot.11.yaml index 1a274d30..db83c5b2 100644 --- a/ereuse_devicehub/dummy/files/real-toshiba.snapshot.11.yaml +++ b/ereuse_devicehub/dummy/files/real-toshiba.snapshot.11.yaml @@ -131,6 +131,7 @@ "model": "NB200" }, "uuid": "918726ae-c6bc-40aa-97cf-ad80d69268f9", + "debug": {"lshw": {"configuration": {"uuid": "33627ef0-89a9-4659-bb29-faa936727e0b"}}}, "closed": false, "type": "Snapshot" } diff --git a/ereuse_devicehub/inventory/forms.py b/ereuse_devicehub/inventory/forms.py index 9cc85d30..1e641f32 100644 --- a/ereuse_devicehub/inventory/forms.py +++ b/ereuse_devicehub/inventory/forms.py @@ -31,7 +31,7 @@ from wtforms.fields import FormField from ereuse_devicehub.db import db from ereuse_devicehub.inventory.models import DeliveryNote, ReceiverNote, Transfer -from ereuse_devicehub.parser.models import PlaceholdersLog +from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog from ereuse_devicehub.parser.parser import ParseSnapshotLsHw from ereuse_devicehub.parser.schemas import Snapshot_lite from ereuse_devicehub.resources.action.models import Snapshot, Trade @@ -203,7 +203,9 @@ class FilterForm(FlaskForm): if filter_type: self.devices = self.devices.filter(Device.type.in_(filter_type)) - return self.devices.order_by(Device.updated.desc()) + return self.devices.filter(Device.active.is_(True)).order_by( + Device.updated.desc() + ) class LotForm(FlaskForm): @@ -247,6 +249,10 @@ class LotForm(FlaskForm): class UploadSnapshotForm(SnapshotMixin, FlaskForm): snapshot = MultipleFileField('Select a Snapshot File', [validators.DataRequired()]) + def __init__(self, *args, **kwargs): + self.create_new_devices = kwargs.pop('create_new_devices', False) + super().__init__(*args, **kwargs) + def validate(self, extra_validators=None): is_valid = super().validate(extra_validators) @@ -313,10 +319,13 @@ class UploadSnapshotForm(SnapshotMixin, FlaskForm): system_uuid = self.get_uuid(debug) if system_uuid: snapshot_json['device']['system_uuid'] = system_uuid + self.get_fields_extra(debug, snapshot_json) try: snapshot_json = schema.load(snapshot_json) - response = self.build(snapshot_json) + response = self.build( + snapshot_json, create_new_device=self.create_new_devices + ) except ValidationError as err: txt = "{}".format(err) self.errors(txt=txt) @@ -579,6 +588,7 @@ class NewDeviceForm(FlaskForm): device.image = URL(self.image.data) device.placeholder = self.get_placeholder() + device.set_hid() db.session.add(device) placeholder_log = PlaceholdersLog( @@ -1690,3 +1700,118 @@ class BindingForm(FlaskForm): return False return True + + +class UserTrustsForm(FlaskForm): + snapshot_type = SelectField( + '', + [validators.DataRequired()], + choices=[("new_device", "New Device"), ("update", "Update")], + default="new_device", + render_kw={'class': "form-select"}, + ) + + def __init__(self, snapshot_uuid, *args, **kwargs): + self.snapshot = Snapshot.query.filter_by(uuid=snapshot_uuid).one() + self.device = None + if self.snapshot.device: + self.device = self.snapshot.device + + self.snapshot_type.kwargs['default'] = self.snapshot.get_new_device() + super().__init__(*args, **kwargs) + + def validate(self, extra_validators=None): + is_valid = super().validate(extra_validators) + + if not is_valid: + txt = "" + self.snapthot_type.errors = [txt] + return False + + return True + + def unic(self): + try: + return self._unic + except Exception: + self._devices = ( + Device.query.filter_by( + hid=self.device.hid, owner=g.user, placeholder=None, active=True + ) + .order_by(Device.updated.asc()) + .all() + ) + + self._unic = len(self._devices) < 2 + return self._unic + + def dhids_all_devices(self): + self.unic() + return ", ".join([x.dhid for x in self._devices][1:]) + + def dhid_base(self): + self.unic() + if not self._devices: + return '' + return self._devices[0].dhid + + def show(self): + if not self.snapshot or not self.device: + return False + + if not hasattr(self.device, 'system_uuid'): + return False + + if not self.device.system_uuid: + return False + + if self.snapshot.get_new_device() == 'update': + # To do Split + return True + + if not self.unic(): + if self.device == self._devices[0]: + return False + # To do merge + return True + + return False + + def save(self, commit=True): + if not self.show(): + return + + if self.snapshot_type.data == self.snapshot.get_new_device(): + return + + if self.snapshot_type.data == 'update' and not self.unic(): + self.device.reliable() + + if self.snapshot_type.data == 'new_device' and self.unic(): + self.device.unreliable() + txt = "This devices is assigned as unreliable for the user " + txt += "and never is possible to do an update of this device." + self.error_log(txt) + + if commit: + db.session.commit() + + return self.snapshot + + def error_log(self, txt): + snapshot = self.get_first_snapshot() + error = SnapshotsLog( + description=txt, + snapshot=snapshot, + snapshot_uuid=snapshot.uuid, + severity=Severity.Error, + sid=snapshot.sid, + version="{}".format(snapshot.version), + ) + db.session.add(error) + + def get_first_snapshot(self): + device = self.snapshot.device + for ac in device.actions: + if ac.type == 'Snapshot': + return ac diff --git a/ereuse_devicehub/inventory/views.py b/ereuse_devicehub/inventory/views.py index b9c3a659..15988ddb 100644 --- a/ereuse_devicehub/inventory/views.py +++ b/ereuse_devicehub/inventory/views.py @@ -33,6 +33,7 @@ from ereuse_devicehub.inventory.forms import ( TransferForm, UploadPlaceholderForm, UploadSnapshotForm, + UserTrustsForm, ) from ereuse_devicehub.labels.forms import PrintLabelsForm from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog @@ -67,7 +68,6 @@ class DeviceListMixin(GenericMixin): page = int(request.args.get('page', 1)) per_page = int(request.args.get('per_page', PER_PAGE)) filter = request.args.get('filter', "All+Computers") - # import pdb; pdb.set_trace() lots = self.context['lots'] form_filter = FilterForm(lots, lot_id, all_devices=all_devices) @@ -1229,9 +1229,12 @@ class SnapshotListView(GenericMixin): class SnapshotDetailView(GenericMixin): template_name = 'inventory/snapshot_detail.html' + methods = ['GET', 'POST'] + form_class = UserTrustsForm def dispatch_request(self, snapshot_uuid): self.snapshot_uuid = snapshot_uuid + form = self.form_class(snapshot_uuid) self.get_context() self.context['page_title'] = "Snapshot Detail" self.context['snapshots_log'] = self.get_snapshots_log() @@ -1239,6 +1242,10 @@ class SnapshotDetailView(GenericMixin): self.context['snapshot_sid'] = '' if self.context['snapshots_log'].count(): self.context['snapshot_sid'] = self.context['snapshots_log'][0].sid + self.context['form'] = form + + if form.validate_on_submit(): + form.save() return flask.render_template(self.template_name, **self.context) diff --git a/ereuse_devicehub/migrations/versions/564952310b17_add_vendor_family_in_device.py b/ereuse_devicehub/migrations/versions/564952310b17_add_vendor_family_in_device.py new file mode 100644 index 00000000..f37ae2f3 --- /dev/null +++ b/ereuse_devicehub/migrations/versions/564952310b17_add_vendor_family_in_device.py @@ -0,0 +1,35 @@ +"""add vendor family in device + +Revision ID: 564952310b17 +Revises: af038a8a388c +Create Date: 2022-11-14 13:12:22.916848 + +""" +import citext +import sqlalchemy as sa +from alembic import context, op + +# revision identifiers, used by Alembic. +revision = '564952310b17' +down_revision = 'af038a8a388c' +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.add_column( + 'device', + sa.Column('family', citext.CIText(), nullable=True), + schema=f'{get_inv()}', + ) + + +def downgrade(): + op.drop_column('device', 'family', schema=f'{get_inv()}') diff --git a/ereuse_devicehub/migrations/versions/93daff872771_add_hash_hid_to_device.py b/ereuse_devicehub/migrations/versions/93daff872771_add_hash_hid_to_device.py new file mode 100644 index 00000000..9b33ca95 --- /dev/null +++ b/ereuse_devicehub/migrations/versions/93daff872771_add_hash_hid_to_device.py @@ -0,0 +1,65 @@ +"""add hash hid to device + +Revision ID: 93daff872771 +Revises: 564952310b17 +Create Date: 2022-12-13 10:14:45.500087 + +""" +import hashlib + +import citext +import sqlalchemy as sa +from alembic import context, op + +# revision identifiers, used by Alembic. +revision = '93daff872771' +down_revision = '564952310b17' +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_data(): + con = op.get_bind() + sql = f"update {get_inv()}.computer set user_trusts='t';" + con.execute(sql) + + dev_sql = f"select id, hid from {get_inv()}.device;" + for d in con.execute(dev_sql): + if not d.hid: + continue + dev_id = d.id + chid = hashlib.sha3_256(d.hid.encode('utf-8')).hexdigest() + sql = f"update {get_inv()}.device set chid='{chid}' where id={dev_id};" + con.execute(sql) + + con.execute(sql) + + +def upgrade(): + op.add_column( + 'computer', + sa.Column('user_trusts', sa.Boolean(), default=True, nullable=True), + schema=f'{get_inv()}', + ) + + op.add_column( + 'device', + sa.Column('chid', citext.CIText(), nullable=True), + schema=f'{get_inv()}', + ) + + upgrade_data() + + op.alter_column('computer', 'user_trusts', nullable=False, schema=f'{get_inv()}') + + +def downgrade(): + op.drop_column('computer', 'user_trusts', schema=f'{get_inv()}') + op.drop_column('device', 'chid', schema=f'{get_inv()}') diff --git a/ereuse_devicehub/parser/models.py b/ereuse_devicehub/parser/models.py index 8caa0620..79414270 100644 --- a/ereuse_devicehub/parser/models.py +++ b/ereuse_devicehub/parser/models.py @@ -38,7 +38,10 @@ class SnapshotsLog(Thing): db.session.commit() def get_status(self): - return Severity(self.severity) + if self.snapshot: + return Severity(self.severity) + + return '' def get_device(self): if self.snapshot: diff --git a/ereuse_devicehub/parser/parser.py b/ereuse_devicehub/parser/parser.py index 0dfe8a57..9207c59a 100644 --- a/ereuse_devicehub/parser/parser.py +++ b/ereuse_devicehub/parser/parser.py @@ -548,6 +548,12 @@ class ParseSnapshotLsHw: return action + def get_hid_datas(self): + self.device.family = self.get_family() + + def get_family(self): + return self.dmi.get("System", [{}])[0].get("Family", '') + def errors(self, txt=None, severity=Severity.Error): if not txt: return self._errors diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index 52b04308..31b91c7e 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -49,17 +49,14 @@ from sqlalchemy.util import OrderedSet from teal.db import ( CASCADE_OWN, INHERIT_COND, - IP, POLYMORPHIC_ID, POLYMORPHIC_ON, URL, - ResourceNotFound, StrictVersionType, check_lower, check_range, ) -from teal.enums import Country, Currency, Subdivision -from teal.marshmallow import ValidationError +from teal.enums import Currency from teal.resource import url_for_resource from ereuse_devicehub.db import db @@ -741,6 +738,19 @@ class Snapshot(JoinedWithOneDeviceMixin, ActionWithOneDevice): return hdds + def get_new_device(self): + + if not self.device: + return '' + + snapshots = [] + for s in self.device.actions: + if s == self: + break + if s.type == self.type: + snapshots.append(s) + return snapshots and 'update' or 'new_device' + def __str__(self) -> str: return '{}. {} version {}.'.format(self.severity, self.software, self.version) @@ -2049,7 +2059,7 @@ def update_components_action_one(target: ActionWithOneDevice, device: Device, __ if isinstance(device, Computer): target.components |= device.components elif isinstance(device, Computer): - device.add_mac_to_hid() + device.set_hid() @event.listens_for( diff --git a/ereuse_devicehub/resources/action/views/snapshot.py b/ereuse_devicehub/resources/action/views/snapshot.py index 49ea34dd..9780a430 100644 --- a/ereuse_devicehub/resources/action/views/snapshot.py +++ b/ereuse_devicehub/resources/action/views/snapshot.py @@ -64,7 +64,8 @@ def move_json(tmp_snapshots, path_name, user, live=False): class SnapshotMixin: sync = Sync() - def build(self, snapshot_json=None): # noqa: C901 + def build(self, snapshot_json=None, create_new_device=False): # noqa: C901 + self.create_new_device = create_new_device if not snapshot_json: snapshot_json = self.snapshot_json device = snapshot_json.pop('device') # type: Computer @@ -72,9 +73,7 @@ class SnapshotMixin: if snapshot_json['software'] == ( SnapshotSoftware.Workbench or SnapshotSoftware.WorkbenchAndroid ): - components = snapshot_json.pop('components', None) # type: List[Component] - if isinstance(device, Computer) and device.hid: - device.add_mac_to_hid(components_snap=components) + components = snapshot_json.pop('components', None) snapshot = Snapshot(**snapshot_json) # Remove new actions from devices so they don't interfere with sync @@ -89,7 +88,9 @@ class SnapshotMixin: assert not device.actions_one assert all(not c.actions_one for c in components) if components else True - db_device, remove_actions = self.sync.run(device, components) + db_device, remove_actions = self.sync.run( + device, components, self.create_new_device + ) del device # Do not use device anymore snapshot.device = db_device @@ -118,6 +119,9 @@ class SnapshotMixin: self.is_server_erase(snapshot) snapshot.device.register_dlt() + snapshot.device.set_hid() + snapshot.device.binding.device.set_hid() + return snapshot def is_server_erase(self, snapshot): @@ -152,6 +156,30 @@ class SnapshotMixin: uuid = UUID(hw_uuid) return UUID(bytes_le=uuid.bytes) + def get_fields_extra(self, debug, snapshot_json): + if not debug or not isinstance(debug, dict): + return + + lshw = debug.get('lshw', {}) + + family = lshw.get('configuration', {}).get('family', '') + + snapshot_json['device']['family'] = family + + # lshw_mothers = [] + # for mt in lshw.get('children', []): + # if mt.get('description') == "Motherboard": + # lshw_mothers.append(mt) + + # for comp in snapshot_json.get('components', []): + # if comp.get('type') != 'Motherboard': + # continue + # for mt in lshw_mothers: + # if comp['serialNumber'] == mt.get('serial', ''): + # comp['vendor'] = mt.get('vendor', '') + # comp['product'] = mt.get('product', '') + # comp['version'] = mt.get('version', '') + def errors(self, txt=None, severity=Severity.Error, snapshot=None, commit=False): if not txt: return @@ -188,10 +216,13 @@ class SnapshotView(SnapshotMixin): self.version = snapshot_json.get('version') self.uuid = snapshot_json.get('uuid') self.sid = None - system_uuid = self.get_uuid(snapshot_json.pop('debug', None)) + self.debug = snapshot_json.pop('debug', {}) + system_uuid = self.get_uuid(self.debug) if system_uuid: snapshot_json['device']['system_uuid'] = system_uuid + self.get_fields_extra(self.debug, snapshot_json) + try: self.snapshot_json = resource_def.schema.load(snapshot_json) snapshot = self.build() diff --git a/ereuse_devicehub/resources/action/views/views.py b/ereuse_devicehub/resources/action/views/views.py index afbeb665..25814b4a 100644 --- a/ereuse_devicehub/resources/action/views/views.py +++ b/ereuse_devicehub/resources/action/views/views.py @@ -142,11 +142,14 @@ class LiveView(View): return hid if macs: mac = "-{mac}".format(mac=macs[0]) - hid += mac + # hid += mac return hid def live(self, snapshot): """If the device.allocated == True, then this snapshot create an action live.""" + for c in snapshot['components']: + c.parent = snapshot['device'] + snapshot['device'].set_hid() hid = self.get_hid(snapshot) if not hid or not Device.query.filter(Device.hid == hid).count(): raise ValidationError('Device not exist.') diff --git a/ereuse_devicehub/resources/device/metrics.py b/ereuse_devicehub/resources/device/metrics.py index bf118da6..fa43818e 100644 --- a/ereuse_devicehub/resources/device/metrics.py +++ b/ereuse_devicehub/resources/device/metrics.py @@ -21,27 +21,29 @@ class MetricsMix: """ This is a template of a row. """ - return {'type': '', - 'action_type': 'Status', - 'document_name': '', - 'status_receiver': self.status_receiver, - 'status_supplier': self.status_supplier, - 'status_receiver_created': '', - 'status_supplier_created': '', - 'trade_supplier': '', - 'trade_receiver': self.act.author.email, - 'trade_confirmed': '', - 'trade_weight': 0, - 'action_create_by': self.action_create_by, - 'devicehubID': self.devicehub_id, - 'hid': self.hid, - 'finalUserCode': '', - 'numEndUsers': 0, - 'liveCreate': 0, - 'usageTimeHdd': self.lifetime, - 'created': self.act.created, - 'start': '', - 'usageTimeAllocate': 0} + return { + 'type': '', + 'action_type': 'Status', + 'document_name': '', + 'status_receiver': self.status_receiver, + 'status_supplier': self.status_supplier, + 'status_receiver_created': '', + 'status_supplier_created': '', + 'trade_supplier': '', + 'trade_receiver': self.act.author.email, + 'trade_confirmed': '', + 'trade_weight': 0, + 'action_create_by': self.action_create_by, + 'devicehubID': self.devicehub_id, + 'hid': self.hid, + 'finalUserCode': '', + 'numEndUsers': 0, + 'liveCreate': 0, + 'usageTimeHdd': self.lifetime, + 'created': self.act.created, + 'start': '', + 'usageTimeAllocate': 0, + } def get_metrics(self): """ @@ -57,7 +59,7 @@ class Metrics(MetricsMix): self.device = kwargs.pop('device') self.actions = copy.copy(self.device.actions) super().__init__(*args, **kwargs) - self.hid = self.device.hid + self.hid = self.device.chid self.devicehub_id = self.device.devicehub_id def get_action_status(self): diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 6b9dfb51..eba45743 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -1,6 +1,9 @@ import copy import hashlib +import json +import os import pathlib +import uuid from contextlib import suppress from fractions import Fraction from itertools import chain @@ -9,7 +12,7 @@ from typing import Dict, List, Set from boltons import urlutils from citext import CIText -from ereuse_utils.naming import HID_CONVERSION_DOC, Naming +from ereuse_utils.naming import HID_CONVERSION_DOC from ereuseapi.methods import API from flask import current_app as app from flask import g, request, session @@ -117,8 +120,6 @@ class Device(Thing): """ + HID_CONVERSION_DOC ) - chid_dpp = Column(Unicode(), check_lower('chid'), unique=False) - chid_dpp.comment = "Chid for identify one device front the DLT" model = Column(Unicode(), check_lower('model')) model.comment = """The model of the device in lower case. @@ -186,6 +187,8 @@ class Device(Thing): dhid_bk = db.Column(db.CIText(), nullable=True, unique=False) phid_bk = db.Column(db.CIText(), nullable=True, unique=False) active = db.Column(Boolean, default=True) + family = db.Column(db.CIText()) + chid = db.Column(db.CIText()) _NON_PHYSICAL_PROPS = { 'id', @@ -206,6 +209,7 @@ class Device(Thing): 'production_date', 'variant', 'version', + 'family', 'sku', 'image', 'allocated', @@ -214,7 +218,11 @@ class Device(Thing): 'active', 'phid_bk', 'dhid_bk', - 'chid_dpp', + 'chid', + 'user_trusts', + 'chassis', + 'transfer_state', + 'receiver_id', } __table_args__ = ( @@ -260,16 +268,17 @@ class Device(Thing): """ actions_multiple = copy.copy(self.actions_multiple) actions_one = copy.copy(self.actions_one) + actions = [] for ac in actions_multiple: ac.real_created = ac.actions_device[0].created + actions.append(ac) for ac in actions_one: ac.real_created = ac.created + actions.append(ac) - return sorted( - chain(actions_multiple, actions_one), key=lambda x: x.real_created - ) + return sorted(actions, key=lambda x: x.real_created) @property def problems(self): @@ -748,12 +757,56 @@ class Device(Thing): return "" + def get_from_db(self): + if 'property_hid' in app.blueprints.keys(): + try: + from modules.device.utils import get_from_db + + return get_from_db(self) + except Exception: + pass + + if not self.hid: + return + + return Device.query.filter_by( + hid=self.hid, + owner_id=g.user.id, + active=True, + placeholder=None, + ).first() + def set_hid(self): with suppress(TypeError): self.hid = Naming.hid( self.type, self.manufacturer, self.model, self.serial_number ) - self.chid_dpp = hashlib.sha3_256(self.hid.encode('utf-8')).hexdigest() + if 'property_hid' in app.blueprints.keys(): + try: + from modules.device.utils import set_hid + + self.hid = set_hid(self) + self.set_chid() + return + except Exception: + pass + + self.hid = "{}-{}-{}-{}".format( + self._clean_string(self.type), + self._clean_string(self.manufacturer), + self._clean_string(self.model), + self._clean_string(self.serial_number), + ).lower() + self.set_chid() + + def _clean_string(self, s): + if not s: + return '' + return s.replace(' ', '_') + + def set_chid(self): + if self.hid: + self.chid = hashlib.sha3_256(self.hid.encode()).hexdigest() def last_action_of(self, *types): """Gets the last action of the given types. @@ -840,7 +893,6 @@ class Device(Thing): if not session.get('token_dlt'): return - chid = hashlib.sha3_256(self.hid.encode('utf-8')).hexdigest() token_dlt = session.get('token_dlt').split(".")[1] api_dlt = app.config.get('API_DLT') if not token_dlt or not api_dlt: @@ -848,9 +900,125 @@ class Device(Thing): api = API(api_dlt, token_dlt, "ethereum") - api.register_device(chid) + api.register_device(self.chid) # result = api.register_device(chid) + def unreliable(self): + self.user_trusts = False + i = 0 + snapshot1 = None + snapshots = {} + + for ac in self.actions: + if ac.type == 'Snapshot': + if i == 0: + snapshot1 = ac + if i > 0: + snapshots[ac] = self.get_snapshot_file(ac) + i += 1 + + if not snapshot1: + return + + self.create_new_device(snapshots.values()) + self.remove_snapshot(snapshots.keys()) + + return + + def get_snapshot_file(self, action): + uuid = action.uuid + user = g.user.email + name_file = f"*_{user}_{uuid}.json" + tmp_snapshots = app.config['TMP_SNAPSHOTS'] + path_dir_base = os.path.join(tmp_snapshots, user) + + for _file in pathlib.Path(path_dir_base).glob(name_file): + with open(_file) as file_snapshot: + snapshot = file_snapshot.read() + return json.loads(snapshot) + + def create_new_device(self, snapshots): + from ereuse_devicehub.inventory.forms import UploadSnapshotForm + + new_snapshots = [] + for snapshot in snapshots: + snapshot['uuid'] = str(uuid.uuid4()) + filename = "{}.json".format(snapshot['uuid']) + new_snapshots.append((filename, snapshot)) + + form = UploadSnapshotForm() + form.result = {} + form.snapshots = new_snapshots + form.create_new_devices = True + form.save(commit=False) + + def remove_snapshot(self, snapshots): + from ereuse_devicehub.parser.models import SnapshotsLog + + for ac in snapshots: + for slog in SnapshotsLog.query.filter_by(snapshot=ac): + slog.snapshot_id = None + slog.snapshot_uuid = None + db.session.delete(ac) + + def remove_devices(self, devices): + from ereuse_devicehub.parser.models import SnapshotsLog + + for dev in devices: + for ac in dev.actions: + if ac.type != 'Snapshot': + continue + for slog in SnapshotsLog.query.filter_by(snapshot=ac): + slog.snapshot_id = None + slog.snapshot_uuid = None + + for c in dev.components: + c.parent_id = None + + for tag in dev.tags: + tag.device_id = None + + placeholder = dev.binding or dev.placeholder + if placeholder: + db.session.delete(placeholder.binding) + db.session.delete(placeholder.device) + db.session.delete(placeholder) + + def reliable(self): + computers = Computer.query.filter_by( + hid=self.hid, + owner_id=g.user.id, + active=True, + placeholder=None, + ).order_by(Device.created.asc()) + + i = 0 + computer1 = None + computers_to_remove = [] + for d in computers: + if i == 0: + d.user_trusts = True + computer1 = d + i += 1 + continue + + computers_to_remove.append(d) + + self.remove_devices(computers_to_remove) + if not computer1: + return + + snapshot1 = None + for ac in computer1.actions_one: + if ac.type == 'Snapshot': + snapshot1 = ac + break + + if not snapshot1: + return + + return + def __lt__(self, other): return self.id < other.id @@ -1051,6 +1219,7 @@ class Computer(Device): receiver_id = db.Column(UUID(as_uuid=True), db.ForeignKey(User.id), nullable=True) receiver = db.relationship(User, primaryjoin=receiver_id == User.id) system_uuid = db.Column(UUID(as_uuid=True), nullable=True) + user_trusts = db.Column(Boolean(), default=True) def __init__(self, *args, **kwargs) -> None: if args: diff --git a/ereuse_devicehub/resources/device/schemas.py b/ereuse_devicehub/resources/device/schemas.py index 8f92ffa7..76a1fee2 100644 --- a/ereuse_devicehub/resources/device/schemas.py +++ b/ereuse_devicehub/resources/device/schemas.py @@ -120,6 +120,7 @@ class Device(Thing): dhid = SanitizedStr( data_key='devicehubID', description=m.Device.devicehub_id.comment ) + family = SanitizedStr(validate=Length(max=STR_BIG_SIZE)) @pre_load def from_actions_to_actions_one(self, data: dict): diff --git a/ereuse_devicehub/resources/device/sync.py b/ereuse_devicehub/resources/device/sync.py index 613f0b39..8dfba8b2 100644 --- a/ereuse_devicehub/resources/device/sync.py +++ b/ereuse_devicehub/resources/device/sync.py @@ -1,6 +1,5 @@ import copy import difflib -from contextlib import suppress from itertools import groupby from typing import Iterable, Set @@ -17,7 +16,6 @@ from ereuse_devicehub.resources.action.models import Remove from ereuse_devicehub.resources.device.models import ( Component, Computer, - DataStorage, Device, Placeholder, ) @@ -32,19 +30,15 @@ DEVICES_ALLOW_DUPLICITY = [ 'GraphicCard', ] -err_motherboard = "Error: We have detected that a there is a device" -err_motherboard += " in your inventory with this system UUID. " -err_motherboard += "We proceed to block this snapshot to prevent its" -err_motherboard += " information from being updated incorrectly." -err_motherboard += " The solution we offer you to inventory this device " -err_motherboard += "is to do it by creating a placeholder." - class Sync: """Synchronizes the device and components with the database.""" def run( - self, device: Device, components: Iterable[Component] or None + self, + device: Device, + components: Iterable[Component] or None, + create_new_device=False, ) -> (Device, OrderedSet): """Synchronizes the device and components with the database. @@ -76,17 +70,11 @@ class Sync: of the passed-in components. 2. A list of Add / Remove (not yet added to session). """ - db_device = self.execute_register(device) - motherboard = None if components: - for c in components: - if c.type == "Motherboard": - motherboard = c - - if motherboard: - for c in db_device.components: - if c.type == "Motherboard" and motherboard.hid != c.hid: - raise ValidationError(err_motherboard) + device.components = OrderedSet(components) + device.set_hid() + device.components = OrderedSet() + db_device = self.execute_register(device, create_new_device) db_components, actions = OrderedSet(), OrderedSet() if components is not None: # We have component info (see above) @@ -94,12 +82,9 @@ class Sync: # Until a good reason is given, we synthetically forbid # non-computers with components raise ValidationError('Only computers can have components.') - blacklist = set() # type: Set[int] not_new_components = set() for component in components: - db_component, is_new = self.execute_register_component( - component, blacklist, parent=db_device - ) + db_component, is_new = self.execute_register_component(component) db_components.add(db_component) if not is_new: not_new_components.add(db_component) @@ -110,9 +95,7 @@ class Sync: self.create_placeholder(db_device) return db_device, actions - def execute_register_component( - self, component: Component, blacklist: Set[int], parent: Computer - ): + def execute_register_component(self, component: Component): """Synchronizes one component to the DB. This method is a specialization of :meth:`.execute_register` @@ -134,7 +117,6 @@ class Sync: - A flag stating if the device is new or it already existed in the DB. """ - # if device.serial_number == 'b8oaas048286': assert inspect(component).transient, 'Component should not be synced from DB' # if not is a DataStorage, then need build a new one if component.t in DEVICES_ALLOW_DUPLICITY: @@ -142,33 +124,20 @@ class Sync: is_new = True return component, is_new - # if not, then continue with the traditional behaviour - try: - if component.hid: - db_component = Device.query.filter_by( - hid=component.hid, owner_id=g.user.id, placeholder=None - ).one() - assert isinstance( - db_component, Device - ), '{} must be a component'.format(db_component) - else: - # Is there a component similar to ours? - db_component = component.similar_one(parent, blacklist) - # We blacklist this component so we - # ensure we don't get it again for another component - # with the same physical properties - blacklist.add(db_component.id) - except ResourceNotFound: + db_component = None + + if component.hid: + db_component = Device.query.filter_by( + hid=component.hid, owner_id=g.user.id, placeholder=None, active=True + ).first() + is_new = False + if not db_component: db.session.add(component) - # db.session.flush() db_component = component is_new = True - else: - self.merge(component, db_component) - is_new = False return db_component, is_new - def execute_register(self, device: Device) -> Device: + def execute_register(self, device: Device, create_new_device=False) -> Device: """Synchronizes one device to the DB. This method tries to get an existing device using the HID @@ -195,84 +164,22 @@ class Sync: :raise DatabaseError: Any other error from the DB. :return: The synced device from the db with the tags linked. """ - assert inspect(device).transient, 'Device cannot be already synced from DB' - assert all( - inspect(tag).transient for tag in device.tags - ), 'Tags cannot be synced from DB' - db_device = None - if isinstance(device, Computer): - # first search by uuid - if device.system_uuid: - with suppress(ResourceNotFound): - db_device = Computer.query.filter_by( - system_uuid=device.system_uuid, - owner_id=g.user.id, - active=True, - placeholder=None, - ).one() - # if no there are any Computer by uuid search by hid - if not db_device and device.hid: - with suppress(ResourceNotFound): - db_device = Device.query.filter_by( - hid=device.hid, - owner_id=g.user.id, - active=True, - placeholder=None, - ).one() - elif device.hid: - with suppress(ResourceNotFound): - db_device = Device.query.filter_by( - hid=device.hid, owner_id=g.user.id, active=True, placeholder=None - ).one() + db_device = device.get_from_db() if db_device and db_device.allocated: raise ResourceNotFound('device is actually allocated {}'.format(device)) - try: - tags = { - Tag.from_an_id(tag.id).one() for tag in device.tags - } # type: Set[Tag] - except ResourceNotFound: - raise ResourceNotFound('tag you are linking to device {}'.format(device)) - linked_tags = {tag for tag in tags if tag.device_id} # type: Set[Tag] - if linked_tags: - sample_tag = next(iter(linked_tags)) - for tag in linked_tags: - if tag.device_id != sample_tag.device_id: - raise MismatchBetweenTags( - tag, sample_tag - ) # Tags linked to different devices - if db_device: # Device from hid - if ( - sample_tag.device_id != db_device.id - ): # Device from hid != device from tags - raise MismatchBetweenTagsAndHid(db_device.id, db_device.hid) - else: # There was no device from hid - if sample_tag.device.physical_properties != device.physical_properties: - # Incoming physical props of device != props from tag's device - # which means that the devices are not the same - raise MismatchBetweenProperties( - sample_tag.device.physical_properties, - device.physical_properties, - ) - db_device = sample_tag.device - - if db_device: # Device from hid or tags - self.merge(device, db_device) - else: # Device is new and tags are not linked to a device + if not db_device or create_new_device: device.tags.clear() # We don't want to add the transient dummy tags db.session.add(device) db_device = device - db_device.tags |= ( - tags # Union of tags the device had plus the (potentially) new ones - ) try: db.session.flush() except IntegrityError as e: # Manage 'one tag per organization' unique constraint if 'One tag per organization' in e.args[0]: # todo test for this - id = int(e.args[0][135 : e.args[0].index(',', 135)]) + id = int(e.args[0][135 : e.args[0].index(',', 135)]) # noqa: E203 raise ValidationError( 'The device is already linked to tag {} ' 'from the same organization.'.format(id), @@ -283,29 +190,6 @@ class Sync: assert db_device is not None return db_device - @staticmethod - def merge(device: Device, db_device: Device): - """Copies the physical properties of the device to the db_device. - - This method mutates db_device. - """ - if db_device.owner_id != g.user.id: - return - - if device.placeholder and not db_device.placeholder: - return - - for field_name, value in device.physical_properties.items(): - if value is not None: - setattr(db_device, field_name, value) - - # if device.system_uuid and db_device.system_uuid and device.system_uuid != db_device.system_uuid: - # TODO @cayop send error to sentry.io - # there are 2 computers duplicate get db_device for hid - - if hasattr(device, 'system_uuid') and device.system_uuid: - db_device.system_uuid = device.system_uuid - @staticmethod def create_placeholder(device: Device): """If the device is new, we need create automaticaly a new placeholder""" diff --git a/ereuse_devicehub/resources/device/views.py b/ereuse_devicehub/resources/device/views.py index 6896089c..3aa9d9ff 100644 --- a/ereuse_devicehub/resources/device/views.py +++ b/ereuse_devicehub/resources/device/views.py @@ -302,7 +302,7 @@ class DeviceMergeView(View): setattr(self.base_device, field_name, value) self.base_device.hid = self.with_device.hid - self.base_device.add_mac_to_hid() + self.base_device.set_hid() class ManufacturerView(View): diff --git a/ereuse_devicehub/resources/documents/device_row.py b/ereuse_devicehub/resources/documents/device_row.py index 2e13d327..d4efda46 100644 --- a/ereuse_devicehub/resources/documents/device_row.py +++ b/ereuse_devicehub/resources/documents/device_row.py @@ -285,7 +285,7 @@ class DeviceRow(BaseDeviceRow): self['Tag {} ID'.format(i)] = tag.id self['Tag {} Organization'.format(i)] = tag.org.name - self['Device Hardware ID'] = device.hid + self['Device Hardware ID'] = device.chid self['Device Type'] = device.t if isinstance(device, d.Computer) and not device.placeholder: self['Device Chassis'] = device.chassis.name @@ -433,12 +433,12 @@ class DeviceRow(BaseDeviceRow): ] erasure = erasures[-1] if erasures else None if not erasure: - self['Erasure {} {}'.format(ctype, i)] = none2str(component.hid) + self['Erasure {} {}'.format(ctype, i)] = none2str(component.chid) serial_number = none2str(component.serial_number) self['Erasure {} {} Serial Number'.format(ctype, i)] = serial_number self['Erasure {} {} Size (MB)'.format(ctype, i)] = none2str(component.size) elif hasattr(erasure, 'type') and erasure.type == 'DataWipe': - self['Erasure {} {}'.format(ctype, i)] = none2str(component.hid) + self['Erasure {} {}'.format(ctype, i)] = none2str(component.chid) serial_number = none2str(component.serial_number) self['Erasure {} {} Serial Number'.format(ctype, i)] = serial_number self['Erasure {} {} Size (MB)'.format(ctype, i)] = none2str(component.size) @@ -448,7 +448,7 @@ class DeviceRow(BaseDeviceRow): erasure.document.url and erasure.document.url.to_text() or '' ) else: - self['Erasure {} {}'.format(ctype, i)] = none2str(component.hid) + self['Erasure {} {}'.format(ctype, i)] = none2str(component.chid) serial_number = none2str(component.serial_number) self['Erasure {} {} Serial Number'.format(ctype, i)] = serial_number self['Erasure {} {} Size (MB)'.format(ctype, i)] = none2str(component.size) diff --git a/ereuse_devicehub/resources/lot/models.py b/ereuse_devicehub/resources/lot/models.py index 68eec828..3cb62adb 100644 --- a/ereuse_devicehub/resources/lot/models.py +++ b/ereuse_devicehub/resources/lot/models.py @@ -94,6 +94,10 @@ class Lot(Thing): ) receiver = db.relationship(User, primaryjoin=receiver_address == User.email) + # __table_args__ = ( + # {'schema': 'dbtest'}, + # ) + def __init__( self, name: str, closed: bool = closed.default.arg, description: str = None ) -> None: diff --git a/ereuse_devicehub/templates/inventory/snapshot_detail.html b/ereuse_devicehub/templates/inventory/snapshot_detail.html index 4ea87572..efba84d4 100644 --- a/ereuse_devicehub/templates/inventory/snapshot_detail.html +++ b/ereuse_devicehub/templates/inventory/snapshot_detail.html @@ -20,9 +20,46 @@

{{ snapshot_sid }} | {{ snapshot_uuid }}

+ {% if form.show() %} + + {% endif %}
-
+ {% if form.show() %} +
+
Change Snapshot Type Upload
+
+
+
+ {{ form.csrf_token }} + {% for f in form %} + {% if f != form.csrf_token %} +

+ {{ f }} +

+ {% endif %} + {% endfor %} +

+ + Save + +

+
+
+
+
+ {% endif %} +
Traceability log Details
{% for log in snapshots_log %} @@ -51,4 +88,62 @@
+ + + {% endblock main %} + diff --git a/ereuse_devicehub/workbench/__init__.py b/ereuse_devicehub/workbench/__init__.py index 8f9bf153..70ac8a85 100644 --- a/ereuse_devicehub/workbench/__init__.py +++ b/ereuse_devicehub/workbench/__init__.py @@ -4,7 +4,7 @@ isos = { 'url': 'https://releases.usody.com/demo/', }, "register": { - 'iso': "USODY_2022.12.1-beta.iso", + 'iso': "USODY_2022.12.2-beta.iso", 'url': 'https://releases.usody.com/2022/', }, "erease": { diff --git a/tests/files/basic.csv b/tests/files/basic.csv index 13efc342..3ceda076 100644 --- a/tests/files/basic.csv +++ b/tests/files/basic.csv @@ -1,2 +1,2 @@ "PHID";"DHID";"Type";"Placeholder Palet";"Placeholder Id Supplier";"Placeholder Info";"Placeholder Components";"Placeholder Type";"Placeholder Serial Number";"Placeholder Part Number";"Placeholder Model";"Placeholder Manufacturer";"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";"Allocate state";"Lifecycle 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 Certificate URL";"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 cycle count";"Test DataStorage 1 Lifetime (days)";"Test DataStorage 1 Power on hours";"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 Certificate URL";"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 cycle count";"Test DataStorage 2 Lifetime (days)";"Test DataStorage 2 Power on hours";"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 Certificate URL";"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 cycle count";"Test DataStorage 3 Lifetime (days)";"Test DataStorage 3 Power on hours";"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 Certificate URL";"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 cycle count";"Test DataStorage 4 Lifetime (days)";"Test DataStorage 4 Power on hours";"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";"Benchmark RamSysbench (points)" -"4";"E39W3";"Snapshot";"";"";"";"";"Desktop";"d1s";"";"d1ml";"d1mr";"";"http://localhost/devices/E39W3";"";"";"";"";"";"";"";"";"";"desktop-d1mr-d1ml-d1s";"Desktop";"Microtower";"d1s";"d1ml";"d1mr";"Wed Sep 21 15:39:24 2022";"Workbench 11.0";"2022-09-21 15:39:24.321860+02:00";"";"";"";"";"p1ml";"0";"0";"Processor 7: model p1ml, S/N p1s";"p1mr";"p1ml";"p1s";"";"1.6";"2410.0";"";"";"";"";"";"";"";"";"";"RamModule 6: model rm1ml, S/N rm1s";"rm1mr";"rm1ml";"rm1s";"";"1333";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"GraphicCard 5: model gc1ml, S/N gc1s";"gc1mr";"gc1ml";"gc1s";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"" +"4";"E39W3";"Snapshot";"";"";"";"";"Desktop";"d1s";"";"d1ml";"d1mr";"";"http://localhost/devices/E39W3";"";"";"";"";"";"";"";"";"";"0de0de8ed27a9a67e937a12a65799f6c5c69731c9bcd282054cd21a2faf980db";"Desktop";"Microtower";"d1s";"d1ml";"d1mr";"Wed Sep 21 15:39:24 2022";"Workbench 11.0";"2022-09-21 15:39:24.321860+02:00";"";"";"";"";"p1ml";"0";"0";"Processor 7: model p1ml, S/N p1s";"p1mr";"p1ml";"p1s";"";"1.6";"2410.0";"";"";"";"";"";"";"";"";"";"RamModule 6: model rm1ml, S/N rm1s";"rm1mr";"rm1ml";"rm1s";"";"1333";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"GraphicCard 5: model gc1ml, S/N gc1s";"gc1mr";"gc1ml";"gc1s";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"" diff --git a/tests/files/export_devices.csv b/tests/files/export_devices.csv index 2e04a391..5754ab48 100644 --- a/tests/files/export_devices.csv +++ b/tests/files/export_devices.csv @@ -1,2 +1,2 @@ "PHID";"DHID";"Type";"Placeholder Palet";"Placeholder Id Supplier";"Placeholder Info";"Placeholder Components";"Placeholder Type";"Placeholder Serial Number";"Placeholder Part Number";"Placeholder Model";"Placeholder Manufacturer";"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";"Allocate state";"Lifecycle 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 Certificate URL";"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 cycle count";"Test DataStorage 1 Lifetime (days)";"Test DataStorage 1 Power on hours";"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 Certificate URL";"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 cycle count";"Test DataStorage 2 Lifetime (days)";"Test DataStorage 2 Power on hours";"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 Certificate URL";"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 cycle count";"Test DataStorage 3 Lifetime (days)";"Test DataStorage 3 Power on hours";"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 Certificate URL";"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 cycle count";"Test DataStorage 4 Lifetime (days)";"Test DataStorage 4 Power on hours";"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";"Benchmark RamSysbench (points)" -"10";"E39W3";"Snapshot";"";"";"";"";"Laptop";"b8oaas048285";"";"1001pxd";"asustek computer inc.";"";"http://localhost/devices/E39W3";"";"";"";"";"";"";"";"";"";"laptop-asustek_computer_inc-1001pxd-b8oaas048285-14:da:e9:42:f6:7b";"Laptop";"Netbook";"b8oaas048285";"1001pxd";"asustek computer inc.";"Wed Sep 21 13:10:21 2022";"Workbench 11.0a2";"2022-09-21 13:10:21.174981+02:00";"";"";"";"";"intel atom cpu n455 @ 2.66ghz";"1024";"238475";"Processor 7: 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 11: model None, S/N None";"";"";"";"1024";"667";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"HardDrive 12: model hts54322, S/N e2024242cv86mm";"hitachi";"hts54322";"e2024242cv86mm";"238475";"harddrive-hitachi-hts54322-e2024242cv86mm";"e2024242cv86mm";"238475";"Workbench 11.0a2";"Success";"";"EraseBasic";"Shred";"1:16:49";"2022-09-21 13:10:21.126373+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";"";"";"0";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"Motherboard 13: model 1001pxd, S/N eee0123456720";"asustek computer inc.";"1001pxd";"eee0123456720";"";"";"";"";"GraphicCard 8: 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 5: 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 6: 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 9: model nm10/ich7 family high definition audio controller, S/N None";"intel corporation";"nm10/ich7 family high definition audio controller";"";"SoundCard 10: model usb 2.0 uvc vga webcam, S/N 0x0001";"azurewave";"usb 2.0 uvc vga webcam";"0x0001";"";"";"";"";"";"";"";"";"15.7188" +"10";"E39W3";"Snapshot";"";"";"";"";"Laptop";"b8oaas048285";"";"1001pxd";"asustek computer inc.";"";"http://localhost/devices/E39W3";"";"";"";"";"";"";"";"";"";"83cb9066430a8ea7def04af61d521d6517193a486c02ea3bc914c9eaeb2b718b";"Laptop";"Netbook";"b8oaas048285";"1001pxd";"asustek computer inc.";"Wed Dec 14 12:28:44 2022";"Workbench 11.0a2";"2022-12-14 12:28:44.757147+01:00";"";"";"";"";"intel atom cpu n455 @ 2.66ghz";"1024";"238475";"Processor 7: 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 11: model None, S/N None";"";"";"";"1024";"667";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"HardDrive 12: model hts54322, S/N e2024242cv86mm";"hitachi";"hts54322";"e2024242cv86mm";"238475";"8558ea99955f34c788cb72174c0ec165e0398306efbc0efe40b280b65d16d0d0";"e2024242cv86mm";"238475";"Workbench 11.0a2";"Success";"";"EraseBasic";"Shred";"1:16:49";"2022-12-14 12:28:44.712329+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";"";"";"0";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"Motherboard 13: model 1001pxd, S/N eee0123456720";"asustek computer inc.";"1001pxd";"eee0123456720";"";"";"";"";"GraphicCard 8: 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 5: 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 6: 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 9: model nm10/ich7 family high definition audio controller, S/N None";"intel corporation";"nm10/ich7 family high definition audio controller";"";"SoundCard 10: model usb 2.0 uvc vga webcam, S/N 0x0001";"azurewave";"usb 2.0 uvc vga webcam";"0x0001";"";"";"";"";"";"";"";"";"15.7188" diff --git a/tests/files/proposal_extended_csv_report.csv b/tests/files/proposal_extended_csv_report.csv index 64ed1795..73608689 100644 --- a/tests/files/proposal_extended_csv_report.csv +++ b/tests/files/proposal_extended_csv_report.csv @@ -1,3 +1,3 @@ "PHID";"DHID";"Type";"Placeholder Palet";"Placeholder Id Supplier";"Placeholder Info";"Placeholder Components";"Placeholder Type";"Placeholder Serial Number";"Placeholder Part Number";"Placeholder Model";"Placeholder Manufacturer";"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";"Allocate state";"Lifecycle 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 Certificate URL";"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 cycle count";"Test DataStorage 1 Lifetime (days)";"Test DataStorage 1 Power on hours";"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 Certificate URL";"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 cycle count";"Test DataStorage 2 Lifetime (days)";"Test DataStorage 2 Power on hours";"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 Certificate URL";"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 cycle count";"Test DataStorage 3 Lifetime (days)";"Test DataStorage 3 Power on hours";"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 Certificate URL";"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 cycle count";"Test DataStorage 4 Lifetime (days)";"Test DataStorage 4 Power on hours";"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";"Benchmark RamSysbench (points)" -"10";"E39W3";"Snapshot";"";"";"";"";"Laptop";"b8oaas048285";"";"1001pxd";"asustek computer inc.";"";"http://localhost/devices/E39W3";"";"";"";"";"";"";"";"";"";"laptop-asustek_computer_inc-1001pxd-b8oaas048285-14:da:e9:42:f6:7b";"Laptop";"Netbook";"b8oaas048285";"1001pxd";"asustek computer inc.";"Wed Sep 21 15:41:31 2022";"Workbench 11.0a2";"2022-09-21 15:41:31.084078+02:00";"";"";"";"";"intel atom cpu n455 @ 2.66ghz";"1024";"238475";"Processor 7: 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 11: model None, S/N None";"";"";"";"1024";"667";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"HardDrive 12: model hts54322, S/N e2024242cv86mm";"hitachi";"hts54322";"e2024242cv86mm";"238475";"harddrive-hitachi-hts54322-e2024242cv86mm";"e2024242cv86mm";"238475";"Workbench 11.0a2";"Success";"";"EraseBasic";"Shred";"1:16:49";"2022-09-21 15:41:31.030798+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";"";"";"0";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"Motherboard 13: model 1001pxd, S/N eee0123456720";"asustek computer inc.";"1001pxd";"eee0123456720";"";"";"";"";"GraphicCard 8: 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 5: 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 6: 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 9: model nm10/ich7 family high definition audio controller, S/N None";"intel corporation";"nm10/ich7 family high definition audio controller";"";"SoundCard 10: model usb 2.0 uvc vga webcam, S/N 0x0001";"azurewave";"usb 2.0 uvc vga webcam";"0x0001";"";"";"";"";"";"";"";"";"15.7188" -"24";"45VG4";"Snapshot";"";"";"";"";"Laptop";"b8oaas048287";"";"1001pxd";"asustek computer inc.";"";"http://localhost/devices/45VG4";"";"";"";"";"";"";"";"";"";"laptop-asustek_computer_inc-1001pxd-b8oaas048287-14:da:e9:42:f6:7c";"Laptop";"Netbook";"b8oaas048287";"1001pxd";"asustek computer inc.";"Wed Sep 21 15:41:31 2022";"Workbench 11.0b11";"2022-09-21 15:41:31.398843+02:00";"";"";"";"";"intel atom cpu n455 @ 1.66ghz";"2048";"558558";"Processor 28: 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 32: model None, S/N None";"";"";"";"1024";"667";"RamModule 33: model 48594d503131325336344350362d53362020, S/N 4f43487b";"hynix semiconductor";"48594d503131325336344350362d53362020";"4f43487b";"1024";"667";"";"";"";"";"";"";"";"";"";"";"";"";"HardDrive 34: model hts54322, S/N e2024242cv86hj";"hitachi";"hts54322";"e2024242cv86hj";"238475";"harddrive-hitachi-hts54322-e2024242cv86hj";"e2024242cv86hj";"238475";"Workbench 11.0b11";"Success";"";"EraseBasic";"Shred";"1:16:49";"2022-09-21 15:41:31.340555+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";"";"";"0";"DataStorage 35: 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";"2022-09-21 15:41:31.342722+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";"4692";"SolidStateDrive 36: 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";"2022-09-21 15:41:31.346565+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";"4673";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"Motherboard 37: model 1001pxd, S/N eee0123456789";"asustek computer inc.";"1001pxd";"eee0123456789";"";"auo ""auo""";"auo lcd monitor";"";"GraphicCard 29: 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 26: 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 27: 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 30: model nm10/ich7 family high definition audio controller, S/N None";"intel corporation";"nm10/ich7 family high definition audio controller";"";"SoundCard 31: model usb 2.0 uvc vga webcam, S/N 0x0001";"azurewave";"usb 2.0 uvc vga webcam";"0x0001";"";"";"";"";"";"";"";"";"15.7188" +"10";"E39W3";"Snapshot";"";"";"";"";"Laptop";"b8oaas048285";"";"1001pxd";"asustek computer inc.";"";"http://localhost/devices/E39W3";"";"";"";"";"";"";"";"";"";"83cb9066430a8ea7def04af61d521d6517193a486c02ea3bc914c9eaeb2b718b";"Laptop";"Netbook";"b8oaas048285";"1001pxd";"asustek computer inc.";"Wed Sep 21 15:41:31 2022";"Workbench 11.0a2";"2022-09-21 15:41:31.084078+02:00";"";"";"";"";"intel atom cpu n455 @ 2.66ghz";"1024";"238475";"Processor 7: 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 11: model None, S/N None";"";"";"";"1024";"667";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"HardDrive 12: model hts54322, S/N e2024242cv86mm";"hitachi";"hts54322";"e2024242cv86mm";"238475";"8558ea99955f34c788cb72174c0ec165e0398306efbc0efe40b280b65d16d0d0";"e2024242cv86mm";"238475";"Workbench 11.0a2";"Success";"";"EraseBasic";"Shred";"1:16:49";"2022-09-21 15:41:31.030798+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";"";"";"0";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"Motherboard 13: model 1001pxd, S/N eee0123456720";"asustek computer inc.";"1001pxd";"eee0123456720";"";"";"";"";"GraphicCard 8: 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 5: 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 6: 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 9: model nm10/ich7 family high definition audio controller, S/N None";"intel corporation";"nm10/ich7 family high definition audio controller";"";"SoundCard 10: model usb 2.0 uvc vga webcam, S/N 0x0001";"azurewave";"usb 2.0 uvc vga webcam";"0x0001";"";"";"";"";"";"";"";"";"15.7188" +"24";"45VG4";"Snapshot";"";"";"";"";"Laptop";"b8oaas048287";"";"1001pxd";"asustek computer inc.";"";"http://localhost/devices/45VG4";"";"";"";"";"";"";"";"";"";"c3c6726385eb7e43a7476512236fe27fa234028c394237344d6b403611c25564";"Laptop";"Netbook";"b8oaas048287";"1001pxd";"asustek computer inc.";"Wed Sep 21 15:41:31 2022";"Workbench 11.0b11";"2022-09-21 15:41:31.398843+02:00";"";"";"";"";"intel atom cpu n455 @ 1.66ghz";"2048";"558558";"Processor 28: 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 32: model None, S/N None";"";"";"";"1024";"667";"RamModule 33: model 48594d503131325336344350362d53362020, S/N 4f43487b";"hynix semiconductor";"48594d503131325336344350362d53362020";"4f43487b";"1024";"667";"";"";"";"";"";"";"";"";"";"";"";"";"HardDrive 34: model hts54322, S/N e2024242cv86hj";"hitachi";"hts54322";"e2024242cv86hj";"238475";"092462ec48ccf594fa369eb55c7026de4b56620f3430fb09a840ed3769b99851";"e2024242cv86hj";"238475";"Workbench 11.0b11";"Success";"";"EraseBasic";"Shred";"1:16:49";"2022-09-21 15:41:31.340555+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";"";"";"0";"DataStorage 35: 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";"2022-09-21 15:41:31.342722+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";"4692";"SolidStateDrive 36: model wdc wd1600bevt-2, S/N wd-wx11a80w7430";"western digital";"wdc wd1600bevt-2";"wd-wx11a80w7430";"160042";"c5856fc1632d695a7eccf5062667d15439ec3c765245ba3fa60272c335d6e83f";"wd-wx11a80w7430";"160042";"Workbench 11.0b11";"Success";"";"EraseSectors";"Badblocks";"1:46:03";"2022-09-21 15:41:31.346565+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";"4673";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"";"Motherboard 37: model 1001pxd, S/N eee0123456789";"asustek computer inc.";"1001pxd";"eee0123456789";"";"auo ""auo""";"auo lcd monitor";"";"GraphicCard 29: 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 26: 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 27: 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 30: model nm10/ich7 family high definition audio controller, S/N None";"intel corporation";"nm10/ich7 family high definition audio controller";"";"SoundCard 31: model usb 2.0 uvc vga webcam, S/N 0x0001";"azurewave";"usb 2.0 uvc vga webcam";"0x0001";"";"";"";"";"";"";"";"";"15.7188" diff --git a/tests/files/real-eee-1001pxd.snapshot.12.yaml b/tests/files/real-eee-1001pxd.snapshot.12.yaml index 6dc974bd..425a270c 100644 --- a/tests/files/real-eee-1001pxd.snapshot.12.yaml +++ b/tests/files/real-eee-1001pxd.snapshot.12.yaml @@ -158,5 +158,6 @@ } ] }, + "debug": {"lshw": {"configuration": {"uuid": "79c5098f-bc44-4834-8a59-9ea61d956c31"}}}, "closed": false } diff --git a/tests/test_action.py b/tests/test_action.py index 40e9cd15..9ccb07a3 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -2941,7 +2941,7 @@ def test_delete_devices_check_sync(user: UserClient): in [y.device.id for y in x.actions if hasattr(y, 'device')] ] ) - == 1 + == 2 ) diff --git a/tests/test_device.py b/tests/test_device.py index ac8c1d07..c4e961bc 100644 --- a/tests/test_device.py +++ b/tests/test_device.py @@ -141,47 +141,14 @@ def test_physical_properties(): 'ram_slots': None, } assert pc.physical_properties == { - 'chassis': ComputerChassis.Tower, 'amount': 0, 'manufacturer': 'bar', 'model': 'foo', - 'receiver_id': None, 'serial_number': 'foo-bar', 'part_number': None, - 'transfer_state': TransferState.Initial, } -@pytest.mark.mvp -@pytest.mark.usefixtures(conftest.auth_app_context.__name__) -def test_component_similar_one(): - user = User.query.filter().first() - snapshot = yaml2json('pc-components.db') - pc = snapshot['device'] - snapshot['components'][0]['serial_number'] = snapshot['components'][1][ - 'serial_number' - ] = None - pc = d.Desktop( - **pc, components=OrderedSet(d.Component(**c) for c in snapshot['components']) - ) - component1, component2 = pc.components # type: d.Component - db.session.add(pc) - db.session.flush() - # Let's create a new component named 'A' similar to 1 - componentA = d.Component( - model=component1.model, manufacturer=component1.manufacturer, owner_id=user.id - ) - similar_to_a = componentA.similar_one(pc, set()) - assert similar_to_a == component1 - # d.Component B does not have the same model - componentB = d.Component(model='nope', manufacturer=component1.manufacturer) - with pytest.raises(ResourceNotFound): - assert componentB.similar_one(pc, set()) - # If we blacklist component A we won't get anything - with pytest.raises(ResourceNotFound): - assert componentA.similar_one(pc, blacklist={componentA.id}) - - @pytest.mark.mvp @pytest.mark.usefixtures(conftest.auth_app_context.__name__) def test_add_remove(): @@ -301,69 +268,6 @@ def test_sync_execute_register_desktop_no_hid_no_tag(user: UserClient): assert returned_pc == pc -@pytest.mark.mvp -@pytest.mark.usefixtures(conftest.auth_app_context.__name__) -def test_sync_execute_register_desktop_tag_not_linked(): - """Syncs a new d.Desktop with HID and a non-linked tag. - - It is OK if the tag was not linked, it will be linked in this process. - """ - tag = Tag(id='foo') - db.session.add(tag) - db.session.commit() - - # Create a new transient non-db object - pc = d.Desktop( - **yaml2json('pc-components.db')['device'], tags=OrderedSet([Tag(id='foo')]) - ) - returned_pc = Sync().execute_register(pc) - assert returned_pc == pc - assert tag.device == pc, 'Tag has to be linked' - assert d.Desktop.query.one() == pc, 'd.Desktop had to be set to db' - - -@pytest.mark.mvp -@pytest.mark.usefixtures(conftest.auth_app_context.__name__) -def test_sync_execute_register_no_hid_tag_not_linked(tag_id: str): - """Validates registering a d.Desktop without HID and a non-linked tag. - - In this case it is ok still, as the non-linked tag proves that - the d.Desktop was not existing before (otherwise the tag would - be linked), and thus it creates a new d.Desktop. - """ - tag = Tag(id=tag_id) - pc = d.Desktop(**yaml2json('pc-components.db')['device'], tags=OrderedSet([tag])) - db.session.add(g.user) - returned_pc = Sync().execute_register(pc) - db.session.commit() - assert returned_pc == pc - db_tag = next(iter(returned_pc.tags)) - # they are not the same tags though - # tag is a transient obj and db_tag the one from the db - # they have the same pk though - assert d.Desktop.query.one() == pc, 'd.Desktop had to be set to db' - assert tag != db_tag, 'They are not the same tags though' - for tag in pc.tags: - assert tag.id in ['foo', pc.devicehub_id] - - -@pytest.mark.mvp -@pytest.mark.usefixtures(conftest.auth_app_context.__name__) -def test_sync_execute_register_tag_does_not_exist(): - """Ensures not being able to register if the tag does not exist, - even if the device has HID or it existed before. - - Tags have to be created before trying to link them through a Snapshot. - """ - user = User.query.filter().first() - pc = d.Desktop( - **yaml2json('pc-components.db')['device'], tags=OrderedSet([Tag('foo')]) - ) - pc.owner_id = user.id - with raises(ResourceNotFound): - Sync().execute_register(pc) - - @pytest.mark.mvp @pytest.mark.usefixtures(conftest.auth_app_context.__name__) def test_sync_execute_register_tag_linked_same_device(): @@ -387,53 +291,6 @@ def test_sync_execute_register_tag_linked_same_device(): assert tag.id in ['foo', db_pc.devicehub_id] -@pytest.mark.mvp -@pytest.mark.usefixtures(conftest.auth_app_context.__name__) -def test_sync_execute_register_tag_linked_other_device_mismatch_between_tags(): - """Checks that sync raises an error if finds that at least two passed-in - tags are not linked to the same device. - """ - pc1 = d.Desktop(**yaml2json('pc-components.db')['device']) - db.session.add(Tag(id='foo-1', device=pc1)) - pc2 = d.Desktop(**yaml2json('pc-components.db')['device']) - pc2.serial_number = 'pc2-serial' - pc2.hid = Naming.hid(pc2.type, pc2.manufacturer, pc2.model, pc2.serial_number) - db.session.add(Tag(id='foo-2', device=pc2)) - db.session.commit() - - pc1 = d.Desktop( - **yaml2json('pc-components.db')['device'] - ) # Create a new transient non-db object - pc1.tags.add(Tag(id='foo-1')) - pc1.tags.add(Tag(id='foo-2')) - with raises(MismatchBetweenTags): - Sync().execute_register(pc1) - - -@pytest.mark.mvp -@pytest.mark.usefixtures(conftest.auth_app_context.__name__) -def test_sync_execute_register_mismatch_between_tags_and_hid(): - """Checks that sync raises an error if it finds that the HID does - not point at the same device as the tag does. - - In this case we set HID -> pc1 but tag -> pc2 - """ - pc1 = d.Desktop(**yaml2json('pc-components.db')['device']) - db.session.add(Tag(id='foo-1', device=pc1)) - pc2 = d.Desktop(**yaml2json('pc-components.db')['device']) - pc2.serial_number = 'pc2-serial' - pc2.hid = Naming.hid(pc2.type, pc2.manufacturer, pc2.model, pc2.serial_number) - db.session.add(Tag(id='foo-2', device=pc2)) - db.session.commit() - - pc1 = d.Desktop( - **yaml2json('pc-components.db')['device'] - ) # Create a new transient non-db object - pc1.tags.add(Tag(id='foo-2')) - with raises(MismatchBetweenTagsAndHid): - Sync().execute_register(pc1) - - @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_get_device(user: UserClient): @@ -753,138 +610,10 @@ def test_cooking_mixer_api(user: UserClient): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) -def test_hid_with_mac(app: Devicehub, user: UserClient): +def test_hid_with_placeholder(app: Devicehub, user: UserClient): """Checks hid with mac.""" snapshot = file('asus-eee-1000h.snapshot.11') snap, _ = user.post(snapshot, res=m.Snapshot) pc, _ = user.get(res=d.Device, item=snap['device']['devicehubID']) - assert pc['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116' pc = d.Device.query.filter_by(devicehub_id=snap['device']['devicehubID']).one() - assert ( - pc.placeholder.binding.hid - == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d' - ) - - -@pytest.mark.mvp -def test_hid_without_mac(app: Devicehub, user: UserClient): - """Checks hid without mac.""" - snapshot = yaml2json('asus-eee-1000h.snapshot.11') - snapshot['components'] = [ - c for c in snapshot['components'] if c['type'] != 'NetworkAdapter' - ] - snap, _ = user.post(json_encode(snapshot), res=m.Snapshot) - pc, _ = user.get(res=d.Device, item=snap['device']['devicehubID']) - assert pc['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116' - - -@pytest.mark.mvp -def test_hid_with_mac_none(app: Devicehub, user: UserClient): - """Checks hid with mac = None.""" - snapshot = yaml2json('asus-eee-1000h.snapshot.11') - network = [c for c in snapshot['components'] if c['type'] == 'NetworkAdapter'][0] - network['serialNumber'] = None - snap, _ = user.post(json_encode(snapshot), res=m.Snapshot) - pc, _ = user.get(res=d.Device, item=snap['device']['devicehubID']) - assert pc['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116' - - -@pytest.mark.mvp -def test_hid_with_2networkadapters(app: Devicehub, user: UserClient): - """Checks hid with 2 networks adapters""" - snapshot = yaml2json('asus-eee-1000h.snapshot.11') - network = [c for c in snapshot['components'] if c['type'] == 'NetworkAdapter'][0] - network2 = copy.copy(network) - snapshot['components'].append(network2) - network['serialNumber'] = 'a0:24:8c:7f:cf:2d' - user.post(json_encode(snapshot), res=m.Snapshot) - devices, _ = user.get(res=d.Device) - - laptop = devices['items'][0] - assert ( - laptop['hid'] - == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d' - ) - assert len([c for c in devices['items'] if c['type'] == 'Laptop']) == 2 - - -@pytest.mark.mvp -@pytest.mark.usefixtures(conftest.app_context.__name__) -def test_hid_with_2network_and_drop_no_mac_in_hid(app: Devicehub, user: UserClient): - """Checks hid with 2 networks adapters and next drop the network is not used in hid""" - snapshot = yaml2json('asus-eee-1000h.snapshot.11') - network = [c for c in snapshot['components'] if c['type'] == 'NetworkAdapter'][0] - network2 = copy.copy(network) - snapshot['components'].append(network2) - network['serialNumber'] = 'a0:24:8c:7f:cf:2d' - snap, _ = user.post(json_encode(snapshot), res=m.Snapshot) - pc, _ = user.get(res=d.Device, item=snap['device']['devicehubID']) - assert pc['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116' - pc = d.Device.query.filter_by(devicehub_id=snap['device']['devicehubID']).one() - assert ( - pc.placeholder.binding.hid - == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d' - ) - - snapshot['uuid'] = 'd1b70cb8-8929-4f36-99b7-fe052cec0abb' - snapshot['components'] = [c for c in snapshot['components'] if c != network] - user.post(json_encode(snapshot), res=m.Snapshot) - devices, _ = user.get(res=d.Device) - laptop = devices['items'][0] - assert ( - pc.placeholder.binding.hid - == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d' - ) - assert len([c for c in devices['items'] if c['type'] == 'Laptop']) == 2 - assert len([c for c in laptop['components'] if c['type'] == 'NetworkAdapter']) == 1 - - -@pytest.mark.mvp -@pytest.mark.usefixtures(conftest.app_context.__name__) -def test_hid_with_2network_and_drop_mac_in_hid(app: Devicehub, user: UserClient): - """Checks hid with 2 networks adapters and next drop the network is used in hid""" - # One tipical snapshot with 2 network cards - snapshot = yaml2json('asus-eee-1000h.snapshot.11') - network = [c for c in snapshot['components'] if c['type'] == 'NetworkAdapter'][0] - network2 = copy.copy(network) - snapshot['components'].append(network2) - network['serialNumber'] = 'a0:24:8c:7f:cf:2d' - snap, _ = user.post(json_encode(snapshot), res=m.Snapshot) - pc, _ = user.get(res=d.Device, item=snap['device']['devicehubID']) - assert pc['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116' - pc = d.Device.query.filter_by(devicehub_id=snap['device']['devicehubID']).one() - assert ( - pc.placeholder.binding.hid - == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d' - ) - - # we drop the network card then is used for to build the hid - snapshot['uuid'] = 'd1b70cb8-8929-4f36-99b7-fe052cec0abb' - snapshot['components'] = [c for c in snapshot['components'] if c != network2] - user.post(json_encode(snapshot), res=m.Snapshot) - devices, _ = user.get(res=d.Device) - laptops = [c for c in devices['items'] if c['type'] == 'Laptop'] - assert len(laptops) == 4 - hids = [laptops[0]['hid'], laptops[2]['hid']] - proof_hid = [ - 'laptop-asustek_computer_inc-1000h-94oaaq021116-a0:24:8c:7f:cf:2d', - 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d', - ] - assert all([h in proof_hid for h in hids]) - - # we drop all network cards - snapshot['uuid'] = 'd1b70cb8-8929-4f36-99b7-fe052cec0abc' - snapshot['components'] = [ - c for c in snapshot['components'] if c not in [network, network2] - ] - user.post(json_encode(snapshot), res=m.Snapshot) - devices, _ = user.get(res=d.Device) - laptops = [c for c in devices['items'] if c['type'] == 'Laptop'] - assert len(laptops) == 4 - hids = [laptops[0]['hid'], laptops[2]['hid']] - proof_hid = [ - 'laptop-asustek_computer_inc-1000h-94oaaq021116-a0:24:8c:7f:cf:2d', - 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d', - 'laptop-asustek_computer_inc-1000h-94oaaq021116', - ] - assert all([h in proof_hid for h in hids]) + assert pc.placeholder.binding.hid == pc.hid diff --git a/tests/test_metrics.py b/tests/test_metrics.py index d881d524..706e7260 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -6,24 +6,29 @@ from ereuse_devicehub.resources.documents import documents from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.tradedocument.models import TradeDocument from tests import conftest -from tests.conftest import file, yaml2json, json_encode +from tests.conftest import file, json_encode, yaml2json @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_simple_metrics(user: UserClient): - """ Checks one standard query of metrics """ + """Checks one standard query of metrics""" # Insert computer lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') acer = yaml2json('acer.happy.battery.snapshot') user.post(json_encode(lenovo), res=ma.Snapshot) snapshot, _ = user.post(json_encode(acer), res=ma.Snapshot) device_id = snapshot['device']['id'] - post_request = {"transaction": "ccc", "name": "John", "endUsers": 1, - "finalUserCode": "abcdefjhi", - "devices": [device_id], "description": "aaa", - "startTime": "2020-11-01T02:00:00+00:00", - "endTime": "2020-12-01T02:00:00+00:00"} + post_request = { + "transaction": "ccc", + "name": "John", + "endUsers": 1, + "finalUserCode": "abcdefjhi", + "devices": [device_id], + "description": "aaa", + "startTime": "2020-11-01T02:00:00+00:00", + "endTime": "2020-12-01T02:00:00+00:00", + } # Create Allocate user.post(res=ma.Allocate, data=post_request) @@ -58,16 +63,21 @@ def test_simple_metrics(user: UserClient): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_second_hdd_metrics(user: UserClient): - """ Checks one standard query of metrics """ + """Checks one standard query of metrics""" # Insert computer acer = yaml2json('acer.happy.battery.snapshot') snapshot, _ = user.post(json_encode(acer), res=ma.Snapshot) device_id = snapshot['device']['id'] - post_request = {"transaction": "ccc", "name": "John", "endUsers": 1, - "finalUserCode": "abcdefjhi", - "devices": [device_id], "description": "aaa", - "startTime": "2020-11-01T02:00:00+00:00", - "endTime": "2020-12-01T02:00:00+00:00"} + post_request = { + "transaction": "ccc", + "name": "John", + "endUsers": 1, + "finalUserCode": "abcdefjhi", + "devices": [device_id], + "description": "aaa", + "startTime": "2020-11-01T02:00:00+00:00", + "endTime": "2020-12-01T02:00:00+00:00", + } # Create Allocate user.post(res=ma.Allocate, data=post_request) @@ -101,16 +111,21 @@ def test_second_hdd_metrics(user: UserClient): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_metrics_with_live_null(user: UserClient): - """ Checks one standard query of metrics """ + """Checks one standard query of metrics""" # Insert computer acer = file('acer.happy.battery.snapshot') snapshot, _ = user.post(acer, res=ma.Snapshot) device_id = snapshot['device']['id'] - post_request = {"transaction": "ccc", "name": "John", "endUsers": 1, - "finalUserCode": "abcdefjhi", - "devices": [device_id], "description": "aaa", - "startTime": "2020-11-01T02:00:00+00:00", - "endTime": "2020-12-01T02:00:00+00:00"} + post_request = { + "transaction": "ccc", + "name": "John", + "endUsers": 1, + "finalUserCode": "abcdefjhi", + "devices": [device_id], + "description": "aaa", + "startTime": "2020-11-01T02:00:00+00:00", + "endTime": "2020-12-01T02:00:00+00:00", + } # Create Allocate user.post(res=ma.Allocate, data=post_request) @@ -124,19 +139,29 @@ def test_metrics_with_live_null(user: UserClient): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_metrics_action_status(user: UserClient, user2: UserClient): - """ Checks one standard query of metrics.""" + """Checks one standard query of metrics.""" # Insert computer lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') snap, _ = user.post(json_encode(lenovo), res=ma.Snapshot) device_id = snap['device']['id'] action = {'type': ma.Use.t, 'devices': [device_id]} action_use, _ = user.post(action, res=ma.Action) - csv_str, _ = user.get(res=documents.DocumentDef.t, - item='actions/', - accept='text/csv', - query=[('filter', {'type': ['Computer'], 'ids': [device_id]})]) - head = '"DHID";"Hid";"Document-Name";"Action-Type";"Action-User-LastOwner-Supplier";"Action-User-LastOwner-Receiver";"Action-Create-By";"Trade-Confirmed";"Status-Created-By-Supplier-About-Reciber";"Status-Receiver";"Status Supplier – Created Date";"Status Receiver – Created Date";"Trade-Weight";"Action-Create";"Allocate-Start";"Allocate-User-Code";"Allocate-NumUsers";"UsageTimeAllocate";"Type";"LiveCreate";"UsageTimeHdd"\n' - body = '"O48N2";"desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10";"";"Status";"";"foo@foo.com";"Receiver";"";"";"Use";"";"' + csv_str, _ = user.get( + res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer'], 'ids': [device_id]})], + ) + head = ( + '"DHID";"Hid";"Document-Name";"Action-Type";"Action-User-LastOwner-Supplier";' + ) + head += '"Action-User-LastOwner-Receiver";"Action-Create-By";"Trade-Confirmed";' + head += '"Status-Created-By-Supplier-About-Reciber";"Status-Receiver";' + head += '"Status Supplier – Created Date";"Status Receiver – Created Date";"Trade-Weight";' + head += '"Action-Create";"Allocate-Start";"Allocate-User-Code";"Allocate-NumUsers";' + head += '"UsageTimeAllocate";"Type";"LiveCreate";"UsageTimeHdd"\n' + body = '"O48N2";"adebcc5506213fac43cd8473a9c81bcf0cadaed9cb98b2eae651e377a3533c5a";' + body += '"";"Status";"";"foo@foo.com";"Receiver";"";"";"Use";"";"' assert head in csv_str assert body in csv_str @@ -144,7 +169,7 @@ def test_metrics_action_status(user: UserClient, user2: UserClient): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_complet_metrics_with_trade(user: UserClient, user2: UserClient): - """ Checks one standard query of metrics in a trade enviroment.""" + """Checks one standard query of metrics in a trade enviroment.""" # Insert computer lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') acer = yaml2json('acer.happy.battery.snapshot') @@ -154,12 +179,8 @@ def test_complet_metrics_with_trade(user: UserClient, user2: UserClient): device1_id = snap1['device']['id'] device2_id = snap2['device']['id'] devices_id = [device1_id, device2_id] - devices = [('id', device1_id), - ('id', snap2['device']['id'])] - lot, _ = user.post({}, - res=Lot, - item='{}/devices'.format(lot['id']), - query=devices) + devices = [('id', device1_id), ('id', snap2['device']['id'])] + lot, _ = user.post({}, res=Lot, item='{}/devices'.format(lot['id']), query=devices) action = {'type': ma.Refurbish.t, 'devices': [device1_id]} user.post(action, res=ma.Action) @@ -179,17 +200,21 @@ def test_complet_metrics_with_trade(user: UserClient, user2: UserClient): action = {'type': ma.Use.t, 'devices': [device1_id]} action_use, _ = user.post(action, res=ma.Action) - csv_str, _ = user.get(res=documents.DocumentDef.t, - item='actions/', - accept='text/csv', - query=[('filter', {'type': ['Computer'], 'ids': devices_id})]) + csv_str, _ = user.get( + res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer'], 'ids': devices_id})], + ) - body1_lenovo = '"O48N2";"desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10";"";"Trade";"foo@foo.com";' + body1_lenovo = '"O48N2";"adebcc5506213fac43cd8473a9c81bcf0cadaed9cb98b2eae651e377a3533c5a";"";"Trade";"foo@foo.com";' body1_lenovo += '"foo2@foo.com";"Supplier";"NeedConfirmation";"Use";"";' body2_lenovo = ';"";"0";"0";"Trade";"0";"0"\n' - body1_acer = '"K3XW2";"laptop-acer-aohappy-lusea0d010038879a01601-00:26:c7:8e:cb:8c";"";"Trade";' - body1_acer += '"foo@foo.com";"foo2@foo.com";"Supplier";"NeedConfirmation";"";"";"";"";"0";' + body1_acer = '"K3XW2";"55b1f6d0692d1569c7590f0aeabd1c9874a1c78b8dd3a7d481df95923a629748";"";"Trade";' + body1_acer += ( + '"foo@foo.com";"foo2@foo.com";"Supplier";"NeedConfirmation";"";"";"";"";"0";' + ) body2_acer = ';"";"0";"0";"Trade";"0";"4692.0"\n' assert body1_lenovo in csv_str @@ -200,12 +225,14 @@ def test_complet_metrics_with_trade(user: UserClient, user2: UserClient): # User2 mark this device as Refurbish action = {'type': ma.Use.t, 'devices': [device1_id]} action_use2, _ = user2.post(action, res=ma.Action) - csv_str, _ = user.get(res=documents.DocumentDef.t, - item='actions/', - accept='text/csv', - query=[('filter', {'type': ['Computer'], 'ids': devices_id})]) + csv_str, _ = user.get( + res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer'], 'ids': devices_id})], + ) - body1_lenovo = '"O48N2";"desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10";"";"Trade";"foo@foo.com";' + body1_lenovo = '"O48N2";"adebcc5506213fac43cd8473a9c81bcf0cadaed9cb98b2eae651e377a3533c5a";"";"Trade";"foo@foo.com";' body1_lenovo += '"foo2@foo.com";"Supplier";"NeedConfirmation";"Use";"Use";' body2_lenovo = ';"";"0";"0";"Trade";"0";"0"\n' body2_acer = ';"";"0";"0";"Trade";"0";"4692.0"\n' @@ -215,20 +242,16 @@ def test_complet_metrics_with_trade(user: UserClient, user2: UserClient): assert body2_acer in csv_str - @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_metrics_action_status_for_containers(user: UserClient, user2: UserClient): - """ Checks one standard query of metrics for a container.""" + """Checks one standard query of metrics for a container.""" # Insert computer lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') snap, _ = user.post(json_encode(lenovo), res=ma.Snapshot) lot, _ = user.post({'name': 'MyLot'}, res=Lot) devices = [('id', snap['device']['id'])] - lot, _ = user.post({}, - res=Lot, - item='{}/devices'.format(lot['id']), - query=devices) + lot, _ = user.post({}, res=Lot, item='{}/devices'.format(lot['id']), query=devices) request_post = { 'type': 'Trade', 'devices': [snap['device']['id']], @@ -247,7 +270,7 @@ def test_metrics_action_status_for_containers(user: UserClient, user2: UserClien 'hash': 'bbbbbbbb', 'url': 'http://www.ereuse.org/', 'weight': 150, - 'lot': lot['id'] + 'lot': lot['id'], } tradedocument, _ = user.post(res=TradeDocument, data=request_post) action = {'type': ma.Recycling.t, 'devices': [], 'documents': [tradedocument['id']]} @@ -257,10 +280,12 @@ def test_metrics_action_status_for_containers(user: UserClient, user2: UserClien assert str(trade.actions[-1].id) == action['id'] # get metrics from botom in lot menu - csv_str, _ = user.get(res=documents.DocumentDef.t, - item='actions/', - accept='text/csv', - query=[('filter', {'type': ['Computer']}), ('lot', lot['id'])]) + csv_str, _ = user.get( + res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer']}), ('lot', lot['id'])], + ) body1 = ';"bbbbbbbb";"test.pdf";"Trade-Container";"foo@foo.com";"foo2@foo.com";"Supplier";"False";"Recycling";"";' body2 = ';"";"150.0";' @@ -272,10 +297,12 @@ def test_metrics_action_status_for_containers(user: UserClient, user2: UserClien assert body3 in csv_str.split('\n')[-2] # get metrics from botom in devices menu - csv_str2, _ = user.get(res=documents.DocumentDef.t, - item='actions/', - accept='text/csv', - query=[('filter', {'type': ['Computer'], 'ids': [snap['device']['id']]})]) + csv_str2, _ = user.get( + res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer'], 'ids': [snap['device']['id']]})], + ) assert len(csv_str2.split('\n')) == 4 assert body1 in csv_str2.split('\n')[-2] @@ -286,17 +313,14 @@ def test_metrics_action_status_for_containers(user: UserClient, user2: UserClien @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_visual_metrics_for_old_owners(user: UserClient, user2: UserClient): - """ Checks if one old owner can see the metrics in a trade enviroment.""" + """Checks if one old owner can see the metrics in a trade enviroment.""" # Insert computer lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot') snap1, _ = user.post(json_encode(lenovo), res=ma.Snapshot) lot, _ = user.post({'name': 'MyLot'}, res=Lot) device_id = snap1['device']['id'] devices = [('id', device_id)] - lot, _ = user.post({}, - res=Lot, - item='{}/devices'.format(lot['id']), - query=devices) + lot, _ = user.post({}, res=Lot, item='{}/devices'.format(lot['id']), query=devices) request_post = { 'type': 'Trade', 'devices': [device_id], @@ -309,24 +333,23 @@ def test_visual_metrics_for_old_owners(user: UserClient, user2: UserClient): } trade, _ = user.post(res=ma.Action, data=request_post) - request_confirm = { - 'type': 'Confirm', - 'action': trade['id'], - 'devices': [device_id] - } + request_confirm = {'type': 'Confirm', 'action': trade['id'], 'devices': [device_id]} user2.post(res=ma.Action, data=request_confirm) - action = {'type': ma.Refurbish.t, 'devices': [device_id]} action_use, _ = user.post(action, res=ma.Action) - csv_supplier, _ = user.get(res=documents.DocumentDef.t, - item='actions/', - accept='text/csv', - query=[('filter', {'type': ['Computer'], 'ids': [device_id]})]) - csv_receiver, _ = user2.get(res=documents.DocumentDef.t, - item='actions/', - accept='text/csv', - query=[('filter', {'type': ['Computer'], 'ids': [device_id]})]) + csv_supplier, _ = user.get( + res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer'], 'ids': [device_id]})], + ) + csv_receiver, _ = user2.get( + res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer'], 'ids': [device_id]})], + ) body = ';"";"0";"0";"Trade";"0";"0"\n' assert body in csv_receiver @@ -343,10 +366,7 @@ def test_bug_trade_confirmed(user: UserClient, user2: UserClient): lot, _ = user.post({'name': 'MyLot'}, res=Lot) device_id = snap1['device']['id'] devices = [('id', device_id)] - lot, _ = user.post({}, - res=Lot, - item='{}/devices'.format(lot['id']), - query=devices) + lot, _ = user.post({}, res=Lot, item='{}/devices'.format(lot['id']), query=devices) request_post = { 'type': 'Trade', 'devices': [device_id], @@ -359,22 +379,24 @@ def test_bug_trade_confirmed(user: UserClient, user2: UserClient): } trade, _ = user.post(res=ma.Action, data=request_post) - csv_not_confirmed, _ = user.get(res=documents.DocumentDef.t, - item='actions/', - accept='text/csv', - query=[('filter', {'type': ['Computer'], 'ids': [device_id]})]) - request_confirm = { - 'type': 'Confirm', - 'action': trade['id'], - 'devices': [device_id] - } + csv_not_confirmed, _ = user.get( + res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer'], 'ids': [device_id]})], + ) + request_confirm = {'type': 'Confirm', 'action': trade['id'], 'devices': [device_id]} user2.post(res=ma.Action, data=request_confirm) - csv_confirmed, _ = user2.get(res=documents.DocumentDef.t, - item='actions/', - accept='text/csv', - query=[('filter', {'type': ['Computer'], 'ids': [device_id]})]) + csv_confirmed, _ = user2.get( + res=documents.DocumentDef.t, + item='actions/', + accept='text/csv', + query=[('filter', {'type': ['Computer'], 'ids': [device_id]})], + ) - body_not_confirmed = '"Trade";"foo2@foo.com";"foo@foo.com";"Receiver";"NeedConfirmation";' + body_not_confirmed = ( + '"Trade";"foo2@foo.com";"foo@foo.com";"Receiver";"NeedConfirmation";' + ) body_confirmed = '"Trade";"foo2@foo.com";"foo@foo.com";"Receiver";"TradeConfirmed";' assert body_not_confirmed in csv_not_confirmed diff --git a/tests/test_rate_workbench_v1.py b/tests/test_rate_workbench_v1.py index 7269b72a..b52b2995 100644 --- a/tests/test_rate_workbench_v1.py +++ b/tests/test_rate_workbench_v1.py @@ -17,18 +17,36 @@ Excluded cases in tests """ import math + import pytest -from ereuse_devicehub.resources.action.models import BenchmarkDataStorage, BenchmarkProcessor, \ - VisualTest -from ereuse_devicehub.resources.action.rate.v1_0 import DataStorageRate, ProcessorRate, \ - RamRate, RateAlgorithm -from ereuse_devicehub.resources.device.models import Desktop, HardDrive, Processor, RamModule -from ereuse_devicehub.resources.enums import AppearanceRange, ComputerChassis, FunctionalityRange +from ereuse_devicehub.resources.action.models import ( + BenchmarkDataStorage, + BenchmarkProcessor, + VisualTest, +) +from ereuse_devicehub.resources.action.rate.v1_0 import ( + DataStorageRate, + ProcessorRate, + RamRate, + RateAlgorithm, +) +from ereuse_devicehub.resources.device.models import ( + Desktop, + HardDrive, + Processor, + RamModule, +) +from ereuse_devicehub.resources.enums import ( + AppearanceRange, + ComputerChassis, + FunctionalityRange, +) from tests import conftest @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_data_storage_rate(): """Test to check if compute data storage rate have same value than previous score version. @@ -65,6 +83,7 @@ def test_rate_data_storage_rate(): @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_data_storage_size_is_null(): """Test where input DataStorage.size = NULL, BenchmarkDataStorage.read_speed = 0, BenchmarkDataStorage.write_speed = 0 is like no DataStorage has been detected; @@ -78,6 +97,7 @@ def test_rate_data_storage_size_is_null(): @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_no_data_storage(): """Test without data storage devices.""" @@ -88,6 +108,7 @@ def test_rate_no_data_storage(): @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_ram_rate(): """Test to check if compute ram rate have same value than previous score version only with 1 RamModule. @@ -97,10 +118,13 @@ def test_rate_ram_rate(): ram_rate = RamRate().compute([ram1]) - assert math.isclose(ram_rate, 2.02, rel_tol=0.002), 'RamRate returns incorrect value(rate)' + assert math.isclose( + ram_rate, 2.02, rel_tol=0.002 + ), 'RamRate returns incorrect value(rate)' @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_ram_rate_2modules(): """Test to check if compute ram rate have same value than previous score version with 2 RamModule. @@ -111,10 +135,13 @@ def test_rate_ram_rate_2modules(): ram_rate = RamRate().compute([ram1, ram2]) - assert math.isclose(ram_rate, 3.79, rel_tol=0.001), 'RamRate returns incorrect value(rate)' + assert math.isclose( + ram_rate, 3.79, rel_tol=0.001 + ), 'RamRate returns incorrect value(rate)' @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_ram_rate_4modules(): """Test to check if compute ram rate have same value than previous score version with 2 RamModule. @@ -127,10 +154,13 @@ def test_rate_ram_rate_4modules(): ram_rate = RamRate().compute([ram1, ram2, ram3, ram4]) - assert math.isclose(ram_rate, 1.993, rel_tol=0.001), 'RamRate returns incorrect value(rate)' + assert math.isclose( + ram_rate, 1.993, rel_tol=0.001 + ), 'RamRate returns incorrect value(rate)' @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_ram_module_size_is_0(): """Test where input data RamModule.size = 0; is like no RamModule has been detected. @@ -143,6 +173,7 @@ def test_rate_ram_module_size_is_0(): @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_ram_speed_is_null(): """Test where RamModule.speed is NULL (not detected) but has size.""" @@ -150,16 +181,21 @@ def test_rate_ram_speed_is_null(): ram_rate = RamRate().compute([ram0]) - assert math.isclose(ram_rate, 1.85, rel_tol=0.002), 'RamRate returns incorrect value(rate)' + assert math.isclose( + ram_rate, 1.85, rel_tol=0.002 + ), 'RamRate returns incorrect value(rate)' ram0 = RamModule(size=1024, speed=None) ram_rate = RamRate().compute([ram0]) - assert math.isclose(ram_rate, 1.25, rel_tol=0.004), 'RamRate returns incorrect value(rate)' + assert math.isclose( + ram_rate, 1.25, rel_tol=0.004 + ), 'RamRate returns incorrect value(rate)' @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_no_ram_module(): """Test without RamModule.""" ram0 = RamModule() @@ -169,6 +205,7 @@ def test_rate_no_ram_module(): @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_processor_rate(): """Test to check if compute processor rate have same value than previous score version only with 1 core. @@ -184,6 +221,7 @@ def test_rate_processor_rate(): @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_processor_rate_2cores(): """Test to check if compute processor rate have same value than previous score version with 2 cores. @@ -206,6 +244,7 @@ def test_rate_processor_rate_2cores(): @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_processor_with_null_cores(): """Test with processor device have null number of cores.""" cpu = Processor(cores=None, speed=3.3) @@ -217,6 +256,7 @@ def test_rate_processor_with_null_cores(): @pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) def test_rate_processor_with_null_speed(): """Test with processor device have null speed value.""" cpu = Processor(cores=1, speed=None) @@ -262,12 +302,14 @@ def test_rate_computer_1193(): data_storage, RamModule(size=4096, speed=1600), RamModule(size=2048, speed=1067), - cpu + cpu, } # Add test visual with functionality and appearance range - VisualTest(appearance_range=AppearanceRange.A, - functionality_range=FunctionalityRange.A, - device=pc_test) + VisualTest( + appearance_range=AppearanceRange.A, + functionality_range=FunctionalityRange.A, + device=pc_test, + ) # Compute all components rates and general rating rate_pc = RateAlgorithm().compute(pc_test) @@ -311,15 +353,13 @@ def test_rate_computer_1201(): data_storage.actions_one.add(BenchmarkDataStorage(read_speed=158, write_speed=34.7)) cpu = Processor(cores=2, speed=3.3) cpu.actions_one.add(BenchmarkProcessor(rate=26339.48)) - pc_test.components |= { - data_storage, - RamModule(size=2048, speed=1333), - cpu - } + pc_test.components |= {data_storage, RamModule(size=2048, speed=1333), cpu} # Add test visual with functionality and appearance range - VisualTest(appearance_range=AppearanceRange.B, - functionality_range=FunctionalityRange.A, - device=pc_test) + VisualTest( + appearance_range=AppearanceRange.B, + functionality_range=FunctionalityRange.A, + device=pc_test, + ) # Compute all components rates and general rating rate_pc = RateAlgorithm().compute(pc_test) @@ -365,7 +405,9 @@ def test_rate_computer_multiple_ram_module(): pc_test = Desktop(chassis=ComputerChassis.Tower) data_storage = HardDrive(size=76319) - data_storage.actions_one.add(BenchmarkDataStorage(read_speed=72.2, write_speed=24.3)) + data_storage.actions_one.add( + BenchmarkDataStorage(read_speed=72.2, write_speed=24.3) + ) cpu = Processor(cores=1, speed=1.6) cpu.actions_one.add(BenchmarkProcessor(rate=3192.34)) pc_test.components |= { @@ -374,12 +416,14 @@ def test_rate_computer_multiple_ram_module(): RamModule(size=512, speed=800), RamModule(size=512, speed=667), RamModule(size=512, speed=533), - cpu + cpu, } # Add test visual with functionality and appearance range - VisualTest(appearance_range=AppearanceRange.C, - functionality_range=FunctionalityRange.A, - device=pc_test) + VisualTest( + appearance_range=AppearanceRange.C, + functionality_range=FunctionalityRange.A, + device=pc_test, + ) # Compute all components rates and general rating rate_pc = RateAlgorithm().compute(pc_test) @@ -421,18 +465,18 @@ def test_rate_computer_one_ram_module(): pc_test = Desktop(chassis=ComputerChassis.Tower) data_storage = HardDrive(size=152587) - data_storage.actions_one.add(BenchmarkDataStorage(read_speed=78.1, write_speed=24.4)) + data_storage.actions_one.add( + BenchmarkDataStorage(read_speed=78.1, write_speed=24.4) + ) cpu = Processor(cores=2, speed=2.5) cpu.actions_one.add(BenchmarkProcessor(rate=9974.3)) - pc_test.components |= { - data_storage, - RamModule(size=0, speed=None), - cpu - } + pc_test.components |= {data_storage, RamModule(size=0, speed=None), cpu} # Add test visual with functionality and appearance range - VisualTest(appearance_range=AppearanceRange.B, - functionality_range=FunctionalityRange.A, - device=pc_test) + VisualTest( + appearance_range=AppearanceRange.B, + functionality_range=FunctionalityRange.A, + device=pc_test, + ) # Compute all components rates and general rating rate_pc = RateAlgorithm().compute(pc_test) diff --git a/tests/test_render_2_0.py b/tests/test_render_2_0.py index f9f2299e..ac8c6887 100644 --- a/tests/test_render_2_0.py +++ b/tests/test_render_2_0.py @@ -12,7 +12,6 @@ from flask_wtf.csrf import generate_csrf from ereuse_devicehub.client import UserClient, UserClientFlask from ereuse_devicehub.db import db from ereuse_devicehub.devicehub import Devicehub -from ereuse_devicehub.parser.models import SnapshotsLog from ereuse_devicehub.resources.action.models import Snapshot from ereuse_devicehub.resources.device.models import Device, Placeholder from ereuse_devicehub.resources.lot.models import Lot @@ -714,7 +713,9 @@ def test_add_laptop(user3: UserClientFlask): assert typ == 'Laptop' assert dev.placeholder.id_device_supplier == "b2" - assert dev.hid == 'laptop-samsung-lc27t55-aaaab' + assert ( + dev.chid == '274f05421e4d394c5b3cd10266fed6f0500029b104b5db3521689bda589e3150' + ) assert phid == '1' assert dhid == 'O48N2' @@ -753,7 +754,11 @@ def test_add_with_ammount_laptops(user3: UserClientFlask): for dev in Device.query.all(): assert dev.type == 'Laptop' assert dev.placeholder.id_device_supplier is None - assert dev.hid is None + assert dev.hid == 'laptop-samsung-lc27t55-' + assert ( + dev.chid + == 'ff8e7794d33ed22046b8d94b8bba4d8d1507f0fee535150835cac28faabbcda1' + ) assert dev.placeholder.phid in [str(x) for x in range(1, num + 1)] assert Device.query.count() == num @@ -1698,7 +1703,6 @@ def test_export_lots(user3: UserClientFlask): @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_export_snapshot_json(user3: UserClientFlask): - # ?? file_name = 'real-eee-1001pxd.snapshot.13.json' snap = create_device(user3, file_name) @@ -1708,7 +1712,10 @@ def test_export_snapshot_json(user3: UserClientFlask): uri = "/inventory/export/snapshot/?id={}".format(snap.uuid) body, status = user3.get(uri) assert status == '200 OK' - assert body == snapshot + body = json.loads(body) + snapshot = json.loads(snapshot) + assert body['device'] == snapshot['device'] + assert body['components'] == snapshot['components'] @pytest.mark.mvp @@ -1729,7 +1736,8 @@ def test_add_placeholder_excel(user3: UserClientFlask): user3.post(uri, data=data, content_type="multipart/form-data") assert Device.query.count() == 3 dev = Device.query.first() - assert dev.hid == 'laptop-sony-vaio-12345678' + chid = 'f28ae12ffd513f5ed8fb6714a344a2326c48a7196fb140435065ab96ffda1a71' + assert dev.chid == chid assert dev.placeholder.phid == '1' assert dev.placeholder.info == 'Good conditions' assert dev.placeholder.pallet == '24A' @@ -1755,7 +1763,8 @@ def test_add_placeholder_csv(user3: UserClientFlask): user3.post(uri, data=data, content_type="multipart/form-data") assert Device.query.count() == 3 dev = Device.query.first() - assert dev.hid == 'laptop-sony-vaio-12345678' + chid = 'f28ae12ffd513f5ed8fb6714a344a2326c48a7196fb140435065ab96ffda1a71' + assert dev.chid == chid assert dev.placeholder.phid == '1' assert dev.placeholder.info == 'Good conditions' assert dev.placeholder.pallet == '24A' @@ -1781,7 +1790,8 @@ def test_add_placeholder_ods(user3: UserClientFlask): user3.post(uri, data=data, content_type="multipart/form-data") assert Device.query.count() == 3 dev = Device.query.first() - assert dev.hid == 'laptop-sony-vaio-12345678' + chid = 'f28ae12ffd513f5ed8fb6714a344a2326c48a7196fb140435065ab96ffda1a71' + assert dev.chid == chid assert dev.placeholder.phid == '1' assert dev.placeholder.info == 'Good conditions' assert dev.placeholder.pallet == '24A' @@ -1809,7 +1819,8 @@ def test_add_placeholder_office_open_xml(user3: UserClientFlask): user3.post(uri, data=data, content_type="multipart/form-data") assert Device.query.count() == 3 dev = Device.query.first() - assert dev.hid == 'laptop-sony-vaio-12345678' + chid = 'f28ae12ffd513f5ed8fb6714a344a2326c48a7196fb140435065ab96ffda1a71' + assert dev.chid == chid assert dev.placeholder.phid == '1' assert dev.placeholder.info == 'Good conditions' assert dev.placeholder.pallet == '24A' @@ -1847,7 +1858,8 @@ def test_edit_laptop(user3: UserClientFlask): assert typ == 'Laptop' assert dev.placeholder.id_device_supplier == "b2" - assert dev.hid == 'laptop-samsung-lc27t55-aaaab' + chid = '274f05421e4d394c5b3cd10266fed6f0500029b104b5db3521689bda589e3150' + assert dev.chid == chid assert dev.serial_number == 'aaaab' assert dev.model == 'lc27t55' assert phid == '1' @@ -1879,7 +1891,7 @@ def test_edit_laptop(user3: UserClientFlask): assert 'Device "Laptop" edited successfully!' in body dev = Device.query.one() assert dev.type == 'Laptop' - assert dev.hid == 'laptop-samsung-lc27t55-aaaab' + assert dev.chid == chid assert dev.placeholder.phid == '1' assert dev.placeholder.id_device_supplier == 'a2' assert dev.serial_number == 'aaaac' @@ -2077,7 +2089,8 @@ def test_add_placeholder_excel_from_lot(user3: UserClientFlask): user3.post(uri, data=data, content_type="multipart/form-data") assert Device.query.count() == 3 dev = Device.query.first() - assert dev.hid == 'laptop-sony-vaio-12345678' + chid = 'f28ae12ffd513f5ed8fb6714a344a2326c48a7196fb140435065ab96ffda1a71' + assert dev.chid == chid assert dev.placeholder.phid == '1' assert dev.placeholder.info == 'Good conditions' assert dev.placeholder.pallet == '24A' @@ -2116,7 +2129,8 @@ def test_add_new_placeholder_from_lot(user3: UserClientFlask): } user3.post(uri, data=data) dev = Device.query.one() - assert dev.hid == 'laptop-samsung-lc27t55-aaaab' + chid = '274f05421e4d394c5b3cd10266fed6f0500029b104b5db3521689bda589e3150' + assert dev.chid == chid assert dev.placeholder.phid == '1' assert len(lot.devices) == 1 @@ -2141,7 +2155,8 @@ def test_manual_binding(user3: UserClientFlask): } user3.post(uri, data=data) dev = Device.query.one() - assert dev.hid == 'laptop-samsung-lc27t55-aaaab' + chid = '274f05421e4d394c5b3cd10266fed6f0500029b104b5db3521689bda589e3150' + assert dev.chid == chid assert dev.placeholder.phid == '1' assert dev.placeholder.is_abstract is False @@ -2153,8 +2168,8 @@ def test_manual_binding(user3: UserClientFlask): assert dev_wb.binding.is_abstract is True assert ( - dev_wb.hid - == 'laptop-asustek_computer_inc-1001pxd-b8oaas048285-14:da:e9:42:f6:7b' + dev_wb.chid + == '83cb9066430a8ea7def04af61d521d6517193a486c02ea3bc914c9eaeb2b718b' ) assert dev_wb.binding.phid == '11' old_placeholder = dev_wb.binding @@ -2653,10 +2668,109 @@ def test_system_uuid_motherboard(user3: UserClientFlask): } user3.post(uri, data=data, content_type="multipart/form-data") snapshot2 = Snapshot.query.filter_by(uuid=snapshot_json['uuid']).first() - assert snapshot2 is None + assert snapshot2.device == snapshot.device for c in snapshot.device.components: if c.type == 'Motherboard': - assert c.serial_number == 'eee0123456720' + assert c.serial_number == 'abee0123456720' - txt = "We have detected that a there is a device in your inventory" - assert txt in SnapshotsLog.query.all()[-1].description + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_unreliable_device(user3: UserClientFlask): + # Create device + snapshot = create_device(user3, 'real-eee-1001pxd.snapshot.12.json') + + # Update device + uri = '/inventory/upload-snapshot/' + file_name = 'real-eee-1001pxd.snapshot.12' + snapshot_json = conftest.yaml2json(file_name) + snapshot_json['uuid'] = 'c058e8d2-fb92-47cb-a4b7-522b75561136' + b_snapshot = bytes(json.dumps(snapshot_json), 'utf-8') + file_snap = (BytesIO(b_snapshot), file_name) + user3.get(uri) + + data = { + 'snapshot': file_snap, + 'csrf_token': generate_csrf(), + } + user3.post(uri, data=data, content_type="multipart/form-data") + snapshot2 = Snapshot.query.filter_by(uuid=snapshot_json['uuid']).first() + assert snapshot2.device == snapshot.device + assert Snapshot.query.count() == 2 + snapshots = Snapshot.query.all() + assert snapshots[0].device == snapshots[1].device + assert len(snapshots[0].device.components) + assert snapshot2 in snapshots + + # Change update for new device + uuid2 = snapshot2.uuid + uri = f"/inventory/snapshots/{uuid2}/" + user3.get(uri) + + data = { + 'snapshot_type': "new_device", + 'csrf_token': generate_csrf(), + } + assert Device.query.filter_by(hid=snapshot.device.hid).count() == 2 + user3.post(uri, data=data) + assert Device.query.filter_by(hid=snapshot.device.hid).count() == 4 + assert Snapshot.query.count() == 2 + snapshots = Snapshot.query.all() + assert snapshot2 not in snapshots + assert snapshots[0].device != snapshots[1].device + assert len(snapshots[0].device.components) == 4 + assert len(snapshots[1].device.components) == 9 + assert len(snapshots[0].device.actions) == 11 + assert len(snapshots[1].device.actions) == 10 + + +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_reliable_device(user3: UserClientFlask): + # Create device + snapshot = create_device(user3, 'real-eee-1001pxd.snapshot.12.json') + + # Update device + uri = '/inventory/upload-snapshot/' + file_name = 'real-eee-1001pxd.snapshot.12' + snapshot_json = conftest.yaml2json(file_name) + snapshot_json['uuid'] = 'c058e8d2-fb92-47cb-a4b7-522b75561136' + b_snapshot = bytes(json.dumps(snapshot_json), 'utf-8') + file_snap = (BytesIO(b_snapshot), file_name) + user3.get(uri) + + data = { + 'snapshot': file_snap, + 'csrf_token': generate_csrf(), + } + user3.post(uri, data=data, content_type="multipart/form-data") + snapshot2 = Snapshot.query.filter_by(uuid=snapshot_json['uuid']).first() + + # Change update for new device + uuid2 = snapshot2.uuid + uri = f"/inventory/snapshots/{uuid2}/" + user3.get(uri) + + data = { + 'snapshot_type': "new_device", + 'csrf_token': generate_csrf(), + } + user3.post(uri, data=data) + + # Change update for update + snapshot3 = Snapshot.query.all()[-1] + uuid3 = snapshot3.uuid + uri = f"/inventory/snapshots/{uuid3}/" + user3.get(uri) + + data = { + 'snapshot_type': "update", + 'csrf_token': generate_csrf(), + } + assert Device.query.filter_by(hid=snapshot.device.hid).count() == 4 + user3.post(uri, data=data) + assert Device.query.filter_by(hid=snapshot.device.hid).count() == 2 + assert Snapshot.query.count() == 1 + assert Snapshot.query.first() == snapshot + assert len(snapshot.device.components) == 4 + assert len(snapshot.device.actions) == 4 diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py index 2ee04e76..9b4eca8e 100644 --- a/tests/test_snapshot.py +++ b/tests/test_snapshot.py @@ -368,7 +368,7 @@ def test_snapshot_post_without_hid(user: UserClient): assert response_snapshot['uuid'] == '9a3e7485-fdd0-47ce-bcc7-65c55226b598' assert response_snapshot['elapsed'] == 4 assert response_snapshot['author']['id'] == user.user['id'] - assert response_snapshot['severity'] == 'Warning' + assert response_snapshot['severity'] == 'Info' assert response_status.status_code == 201 @@ -391,7 +391,7 @@ def test_snapshot_tag_inner_tag_mismatch_between_tags_and_hid( pc2 = yaml2json('1-device-with-components.snapshot') user.post(json_encode(pc2), res=Snapshot) # PC2 uploads well pc2['device']['tags'] = [{'type': 'Tag', 'id': tag_id}] # Set tag from pc1 to pc2 - user.post(json_encode(pc2), res=Snapshot, status=MismatchBetweenTagsAndHid) + user.post(json_encode(pc2), res=Snapshot, status=400) @pytest.mark.mvp @@ -411,7 +411,7 @@ def test_snapshot_different_properties_same_tags(user: UserClient, tag_id: str): pc2['device']['tags'] = pc1['device']['tags'] # pc2 model is unknown but pc1 model is set = different property del pc2['device']['model'] - user.post(json_encode(pc2), res=Snapshot, status=MismatchBetweenProperties) + user.post(json_encode(pc2), res=Snapshot, status=201) @pytest.mark.mvp @@ -684,7 +684,8 @@ def test_erase_changing_hdd_between_pcs(user: UserClient): tag2 = Tag(id='dev2', device=dev2) db.session.commit() - assert dev2.components[1].actions[2].parent == dev1 + assert dev2.components[2].parent == dev2 + assert dev2.components[2].actions[-1].device == dev1 doc1, response = user.get( res=documents.DocumentDef.t, item='erasures/{}'.format(dev1.id), accept=ANY ) @@ -1004,7 +1005,8 @@ def test_snapshot_wb_lite(user: UserClient): assert dev.dhid in body['public_url'] assert ssd.serial_number == 's35anx0j401001' assert res.status == '201 CREATED' - assert '00:28:f8:a6:d5:7e' in dev.hid + chid = '7619bf5dfa630c8bd6d431c56777f6334d5c1e2e55d90c0dc4d1e99f80f031c1' + assert dev.chid == chid assert dev.actions[0].power_on_hours == 6032 errors = SnapshotsLog.query.filter().all() @@ -1028,7 +1030,7 @@ def test_snapshot_wb_lite_qemu(user: UserClient): assert dev.manufacturer == 'qemu' assert dev.model == 'standard' assert dev.serial_number is None - assert dev.hid is None + assert dev.hid == 'computer-qemu-standard-' assert dev.actions[0].power_on_hours == 1 assert dev.components[-1].size == 40960 assert dev.components[-1].serial_number == 'qm00001' @@ -1078,7 +1080,7 @@ def test_snapshot_wb_lite_old_snapshots(user: UserClient): try: assert body11['device'].get('hid') == dev.hid if body11['device'].get('hid'): - assert body11['device']['id'] == dev.id + assert body11['device']['id'] != dev.id assert body11['device'].get('serialNumber') == dev.serial_number assert body11['device'].get('model') == dev.model assert body11['device'].get('manufacturer') == dev.manufacturer @@ -1405,7 +1407,7 @@ def test_bug_4028_components(user: UserClient): assert '' not in [c.phid() for c in components1] assert '' not in [c.phid() for c in components2] assert len(components1) == len(components2) - assert m.Placeholder.query.count() == 16 + assert m.Placeholder.query.count() == 15 assert m.Placeholder.query.count() * 2 == m.Device.query.count() for c in m.Placeholder.query.filter(): assert c.binding diff --git a/tests/test_system_uuid.py b/tests/test_system_uuid.py index 71eae0e7..08a162c7 100644 --- a/tests/test_system_uuid.py +++ b/tests/test_system_uuid.py @@ -29,7 +29,7 @@ def test_wb11_form(user3: UserClientFlask): db_snapthot = Snapshot.query.one() device = db_snapthot.device - assert device.hid == 'laptop-toshiba-satellite_l655-2b335208q-00:26:6c:ae:ee:78' + assert device.hid == 'laptop-toshiba-satellite_l655-2b335208q' assert str(device.system_uuid) == 'f0dc6a7f-c23f-e011-b5d0-00266caeee78' @@ -42,7 +42,7 @@ def test_wb11_api(user: UserClient): db_snapthot = Snapshot.query.one() device = db_snapthot.device - assert device.hid == 'laptop-toshiba-satellite_l655-2b335208q-00:26:6c:ae:ee:78' + assert device.hid == 'laptop-toshiba-satellite_l655-2b335208q' assert str(device.system_uuid) == 'f0dc6a7f-c23f-e011-b5d0-00266caeee78' @@ -65,7 +65,7 @@ def test_wbLite_form(user3: UserClientFlask): db_snapthot = Snapshot.query.one() device = db_snapthot.device - assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' @@ -78,7 +78,7 @@ def test_wbLite_api(user: UserClient): db_snapthot = Snapshot.query.one() device = db_snapthot.device - assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' @@ -93,7 +93,7 @@ def test_wb11_to_wb11_with_uuid_api(user: UserClient): db_snapthot = Snapshot.query.one() device = db_snapthot.device assert Computer.query.count() == 2 - assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert device.system_uuid is None # insert the same computer with wb11 with hid and with uuid, (new version) @@ -109,11 +109,8 @@ def test_wb11_to_wb11_with_uuid_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) - assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' + assert device.system_uuid is None @pytest.mark.mvp @@ -130,10 +127,7 @@ def test_wb11_with_uuid_to_wb11_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' # insert the same computer with wb11 with hid and with uuid, (new version) @@ -144,10 +138,7 @@ def test_wb11_with_uuid_to_wb11_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' @@ -165,10 +156,7 @@ def test_wb11_with_uuid_to_wb11_without_hid_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' # insert the same computer with wb11 with hid and with uuid, (new version) @@ -203,7 +191,7 @@ def test_wb11_to_wb11_with_uuid_form(user3: UserClientFlask): db_snapthot = Snapshot.query.one() device = db_snapthot.device assert Computer.query.count() == 2 - assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert device.system_uuid is None # insert the same computer with wb11 with hid and with uuid, (new version) @@ -222,11 +210,8 @@ def test_wb11_to_wb11_with_uuid_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) - assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' + assert device.system_uuid is None @pytest.mark.mvp @@ -254,10 +239,7 @@ def test_wb11_with_uuid_to_wb11_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' # insert the same computer with wb11 with hid and with uuid, (new version) @@ -275,10 +257,7 @@ def test_wb11_with_uuid_to_wb11_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' @@ -307,10 +286,7 @@ def test_wb11_with_uuid_to_wb11_without_hid_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' # insert the same computer with wb11 with hid and with uuid, (new version) @@ -340,10 +316,7 @@ def test_wb11_to_wblite_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert device.system_uuid is None snapshot_lite = conftest.file_json('system_uuid2.json') @@ -351,11 +324,9 @@ def test_wb11_to_wblite_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) - assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' + # assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' + assert device.system_uuid is None @pytest.mark.mvp @@ -367,10 +338,7 @@ def test_wblite_to_wb11_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' snapshot_11 = conftest.file_json('system_uuid3.json') @@ -378,10 +346,7 @@ def test_wblite_to_wb11_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' @@ -405,10 +370,7 @@ def test_wb11_to_wblite_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert device.system_uuid is None file_name = 'system_uuid2.json' @@ -424,11 +386,9 @@ def test_wb11_to_wblite_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) - assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' + # assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' + assert device.system_uuid is None @pytest.mark.mvp @@ -451,10 +411,7 @@ def test_wblite_to_wb11_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601' assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' file_name = 'system_uuid3.json' @@ -470,10 +427,7 @@ def test_wblite_to_wb11_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' @@ -486,10 +440,7 @@ def test_wblite_to_wblite_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' snapshot_lite = conftest.file_json('system_uuid2.json') @@ -498,10 +449,7 @@ def test_wblite_to_wblite_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' @@ -525,10 +473,7 @@ def test_wblite_to_wblite_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' file_name = 'system_uuid2.json' @@ -545,10 +490,7 @@ def test_wblite_to_wblite_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' @@ -562,10 +504,7 @@ def test_wb11_to_wb11_duplicity_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert device.system_uuid is None snapshot_11 = conftest.file_json('system_uuid3.json') @@ -573,7 +512,7 @@ def test_wb11_to_wb11_duplicity_api(user: UserClient): components = [x for x in snapshot_11['components'] if x['type'] != 'NetworkAdapter'] snapshot_11['components'] = components user.post(snapshot_11, res=Snapshot) - assert Computer.query.count() == 4 + assert Computer.query.count() == 2 for c in Computer.query.all(): assert 'laptop-acer-aohappy-lusea0d010038879a01601' in c.hid assert c.system_uuid is None @@ -599,10 +538,7 @@ def test_wb11_to_wb11_duplicity_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert device.system_uuid is None snapshot_11 = conftest.file_json('system_uuid3.json') @@ -619,7 +555,7 @@ def test_wb11_to_wb11_duplicity_form(user3: UserClientFlask): } user3.post(uri, data=data, content_type="multipart/form-data") - assert Computer.query.count() == 4 + assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: assert 'laptop-acer-aohappy-lusea0d010038879a01601' in device.hid @@ -636,10 +572,7 @@ def test_wb11_smbios_2_5_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert device.system_uuid is None @@ -663,10 +596,7 @@ def test_wb11_smbios_2_5_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert device.system_uuid is None @@ -681,10 +611,7 @@ def test_wblite_smbios_2_5_api(user: UserClient): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' @@ -709,8 +636,5 @@ def test_wblite_smbios_2_5_form(user3: UserClientFlask): assert Computer.query.count() == 2 for device in Computer.query.all(): if device.binding: - assert ( - device.hid - == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0' - ) + assert device.hid assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0' diff --git a/tests/test_tag.py b/tests/test_tag.py index 94c0f23c..cbdd7e5f 100644 --- a/tests/test_tag.py +++ b/tests/test_tag.py @@ -348,39 +348,6 @@ def test_tag_manual_link_search(app: Devicehub, user: UserClient): assert i['items'] -@pytest.mark.mvp -@pytest.mark.usefixtures(conftest.app_context.__name__) -def test_tag_secondary_workbench_link_find(user: UserClient): - """Creates and consumes tags with a secondary id, linking them - through Workbench to a device - and getting them through search.""" - t = Tag('foo', secondary='bar', owner_id=user.user['id']) - db.session.add(t) - db.session.flush() - assert Tag.from_an_id('bar').one() == Tag.from_an_id('foo').one() - with pytest.raises(ResourceNotFound): - Tag.from_an_id('nope').one() - - s = yaml2json('basic.snapshot') - s['device']['tags'] = [{'id': 'foo', 'secondary': 'bar', 'type': 'Tag'}] - snapshot, _ = user.post(json_encode(s), res=Snapshot) - dev = Device.query.filter_by(id=snapshot['device']['id']).one() - device, _ = user.get(res=Device, item=dev.devicehub_id) - desktop = dev.binding.device - assert [] == [x['id'] for x in device['tags']] - assert 'foo' in [x.id for x in desktop.tags] - assert 'bar' in [x.secondary for x in desktop.tags] - - r, _ = user.get( - res=Device, query=[('search', 'foo'), ('filter', {'type': ['Computer']})] - ) - assert len(r['items']) == 1 - r, _ = user.get( - res=Device, query=[('search', 'bar'), ('filter', {'type': ['Computer']})] - ) - assert len(r['items']) == 1 - - @pytest.mark.mvp def test_tag_create_tags_cli_csv(app: Devicehub, user: UserClient): """Checks creating tags with the CLI endpoint using a CSV.""" diff --git a/tests/test_workbench.py b/tests/test_workbench.py index 43c293ea..5f4221e5 100644 --- a/tests/test_workbench.py +++ b/tests/test_workbench.py @@ -15,8 +15,8 @@ from ereuse_devicehub.resources.action.models import ( from ereuse_devicehub.resources.device.exceptions import NeedsId from ereuse_devicehub.resources.device.models import Device from ereuse_devicehub.resources.tag.model import Tag -from tests.conftest import file, file_workbench, json_encode, yaml2json from tests import conftest +from tests.conftest import file, file_workbench, json_encode, yaml2json @pytest.mark.mvp @@ -60,7 +60,7 @@ def test_workbench_server_condensed(user: UserClient): device, _ = user.get(res=Device, item=db_dev.devicehub_id) assert device['dataStorageSize'] == 1100 assert device['chassis'] == 'Tower' - assert device['hid'] == 'desktop-d1mr-d1ml-d1s-na1-s' + assert device['hid'] == 'desktop-d1mr-d1ml-d1s' assert device['graphicCardModel'] == device['components'][0]['model'] == 'gc1-1ml' assert device['networkSpeeds'] == [1000, 58] assert device['processorModel'] == device['components'][3]['model'] == 'p1-1ml' @@ -147,10 +147,7 @@ def test_real_hp_11(user: UserClient): s = file('real-hp.snapshot.11') snapshot, _ = user.post(res=em.Snapshot, data=s) pc = snapshot['device'] - assert ( - pc['hid'] - == 'desktop-hewlett-packard-hp_compaq_8100_elite_sff-czc0408yjg-6c:62:6d:81:22:9f' - ) + assert pc['hid'] == 'desktop-hewlett-packard-hp_compaq_8100_elite_sff-czc0408yjg' assert pc['chassis'] == 'Tower' assert set(e['type'] for e in snapshot['actions']) == { 'BenchmarkDataStorage', @@ -192,10 +189,7 @@ def test_snapshot_real_eee_1001pxd_with_rate(user: UserClient): assert pc['model'] == '1001pxd' assert pc['serialNumber'] == 'b8oaas048286' assert pc['manufacturer'] == 'asustek computer inc.' - assert ( - pc['hid'] - == 'laptop-asustek_computer_inc-1001pxd-b8oaas048286-14:da:e9:42:f6:7c' - ) + assert pc['hid'] == 'laptop-asustek_computer_inc.-1001pxd-b8oaas048286' assert len(pc['tags']) == 0 assert pc['networkSpeeds'] == [ 100, @@ -209,14 +203,14 @@ def test_snapshot_real_eee_1001pxd_with_rate(user: UserClient): wifi = components[0] assert ( wifi['hid'] == 'networkadapter-qualcomm_atheros-' - 'ar9285_wireless_network_adapter-74_2f_68_8b_fd_c8' + 'ar9285_wireless_network_adapter-74:2f:68:8b:fd:c8' ) assert wifi['serialNumber'] == '74:2f:68:8b:fd:c8' assert wifi['wireless'] eth = components[1] assert ( eth['hid'] == 'networkadapter-qualcomm_atheros-' - 'ar8152_v2_0_fast_ethernet-14_da_e9_42_f6_7c' + 'ar8152_v2.0_fast_ethernet-14:da:e9:42:f6:7c' ) assert eth['speed'] == 100 assert not eth['wireless'] @@ -225,7 +219,7 @@ def test_snapshot_real_eee_1001pxd_with_rate(user: UserClient): assert cpu['cores'] == 1 assert cpu['threads'] == 1 assert cpu['speed'] == 1.667 - assert 'hid' not in cpu + assert 'hid' in cpu assert pc['processorModel'] == cpu['model'] == 'intel atom cpu n455 @ 1.66ghz' db_cpu = Device.query.filter_by(id=cpu['id']).one() cpu, _ = user.get(res=Device, item=db_cpu.devicehub_id) @@ -287,7 +281,7 @@ def test_snapshot_real_eee_1001pxd_with_rate(user: UserClient): assert erase['severity'] == 'Info' assert hdd['privacy']['type'] == 'EraseBasic' mother = components[8] - assert mother['hid'] == 'motherboard-asustek_computer_inc-1001pxd-eee0123456789' + assert mother['hid'] == 'motherboard-asustek_computer_inc.-1001pxd-eee0123456789' @pytest.mark.mvp