mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
When enabling the `warn_unused_ignores = True` option of mypy, this
was making the `test_galaxy_packages` tests fail with:
```
mypy .
Traceback (most recent call last):
File "/tmp/gxpkgtestenvu3fgDr/bin/mypy", line 8, in <module>
sys.exit(console_entry())
File "/tmp/gxpkgtestenvu3fgDr/lib/python3.10/site-packages/mypy/__main__.py", line 15, in console_entry
main()
File "mypy/main.py", line 100, in main
File "mypy/main.py", line 182, in run_build
File "mypy/build.py", line 192, in build
File "mypy/build.py", line 266, in _build
File "mypy/build.py", line 2942, in dispatch
File "mypy/build.py", line 3333, in process_graph
File "mypy/build.py", line 3414, in process_fresh_modules
File "mypy/build.py", line 2110, in fix_cross_refs
File "mypy/fixup.py", line 52, in fixup_module
File "mypy/fixup.py", line 127, in visit_symbol_table
File "mypy/lookup.py", line 49, in lookup_fully_qualified
AssertionError: Cannot find component 'util' for 'galaxy.util'
make: *** [Makefile:96: mypy] Error 1
```
Moreover, installing packages in editable mode was hiding some issues
with how files from other packages were accessed.
168 lines
5.2 KiB
Python
168 lines
5.2 KiB
Python
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from galaxy.config import BaseAppConfiguration
|
|
from galaxy.config.schema import AppSchema
|
|
from galaxy.exceptions import ConfigurationError
|
|
|
|
# When a config property 'foo' has an attribute 'path_resolves_to', that attribute is a reference to
|
|
# another property 'bar'. Together, these two properties form a graph where 'foo' and 'bar are
|
|
# vertices and the reference from 'foo' to 'bar' is a directed edge.
|
|
#
|
|
# A schema may have any number of such implicit graphs, each having one or more edges. All together,
|
|
# they should form a DAG (directed acyclic graph).
|
|
#
|
|
# These tests ensure that the graph is loaded correctly for a variety of valid configurations,
|
|
# whereas an invalid configuration raises an error.
|
|
|
|
|
|
def get_schema(app_mapping):
|
|
return {"mapping": {"_": {"mapping": app_mapping}}}
|
|
|
|
|
|
def test_basecase(monkeypatch):
|
|
# Check that a valid graph is loaded correctly (this graph has 2 components)
|
|
mock_schema = {
|
|
"component1_path0": {
|
|
"type": "str",
|
|
"default": "value0",
|
|
},
|
|
"component1_path1": {
|
|
"type": "str",
|
|
"default": "value1",
|
|
"path_resolves_to": "component1_path0",
|
|
},
|
|
"component1_path2": {
|
|
"type": "str",
|
|
"default": "value2",
|
|
"path_resolves_to": "component1_path1",
|
|
},
|
|
"component2_path0": {
|
|
"type": "str",
|
|
"default": "value3",
|
|
},
|
|
"component2_path1": {
|
|
"type": "str",
|
|
"default": "value4",
|
|
"path_resolves_to": "component2_path0",
|
|
},
|
|
}
|
|
monkeypatch.setattr(AppSchema, "_read_schema", lambda a, b: get_schema(mock_schema))
|
|
monkeypatch.setattr(BaseAppConfiguration, "_load_schema", lambda a: AppSchema(Path("no path"), "_"))
|
|
|
|
config = BaseAppConfiguration()
|
|
assert config.component1_path0 == "value0"
|
|
assert config.component1_path1 == "value0/value1"
|
|
assert config.component1_path2 == "value0/value1/value2"
|
|
assert config.component2_path0 == "value3"
|
|
assert config.component2_path1 == "value3/value4"
|
|
|
|
|
|
def test_resolves_to_invalid_property(monkeypatch):
|
|
# 'path_resolves_to' should point to an existing property in the schema
|
|
mock_schema = {
|
|
"path0": {
|
|
"type": "str",
|
|
"default": "value0",
|
|
},
|
|
"path1": {
|
|
"type": "str",
|
|
"default": "value1",
|
|
"path_resolves_to": "invalid", # invalid
|
|
},
|
|
}
|
|
monkeypatch.setattr(AppSchema, "_read_schema", lambda a, b: get_schema(mock_schema))
|
|
|
|
with pytest.raises(ConfigurationError):
|
|
AppSchema(Path("no path"), "_").validate_path_resolution_graph()
|
|
|
|
|
|
def test_path_resolution_cycle(monkeypatch):
|
|
# Must be a DAG, but this one has a cycle
|
|
mock_schema = {
|
|
"path0": {
|
|
"type": "str",
|
|
"default": "value0",
|
|
"path_resolves_to": "path2",
|
|
},
|
|
"path1": {
|
|
"type": "str",
|
|
"default": "value1",
|
|
"path_resolves_to": "path0",
|
|
},
|
|
"path2": {
|
|
"type": "str",
|
|
"default": "value2",
|
|
"path_resolves_to": "path1",
|
|
},
|
|
}
|
|
monkeypatch.setattr(AppSchema, "_read_schema", lambda a, b: get_schema(mock_schema))
|
|
|
|
with pytest.raises(ConfigurationError):
|
|
AppSchema(Path("no path"), "_").validate_path_resolution_graph()
|
|
|
|
|
|
def test_path_invalid_type(monkeypatch):
|
|
# Paths should be strings
|
|
mock_schema = {
|
|
"path0": {
|
|
"type": "str",
|
|
"default": "value0",
|
|
},
|
|
"path1": {
|
|
"type": "float", # invalid
|
|
"default": "value1",
|
|
"path_resolves_to": "path0",
|
|
},
|
|
}
|
|
monkeypatch.setattr(AppSchema, "_read_schema", lambda a, b: get_schema(mock_schema))
|
|
|
|
with pytest.raises(ConfigurationError):
|
|
AppSchema(Path("no path"), "_").validate_path_resolution_graph()
|
|
|
|
|
|
def test_resolves_to_invalid_type(monkeypatch):
|
|
# Paths should be strings
|
|
mock_schema = {
|
|
"path0": {
|
|
"type": "int", # invalid
|
|
"default": "value0",
|
|
},
|
|
"path1": {
|
|
"type": "str",
|
|
"default": "value1",
|
|
"path_resolves_to": "path0",
|
|
},
|
|
}
|
|
monkeypatch.setattr(AppSchema, "_read_schema", lambda a, b: get_schema(mock_schema))
|
|
|
|
with pytest.raises(ConfigurationError):
|
|
AppSchema(Path("no path"), "_").validate_path_resolution_graph()
|
|
|
|
|
|
def test_resolves_with_empty_component(monkeypatch):
|
|
# A path can be None (root path is never None; may be asigned elsewhere)
|
|
mock_schema = {
|
|
"path0": {
|
|
"type": "str",
|
|
"default": "value0",
|
|
},
|
|
"path1": {
|
|
"type": "str",
|
|
"path_resolves_to": "path0",
|
|
},
|
|
"path2": {
|
|
"type": "str",
|
|
"default": "value2",
|
|
"path_resolves_to": "path1",
|
|
},
|
|
}
|
|
monkeypatch.setattr(AppSchema, "_read_schema", lambda a, b: get_schema(mock_schema))
|
|
monkeypatch.setattr(BaseAppConfiguration, "_load_schema", lambda a: AppSchema(Path("no path"), "_"))
|
|
|
|
config = BaseAppConfiguration()
|
|
assert config.path0 == "value0"
|
|
assert config.path1 == "value0"
|
|
assert config.path2 == "value0/value2"
|