# Copyright 2023 Greptime Team # # 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 # # http://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 importlib.util import tempfile import textwrap import unittest from pathlib import Path SCRIPT_PATH = Path(__file__).resolve().parent / "check-enterprise-license.py" spec = importlib.util.spec_from_file_location("check_enterprise_license", SCRIPT_PATH) checker = importlib.util.module_from_spec(spec) spec.loader.exec_module(checker) def write(root: Path, relative: str, source: str) -> Path: path = root / relative path.parent.mkdir(parents=True, exist_ok=True) path.write_text(textwrap.dedent(source).lstrip(), encoding="utf-8") return path class ParseModDeclsTest(unittest.TestCase): def parse(self, source: str) -> dict[str, bool]: return dict(checker.parse_mod_decls(textwrap.dedent(source))) def test_gate_applies_only_to_the_next_declaration(self): self.assertEqual( self.parse( """ #[cfg(feature = "enterprise")] pub mod trigger; mod plain; """ ), {"trigger": True, "plain": False}, ) def test_test_only_gate_counts_as_enterprise(self): self.assertEqual( self.parse( """ #[cfg(all(test, feature = "enterprise"))] mod recycle_bin_test; """ ), {"recycle_bin_test": True}, ) def test_non_gating_enterprise_attributes_are_ignored(self): self.assertEqual( self.parse( """ #[cfg(any(test, feature = "enterprise"))] mod shared_test; #[cfg_attr(feature = "enterprise", allow(dead_code))] mod shared; """ ), {"shared_test": False, "shared": False}, ) def test_doc_comment_between_attribute_and_declaration(self): self.assertEqual( self.parse( """ #[cfg(feature = "enterprise")] /// Enterprise only. pub(crate) mod gated; """ ), {"gated": True}, ) def test_attribute_on_the_same_line(self): self.assertEqual( self.parse('#[cfg(feature = "enterprise")] mod gated;\n'), {"gated": True}, ) def test_attribute_consumed_by_another_item_does_not_leak(self): self.assertEqual( self.parse( """ #[cfg(feature = "enterprise")] use crate::gated::Thing; mod plain; """ ), {"plain": False}, ) def test_other_features_are_not_enterprise(self): self.assertEqual( self.parse( """ #[cfg(feature = "testing")] mod helper; """ ), {"helper": False}, ) def test_inline_module_is_ignored(self): self.assertEqual( self.parse( """ #[cfg(feature = "enterprise")] mod inline { pub const A: u8 = 1; } """ ), {}, ) class CollectGatedFilesTest(unittest.TestCase): def collect(self, root: Path): rust_files = sorted(root.rglob("*.rs")) return checker.collect_gated_files(rust_files) def test_descendants_of_a_gated_module_are_gated(self): with tempfile.TemporaryDirectory() as temp_dir: root = Path(temp_dir) write( root, "src/lib.rs", """ #[cfg(feature = "enterprise")] pub mod gated; pub mod plain; """, ) write(root, "src/gated.rs", "pub mod nested;\n") write(root, "src/gated/nested.rs", "pub const A: u8 = 1;\n") write(root, "src/plain.rs", "pub const B: u8 = 2;\n") gated, unresolved = self.collect(root) self.assertEqual( gated, {root / "src/gated.rs", root / "src/gated/nested.rs"}, ) self.assertEqual(unresolved, []) def test_module_declared_as_directory(self): with tempfile.TemporaryDirectory() as temp_dir: root = Path(temp_dir) write( root, "src/lib.rs", """ #[cfg(feature = "enterprise")] mod gated; """, ) write(root, "src/gated/mod.rs", "mod leaf;\n") write(root, "src/gated/leaf.rs", "pub const A: u8 = 1;\n") gated, unresolved = self.collect(root) self.assertEqual( gated, {root / "src/gated/mod.rs", root / "src/gated/leaf.rs"}, ) self.assertEqual(unresolved, []) def test_missing_file_is_reported(self): with tempfile.TemporaryDirectory() as temp_dir: root = Path(temp_dir) declaring = write( root, "src/lib.rs", """ #[cfg(feature = "enterprise")] mod elsewhere; """, ) gated, unresolved = self.collect(root) self.assertEqual(gated, set()) self.assertEqual(unresolved, [(declaring, "elsewhere")]) class ConfigSyncTest(unittest.TestCase): def test_load_marked_paths(self): with tempfile.TemporaryDirectory() as temp_dir: config = write( Path(temp_dir), "licenserc.toml", """ excludes = [ "copied.rs", # enterprise:start "gated.rs", # enterprise:end ] """, ) self.assertEqual( checker.load_marked_paths( config, checker.ENTERPRISE_EXCLUDES_START, checker.ENTERPRISE_EXCLUDES_END, ), {"gated.rs"}, ) if __name__ == "__main__": unittest.main()