diff --git a/tests/test_common.py b/tests/test_common.py index d32144092..b32e1b3ce 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -18,8 +18,7 @@ import os import requests_mock import synthtool as s -import tempfile -import shutil +from . import util MOCK = Path(__file__).parent / "generationmock" @@ -53,172 +52,101 @@ def test_get_default_branch(): def test_py_samples_clientlib(): path_to_gen = MOCK / "client_library" - with tempfile.TemporaryDirectory() as tempdir: - workdir = shutil.copytree(path_to_gen, Path(tempdir) / "client_library") - cwd = os.getcwd() - os.chdir(workdir) - - try: - sample_files = common.py_samples( - unit_cov_level=97, cov_level=99, samples=True - ) - s.move(sample_files, excludes=["noxfile.py"]) - assert os.path.isfile(workdir / "samples" / "README.md") - finally: - os.chdir(cwd) + with util.copied_fixtures_dir(path_to_gen) as workdir: + sample_files = common.py_samples(unit_cov_level=97, cov_level=99, samples=True) + s.move(sample_files, excludes=["noxfile.py"]) + assert os.path.isfile(workdir / "samples" / "README.md") def test_py_samples_custom_path(): path_to_gen = MOCK / "custom_path" - with tempfile.TemporaryDirectory() as tempdir: - workdir = shutil.copytree(path_to_gen, Path(tempdir) / "custom_path") - cwd = os.getcwd() - os.chdir(workdir) + with util.copied_fixtures_dir(path_to_gen) as workdir: + sample_files = common.py_samples(unit_cov_level=97, cov_level=99, samples=True) + s.move(sample_files, excludes=["noxfile.py"]) + assert os.path.isfile(workdir / "custom_samples_folder" / "README.md") + - try: +def test_py_samples_custom_path_DNE(): + path_to_gen = MOCK / "custom_path_DNE" + with util.copied_fixtures_dir(path_to_gen) as workdir: + with raises(Exception) as e: + os.chdir(workdir / "custom_path_DNE") sample_files = common.py_samples( unit_cov_level=97, cov_level=99, samples=True ) s.move(sample_files, excludes=["noxfile.py"]) - assert os.path.isfile(workdir / "custom_samples_folder" / "README.md") - finally: - os.chdir(cwd) - - -def test_py_samples_custom_path_DNE(): - with tempfile.TemporaryDirectory() as tempdir: - workdir = shutil.copytree( - MOCK / "custom_path_DNE", Path(tempdir) / "custom_path_DNE" - ) - cwd = os.getcwd() - os.chdir(workdir) - - try: - with raises(Exception) as e: - os.chdir(workdir / "custom_path_DNE") - sample_files = common.py_samples( - unit_cov_level=97, cov_level=99, samples=True - ) - s.move(sample_files, excludes=["noxfile.py"]) - assert "'nonexistent_folder' does not exist" in str(e.value) - finally: - os.chdir(cwd) + assert "'nonexistent_folder' does not exist" in str(e.value) def test_py_samples_samples_folder(): path_to_gen = MOCK / "samples_folder" - with tempfile.TemporaryDirectory() as tempdir: - workdir = shutil.copytree(path_to_gen, Path(tempdir) / "samples_folder") - cwd = os.getcwd() - os.chdir(workdir) - - try: - sample_files = common.py_samples( - unit_cov_level=97, cov_level=99, samples=True - ) - s.move(sample_files, excludes=["noxfile.py"]) - assert os.path.isfile(workdir / "README.md") - finally: - os.chdir(cwd) + with util.copied_fixtures_dir(path_to_gen) as workdir: + sample_files = common.py_samples(unit_cov_level=97, cov_level=99, samples=True) + s.move(sample_files, excludes=["noxfile.py"]) + assert os.path.isfile(workdir / "README.md") def test_py_samples_override(): path_to_gen = MOCK / "override_path" - with tempfile.TemporaryDirectory() as tempdir: - workdir = shutil.copytree(path_to_gen, Path(tempdir) / "override_path") - cwd = os.getcwd() - os.chdir(workdir) - - try: - sample_files = common.py_samples( - unit_cov_level=97, cov_level=99, samples=True - ) - for path in sample_files: - s.move(path, excludes=["noxfile.py"]) - assert os.path.isfile(workdir / "README.md") - assert os.path.isfile(workdir / "override" / "README.md") - finally: - os.chdir(cwd) + with util.copied_fixtures_dir(path_to_gen) as workdir: + sample_files = common.py_samples(unit_cov_level=97, cov_level=99, samples=True) + for path in sample_files: + s.move(path, excludes=["noxfile.py"]) + assert os.path.isfile(workdir / "README.md") + assert os.path.isfile(workdir / "override" / "README.md") def test_py_samples_override_content(): path_to_gen = MOCK / "override_path" - with tempfile.TemporaryDirectory() as tempdir: - workdir = shutil.copytree(path_to_gen, Path(tempdir) / "override_path") - cwd = os.getcwd() + with util.copied_fixtures_dir(path_to_gen) as workdir: + sample_files = common.py_samples(unit_cov_level=97, cov_level=99, samples=True) + for path in sample_files: + s.move(path, excludes=["noxfile.py"]) os.chdir(workdir) - - try: - sample_files = common.py_samples( - unit_cov_level=97, cov_level=99, samples=True - ) - for path in sample_files: - s.move(path, excludes=["noxfile.py"]) - os.chdir(workdir) - with open("README.md") as f: - result = f.read() - assert "Hello World" in result - assert "Quickstart" not in result - os.chdir(workdir / "override") - with open("README.md") as f: - result = f.read() - assert "Hello World" not in result - assert "Quickstart" in result - finally: - os.chdir(cwd) + with open("README.md") as f: + result = f.read() + assert "Hello World" in result + assert "Quickstart" not in result + os.chdir(workdir / "override") + with open("README.md") as f: + result = f.read() + assert "Hello World" not in result + assert "Quickstart" in result def test_py_samples_multiple_override(): path_to_gen = MOCK / "multiple_override_path" - with tempfile.TemporaryDirectory() as tempdir: - workdir = shutil.copytree(path_to_gen, Path(tempdir) / "multiple_override_path") - cwd = os.getcwd() - os.chdir(workdir) - - try: - sample_files = common.py_samples( - unit_cov_level=97, cov_level=99, samples=True - ) - for path in sample_files: - s.move(path, excludes=["noxfile.py"]) - assert os.path.isfile(workdir / "README.md") - assert os.path.isfile(workdir / "override" / "README.md") - assert os.path.isfile(workdir / "another_override" / "README.md") - os.chdir(workdir / "another_override") - with open("README.md") as f: - result = f.read() - assert "Hello World" in result - assert "Hello Synthtool" in result - finally: - os.chdir(cwd) + with util.copied_fixtures_dir(path_to_gen) as workdir: + sample_files = common.py_samples(unit_cov_level=97, cov_level=99, samples=True) + for path in sample_files: + s.move(path, excludes=["noxfile.py"]) + assert os.path.isfile(workdir / "README.md") + assert os.path.isfile(workdir / "override" / "README.md") + assert os.path.isfile(workdir / "another_override" / "README.md") + os.chdir(workdir / "another_override") + with open("README.md") as f: + result = f.read() + assert "Hello World" in result + assert "Hello Synthtool" in result def test_py_samples_multiple_override_content(): path_to_gen = MOCK / "multiple_override_path" - with tempfile.TemporaryDirectory() as tempdir: - workdir = shutil.copytree(path_to_gen, Path(tempdir) / "multiple_override_path") - cwd = os.getcwd() + with util.copied_fixtures_dir(path_to_gen) as workdir: + sample_files = common.py_samples(unit_cov_level=97, cov_level=99, samples=True) + for path in sample_files: + s.move(path, excludes=["noxfile.py"]) + os.chdir(workdir / "override") + with open("README.md") as f: + result = f.read() + assert "Quickstart" in result + assert "first_arg" in result + os.chdir(workdir / "another_override") + with open("README.md") as f: + result = f.read() + assert "Hello World" in result + assert "Hello Synthtool" in result os.chdir(workdir) - - try: - sample_files = common.py_samples( - unit_cov_level=97, cov_level=99, samples=True - ) - for path in sample_files: - s.move(path, excludes=["noxfile.py"]) - os.chdir(workdir / "override") - with open("README.md") as f: - result = f.read() - assert "Quickstart" in result - assert "first_arg" in result - os.chdir(workdir / "another_override") - with open("README.md") as f: - result = f.read() - assert "Hello World" in result - assert "Hello Synthtool" in result - os.chdir(workdir) - with open("README.md") as f: - result = f.read() - assert "Last Example" in result - finally: - os.chdir(cwd) + with open("README.md") as f: + result = f.read() + assert "Last Example" in result diff --git a/tests/test_language_java.py b/tests/test_language_java.py index 68428896d..d3ad19ba6 100644 --- a/tests/test_language_java.py +++ b/tests/test_language_java.py @@ -21,6 +21,7 @@ from synthtool.languages import java import requests_mock import pytest +from . import util FIXTURES = Path(__file__).parent / "fixtures" TEMPLATES_PATH = Path(__file__).parent.parent / "synthtool" / "gcp" / "templates" @@ -90,29 +91,20 @@ def assert_valid_yaml(file): except yaml.YAMLError: pytest.fail(f"unable to parse YAML: {file}") - with tempfile.TemporaryDirectory() as tempdir: - workdir = shutil.copytree( - FIXTURES / "java_templates" / "standard", Path(tempdir) / "standard" - ) - cwd = os.getcwd() - os.chdir(workdir) - - try: - # generate the common templates - java.common_templates(template_path=TEMPLATES_PATH) - assert os.path.isfile("renovate.json") - - # lint xml, yaml files - # use os.walk because glob ignores hidden directories - for (dirpath, _, filenames) in os.walk(tempdir): - for file in filenames: - (_, ext) = os.path.splitext(file) - if ext == ".xml": - assert_valid_xml(os.path.join(dirpath, file)) - elif ext == ".yaml" or ext == ".yml": - assert_valid_yaml(os.path.join(dirpath, file)) - finally: - os.chdir(cwd) + with util.copied_fixtures_dir(FIXTURES / "java_templates" / "standard") as workdir: + # generate the common templates + java.common_templates(template_path=TEMPLATES_PATH) + assert os.path.isfile("renovate.json") + + # lint xml, yaml files + # use os.walk because glob ignores hidden directories + for (dirpath, _, filenames) in os.walk(workdir): + for file in filenames: + (_, ext) = os.path.splitext(file) + if ext == ".xml": + assert_valid_xml(os.path.join(dirpath, file)) + elif ext == ".yaml" or ext == ".yml": + assert_valid_yaml(os.path.join(dirpath, file)) def test_remove_method(): diff --git a/tests/test_node.py b/tests/test_node.py index f61633b20..8e4c2c387 100644 --- a/tests/test_node.py +++ b/tests/test_node.py @@ -15,7 +15,6 @@ import filecmp import os import pathlib -import shutil import tempfile from pathlib import Path from unittest import TestCase @@ -25,62 +24,51 @@ import synthtool as s from synthtool.languages import node +from . import util FIXTURES = Path(__file__).parent / "fixtures" TEMPLATES = Path(__file__).parent.parent / "synthtool" / "gcp" / "templates" def test_quickstart_metadata_with_snippet(): - cwd = os.getcwd() - os.chdir(FIXTURES / "node_templates" / "standard") + with util.chdir(FIXTURES / "node_templates" / "standard"): + metadata = node.template_metadata() - metadata = node.template_metadata() + # should have loaded the special quickstart sample (ignoring header). + assert "ID of the Cloud Bigtable instance" in metadata["quickstart"] + assert "limitations under the License" not in metadata["quickstart"] - # should have loaded the special quickstart sample (ignoring header). - assert "ID of the Cloud Bigtable instance" in metadata["quickstart"] - assert "limitations under the License" not in metadata["quickstart"] + assert isinstance(metadata["samples"], list) - assert isinstance(metadata["samples"], list) - - # should have a link to the quickstart in the samples - sample_names = list(map(lambda sample: sample["file"], metadata["samples"])) - assert "samples/quickstart.js" in sample_names - - os.chdir(cwd) + # should have a link to the quickstart in the samples + sample_names = list(map(lambda sample: sample["file"], metadata["samples"])) + assert "samples/quickstart.js" in sample_names def test_quickstart_metadata_without_snippet(): - cwd = os.getcwd() - os.chdir(FIXTURES / "node_templates" / "no_quickstart_snippet") - - metadata = node.template_metadata() - - # should not have populated the quickstart for the README - assert not metadata["quickstart"] + with util.chdir(FIXTURES / "node_templates" / "no_quickstart_snippet"): + metadata = node.template_metadata() - assert isinstance(metadata["samples"], list) + # should not have populated the quickstart for the README + assert not metadata["quickstart"] - # should not have a link to the quickstart in the samples - sample_names = list(map(lambda sample: sample["file"], metadata["samples"])) - assert "samples/quickstart.js" not in sample_names + assert isinstance(metadata["samples"], list) - os.chdir(cwd) + # should not have a link to the quickstart in the samples + sample_names = list(map(lambda sample: sample["file"], metadata["samples"])) + assert "samples/quickstart.js" not in sample_names def test_no_samples(): - cwd = os.getcwd() # use a non-nodejs template directory - os.chdir(FIXTURES) + with util.chdir(FIXTURES): + metadata = node.template_metadata() - metadata = node.template_metadata() + # should not have populated the quickstart for the README + assert not metadata["quickstart"] - # should not have populated the quickstart for the README - assert not metadata["quickstart"] - - assert isinstance(metadata["samples"], list) - assert len(metadata["samples"]) == 0 - - os.chdir(cwd) + assert isinstance(metadata["samples"], list) + assert len(metadata["samples"]) == 0 def test_extract_clients_no_file(): @@ -117,10 +105,8 @@ def test_extract_multiple_clients(): def test_generate_index_ts(): - cwd = os.getcwd() - try: - # use a non-nodejs template directory - os.chdir(FIXTURES / "node_templates" / "index_samples") + # use a non-nodejs template directory + with util.chdir(FIXTURES / "node_templates" / "index_samples"): node.generate_index_ts(["v1", "v1beta1"], "v1") generated_index_path = pathlib.Path( FIXTURES / "node_templates" / "index_samples" / "src" / "index.ts" @@ -129,43 +115,30 @@ def test_generate_index_ts(): FIXTURES / "node_templates" / "index_samples" / "sample_index.ts" ) assert filecmp.cmp(generated_index_path, sample_index_path) - finally: - os.chdir(cwd) def test_generate_index_ts_empty_versions(): - cwd = os.getcwd() - try: - # use a non-nodejs template directory - os.chdir(FIXTURES / "node_templates" / "index_samples") - + # use a non-nodejs template directory + with util.chdir(FIXTURES / "node_templates" / "index_samples"): with pytest.raises(AttributeError) as err: node.generate_index_ts([], "v1") assert "can't be empty" in err.args - finally: - os.chdir(cwd) def test_generate_index_ts_invalid_default_version(): - cwd = os.getcwd() - try: - # use a non-nodejs template directory - os.chdir(FIXTURES / "node_templates" / "index_samples") + # use a non-nodejs template directory + with util.chdir(FIXTURES / "node_templates" / "index_samples"): versions = ["v1beta1"] default_version = "v1" with pytest.raises(AttributeError) as err: node.generate_index_ts(versions, default_version) assert f"must contain default version {default_version}" in err.args - finally: - os.chdir(cwd) def test_generate_index_ts_no_clients(): - cwd = os.getcwd() - try: - # use a non-nodejs template directory - os.chdir(FIXTURES / "node_templates" / "index_samples") + # use a non-nodejs template directory + with util.chdir(FIXTURES / "node_templates" / "index_samples"): versions = ["v1", "v1beta1", "invalid_index"] default_version = "invalid_index" @@ -175,8 +148,6 @@ def test_generate_index_ts_no_clients(): f"No client is exported in the default version's({default_version}) index.ts ." in err.args ) - finally: - os.chdir(cwd) class TestPostprocess(TestCase): @@ -211,28 +182,16 @@ def test_postprocess_gapic_library(self, shell_run_mock): # present in the docker image but absent while running unit tests. @patch("synthtool.languages.node.postprocess_gapic_library_hermetic") def test_owlbot_main(hermetic_mock): - temp_dir = Path(tempfile.mkdtemp()) - shutil.copytree(FIXTURES / "nodejs-dlp", temp_dir / "nodejs-dlp") - cwd = os.getcwd() - try: - os.chdir(temp_dir / "nodejs-dlp") + with util.copied_fixtures_dir(FIXTURES / "nodejs-dlp"): # just confirm it doesn't throw an exception. node.owlbot_main(TEMPLATES) - finally: - os.chdir(cwd) @pytest.fixture def nodejs_dlp(): """chdir to a copy of nodejs-dlp-with-staging.""" - temp_dir = Path(tempfile.mkdtemp()) - shutil.copytree(FIXTURES / "nodejs-dlp-with-staging", temp_dir / "nodejs-dlp") - cwd = os.getcwd() - try: - os.chdir(temp_dir / "nodejs-dlp") - yield temp_dir / "nodejs-dlp" - finally: - os.chdir(cwd) + with util.copied_fixtures_dir(FIXTURES / "nodejs-dlp-with-staging") as workdir: + yield workdir @patch("synthtool.languages.node.postprocess_gapic_library_hermetic") @@ -320,13 +279,10 @@ def test_detect_versions_src(): src_dir = temp_dir / "src" for v in ("v1", "v2", "v3"): os.makedirs(src_dir / v) - cwd = os.getcwd() - try: - os.chdir(temp_dir) + + with util.chdir(temp_dir): versions = node.detect_versions() assert ["v1", "v2", "v3"] == versions - finally: - os.chdir(cwd) def test_detect_versions_staging(): @@ -352,14 +308,11 @@ def test_detect_versions_with_default(): vs = ("v1", "v2", "v3") for v in vs: os.makedirs(src_dir / v) - cwd = os.getcwd() - try: - os.chdir(temp_dir) + + with util.chdir(temp_dir): versions = node.detect_versions(default_version="v1") assert ["v2", "v3", "v1"] == versions versions = node.detect_versions(default_version="v2") assert ["v1", "v3", "v2"] == versions versions = node.detect_versions(default_version="v3") assert ["v1", "v2", "v3"] == versions - finally: - os.chdir(cwd) diff --git a/tests/test_partials.py b/tests/test_partials.py index 07c3da71b..ed89a1558 100644 --- a/tests/test_partials.py +++ b/tests/test_partials.py @@ -12,23 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os from pathlib import Path from synthtool.gcp import partials +from . import util FIXTURES = Path(__file__).parent / "fixtures" / "node_templates" / "standard" def test_readme_partials(): - cwd = os.getcwd() - os.chdir(FIXTURES) - - data = partials.load_partials() - # should have populated introduction from partial. - assert "objects to users via direct download" in data["introduction"] - - os.chdir(cwd) + with util.chdir(FIXTURES): + data = partials.load_partials() + # should have populated introduction from partial. + assert "objects to users via direct download" in data["introduction"] def test_readme_partials_not_found(): diff --git a/tests/test_python_library.py b/tests/test_python_library.py index fdcef75a8..04fdb9a12 100644 --- a/tests/test_python_library.py +++ b/tests/test_python_library.py @@ -19,6 +19,7 @@ from synthtool import gcp from synthtool.sources import templates +from . import util PYTHON_LIBRARY = Path(__file__).parent.parent / "synthtool/gcp/templates/python_library" @@ -101,27 +102,27 @@ def test_library_noxfile(template_kwargs, expected_text): def test_python_library(): - os.chdir(Path(__file__).parent / "fixtures/python_library") - template_dir = Path(__file__).parent.parent / "synthtool/gcp/templates" - common = gcp.CommonTemplates(template_path=template_dir) - templated_files = common.py_library() + with util.chdir(Path(__file__).parent / "fixtures/python_library"): + template_dir = Path(__file__).parent.parent / "synthtool/gcp/templates" + common = gcp.CommonTemplates(template_path=template_dir) + templated_files = common.py_library() - assert os.path.exists(templated_files / ".kokoro/docs/docs-presubmit.cfg") - assert os.path.exists(templated_files / ".kokoro/docker/docs/fetch_gpg_keys.sh") + assert os.path.exists(templated_files / ".kokoro/docs/docs-presubmit.cfg") + assert os.path.exists(templated_files / ".kokoro/docker/docs/fetch_gpg_keys.sh") def test_split_system_tests(): - os.chdir(Path(__file__).parent / "fixtures/python_library") - template_dir = Path(__file__).parent.parent / "synthtool/gcp/templates" - common = gcp.CommonTemplates(template_path=template_dir) - templated_files = common.py_library(split_system_tests=True) + with util.chdir(Path(__file__).parent / "fixtures/python_library"): + template_dir = Path(__file__).parent.parent / "synthtool/gcp/templates" + common = gcp.CommonTemplates(template_path=template_dir) + templated_files = common.py_library(split_system_tests=True) - with open(templated_files / ".kokoro/presubmit/presubmit.cfg", "r") as f: - contents = f.read() - assert "RUN_SYSTEM_TESTS" in contents - assert "false" in contents + with open(templated_files / ".kokoro/presubmit/presubmit.cfg", "r") as f: + contents = f.read() + assert "RUN_SYSTEM_TESTS" in contents + assert "false" in contents - assert os.path.exists(templated_files / ".kokoro/presubmit/system-3.8.cfg") - with open(templated_files / ".kokoro/presubmit/system-3.8.cfg", "r") as f: - contents = f.read() - assert "system-3.8" in contents + assert os.path.exists(templated_files / ".kokoro/presubmit/system-3.8.cfg") + with open(templated_files / ".kokoro/presubmit/system-3.8.cfg", "r") as f: + contents = f.read() + assert "system-3.8" in contents diff --git a/tests/test_samples.py b/tests/test_samples.py index c6b18fb3e..d2bb6c6d0 100644 --- a/tests/test_samples.py +++ b/tests/test_samples.py @@ -12,28 +12,24 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os from pathlib import Path from synthtool.gcp import samples +from . import util FIXTURES = Path(__file__).parent / "fixtures" def test_load_node_samples(): - cwd = os.getcwd() - os.chdir(FIXTURES / "node_templates" / "standard") - - all_samples = samples.all_samples(["samples/*.js"]) - - # should have loaded samples. - assert all_samples[3]["title"] == "Requester Pays" - assert all_samples[3]["file"] == "samples/requesterPays.js" - assert len(all_samples) == 4 - - # should have included additional meta-information provided. - assert all_samples[0]["title"] == "Metadata Example 1" - assert all_samples[0]["usage"] == "node hello-world.js" - assert all_samples[1]["title"] == "Metadata Example 2" - assert all_samples[1]["usage"] == "node goodnight-moon.js" - - os.chdir(cwd) + with util.chdir(FIXTURES / "node_templates" / "standard"): + all_samples = samples.all_samples(["samples/*.js"]) + + # should have loaded samples. + assert all_samples[3]["title"] == "Requester Pays" + assert all_samples[3]["file"] == "samples/requesterPays.js" + assert len(all_samples) == 4 + + # should have included additional meta-information provided. + assert all_samples[0]["title"] == "Metadata Example 1" + assert all_samples[0]["usage"] == "node hello-world.js" + assert all_samples[1]["title"] == "Metadata Example 2" + assert all_samples[1]["usage"] == "node goodnight-moon.js" diff --git a/tests/test_snippets.py b/tests/test_snippets.py index 5870db510..40195cfd9 100644 --- a/tests/test_snippets.py +++ b/tests/test_snippets.py @@ -12,32 +12,30 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os from pathlib import Path from synthtool.gcp import snippets +from . import util FIXTURES = Path(__file__).parent / "fixtures" def test_load_snippets(): - cwd = os.getcwd() - os.chdir(FIXTURES) + with util.chdir(FIXTURES): + all_snippets = snippets.all_snippets(["snippets/*.java", "snippets/*.xml"]) + assert len(all_snippets) == 2 - all_snippets = snippets.all_snippets(["snippets/*.java", "snippets/*.xml"]) - assert len(all_snippets) == 2 - - assert ( - all_snippets["monitoring_quickstart"] - == """ + assert ( + all_snippets["monitoring_quickstart"] + == """ public class MonitoringQuickstartSample { // do something } """ - ) - assert ( - all_snippets["monitoring_install_with_bom"] - == """ + ) + assert ( + all_snippets["monitoring_install_with_bom"] + == """ com.google.cloud @@ -56,83 +54,65 @@ def test_load_snippets(): """ - ) - - os.chdir(cwd) + ) def test_interleaving_snippets(): - cwd = os.getcwd() - os.chdir(FIXTURES) - - all_snippets = snippets.all_snippets_from_file("snippets/interleaved.js") - assert len(all_snippets) == 2 + with util.chdir(FIXTURES): + all_snippets = snippets.all_snippets_from_file("snippets/interleaved.js") + assert len(all_snippets) == 2 - assert ( - all_snippets["interleave_snippet_1"] - == """var line1 = 1; + assert ( + all_snippets["interleave_snippet_1"] + == """var line1 = 1; var line2 = 2; """ - ) + ) - assert ( - all_snippets["interleave_snippet_2"] - == """var line2 = 2; + assert ( + all_snippets["interleave_snippet_2"] + == """var line2 = 2; var line3 = 3; """ - ) - - os.chdir(cwd) + ) def test_interleaving_snippets_with_exclude(): - cwd = os.getcwd() - os.chdir(FIXTURES) - - all_snippets = snippets.all_snippets_from_file( - "snippets/interleaved_with_exclude.js" - ) - assert len(all_snippets) == 1 - - assert ( - all_snippets["snippet_1"] - == """var line1 = 1; + with util.chdir(FIXTURES): + all_snippets = snippets.all_snippets_from_file( + "snippets/interleaved_with_exclude.js" + ) + assert len(all_snippets) == 1 + + assert ( + all_snippets["snippet_1"] + == """var line1 = 1; var line3 = 3; """ - ) - - os.chdir(cwd) + ) def test_nested_snippets(): - cwd = os.getcwd() - os.chdir(FIXTURES) - - all_snippets = snippets.all_snippets_from_file("snippets/nested.js") - assert len(all_snippets) == 2 + with util.chdir(FIXTURES): + all_snippets = snippets.all_snippets_from_file("snippets/nested.js") + assert len(all_snippets) == 2 - assert ( - all_snippets["nested_snippet_1"] - == """var line1 = 1; + assert ( + all_snippets["nested_snippet_1"] + == """var line1 = 1; var line2 = 2; var line3 = 3; """ - ) + ) - assert ( - all_snippets["nested_snippet_2"] - == """var line2 = 2; + assert ( + all_snippets["nested_snippet_2"] + == """var line2 = 2; """ - ) - - os.chdir(cwd) + ) def test_non_existent_file(): - cwd = os.getcwd() - os.chdir(FIXTURES) - - all_snippets = snippets.all_snippets_from_file("snippets/non-existent-file.foo") - assert len(all_snippets) == 0 - - os.chdir(cwd) + with util.chdir(FIXTURES): + all_snippets = snippets.all_snippets_from_file("snippets/non-existent-file.foo") + assert len(all_snippets) == 0 diff --git a/tests/test_transforms.py b/tests/test_transforms.py index 210b2dfe0..b5033a066 100644 --- a/tests/test_transforms.py +++ b/tests/test_transforms.py @@ -23,6 +23,7 @@ from synthtool import transforms from synthtool import _tracked_paths +from . import util import pathlib @@ -165,15 +166,11 @@ def test__dont_overwrite(): Path(dirb).joinpath("README.md").write_text("chickens") Path(dirb).joinpath("code.py").write_text("# chickens") - cwd = os.getcwd() - os.chdir(dirb) - try: + with util.chdir(dirb): _tracked_paths.add(dira) transforms.move( [Path(dira).joinpath("*")], merge=transforms.dont_overwrite(["*.md"]) ) - finally: - os.chdir(cwd) # Should not have been overwritten. assert "chickens" == Path(dirb).joinpath("README.md").read_text() @@ -189,14 +186,14 @@ def test__move_to_dest_subdir(expand_path_fixtures): dest = Path(str(expand_path_fixtures / normpath("dest/dira"))) # Move to a different dir to make sure that move doesn't depend on the cwd - os.chdir(tempfile.gettempdir()) - transforms.move(tmp_path / "dira", dest, excludes=["f.py"]) + with util.chdir(tempfile.gettempdir()): + transforms.move(tmp_path / "dira", dest, excludes=["f.py"]) - os.chdir(str(tmp_path)) - files = sorted([str(x) for x in transforms._expand_paths("**/*", root="dest")]) + with util.chdir(str(tmp_path)): + files = sorted([str(x) for x in transforms._expand_paths("**/*", root="dest")]) - # Assert destination does not contain dira/f.py (excluded) - assert files == [normpath("dest/dira"), normpath("dest/dira/e.txt")] + # Assert destination does not contain dira/f.py (excluded) + assert files == [normpath("dest/dira"), normpath("dest/dira/e.txt")] def test_simple_replace(expand_path_fixtures): @@ -258,27 +255,20 @@ def test_copy_with_merge_file_permissions(expand_path_fixtures): assert os.stat(destination_file).st_mode != os.stat(template).st_mode # Move to a different dir to make sure that move doesn't depend on the cwd - os.chdir(tempfile.gettempdir()) - transforms.move( - sources=template_directory / "executable_file.sh", - destination=expand_path_fixtures / "executable_file.sh", - merge=_noop_merge, - required=True, - ) - - # ensure that the destination existing file now has the correct file permissions - assert os.stat(destination_file).st_mode == os.stat(template).st_mode - - -@pytest.fixture(scope="function") -def change_test_dir(): - cur = os.curdir - os.chdir(Path(__file__).parent / "fixtures/staging_dirs") - yield - os.chdir(cur) - - -def test_get_staging_dirs(change_test_dir): - assert [path.name for path in transforms.get_staging_dirs("v1")] == ["v2", "v1"] - assert [path.name for path in transforms.get_staging_dirs("v2")] == ["v1", "v2"] - assert [path.name for path in transforms.get_staging_dirs()] == ["v1", "v2"] + with util.chdir(tempfile.gettempdir()): + transforms.move( + sources=template_directory / "executable_file.sh", + destination=expand_path_fixtures / "executable_file.sh", + merge=_noop_merge, + required=True, + ) + + # ensure that the destination existing file now has the correct file permissions + assert os.stat(destination_file).st_mode == os.stat(template).st_mode + + +def test_get_staging_dirs(): + with util.chdir(Path(__file__).parent / "fixtures/staging_dirs"): + assert [path.name for path in transforms.get_staging_dirs("v1")] == ["v2", "v1"] + assert [path.name for path in transforms.get_staging_dirs("v2")] == ["v1", "v2"] + assert [path.name for path in transforms.get_staging_dirs()] == ["v1", "v2"] diff --git a/tests/test_util.py b/tests/test_util.py new file mode 100644 index 000000000..4286bd4bb --- /dev/null +++ b/tests/test_util.py @@ -0,0 +1,46 @@ +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +from pathlib import Path + +from . import util + +TEST_PATH = Path(__file__).parent / "testdata" + + +def test_chdir(): + cwd = os.getcwd() + with util.chdir(TEST_PATH): + assert os.getcwd().endswith("/testdata") + + assert os.getcwd() == cwd + + +def test_chdir_str(): + cwd = os.getcwd() + with util.chdir(str(TEST_PATH)): + assert os.getcwd().endswith("/testdata") + + assert os.getcwd() == cwd + + +def test_chdir_restores_on_error(): + cwd = os.getcwd() + try: + with util.chdir(TEST_PATH): + raise RuntimeError("foo") + except RuntimeError: + pass + assert os.getcwd() == cwd diff --git a/tests/util.py b/tests/util.py index 1cdff17e0..c0b200eaa 100644 --- a/tests/util.py +++ b/tests/util.py @@ -11,9 +11,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +import contextlib import subprocess +import os import pathlib +import shutil import sys +import tempfile +import typing def make_working_repo(working_dir: str): @@ -82,3 +88,38 @@ def make_working_repo(working_dir: str): ) return text + + +@contextlib.contextmanager +def chdir(path: typing.Union[pathlib.Path, str]): + """Context Manager to change the current working directory and restore the + previous working directory after completing the context. + + Args: + path (pathlib.Path, str) - The new current working directory. + Yields: + pathlib.Path - The new current working directory. + """ + old_cwd = os.getcwd() + os.chdir(str(path)) + try: + yield pathlib.Path(path) + finally: + os.chdir(old_cwd) + + +@contextlib.contextmanager +def copied_fixtures_dir(source: pathlib.Path): + """Context Manager to copy from a fixtures directory into a new temporary directory + and change the current working directory to that copy. Restores the original + current working directory after completing the context. + + Args: + source (pathlib.Path) - The directory to copy. + Yields: + pathlib.Path - The temporary directory with the copied contents. + """ + with tempfile.TemporaryDirectory() as tempdir: + workdir = shutil.copytree(source, pathlib.Path(tempdir) / "workspace") + with chdir(workdir): + yield workdir