diff --git a/eden/fs/cli/test/config_test.py b/eden/fs/cli/test/config_test.py index dff787249c..367fbe3aca 100644 --- a/eden/fs/cli/test/config_test.py +++ b/eden/fs/cli/test/config_test.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import configparser import io import os @@ -22,14 +24,14 @@ from ..configinterpolator import EdenConfigInterpolator from ..configutil import EdenConfigParser, UnexpectedType -def get_toml_test_file_invalid(): +def get_toml_test_file_invalid() -> str: cfg_file = """ [core thisIsNotAllowed] """ return cfg_file -def get_toml_test_file_defaults(): +def get_toml_test_file_defaults() -> str: cfg_file = """ [core] systemIgnoreFile = "/etc/eden/gitignore" @@ -44,7 +46,7 @@ reporter = 'pastry --title "eden rage from $(hostname)"' return cfg_file -def get_toml_test_file_user_rc(): +def get_toml_test_file_user_rc() -> str: cfg_file = """ [core] ignoreFile = "/home/${USER}/.gitignore-override" @@ -56,7 +58,7 @@ scribe-cat = "/usr/local/bin/scribe_cat" return cfg_file -def get_toml_test_file_system_rc(): +def get_toml_test_file_system_rc() -> str: cfg_file = """ ["telemetry"] scribe-cat = "/bad/path/to/scribe_cat" diff --git a/eden/fs/cli/test/debug_test.py b/eden/fs/cli/test/debug_test.py index a708cc076a..29cb84243c 100644 --- a/eden/fs/cli/test/debug_test.py +++ b/eden/fs/cli/test/debug_test.py @@ -4,75 +4,85 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import unittest +from typing import List, NamedTuple, Tuple, Dict, Union from eden.fs.cli.debug import FileStatsCMD class DebugTest(unittest.TestCase): - def test_get_largest_directories_by_count(self): + def test_get_largest_directories_by_count(self) -> None: + class TestCase(NamedTuple): + test_input: Tuple[List[Tuple[str, int]], int] + test_output: List[Dict[str, Union[int, str]]] + msg: str - test_cases = [ - { - "input": ([], 0), - "output": [{"path": ".", "file_count": 0}], - "msg": "empty directory with no minimum", - }, - { - "input": ([], 1), - "output": [], - "msg": "empty directory with minimum of 1", - }, - { - "input": ([("dirA/filename", 1000)], 1), - "output": [ + test_cases: List[TestCase] = [ + TestCase( + test_input=([], 0), + test_output=[{"path": ".", "file_count": 0}], + msg="empty directory with minimum of 1", + ), + TestCase( + test_input=([], 1), + test_output=[], + msg="empty directory with minimum of 1", + ), + TestCase( + test_input=([("dirA/filename", 1000)], 1), + test_output=[ {"path": ".", "file_count": 1}, {"path": "dirA", "file_count": 1}, ], - "msg": "single file with minimum of 1", - }, - { - "input": ([("dirA/filename", 1000)], 2), - "output": [], - "msg": "single file with minimum of 2", - }, - { - "input": ([("dirA/filename", 1000), ("dirB/filename2", 50)], 1), - "output": [ + msg="single file with minimum of 1", + ), + TestCase( + test_input=([("dirA/filename", 1000)], 2), + test_output=[], + msg="single file with minimum of 2", + ), + TestCase( + test_input=([("dirA/filename", 1000), ("dirB/filename2", 50)], 1), + test_output=[ {"path": ".", "file_count": 2}, {"path": "dirA", "file_count": 1}, {"path": "dirB", "file_count": 1}, ], - "msg": "two files with minimum of 1", - }, - { - "input": ([("dirA/filename", 1000), ("dirB/filename2", 50)], 2), - "output": [{"path": ".", "file_count": 2}], - "msg": "two files with minimum of 2", - }, - { - "input": ([("filename", 1000), ("dirA/filename2", 50)], 1), - "output": [ + msg="two files with minimum of 1", + ), + TestCase( + test_input=([("dirA/filename", 1000), ("dirB/filename2", 50)], 2), + test_output=[{"path": ".", "file_count": 2}], + msg="two files with minimum of 2", + ), + TestCase( + test_input=([("filename", 1000), ("dirA/filename2", 50)], 1), + test_output=[ {"path": ".", "file_count": 2}, {"path": "dirA", "file_count": 1}, ], - "msg": "file in root dir", - }, - { - "input": ([("filename", 1000), ("dirA/dirB/dirC/filename2", 50)], 1), - "output": [ + msg="file in root dir", + ), + TestCase( + test_input=([("filename", 1000), ("dirA/dirB/dirC/filename2", 50)], 1), + test_output=[ {"path": ".", "file_count": 2}, {"path": "dirA", "file_count": 1}, {"path": "dirA/dirB", "file_count": 1}, {"path": "dirA/dirB/dirC", "file_count": 1}, ], - "msg": "deeply nested file", - }, + msg="deeply nested file", + ), ] for test_case in test_cases: + path_and_sizes, min_file_count = test_case.test_input self.assertEqual( - FileStatsCMD.get_largest_directories_by_count(*test_case["input"]), - test_case["output"], - test_case["msg"], + FileStatsCMD.get_largest_directories_by_count( + path_and_sizes, min_file_count + ), + test_case.test_output, + test_case.msg, ) diff --git a/eden/fs/cli/test/find_eden_test.py b/eden/fs/cli/test/find_eden_test.py index 7fdd81920d..ddfadb3f17 100644 --- a/eden/fs/cli/test/find_eden_test.py +++ b/eden/fs/cli/test/find_eden_test.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import json import os import re diff --git a/eden/fs/cli/test/interp_test.py b/eden/fs/cli/test/interp_test.py index 7b9cc1d4fa..2a39398f02 100644 --- a/eden/fs/cli/test/interp_test.py +++ b/eden/fs/cli/test/interp_test.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import configparser import unittest @@ -11,7 +13,7 @@ from .. import configinterpolator class InterpolatorTest(unittest.TestCase): - def test_basic_subs(self): + def test_basic_subs(self) -> None: defaults = {"USER": "wez", "RECURSIVE": "a${RECURSIVE}b"} parser = configparser.ConfigParser( interpolation=configinterpolator.EdenConfigInterpolator(defaults) diff --git a/eden/fs/cli/test/lib/fake_proc_utils.py b/eden/fs/cli/test/lib/fake_proc_utils.py index 9f9085cee7..5704e5b09f 100644 --- a/eden/fs/cli/test/lib/fake_proc_utils.py +++ b/eden/fs/cli/test/lib/fake_proc_utils.py @@ -4,7 +4,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. -# pyre_strict +# pyre-strict import datetime import errno diff --git a/eden/fs/cli/test/lib/output.py b/eden/fs/cli/test/lib/output.py index b2690bc712..5c6d3e8010 100644 --- a/eden/fs/cli/test/lib/output.py +++ b/eden/fs/cli/test/lib/output.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import io import eden.fs.cli.ui diff --git a/eden/fs/cli/test/logfile_test.py b/eden/fs/cli/test/logfile_test.py index 1639a0432a..42b4cefd3f 100644 --- a/eden/fs/cli/test/logfile_test.py +++ b/eden/fs/cli/test/logfile_test.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import io import os import pathlib diff --git a/eden/fs/cli/test/mtab_test.py b/eden/fs/cli/test/mtab_test.py index 0f379d472e..2a8a694f6b 100644 --- a/eden/fs/cli/test/mtab_test.py +++ b/eden/fs/cli/test/mtab_test.py @@ -4,17 +4,20 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import unittest +from typing import Optional from eden.fs.cli.mtab import MountInfo, parse_macos_mount_output, parse_mtab class MTabTest(unittest.TestCase): # The diffs for what is written to stdout can be large. - maxDiff = None + maxDiff: Optional[int] = None - def test_parse_mtab(self): - contents = """\ + def test_parse_mtab(self) -> None: + contents = b"""\ homedir.eden.com:/home109/chadaustin/public_html /mnt/public/chadaustin nfs rw,context=user_u:object_r:user_home_dir_t,relatime,vers=3,rsize=65536,wsize=65536,namlen=255,soft,nosharecache,proto=tcp6,timeo=100,retrans=2,sec=krb5i,mountaddr=2401:db00:fffe:1007:face:0000:0:4007,mountvers=3,mountport=635,mountproto=udp6,local_lock=none,addr=2401:db00:fffe:1007:0000:b00c:0:4007 0 0 squashfuse_ll /mnt/xarfuse/uid-0/2c071047-ns-4026531840 fuse.squashfuse_ll rw,nosuid,nodev,relatime,user_id=0,group_id=0 0 0 bogus line here @@ -23,11 +26,11 @@ edenfs: /tmp/eden_test.4rec6drf/mounts/main fuse rw,nosuid,relatime,user_id=1386 mount_infos = parse_mtab(contents) self.assertEqual(3, len(mount_infos)) one, two, three = mount_infos - self.assertEqual("edenfs:", three.device) - self.assertEqual("/tmp/eden_test.4rec6drf/mounts/main", three.mount_point) - self.assertEqual("fuse", three.vfstype) + self.assertEqual(b"edenfs:", three.device) + self.assertEqual(b"/tmp/eden_test.4rec6drf/mounts/main", three.mount_point) + self.assertEqual(b"fuse", three.vfstype) - def test_parse_mtab_macos(self): + def test_parse_mtab_macos(self) -> None: contents = b"""\ /dev/disk1s1 on / (apfs, local, journaled) devfs on /dev (devfs, local, nobrowse) diff --git a/eden/fs/cli/test/stats_test.py b/eden/fs/cli/test/stats_test.py index 13f896965e..f214a0fd3a 100644 --- a/eden/fs/cli/test/stats_test.py +++ b/eden/fs/cli/test/stats_test.py @@ -4,17 +4,20 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import unittest from io import StringIO +from typing import Optional from .. import stats_print from ..stats import DiagInfoCounters, get_counter_table, get_store_latency class StatsTest(unittest.TestCase): - maxDiff = None + maxDiff: Optional[int] = None - def test_print_heading(self): + def test_print_heading(self) -> None: expected_output = """\ ********** TheHeading @@ -25,7 +28,7 @@ class StatsTest(unittest.TestCase): stats_print.write_heading("TheHeading", out) self.assertEqual(out.getvalue(), expected_output) - def test_print_latency_record(self): + def test_print_latency_record(self) -> None: matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]] expected_output = """\ | avg 1 2 3 4 @@ -39,7 +42,7 @@ access | p90 9 10 11 12 stats_print.write_latency_record("access", matrix, out) self.assertEqual(out.getvalue(), expected_output) - def test_print_table(self): + def test_print_table(self) -> None: table = { "key1": [1, 2, 3, 4], "key2": [5, 6, 7, 8], @@ -58,7 +61,7 @@ key4 13 14 15 16 stats_print.write_table(table, "SystemCall", out) self.assertEqual(expected_output, out.getvalue()) - def test_print_table_with_shorter_header_and_key_column(self): + def test_print_table_with_shorter_header_and_key_column(self) -> None: table = {"key": [1, 2, 3, 4]} # Verifies the width of the first column depends on the header's and # key's lengths. @@ -71,7 +74,7 @@ key 1 2 3 4 stats_print.write_table(table, "SC", out) self.assertEqual(expected_output, out.getvalue()) - def test_format_size(self): + def test_format_size(self) -> None: self.assertEqual("1.5 GB", stats_print.format_size(1500000000)) # rounds up self.assertEqual("1.6 GB", stats_print.format_size(1590000000)) @@ -79,7 +82,7 @@ key 1 2 3 4 self.assertEqual("12 B", stats_print.format_size(12)) self.assertEqual("0", stats_print.format_size(0)) - def test_time_formats_correctly(self): + def test_time_formats_correctly(self) -> None: self.assertEqual(stats_print.format_time(0), "0 second(s)") self.assertEqual(stats_print.format_time(30), "30 second(s)") self.assertEqual(stats_print.format_time(60), "1.0 minute(s)") diff --git a/eden/fs/cli/test/systemd_test.py b/eden/fs/cli/test/systemd_test.py index 39062058d6..03fe1c1a7d 100644 --- a/eden/fs/cli/test/systemd_test.py +++ b/eden/fs/cli/test/systemd_test.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import collections import pathlib import sys diff --git a/eden/fs/cli/test/tabulate_test.py b/eden/fs/cli/test/tabulate_test.py index 5519155ce5..bd24870d14 100644 --- a/eden/fs/cli/test/tabulate_test.py +++ b/eden/fs/cli/test/tabulate_test.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import unittest from eden.fs.cli.tabulate import tabulate @@ -13,7 +15,7 @@ eol = "" class TabulateTest(unittest.TestCase): - def test_tabulate(self): + def test_tabulate(self) -> None: output = tabulate( ["a", "b", "c"], rows=[ @@ -29,7 +31,7 @@ a_1 b_1 see_1{eol} a_two b_2 c_2{eol}""", ) - def test_tabulate_header_labels(self): + def test_tabulate_header_labels(self) -> None: output = tabulate( ["a", "b", "c"], rows=[ diff --git a/eden/fs/cli/test/telemetry_test.py b/eden/fs/cli/test/telemetry_test.py index 664fdad2b6..720b439dde 100644 --- a/eden/fs/cli/test/telemetry_test.py +++ b/eden/fs/cli/test/telemetry_test.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import json import math import typing diff --git a/eden/fs/cli/test/top_test.py b/eden/fs/cli/test/top_test.py index 77ef544369..a6dddd0764 100644 --- a/eden/fs/cli/test/top_test.py +++ b/eden/fs/cli/test/top_test.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import unittest from ..top import Process, format_duration @@ -14,22 +16,22 @@ class TopTest(unittest.TestCase): def setUp(self) -> None: self.process = Process(42, "ls", "fbsource") - def test_format_cmd(self): + def test_format_cmd(self) -> None: self.assertEqual("ls", format_cmd(b"/bin/ls")) self.assertEqual("'chg[worker/0]'", format_cmd(b"chg[worker/0]")) - def test_format_cmd_with_arg(self): + def test_format_cmd_with_arg(self) -> None: self.assertEqual("ls -l", format_cmd(b"/bin/ls\x00-l"), "ls -l") self.assertEqual("ls -l 'one two'", format_cmd(b"ls\0-l\0one two")) - def test_format_cmd_trailing_null(self): + def test_format_cmd_trailing_null(self) -> None: self.assertEqual("ls -l", format_cmd(b"ls\x00-l\x00"), "ls -l") self.assertEqual("ls -l ''", format_cmd(b"ls\x00-l\x00\x00"), "ls -l ''") - def test_format_mount(self): + def test_format_mount(self) -> None: self.assertEqual(format_mount("/data/users/zuck/fbsource"), "fbsource") - def test_format_duration(self): + def test_format_duration(self) -> None: self.assertEqual(format_duration(1), "1ns") self.assertEqual(format_duration(1 * 1000), "1us") self.assertEqual(format_duration(1 * 1000 * 1000), "1ms") diff --git a/eden/fs/cli/test/util_test.py b/eden/fs/cli/test/util_test.py index edb0d8ffb6..aa125ebca3 100644 --- a/eden/fs/cli/test/util_test.py +++ b/eden/fs/cli/test/util_test.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import stat import unittest diff --git a/eden/fs/cli/test/wait_for_shutdown_test.py b/eden/fs/cli/test/wait_for_shutdown_test.py index 1c7fae7f17..a8d31fafd3 100644 --- a/eden/fs/cli/test/wait_for_shutdown_test.py +++ b/eden/fs/cli/test/wait_for_shutdown_test.py @@ -4,6 +4,8 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2. +# pyre-strict + import contextlib import signal import subprocess @@ -43,7 +45,7 @@ class WaitForShutdownTest(unittest.TestCase): class AutoReapingChildProcess: """A child process (subprocess.Popen) which is promptly reaped.""" - def __init__(self, args) -> None: + def __init__(self, args: typing.List[str]) -> None: super().__init__() self.__condition = threading.Condition() @@ -65,29 +67,26 @@ class AutoReapingChildProcess: with self.__condition: while self.__returncode is None: self.__condition.wait() - assert self.__returncode is not None - # pyre-fixme[7]: Expected `int` but got `Optional[int]`. - return self.__returncode + returncode = self.__returncode + assert returncode is not None + return returncode def __wait_for_process_start(self) -> None: with self.__condition: while self.__pid is None and self.__error is None: self.__condition.wait() - if self.__error is not None: - # pyre-fixme[48]: Expression `self.__error` has type - # `Optional[BaseException]` but must extend BaseException. - raise self.__error + error = self.__error + if error is not None: + raise error assert self.__pid is not None - def __start_thread(self, *args, **kwargs) -> None: - thread = threading.Thread( - target=self.__run_thread, args=(args, kwargs), daemon=True - ) + def __start_thread(self, *args: typing.List[str]) -> None: + thread = threading.Thread(target=self.__run_thread, args=(args), daemon=True) thread.start() - def __run_thread(self, popen_args, popen_kwargs) -> None: + def __run_thread(self, popen_args: typing.List[str]) -> None: try: - with subprocess.Popen(*popen_args, **popen_kwargs) as process: + with subprocess.Popen(popen_args) as process: with self.__condition: self.__pid = process.pid self.__condition.notify_all()