This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
devicehub-teal/tests/test_device.py

228 lines
8.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import timedelta
from uuid import UUID
import pytest
from ereuse_devicehub.client import UserClient
from ereuse_devicehub.db import db
from ereuse_devicehub.devicehub import Devicehub
from ereuse_devicehub.resources.device.exceptions import NeedsId
from ereuse_devicehub.resources.device.models import Component, Computer, Desktop, Device, \
GraphicCard, Laptop, Microtower, Motherboard, NetworkAdapter
from ereuse_devicehub.resources.device.schemas import Device as DeviceS
from ereuse_devicehub.resources.device.sync import Sync
from ereuse_devicehub.resources.event.models import Remove, Test
from ereuse_devicehub.resources.user import User
from teal.db import ResourceNotFound
from tests.conftest import file
@pytest.mark.usefixtures('app_context')
def test_device_model():
"""
Tests that the correctness of the device model and its relationships.
"""
pc = Desktop(model='p1mo', manufacturer='p1ma', serial_number='p1s')
pc.components = components = [
NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'),
GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
]
db.session.add(pc)
db.session.commit()
pc = Desktop.query.one()
assert pc.serial_number == 'p1s'
assert pc.components == components
network_adapter = NetworkAdapter.query.one()
assert network_adapter.parent == pc
# Removing a component from pc doesn't delete the component
del pc.components[0]
db.session.commit()
pc = Device.query.first() # this is the same as querying for Desktop directly
assert pc.components[0].type == GraphicCard.__name__
network_adapter = NetworkAdapter.query.one()
assert network_adapter not in pc.components
assert network_adapter.parent is None
# Deleting the pc deletes everything
gcard = GraphicCard.query.one()
db.session.delete(pc)
assert pc.id == 1
assert Desktop.query.first() is None
db.session.commit()
assert Desktop.query.first() is None
assert network_adapter.id == 2
assert NetworkAdapter.query.first() is not None, 'We removed the network adaptor'
assert gcard.id == 3, 'We should still hold a reference to a zombie graphic card'
assert GraphicCard.query.first() is None, 'We should have deleted it it was inside the pc'
@pytest.mark.usefixtures('app_context')
def test_device_schema():
"""Ensures the user does not upload non-writable or extra fields."""
device_s = DeviceS()
device_s.load({'serialNumber': 'foo1', 'model': 'foo', 'manufacturer': 'bar2'})
device_s.dump(Device(id=1))
@pytest.mark.usefixtures('app_context')
def test_physical_properties():
c = Motherboard(slots=2,
usb=3,
serial_number='sn',
model='ml',
manufacturer='mr',
width=2.0,
pid='abc')
pc = Computer(components=[c])
db.session.add(pc)
db.session.commit()
assert c.physical_properties == {
'gid': None,
'usb': 3,
'pid': 'abc',
'serial_number': 'sn',
'pcmcia': None,
'model': 'ml',
'slots': 2,
'serial': None,
'firewire': None,
'manufacturer': 'mr',
'weight': None,
'height': None,
'width': 2.0
}
@pytest.mark.usefixtures('app_context')
def test_component_similar_one():
snapshot = file('pc-components.db')
d = snapshot['device']
snapshot['components'][0]['serial_number'] = snapshot['components'][1]['serial_number'] = None
pc = Computer(**d, components=[Component(**c) for c in snapshot['components']])
component1, component2 = pc.components # type: Component
db.session.add(pc)
# Let's create a new component named 'A' similar to 1
componentA = Component(model=component1.model, manufacturer=component1.manufacturer)
similar_to_a = componentA.similar_one(pc, set())
assert similar_to_a == component1
# Component B does not have the same model
componentB = 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.usefixtures('auth_app_context')
def test_add_remove():
# Original state:
# pc has c1 and c2
# pc2 has c3
# c4 is not with any pc
values = file('pc-components.db')
pc = values['device']
c1, c2 = [Component(**c) for c in values['components']]
pc = Computer(**pc, components=[c1, c2])
db.session.add(pc)
c3 = Component(serial_number='nc1')
pc2 = Computer(serial_number='s2', components=[c3])
c4 = Component(serial_number='c4s')
db.session.add(pc2)
db.session.add(c4)
db.session.commit()
# Test:
# pc has only c3
events = Sync.add_remove(device=pc, components={c3, c4})
db.session.add_all(events)
db.session.commit() # We enforce the appliance of order_by
assert len(events) == 1
assert isinstance(events[0], Remove)
assert events[0].device == pc2
assert events[0].components == [c3]
@pytest.mark.usefixtures('app_context')
def test_execute_register_computer():
# Case 1: device does not exist on DB
pc = Computer(**file('pc-components.db')['device'])
db_pc, _ = Sync.execute_register(pc, set())
assert pc.physical_properties == db_pc.physical_properties
@pytest.mark.usefixtures('app_context')
def test_execute_register_computer_existing():
pc = Computer(**file('pc-components.db')['device'])
db.session.add(pc)
db.session.commit() # We need two separate sessions
pc = Computer(**file('pc-components.db')['device'])
# 1: device exists on DB
db_pc, _ = Sync.execute_register(pc, set())
assert pc.physical_properties == db_pc.physical_properties
@pytest.mark.usefixtures('app_context')
def test_execute_register_computer_no_hid():
pc = Computer(**file('pc-components.db')['device'])
# 1: device has no HID
pc.hid = pc.model = None
with pytest.raises(NeedsId):
Sync.execute_register(pc, set())
# 2: device has no HID and we force it
db_pc, _ = Sync.execute_register(pc, set(), force_creation=True)
assert pc.physical_properties == db_pc.physical_properties
def test_get_device(app: Devicehub, user: UserClient):
"""Checks GETting a Desktop with its components."""
with app.app_context():
pc = Desktop(model='p1mo', manufacturer='p1ma', serial_number='p1s')
pc.components = [
NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'),
GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
]
db.session.add(pc)
db.session.add(Test(device=pc,
elapsed=timedelta(seconds=4),
success=True,
author=User(email='bar@bar.com')))
db.session.commit()
pc, _ = user.get(res=Device, item=1)
assert len(pc['events']) == 1
assert pc['events'][0]['type'] == 'Test'
assert pc['events'][0]['id'] == 1
assert pc['events'][0]['device'] == 1
assert pc['events'][0]['elapsed'] == 4
assert pc['events'][0]['success'] == True
assert UUID(pc['events'][0]['author'])
assert 'events_components' not in pc, 'events_components are internal use only'
assert 'events_one' not in pc, 'they are internal use only'
assert 'author' not in pc
assert tuple(c['id'] for c in pc['components']) == (2, 3)
assert pc['hid'] == 'p1ma-p1s-p1mo'
assert pc['model'] == 'p1mo'
assert pc['manufacturer'] == 'p1ma'
assert pc['serialNumber'] == 'p1s'
assert pc['type'] == 'Desktop'
def test_get_devices(app: Devicehub, user: UserClient):
"""Checks GETting multiple devices."""
with app.app_context():
pc = Desktop(model='p1mo', manufacturer='p1ma', serial_number='p1s')
pc.components = [
NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'),
GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
]
pc1 = Microtower(model='p2mo', manufacturer='p2ma', serial_number='p2s')
pc2 = Laptop(model='p3mo', manufacturer='p3ma', serial_number='p3s')
db.session.add_all((pc, pc1, pc2))
db.session.commit()
devices, _ = user.get(res=Device)
assert tuple(d['id'] for d in devices) == (1, 2, 3, 4, 5)
assert tuple(d['type'] for d in devices) == ('Desktop', 'Microtower',
'Laptop', 'NetworkAdapter', 'GraphicCard')