mirror of
https://github.com/minetest/contentdb.git
synced 2024-12-22 14:02:24 +01:00
Add broken test for game support issue
This commit is contained in:
parent
e31433f320
commit
2a84ec5bad
@ -13,7 +13,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import sys
|
||||
from typing import List, Dict, Optional, Tuple
|
||||
|
||||
import sqlalchemy
|
||||
@ -90,6 +90,7 @@ class GSPackage:
|
||||
return self.user_unsupported_games
|
||||
|
||||
def add_error(self, error: str):
|
||||
print(f"ERROR {self.name}: {error}")
|
||||
return self.errors.add(error)
|
||||
|
||||
|
||||
@ -135,10 +136,12 @@ class GameSupport:
|
||||
return [package for package in self.packages.values() if modname in package.depends]
|
||||
|
||||
def _get_supported_games_for_modname(self, depend: str, visited: list[str]):
|
||||
print(f"_get_supported_games_for_modname {depend} visited {', '.join(visited)}", file=sys.stderr)
|
||||
dep_supports_all = False
|
||||
for_dep = set()
|
||||
for provider in self.get_all_that_provide(depend):
|
||||
found_in = self._get_supported_games(provider, visited)
|
||||
print(f" - provider for {depend}: {provider.name}: {found_in}", file=sys.stderr)
|
||||
if found_in is None:
|
||||
# Unsupported, keep going
|
||||
pass
|
||||
@ -151,6 +154,7 @@ class GameSupport:
|
||||
return dep_supports_all, for_dep
|
||||
|
||||
def _get_supported_games_for_deps(self, package: GSPackage, visited: list[str]) -> Optional[set[str]]:
|
||||
print(f"_get_supported_games_for_deps package {package.name} visited {', '.join(visited)}", file=sys.stderr)
|
||||
ret = set()
|
||||
|
||||
for depend in package.depends:
|
||||
@ -173,6 +177,7 @@ class GameSupport:
|
||||
return ret
|
||||
|
||||
def _get_supported_games(self, package: GSPackage, visited: list[str]) -> Optional[set[str]]:
|
||||
print(f"_get_supported_games package {package.name} visited {', '.join(visited)}", file=sys.stderr)
|
||||
if package.id_ in visited:
|
||||
first_idx = visited.index(package.id_)
|
||||
visited = visited[first_idx:]
|
||||
@ -183,8 +188,10 @@ class GameSupport:
|
||||
return None
|
||||
|
||||
if package.type == PackageType.GAME:
|
||||
print(f"_get_supported_games package {package.name} is game", file=sys.stderr)
|
||||
return {package.name}
|
||||
elif package.is_confirmed:
|
||||
print(f"_get_supported_games package {package.name} is confirmed", file=sys.stderr)
|
||||
return package.supported_games
|
||||
|
||||
visited = visited.copy()
|
||||
@ -221,6 +228,7 @@ class GameSupport:
|
||||
|
||||
while len(to_update) > 0:
|
||||
current_package = to_update.pop()
|
||||
print(f"on_update package {current_package.name}", file=sys.stderr)
|
||||
if current_package.id_ in self.packages and current_package.type != PackageType.GAME:
|
||||
self._get_supported_games(current_package, [])
|
||||
|
||||
|
@ -217,6 +217,14 @@ def test_cycle_fails_safely():
|
||||
"""
|
||||
A dependency cycle shouldn't completely break the graph if a mod is
|
||||
available elsewhere
|
||||
|
||||
a -> d
|
||||
game has d
|
||||
|
||||
cycle:
|
||||
d -> b
|
||||
b -> c
|
||||
c -> b
|
||||
"""
|
||||
support = GameSupport()
|
||||
support.add(make_game("game1", ["default", "mod_d"]))
|
||||
@ -241,6 +249,68 @@ def test_cycle_fails_safely():
|
||||
}
|
||||
|
||||
|
||||
def test_cycle_not_fulfill_with_conflict():
|
||||
"""
|
||||
Test that cycles aren't fulfilled by installing a mod multiple times, which would conflict
|
||||
|
||||
a -> b -> a
|
||||
game1 has a
|
||||
|
||||
b should be {game1}
|
||||
a should be unfulfilled
|
||||
"""
|
||||
support = GameSupport()
|
||||
support.add(make_game("game1", ["default", "mod_a"]))
|
||||
modB = support.add(make_mod("mod_b", ["mod_b"], ["mod_a"]))
|
||||
modA = support.add(make_mod("mod_a", ["mod_a"], ["mod_b"]))
|
||||
support.on_first_run()
|
||||
|
||||
assert modB.is_confirmed
|
||||
assert modB.detected_supported_games == {"game1"}
|
||||
|
||||
# Can't install mod_a and game1 at the same time
|
||||
assert not modA.is_confirmed
|
||||
assert modA.detected_supported_games == {}
|
||||
|
||||
assert support.all_errors == {
|
||||
"author/mod_a: Dependency cycle detected: author/mod_b -> author/mod_a -> author/mod_b",
|
||||
"author/mod_b: Dependency cycle detected: author/mod_b -> author/mod_a -> author/mod_b",
|
||||
}
|
||||
|
||||
|
||||
def test_cycle_not_fulfill_with_conflict2():
|
||||
"""
|
||||
Test that cycles aren't fulfilled by installing a mod multiple times, which would conflict
|
||||
|
||||
a -> b -> a
|
||||
game1 has a
|
||||
|
||||
b should be {game1}
|
||||
a should be unfulfilled
|
||||
"""
|
||||
support = GameSupport()
|
||||
support.add(make_game("game1", ["default"]))
|
||||
modB = support.add(make_mod("mod_b", ["mod_b"], ["mod_a"]))
|
||||
modA2 = support.add(make_mod("mod_a", ["mod_a"], ["default"]))
|
||||
modA = support.add(make_mod("mod_a", ["mod_a"], ["mod_b"]))
|
||||
support.on_first_run()
|
||||
|
||||
assert modB.is_confirmed
|
||||
assert modB.detected_supported_games == {"game1"}
|
||||
|
||||
assert modA2.is_confirmed
|
||||
assert modA2.detected_supported_games == {"game1"}
|
||||
|
||||
# Can't install modA and modA2 at the same time
|
||||
assert not modA.is_confirmed
|
||||
assert modA.detected_supported_games == {}
|
||||
|
||||
assert support.all_errors == {
|
||||
"author/mod_a: Dependency cycle detected: author/mod_b -> author/mod_a -> author/mod_b",
|
||||
"author/mod_b: Dependency cycle detected: author/mod_b -> author/mod_a -> author/mod_b",
|
||||
}
|
||||
|
||||
|
||||
def test_update():
|
||||
"""
|
||||
Test updating a mod will update mods that depend on it
|
||||
|
Loading…
Reference in New Issue
Block a user