示例#1
0
 def __init__(self, name: str, assertfun) -> None:
     super().__init__(assertfun)
     self.no_cd = None  # type: bool
     self.name = name
     self.check = assertfun
     self.main("init", self.name)
     self.fs = Filesystem(self.test_dir)
     self.db = DatabaseJson()
     self.db_sizes = (0, 0, 0)
示例#2
0
    def test_goup_on_sub(self) -> None:
        os.chdir(self.foodir)
        self.fs = Filesystem()
        self.fs.go_up_until(self.path_target, )

        conv = self.fs.make_relative(".")
        sub_foo = self.foodir
        self.assertEqual(sub_foo, conv)

        conv = self.fs.make_relative("FOO")
        sub_foo = join('dir1', 'dir2', 'dir3', 'FOO')
        self.assertEqual(sub_foo, conv)

        # Check that the absolute is proper
        conv = self.fs.make_relative(join(self.test_dir, "FOO"))
        self.assertEqual('FOO', conv)

        # Check relative down is ok
        conv = self.fs.make_relative(join('..', '..', '..', "FOO"))
        self.assertEqual('FOO', conv)
示例#3
0
    def setUp(self) -> None:
        self.log = LogOutput(self.assertEqual)
        self.log.start()

        self.tdir = TempDir(self.assertEqual)

        self.tdir.file_make("FOO", )
        self.tdir.file_make_many((
            "FOO",
            "BAR",
            "FUBA",
        ),
                                 basepath=["dir1", "dir2", "dir3"])
        self.tdir.file_make_many(("database.json", ), basepath=(CONFIG.PATH, ))

        self.test_dir = self.tdir.test_dir
        os.chdir(self.test_dir)
        self.fs = Filesystem()

        self.foodir = join('dir1', 'dir2', 'dir3')
        self.path_target = CONFIG.PATH
示例#4
0
 def goto_test_dir(self) -> None:
     self.fs = Filesystem(self.test_dir)
     self.fs.go_up_until(self.path_target, max_levels=1)
     os.chdir("/var")  # Somthing
示例#5
0
class TestFS(unittest.TestCase):
    def setUp(self) -> None:
        self.log = LogOutput(self.assertEqual)
        self.log.start()

        self.tdir = TempDir(self.assertEqual)

        self.tdir.file_make("FOO", )
        self.tdir.file_make_many((
            "FOO",
            "BAR",
            "FUBA",
        ),
                                 basepath=["dir1", "dir2", "dir3"])
        self.tdir.file_make_many(("database.json", ), basepath=(CONFIG.PATH, ))

        self.test_dir = self.tdir.test_dir
        os.chdir(self.test_dir)
        self.fs = Filesystem()

        self.foodir = join('dir1', 'dir2', 'dir3')
        self.path_target = CONFIG.PATH

    def tearDown(self):
        self.log.stop()
        self.tdir.clean()

    def test_travel(self) -> None:
        self.fs.go_up_until(self.path_target, )
        items = [x for x in self.fs.recursive_walk_files(".")]
        self.assertEqual(4, len(items))
        sub_foo = join('dir1', 'dir2', 'dir3', 'FOO')
        assert (sub_foo in items)
        items = [x for x in self.fs.recursive_walk_files("dir1")]
        self.assertEqual(3, len(items))
        assert (sub_foo in items)

    def test_goup_on_root(self) -> None:
        self.fs.go_up_until(self.path_target, )
        self.assertEqual(self.test_dir, os.getcwd())
        conv = self.fs.make_relative("FOO")
        self.assertEqual('FOO', conv)

    def goto_test_dir(self) -> None:
        self.fs = Filesystem(self.test_dir)
        self.fs.go_up_until(self.path_target, max_levels=1)
        os.chdir("/var")  # Somthing

    def test_read_nonext(self) -> None:
        with self.assertRaises(SA_FS_Exception_NotFound):
            fid = self.fs.file_read("NO_SUCH_FILE")
            d = [x for x in fid]

    def test_read_create(self) -> None:
        self.goto_test_dir()
        new_fn = join("NEW_DIR", "NEW_DIR2", "NEW_FILE")
        meta = Meta(new_fn)
        meta.modtime = 10**2
        self.fs.file_create(meta, (bytes("FOO", "utf8"), bytes("BAR", "utf8")))
        tfile_abs = join(self.test_dir, new_fn)
        self.tdir.file_check(tfile_abs, exists=True)
        content = self.fs.file_read(meta.filename)

        # Then try with valid meta
        self.fs.meta_update(meta)
        meta.filename = "NEW_FILE2"
        fid = self.fs.file_read(new_fn)
        self.fs.file_create(meta, fid)

    def test_no_cwd(self) -> None:
        self.goto_test_dir()
        curr_dir = os.getcwd()
        self.assertEqual(curr_dir, os.getcwd())

    def test_no_cwd_rm(self) -> None:
        self.goto_test_dir()
        tfile_rel = join(self.foodir, "FUBA")
        tfile_abs = join(self.test_dir, tfile_rel)

        self.tdir.file_check(tfile_abs, exists=True)
        self.fs.trash_add(tfile_rel)
        self.tdir.file_check(tfile_abs, exists=False)
        self.fs.trash_revert(tfile_rel)
        self.tdir.file_check(tfile_abs, exists=True)

    def test_trash_add_missing(self):
        self.fs.trash_add("NONEXISTING", missing_ok=True)
        with self.assertRaises(SA_FS_Exception_NotFound):
            self.fs.trash_add("NONEXISTING2", missing_ok=False)

    def test_goup_on_sub(self) -> None:
        os.chdir(self.foodir)
        self.fs = Filesystem()
        self.fs.go_up_until(self.path_target, )

        conv = self.fs.make_relative(".")
        sub_foo = self.foodir
        self.assertEqual(sub_foo, conv)

        conv = self.fs.make_relative("FOO")
        sub_foo = join('dir1', 'dir2', 'dir3', 'FOO')
        self.assertEqual(sub_foo, conv)

        # Check that the absolute is proper
        conv = self.fs.make_relative(join(self.test_dir, "FOO"))
        self.assertEqual('FOO', conv)

        # Check relative down is ok
        conv = self.fs.make_relative(join('..', '..', '..', "FOO"))
        self.assertEqual('FOO', conv)
