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
|
# 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/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
import sys
|
||||||
from typing import List, Dict, Optional, Tuple
|
from typing import List, Dict, Optional, Tuple
|
||||||
|
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
@ -90,6 +90,7 @@ class GSPackage:
|
|||||||
return self.user_unsupported_games
|
return self.user_unsupported_games
|
||||||
|
|
||||||
def add_error(self, error: str):
|
def add_error(self, error: str):
|
||||||
|
print(f"ERROR {self.name}: {error}")
|
||||||
return self.errors.add(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]
|
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]):
|
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
|
dep_supports_all = False
|
||||||
for_dep = set()
|
for_dep = set()
|
||||||
for provider in self.get_all_that_provide(depend):
|
for provider in self.get_all_that_provide(depend):
|
||||||
found_in = self._get_supported_games(provider, visited)
|
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:
|
if found_in is None:
|
||||||
# Unsupported, keep going
|
# Unsupported, keep going
|
||||||
pass
|
pass
|
||||||
@ -151,6 +154,7 @@ class GameSupport:
|
|||||||
return dep_supports_all, for_dep
|
return dep_supports_all, for_dep
|
||||||
|
|
||||||
def _get_supported_games_for_deps(self, package: GSPackage, visited: list[str]) -> Optional[set[str]]:
|
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()
|
ret = set()
|
||||||
|
|
||||||
for depend in package.depends:
|
for depend in package.depends:
|
||||||
@ -173,6 +177,7 @@ class GameSupport:
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
def _get_supported_games(self, package: GSPackage, visited: list[str]) -> Optional[set[str]]:
|
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:
|
if package.id_ in visited:
|
||||||
first_idx = visited.index(package.id_)
|
first_idx = visited.index(package.id_)
|
||||||
visited = visited[first_idx:]
|
visited = visited[first_idx:]
|
||||||
@ -183,8 +188,10 @@ class GameSupport:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
if package.type == PackageType.GAME:
|
if package.type == PackageType.GAME:
|
||||||
|
print(f"_get_supported_games package {package.name} is game", file=sys.stderr)
|
||||||
return {package.name}
|
return {package.name}
|
||||||
elif package.is_confirmed:
|
elif package.is_confirmed:
|
||||||
|
print(f"_get_supported_games package {package.name} is confirmed", file=sys.stderr)
|
||||||
return package.supported_games
|
return package.supported_games
|
||||||
|
|
||||||
visited = visited.copy()
|
visited = visited.copy()
|
||||||
@ -221,6 +228,7 @@ class GameSupport:
|
|||||||
|
|
||||||
while len(to_update) > 0:
|
while len(to_update) > 0:
|
||||||
current_package = to_update.pop()
|
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:
|
if current_package.id_ in self.packages and current_package.type != PackageType.GAME:
|
||||||
self._get_supported_games(current_package, [])
|
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
|
A dependency cycle shouldn't completely break the graph if a mod is
|
||||||
available elsewhere
|
available elsewhere
|
||||||
|
|
||||||
|
a -> d
|
||||||
|
game has d
|
||||||
|
|
||||||
|
cycle:
|
||||||
|
d -> b
|
||||||
|
b -> c
|
||||||
|
c -> b
|
||||||
"""
|
"""
|
||||||
support = GameSupport()
|
support = GameSupport()
|
||||||
support.add(make_game("game1", ["default", "mod_d"]))
|
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():
|
def test_update():
|
||||||
"""
|
"""
|
||||||
Test updating a mod will update mods that depend on it
|
Test updating a mod will update mods that depend on it
|
||||||
|
Loading…
Reference in New Issue
Block a user