Merge remote-tracking branch 'origin/testing' into feature/33-export-lot-description

# Conflicts:
#	ereuse_devicehub/resources/documents/documents.py
#	ereuse_devicehub/resources/lot/views.py
#	tests/test_documents.py
This commit is contained in:
nad 2020-08-18 11:23:50 +02:00
commit 5c7444dc4d
42 changed files with 679 additions and 189 deletions

View File

@ -13,12 +13,13 @@ from teal.teal import Teal
from teal.db import SchemaSQLAlchemy from teal.db import SchemaSQLAlchemy
from ereuse_devicehub.auth import Auth from ereuse_devicehub.auth import Auth
from ereuse_devicehub.client import Client from ereuse_devicehub.client import Client, UserClient
from ereuse_devicehub.config import DevicehubConfig from ereuse_devicehub.config import DevicehubConfig
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
from ereuse_devicehub.dummy.dummy import Dummy from ereuse_devicehub.dummy.dummy import Dummy
from ereuse_devicehub.resources.device.search import DeviceSearch from ereuse_devicehub.resources.device.search import DeviceSearch
from ereuse_devicehub.resources.inventory import Inventory, InventoryDef from ereuse_devicehub.resources.inventory import Inventory, InventoryDef
from ereuse_devicehub.resources.user import User
from ereuse_devicehub.templating import Environment from ereuse_devicehub.templating import Environment
@ -151,3 +152,8 @@ class Devicehub(Teal):
inv = g.inventory = Inventory.current # type: Inventory inv = g.inventory = Inventory.current # type: Inventory
g.tag_provider = DevicehubClient(base_url=inv.tag_provider, g.tag_provider = DevicehubClient(base_url=inv.tag_provider,
token=DevicehubClient.encode_token(inv.tag_token)) token=DevicehubClient.encode_token(inv.tag_token))
def create_client(self, email='user@dhub.com', password='1234'):
client = UserClient(self, email, password, response_wrapper=self.response_class)
client.login()
return client

View File

@ -3,7 +3,7 @@ import uuid
from itertools import filterfalse from itertools import filterfalse
import marshmallow import marshmallow
from flask import current_app as app, render_template, request, Response from flask import g, current_app as app, render_template, request, Response
from flask.json import jsonify from flask.json import jsonify
from flask_sqlalchemy import Pagination from flask_sqlalchemy import Pagination
from marshmallow import fields, fields as f, validate as v, ValidationError, \ from marshmallow import fields, fields as f, validate as v, ValidationError, \
@ -64,7 +64,8 @@ class Filters(query.Query):
# todo This part of the query is really slow # todo This part of the query is really slow
# And forces usage of distinct, as it returns many rows # And forces usage of distinct, as it returns many rows
# due to having multiple paths to the same # due to having multiple paths to the same
lot = query.Join(Device.id == LotDeviceDescendants.device_id, LotQ) lot = query.Join((Device.id == LotDeviceDescendants.device_id),
LotQ)
class Sorting(query.Sort): class Sorting(query.Sort):
@ -153,9 +154,18 @@ class DeviceView(View):
).order_by( ).order_by(
search.Search.rank(properties, search_p) + search.Search.rank(tags, search_p) search.Search.rank(properties, search_p) + search.Search.rank(tags, search_p)
) )
query = self.visibility_filter(query)
return query.filter(*args['filter']).order_by(*args['sort']) return query.filter(*args['filter']).order_by(*args['sort'])
def visibility_filter(self, query):
filterqs = request.args.get('filter', None)
if (filterqs and
'lot' not in filterqs):
query = query.filter((Computer.id == Device.id), (Computer.owner_id == g.user.id))
pass
return query
class DeviceMergeView(View): class DeviceMergeView(View):
"""View for merging two devices """View for merging two devices

View File

@ -23,6 +23,7 @@ from ereuse_devicehub.resources.documents.device_row import DeviceRow
from ereuse_devicehub.resources.lot import LotView from ereuse_devicehub.resources.lot import LotView
from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.lot.models import Lot
from flask import g, request
class Format(enum.Enum): class Format(enum.Enum):
HTML = 'HTML' HTML = 'HTML'
@ -128,7 +129,6 @@ class DevicesDocumentView(DeviceView):
output.headers['Content-type'] = 'text/csv' output.headers['Content-type'] = 'text/csv'
return output return output
class LotsDocumentView(LotView): class LotsDocumentView(LotView):
def find(self, args: dict): def find(self, args: dict):
query = self.query(args) query = self.query(args)
@ -165,12 +165,34 @@ class LotRow(OrderedDict):
self['Description'] = '' self['Description'] = ''
class StockDocumentView(DeviceView):
# @cache(datetime.timedelta(minutes=1))
def find(self, args: dict):
query = self.query(args)
return self.generate_post_csv(query)
def generate_post_csv(self, query):
"""Get device query and put information in csv format."""
data = StringIO()
cw = csv.writer(data)
first = True
for device in query:
d = DeviceRow(device)
if first:
cw.writerow(d.keys())
first = False
cw.writerow(d.values())
output = make_response(data.getvalue())
output.headers['Content-Disposition'] = 'attachment; filename=export.csv'
output.headers['Content-type'] = 'text/csv'
return output
class DocumentDef(Resource): class DocumentDef(Resource):
__type__ = 'Document' __type__ = 'Document'
SCHEMA = None SCHEMA = None
VIEW = None # We do not want to create default / documents endpoint VIEW = None # We do not want to create default / documents endpoint
AUTH = False AUTH = False
def __init__(self, app, def __init__(self, app,
import_name=__name__, import_name=__name__,
static_folder='static', static_folder='static',
@ -187,16 +209,26 @@ class DocumentDef(Resource):
get = {'GET'} get = {'GET'}
view = DocumentView.as_view('main', definition=self, auth=app.auth) view = DocumentView.as_view('main', definition=self, auth=app.auth)
# TODO @cayop This two lines never pass
if self.AUTH: if self.AUTH:
view = app.auth.requires_auth(view) view = app.auth.requires_auth(view)
self.add_url_rule('/erasures/', defaults=d, view_func=view, methods=get) self.add_url_rule('/erasures/', defaults=d, view_func=view, methods=get)
self.add_url_rule('/erasures/<{}:{}>'.format(self.ID_CONVERTER.value, self.ID_NAME), self.add_url_rule('/erasures/<{}:{}>'.format(self.ID_CONVERTER.value, self.ID_NAME),
view_func=view, methods=get) view_func=view, methods=get)
devices_view = DevicesDocumentView.as_view('devicesDocumentView', devices_view = DevicesDocumentView.as_view('devicesDocumentView',
definition=self, definition=self,
auth=app.auth) auth=app.auth)
lots_view = LotsDocumentView.as_view('lotsDocumentView', definition=self)
if self.AUTH:
devices_view = app.auth.requires_auth(devices_view) devices_view = app.auth.requires_auth(devices_view)
self.add_url_rule('/devices/', defaults=d, view_func=devices_view, methods=get) self.add_url_rule('/devices/', defaults=d, view_func=devices_view, methods=get)
lots_view = LotsDocumentView.as_view('lotsDocumentView', definition=self)
lots_view = app.auth.requires_auth(lots_view)
self.add_url_rule('/lots/', defaults=d, view_func=lots_view, methods=get) self.add_url_rule('/lots/', defaults=d, view_func=lots_view, methods=get)
stock_view = StockDocumentView.as_view('stockDocumentView', definition=self, auth=app.auth)
stock_view = app.auth.requires_auth(stock_view)
self.add_url_rule('/stock/', defaults=d, view_func=stock_view, methods=get)

View File

@ -6,16 +6,19 @@ from typing import Dict, List, Set, Union
import marshmallow as ma import marshmallow as ma
import teal.cache import teal.cache
from flask import Response, jsonify, request from flask import Response, jsonify, request, g
from marshmallow import Schema as MarshmallowSchema, fields as f from marshmallow import Schema as MarshmallowSchema, fields as f
from teal.marshmallow import EnumField from teal.marshmallow import EnumField
from teal.resource import View from teal.resource import View
from sqlalchemy import or_
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from ereuse_devicehub import auth
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
from ereuse_devicehub.query import things_response from ereuse_devicehub.query import things_response
from ereuse_devicehub.resources.device.models import Device, Computer from ereuse_devicehub.resources.device.models import Device, Computer
from ereuse_devicehub.resources.lot.models import Lot, Path from ereuse_devicehub.resources.lot.models import Lot, Path
from ereuse_devicehub.resources.deliverynote.models import Deliverynote
class LotFormat(Enum): class LotFormat(Enum):
@ -85,15 +88,23 @@ class LotView(View):
} }
else: else:
query = Lot.query query = Lot.query
query = self.visibility_filter(query)
if args['search']: if args['search']:
query = query.filter(Lot.name.ilike(args['search'] + '%')) query = query.filter(Lot.name.ilike(args['search'] + '%'))
lots = query.paginate(per_page=6 if args['search'] else 30) lots = query.paginate(per_page=6 if args['search'] else 30)
return things_response( return things_response(
self.schema.dump(lots.items, many=True, nested=0), self.schema.dump(lots.items, many=True, nested=2),
lots.page, lots.per_page, lots.total, lots.prev_num, lots.next_num lots.page, lots.per_page, lots.total, lots.prev_num, lots.next_num
) )
return jsonify(ret) return jsonify(ret)
def visibility_filter(self, query):
query = query.outerjoin(Deliverynote) \
.filter(or_(Deliverynote.receiver_address == g.user.email,
Deliverynote.supplier_email == g.user.email,
Lot.owner_id == g.user.id))
return query
def query(self, args): def query(self, args):
query = Lot.query.distinct() query = Lot.query.distinct()
return query return query