示例#6
0
 def __init__(self, check) -> None:
     self.start_dir = os.getcwd()
     self.test_dir = tempfile.mkdtemp()
     self.fs = Filesystem(self.test_dir)
     self.check = check
示例#7
0
class TempDir:
    def __init__(self, check) -> None:
        self.start_dir = os.getcwd()
        self.test_dir = tempfile.mkdtemp()
        self.fs = Filesystem(self.test_dir)
        self.check = check

    def clean(self) -> None:
        os.chdir(self.start_dir)
        shutil.rmtree(self.test_dir)

    def file_del(self, filename):
        fn = Path(self.fs.make_absolute(filename))
        os.unlink(str(fn))

    def file_check(self, filename, exists, checksum=None):
        fn = Path(self.fs.make_absolute(filename))
        self.check(exists, fn.exists())
        if checksum != None:
            meta = Meta(filename)
            self.fs.meta_update(meta)
            self.check(meta.checksum, checksum)

    def file_copy(self, filename_source: str, filename_target: str) -> None:
        fid = self.fs.file_read(filename_source)
        meta = Meta(filename_target)
        self.fs.file_create(meta, fid)

    def file_make(
        self,
        filename: str,
        content: str = None,
        timestamp: int = (2**20 + 3145),
        subs=(".", )) -> str:
        basepath = Path(*subs)
        filename = str(basepath / Path(filename))

        absname_path = self.fs._make_absolute(filename)
        self.fs.make_directories(absname_path.parent)
        absname = str(absname_path)

        if content == None:
            content = (absname) * 8

        with open(absname, 'wb') as fid:
            fid.write(bytes(content, "utf8"))

        self.fs._file_set_modtime(absname, timestamp)
        return filename

    def file_make_many(self,
                       filenames,
                       basepath=(".", ),
                       content=None,
                       timestamp=2**20 + 3145):
        created = []
        for fn in filenames:
            fn = self.file_make(fn,
                                content=content,
                                timestamp=timestamp,
                                subs=basepath)
            created.append(fn)
        return created
示例#8
0
class RepoInDir(TempDir):
    def __init__(self, name: str, assertfun) -> None:
        super().__init__(assertfun)
        self.no_cd = None  # type: bool
        self.name = name
        self.check = assertfun
        self.main("init", self.name)
        self.fs = Filesystem(self.test_dir)
        self.db = DatabaseJson()
        self.db_sizes = (0, 0, 0)

    def open_db(self):
        self.db.open_from_path(self.fs.make_absolute(CONFIG.PATH))

    def commit_check_log(self, with_output=False):
        self.main("commit")
        self.main("verify")
        self.main("status")
        self.main("log")

    def db_get(self, filename) -> Meta:
        self.open_db()
        return self.db.meta_get(filename)

    def db_update_size(self):
        self.open_db()
        self.db_sizes = self.db.get_table_sizes()

    def db_is_reverted(self, filename, status):
        self.check(status,
                   Meta.CHECKSUM_REVERTED == self.db_get(filename).checksum)

    def db_check_size(self, n_commits, n_stor, n_staging, absolute=False):
        self.open_db()
        lens = self.db.get_table_sizes()
        add_sizes = self.db_sizes
        if absolute == True:
            add_sizes = (
                0,
                0,
                0,
            )

        self.check(add_sizes[0] + n_commits, lens[0])
        self.check(add_sizes[1] + n_stor, lens[1])
        self.check(add_sizes[2] + n_staging, lens[2])

    def main_set_cwd(self, no_cd):
        self.no_cd = no_cd

    def main(self, *arguments, assumed_ret=0, verbose=False, no_cd=None):

        if no_cd == None:
            if self.no_cd != None:
                no_cd = self.no_cd
            else:
                no_cd = False

        if no_cd == False:
            os.chdir(self.test_dir)

        ret = sarch_main_raw(arguments)
        self.check(ret, assumed_ret)

        if no_cd == False:
            os.chdir(self.start_dir)

    def sync(self, other: 'RepoInDir', assumed_ret: int = 0):
        target = "file:///%s" % other.test_dir
        self.main("sync", target, "--verbose", assumed_ret=assumed_ret)

    def check_equal(self, other: 'RepoInDir'):
        fn_local = {x for x in self.fs.recursive_walk_files(".")}
        fn_remote = {x for x in self.fs.recursive_walk_files(".")}
        self.check(fn_local, fn_remote)

        self.open_db()
        other.open_db()

        # Sets are equal -> all files ok
        for fn in fn_local:
            meta_local = Meta(fn)
            meta_other = Meta(fn)
            self.fs.meta_update(meta_local)
            other.fs.meta_update(meta_other)

            self.check(meta_local.modtime, meta_other.modtime)
            self.check(meta_local.checksum, meta_other.checksum)

        self.check_databases(other)
        other.check_databases(self)

    def check_databases(self, other: 'RepoInDir'):
        for key in ["stag", "commit", "stor"]:
            values_local = self.db.db[key]
            values_other = other.db.db[key]
            for (key, value) in values_local.items():
                self.check(value, values_other[key])

    def make_std_mods(self):
        self.file_make("FOO", timestamp=(2**10))
        self.main("add", "FOO")
        self.main("commit")
        self.fs.move("FOO", "FOO_NEW")
        self.main("add", "FOO_NEW")
        self.main("rm", "FOO")
        self.main("commit")
        self.main("status")
        self.file_copy("BAR", "BAR_COPY")
        self.main("add", "BAR_COPY")
        self.file_make("FOO_NEW", timestamp=(2**12))
        self.main("add", "FOO_NEW")
        self.commit_check_log()

    def fillup_std_layout(self):
        files = []
        files += self.file_make_many(
            ["FOO", "BAR", "REMOVED", "REMOVED_ADDED"])
        files += self.file_make_many(["FOO", "BAR"], basepath=["dir1", "dir2"])
        files += self.file_make_many([
            "FOO",
        ], basepath=["sdir1", "sdir2"])
        self.main("add", *files)
        self.main("commit", "--msg", "Initial commit")
        self.main("rm", "REMOVED", "REMOVED_ADDED")
        self.main("commit", )
        self.file_make("REMOVED_ADDED", timestamp=2**20 + 3144)
        self.main("add", "REMOVED_ADDED")
        self.main("commit", )
示例#9
0
def main(commandline_args: List[str]) -> int:
    cmdline, unknown = get_parameters_common().parse_known_args(
        commandline_args)
    registered_commands = get_commands()
    registered_commands["help"] = (command_print_help, {
        'help_on': {
            'nargs': '?',
            'help': 'Help from what command'
        }
    }, {
        CommandFlags.COMMAND_NO_DB: True,
        CommandFlags.COMMAND_WITH_DIRTY_SYNC: True
    })

    if cmdline.command not in registered_commands:
        print_error("Command '%s' is not registered." % cmdline.command)
        return -1

    if cmdline.verbose == True:
        CONFIG.VERBOSE = 1

    fun, params_raw, fun_props = registered_commands[cmdline.command]
    params, params_properties = get_parameters_command(commandline_args,
                                                       params_raw)

    filesystem = Filesystem()
    params["database"] = None
    params["filesystem"] = filesystem

    if CommandFlags.COMMAND_NO_DB not in fun_props:
        try:
            filesystem.go_up_until(CONFIG.PATH)
        except SA_FS_Exception_NotFound as err:

            if CommandFlags.COMMAND_NO_DB_OK in fun_props:
                database = None
            else:
                print_error("Cannot find repository, root reached.")
                return -1
        else:
            for key, key_prop in params_properties.items():
                if CommandFlags.ARG_IS_PATH in key_prop:
                    try:
                        params[key] = filesystem.make_relative(params[key])
                    except SA_FS_Exception_NotFound as err:
                        if CommandFlags.ARG_PATH_MAYBE in key_prop:
                            params[key] = filesystem.make_relative(
                                params[key], no_resolve=True)
                        else:
                            print_error(str(err))
                            return -1
                if CommandFlags.ARG_IS_NOT_RELATIVE_PATH in key_prop:
                    try:
                        params[key] = filesystem.make_relative(params[key])
                    except:
                        pass  # This is the wanted case, it should not be relative.
                    else:
                        print_error(
                            "Path '%s' is relative to Sarch root. This command requires other path."
                        )
                        return -1

            database = open_database(filesystem.make_absolute(CONFIG.PATH))

            if (database.get_status() == DatabaseBase.STATUS_SYNC) and (
                    CommandFlags.COMMAND_WITH_DIRTY_SYNC not in fun_props):
                print_error(
                    "Repository is in sync mode. Use 'sync --clear' to reset this or run sync again"
                )
                return -1

        params["database"] = database

    # The database was not wanted -> we do not open database or change directory
    try:
        ret = fun(**params)
    except SA_Exception as error:
        print_error("%s" % (str(error)))
        ret = -1

    return ret