refactor score to new rate version structure
This commit is contained in:
parent
75e1817e9c
commit
880b5e706e
|
@ -39,6 +39,7 @@ class DevicehubConfig(Config):
|
|||
}
|
||||
API_DOC_CLASS_DISCRIMINATOR = 'type'
|
||||
|
||||
# TODO is necessary??
|
||||
WORKBENCH_RATE_VERSION = StrictVersion('1.0')
|
||||
PHOTOBOX_RATE_VERSION = StrictVersion('1.0')
|
||||
"""
|
||||
|
|
|
@ -175,10 +175,10 @@ class Device(Thing):
|
|||
|
||||
@property
|
||||
def rate(self):
|
||||
"""The last AggregateRate of the device."""
|
||||
"""The last Rate of the device."""
|
||||
with suppress(LookupError, ValueError):
|
||||
from ereuse_devicehub.resources.event.models import AggregateRate
|
||||
return self.last_event_of(AggregateRate)
|
||||
from ereuse_devicehub.resources.event.models import Rate
|
||||
return self.last_event_of(Rate)
|
||||
|
||||
@property
|
||||
def price(self):
|
||||
|
@ -756,32 +756,3 @@ class Manufacturer(db.Model):
|
|||
'COPY common.manufacturer FROM STDIN (FORMAT csv)',
|
||||
f
|
||||
)
|
||||
|
||||
|
||||
class Battery(Component):
|
||||
"""
|
||||
Battery component, mobile device
|
||||
"""
|
||||
size = Column(Float(decimal_return_scale=2))
|
||||
size.comment = 'Battery size; Units: 2000 mAh'
|
||||
voltage = Column()
|
||||
voltage.comment = 'Battery voltage; Units: 3,5 V'
|
||||
technology = Column()
|
||||
technology.comment = 'Battery technology used; Ex: Li-Ti'
|
||||
charge_counter = Column()
|
||||
charge_counter.comment = 'Number of time that battery has been charged'
|
||||
wireless = Column(Boolean, nullable=False, default=False)
|
||||
wireless.comment = 'If battery can charging wireless'
|
||||
health = Column(DBEnum)
|
||||
health.comment = 'Battery health indicator'
|
||||
status = Column(DBEnum)
|
||||
status.comment = 'Battery status indicator'
|
||||
|
||||
|
||||
class Camera(Component):
|
||||
"""
|
||||
Component camera in mobile devices
|
||||
"""
|
||||
|
||||
resolution = Column(Float(decimal_return_scale=2))
|
||||
resolution.comment = 'Camera resolution; Units: Megapixels'
|
||||
|
|
|
@ -73,7 +73,7 @@ class Device(Thing):
|
|||
pass
|
||||
|
||||
@property
|
||||
def rate(self) -> Optional[e.AggregateRate]:
|
||||
def rate(self) -> Optional[e.Rate]:
|
||||
pass
|
||||
|
||||
@property
|
||||
|
|
|
@ -37,7 +37,7 @@ class Device(Thing):
|
|||
many=True,
|
||||
dump_only=True,
|
||||
description='The lots where this device is directly under.')
|
||||
rate = NestedOn('AggregateRate', dump_only=True, description=m.Device.rate.__doc__)
|
||||
rate = NestedOn('Rate', dump_only=True, description=m.Device.rate.__doc__)
|
||||
price = NestedOn('Price', dump_only=True, description=m.Device.price.__doc__)
|
||||
trading = EnumField(states.Trading, dump_only=True, description=m.Device.trading.__doc__)
|
||||
physical = EnumField(states.Physical, dump_only=True, description=m.Device.physical.__doc__)
|
||||
|
|
|
@ -70,7 +70,7 @@ class AggregateRatingVersions(Enum):
|
|||
v1 = StrictVersion('1.0')
|
||||
"""
|
||||
This version is set to aggregate :class:`ereuse_devicehub.resources.
|
||||
event.models.WorkbenchRate` version X and :class:`ereuse_devicehub.
|
||||
event.models.RateComputer` version X and :class:`ereuse_devicehub.
|
||||
resources.event.models.PhotoboxRate` version Y.
|
||||
"""
|
||||
|
||||
|
@ -89,9 +89,6 @@ class AppearanceRange(Enum):
|
|||
E = 'E. Is unacceptable; severity visual damage, missing essential parts'
|
||||
NONE = 'NA. Grade doesn’t exists'
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
APPEARANCE_RANGE = 0.5, -0.3
|
||||
|
||||
|
@ -105,8 +102,6 @@ class FunctionalityRange(Enum):
|
|||
D = 'D. Chassis severity usage problems. All buttons, screen or camera don\'t work; broken or unusable it'
|
||||
NONE = 'NA. Grade doesn’t exists'
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
FUNCTIONALITY_RANGE = -0.3, 0.4
|
||||
|
@ -122,8 +117,6 @@ class BatteryHealthRange(Enum):
|
|||
E = 'E. Battery health is very bad; and status is dead; unusable or miss it '
|
||||
NONE = 'NA. Grade doesn’t exists'
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
@unique
|
||||
|
@ -135,9 +128,6 @@ class BiosAccessRange(Enum):
|
|||
D = 'D. Like B or C, but you had to unlock the BIOS (i.e. by removing the battery)'
|
||||
E = 'E. The device could not be booted through the network.'
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
@unique
|
||||
class Orientation(Enum):
|
||||
|
|
|
@ -84,7 +84,59 @@ class BenchmarkRamSysbenchDef(BenchmarkWithRateDef):
|
|||
SCHEMA = schemas.BenchmarkRamSysbench
|
||||
|
||||
|
||||
# TODO add test defs
|
||||
class TestDef(EventDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.Test
|
||||
|
||||
|
||||
class TestDataStorageDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.TestDataStorage
|
||||
|
||||
|
||||
class StressTestDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.StressTest
|
||||
|
||||
|
||||
class TestAudioDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.TestAudio
|
||||
|
||||
|
||||
class TestConnectivityDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.TestConnectivity
|
||||
|
||||
|
||||
class TestBatteryDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.TestBattery
|
||||
|
||||
|
||||
class TestCameraDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.TestCamera
|
||||
|
||||
|
||||
class TestKeyboardDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.TestKeyboard
|
||||
|
||||
|
||||
class TestTrackpadDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.TestTrackpad
|
||||
|
||||
|
||||
class TestBiosDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.TestBios
|
||||
|
||||
|
||||
class TestVisualDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.TestVisual
|
||||
|
||||
|
||||
class RateDef(EventDef):
|
||||
|
@ -126,21 +178,6 @@ class SnapshotDef(EventDef):
|
|||
self.sync = Sync()
|
||||
|
||||
|
||||
class TestDef(EventDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.Test
|
||||
|
||||
|
||||
class TestDataStorageDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.TestDataStorage
|
||||
|
||||
|
||||
class StressTestDef(TestDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.StressTest
|
||||
|
||||
|
||||
class ToRepairDef(EventDef):
|
||||
VIEW = None
|
||||
SCHEMA = schemas.ToRepair
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
"""
|
||||
This file contains all events can apply to a device and is sorted according to a structure based on:
|
||||
|
||||
* Generic Events
|
||||
* Benchmarks
|
||||
* Tests
|
||||
* Rates
|
||||
* Prices
|
||||
|
||||
Within the above general classes are subclasses in A order.
|
||||
"""
|
||||
|
||||
from collections import Iterable
|
||||
from datetime import datetime, timedelta
|
||||
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_UP
|
||||
|
@ -571,6 +583,13 @@ class Benchmark(JoinedWithOneDeviceMixin, EventWithOneDevice):
|
|||
return args
|
||||
|
||||
|
||||
class BenchmarkMixin:
|
||||
# noinspection PyMethodParameters
|
||||
@declared_attr
|
||||
def id(cls):
|
||||
return Column(UUID(as_uuid=True), ForeignKey(Test.id), primary_key=True)
|
||||
|
||||
|
||||
class BenchmarkDataStorage(Benchmark):
|
||||
"""Benchmarks the data storage unit reading and writing speeds."""
|
||||
id = Column(UUID(as_uuid=True), ForeignKey(Benchmark.id), primary_key=True)
|
||||
|
@ -607,6 +626,9 @@ class BenchmarkProcessorSysbench(BenchmarkProcessor):
|
|||
|
||||
|
||||
class BenchmarkRamSysbench(BenchmarkWithRate):
|
||||
"""Benchmarks a RAM by using the ram benchmarking
|
||||
utility of `sysbench <https://github.com/akopytov/sysbench>`_.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
@ -621,7 +643,6 @@ class Test(JoinedWithOneDeviceMixin, EventWithOneDevice):
|
|||
Testing errors and warnings are easily taken in
|
||||
:attr:`ereuse_devicehub.resources.device.models.Device.working`.
|
||||
"""
|
||||
elapsed = Column(Interval, nullable=False)
|
||||
|
||||
@declared_attr
|
||||
def __mapper_args__(cls):
|
||||
|
@ -638,7 +659,14 @@ class Test(JoinedWithOneDeviceMixin, EventWithOneDevice):
|
|||
return args
|
||||
|
||||
|
||||
class TestDataStorage(Test):
|
||||
class TestMixin:
|
||||
# noinspection PyMethodParameters
|
||||
@declared_attr
|
||||
def id(cls):
|
||||
return Column(UUID(as_uuid=True), ForeignKey(Test.id), primary_key=True)
|
||||
|
||||
|
||||
class TestDataStorage(TestMixin, Test):
|
||||
"""
|
||||
The act of testing the data storage.
|
||||
|
||||
|
@ -650,7 +678,6 @@ class TestDataStorage(Test):
|
|||
The test takes to other SMART values indicators of the overall health
|
||||
of the data storage.
|
||||
"""
|
||||
id = Column(UUID(as_uuid=True), ForeignKey(Test.id), primary_key=True)
|
||||
length = Column(DBEnum(TestDataStorageLength), nullable=False) # todo from type
|
||||
status = Column(Unicode(), check_lower('status'), nullable=False)
|
||||
lifetime = Column(Interval)
|
||||
|
@ -662,6 +689,7 @@ class TestDataStorage(Test):
|
|||
current_pending_sector_count = Column(SmallInteger)
|
||||
offline_uncorrectable = Column(SmallInteger)
|
||||
remaining_lifetime_percentage = Column(SmallInteger)
|
||||
elapsed = Column(Interval, nullable=False)
|
||||
|
||||
def __init__(self, **kwargs) -> None:
|
||||
super().__init__(**kwargs)
|
||||
|
@ -686,11 +714,12 @@ class TestDataStorage(Test):
|
|||
return t
|
||||
|
||||
|
||||
class StressTest(Test):
|
||||
class StressTest(TestMixin, Test):
|
||||
"""The act of stressing (putting to the maximum capacity)
|
||||
a device for an amount of minutes. If the device is not in great
|
||||
condition won't probably survive such test.
|
||||
"""
|
||||
elapsed = Column(Interval, nullable=False)
|
||||
|
||||
@validates('elapsed')
|
||||
def is_minute_and_bigger_than_1_minute(self, _, value: timedelta):
|
||||
|
@ -703,7 +732,7 @@ class StressTest(Test):
|
|||
return '{}. Computing for {}'.format(self.severity, self.elapsed)
|
||||
|
||||
|
||||
class TestAudio(Test):
|
||||
class TestAudio(TestMixin, Test):
|
||||
"""
|
||||
Test to check all this aspects related with audio functions, Manual Tests??
|
||||
"""
|
||||
|
@ -713,7 +742,7 @@ class TestAudio(Test):
|
|||
microphone.comment = 'This evaluate if microphone works correctly'
|
||||
|
||||
|
||||
class TestConnectivity(Test):
|
||||
class TestConnectivity(TestMixin, Test):
|
||||
"""
|
||||
Test to check all this aspects related with functionality connections in devices
|
||||
"""
|
||||
|
@ -724,18 +753,18 @@ class TestConnectivity(Test):
|
|||
wifi.comment = 'Evaluate if wifi connection works correctly'
|
||||
bluetooth = Column(Boolean)
|
||||
bluetooth.comment = 'Evaluate if bluetooth works'
|
||||
usb_port = Column(Boolean())
|
||||
usb_port = Column(Boolean)
|
||||
usb_port.comment = 'Evaluate if usb port was detected and charger plug works'
|
||||
locked = Column(Boolean)
|
||||
locked.comment = 'Test to check if devices is locked'
|
||||
|
||||
|
||||
class TestBattery(Test):
|
||||
class TestBattery(TestMixin, Test):
|
||||
"""
|
||||
Test battery health, status and length of charge. Minimum X minutes discharging the device
|
||||
"""
|
||||
# TODO how to determinate if test PASS depend on battery stat and/or health
|
||||
battery_stat = Column(Boolean())
|
||||
battery_stat = Column(Boolean)
|
||||
battery_stat.comment = """
|
||||
Some batteries can report a self-check life status.
|
||||
"""
|
||||
|
@ -743,7 +772,7 @@ class TestBattery(Test):
|
|||
battery_health.comment = BatteryHealthRange.__doc__
|
||||
|
||||
|
||||
class TestCamera(Test):
|
||||
class TestCamera(TestMixin, Test):
|
||||
"""
|
||||
Test to determinate functionality and defects on camera when take pictures or record video
|
||||
# TODO define when test FAIL
|
||||
|
@ -752,39 +781,38 @@ class TestCamera(Test):
|
|||
camera.comment = ""
|
||||
|
||||
|
||||
class TestKeyboard(Test):
|
||||
class TestKeyboard(TestMixin, Test):
|
||||
"""
|
||||
Test to determinate if keyboard layout are and works correctly
|
||||
# TODO define when test FAIL
|
||||
"""
|
||||
keyboard = Column(Boolean)
|
||||
keyboard.comment = ""
|
||||
|
||||
|
||||
class TestTrackpad(Test):
|
||||
"""Test trackpad works correctly"""
|
||||
class TestTrackpad(TestMixin, Test):
|
||||
"""
|
||||
Test trackpad works correctly
|
||||
# TODO define when test FAIL
|
||||
"""
|
||||
trackpad = Column(Boolean)
|
||||
trackpad.comment = ""
|
||||
|
||||
|
||||
class TestBios(Test):
|
||||
class TestBios(TestMixin, Test):
|
||||
"""
|
||||
Test that determinate motherboard no beeps, codes or errors when power on
|
||||
Test that determinate motherboard no beeps, codes or errors when power on.
|
||||
And a grade to reflect some possibles difficult to access or modify setting in the BIOS, like password protection..
|
||||
"""
|
||||
bios_power_on = Column(Boolean())
|
||||
bios_power_on = Column(Boolean)
|
||||
bios_power_on.comment = """
|
||||
Motherboards do a self check when powering up (R2 p.23), test PASS if no beeps, codes, or errors appears.
|
||||
"""
|
||||
|
||||
|
||||
class TestBiosDifficulty:
|
||||
"""
|
||||
Test to determinate a grade to reflect some possibles difficult to access or modify setting in the BIOS, like password protection..
|
||||
"""
|
||||
bios_access_range = Column(DBEnum(BiosAccessRange))
|
||||
bios_access_range.comment = 'Range of difficult to access BIOS'
|
||||
|
||||
|
||||
class TestVisual(Test):
|
||||
class TestVisual(TestMixin, Test):
|
||||
"""
|
||||
Manual rate test its are represented with grade and focuses mainly on
|
||||
the aesthetic or cosmetic defects of important parts of a device.
|
||||
|
@ -849,8 +877,7 @@ class Rate(JoinedWithOneDeviceMixin, EventWithOneDevice):
|
|||
"""
|
||||
The act of compute general computer rate
|
||||
"""
|
||||
from ereuse_devicehub.resources.event.rate.workbench.v1_0 import rate_algorithm
|
||||
return rate_algorithm.compute(device)
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class RateComputer(Rate):
|
||||
|
@ -886,6 +913,14 @@ class RateComputer(Rate):
|
|||
if self.processor:
|
||||
return RatingRange.from_score(self.processor)
|
||||
|
||||
@classmethod
|
||||
def compute(cls, device) -> 'RateComputer':
|
||||
"""
|
||||
The act of compute general computer rate
|
||||
"""
|
||||
from ereuse_devicehub.resources.event.rate.workbench.v1_0 import rate_algorithm
|
||||
return rate_algorithm.compute(device)
|
||||
|
||||
|
||||
class Price(JoinedWithOneDeviceMixin, EventWithOneDevice):
|
||||
"""The act of setting a trading price for the device.
|
||||
|
@ -913,7 +948,7 @@ class Price(JoinedWithOneDeviceMixin, EventWithOneDevice):
|
|||
version = Column(StrictVersionType)
|
||||
version.comment = """The version of the software, or None."""
|
||||
rating_id = Column(UUID(as_uuid=True), ForeignKey(Rate.id))
|
||||
rating_id.comment = """The AggregateRate used to auto-compute
|
||||
rating_id.comment = """The Rate used to auto-compute
|
||||
this price, if it has not been set manually."""
|
||||
rating = relationship(Rate,
|
||||
backref=backref('price',
|
||||
|
|
|
@ -224,9 +224,10 @@ class BenchmarkGraphicCard(BenchmarkWithRate):
|
|||
|
||||
|
||||
class Test(EventWithOneDevice):
|
||||
elapsed = ... # type: Column
|
||||
def __init__(self, **kwargs) -> None:
|
||||
super().__init__(**kwargs)
|
||||
self.elapsed = ... # type: timedelta
|
||||
self.elapsed = ... # type: Optional[timedelta]
|
||||
self.success = ... # type: bool
|
||||
|
||||
|
||||
|
@ -288,9 +289,6 @@ class TestTrackpad(Test):
|
|||
|
||||
class TestBios(Test):
|
||||
bios_power_on = ... # type: Column
|
||||
|
||||
|
||||
class TestBiosDifficulty:
|
||||
bios_access_range = ... # type: BiosAccessRange
|
||||
|
||||
|
||||
|
@ -321,6 +319,10 @@ class RateComputer(Rate):
|
|||
ram = ...
|
||||
data_storage = ...
|
||||
|
||||
@classmethod
|
||||
def compute(cls, device) -> 'RateComputer':
|
||||
pass
|
||||
|
||||
|
||||
class Price(EventWithOneDevice):
|
||||
SCALE = ...
|
||||
|
@ -338,7 +340,7 @@ class Price(EventWithOneDevice):
|
|||
self.currency = ... # type: Currency
|
||||
self.software = ... # type: PriceSoftware
|
||||
self.version = ... # type: StrictVersion
|
||||
self.rating = ... # type: AggregateRate
|
||||
self.rating = ... # type: Rate
|
||||
|
||||
@classmethod
|
||||
def to_price(cls, value: Union[Decimal, float], rounding=ROUND) -> Decimal:
|
||||
|
@ -360,7 +362,7 @@ class EreusePrice(Price):
|
|||
self.standard = ... # type: EreusePrice.Type
|
||||
self.warranty2 = ... # type: EreusePrice.Type
|
||||
|
||||
def __init__(self, rating: AggregateRate, **kwargs) -> None:
|
||||
def __init__(self, rating: Rate, **kwargs) -> None:
|
||||
super().__init__(**kwargs)
|
||||
self.retailer = ... # type: EreusePrice.Service
|
||||
self.platform = ... # type: EreusePrice.Service
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
from ereuse_devicehub.resources.device.models import Device
|
||||
from ereuse_devicehub.resources.event.models import RateComputer
|
||||
from ereuse_devicehub.resources.event.rate.workbench import v1_0
|
||||
|
||||
RATE_TYPES = {
|
||||
RateComputer: {
|
||||
'1.0': v1_0.Rate()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def rate(device: Device, version):
|
||||
"""
|
||||
Rates the passed-in ``rate`` using values from the rate itself
|
||||
and the ``device``.
|
||||
|
||||
This method mutates ``rate``.
|
||||
|
||||
:param device: The device to use as a model.
|
||||
:param rate: A half-filled rate.
|
||||
"""
|
||||
assert cls in RATE_TYPES, 'Rate type {} not supported.'.format(cls)
|
||||
assert str(rate.version) in RATE_TYPES[cls], \
|
||||
'Rate version {} not supported.'.format(rate.version)
|
||||
RATE_TYPES[cls][str(rate.version)].compute(device)
|
|
@ -53,7 +53,7 @@ class RateAlgorithm(BaseRate):
|
|||
|
||||
This mutates "rate".
|
||||
"""
|
||||
assert isinstance(device, (Desktop, Laptop, Server))
|
||||
assert isinstance(device, Computer)
|
||||
|
||||
rate = RateComputer()
|
||||
|
||||
|
@ -70,7 +70,7 @@ class RateAlgorithm(BaseRate):
|
|||
result = rate_cls.compute(components, rate)
|
||||
if result:
|
||||
setattr(rate, field, result)
|
||||
|
||||
# TODO is necessary check if TestVisual exists?? cause StopIteration Error
|
||||
test_visual = next(e for e in device.events if isinstance(e, TestVisual))
|
||||
|
||||
rate_components = self.harmonic_mean_rates(rate.processor, rate.data_storage, rate.ram)
|
||||
|
@ -212,7 +212,7 @@ class DataStorageRate(BaseRate):
|
|||
|
||||
# STEP: Filtering, data cleaning and merging of component parts
|
||||
for storage in data_storage_devices:
|
||||
# todo fix StopIteration if don't exists BenchmarkDataStorage
|
||||
# We assume all hdd snapshots have BenchmarkDataStorage
|
||||
benchmark = next(e for e in storage.events if isinstance(e, BenchmarkDataStorage))
|
||||
# prevent NULL values
|
||||
_size = storage.size or 0
|
||||
|
|
|
@ -14,7 +14,7 @@ from ereuse_devicehub.resources.agent import schemas as s_agent
|
|||
from ereuse_devicehub.resources.device import schemas as s_device
|
||||
from ereuse_devicehub.resources.enums import AppearanceRange, BiosAccessRange, FunctionalityRange, \
|
||||
PhysicalErasureMethod, PriceSoftware, RATE_POSITIVE, RatingRange, ReceiverRole, \
|
||||
Severity, SnapshotExpectedEvents, SnapshotSoftware, TestDataStorageLength
|
||||
Severity, SnapshotExpectedEvents, SnapshotSoftware, TestDataStorageLength, BatteryHealthRange
|
||||
from ereuse_devicehub.resources.event import models as m
|
||||
from ereuse_devicehub.resources.models import STR_BIG_SIZE, STR_SIZE
|
||||
from ereuse_devicehub.resources.schemas import Thing
|
||||
|
@ -143,11 +143,11 @@ class BenchmarkGraphicCard(BenchmarkWithRate):
|
|||
|
||||
class Test(EventWithOneDevice):
|
||||
__doc__ = m.Test.__doc__
|
||||
elapsed = TimeDelta(precision=TimeDelta.SECONDS, required=True)
|
||||
|
||||
|
||||
class TestDataStorage(Test):
|
||||
__doc__ = m.TestDataStorage.__doc__
|
||||
elapsed = TimeDelta(precision=TimeDelta.SECONDS, required=True)
|
||||
length = EnumField(TestDataStorageLength, required=True)
|
||||
status = SanitizedStr(lower=True, validate=Length(max=STR_SIZE), required=True)
|
||||
lifetime = TimeDelta(precision=TimeDelta.HOURS)
|
||||
|
@ -163,6 +163,7 @@ class TestDataStorage(Test):
|
|||
|
||||
class StressTest(Test):
|
||||
__doc__ = m.StressTest.__doc__
|
||||
elapsed = TimeDelta(precision=TimeDelta.SECONDS, required=True)
|
||||
|
||||
|
||||
class TestAudio(Test):
|
||||
|
@ -173,22 +174,41 @@ class TestAudio(Test):
|
|||
|
||||
class TestConnectivity(Test):
|
||||
__doc__ = m.TestConnectivity.__doc__
|
||||
cellular_network = Boolean()
|
||||
wifi = Boolean()
|
||||
bluetooth = Boolean()
|
||||
usb_port = Boolean()
|
||||
locked = Boolean()
|
||||
|
||||
|
||||
class TestBattery(Test):
|
||||
__doc__ = m.TestBattery.__doc__
|
||||
battery_stat = Boolean()
|
||||
battery_health = EnumField(BatteryHealthRange, data_key='batteryHealthRange')
|
||||
|
||||
|
||||
class TestBios:
|
||||
class TestCamera(Test):
|
||||
__doc__ = m.TestCamera.__doc__
|
||||
camera = Boolean()
|
||||
|
||||
|
||||
class TestKeyboard(Test):
|
||||
__doc__ = m.TestKeyboard.__doc__
|
||||
keyboard = Boolean()
|
||||
|
||||
|
||||
class TestTrackpad(Test):
|
||||
__doc__ = m.TestTrackpad.__doc__
|
||||
trackpad = Boolean()
|
||||
|
||||
|
||||
class TestBios(Test):
|
||||
__doc__ = m.TestBios.__doc__
|
||||
bios_power_on = Boolean()
|
||||
bios_access_range = EnumField(BiosAccessRange, data_key='accessRange')
|
||||
|
||||
|
||||
class TestBiosDifficulty:
|
||||
__doc__ = m.TestBiosDifficulty.__doc__
|
||||
bios_access_range = EnumField(BiosAccessRange, dump_only=True, data_key='biosAccessRange')
|
||||
|
||||
|
||||
class TestVisual():
|
||||
class TestVisual(Test):
|
||||
__doc__ = m.TestVisual.__doc__
|
||||
appearance_range = EnumField(AppearanceRange, dump_only=True, data_key='appearanceRange')
|
||||
functionality_range = EnumField(FunctionalityRange, dump_only=True, data_key='functionalityRange')
|
||||
|
|
|
@ -10,7 +10,7 @@ from teal.resource import View
|
|||
from ereuse_devicehub.db import db
|
||||
from ereuse_devicehub.resources.device.models import Component, Computer
|
||||
from ereuse_devicehub.resources.enums import SnapshotSoftware
|
||||
from ereuse_devicehub.resources.event.models import Event, Snapshot, Rate
|
||||
from ereuse_devicehub.resources.event.models import Event, Snapshot, Rate, RateComputer
|
||||
|
||||
SUPPORTED_WORKBENCH = StrictVersion('11.0')
|
||||
|
||||
|
@ -81,9 +81,9 @@ class EventView(View):
|
|||
snapshot.events |= events
|
||||
|
||||
# Compute ratings
|
||||
for rate in (e for e in events_device if isinstance(e, Rate)):
|
||||
rates = rate.ratings()
|
||||
snapshot.events |= rates
|
||||
if isinstance(device, Computer):
|
||||
rate_computer = RateComputer.compute(device)
|
||||
snapshot.events.add(rate_computer)
|
||||
|
||||
db.session.add(snapshot)
|
||||
db.session().final_flush()
|
||||
|
|
Reference in New Issue