Example #1
0
def test_remote_fs_observer(remote_fs_observer, tmpdir):
    from robocorp_ls_core import watchdog_wrapper
    from robocorp_ls_core.watchdog_wrapper import PathInfo
    from robocorp_ls_core.unittest_tools.fixtures import wait_for_test_condition
    from robocorp_ls_core.watchdog_wrapper import IFSObserver

    tmpdir.join("dir_not_rec").mkdir()
    tmpdir.join("dir_rec").mkdir()

    found = []

    def on_change(filepath, *args):
        found.append(filepath)
        assert args == ("foo", "bar")

    notifier = watchdog_wrapper.create_notifier(on_change, timeout=0.1)
    observer: IFSObserver = remote_fs_observer

    watch = observer.notify_on_any_change(
        [
            PathInfo(tmpdir.join("dir_not_rec"), False),
            PathInfo(tmpdir.join("dir_rec"), True),
        ],
        notifier.on_change,
        call_args=("foo", "bar"),
    )

    try:
        tmpdir.join("dir_not_rec").join("mya.txt").write("foo")
        tmpdir.join("dir_not_rec").join("mya.libspec").write("foo")

        tmpdir.join("dir_rec").join("myb.txt").write("foo")
        tmpdir.join("dir_rec").join("myb.libspec").write("foo")

        def collect_basenames():
            import os.path

            basenames = [os.path.basename(x) for x in found]
            return set(basenames)

        def check1():
            expected = {"myb.txt", "mya.libspec", "myb.libspec", "mya.txt"}
            return collect_basenames().issuperset(expected)

        wait_for_test_condition(
            check1, msg=lambda: f"Basenames found: {collect_basenames()}"
        )

    finally:
        watch.stop_tracking()
        notifier.dispose()
        observer.dispose()
Example #2
0
    def __init__(self, builtin_libspec_dir=None, user_libspec_dir=None):
        """
        :param __internal_libspec_dir__:
            Only to be used in tests (to regenerate the builtins)!
        """
        from robocorp_ls_core import watchdog_wrapper

        self._libspec_failures_cache: Dict[tuple, bool] = {}

        self._main_thread = threading.current_thread()

        watch_impl = os.environ.get("ROBOTFRAMEWORK_LS_WATCH_IMPL", "watchdog")
        if watch_impl not in ("watchdog", "fsnotify"):
            log.info(
                f"ROBOTFRAMEWORK_LS_WATCH_IMPL should be 'watchdog' or 'fsnotify'. Found: {watch_impl} (falling back to fsnotify)"
            )
            # i.e.: the default is watchdog, so, if a different one is set,
            # presumably the default is not ok, so, fall back to watchdog.
            watch_impl = "fsnotify"

        self._observer = watchdog_wrapper.create_observer(
            watch_impl, (".py", ".libspec")
        )

        self._file_changes_notifier = watchdog_wrapper.create_notifier(
            self._on_file_changed, timeout=0.5
        )

        self._libspec_dir = self.get_internal_libspec_dir()

        self._user_libspec_dir = user_libspec_dir or os.path.join(
            self._libspec_dir, "user"
        )
        self._builtins_libspec_dir = (
            builtin_libspec_dir
            or self.get_internal_builtins_libspec_dir(self._libspec_dir)
        )
        log.debug("User libspec dir: %s", self._user_libspec_dir)
        log.debug("Builtins libspec dir: %s", self._builtins_libspec_dir)

        try:
            os.makedirs(self._user_libspec_dir)
        except:
            # Ignore exception if it's already created.
            pass
        try:
            os.makedirs(self._builtins_libspec_dir)
        except:
            # Ignore exception if it's already created.
            pass

        # Spec info found in the workspace
        self._workspace_folder_uri_to_folder_info = {}
        self._additional_pythonpath_folder_to_folder_info = {}

        # Spec info found in the pythonpath
        pythonpath_folder_to_folder_info = {}
        for path in sys.path:
            if path and os.path.isdir(path):
                pythonpath_folder_to_folder_info[path] = _FolderInfo(
                    path, recursive=False
                )
        self._pythonpath_folder_to_folder_info = pythonpath_folder_to_folder_info

        # Spec info found in internal dirs (autogenerated)
        self._internal_folder_to_folder_info = {
            self._user_libspec_dir: _FolderInfo(
                self._user_libspec_dir, recursive=False
            ),
            self._builtins_libspec_dir: _FolderInfo(
                self._builtins_libspec_dir, recursive=False
            ),
        }

        # Must be set from the outside world when needed.
        self.config = None

        log.debug("Generating builtin libraries.")
        self._gen_builtin_libraries()
        log.debug("Synchronizing internal caches.")
        self._synchronize()
        log.debug("Finished initializing LibspecManager.")
