diff --git a/.gitignore b/.gitignore index 69f6d4be..6a130a6e 100644 --- a/.gitignore +++ b/.gitignore @@ -116,3 +116,6 @@ ENV/ # Environment .env + +# Temporal dir +tmp/ diff --git a/ereuse_devicehub/config.py b/ereuse_devicehub/config.py index 6a176f6e..f7ff436f 100644 --- a/ereuse_devicehub/config.py +++ b/ereuse_devicehub/config.py @@ -44,6 +44,9 @@ class DevicehubConfig(Config): """The minimum version of ereuse.org workbench that this devicehub 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_VERSION = '0.2' API_DOC_CONFIG_COMPONENTS = { diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py index ba727dc3..689cb942 100644 --- a/ereuse_devicehub/resources/action/views.py +++ b/ereuse_devicehub/resources/action/views.py @@ -1,5 +1,9 @@ +""" This is the view for Snapshots """ + +import os +import json +from datetime import datetime from distutils.version import StrictVersion -from typing import List from uuid import UUID 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, \ InitTransfer 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.user.exceptions import InsufficientPermission 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): def post(self): """Posts an action.""" 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: raise ValidationError('Resource needs a type.') # todo there should be a way to better get subclassess resource @@ -29,11 +59,14 @@ class ActionView(View): resource_def = app.resources[json['type']] a = resource_def.schema.load(json) 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: pass # TODO JN add compute rate with new visual test and old components device if json['type'] == InitTransfer.t: + os.remove(path_snapshot) return self.transfer_ownership() Model = db.Model._decl_class_registry.data[json['type']]() action = Model(**a) @@ -42,6 +75,7 @@ class ActionView(View): ret = self.schema.jsonify(action) ret.status_code = 201 db.session.commit() + os.remove(path_snapshot) return ret def one(self, id: UUID): diff --git a/tests/conftest.py b/tests/conftest.py index be01b87f..bdae5797 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -30,6 +30,7 @@ class TestConfig(DevicehubConfig): SQLALCHEMY_DATABASE_URI = 'postgresql://dhub:ereuse@localhost/dh_test' TESTING = True SERVER_NAME = 'localhost' + TMP_SNAPSHOTS = '/tmp/snapshots' @pytest.fixture(scope='session') diff --git a/tests/files/basic.snapshot.badly_formed.yaml b/tests/files/basic.snapshot.badly_formed.yaml new file mode 100644 index 00000000..c63ade42 --- /dev/null +++ b/tests/files/basic.snapshot.badly_formed.yaml @@ -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 diff --git a/tests/files/failed.snapshot.422.missing-chassis.yaml b/tests/files/failed.snapshot.422.missing-chassis.yaml new file mode 100644 index 00000000..1d78da4a --- /dev/null +++ b/tests/files/failed.snapshot.422.missing-chassis.yaml @@ -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 diff --git a/tests/files/failed.snapshot.422.null-chassis.yaml b/tests/files/failed.snapshot.422.null-chassis.yaml new file mode 100644 index 00000000..0cf56bb7 --- /dev/null +++ b/tests/files/failed.snapshot.422.null-chassis.yaml @@ -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 diff --git a/tests/files/failed.snapshot.500.missing-cpu-benchmark.yaml b/tests/files/failed.snapshot.500.missing-cpu-benchmark.yaml new file mode 100644 index 00000000..2a5496ae --- /dev/null +++ b/tests/files/failed.snapshot.500.missing-cpu-benchmark.yaml @@ -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 diff --git a/tests/files/failed.snapshot.500.missing-hdd-benchmark.yaml b/tests/files/failed.snapshot.500.missing-hdd-benchmark.yaml new file mode 100644 index 00000000..19269d33 --- /dev/null +++ b/tests/files/failed.snapshot.500.missing-hdd-benchmark.yaml @@ -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 diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py index 4482e66e..42792c2f 100644 --- a/tests/test_snapshot.py +++ b/tests/test_snapshot.py @@ -1,9 +1,13 @@ +import os +import json +import pytest + from datetime import datetime, timedelta, timezone +from requests.exceptions import HTTPError from operator import itemgetter from typing import List, Tuple from uuid import uuid4 -import pytest from boltons import urlutils from teal.db import UniqueViolation, DBError 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.tag import Tag from ereuse_devicehub.resources.user.models import User +from ereuse_devicehub.resources.action.views import save_json from tests.conftest import file @@ -473,3 +478,147 @@ def test_pc_rating_rate_none(user: UserClient): def test_pc_2(user: UserClient): s = file('laptop-hp_255_g3_notebook-hewlett-packard-cnd52270fw.snapshot') 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 +