Merge pull request #62 from eReuse/feature/61-Json-Backup

Feature/61 json backup
This commit is contained in:
Jordi Nadeu 2020-10-15 11:18:46 +02:00 committed by GitHub
commit 7c0ccd5794
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 349 additions and 4 deletions

3
.gitignore vendored
View File

@ -116,3 +116,6 @@ ENV/
# Environment # Environment
.env .env
# Temporal dir
tmp/

View File

@ -44,6 +44,9 @@ class DevicehubConfig(Config):
"""The minimum version of ereuse.org workbench that this devicehub """The minimum version of ereuse.org workbench that this devicehub
accepts. we recommend not changing this value. accepts. we recommend not changing this value.
""" """
TMP_SNAPSHOTS = config('TMP_SNAPSHOTS', '/tmp/snapshots')
"""This var is for save a snapshots in json format when fail something"""
API_DOC_CONFIG_TITLE = 'Devicehub' API_DOC_CONFIG_TITLE = 'Devicehub'
API_DOC_CONFIG_VERSION = '0.2' API_DOC_CONFIG_VERSION = '0.2'
API_DOC_CONFIG_COMPONENTS = { API_DOC_CONFIG_COMPONENTS = {

View File

@ -1,5 +1,9 @@
""" This is the view for Snapshots """
import os
import json
from datetime import datetime
from distutils.version import StrictVersion from distutils.version import StrictVersion
from typing import List
from uuid import UUID from uuid import UUID
from flask import current_app as app, request, g from flask import current_app as app, request, g
@ -11,17 +15,43 @@ from ereuse_devicehub.db import db
from ereuse_devicehub.resources.action.models import Action, RateComputer, Snapshot, VisualTest, \ from ereuse_devicehub.resources.action.models import Action, RateComputer, Snapshot, VisualTest, \
InitTransfer InitTransfer
from ereuse_devicehub.resources.action.rate.v1_0 import CannotRate from ereuse_devicehub.resources.action.rate.v1_0 import CannotRate
from ereuse_devicehub.resources.device.models import Component, Computer
from ereuse_devicehub.resources.enums import SnapshotSoftware, Severity from ereuse_devicehub.resources.enums import SnapshotSoftware, Severity
from ereuse_devicehub.resources.user.exceptions import InsufficientPermission from ereuse_devicehub.resources.user.exceptions import InsufficientPermission
SUPPORTED_WORKBENCH = StrictVersion('11.0') SUPPORTED_WORKBENCH = StrictVersion('11.0')
def save_json(req_json, tmp_snapshots, user):
"""
This function allow save a snapshot in json format un a TMP_SNAPSHOTS directory
The file need to be saved with one name format with the stamptime and uuid joins
"""
uuid = req_json.get('uuid', '')
now = datetime.now()
year = now.year
month = now.month
day = now.day
hour = now.hour
minutes = now.min
name_file = f"{year}-{month}-{day}-{hour}-{minutes}_{user}_{uuid}.json"
path_name = os.path.join(tmp_snapshots, name_file)
if not os.path.isdir(tmp_snapshots):
os.system('mkdir -p {}'.format(tmp_snapshots))
with open(path_name, 'w') as snapshot_file:
snapshot_file.write(json.dumps(req_json))
return path_name
class ActionView(View): class ActionView(View):
def post(self): def post(self):
"""Posts an action.""" """Posts an action."""
json = request.get_json(validate=False) json = request.get_json(validate=False)
tmp_snapshots = app.config['TMP_SNAPSHOTS']
path_snapshot = save_json(json, tmp_snapshots, g.user.email)
if not json or 'type' not in json: if not json or 'type' not in json:
raise ValidationError('Resource needs a type.') raise ValidationError('Resource needs a type.')
# todo there should be a way to better get subclassess resource # todo there should be a way to better get subclassess resource
@ -29,11 +59,14 @@ class ActionView(View):
resource_def = app.resources[json['type']] resource_def = app.resources[json['type']]
a = resource_def.schema.load(json) a = resource_def.schema.load(json)
if json['type'] == Snapshot.t: if json['type'] == Snapshot.t:
return self.snapshot(a, resource_def) response = self.snapshot(a, resource_def)
os.remove(path_snapshot)
return response
if json['type'] == VisualTest.t: if json['type'] == VisualTest.t:
pass pass
# TODO JN add compute rate with new visual test and old components device # TODO JN add compute rate with new visual test and old components device
if json['type'] == InitTransfer.t: if json['type'] == InitTransfer.t:
os.remove(path_snapshot)
return self.transfer_ownership() return self.transfer_ownership()
Model = db.Model._decl_class_registry.data[json['type']]() Model = db.Model._decl_class_registry.data[json['type']]()
action = Model(**a) action = Model(**a)
@ -42,6 +75,7 @@ class ActionView(View):
ret = self.schema.jsonify(action) ret = self.schema.jsonify(action)
ret.status_code = 201 ret.status_code = 201
db.session.commit() db.session.commit()
os.remove(path_snapshot)
return ret return ret
def one(self, id: UUID): def one(self, id: UUID):

View File

@ -30,6 +30,7 @@ class TestConfig(DevicehubConfig):
SQLALCHEMY_DATABASE_URI = 'postgresql://dhub:ereuse@localhost/dh_test' SQLALCHEMY_DATABASE_URI = 'postgresql://dhub:ereuse@localhost/dh_test'
TESTING = True TESTING = True
SERVER_NAME = 'localhost' SERVER_NAME = 'localhost'
TMP_SNAPSHOTS = '/tmp/snapshots'
@pytest.fixture(scope='session') @pytest.fixture(scope='session')

View File

@ -0,0 +1,30 @@
type: Snapshot
uuid: 9a3e7485-fdd0-47ce-bcc7-65c55226b598
version: '11.0b9'
software: Workbench
elapsed: 4
device:
type: Desktop
chassis: Microtower
serialNumber: null
model: null
manufacturer: null
actions:
- type: VisualTest
appearanceRange: A
functionalityRange: B
components:
- type: RamModule
serialNumber: rm1s
model: rm1ml
manufacturer: rm1mr
speed: 1333
- type: Processor
serialNumber: p1s
model: p1ml
manufacturer: p1mr
speed: 1.6
actions:
- type: BenchmarkProcessorr
rate: 2410
elapsed: 11

View File

@ -0,0 +1,36 @@
type: Snapshot
uuid: 62b3e393-0c25-42cf-a5fa-ab796fac76dd
version: 11.0
software: Workbench
elapsed: 4
device:
type: Laptop
chassis: Notebook
serialNumber: d6s
model: d6ml
manufacturer: d6mr
components:
- type: RamModule
serialNumber: rm6s
model: rm6ml
manufacturer: rm6mr
speed: 1333
- type: Processor
serialNumber: p6s
model: p6ml
manufacturer: p6mr
speed: 1.6
actions:
- type: BenchmarkProcessor
rate: 2410
elapsed: 11
- type: HardDrive
size: 160041.88569599998
model: hdd4m
manufacturer: hdd4mr
serialNumber: hdd4s
actions:
- type: BenchmarkDataStorage
elapsed: 22
writeSpeed: 17.3
readSpeed: 41.6

View File

@ -0,0 +1,36 @@
type: Snapshot
uuid: 81e1f340-5aac-4619-931b-d312e4866cb7
version: 11.0
software: Workbench
elapsed: 4
device:
type: Laptop
chassis: null
serialNumber: d5s
model: d5ml
manufacturer: d5mr
components:
- type: RamModule
serialNumber: rm5s
model: rm5ml
manufacturer: rm5mr
speed: 1333
type: Processor
serialNumber: p5s
model: p5ml
manufacturer: p5mr
speed: 1.6
actions:
- type: BenchmarkProcessor
rate: 2410
elapsed: 11
size: 160041.88569599998
model: hdd5m
type: HardDrive
manufacturer: hdd5mr
serialNumber: hdd5s
actions:
- type: BenchmarkDataStorage
elapsed: 22
writeSpeed: 17.3
readSpeed: 41.6

View File

@ -0,0 +1,22 @@
type: Snapshot
uuid: 127fad1c-a3f2-4677-9dab-4a370071a882
version: 11.0
software: Workbench
elapsed: 4
device:
type: Laptop
chassis: Microtower
serialNumber: d2s
model: d2ml
manufacturer: d2mr
components:
- type: RamModule
serialNumber: rm2s
model: rm2ml
manufacturer: rm2mr
speed: 1333
- type: Processor
serialNumber: p2s
model: p2ml
manufacturer: p2mr
speed: 1.6

View File

@ -0,0 +1,31 @@
type: Snapshot
uuid: 2afa5413-9858-4577-8273-a027a647fed0
version: 11.0
software: Workbench
elapsed: 4
device:
type: Desktop
chassis: Microtower
serialNumber: d3s
model: d3ml
manufacturer: d3mr
components:
- type: RamModule
serialNumber: rm3s
model: rm3ml
manufacturer: rm3mr
speed: 1333
- type: Processor
serialNumber: p3s
model: p3ml
manufacturer: p3mr
speed: 1.6
size: 160041.88569599998
model: hdd3m
type: HardDrive
manufacturer: hdd3mr
serialNumber: hdd3s
actions:
- type: BenchmarkProcessor
rate: 2410
elapsed: 11

View File

@ -1,9 +1,13 @@
import os
import json
import pytest
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from requests.exceptions import HTTPError
from operator import itemgetter from operator import itemgetter
from typing import List, Tuple from typing import List, Tuple
from uuid import uuid4 from uuid import uuid4
import pytest
from boltons import urlutils from boltons import urlutils
from teal.db import UniqueViolation, DBError from teal.db import UniqueViolation, DBError
from teal.marshmallow import ValidationError from teal.marshmallow import ValidationError
@ -22,6 +26,7 @@ from ereuse_devicehub.resources.device.sync import MismatchBetweenProperties, \
from ereuse_devicehub.resources.enums import ComputerChassis, SnapshotSoftware from ereuse_devicehub.resources.enums import ComputerChassis, SnapshotSoftware
from ereuse_devicehub.resources.tag import Tag from ereuse_devicehub.resources.tag import Tag
from ereuse_devicehub.resources.user.models import User from ereuse_devicehub.resources.user.models import User
from ereuse_devicehub.resources.action.views import save_json
from tests.conftest import file from tests.conftest import file
@ -473,3 +478,147 @@ def test_pc_rating_rate_none(user: UserClient):
def test_pc_2(user: UserClient): def test_pc_2(user: UserClient):
s = file('laptop-hp_255_g3_notebook-hewlett-packard-cnd52270fw.snapshot') s = file('laptop-hp_255_g3_notebook-hewlett-packard-cnd52270fw.snapshot')
snapshot, _ = user.post(res=Snapshot, data=s) snapshot, _ = user.post(res=Snapshot, data=s)
@pytest.mark.mvp
def test_save_snapshot_in_file(app: Devicehub, user: UserClient):
""" This test check if works the function save_snapshot_in_file """
tmp_snapshots = app.config['TMP_SNAPSHOTS']
snapshot_no_hid = file('basic.snapshot.nohid')
save_json(snapshot_no_hid, tmp_snapshots, user.user['email'])
uuid = snapshot_no_hid['uuid']
files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
snapshot = {'software': '', 'version': '', 'uuid': ''}
if files:
path_snapshot = os.path.join(tmp_snapshots, files[0])
with open(path_snapshot) as file_snapshot:
snapshot = json.loads(file_snapshot.read())
os.remove(path_snapshot)
assert snapshot['software'] == snapshot_no_hid['software']
assert snapshot['version'] == snapshot_no_hid['version']
assert snapshot['uuid'] == uuid
@pytest.mark.mvp
def test_backup_snapshot_with_errors(app: Devicehub, user: UserClient):
""" This test check if the file snapshot is create when some snapshot is wrong """
tmp_snapshots = app.config['TMP_SNAPSHOTS']
snapshot_no_hid = file('basic.snapshot.badly_formed')
uuid = snapshot_no_hid['uuid']
snapshot = {'software': '', 'version': '', 'uuid': ''}
with pytest.raises(KeyError):
response = user.post(res=Snapshot, data=snapshot_no_hid)
files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
if files:
path_snapshot = os.path.join(tmp_snapshots, files[0])
with open(path_snapshot) as file_snapshot:
snapshot = json.loads(file_snapshot.read())
os.remove(path_snapshot)
assert snapshot['software'] == snapshot_no_hid['software']
assert snapshot['version'] == snapshot_no_hid['version']
assert snapshot['uuid'] == uuid
@pytest.mark.mvp
def test_snapshot_failed_missing_cpu_benchmark(app: Devicehub, user: UserClient):
""" This test check if the file snapshot is create when some snapshot is wrong """
tmp_snapshots = app.config['TMP_SNAPSHOTS']
snapshot_error = file('failed.snapshot.500.missing-cpu-benchmark')
uuid = snapshot_error['uuid']
snapshot = {'software': '', 'version': '', 'uuid': ''}
with pytest.raises(TypeError):
user.post(res=Snapshot, data=snapshot_error)
files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
if files:
path_snapshot = os.path.join(tmp_snapshots, files[0])
with open(path_snapshot) as file_snapshot:
snapshot = json.loads(file_snapshot.read())
os.remove(path_snapshot)
assert snapshot['software'] == snapshot_error['software']
assert snapshot['version'] == snapshot_error['version']
assert snapshot['uuid'] == uuid
@pytest.mark.mvp
def test_snapshot_failed_missing_hdd_benchmark(app: Devicehub, user: UserClient):
""" This test check if the file snapshot is create when some snapshot is wrong """
tmp_snapshots = app.config['TMP_SNAPSHOTS']
snapshot_error = file('failed.snapshot.500.missing-hdd-benchmark')
uuid = snapshot_error['uuid']
snapshot = {'software': '', 'version': '', 'uuid': ''}
with pytest.raises(TypeError):
user.post(res=Snapshot, data=snapshot_error)
files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
if files:
path_snapshot = os.path.join(tmp_snapshots, files[0])
with open(path_snapshot) as file_snapshot:
snapshot = json.loads(file_snapshot.read())
os.remove(path_snapshot)
assert snapshot['software'] == snapshot_error['software']
assert snapshot['version'] == snapshot_error['version']
assert snapshot['uuid'] == uuid
@pytest.mark.mvp
def test_snapshot_failed_null_chassis(app: Devicehub, user: UserClient):
""" This test check if the file snapshot is create when some snapshot is wrong """
tmp_snapshots = app.config['TMP_SNAPSHOTS']
snapshot_error = file('failed.snapshot.422.null-chassis')
uuid = snapshot_error['uuid']
snapshot = {'software': '', 'version': '', 'uuid': ''}
with pytest.raises(TypeError):
user.post(res=Snapshot, data=snapshot_error)
files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
if files:
path_snapshot = os.path.join(tmp_snapshots, files[0])
with open(path_snapshot) as file_snapshot:
snapshot = json.loads(file_snapshot.read())
os.remove(path_snapshot)
assert snapshot['software'] == snapshot_error['software']
assert snapshot['version'] == snapshot_error['version']
assert snapshot['uuid'] == uuid
@pytest.mark.mvp
def test_snapshot_failed_missing_chassis(app: Devicehub, user: UserClient):
""" This test check if the file snapshot is create when some snapshot is wrong """
tmp_snapshots = app.config['TMP_SNAPSHOTS']
snapshot_error = file('failed.snapshot.422.missing-chassis')
uuid = snapshot_error['uuid']
snapshot = {'software': '', 'version': '', 'uuid': ''}
with pytest.raises(TypeError):
user.post(res=Snapshot, data=snapshot_error)
files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
if files:
path_snapshot = os.path.join(tmp_snapshots, files[0])
with open(path_snapshot) as file_snapshot:
snapshot = json.loads(file_snapshot.read())
os.remove(path_snapshot)
assert snapshot['software'] == snapshot_error['software']
assert snapshot['version'] == snapshot_error['version']
assert snapshot['uuid'] == uuid