Example #3
0
def test_watchdog_extensions(tmpdir):
    from robocorp_ls_core import watchdog_wrapper
    from robocorp_ls_core.watchdog_wrapper import PathInfo
    from robocorp_ls_core.unittest_tools.fixtures import wait_for_test_condition

    tmpdir.join("dir_not_rec").mkdir()
    tmpdir.join("dir_rec").mkdir()

    found = []

    def on_change(filepath, *args):
        found.append(filepath)
        assert args == ("foo", "bar")

    notifier = watchdog_wrapper.create_notifier(on_change, timeout=0.1)
    observer = watchdog_wrapper.create_observer()

    watch = observer.notify_on_extensions_change(
        [
            PathInfo(tmpdir.join("dir_not_rec"), False),
            PathInfo(tmpdir.join("dir_rec"), True),
        ],
        ["libspec"],
        notifier.on_change,
        call_args=("foo", "bar"),
    )

    try:
        tmpdir.join("my.txt").write("foo")
        tmpdir.join("my.libspec").write("foo")

        tmpdir.join("dir_not_rec").join("mya.txt").write("foo")
        tmpdir.join("dir_not_rec").join("mya.libspec").write("foo")

        tmpdir.join("dir_rec").join("myb.txt").write("foo")
        tmpdir.join("dir_rec").join("myb.libspec").write("foo")

        def check1():
            found_my_a = False
            found_my_b = False
            for filepath in found:
                if not filepath.endswith(".libspec"):
                    raise AssertionError(
                        "Expected only libspec files to be tracked.")
                if filepath.endswith("my.libspec"):
                    raise AssertionError("Wrong folder tracked.")
                found_my_a = found_my_a or "mya.libspec" in filepath
                found_my_b = found_my_b or "myb.libspec" in filepath

            return found_my_a and found_my_b

        wait_for_test_condition(
            check1,
            msg=lambda:
            "Expected to find mya.libspec and myb.libspec. Found:\n%s" %
            ("\n".join(found), ),
        )

        # not listened
        tmpdir.join("dir_not_rec").join("another").mkdir()
        tmpdir.join("dir_not_rec").join("another").join("myc.txt").write("foo")
        tmpdir.join("dir_not_rec").join("another").join("myc.libspec").write(
            "foo")

        # listened
        tmpdir.join("dir_rec").join("another").mkdir()
        tmpdir.join("dir_rec").join("another").join("myd.txt").write("foo")
        tmpdir.join("dir_rec").join("another").join("myd.libspec").write("foo")

        del found[:]

        def check2():
            found_my_d = False
            for filepath in found:
                if not filepath.endswith(".libspec"):
                    raise AssertionError(
                        "Expected only libspec files to be tracked.")
                if filepath.endswith("myc.libspec"):
                    raise AssertionError("Wrong folder tracked.")
                found_my_d = found_my_d or "myd.libspec" in filepath

            return found_my_d

        wait_for_test_condition(
            check2,
            msg=lambda: "Expected to find myd.libspec. Found:\n%s" %
            ("\n".join(found), ),
        )

        watch.stop_tracking()
        del found[:]
        tmpdir.join("dir_rec").join("mye.txt").write("foo")
        tmpdir.join("dir_rec").join("mye.libspec").write("foo")

        # Give time to check if some change arrives.
        time.sleep(1)
        assert not found

    finally:
        notifier.dispose()
        observer.dispose()
Example #4
0
    def __init__(self, builtin_libspec_dir=None, user_libspec_dir=None):
        """
        :param __internal_libspec_dir__:
            Only to be used in tests (to regenerate the builtins)!
        """

        from robocorp_ls_core import watchdog_wrapper

        self._libspec_failures_cache: Dict[tuple, bool] = {}

        self._main_thread = threading.current_thread()

        self._observer = watchdog_wrapper.create_observer()

        self._file_changes_notifier = watchdog_wrapper.create_notifier(
            self._on_file_changed, timeout=0.5)

        self._root_uri = None

        self._libspec_dir = self.get_internal_libspec_dir()

        self._user_libspec_dir = user_libspec_dir or os.path.join(
            self._libspec_dir, "user")
        self._builtins_libspec_dir = (
            builtin_libspec_dir
            or self.get_internal_builtins_libspec_dir(self._libspec_dir))
        log.debug("User libspec dir: %s", self._user_libspec_dir)
        log.debug("Builtins libspec dir: %s", self._builtins_libspec_dir)

        try:
            os.makedirs(self._user_libspec_dir)
        except BaseException:
            # Ignore exception if it's already created.
            pass
        try:
            os.makedirs(self._builtins_libspec_dir)
        except BaseException:
            # Ignore exception if it's already created.
            pass

        self.libspec_errors: Dict[LibspecErrorEntry, str] = {}
        self.libspec_warnings: Dict[LibspecErrorEntry, str] = {}

        # Spec info found in the workspace
        self._workspace_folder_uri_to_folder_info = {}
        self._additional_pythonpath_folder_to_folder_info = {}

        # Spec info found in the pythonpath
        pythonpath_folder_to_folder_info = {}
        for path in sys.path:
            if path and os.path.isdir(path):
                pythonpath_folder_to_folder_info[path] = _FolderInfo(
                    path, recursive=False)
        self._pythonpath_folder_to_folder_info = pythonpath_folder_to_folder_info

        # Spec info found in internal dirs (autogenerated)
        self._internal_folder_to_folder_info = {
            self._user_libspec_dir:
            _FolderInfo(self._user_libspec_dir, recursive=False),
            self._builtins_libspec_dir:
            _FolderInfo(self._builtins_libspec_dir, recursive=False),
        }

        # Must be set from the outside world when needed.
        self.config = None

        self.process_pool = ProcessPoolExecutor()

        # we have to submit a dummy process to start the process pool,
        # because it does not start correctly if we do it from another
        # thread
        self.process_pool.submit(dummy_process).result()

        self.thread_pool = ThreadPoolExecutor(
            thread_name_prefix="libspec_manager_")

        log.debug("Generating builtin libraries.")
        self._gen_builtin_libraries()
        log.debug("Synchronizing internal caches.")
        self._synchronize()
        log.debug("Finished initializing LibspecManager.")
Example #5
0
    def __init__(self, builtin_libspec_dir=None, user_libspec_dir=None):
        """
        :param __internal_libspec_dir__:
            Only to be used in tests (to regenerate the builtins)!
        """
        from robocorp_ls_core import watchdog_wrapper

        self._main_thread = threading.current_thread()

        self._observer = watchdog_wrapper.create_observer()

        self._spec_changes_notifier = watchdog_wrapper.create_notifier(
            self._on_spec_file_changed, timeout=0.5)

        self._libspec_dir = self.get_internal_libspec_dir()

        self._user_libspec_dir = user_libspec_dir or os.path.join(
            self._libspec_dir, "user")
        self._builtins_libspec_dir = (
            builtin_libspec_dir
            or self.get_internal_builtins_libspec_dir(self._libspec_dir))
        log.debug("User libspec dir: %s", self._user_libspec_dir)
        log.debug("Builtins libspec dir: %s", self._builtins_libspec_dir)

        try:
            os.makedirs(self._user_libspec_dir)
        except:
            # Ignore exception if it's already created.
            pass
        try:
            os.makedirs(self._builtins_libspec_dir)
        except:
            # Ignore exception if it's already created.
            pass

        # Spec info found in the workspace
        self._workspace_folder_uri_to_folder_info = {}
        self._additional_pythonpath_folder_to_folder_info = {}

        # Spec info found in the pythonpath
        pythonpath_folder_to_folder_info = {}
        for path in sys.path:
            if path and os.path.isdir(path):
                pythonpath_folder_to_folder_info[path] = _FolderInfo(
                    path, recursive=False)
        self._pythonpath_folder_to_folder_info = pythonpath_folder_to_folder_info

        # Spec info found in internal dirs (autogenerated)
        self._internal_folder_to_folder_info = {
            self._user_libspec_dir:
            _FolderInfo(self._user_libspec_dir, recursive=False),
            self._builtins_libspec_dir:
            _FolderInfo(self._builtins_libspec_dir, recursive=False),
        }

        # Must be set from the outside world when needed.
        self.config = None

        log.debug("Generating builtin libraries.")
        self._gen_builtin_libraries()
        log.debug("Synchronizing internal caches.")
        self._synchronize()
        log.debug("Finished initializing LibspecManager.")
    def __init__(self, builtin_libspec_dir=None, user_libspec_dir=None):
        """
        :param __internal_libspec_dir__:
            Only to be used in tests (to regenerate the builtins)!
        """
        from robocorp_ls_core import watchdog_wrapper

        self._libspec_failures_cache: Dict[tuple, bool] = {}

        self._main_thread = threading.current_thread()

        watch_impl = os.environ.get("ROBOTFRAMEWORK_LS_WATCH_IMPL", "auto")
        if watch_impl not in ("watchdog", "fsnotify", "auto"):
            log.info(
                f"ROBOTFRAMEWORK_LS_WATCH_IMPL should be 'auto', 'watchdog' or 'fsnotify'. Found: {watch_impl} (falling back to auto)"
            )
            watch_impl = "auto"

        if watch_impl == "auto":
            # In auto mode we use watchdog for windows and fsnotify (polling)
            # for Linux and Mac. The reason for that is that on Linux and Mac
            # if big folders are watched the system may complain due to the
            # lack of resources, which may prevent the extension from working
            # properly.
            #
            # If users want to opt-in, they can change to watchdog (and
            # ideally install it to their env to get native extensions).
            if sys.platform == "win32":
                watch_impl = "watchdog"
            else:
                watch_impl = "fsnotify"

        self._observer = watchdog_wrapper.create_observer(
            watch_impl, (".py", ".libspec")
        )

        self._file_changes_notifier = watchdog_wrapper.create_notifier(
            self._on_file_changed, timeout=0.5
        )

        self._libspec_dir = self.get_internal_libspec_dir()

        self._user_libspec_dir = user_libspec_dir or os.path.join(
            self._libspec_dir, "user"
        )
        self._builtins_libspec_dir = (
            builtin_libspec_dir
            or self.get_internal_builtins_libspec_dir(self._libspec_dir)
        )
        log.debug("User libspec dir: %s", self._user_libspec_dir)
        log.debug("Builtins libspec dir: %s", self._builtins_libspec_dir)

        try:
            os.makedirs(self._user_libspec_dir)
        except:
            # Ignore exception if it's already created.
            pass
        try:
            os.makedirs(self._builtins_libspec_dir)
        except:
            # Ignore exception if it's already created.
            pass

        # Spec info found in the workspace
        self._workspace_folder_uri_to_folder_info = {}
        self._additional_pythonpath_folder_to_folder_info = {}

        # Spec info found in the pythonpath
        pythonpath_folder_to_folder_info = {}
        for path in sys.path:
            if path and os.path.isdir(path):
                pythonpath_folder_to_folder_info[path] = _FolderInfo(
                    path, recursive=False
                )
        self._pythonpath_folder_to_folder_info = pythonpath_folder_to_folder_info

        # Spec info found in internal dirs (autogenerated)
        self._internal_folder_to_folder_info = {
            self._user_libspec_dir: _FolderInfo(
                self._user_libspec_dir, recursive=False
            ),
            self._builtins_libspec_dir: _FolderInfo(
                self._builtins_libspec_dir, recursive=False
            ),
        }

        # Must be set from the outside world when needed.
        self.config = None

        log.debug("Generating builtin libraries.")
        self._gen_builtin_libraries()
        log.debug("Synchronizing internal caches.")
        self._synchronize()
        log.debug("Finished initializing LibspecManager.")