mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 01:07:15 +03:00
72f6ada7c2
Summary: This adds a new `EdenTestCaseBase` class to serve as the base class across a number of our integration tests and some of our CLI tests. The main goal of this is to allow eliminating many of the annoying `*Mixin` classes used in a lot of our integration tests. These mixin classes are annoying since they result in complicated multiple inheritance, and it can be tricky to ensure that the method resolution order behaves the way you want. The systemd tests in particular use a lot of mixins, which gets complicated. These mixin classes are also awkward from a Python typing perspective, and the systemd tests end up resorting to just declaring different APIs in several places when `typing.TYPE_CHECKING` is True. The fact that `EdenTestCaseBase` has a `contextlib.ExitStack` member variable should make it easier for us to eliminate these mixins moving forward: rather than using mixins that use inheritance and assume a `self.cleanUp()` method exists, we can transition this code to standalone functions or context managers, and they can take the `ExitStack` variable as an argument if necessary. Reviewed By: wez Differential Revision: D21084097 fbshipit-source-id: 77ee457b7debe6f584f630e3e30f79fe634a2026
69 lines
2.4 KiB
Python
69 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright (c) Facebook, Inc. and its affiliates.
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2.
|
|
|
|
import contextlib
|
|
import unittest
|
|
from pathlib import Path
|
|
from typing import Optional, Union
|
|
|
|
from . import environment_variable as env_module
|
|
from .temporary_directory import TempFileManager
|
|
|
|
|
|
class EdenTestCaseBase(unittest.TestCase):
|
|
"""Base class for many EdenFS test cases.
|
|
|
|
This class provides a number of convenience functions.
|
|
"""
|
|
|
|
exit_stack: contextlib.ExitStack
|
|
temp_mgr: TempFileManager
|
|
|
|
def setUp(self) -> None:
|
|
super().setUp()
|
|
self.exit_stack = contextlib.ExitStack()
|
|
self.addCleanup(self.exit_stack.close)
|
|
self.temp_mgr = self.exit_stack.enter_context(
|
|
TempFileManager(self._get_tmp_prefix())
|
|
)
|
|
|
|
def _get_tmp_prefix(self) -> str:
|
|
"""Get a prefix to use for the test's temporary directory name. """
|
|
# Attempt to include a potion of the test name in the temporary directory
|
|
# prefix, but limit it to 20 characters. If the path is too long EdenFS will
|
|
# fail to start since its Unix socket path won't fit in sockaddr_un, which has a
|
|
# 108 byte maximum path length.
|
|
method_name = self._testMethodName
|
|
for strip_prefix in ("test_", "test"):
|
|
if method_name.startswith(strip_prefix):
|
|
method_name = method_name[len(strip_prefix) :]
|
|
break
|
|
return f"eden_test.{method_name[:20]}."
|
|
|
|
def setenv(self, name: str, value: Optional[str]) -> None:
|
|
self.exit_stack.enter_context(env_module.setenv_scope(name, value))
|
|
|
|
def unsetenv(self, name: str) -> None:
|
|
self.exit_stack.enter_context(env_module.unsetenv_scope(name))
|
|
|
|
@property
|
|
def tmp_dir(self) -> Path:
|
|
return self.temp_mgr.top_level_tmp_dir()
|
|
|
|
def make_temp_dir(self, prefix: Optional[str] = None) -> Path:
|
|
"""Make a directory with a uniquely-generated name under the top-level test-case
|
|
subdirectory.
|
|
"""
|
|
return self.temp_mgr.make_temp_dir(prefix=prefix)
|
|
|
|
def make_test_dir(self, name: Union[Path, str], parents: bool = True) -> Path:
|
|
"""Make a directory with a specific name under the top-level test-case
|
|
subdirectory.
|
|
"""
|
|
dir_path = self.tmp_dir / name
|
|
dir_path.mkdir(parents=parents)
|
|
return dir_path
|