Commit d010ceaf authored by Flavio TARSETTI's avatar Flavio TARSETTI
Browse files

Merge branch '60_fix_non_forkable_types_handling' into 'master'

Fix non forkable types handling

See merge request !68
parents 7d4030f9 78c0a1f1
Pipeline #31396 passed with stage
in 10 minutes and 55 seconds
......@@ -151,9 +151,9 @@ class Selector(object):
self.__version = {}
self.__fork = {}
self.__versionables = [
"algorithm",
"dataformat",
"database",
"algorithm",
"library",
"toolchain",
"plotter",
......@@ -161,7 +161,15 @@ class Selector(object):
"protocoltemplate",
]
self.__forkables = self.__versionables + ["experiment"]
self.__forkables = [
"algorithm",
"dataformat",
"experiment",
"library",
"toolchain",
"plotter",
"plotterparameter",
]
if os.path.exists(self.path):
self.load()
......@@ -187,27 +195,37 @@ class Selector(object):
if asset_type not in self.__fork:
self.__fork[asset_type] = dict()
def fork(self, type, src, dst):
def can_fork(self, asset_type):
"""Returns whether the given asset type can be forked"""
return asset_type in self.__forkables
def fork(self, asset_type, src, dst):
"""Registers that object ``dst`` is a fork of object ``src``"""
if not self.can_fork(asset_type):
raise RuntimeError("Can't create new version of {}".format(asset_type))
logger.info(
"`%s/%s' is forked from `%s/%s'",
TYPE_PLURAL[type],
TYPE_PLURAL[asset_type],
dst,
TYPE_PLURAL[type],
TYPE_PLURAL[asset_type],
src,
)
self.__fork[type][dst] = src
self.__fork[asset_type][dst] = src
def forked_from(self, type, name):
def forked_from(self, asset_type, name):
"""Returns the name of the originating source object or ``None``"""
if not self.can_fork(asset_type):
return None
return self.__fork[type].get(name)
return self.__fork[asset_type].get(name)
def version(self, asset_type, src, dst):
"""Registers that object ``dst`` is a new version of object ``src``"""
if asset_type not in self.__version:
if asset_type not in self.__versionables:
raise RuntimeError("Can't create new version of {}".format(asset_type))
logger.info(
......@@ -230,7 +248,7 @@ class Selector(object):
def delete(self, asset_type, name):
"""Forgets about an object that was being tracked"""
if name in self.__fork[asset_type]:
if asset_type in self.__fork and name in self.__fork[asset_type]:
del self.__fork[asset_type][name]
if asset_type in self.__version and name in self.__version[asset_type]:
del self.__version[asset_type][name]
......
......@@ -666,7 +666,6 @@ CMD_LIST = [
"status",
"create",
"version",
"fork",
("rm", "rm_local"),
"diff",
]
......
......@@ -56,15 +56,6 @@ def protocoltemplates(ctx):
ctx.meta["asset_type"] = "protocoltemplate"
CMD_LIST = [
"list",
"path",
"edit",
"check",
"create",
"version",
"fork",
("rm", "rm_local"),
]
CMD_LIST = ["list", "path", "edit", "check", "create", "version", ("rm", "rm_local")]
commands.initialise_asset_commands(protocoltemplates, CMD_LIST)
......@@ -142,14 +142,17 @@ class AssetLocalTest:
obj = self.object_map["create"]
obj2 = self.object_map["fork"]
self.test_create(obj)
exit_code, outputs = self.call("fork", obj, obj2, prefix=tmp_prefix)
nose.tools.eq_(exit_code, 0, outputs)
s = self.storage_cls(tmp_prefix, obj2)
nose.tools.assert_true(s.exists())
# check fork status
with common.Selector(tmp_prefix) as selector:
nose.tools.eq_(selector.forked_from(self.asset_type, obj2), obj)
if selector.can_fork(self.asset_type):
exit_code, outputs = self.call("fork", obj, obj2, prefix=tmp_prefix)
nose.tools.eq_(exit_code, 0, outputs)
selector.load()
s = self.storage_cls(tmp_prefix, obj2)
nose.tools.assert_true(s.exists())
nose.tools.eq_(selector.forked_from(self.asset_type, obj2), obj)
else:
exit_code, outputs = self.call("fork", obj, obj2, prefix=tmp_prefix)
nose.tools.assert_not_equal(exit_code, 0)
def test_delete_local(self):
obj = self.object_map["create"]
......
......@@ -40,12 +40,36 @@ import nose.tools
import click
from click.testing import CliRunner
from . import platform, disconnected, prefix, tmp_prefix, user, token
from beat.cmdline.scripts import main_cli
from beat.core.test.utils import slow, cleanup, skipif
from beat.core.database import Storage, Database
from beat.backend.python.test.test_database import INTEGERS_DBS
from beat.backend.python.protocoltemplate import Storage as PTStorage
from beat.core.test.utils import slow, cleanup, skipif
from beat.core.database import Storage, Database, get_first_procotol_template
from beat.cmdline.scripts import main_cli
from . import core
from . import platform, disconnected, prefix, tmp_prefix, user, token
class TestDatabaseLocal(core.AssetLocalTest):
storage_cls = Storage
asset_type = "database"
object_map = {
"valid": "integers_db/1",
"invalid": "invalid/1",
"create": "new_database/1",
"new": "new_database/2",
"fork": "forked_database/1",
}
def setup(self):
obj = get_first_procotol_template(prefix)
storage = PTStorage(tmp_prefix, obj)
if not storage.exists():
exit_code, outputs = self.call(
"create", obj, prefix=tmp_prefix, asset_type=storage.asset_type
)
nose.tools.eq_(exit_code, 0, outputs)
def index_integer_db():
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment