Skip to content
Snippets Groups Projects
Verified Commit 0db1530b authored by Timm Fitschen's avatar Timm Fitschen
Browse files

WIP: file storage refactoring: directory

parent 987d1ac6
Branches
No related tags found
1 merge request!49Draft: ENH: file system: directory
Pipeline #31752 failed
......@@ -34,6 +34,7 @@ import shutil
from lxml import etree
from pytest import raises, mark
import caosdb as db
from caosdb.exceptions import TransactionError
from caosdb import execute_query, get_config, get_connection
from caosdb.common import models
from caosdb.utils.checkFileSystemConsistency import runCheck
......@@ -344,3 +345,179 @@ def test_consistency_file_was_modified_2():
qfile = execute_query("FIND FILE TestConsistency3", unique=True)
assert qfile.id == file_.id
assert qfile.checksum.lower() == checksum2
def test_insert_empty_directory():
directory = db.Directory(path="A").insert()
assert directory.path == "/A"
did = directory.id
assert execute_query("FIND DIRECTORY", unique=True).id == did
assert execute_query("FIND ENTITY WHICH IS STORED AT '/A*'",
unique=True).id == did
assert execute_query("FIND Directory WHICH IS STORED AT '/A'",
unique=True).id == did
directory.delete()
def test_insert_empty_directory():
directory = db.Directory(path="A").insert()
assert directory.path == "/A"
did = directory.id
assert execute_query("FIND DIRECTORY", unique=True).id == did
assert execute_query("FIND ENTITY WHICH IS STORED AT '/A*'",
unique=True).id == did
assert execute_query("FIND Directory WHICH IS STORED AT '/A'",
unique=True).id == did
# test if the empty directory shows up in the FileSystem resource as
# expected.
body = get_connection().retrieve(
entity_uri_segments=[
"FileSystem",
""],
reconnect=True).read()
xml = etree.fromstring(body)
assert len(xml.xpath('/Response/dir')) == 1
root = xml.xpath('/Response/dir')[0]
assert root.get("name") == "/"
assert root.get("path") == "/"
assert root.get("url")[-12:] == "/FileSystem/"
assert len(root.xpath('dir')) == 1
assert len(root.xpath('file')) == 0
dir_a = root.xpath('dir')[0]
assert dir_a.get("name") == "A"
assert dir_a.get("url")[-14:] == "/FileSystem/A/"
body = get_connection().retrieve(
entity_uri_segments=[
"FileSystem",
"A", ""],
reconnect=True).read()
xml = etree.fromstring(body)
assert len(xml.xpath('/Response/dir')) == 1
dir_a = xml.xpath('/Response/dir')[0]
assert dir_a.get("name") == "A"
assert dir_a.get("url")[-14:] == "/FileSystem/A/"
assert len(dir_a.xpath('dir')) == 0
assert len(dir_a.xpath('file')) == 0
directory.delete()
def test_insert_empty_subdir():
directoryA = db.Directory(path="A").insert()
assert directoryA.path == "/A"
aid = directoryA.id
directoryB = db.Directory(path="A/B").insert()
assert directoryB.path == "/A/B"
bid = directoryB.id
assert len(execute_query("FIND DIRECTORY")) == 2
assert len(execute_query("FIND ENTITY WHICH IS STORED AT '/A**'")) == 2
assert execute_query("FIND Directory WHICH IS STORED AT '/A*'",
unique=True).id == aid
assert execute_query("FIND Directory WHICH IS STORED AT '/A'",
unique=True).id == aid
assert execute_query("FIND Directory WHICH IS STORED AT '/A/B'",
unique=True).id == bid
assert execute_query("FIND Directory WHICH IS STORED AT '*/B'",
unique=True).id == bid
# test if the empty directory shows up in the FileSystem resource as
# expected.
body = get_connection().retrieve(
entity_uri_segments=[
"FileSystem",
""],
reconnect=True).read()
xml = etree.fromstring(body)
assert len(xml.xpath('/Response/dir')) == 1
root = xml.xpath('/Response/dir')[0]
assert root.get("name") == "/"
assert root.get("path") == "/"
assert root.get("url")[-12:] == "/FileSystem/"
assert len(root.xpath('dir')) == 1
assert len(root.xpath('file')) == 0
dir_a = root.xpath('dir')[0]
assert dir_a.get("name") == "A"
assert dir_a.get("url")[-14:] == "/FileSystem/A/"
body = get_connection().retrieve(
entity_uri_segments=[
"FileSystem",
"A", ""],
reconnect=True).read()
xml = etree.fromstring(body)
assert len(xml.xpath('/Response/dir')) == 1
dir_a = xml.xpath('/Response/dir')[0]
assert dir_a.get("name") == "A"
assert dir_a.get("url")[-14:] == "/FileSystem/A/"
assert len(dir_a.xpath('dir')) == 1
assert len(dir_a.xpath('file')) == 0
def test_delete_dir_failure_not_empty():
directoryA = db.Directory(path="A").insert()
directoryB = db.Directory(path="A/B").insert()
with raises(TransactionError) as exc:
directoryA.delete()
assert exc.value.msg == "One or more entities are not qualified. None of them have been inserted/updated/deleted."
assert exc.value.entities[0].get_errors()[0].description == "Entity is required by other entities which are not to be deleted."
body = get_connection().retrieve(
entity_uri_segments=[
"FileSystem",
"A", "B"],
reconnect=True).read()
xml = etree.fromstring(body)
assert len(xml.xpath('/Response/dir')) == 1
dir_a = xml.xpath('/Response/dir')[0]
assert dir_a.get("name") == "B"
assert dir_a.get("url")[-16:] == "/FileSystem/A/B/"
assert len(dir_a.xpath('dir')) == 0
assert len(dir_a.xpath('file')) == 0
directoryB.delete()
c = runCheck(None, "/")
assert c.messages["Info", 0] is not None
assert c.messages["Info",
0][0] == "File system below / is consistent."
body = get_connection().retrieve(
entity_uri_segments=[
"FileSystem",
"A", ""],
reconnect=True).read()
xml = etree.fromstring(body)
assert len(xml.xpath('/Response/dir')) == 1
dir_a = xml.xpath('/Response/dir')[0]
assert dir_a.get("name") == "A"
assert dir_a.get("url")[-14:] == "/FileSystem/A/"
assert len(dir_a.xpath('dir')) == 0
assert len(dir_a.xpath('file')) == 0
directoryA.delete()
def test_insert_without_auto_create_parent_dirs():
with raises(TransactionError) as exc:
db.Directory(path="A/B").insert(flags={"autoCreateDirs":
"false"})
# encoding: utf-8
#
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2022 IndiScale GmbH <info@indiscale.com>
# Copyright (C) 2022 Timm Fitschen <t.fitschen@indiscale.com>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
import caosdb as db
def setup_module():
teardown_module()
db.RecordType("State").insert()
db.RecordType("StateModel").insert()
db.RecordType("Transition").insert()
db.Property(name="from", datatype="State").insert()
db.Property(name="to", datatype="State").insert()
db.Property(name="initial", datatype="State").insert()
db.Property(name="final", datatype="State").insert()
def teardown_module():
"""delete all entities!!!"""
try:
db.execute_query("FIND ENTITY").delete()
except:
pass
def create_transition(name, fro, to):
db.Record(name).add_parent("Transition").add_property(
"from", fro).add_property("to", to).insert()
def create_state_model(name, transitions, initial, final):
m = db.Record(name)
m.add_parent("StateModel")
m.add_property("Transition",
datatype=db.LIST("Transition"),
value=transitions)
m.add_property("initial", initial)
m.add_property("final", final)
m.insert()
def test_issue_86():
# two states
db.Record("S1").add_parent("State").insert()
db.Record("S2").add_parent("State").insert()
# three transitions
create_transition("t11", "S1", "S1")
create_transition("t12", "S1", "S2")
create_transition("t21", "S2", "S1")
create_state_model("Model1", ["t11", "t12", "t21"], "S1", "S1")
# stateful record type
rt = db.RecordType("TestRT")
rt.state = db.State(model="Model1", name="S1")
rt.insert()
# record inherits the state from the record type.
rec = db.Record().add_parent("TestRT")
rec.insert()
assert rec.state == db.State(model="Model1", name="S1")
# now try to update the record without changing the state.
p = db.Property("p1", datatype=db.TEXT).insert()
rec.add_property(p, value="val1").update()
......@@ -42,9 +42,7 @@ test_pw = "passphrase1P!"
def setup_module():
d = db.execute_query("FIND *")
if len(d) > 0:
d.delete()
teardown_function(None)
insert_test_user()
......@@ -61,9 +59,7 @@ def teardown_module():
os.remove("test2.dat")
except BaseException:
pass
d = db.execute_query("FIND *")
if len(d) > 0:
d.delete()
teardown_function(None)
@mark.skip
......@@ -147,7 +143,7 @@ def teardown_function(function):
def setup_function(function):
switch_to_admin_user()
try:
db.execute_query("FIND Test*").delete()
db.execute_query("FIND ENTITY *").delete()
except BaseException:
pass
......
......@@ -17,9 +17,7 @@
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# ** end header
#
import pytest
import caosdb as db
from caosdb import administration as admin
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment