コード例 #1
0
 def cure_what_ails_you(self, dry_run: bool) -> TestOutput:
     out = TestOutput()
     doctor.cure_what_ails_you(
         typing.cast(EdenInstance, self.instance),
         dry_run,
         self.instance.mount_table,
         fs_util=filesystem.LinuxFsUtil(),
         process_finder=self.make_process_finder(),
         out=out,
     )
     return out
コード例 #2
0
 def cure_what_ails_you(self, dry_run: bool) -> TestOutput:
     out = TestOutput()
     doctor.cure_what_ails_you(
         typing.cast(EdenInstance, self.instance),
         dry_run,
         self.instance.mount_table,
         fs_util=filesystem.LinuxFsUtil(),
         process_finder=self.make_process_finder(),
         out=out,
     )
     return out
コード例 #3
0
ファイル: doctor_test.py プロジェクト: x414e54/eden
    def test_edenfs_stopping(self, mock_get_roots_for_nuclide, mock_watchman):
        instance = FakeEdenInstance(
            self.make_temporary_directory(), status=fb303_status.STOPPING
        )
        instance.create_test_mount("eden-mount")

        out = TestOutput()
        dry_run = False
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            FakeMountTable(),
            fs_util=FakeFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            """\
<yellow>- Found problem:<reset>
Eden is currently shutting down.
Either wait for edenfs to exit, or to forcibly kill Eden, run:

    eden stop --kill

<yellow>1 issue requires manual attention.<reset>
Ask in the Eden Users group if you need help fixing issues with Eden:
https://fb.facebook.com/groups/eden.users/
""",
            out.getvalue(),
        )
        self.assertEqual(1, exit_code)
コード例 #4
0
ファイル: doctor_test.py プロジェクト: x414e54/eden
    def test_unconfigured_mounts_dont_crash(self, mock_get_roots_for_nuclide):
        # If Eden advertises that a mount is active, but it is not in the
        # configuration, then at least don't throw an exception.
        instance = FakeEdenInstance(self.make_temporary_directory())
        edenfs_path1 = instance.create_test_mount("path1").path
        edenfs_path2 = instance.create_test_mount("path2").path
        # Remove path2 from the list of mounts in the instance
        instance.remove_checkout_configuration(str(edenfs_path2))

        dry_run = False
        out = TestOutput()
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            instance.mount_table,
            fs_util=FakeFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            f"""\
Checking {edenfs_path1}
Checking {edenfs_path2}
<yellow>- Found problem:<reset>
Checkout {edenfs_path2} is running but not listed in Eden's configuration file.
Running "eden unmount {edenfs_path2}" will unmount this checkout.

<yellow>1 issue requires manual attention.<reset>
Ask in the Eden Users group if you need help fixing issues with Eden:
https://fb.facebook.com/groups/eden.users/
""",
            out.getvalue(),
        )
        self.assertEqual(1, exit_code)
コード例 #5
0
ファイル: doctor_test.py プロジェクト: x414e54/eden
    def _test_remount_checkouts(
        self,
        mock_get_roots_for_nuclide,
        mock_watchman,
        dry_run: bool,
        old_edenfs: bool = False,
    ) -> Tuple[int, str, List[Path]]:
        """Test that `eden doctor` remounts configured mount points that are not
        currently mounted.
        """
        tmp_dir = self.make_temporary_directory()
        instance = FakeEdenInstance(tmp_dir)

        mounts = []
        mount1 = instance.create_test_mount("path1")
        mounts.append(mount1.path)
        mounts.append(instance.create_test_mount("path2", active=False).path)
        if old_edenfs:
            # Mimic older versions of edenfs, and do not return mount state data.
            instance.get_thrift_client().change_mount_state(mount1.path, None)

        out = TestOutput()
        exit_code = doctor.cure_what_ails_you(
            typing.cast(EdenInstance, instance),
            dry_run,
            instance.mount_table,
            fs_util=FakeFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )
        return exit_code, out.getvalue(), mounts
コード例 #6
0
    def test_not_much_to_do_when_eden_is_not_running(self, mock_watchman):
        edenfs_path = '/path/to/eden-mount'
        side_effects: List[Dict[str, Any]] = []
        calls = []

        calls.append(call(['watch-list']))
        side_effects.append({'roots': [edenfs_path]})
        mock_watchman.side_effect = side_effects

        out = io.StringIO()
        dry_run = False
        mount_paths = {
            edenfs_path: {
                'bind-mounts': {},
                'mount': edenfs_path,
                'scm_type': 'hg',
                'snapshot': 'abcd' * 10,
                'client-dir': '/I_DO_NOT_EXIST'
            }
        }
        config = FakeConfig(mount_paths, is_healthy=False)
        exit_code = doctor.cure_what_ails_you(config, dry_run, out)

        self.assertEqual(
            'Eden is not running: cannot perform all checks.\n'
            'Performing 3 checks for /path/to/eden-mount.\n'
            'All is well.\n', out.getvalue()
        )
        mock_watchman.assert_has_calls(calls)
        self.assertEqual(0, exit_code)
コード例 #7
0
    def test_edenfs_starting(self, mock_get_roots_for_nuclide, mock_watchman):
        instance = FakeEdenInstance(
            self.make_temporary_directory(), status=fb_status.STARTING
        )
        instance.create_test_mount("eden-mount")

        out = TestOutput()
        dry_run = False
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            FakeMountTable(),
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            """\
<yellow>- Found problem:<reset>
Eden is currently still starting.
Please wait for edenfs to finish starting.
If Eden seems to be taking too long to start you can try restarting it
with "eden restart"

<yellow>1 issue requires manual attention.<reset>
Ask in the Eden Users group if you need help fixing issues with Eden:
https://fb.facebook.com/groups/eden.users/
""",
            out.getvalue(),
        )
        self.assertEqual(1, exit_code)
コード例 #8
0
    def test_edenfs_stopping(self, mock_get_roots_for_nuclide, mock_watchman):
        instance = FakeEdenInstance(
            self.make_temporary_directory(), status=fb_status.STOPPING
        )
        instance.create_test_mount("eden-mount")

        out = TestOutput()
        dry_run = False
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            FakeMountTable(),
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            """\
<yellow>- Found problem:<reset>
Eden is currently shutting down.
Either wait for edenfs to exit, or to forcibly kill Eden, run:

    eden stop --kill

<yellow>1 issue requires manual attention.<reset>
Ask in the Eden Users group if you need help fixing issues with Eden:
https://fb.facebook.com/groups/eden.users/
""",
            out.getvalue(),
        )
        self.assertEqual(1, exit_code)
コード例 #9
0
    def test_edenfs_not_running(self, mock_get_roots_for_nuclide,
                                mock_watchman):
        instance = FakeEdenInstance(self.make_temporary_directory(),
                                    status=fb_status.DEAD)
        instance.create_test_mount("eden-mount")

        out = TestOutput()
        dry_run = False
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            FakeMountTable(),
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            """\
<yellow>- Found problem:<reset>
Eden is not running.
To start Eden, run:

    eden start

<yellow>1 issue requires manual attention.<reset>
Ask in the Eden Users group if you need help fixing issues with Eden:
https://fb.facebook.com/groups/eden.users/
""",
            out.getvalue(),
        )
        self.assertEqual(1, exit_code)
コード例 #10
0
ファイル: nfs_test.py プロジェクト: facebookexperimental/eden
    def test_nfs_mounted(self, mock_is_nfs_mounted):
        mock_is_nfs_mounted.return_value = True
        instance = FakeEdenInstance(self.make_temporary_directory())
        checkout = instance.create_test_mount("mount_dir")

        dry_run = True
        out = TestOutput()
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            instance.mount_table,
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )
        expected = f"""\
<yellow>- Found problem:<reset>
Eden's state directory is on an NFS file system: {instance.state_dir}
  This will likely cause performance problems and/or other errors.
The most common cause for this is if your ~/local symlink does not point to local disk.\
  Make sure that ~/local is a symlink pointing to local disk and then restart Eden.

Checking {checkout.path}
<yellow>- Found problem:<reset>
The Mercurial data directory for {checkout.path}/.hg/sharedpath is at \
{instance.default_backing_repo}/.hg which is on a NFS filesystem. \
Accessing files and directories in this repository will be slow.
<yellow>Discovered 2 problems during --dry-run<reset>
"""
        self.assertEqual(expected, out.getvalue())
        self.assertEqual(1, exit_code)
コード例 #11
0
ファイル: nfs_test.py プロジェクト: JoeLoser/eden
    def test_nfs_mounted(self, mock_is_nfs_mounted):
        mock_is_nfs_mounted.return_value = True
        instance = FakeEdenInstance(self.make_temporary_directory())
        checkout = instance.create_test_mount("mount_dir")

        dry_run = True
        out = TestOutput()
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            instance.mount_table,
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )
        expected = f"""\
<yellow>- Found problem:<reset>
Eden's state directory is on an NFS file system: {instance.state_dir}
  This will likely cause performance problems and/or other errors.
The most common cause for this is if your ~/local symlink does not point to local disk.\
  Make sure that ~/local is a symlink pointing to local disk and then restart Eden.

Checking {checkout.path}
<yellow>- Found problem:<reset>
The Mercurial data directory for {checkout.path}/.hg/sharedpath is at \
{instance.default_backing_repo}/.hg which is on a NFS filesystem. \
Accessing files and directories in this repository will be slow.
<yellow>Discovered 2 problems during --dry-run<reset>
"""
        self.assertEqual(expected, out.getvalue())
        self.assertEqual(1, exit_code)
コード例 #12
0
    def _test_remount_checkouts(
        self,
        mock_get_roots_for_nuclide,
        mock_watchman,
        dry_run: bool,
        old_edenfs: bool = False,
    ) -> Tuple[int, str, List[Path]]:
        """Test that `eden doctor` remounts configured mount points that are not
        currently mounted.
        """
        tmp_dir = self.make_temporary_directory()
        instance = FakeEdenInstance(tmp_dir)

        mounts = []
        mount1 = instance.create_test_mount("path1")
        mounts.append(mount1.path)
        mounts.append(instance.create_test_mount("path2", active=False).path)
        if old_edenfs:
            # Mimic older versions of edenfs, and do not return mount state data.
            instance.get_thrift_client().change_mount_state(mount1.path, None)

        out = TestOutput()
        exit_code = doctor.cure_what_ails_you(
            typing.cast(EdenInstance, instance),
            dry_run,
            instance.mount_table,
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )
        return exit_code, out.getvalue(), mounts
コード例 #13
0
    def test_unconfigured_mounts_dont_crash(self, mock_get_roots_for_nuclide):
        # If Eden advertises that a mount is active, but it is not in the
        # configuration, then at least don't throw an exception.
        instance = FakeEdenInstance(self.make_temporary_directory())
        edenfs_path1 = instance.create_test_mount("path1").path
        edenfs_path2 = instance.create_test_mount("path2").path
        # Remove path2 from the list of mounts in the instance
        instance.remove_checkout_configuration(str(edenfs_path2))

        dry_run = False
        out = TestOutput()
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            instance.mount_table,
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            f"""\
Checking {edenfs_path1}
Checking {edenfs_path2}
<yellow>- Found problem:<reset>
Checkout {edenfs_path2} is running but not listed in Eden's configuration file.
Running "eden unmount {edenfs_path2}" will unmount this checkout.

<yellow>1 issue requires manual attention.<reset>
Ask in the Eden Users group if you need help fixing issues with Eden:
https://fb.facebook.com/groups/eden.users/
""",
            out.getvalue(),
        )
        self.assertEqual(1, exit_code)
コード例 #14
0
ファイル: doctor_test.py プロジェクト: x414e54/eden
    def test_edenfs_starting(self, mock_get_roots_for_nuclide, mock_watchman):
        instance = FakeEdenInstance(
            self.make_temporary_directory(), status=fb303_status.STARTING
        )
        instance.create_test_mount("eden-mount")

        out = TestOutput()
        dry_run = False
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            FakeMountTable(),
            fs_util=FakeFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            """\
<yellow>- Found problem:<reset>
Eden is currently still starting.
Please wait for edenfs to finish starting.
If Eden seems to be taking too long to start you can try restarting it
with "eden restart"

<yellow>1 issue requires manual attention.<reset>
Ask in the Eden Users group if you need help fixing issues with Eden:
https://fb.facebook.com/groups/eden.users/
""",
            out.getvalue(),
        )
        self.assertEqual(1, exit_code)
コード例 #15
0
    def test_fails_if_no_mount_points(self):
        out = io.StringIO()
        dry_run = False
        mount_paths = {}
        config = FakeConfig(mount_paths, is_healthy=False)

        exit_code = doctor.cure_what_ails_you(config, dry_run, out)
        self.assertEqual('No mounts points to assess.\n', out.getvalue())
        self.assertEqual(1, exit_code)
コード例 #16
0
    def test_unconfigured_mounts_dont_crash(self):
        # If Eden advertises that a mount is active, but it is not in the
        # configuration, then at least don't throw an exception.
        tmp_dir = tempfile.mkdtemp(prefix='eden_test.')
        try:
            edenfs_path1 = os.path.join(tmp_dir, 'path1')
            edenfs_path2 = os.path.join(tmp_dir, 'path2')

            mount_paths = OrderedDict()
            mount_paths[edenfs_path1] = {
                'bind-mounts': {},
                'mount': edenfs_path1,
                'scm_type': 'hg',
                'snapshot': 'abcd' * 10,
                'client-dir': '/I_DO_NOT_EXIST1'
            }
            # path2 is not configured in the config...
            config = FakeConfig(mount_paths, is_healthy=True)
            # ... but is advertised by the daemon...
            config.get_thrift_client()._mounts = [
                eden_ttypes.MountInfo(mountPoint=edenfs_path1),
                eden_ttypes.MountInfo(mountPoint=edenfs_path2),
            ]

            # ... and is in the system mount table.
            mount_table = FakeMountTable()
            mount_table.stats[edenfs_path1] = mtab.MTStat(st_uid=os.getuid(),
                                                          st_dev=11)
            mount_table.stats[edenfs_path2] = mtab.MTStat(st_uid=os.getuid(),
                                                          st_dev=12)

            os.mkdir(edenfs_path1)
            hg_dir = os.path.join(edenfs_path1, '.hg')
            os.mkdir(hg_dir)
            dirstate = os.path.join(hg_dir, 'dirstate')
            dirstate_hash = b'\xab\xcd' * 10
            parents = (dirstate_hash, b'\x00' * 20)
            with open(dirstate, 'wb') as f:
                eden.dirstate.write(f, parents, tuples_dict={}, copymap={})

            dry_run = False
            out = io.StringIO()
            exit_code = doctor.cure_what_ails_you(config, dry_run, out,
                                                  mount_table)
        finally:
            shutil.rmtree(tmp_dir)

        self.assertEqual(
            f'''\
Performing 3 checks for {edenfs_path1}.
All is well.
''', out.getvalue())
        self.assertEqual(0, exit_code)
コード例 #17
0
    def test_not_all_mounts_have_watchman_watcher(self, mock_watchman):
        edenfs_path = '/path/to/eden-mount'
        edenfs_path_not_watched = '/path/to/eden-mount-not-watched'
        side_effects: List[Dict[str, Any]] = []
        calls = []

        calls.append(call(['watch-list']))
        side_effects.append({'roots': [edenfs_path]})
        calls.append(call(['watch-project', edenfs_path]))
        side_effects.append({'watcher': 'eden'})
        calls.append(call(['debug-get-subscriptions', edenfs_path]))
        side_effects.append({})
        mock_watchman.side_effect = side_effects

        out = io.StringIO()
        dry_run = False
        mount_paths = OrderedDict()
        mount_paths[edenfs_path] = {
            'bind-mounts': {},
            'mount': edenfs_path,
            'scm_type': 'git',
            'snapshot': 'abcd' * 10,
            'client-dir': '/I_DO_NOT_EXIST'
        }
        mount_paths[edenfs_path_not_watched] = {
            'bind-mounts': {},
            'mount': edenfs_path_not_watched,
            'scm_type': 'git',
            'snapshot': 'abcd' * 10,
            'client-dir': '/I_DO_NOT_EXIST'
        }
        config = FakeConfig(mount_paths, is_healthy=True)
        config.get_thrift_client()._mounts = [
            eden_ttypes.MountInfo(mountPoint=edenfs_path),
            eden_ttypes.MountInfo(mountPoint=edenfs_path_not_watched),
        ]
        mount_table = FakeMountTable()
        mount_table.stats['/path/to/eden-mount'] = mtab.MTStat(
            st_uid=os.getuid(), st_dev=10)
        mount_table.stats['/path/to/eden-mount-not-watched'] = mtab.MTStat(
            st_uid=os.getuid(), st_dev=11)
        exit_code = doctor.cure_what_ails_you(config,
                                              dry_run,
                                              out,
                                              mount_table=mount_table)

        self.assertEqual(
            'Performing 2 checks for /path/to/eden-mount.\n'
            'Performing 2 checks for /path/to/eden-mount-not-watched.\n'
            'All is well.\n', out.getvalue())
        mock_watchman.assert_has_calls(calls)
        self.assertEqual(0, exit_code)
コード例 #18
0
    def test_eden_not_in_use(self, mock_get_roots_for_nuclide, mock_watchman):
        instance = FakeEdenInstance(self.make_temporary_directory(),
                                    status=fb_status.DEAD)

        out = TestOutput()
        dry_run = False
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            FakeMountTable(),
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual("Eden is not in use.\n", out.getvalue())
        self.assertEqual(0, exit_code)
コード例 #19
0
    def test_eden_not_in_use(self, mock_get_roots_for_nuclide, mock_watchman):
        instance = FakeEdenInstance(
            self.make_temporary_directory(), status=fb_status.DEAD
        )

        out = TestOutput()
        dry_run = False
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            FakeMountTable(),
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual("Eden is not in use.\n", out.getvalue())
        self.assertEqual(0, exit_code)
コード例 #20
0
ファイル: nfs_test.py プロジェクト: facebookexperimental/eden
    def run_varying_nfs(self, mock_path_read_text):
        instance = FakeEdenInstance(self.make_temporary_directory())
        v = SimpleNamespace(
            mount_dir="mount_dir", shared_path="shared_path", instance=instance
        )
        mock_path_read_text.return_value = v.shared_path
        v.client_path = str(instance.create_test_mount(v.mount_dir).path)

        dry_run = True
        out = TestOutput()
        v.exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            instance.mount_table,
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )
        v.stdout = out.getvalue()
        return v
コード例 #21
0
ファイル: nfs_test.py プロジェクト: JoeLoser/eden
    def run_varying_nfs(self, mock_path_read_text):
        instance = FakeEdenInstance(self.make_temporary_directory())
        v = SimpleNamespace(mount_dir="mount_dir",
                            shared_path="shared_path",
                            instance=instance)
        mock_path_read_text.return_value = v.shared_path
        v.client_path = str(instance.create_test_mount(v.mount_dir).path)

        dry_run = True
        out = TestOutput()
        v.exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            instance.mount_table,
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )
        v.stdout = out.getvalue()
        return v
コード例 #22
0
 def _test_with_pwd(self, instance: "FakeEdenInstance",
                    pwd: Optional[str]) -> Tuple[int, str]:
     if pwd is None:
         old_pwd = os.environ.pop("PWD", None)
     else:
         old_pwd = os.environ.get("PWD")
         os.environ["PWD"] = pwd
     try:
         out = TestOutput()
         exit_code = doctor.cure_what_ails_you(
             typing.cast(EdenInstance, instance),
             dry_run=False,
             mount_table=instance.mount_table,
             fs_util=filesystem.LinuxFsUtil(),
             process_finder=self.make_process_finder(),
             out=out,
         )
         return exit_code, out.getvalue()
     finally:
         if old_pwd is not None:
             os.environ["PWD"] = old_pwd
コード例 #23
0
 def _test_with_pwd(
     self, instance: "FakeEdenInstance", pwd: Optional[str]
 ) -> Tuple[int, str]:
     if pwd is None:
         old_pwd = os.environ.pop("PWD", None)
     else:
         old_pwd = os.environ.get("PWD")
         os.environ["PWD"] = pwd
     try:
         out = TestOutput()
         exit_code = doctor.cure_what_ails_you(
             typing.cast(EdenInstance, instance),
             dry_run=False,
             mount_table=instance.mount_table,
             fs_util=filesystem.LinuxFsUtil(),
             process_finder=self.make_process_finder(),
             out=out,
         )
         return exit_code, out.getvalue()
     finally:
         if old_pwd is not None:
             os.environ["PWD"] = old_pwd
コード例 #24
0
    def test_not_all_mounts_have_watchman_watcher(self,
                                                  mock_get_roots_for_nuclide,
                                                  mock_watchman):
        instance = FakeEdenInstance(self.make_temporary_directory())
        edenfs_path = str(
            instance.create_test_mount("eden-mount", scm_type="git").path)
        edenfs_path_not_watched = str(
            instance.create_test_mount("eden-mount-not-watched",
                                       scm_type="git").path)
        side_effects: List[Dict[str, Any]] = []
        calls = []

        calls.append(call(["watch-list"]))
        side_effects.append({"roots": [edenfs_path]})
        calls.append(call(["watch-project", edenfs_path]))
        side_effects.append({"watcher": "eden"})
        mock_watchman.side_effect = side_effects

        out = TestOutput()
        dry_run = False
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            mount_table=instance.mount_table,
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            f"Checking {edenfs_path}\n"
            f"Checking {edenfs_path_not_watched}\n"
            "<green>No issues detected.<reset>\n",
            out.getvalue(),
        )
        mock_watchman.assert_has_calls(calls)
        self.assertEqual(0, exit_code)
コード例 #25
0
ファイル: doctor_test.py プロジェクト: x414e54/eden
    def test_watchman_fails(self, mock_watchman):
        tmp_dir = self.make_temporary_directory()
        instance = FakeEdenInstance(tmp_dir)

        mount = instance.create_test_mount("path1", active=False).path

        # Make calls to watchman fail rather than returning expected output
        side_effects = [{"error": "watchman failed"}]
        mock_watchman.side_effect = side_effects

        out = TestOutput()
        exit_code = doctor.cure_what_ails_you(
            typing.cast(EdenInstance, instance),
            dry_run=False,
            mount_table=instance.mount_table,
            fs_util=FakeFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        # "watchman watch-list" should have been called by the doctor code
        calls = [call(["watch-list"])]
        mock_watchman.assert_has_calls(calls)

        self.assertEqual(
            out.getvalue(),
            f"""\
Checking {mount}
<yellow>- Found problem:<reset>
{mount} is not currently mounted
Remounting {mount}...<green>fixed<reset>

<yellow>Successfully fixed 1 problem.<reset>
""",
        )
        self.assertEqual(exit_code, 0)
コード例 #26
0
    def test_not_all_mounts_have_watchman_watcher(
        self, mock_get_roots_for_nuclide, mock_watchman
    ):
        instance = FakeEdenInstance(self.make_temporary_directory())
        edenfs_path = str(instance.create_test_mount("eden-mount", scm_type="git").path)
        edenfs_path_not_watched = str(
            instance.create_test_mount("eden-mount-not-watched", scm_type="git").path
        )
        side_effects: List[Dict[str, Any]] = []
        calls = []

        calls.append(call(["watch-list"]))
        side_effects.append({"roots": [edenfs_path]})
        calls.append(call(["watch-project", edenfs_path]))
        side_effects.append({"watcher": "eden"})
        mock_watchman.side_effect = side_effects

        out = TestOutput()
        dry_run = False
        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            mount_table=instance.mount_table,
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            f"Checking {edenfs_path}\n"
            f"Checking {edenfs_path_not_watched}\n"
            "<green>No issues detected.<reset>\n",
            out.getvalue(),
        )
        mock_watchman.assert_has_calls(calls)
        self.assertEqual(0, exit_code)
コード例 #27
0
    def test_watchman_fails(self, mock_watchman):
        tmp_dir = self.make_temporary_directory()
        instance = FakeEdenInstance(tmp_dir)

        mount = instance.create_test_mount("path1", active=False).path

        # Make calls to watchman fail rather than returning expected output
        side_effects = [{"error": "watchman failed"}]
        mock_watchman.side_effect = side_effects

        out = TestOutput()
        exit_code = doctor.cure_what_ails_you(
            typing.cast(EdenInstance, instance),
            dry_run=False,
            mount_table=instance.mount_table,
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        # "watchman watch-list" should have been called by the doctor code
        calls = [call(["watch-list"])]
        mock_watchman.assert_has_calls(calls)

        self.assertEqual(
            out.getvalue(),
            f"""\
Checking {mount}
<yellow>- Found problem:<reset>
{mount} is not currently mounted
Remounting {mount}...<green>fixed<reset>

<yellow>Successfully fixed 1 problem.<reset>
""",
        )
        self.assertEqual(exit_code, 0)
コード例 #28
0
    def test_end_to_end_test_with_various_scenarios(self, mock_watchman):
        side_effects: List[Dict[str, Any]] = []
        calls = []
        tmp_dir = tempfile.mkdtemp(prefix='eden_test.')
        try:
            # In edenfs_path1, we will break the snapshot check.
            edenfs_path1 = os.path.join(tmp_dir, 'path1')
            # In edenfs_path2, we will break the inotify check and the Nuclide
            # subscriptions check.
            edenfs_path2 = os.path.join(tmp_dir, 'path2')

            calls.append(call(['watch-list']))
            side_effects.append({'roots': [edenfs_path1, edenfs_path2]})

            calls.append(call(['watch-project', edenfs_path1]))
            side_effects.append({'watcher': 'eden'})

            calls.append(call(['debug-get-subscriptions', edenfs_path1]))
            side_effects.append(
                _create_watchman_subscription(
                    filewatcher_subscription=f'filewatcher-{edenfs_path1}',
                )
            )

            calls.append(call(['watch-project', edenfs_path2]))
            side_effects.append({'watcher': 'inotify'})
            calls.append(call(['watch-del', edenfs_path2]))
            side_effects.append({'watch-del': True, 'root': edenfs_path2})
            calls.append(call(['watch-project', edenfs_path2]))
            side_effects.append({'watcher': 'eden'})

            calls.append(call(['debug-get-subscriptions', edenfs_path2]))
            side_effects.append(
                _create_watchman_subscription(filewatcher_subscription=None)
            )

            mock_watchman.side_effect = side_effects

            out = io.StringIO()
            dry_run = False
            mount_paths = OrderedDict()
            edenfs_path1_snapshot_hex = 'abcd' * 10
            mount_paths[edenfs_path1] = {
                'bind-mounts': {},
                'mount': edenfs_path1,
                'scm_type': 'hg',
                'snapshot': edenfs_path1_snapshot_hex,
                'client-dir': '/I_DO_NOT_EXIST1'
            }
            mount_paths[edenfs_path2] = {
                'bind-mounts': {},
                'mount': edenfs_path2,
                'scm_type': 'git',
                'snapshot': 'dcba' * 10,
                'client-dir': '/I_DO_NOT_EXIST2'
            }
            config = FakeConfig(mount_paths, is_healthy=True)

            os.mkdir(edenfs_path1)
            hg_dir = os.path.join(edenfs_path1, '.hg')
            os.mkdir(hg_dir)
            dirstate = os.path.join(hg_dir, 'dirstate')
            dirstate_hash = b'\x12\x34\x56\x78' * 5
            parents = (dirstate_hash, b'\x00' * 20)
            with open(dirstate, 'wb') as f:
                eden.dirstate.write(f, parents, tuples_dict={}, copymap={})

            exit_code = doctor.cure_what_ails_you(config, dry_run, out)
        finally:
            shutil.rmtree(tmp_dir)

        self.assertEqual(
            f'''\
Performing 3 checks for {edenfs_path1}.
p1 for {edenfs_path1} is {'12345678' * 5}, but Eden's internal
hash in its SNAPSHOT file is {edenfs_path1_snapshot_hex}.
Performing 2 checks for {edenfs_path2}.
Previous Watchman watcher for {edenfs_path2} was "inotify" but is now "eden".
Nuclide appears to be used to edit {edenfs_path2},
but a key Watchman subscription appears to be missing.
This can cause file changes to fail to show up in Nuclide.
Currently, the only workaround this is to run
"Nuclide Remote Projects: Kill And Restart" from the
command palette in Atom.
Number of fixes made: 1.
Number of issues that could not be fixed: 2.
''', out.getvalue()
        )
        mock_watchman.assert_has_calls(calls)
        self.assertEqual(1, exit_code)
コード例 #29
0
ファイル: doctor_test.py プロジェクト: x414e54/eden
    def test_end_to_end_test_with_various_scenarios(
        self, mock_get_roots_for_nuclide, mock_watchman
    ):
        side_effects: List[Dict[str, Any]] = []
        calls = []
        instance = FakeEdenInstance(self.make_temporary_directory())

        # In edenfs_path1, we will break the snapshot check.
        edenfs_path1_snapshot = "abcd" * 10
        edenfs_path1_dirstate_parent = "12345678" * 5
        edenfs_path1 = str(
            instance.create_test_mount(
                "path1",
                snapshot=edenfs_path1_snapshot,
                dirstate_parent=edenfs_path1_dirstate_parent,
            ).path
        )

        # In edenfs_path2, we will break the inotify check and the Nuclide
        # subscriptions check.
        edenfs_path2 = str(
            instance.create_test_mount("path2", scm_type="git", setup_path=False).path
        )

        # In edenfs_path3, we do not create the .hg directory
        edenfs_path3 = str(instance.create_test_mount("path3", setup_path=False).path)
        os.makedirs(edenfs_path3)

        # Assume all paths are used as root folders in a connected Nuclide.
        mock_get_roots_for_nuclide.return_value = {
            edenfs_path1,
            edenfs_path2,
            edenfs_path3,
        }

        calls.append(call(["watch-list"]))
        side_effects.append({"roots": [edenfs_path1, edenfs_path2, edenfs_path3]})

        calls.append(call(["watch-project", edenfs_path1]))
        side_effects.append({"watcher": "eden"})

        calls.append(call(["debug-get-subscriptions", edenfs_path1]))
        side_effects.append(
            _create_watchman_subscription(
                filewatcher_subscriptions=[f"filewatcher-{edenfs_path1}"]
            )
        )

        calls.append(call(["watch-project", edenfs_path2]))
        side_effects.append({"watcher": "inotify"})
        calls.append(call(["watch-del", edenfs_path2]))
        side_effects.append({"watch-del": True, "root": edenfs_path2})
        calls.append(call(["watch-project", edenfs_path2]))
        side_effects.append({"watcher": "eden"})

        calls.append(call(["debug-get-subscriptions", edenfs_path2]))
        side_effects.append(_create_watchman_subscription(filewatcher_subscriptions=[]))

        calls.append(call(["watch-project", edenfs_path3]))
        side_effects.append({"watcher": "eden"})
        calls.append(call(["debug-get-subscriptions", edenfs_path3]))
        side_effects.append(
            _create_watchman_subscription(
                filewatcher_subscriptions=[f"filewatcher-{edenfs_path3}"]
            )
        )

        mock_watchman.side_effect = side_effects

        out = TestOutput()
        dry_run = False

        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            instance.mount_table,
            fs_util=FakeFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            f"""\
Checking {edenfs_path1}
<yellow>- Found problem:<reset>
Found inconsistent/missing data in {edenfs_path1}/.hg:
  mercurial's parent commit is {edenfs_path1_dirstate_parent}, \
but Eden's internal parent commit is {edenfs_path1_snapshot}
Repairing hg directory contents for {edenfs_path1}...<green>fixed<reset>

Checking {edenfs_path2}
<yellow>- Found problem:<reset>
Watchman is watching {edenfs_path2} with the wrong watcher type: \
"inotify" instead of "eden"
Fixing watchman watch for {edenfs_path2}...<green>fixed<reset>

<yellow>- Found problem:<reset>
Nuclide appears to be used to edit the following directories
under {edenfs_path2}:

  {edenfs_path2}

but the following Watchman subscriptions appear to be missing:

  filewatcher-{edenfs_path2}

This can cause file changes to fail to show up in Nuclide.
Currently, the only workaround for this is to run
"Nuclide Remote Projects: Kill And Restart" from the
command palette in Atom.

Checking {edenfs_path3}
<yellow>- Found problem:<reset>
Missing hg directory: {edenfs_path3}/.hg
Repairing hg directory contents for {edenfs_path3}...<green>fixed<reset>

<yellow>Successfully fixed 3 problems.<reset>
<yellow>1 issue requires manual attention.<reset>
Ask in the Eden Users group if you need help fixing issues with Eden:
https://fb.facebook.com/groups/eden.users/
""",
            out.getvalue(),
        )
        mock_watchman.assert_has_calls(calls)
        self.assertEqual(1, exit_code)