View File

@ -66,6 +66,7 @@ class TagDef(Resource):
))) )))
db.session.commit() db.session.commit()
@option('-u', '--owner', help=OWNER_H)
@option('--org', help=ORG_H) @option('--org', help=ORG_H)
@option('--provider', help=PROV_H) @option('--provider', help=PROV_H)
@argument('path', type=cli.Path(writable=True)) @argument('path', type=cli.Path(writable=True))

View File

@ -125,7 +125,11 @@ def file(name: str) -> dict:
def tag_id(app: Devicehub) -> str: def tag_id(app: Devicehub) -> str:
"""Creates a tag and returns its id.""" """Creates a tag and returns its id."""
with app.app_context(): with app.app_context():
t = Tag(id='foo') if User.query.count():
user = User.query.one()
else:
user = create_user()
t = Tag(id='foo', owner_id=user.id)
db.session.add(t) db.session.add(t)
db.session.commit() db.session.commit()
return t.id return t.id

View File

@ -28,24 +28,77 @@ def test_api_docs(client: Client):
"""Tests /apidocs correct initialization.""" """Tests /apidocs correct initialization."""
docs, _ = client.get('/apidocs') docs, _ = client.get('/apidocs')
assert set(docs['paths'].keys()) == { assert set(docs['paths'].keys()) == {
# todo this does not appear: '/tags/{id}/device',
'/apidocs',
'/users/',
'/devices/',
'/tags/',
'/users/login/',
'/actions/', '/actions/',
'/apidocs',
'/batteries/{id}/merge/',
'/bikes/{id}/merge/',
'/cameras/{id}/merge/',
'/cellphones/{id}/merge/',
'/components/{id}/merge/',
'/computer-accessories/{id}/merge/',
'/computer-monitors/{id}/merge/',
'/computers/{id}/merge/',
'/cookings/{id}/merge/',
'/data-storages/{id}/merge/',
'/dehumidifiers/{id}/merge/',
'/deliverynotes/',
'/desktops/{id}/merge/',
'/devices/',
'/devices/static/{filename}',
'/devices/{id}/merge/',
'/displays/{id}/merge/',
'/diy-and-gardenings/{id}/merge/',
'/documents/devices/',
'/documents/erasures/',
'/documents/static/{filename}',
'/documents/stock/',
'/drills/{id}/merge/',
'/graphic-cards/{id}/merge/',
'/hard-drives/{id}/merge/',
'/homes/{id}/merge/',
'/hubs/{id}/merge/',
'/keyboards/{id}/merge/',
'/label-printers/{id}/merge/',
'/laptops/{id}/merge/',
'/lots/', '/lots/',
'/manufacturers/',
'/lots/{id}/children', '/lots/{id}/children',
'/lots/{id}/devices', '/lots/{id}/devices',
'/documents/erasures/', '/manufacturers/',
'/documents/devices/', '/memory-card-readers/{id}/merge/',
'/documents/static/{filename}', '/mice/{id}/merge/',
'/microphones/{id}/merge/',
'/mixers/{id}/merge/',
'/mobiles/{id}/merge/',
'/monitors/{id}/merge/',
'/motherboards/{id}/merge/',
'/network-adapters/{id}/merge/',
'/networkings/{id}/merge/',
'/pack-of-screwdrivers/{id}/merge/',
'/printers/{id}/merge/',
'/processors/{id}/merge/',
'/proofs/',
'/rackets/{id}/merge/',
'/ram-modules/{id}/merge/',
'/recreations/{id}/merge/',
'/routers/{id}/merge/',
'/sais/{id}/merge/',
'/servers/{id}/merge/',
'/smartphones/{id}/merge/',
'/solid-state-drives/{id}/merge/',
'/sound-cards/{id}/merge/',
'/sounds/{id}/merge/',
'/stairs/{id}/merge/',
'/switches/{id}/merge/',
'/tablets/{id}/merge/',
'/tags/',
'/tags/{tag_id}/device/{device_id}', '/tags/{tag_id}/device/{device_id}',
'/devices/static/{filename}', '/television-sets/{id}/merge/',
'/deliverynotes/', '/users/',
'/proofs/' '/users/login/',
'/video-scalers/{id}/merge/',
'/videoconferences/{id}/merge/',
'/videos/{id}/merge/',
'/wireless-access-points/{id}/merge/'
} }
assert docs['info'] == {'title': 'Devicehub', 'version': '0.2'} assert docs['info'] == {'title': 'Devicehub', 'version': '0.2'}
assert docs['components']['securitySchemes']['bearerAuth'] == { assert docs['components']['securitySchemes']['bearerAuth'] == {

View File

@ -256,16 +256,17 @@ def test_sync_execute_register_desktop_existing_no_tag():
@pytest.mark.mvp @pytest.mark.mvp
@pytest.mark.usefixtures(conftest.app_context.__name__) @pytest.mark.usefixtures(conftest.app_context.__name__)
def test_sync_execute_register_desktop_no_hid_no_tag(): def test_sync_execute_register_desktop_no_hid_no_tag(user: UserClient):
"""Syncs a d.Desktop without HID and no tag. """Syncs a d.Desktop without HID and no tag.
This should not fail as we don't have a way to identify it.
This should fail as we don't have a way to identify it.
""" """
pc = d.Desktop(**conftest.file('pc-components.db')['device']) device = conftest.file('pc-components.db')['device']
device['owner_id'] = user.user['id']
pc = d.Desktop(**device)
# 1: device has no HID # 1: device has no HID
pc.hid = pc.model = None pc.hid = pc.model = None
with pytest.raises(NeedsId): returned_pc = Sync().execute_register(pc)
Sync().execute_register(pc) assert returned_pc == pc
@pytest.mark.mvp @pytest.mark.mvp
@ -391,14 +392,14 @@ def test_sync_execute_register_mismatch_between_tags_and_hid():
@pytest.mark.mvp @pytest.mark.mvp
@pytest.mark.xfail(reason='It needs to be fixed.')
def test_get_device(app: Devicehub, user: UserClient): def test_get_device(app: Devicehub, user: UserClient):
"""Checks GETting a d.Desktop with its components.""" """Checks GETting a d.Desktop with its components."""
with app.app_context(): with app.app_context():
pc = d.Desktop(model='p1mo', pc = d.Desktop(model='p1mo',
manufacturer='p1ma', manufacturer='p1ma',
serial_number='p1s', serial_number='p1s',
chassis=ComputerChassis.Tower) chassis=ComputerChassis.Tower,
owner_id=user.user['id'])
pc.components = OrderedSet([ pc.components = OrderedSet([
d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'), d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'),
d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500) d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
@ -428,14 +429,14 @@ def test_get_device(app: Devicehub, user: UserClient):
@pytest.mark.mvp @pytest.mark.mvp
@pytest.mark.xfail(reason='It needs to be fixed.')
def test_get_devices(app: Devicehub, user: UserClient): def test_get_devices(app: Devicehub, user: UserClient):
"""Checks GETting multiple devices.""" """Checks GETting multiple devices."""
with app.app_context(): with app.app_context():
pc = d.Desktop(model='p1mo', pc = d.Desktop(model='p1mo',
manufacturer='p1ma', manufacturer='p1ma',
serial_number='p1s', serial_number='p1s',
chassis=ComputerChassis.Tower) chassis=ComputerChassis.Tower,
owner_id=user.user['id'])
pc.components = OrderedSet([ pc.components = OrderedSet([
d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'), d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'),
d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500) d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
@ -443,11 +444,13 @@ def test_get_devices(app: Devicehub, user: UserClient):
pc1 = d.Desktop(model='p2mo', pc1 = d.Desktop(model='p2mo',
manufacturer='p2ma', manufacturer='p2ma',
serial_number='p2s', serial_number='p2s',
chassis=ComputerChassis.Tower) chassis=ComputerChassis.Tower,
owner_id=user.user['id'])
pc2 = d.Laptop(model='p3mo', pc2 = d.Laptop(model='p3mo',
manufacturer='p3ma', manufacturer='p3ma',
serial_number='p3s', serial_number='p3s',
chassis=ComputerChassis.Netbook) chassis=ComputerChassis.Netbook,
owner_id=user.user['id'])
db.session.add_all((pc, pc1, pc2)) db.session.add_all((pc, pc1, pc2))
db.session.commit() db.session.commit()
devices, _ = user.get(res=d.Device) devices, _ = user.get(res=d.Device)

View File

@ -19,7 +19,7 @@ def test_erasure_certificate_public_one(user: UserClient, client: Client):
s = file('erase-sectors.snapshot') s = file('erase-sectors.snapshot')
snapshot, _ = user.post(s, res=Snapshot) snapshot, _ = user.post(s, res=Snapshot)
doc, response = client.get(res=documents.DocumentDef.t, doc, response = user.get(res=documents.DocumentDef.t,
item='erasures/{}'.format(snapshot['device']['id']), item='erasures/{}'.format(snapshot['device']['id']),
accept=ANY) accept=ANY)
assert 'html' in response.content_type assert 'html' in response.content_type
@ -146,7 +146,7 @@ def test_export_empty(user: UserClient):
assert len(export_csv) == 0, 'Csv is not empty' assert len(export_csv) == 0, 'Csv is not empty'
@pytest.mark.mvp @pytest.mark.xfail(reason='Feature not developed (Beta)')
def test_export_computer_monitor(user: UserClient): def test_export_computer_monitor(user: UserClient):
"""Test a export device type computer monitor.""" """Test a export device type computer monitor."""
snapshot, _ = user.post(file('computer-monitor.snapshot'), res=Snapshot) snapshot, _ = user.post(file('computer-monitor.snapshot'), res=Snapshot)
@ -171,6 +171,7 @@ def test_export_computer_monitor(user: UserClient):
assert fixture_csv[1] == export_csv[1], 'Component information are not equal' assert fixture_csv[1] == export_csv[1], 'Component information are not equal'
@pytest.mark.xfail(reason='Feature not developed (Beta)')
def test_export_keyboard(user: UserClient): def test_export_keyboard(user: UserClient):
"""Test a export device type keyboard.""" """Test a export device type keyboard."""
snapshot, _ = user.post(file('keyboard.snapshot'), res=Snapshot) snapshot, _ = user.post(file('keyboard.snapshot'), res=Snapshot)
@ -194,7 +195,7 @@ def test_export_keyboard(user: UserClient):
assert fixture_csv[1] == export_csv[1], 'Component information are not equal' assert fixture_csv[1] == export_csv[1], 'Component information are not equal'
@pytest.mark.mvp @pytest.mark.xfail(reason='Feature not developed (Beta)')
def test_export_multiple_different_devices(user: UserClient): def test_export_multiple_different_devices(user: UserClient):
"""Test function 'Export' of multiple different device types (like """Test function 'Export' of multiple different device types (like
computers, keyboards, monitors, etc..) computers, keyboards, monitors, etc..)

View File

@ -351,7 +351,6 @@ def test_lot_post_add_children_view_ui_tree_normal(user: UserClient):
@pytest.mark.mvp @pytest.mark.mvp
@pytest.mark.xfail(reason='It needs to be fixed.')
def test_lot_post_add_remove_device_view(app: Devicehub, user: UserClient): def test_lot_post_add_remove_device_view(app: Devicehub, user: UserClient):
"""Tests adding a device to a lot using POST and """Tests adding a device to a lot using POST and
removing it with DELETE. removing it with DELETE.
@ -361,7 +360,8 @@ def test_lot_post_add_remove_device_view(app: Devicehub, user: UserClient):
device = Desktop(serial_number='foo', device = Desktop(serial_number='foo',
model='bar', model='bar',
manufacturer='foobar', manufacturer='foobar',
chassis=ComputerChassis.Lunchbox) chassis=ComputerChassis.Lunchbox,
owner_id=user.user['id'])
db.session.add(device) db.session.add(device)
db.session.commit() db.session.commit()
device_id = device.id device_id = device.id

View File

@ -5,14 +5,15 @@ from uuid import uuid4
import pytest import pytest
from boltons import urlutils from boltons import urlutils
from teal.db import UniqueViolation from teal.db import UniqueViolation, DBError
from teal.marshmallow import ValidationError from teal.marshmallow import ValidationError
from ereuse_devicehub.client import UserClient from ereuse_devicehub.client import UserClient
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
from ereuse_devicehub.devicehub import Devicehub from ereuse_devicehub.devicehub import Devicehub
from ereuse_devicehub.resources.action.models import Action, BenchmarkDataStorage, \ from ereuse_devicehub.resources.action.models import Action, BenchmarkDataStorage, \
BenchmarkProcessor, EraseSectors, RateComputer, Snapshot, SnapshotRequest, VisualTest BenchmarkProcessor, EraseSectors, RateComputer, Snapshot, SnapshotRequest, VisualTest, \
EreusePrice
from ereuse_devicehub.resources.device import models as m from ereuse_devicehub.resources.device import models as m
from ereuse_devicehub.resources.device.exceptions import NeedsId from ereuse_devicehub.resources.device.exceptions import NeedsId
from ereuse_devicehub.resources.device.models import SolidStateDrive from ereuse_devicehub.resources.device.models import SolidStateDrive
@ -67,7 +68,6 @@ def test_snapshot_post(user: UserClient):
"""Tests the post snapshot endpoint (validation, etc), data correctness, """Tests the post snapshot endpoint (validation, etc), data correctness,
and relationship correctness. and relationship correctness.
""" """
# TODO add all action_types to check, how to add correctly??
snapshot = snapshot_and_check(user, file('basic.snapshot'), snapshot = snapshot_and_check(user, file('basic.snapshot'),
action_types=( action_types=(
BenchmarkProcessor.t, BenchmarkProcessor.t,
@ -99,7 +99,6 @@ def test_snapshot_post(user: UserClient):
@pytest.mark.mvp @pytest.mark.mvp
@pytest.mark.xfail(reason='Needs to fix it')
def test_snapshot_component_add_remove(user: UserClient): def test_snapshot_component_add_remove(user: UserClient):
"""Tests adding and removing components and some don't generate HID. """Tests adding and removing components and some don't generate HID.
All computers generate HID. All computers generate HID.
@ -120,7 +119,8 @@ def test_snapshot_component_add_remove(user: UserClient):
s1 = file('1-device-with-components.snapshot') s1 = file('1-device-with-components.snapshot')
snapshot1 = snapshot_and_check(user, snapshot1 = snapshot_and_check(user,
s1, s1,
action_types=(BenchmarkProcessor.t,), action_types=(BenchmarkProcessor.t,
RateComputer.t),
perform_second_snapshot=False) perform_second_snapshot=False)
pc1_id = snapshot1['device']['id'] pc1_id = snapshot1['device']['id']
pc1, _ = user.get(res=m.Device, item=pc1_id) pc1, _ = user.get(res=m.Device, item=pc1_id)
@ -128,12 +128,12 @@ def test_snapshot_component_add_remove(user: UserClient):
assert tuple(c['serialNumber'] for c in pc1['components']) == ('p1c1s', 'p1c2s', 'p1c3s') assert tuple(c['serialNumber'] for c in pc1['components']) == ('p1c1s', 'p1c2s', 'p1c3s')
# Components contain parent # Components contain parent
assert all(c['parent'] == pc1_id for c in pc1['components']) assert all(c['parent'] == pc1_id for c in pc1['components'])
# pc has two actions: Snapshot and the BenchmarkProcessor # pc has three actions: Snapshot, BenchmarkProcessor and RateComputer
assert len(pc1['actions']) == 2 assert len(pc1['actions']) == 3
assert pc1['actions'][1]['type'] == Snapshot.t assert pc1['actions'][1]['type'] == Snapshot.t
# p1c1s has Snapshot # p1c1s has Snapshot
p1c1s, _ = user.get(res=m.Device, item=pc1['components'][0]['id']) p1c1s, _ = user.get(res=m.Device, item=pc1['components'][0]['id'])
assert tuple(e['type'] for e in p1c1s['actions']) == ('Snapshot',) assert tuple(e['type'] for e in p1c1s['actions']) == ('Snapshot', 'RateComputer')
# We register a new device # We register a new device
# It has the processor of the first one (p1c2s) # It has the processor of the first one (p1c2s)
@ -141,7 +141,7 @@ def test_snapshot_component_add_remove(user: UserClient):
# Actions PC1: Snapshot, Remove. PC2: Snapshot # Actions PC1: Snapshot, Remove. PC2: Snapshot
s2 = file('2-second-device-with-components-of-first.snapshot') s2 = file('2-second-device-with-components-of-first.snapshot')
# num_actions = 2 = Remove, Add # num_actions = 2 = Remove, Add
snapshot2 = snapshot_and_check(user, s2, action_types=('Remove',), snapshot2 = snapshot_and_check(user, s2, action_types=('Remove', 'RateComputer'),
perform_second_snapshot=False) perform_second_snapshot=False)
pc2_id = snapshot2['device']['id'] pc2_id = snapshot2['device']['id']
pc1, _ = user.get(res=m.Device, item=pc1_id) pc1, _ = user.get(res=m.Device, item=pc1_id)
@ -149,15 +149,15 @@ def test_snapshot_component_add_remove(user: UserClient):
# PC1 # PC1
assert tuple(c['serialNumber'] for c in pc1['components']) == ('p1c1s', 'p1c3s') assert tuple(c['serialNumber'] for c in pc1['components']) == ('p1c1s', 'p1c3s')
assert all(c['parent'] == pc1_id for c in pc1['components']) assert all(c['parent'] == pc1_id for c in pc1['components'])
assert tuple(e['type'] for e in pc1['actions']) == ('BenchmarkProcessor', 'Snapshot', 'Remove') assert tuple(e['type'] for e in pc1['actions']) == ('BenchmarkProcessor', 'Snapshot', 'RateComputer', 'Remove')
# PC2 # PC2
assert tuple(c['serialNumber'] for c in pc2['components']) == ('p1c2s', 'p2c1s') assert tuple(c['serialNumber'] for c in pc2['components']) == ('p1c2s', 'p2c1s')
assert all(c['parent'] == pc2_id for c in pc2['components']) assert all(c['parent'] == pc2_id for c in pc2['components'])
assert tuple(e['type'] for e in pc2['actions']) == ('Snapshot',) assert tuple(e['type'] for e in pc2['actions']) == ('Snapshot', 'RateComputer')
# p1c2s has two Snapshots, a Remove and an Add # p1c2s has two Snapshots, a Remove and an Add
p1c2s, _ = user.get(res=m.Device, item=pc2['components'][0]['id']) p1c2s, _ = user.get(res=m.Device, item=pc2['components'][0]['id'])
assert tuple(e['type'] for e in p1c2s['actions']) == ( assert tuple(e['type'] for e in p1c2s['actions']) == (
'BenchmarkProcessor', 'Snapshot', 'Snapshot', 'Remove' 'BenchmarkProcessor', 'Snapshot', 'RateComputer', 'Snapshot', 'Remove', 'RateComputer'
) )
# We register the first device again, but removing motherboard # We register the first device again, but removing motherboard
@ -165,7 +165,7 @@ def test_snapshot_component_add_remove(user: UserClient):
# We have created 1 Remove (from PC2's processor back to PC1) # We have created 1 Remove (from PC2's processor back to PC1)
# PC 0: p1c2s, p1c3s. PC 1: p2c1s # PC 0: p1c2s, p1c3s. PC 1: p2c1s
s3 = file('3-first-device-but-removing-motherboard-and-adding-processor-from-2.snapshot') s3 = file('3-first-device-but-removing-motherboard-and-adding-processor-from-2.snapshot')
snapshot_and_check(user, s3, ('Remove',), perform_second_snapshot=False) snapshot_and_check(user, s3, ('Remove', 'RateComputer'), perform_second_snapshot=False)
pc1, _ = user.get(res=m.Device, item=pc1_id) pc1, _ = user.get(res=m.Device, item=pc1_id)
pc2, _ = user.get(res=m.Device, item=pc2_id) pc2, _ = user.get(res=m.Device, item=pc2_id)
# PC1 # PC1
@ -175,14 +175,17 @@ def test_snapshot_component_add_remove(user: UserClient):
# id, type, components, snapshot # id, type, components, snapshot
('BenchmarkProcessor', []), # first BenchmarkProcessor ('BenchmarkProcessor', []), # first BenchmarkProcessor
('Snapshot', ['p1c1s', 'p1c2s', 'p1c3s']), # first Snapshot1 ('Snapshot', ['p1c1s', 'p1c2s', 'p1c3s']), # first Snapshot1
('RateComputer', ['p1c1s', 'p1c2s', 'p1c3s']),
('Remove', ['p1c2s']), # Remove Processor in Snapshot2 ('Remove', ['p1c2s']), # Remove Processor in Snapshot2
('Snapshot', ['p1c2s', 'p1c3s']) # This Snapshot3 ('Snapshot', ['p1c2s', 'p1c3s']), # This Snapshot3
('RateComputer', ['p1c2s', 'p1c3s'])
) )
# PC2 # PC2
assert tuple(c['serialNumber'] for c in pc2['components']) == ('p2c1s',) assert tuple(c['serialNumber'] for c in pc2['components']) == ('p2c1s',)
assert all(c['parent'] == pc2_id for c in pc2['components']) assert all(c['parent'] == pc2_id for c in pc2['components'])
assert tuple(e['type'] for e in pc2['actions']) == ( assert tuple(e['type'] for e in pc2['actions']) == (
'Snapshot', # Second Snapshot 'Snapshot', # Second Snapshot
'RateComputer',
'Remove' # the processor we added in 2. 'Remove' # the processor we added in 2.
) )
# p1c2s has Snapshot, Remove and Add # p1c2s has Snapshot, Remove and Add
@ -190,72 +193,45 @@ def test_snapshot_component_add_remove(user: UserClient):
assert tuple(get_actions_info(p1c2s['actions'])) == ( assert tuple(get_actions_info(p1c2s['actions'])) == (
('BenchmarkProcessor', []), # first BenchmarkProcessor ('BenchmarkProcessor', []), # first BenchmarkProcessor
('Snapshot', ['p1c1s', 'p1c2s', 'p1c3s']), # First Snapshot to PC1 ('Snapshot', ['p1c1s', 'p1c2s', 'p1c3s']), # First Snapshot to PC1
('RateComputer', ['p1c1s', 'p1c2s', 'p1c3s']),
('Snapshot', ['p1c2s', 'p2c1s']), # Second Snapshot to PC2 ('Snapshot', ['p1c2s', 'p2c1s']), # Second Snapshot to PC2
('Remove', ['p1c2s']), # ...which caused p1c2s to be removed form PC1 ('Remove', ['p1c2s']), # ...which caused p1c2s to be removed form PC1
('RateComputer', ['p1c2s', 'p2c1s']),
('Snapshot', ['p1c2s', 'p1c3s']), # The third Snapshot to PC1 ('Snapshot', ['p1c2s', 'p1c3s']), # The third Snapshot to PC1
('Remove', ['p1c2s']) # ...which caused p1c2 to be removed from PC2 ('Remove', ['p1c2s']), # ...which caused p1c2 to be removed from PC2
('RateComputer', ['p1c2s', 'p1c3s'])
) )
# We register the first device but without the processor, # We register the first device but without the processor,
# adding a graphic card and adding a new component # adding a graphic card and adding a new component
s4 = file('4-first-device-but-removing-processor.snapshot-and-adding-graphic-card') s4 = file('4-first-device-but-removing-processor.snapshot-and-adding-graphic-card')
snapshot_and_check(user, s4, perform_second_snapshot=False) snapshot_and_check(user, s4, ('RateComputer',), perform_second_snapshot=False)
pc1, _ = user.get(res=m.Device, item=pc1_id) pc1, _ = user.get(res=m.Device, item=pc1_id)
pc2, _ = user.get(res=m.Device, item=pc2_id) pc2, _ = user.get(res=m.Device, item=pc2_id)
# PC 0: p1c3s, p1c4s. PC1: p2c1s # PC 0: p1c3s, p1c4s. PC1: p2c1s
assert {c['serialNumber'] for c in pc1['components']} == {'p1c3s', 'p1c4s'} assert {c['serialNumber'] for c in pc1['components']} == {'p1c3s', 'p1c4s'}
assert all(c['parent'] == pc1_id for c in pc1['components']) assert all(c['parent'] == pc1_id for c in pc1['components'])
# This last Snapshot only # This last Action only
assert get_actions_info(pc1['actions'])[-1] == ('Snapshot', ['p1c3s', 'p1c4s']) assert get_actions_info(pc1['actions'])[-1] == ('RateComputer', ['p1c3s', 'p1c4s'])
# PC2 # PC2
# We haven't changed PC2 # We haven't changed PC2
assert tuple(c['serialNumber'] for c in pc2['components']) == ('p2c1s',) assert tuple(c['serialNumber'] for c in pc2['components']) == ('p2c1s',)
assert all(c['parent'] == pc2_id for c in pc2['components']) assert all(c['parent'] == pc2_id for c in pc2['components'])
def _test_snapshot_computer_no_hid(user: UserClient):
"""Tests inserting a computer that doesn't generate a HID, neither
some of its components.
"""
# PC with 2 components. PC doesn't have HID and neither 1st component
s = file('basic.snapshot')
del s['device']['model']
del s['components'][0]['model']
user.post(s, res=Snapshot, status=NeedsId)
# The system tells us that it could not register the device because
# the device (computer) cannot generate a HID.
# In such case we need to specify an ``id`` so the system can
# recognize the device. The ``id`` can reference to the same
# device, it already existed in the DB, or to a placeholder,
# if the device is new in the DB.
user.post(s, res=m.Device)
s['device']['id'] = 1 # Assign the ID of the placeholder
user.post(s, res=Snapshot)
@pytest.mark.mvp @pytest.mark.mvp
@pytest.mark.xfail(reason='Needs to fix it')
def test_snapshot_post_without_hid(user: UserClient): def test_snapshot_post_without_hid(user: UserClient):
"""Tests the post snapshot endpoint (validation, etc), data correctness, """Tests the post snapshot endpoint (validation, etc), data correctness,
and relationship correctness with HID field generated with type - model - manufacturer - S/N. and relationship correctness with HID field generated with type - model - manufacturer - S/N.
""" """
snapshot = snapshot_and_check(user, file('basic.snapshot.nohid'), snapshot_no_hid = file('basic.snapshot.nohid')
action_types=( response_snapshot, response_status = user.post(res=Snapshot, data=snapshot_no_hid)
BenchmarkProcessor.t, assert response_snapshot['software'] == 'Workbench'
VisualTest.t, assert response_snapshot['version'] == '11.0b9'
RateComputer.t assert response_snapshot['uuid'] == '9a3e7485-fdd0-47ce-bcc7-65c55226b598'
), assert response_snapshot['elapsed'] == 4
perform_second_snapshot=False) assert response_snapshot['author']['id'] == user.user['id']
assert snapshot['software'] == 'Workbench' assert response_snapshot['severity'] == 'Warning'
assert snapshot['version'] == '11.0b9' assert response_status.status_code == 201
assert snapshot['uuid'] == '9a3e7485-fdd0-47ce-bcc7-65c55226b598'
assert snapshot['elapsed'] == 4
assert snapshot['author']['id'] == user.user['id']
assert 'actions' not in snapshot['device']
assert 'author' not in snapshot['device']
assert snapshot['severity'] == 'Warning'
response = user.post(snapshot, res=Snapshot)
assert response.status == 201
@pytest.mark.mvp @pytest.mark.mvp
@ -267,7 +243,7 @@ def test_snapshot_mismatch_id():
@pytest.mark.mvp @pytest.mark.mvp
def test_snapshot_tag_inner_tag(tag_id: str, user: UserClient, app: Devicehub): def test_snapshot_tag_inner_tag(user: UserClient, tag_id: str, app: Devicehub):
"""Tests a posting Snapshot with a local tag.""" """Tests a posting Snapshot with a local tag."""
b = file('basic.snapshot') b = file('basic.snapshot')
b['device']['tags'] = [{'type': 'Tag', 'id': tag_id}] b['device']['tags'] = [{'type': 'Tag', 'id': tag_id}]
@ -336,7 +312,6 @@ def test_snapshot_component_containing_components(user: UserClient):
@pytest.mark.mvp @pytest.mark.mvp
@pytest.mark.xfail(reason='It needs to be fixed.')
def test_erase_privacy_standards_endtime_sort(user: UserClient): def test_erase_privacy_standards_endtime_sort(user: UserClient):
"""Tests a Snapshot with EraseSectors and the resulting privacy """Tests a Snapshot with EraseSectors and the resulting privacy
properties. properties.
@ -349,7 +324,9 @@ def test_erase_privacy_standards_endtime_sort(user: UserClient):
snapshot = snapshot_and_check(user, s, action_types=( snapshot = snapshot_and_check(user, s, action_types=(
EraseSectors.t, EraseSectors.t,
BenchmarkDataStorage.t, BenchmarkDataStorage.t,
BenchmarkProcessor.t BenchmarkProcessor.t,
RateComputer.t,
EreusePrice.t
), perform_second_snapshot=False) ), perform_second_snapshot=False)
# Perform a new snapshot changing the erasure time, as if # Perform a new snapshot changing the erasure time, as if
# it is a new erasure performed after. # it is a new erasure performed after.
@ -360,7 +337,9 @@ def test_erase_privacy_standards_endtime_sort(user: UserClient):
snapshot = snapshot_and_check(user, s, action_types=( snapshot = snapshot_and_check(user, s, action_types=(
EraseSectors.t, EraseSectors.t,
BenchmarkDataStorage.t, BenchmarkDataStorage.t,
BenchmarkProcessor.t BenchmarkProcessor.t,
RateComputer.t,
EreusePrice.t
), perform_second_snapshot=False) ), perform_second_snapshot=False)
# The actual test # The actual test
@ -368,7 +347,7 @@ def test_erase_privacy_standards_endtime_sort(user: UserClient):
storage, _ = user.get(res=m.Device, item=storage['id']) # Let's get storage actions too storage, _ = user.get(res=m.Device, item=storage['id']) # Let's get storage actions too
# order: endTime ascending # order: endTime ascending
# erasure1/2 have an user defined time and others actions endTime = created # erasure1/2 have an user defined time and others actions endTime = created
erasure1, erasure2, benchmark_hdd1, _snapshot1, benchmark_hdd2, _snapshot2 = storage['actions'] erasure1, erasure2, benchmark_hdd1, _snapshot1, _, _, benchmark_hdd2, _snapshot2 = storage['actions'][:8]
assert erasure1['type'] == erasure2['type'] == 'EraseSectors' assert erasure1['type'] == erasure2['type'] == 'EraseSectors'
assert benchmark_hdd1['type'] == benchmark_hdd2['type'] == 'BenchmarkDataStorage' assert benchmark_hdd1['type'] == benchmark_hdd2['type'] == 'BenchmarkDataStorage'
assert _snapshot1['type'] == _snapshot2['type'] == 'Snapshot' assert _snapshot1['type'] == _snapshot2['type'] == 'Snapshot'

View File

@ -5,7 +5,7 @@ import requests_mock
from boltons.urlutils import URL from boltons.urlutils import URL
from ereuse_utils.session import DevicehubClient from ereuse_utils.session import DevicehubClient
from pytest import raises from pytest import raises
from teal.db import MultipleResourcesFound, ResourceNotFound, UniqueViolation from teal.db import MultipleResourcesFound, ResourceNotFound, UniqueViolation, DBError
from teal.marshmallow import ValidationError from teal.marshmallow import ValidationError
from ereuse_devicehub.client import UserClient from ereuse_devicehub.client import UserClient
@ -24,10 +24,10 @@ from tests.conftest import file
@pytest.mark.mvp @pytest.mark.mvp
@pytest.mark.usefixtures(conftest.app_context.__name__) @pytest.mark.usefixtures(conftest.app_context.__name__)
def test_create_tag(): def test_create_tag(user: UserClient):
"""Creates a tag specifying a custom organization.""" """Creates a tag specifying a custom organization."""
org = Organization(name='bar', tax_id='bartax') org = Organization(name='bar', tax_id='bartax')
tag = Tag(id='bar-1', org=org, provider=URL('http://foo.bar')) tag = Tag(id='bar-1', org=org, provider=URL('http://foo.bar'), owner_id=user.user['id'])
db.session.add(tag) db.session.add(tag)
db.session.commit() db.session.commit()
tag = Tag.query.one() tag = Tag.query.one()
@ -37,9 +37,9 @@ def test_create_tag():
@pytest.mark.mvp @pytest.mark.mvp
@pytest.mark.usefixtures(conftest.app_context.__name__) @pytest.mark.usefixtures(conftest.app_context.__name__)
def test_create_tag_default_org(): def test_create_tag_default_org(user: UserClient):
"""Creates a tag using the default organization.""" """Creates a tag using the default organization."""
tag = Tag(id='foo-1') tag = Tag(id='foo-1', owner_id=user.user['id'])
assert not tag.org_id, 'org-id is set as default value so it should only load on flush' assert not tag.org_id, 'org-id is set as default value so it should only load on flush'
# We don't want the organization to load, or it would make this # We don't want the organization to load, or it would make this
# object, from transient to new (added to session) # object, from transient to new (added to session)
@ -62,17 +62,19 @@ def test_create_tag_no_slash():
@pytest.mark.mvp @pytest.mark.mvp
@pytest.mark.usefixtures(conftest.app_context.__name__) @pytest.mark.usefixtures(conftest.app_context.__name__)
def test_create_two_same_tags(): def test_create_two_same_tags(user: UserClient):
"""Ensures there cannot be two tags with the same ID and organization.""" """Ensures there cannot be two tags with the same ID and organization."""
db.session.add(Tag(id='foo-bar'))
db.session.add(Tag(id='foo-bar')) db.session.add(Tag(id='foo-bar', owner_id=user.user['id']))
with raises(UniqueViolation): db.session.add(Tag(id='foo-bar', owner_id=user.user['id']))
with raises(DBError):
db.session.commit() db.session.commit()
db.session.rollback() db.session.rollback()
# And it works if tags are in different organizations # And it works if tags are in different organizations
db.session.add(Tag(id='foo-bar')) db.session.add(Tag(id='foo-bar', owner_id=user.user['id']))
org2 = Organization(name='org 2', tax_id='tax id org 2') org2 = Organization(name='org 2', tax_id='tax id org 2')
db.session.add(Tag(id='foo-bar', org=org2)) db.session.add(Tag(id='foo-bar', org=org2, owner_id=user.user['id']))
db.session.commit() db.session.commit()
@ -104,7 +106,7 @@ def test_tag_get_device_from_tag_endpoint(app: Devicehub, user: UserClient):
"""Checks getting a linked device from a tag endpoint""" """Checks getting a linked device from a tag endpoint"""
with app.app_context(): with app.app_context():
# Create a pc with a tag # Create a pc with a tag
tag = Tag(id='foo-bar') tag = Tag(id='foo-bar', owner_id=user.user['id'])
pc = Desktop(serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id']) pc = Desktop(serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id'])
pc.tags.add(tag) pc.tags.add(tag)
db.session.add(pc) db.session.add(pc)
@ -117,7 +119,7 @@ def test_tag_get_device_from_tag_endpoint(app: Devicehub, user: UserClient):
def test_tag_get_device_from_tag_endpoint_no_linked(app: Devicehub, user: UserClient): def test_tag_get_device_from_tag_endpoint_no_linked(app: Devicehub, user: UserClient):
"""As above, but when the tag is not linked.""" """As above, but when the tag is not linked."""
with app.app_context(): with app.app_context():
db.session.add(Tag(id='foo-bar')) db.session.add(Tag(id='foo-bar', owner_id=user.user['id']))
db.session.commit() db.session.commit()
user.get(res=Tag, item='foo-bar/device', status=TagNotLinked) user.get(res=Tag, item='foo-bar/device', status=TagNotLinked)
@ -135,9 +137,9 @@ def test_tag_get_device_from_tag_endpoint_multiple_tags(app: Devicehub, user: Us
it should raise an exception. it should raise an exception.
""" """
with app.app_context(): with app.app_context():
db.session.add(Tag(id='foo-bar')) db.session.add(Tag(id='foo-bar', owner_id=user.user['id']))
org2 = Organization(name='org 2', tax_id='tax id org 2') org2 = Organization(name='org 2', tax_id='tax id org 2')
db.session.add(Tag(id='foo-bar', org=org2)) db.session.add(Tag(id='foo-bar', org=org2, owner_id=user.user['id']))
db.session.commit() db.session.commit()
user.get(res=Tag, item='foo-bar/device', status=MultipleResourcesFound) user.get(res=Tag, item='foo-bar/device', status=MultipleResourcesFound)
@ -145,8 +147,9 @@ def test_tag_get_device_from_tag_endpoint_multiple_tags(app: Devicehub, user: Us
@pytest.mark.mvp @pytest.mark.mvp
def test_tag_create_tags_cli(app: Devicehub, user: UserClient): def test_tag_create_tags_cli(app: Devicehub, user: UserClient):
"""Checks creating tags with the CLI endpoint.""" """Checks creating tags with the CLI endpoint."""
owner_id = user.user['id']
runner = app.test_cli_runner() runner = app.test_cli_runner()
runner.invoke('tag', 'add', 'id1') runner.invoke('tag', 'add', 'id1', '-u', owner_id)
with app.app_context(): with app.app_context():
tag = Tag.query.one() # type: Tag tag = Tag.query.one() # type: Tag
assert tag.id == 'id1' assert tag.id == 'id1'
@ -157,8 +160,10 @@ def test_tag_create_tags_cli(app: Devicehub, user: UserClient):
def test_tag_create_etags_cli(app: Devicehub, user: UserClient): def test_tag_create_etags_cli(app: Devicehub, user: UserClient):
"""Creates an eTag through the CLI.""" """Creates an eTag through the CLI."""
# todo what happens to organization? # todo what happens to organization?
owner_id = user.user['id']
runner = app.test_cli_runner() runner = app.test_cli_runner()
runner.invoke('tag', 'add', '-p', 'https://t.ereuse.org', '-s', 'foo', 'DT-BARBAR') args = ('tag', 'add', '-p', 'https://t.ereuse.org', '-s', 'foo', 'DT-BARBAR', '-u', owner_id)
runner.invoke(*args)
with app.app_context(): with app.app_context():
tag = Tag.query.one() # type: Tag tag = Tag.query.one() # type: Tag
assert tag.id == 'dt-barbar' assert tag.id == 'dt-barbar'
@ -173,7 +178,7 @@ def test_tag_manual_link_search(app: Devicehub, user: UserClient):
Checks search has the term. Checks search has the term.
""" """
with app.app_context(): with app.app_context():
db.session.add(Tag('foo-bar', secondary='foo-sec')) db.session.add(Tag('foo-bar', secondary='foo-sec', owner_id=user.user['id']))
desktop = Desktop(serial_number='foo', chassis=ComputerChassis.AllInOne, owner_id=user.user['id']) desktop = Desktop(serial_number='foo', chassis=ComputerChassis.AllInOne, owner_id=user.user['id'])
db.session.add(desktop) db.session.add(desktop)
db.session.commit() db.session.commit()
@ -208,7 +213,7 @@ def test_tag_secondary_workbench_link_find(user: UserClient):
"""Creates and consumes tags with a secondary id, linking them """Creates and consumes tags with a secondary id, linking them
through Workbench to a device through Workbench to a device
and getting them through search.""" and getting them through search."""
t = Tag('foo', secondary='bar') t = Tag('foo', secondary='bar', owner_id=user.user['id'])
db.session.add(t) db.session.add(t)
db.session.flush() db.session.flush()
assert Tag.from_an_id('bar').one() == t assert Tag.from_an_id('bar').one() == t
@ -232,9 +237,10 @@ def test_tag_secondary_workbench_link_find(user: UserClient):
@pytest.mark.mvp @pytest.mark.mvp
def test_tag_create_tags_cli_csv(app: Devicehub, user: UserClient): def test_tag_create_tags_cli_csv(app: Devicehub, user: UserClient):
"""Checks creating tags with the CLI endpoint using a CSV.""" """Checks creating tags with the CLI endpoint using a CSV."""
owner_id = user.user['id']
csv = pathlib.Path(__file__).parent / 'files' / 'tags-cli.csv' csv = pathlib.Path(__file__).parent / 'files' / 'tags-cli.csv'
runner = app.test_cli_runner() runner = app.test_cli_runner()
runner.invoke('tag', 'add-csv', str(csv)) runner.invoke('tag', 'add-csv', str(csv), '-u', owner_id)
with app.app_context(): with app.app_context():
t1 = Tag.from_an_id('id1').one() t1 = Tag.from_an_id('id1').one()
t2 = Tag.from_an_id('sec1').one() t2 = Tag.from_an_id('sec1').one()
@ -277,7 +283,7 @@ def test_get_tags_endpoint(user: UserClient, app: Devicehub,
# Prepare test # Prepare test
with app.app_context(): with app.app_context():
org = Organization(name='bar', tax_id='bartax') org = Organization(name='bar', tax_id='bartax')
tag = Tag(id='bar-1', org=org, provider=URL('http://foo.bar')) tag = Tag(id='bar-1', org=org, provider=URL('http://foo.bar'), owner_id=user.user['id'])
db.session.add(tag) db.session.add(tag)
db.session.commit() db.session.commit()
assert not tag.printable assert not tag.printable

View File

@ -66,7 +66,6 @@ def test_workbench_server_condensed(user: UserClient):
assert device['tags'][0]['id'] == 'tag1' assert device['tags'][0]['id'] == 'tag1'
@pytest.mark.mvp
@pytest.mark.xfail(reason='Functionality not yet developed.') @pytest.mark.xfail(reason='Functionality not yet developed.')
def test_workbench_server_phases(user: UserClient): def test_workbench_server_phases(user: UserClient):
"""Tests the phases described in the docs section `Snapshots from """Tests the phases described in the docs section `Snapshots from
@ -274,7 +273,7 @@ def test_snapshot_real_eee_1001pxd_with_rate(user: UserClient):
@pytest.mark.mvp @pytest.mark.mvp
def test_real_custom(user: UserClient): def test_real_custom(user: UserClient):
s = file('real-custom.snapshot.11') s = file('real-custom.snapshot.11')
snapshot, _ = user.post(res=em.Snapshot, data=s, status=NeedsId) snapshot, _ = user.post(res=em.Snapshot, data=s, status=201)
# todo insert with tag # todo insert with tag
@ -302,7 +301,7 @@ SNAPSHOTS_NEED_ID = {
"""Snapshots that do not generate HID requiring a custom ID.""" """Snapshots that do not generate HID requiring a custom ID."""
@pytest.mark.xfail(reason='It needs to be fixed.') @pytest.mark.mvp
@pytest.mark.parametrize('file', @pytest.mark.parametrize('file',
(pytest.param(f, id=f.name) (pytest.param(f, id=f.name)
for f in pathlib.Path(__file__).parent.joinpath('workbench_files').iterdir()) for f in pathlib.Path(__file__).parent.joinpath('workbench_files').iterdir())
@ -315,7 +314,7 @@ def test_workbench_fixtures(file: pathlib.Path, user: UserClient):
s = json.load(file.open()) s = json.load(file.open())
user.post(res=em.Snapshot, user.post(res=em.Snapshot,
data=s, data=s,
status=201 if file.name not in SNAPSHOTS_NEED_ID else NeedsId) status=201)
@pytest.mark.mvp @pytest.mark.mvp

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Atom CPU N270 @ 1.60GHz", "model": "Intel Atom CPU N270 @ 1.60GHz",
@ -40,7 +46,14 @@
"interface": "SDRAM" "interface": "SDRAM"
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": null, "manufacturer": null,
"model": "TS32GSSD370S", "model": "TS32GSSD370S",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Atom CPU N455 @ 1.66GHz", "model": "Intel Atom CPU N455 @ 1.66GHz",
@ -42,7 +48,14 @@
"speed": 667.0 "speed": 667.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Hitachi", "manufacturer": "Hitachi",
"model": "HTS54322", "model": "HTS54322",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Xeon CPU E5520 @ 2.27GHz", "model": "Intel Xeon CPU E5520 @ 2.27GHz",
@ -97,7 +103,14 @@
"speed": 1066.0 "speed": 1066.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Western Digital", "manufacturer": "Western Digital",
"model": "WDC WDS120G1G0A-", "model": "WDC WDS120G1G0A-",
@ -107,7 +120,14 @@
"variant": "1000" "variant": "1000"
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Seagate", "manufacturer": "Seagate",
"model": "ST160LM000 HM161", "model": "ST160LM000 HM161",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core2 Duo CPU E8400 @ 3.00GHz", "model": "Intel Core2 Duo CPU E8400 @ 3.00GHz",
@ -53,7 +59,14 @@
"speed": 1067.0 "speed": 1067.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Seagate", "manufacturer": "Seagate",
"model": "ST3250318AS", "model": "ST3250318AS",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core2 Duo CPU E8400 @ 3.00GHz", "model": "Intel Core2 Duo CPU E8400 @ 3.00GHz",
@ -42,7 +48,14 @@
"speed": 800.0 "speed": 800.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Seagate", "manufacturer": "Seagate",
"model": "ST3160815AS", "model": "ST3160815AS",
@ -52,7 +65,14 @@
"variant": "H" "variant": "H"
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Western Digital", "manufacturer": "Western Digital",
"model": "WDC WD3200AAJS-0", "model": "WDC WD3200AAJS-0",
@ -62,7 +82,14 @@
"variant": "1B02" "variant": "1B02"
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Western Digital", "manufacturer": "Western Digital",
"model": "WDC WD5000AAKX-6", "model": "WDC WD5000AAKX-6",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i3 CPU 530 @ 2.93GHz", "model": "Intel Core i3 CPU 530 @ 2.93GHz",
@ -75,7 +81,14 @@
"speed": 1333.0 "speed": 1333.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Western Digital", "manufacturer": "Western Digital",
"model": "WDC WD3200AAJS-6", "model": "WDC WD3200AAJS-6",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i5-6200U CPU @ 2.30GHz", "model": "Intel Core i5-6200U CPU @ 2.30GHz",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core2 Duo CPU T6400 @ 2.00GHz", "model": "Intel Core2 Duo CPU T6400 @ 2.00GHz",
@ -31,7 +37,14 @@
"generation": null "generation": null
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Western Digital", "manufacturer": "Western Digital",
"model": "WDC WD5000BEVT-2", "model": "WDC WD5000BEVT-2",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i5-4440 CPU @ 3.10GHz", "model": "Intel Core i5-4440 CPU @ 3.10GHz",
@ -42,7 +48,14 @@
"speed": 1600.0 "speed": 1600.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Western Digital", "manufacturer": "Western Digital",
"model": "WDC WD5000AAKX-0", "model": "WDC WD5000AAKX-0",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i5-4440 CPU @ 3.10GHz", "model": "Intel Core i5-4440 CPU @ 3.10GHz",
@ -42,7 +48,14 @@
"speed": 1600.0 "speed": 1600.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Western Digital", "manufacturer": "Western Digital",
"model": "WDC WD5000AAKX-0", "model": "WDC WD5000AAKX-0",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Celeron CPU J3455 @ 1.50GHz", "model": "Intel Celeron CPU J3455 @ 1.50GHz",
@ -42,7 +48,14 @@
"speed": 1600.0 "speed": 1600.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": null, "manufacturer": null,
"model": "KINGSTON SA400S3", "model": "KINGSTON SA400S3",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core2 CPU 6600 @ 2.40GHz", "model": "Intel Core2 CPU 6600 @ 2.40GHz",
@ -41,7 +47,14 @@
"speed": 667.0 "speed": 667.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": null, "manufacturer": null,
"model": "SAMSUNG HD250HJ", "model": "SAMSUNG HD250HJ",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i5-4440 CPU @ 3.10GHz", "model": "Intel Core i5-4440 CPU @ 3.10GHz",
@ -42,7 +48,14 @@
"speed": 1600.0 "speed": 1600.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Western Digital", "manufacturer": "Western Digital",
"model": "WDC WD5000AAKX-0", "model": "WDC WD5000AAKX-0",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i7-4600M CPU @ 2.90GHz", "model": "Intel Core i7-4600M CPU @ 2.90GHz",
@ -53,7 +59,14 @@
"speed": 1600.0 "speed": 1600.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": null, "manufacturer": null,
"model": "Crucial_CT525MX3", "model": "Crucial_CT525MX3",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i5-3340M CPU @ 2.70GHz", "model": "Intel Core i5-3340M CPU @ 2.70GHz",
@ -53,7 +59,14 @@
"speed": 1600.0 "speed": 1600.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": null, "manufacturer": null,
"model": "HGST HTS725050A7", "model": "HGST HTS725050A7",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core2 CPU 6600 @ 2.40GHz", "model": "Intel Core2 CPU 6600 @ 2.40GHz",
@ -63,7 +69,14 @@
"speed": 533.0 "speed": 533.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": null, "manufacturer": null,
"model": "SAMSUNG HD250HJ", "model": "SAMSUNG HD250HJ",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i5-4440 CPU @ 3.10GHz", "model": "Intel Core i5-4440 CPU @ 3.10GHz",
@ -42,7 +48,14 @@
"speed": 1600.0 "speed": 1600.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Western Digital", "manufacturer": "Western Digital",
"model": "WDC WD5000AAKX-6", "model": "WDC WD5000AAKX-6",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Pentium M processor 1.60GHz", "model": "Intel Pentium M processor 1.60GHz",
@ -50,7 +56,14 @@
"interface": "DDR" "interface": "DDR"
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Fujitsu", "manufacturer": "Fujitsu",
"model": "MHT2080A", "model": "MHT2080A",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core2 Duo CPU E8400 @ 3.00GHz", "model": "Intel Core2 Duo CPU E8400 @ 3.00GHz",
@ -53,7 +59,14 @@
"speed": 1067.0 "speed": 1067.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": null, "manufacturer": null,
"model": "SAMSUNG HD251HJ", "model": "SAMSUNG HD251HJ",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Pentium CPU G645 @ 2.90GHz", "model": "Intel Pentium CPU G645 @ 2.90GHz",
@ -42,7 +48,14 @@
"speed": 1333.0 "speed": 1333.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Seagate", "manufacturer": "Seagate",
"model": "ST250DM000-1BD14", "model": "ST250DM000-1BD14",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core2 Duo CPU E8400 @ 3.00GHz", "model": "Intel Core2 Duo CPU E8400 @ 3.00GHz",
@ -53,7 +59,14 @@
"speed": 667.0 "speed": 667.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Hitachi", "manufacturer": "Hitachi",
"model": "HDT72103", "model": "HDT72103",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i3-2100 CPU @ 3.10GHz", "model": "Intel Core i3-2100 CPU @ 3.10GHz",
@ -42,7 +48,14 @@
"speed": 1333.0 "speed": 1333.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Seagate", "manufacturer": "Seagate",
"model": "ST3500413AS", "model": "ST3500413AS",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core2 CPU 6400 @ 2.13GHz", "model": "Intel Core2 CPU 6400 @ 2.13GHz",
@ -53,7 +59,14 @@
"speed": 667.0 "speed": 667.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Western Digital", "manufacturer": "Western Digital",
"model": "WDC WD3200AAKS-7", "model": "WDC WD3200AAKS-7",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Pentium 4 CPU 3.00GHz", "model": "Intel Pentium 4 CPU 3.00GHz",
@ -52,7 +58,14 @@
"speed": 533.0 "speed": 533.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Seagate", "manufacturer": "Seagate",
"model": "ST3808110AS", "model": "ST3808110AS",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i5-7200U CPU @ 2.50GHz", "model": "Intel Core i5-7200U CPU @ 2.50GHz",
@ -42,7 +48,14 @@
"speed": 2133.0 "speed": 2133.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": null, "manufacturer": null,
"model": "SAMSUNG MZNTY256", "model": "SAMSUNG MZNTY256",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i3 CPU 530 @ 2.93GHz", "model": "Intel Core i3 CPU 530 @ 2.93GHz",
@ -75,7 +81,14 @@
"speed": 1333.0 "speed": 1333.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": null, "manufacturer": null,
"model": "KINGSTON SA400S3", "model": "KINGSTON SA400S3",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i5 CPU M 560 @ 2.67GHz", "model": "Intel Core i5 CPU M 560 @ 2.67GHz",
@ -41,7 +47,14 @@
"speed": 1067.0 "speed": 1067.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Hitachi", "manufacturer": "Hitachi",
"model": "HTS54505", "model": "HTS54505",

View File

@ -8,7 +8,7 @@
"elapsed": 0, "elapsed": 0,
"device": { "device": {
"actions": [], "actions": [],
"type": "Computer", "type": "Desktop",
"manufacturer": "innotek GmbH", "manufacturer": "innotek GmbH",
"model": "VirtualBox", "model": "VirtualBox",
"serialNumber": "0", "serialNumber": "0",
@ -18,7 +18,14 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 126.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": null, "manufacturer": null,
"model": "VBOX HARDDISK", "model": "VBOX HARDDISK",

View File

@ -18,7 +18,13 @@
}, },
"components": [ "components": [
{ {
"actions": [], "actions": [
{
"type": "BenchmarkProcessor",
"rate": 11969.98,
"elapsed": 0
}
],
"type": "Processor", "type": "Processor",
"manufacturer": "Intel Corp.", "manufacturer": "Intel Corp.",
"model": "Intel Core i3-2120 CPU @ 3.30GHz", "model": "Intel Core i3-2120 CPU @ 3.30GHz",
@ -53,7 +59,14 @@
"speed": 1333.0 "speed": 1333.0
}, },
{ {
"actions": [], "actions": [
{
"elapsed": 13,
"readSpeed": 106.0,
"writeSpeed": 26.6,
"type": "BenchmarkDataStorage"
}
],
"type": "HardDrive", "type": "HardDrive",
"manufacturer": "Seagate", "manufacturer": "Seagate",
"model": "ST500DM002-1BD14", "model": "ST500DM002-1BD14",