コード例 #30
0
    def test_end_to_end_test_with_various_scenarios(
        self, mock_get_roots_for_nuclide, mock_watchman
    ):
        side_effects: List[Dict[str, Any]] = []
        calls = []
        instance = FakeEdenInstance(self.make_temporary_directory())

        # In edenfs_path1, we will break the snapshot check.
        edenfs_path1_snapshot = "abcd" * 10
        edenfs_path1_dirstate_parent = "12345678" * 5
        edenfs_path1 = str(
            instance.create_test_mount(
                "path1",
                snapshot=edenfs_path1_snapshot,
                dirstate_parent=edenfs_path1_dirstate_parent,
            ).path
        )

        # In edenfs_path2, we will break the inotify check and the Nuclide
        # subscriptions check.
        edenfs_path2 = str(
            instance.create_test_mount("path2", scm_type="git", setup_path=False).path
        )

        # In edenfs_path3, we do not create the .hg directory
        edenfs_path3 = str(instance.create_test_mount("path3", setup_path=False).path)
        os.makedirs(edenfs_path3)

        # Assume all paths are used as root folders in a connected Nuclide.
        mock_get_roots_for_nuclide.return_value = {
            edenfs_path1,
            edenfs_path2,
            edenfs_path3,
        }

        calls.append(call(["watch-list"]))
        side_effects.append({"roots": [edenfs_path1, edenfs_path2, edenfs_path3]})

        calls.append(call(["watch-project", edenfs_path1]))
        side_effects.append({"watcher": "eden"})

        calls.append(call(["debug-get-subscriptions", edenfs_path1]))
        side_effects.append(
            _create_watchman_subscription(
                filewatcher_subscriptions=[f"filewatcher-{edenfs_path1}"]
            )
        )

        calls.append(call(["watch-project", edenfs_path2]))
        side_effects.append({"watcher": "inotify"})
        calls.append(call(["watch-del", edenfs_path2]))
        side_effects.append({"watch-del": True, "root": edenfs_path2})
        calls.append(call(["watch-project", edenfs_path2]))
        side_effects.append({"watcher": "eden"})

        calls.append(call(["debug-get-subscriptions", edenfs_path2]))
        side_effects.append(_create_watchman_subscription(filewatcher_subscriptions=[]))

        calls.append(call(["watch-project", edenfs_path3]))
        side_effects.append({"watcher": "eden"})
        calls.append(call(["debug-get-subscriptions", edenfs_path3]))
        side_effects.append(
            _create_watchman_subscription(
                filewatcher_subscriptions=[f"filewatcher-{edenfs_path3}"]
            )
        )

        mock_watchman.side_effect = side_effects

        out = TestOutput()
        dry_run = False

        exit_code = doctor.cure_what_ails_you(
            instance,
            dry_run,
            instance.mount_table,
            fs_util=filesystem.LinuxFsUtil(),
            process_finder=self.make_process_finder(),
            out=out,
        )

        self.assertEqual(
            f"""\
Checking {edenfs_path1}
<yellow>- Found problem:<reset>
Found inconsistent/missing data in {edenfs_path1}/.hg:
  mercurial's parent commit is {edenfs_path1_dirstate_parent}, \
but Eden's internal parent commit is {edenfs_path1_snapshot}
Repairing hg directory contents for {edenfs_path1}...<green>fixed<reset>

Checking {edenfs_path2}
<yellow>- Found problem:<reset>
Watchman is watching {edenfs_path2} with the wrong watcher type: \
"inotify" instead of "eden"
Fixing watchman watch for {edenfs_path2}...<green>fixed<reset>

<yellow>- Found problem:<reset>
Nuclide appears to be used to edit the following directories
under {edenfs_path2}:

  {edenfs_path2}

but the following Watchman subscriptions appear to be missing:

  filewatcher-{edenfs_path2}

This can cause file changes to fail to show up in Nuclide.
Currently, the only workaround for this is to run
"Nuclide Remote Projects: Kill And Restart" from the
command palette in Atom.

Checking {edenfs_path3}
<yellow>- Found problem:<reset>
Missing hg directory: {edenfs_path3}/.hg
Repairing hg directory contents for {edenfs_path3}...<green>fixed<reset>

<yellow>Successfully fixed 3 problems.<reset>
<yellow>1 issue requires manual attention.<reset>
Ask in the Eden Users group if you need help fixing issues with Eden:
https://fb.facebook.com/groups/eden.users/
""",
            out.getvalue(),
        )
        mock_watchman.assert_has_calls(calls)
        self.assertEqual(1, exit_code)