mirror of
https://github.com/yusufipk/dikte.git
synced 2026-09-11 10:56:10 +00:00
Let the new tests run on a Windows box and on a small machine
Two ways the tests were standing on this machine rather than on the one they meant to describe. Windows has no os.sysconf at all, and mock.patch.object insists the attribute exists before it will replace it, so four tests failed at the patch rather than in the body. `create=True` is what lets them stand somewhere that has no such function, which is the case the code under test already handles two lines down and which is checked on its own. And the publisher order follows the memory on purpose: a runner with 7 GB in it puts the two Gemma 4 rows last and is right to. The three tests that read an order now say which machine they are standing on instead of assuming the one that ran them has room for everything.
This commit is contained in:
+19
-6
@@ -1240,10 +1240,22 @@ class WindowsOwnership(Local):
|
|||||||
class Machine(Local):
|
class Machine(Local):
|
||||||
"""What this machine can hold, and what that makes worth pointing at."""
|
"""What this machine can hold, and what that makes worth pointing at."""
|
||||||
|
|
||||||
|
def _sysconf(self, phys_pages, page_size=4096):
|
||||||
|
"""Stand where sysconf answers whatever this test wants it to.
|
||||||
|
|
||||||
|
`create` because Windows has no os.sysconf at all, and a patch that
|
||||||
|
insists on the real attribute fails there before the test runs. What
|
||||||
|
the code under test does about that absence is two lines down from
|
||||||
|
what these are checking, and it is checked on its own below.
|
||||||
|
"""
|
||||||
|
return mock.patch.object(
|
||||||
|
ggml.os, "sysconf", create=True,
|
||||||
|
side_effect=lambda name: (page_size if name == "SC_PAGE_SIZE"
|
||||||
|
else phys_pages))
|
||||||
|
|
||||||
def test_the_memory_is_read_the_way_each_system_reports_it(self):
|
def test_the_memory_is_read_the_way_each_system_reports_it(self):
|
||||||
# Linux and most Macs answer through sysconf.
|
# Linux and most Macs answer through sysconf.
|
||||||
with mock.patch.object(ggml.os, "sysconf", lambda name:
|
with self._sysconf(4_194_304):
|
||||||
4096 if name == "SC_PAGE_SIZE" else 4_194_304):
|
|
||||||
self.assertEqual(ggml.total_memory(), 16 * ggml.GB)
|
self.assertEqual(ggml.total_memory(), 16 * ggml.GB)
|
||||||
|
|
||||||
def test_a_mac_without_the_page_count_is_asked_for_the_number(self):
|
def test_a_mac_without_the_page_count_is_asked_for_the_number(self):
|
||||||
@@ -1253,7 +1265,8 @@ class Machine(Local):
|
|||||||
self.assertEqual(args, ["sysctl", "-n", "hw.memsize"])
|
self.assertEqual(args, ["sysctl", "-n", "hw.memsize"])
|
||||||
return mock.Mock(stdout=f"{32 * ggml.GB}\n")
|
return mock.Mock(stdout=f"{32 * ggml.GB}\n")
|
||||||
|
|
||||||
with mock.patch.object(ggml.os, "sysconf", side_effect=ValueError), \
|
with mock.patch.object(ggml.os, "sysconf", create=True,
|
||||||
|
side_effect=ValueError), \
|
||||||
mock.patch.object(sys, "platform", "darwin"), \
|
mock.patch.object(sys, "platform", "darwin"), \
|
||||||
mock.patch.object(ggml.subprocess, "run", answer):
|
mock.patch.object(ggml.subprocess, "run", answer):
|
||||||
self.assertEqual(ggml.total_memory(), 32 * ggml.GB)
|
self.assertEqual(ggml.total_memory(), 32 * ggml.GB)
|
||||||
@@ -1263,8 +1276,7 @@ class Machine(Local):
|
|||||||
# CPython hands that back rather than raising, so the product came out
|
# CPython hands that back rather than raising, so the product came out
|
||||||
# negative: a 64 GB workstation was told every model past 512 MB was
|
# negative: a 64 GB workstation was told every model past 512 MB was
|
||||||
# too big for it, and the machine line read "Memory: -4096 B".
|
# too big for it, and the machine line read "Memory: -4096 B".
|
||||||
with mock.patch.object(ggml.os, "sysconf", lambda name:
|
with self._sysconf(-1):
|
||||||
4096 if name == "SC_PAGE_SIZE" else -1):
|
|
||||||
self.assertEqual(ggml.total_memory(), 0)
|
self.assertEqual(ggml.total_memory(), 0)
|
||||||
self.assertTrue(ggml.fits(574 << 20, memory=0))
|
self.assertTrue(ggml.fits(574 << 20, memory=0))
|
||||||
|
|
||||||
@@ -1279,7 +1291,8 @@ class Machine(Local):
|
|||||||
self.assertEqual(len(calls), 1)
|
self.assertEqual(len(calls), 1)
|
||||||
|
|
||||||
def test_a_system_that_answers_nothing_is_an_unknown_machine(self):
|
def test_a_system_that_answers_nothing_is_an_unknown_machine(self):
|
||||||
with mock.patch.object(ggml.os, "sysconf", side_effect=ValueError), \
|
with mock.patch.object(ggml.os, "sysconf", create=True,
|
||||||
|
side_effect=ValueError), \
|
||||||
mock.patch.object(sys, "platform", "linux"):
|
mock.patch.object(sys, "platform", "linux"):
|
||||||
self.assertEqual(ggml.total_memory(), 0)
|
self.assertEqual(ggml.total_memory(), 0)
|
||||||
|
|
||||||
|
|||||||
+26
-13
@@ -1245,6 +1245,16 @@ class LocalModels(DikteTest):
|
|||||||
def _repos(box):
|
def _repos(box):
|
||||||
return [box.repo.itemText(row) for row in range(box.repo.count())]
|
return [box.repo.itemText(row) for row in range(box.repo.count())]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _roomy():
|
||||||
|
"""Stand on a machine with room for every suggestion.
|
||||||
|
|
||||||
|
The order the publishers come in follows the memory, so a test that
|
||||||
|
reads it has to say which machine it is standing on. A build runner
|
||||||
|
with 7 GB in it puts the two Gemma 4 rows last and is right to.
|
||||||
|
"""
|
||||||
|
return mock.patch.object(ggml, "total_memory", return_value=64 << 30)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _offered(box):
|
def _offered(box):
|
||||||
"""The model names in the box, headings and duplicates left out."""
|
"""The model names in the box, headings and duplicates left out."""
|
||||||
@@ -1377,12 +1387,13 @@ class LocalModels(DikteTest):
|
|||||||
# reading the rows back the way a finished download does was doubling
|
# reading the rows back the way a finished download does was doubling
|
||||||
# it in the list every time.
|
# it in the list every time.
|
||||||
box = self.window(cfg.Config()).local_whisper
|
box = self.window(cfg.Config()).local_whisper
|
||||||
box._on_listed([("models", [
|
with self._roomy():
|
||||||
self._item("ggml-tiny.bin", 77 << 20),
|
box._on_listed([("models", [
|
||||||
self._item("ggml-large-v3-turbo-q5_0.bin", 574 << 20),
|
self._item("ggml-tiny.bin", 77 << 20),
|
||||||
], "")], "")
|
self._item("ggml-large-v3-turbo-q5_0.bin", 574 << 20),
|
||||||
before = self._offered(box)
|
], "")], "")
|
||||||
box._fill_models_from_current()
|
before = self._offered(box)
|
||||||
|
box._fill_models_from_current()
|
||||||
self.assertEqual(self._offered(box), before)
|
self.assertEqual(self._offered(box), before)
|
||||||
names = [box.model.itemData(row) for row in range(box.model.count())]
|
names = [box.model.itemData(row) for row in range(box.model.count())]
|
||||||
self.assertEqual(len([n for n in names if n]), len(before) + 1)
|
self.assertEqual(len([n for n in names if n]), len(before) + 1)
|
||||||
@@ -1423,9 +1434,10 @@ class LocalModels(DikteTest):
|
|||||||
def test_only_the_suggested_publishers_are_offered_to_start_with(self):
|
def test_only_the_suggested_publishers_are_offered_to_start_with(self):
|
||||||
# Forty repository ids is not a choice anybody can make.
|
# Forty repository ids is not a choice anybody can make.
|
||||||
box = self.window(cfg.Config()).local_llm
|
box = self.window(cfg.Config()).local_llm
|
||||||
box._on_listed([("repos", [ggml.SUGGESTED_LLM[0],
|
with self._roomy():
|
||||||
"ggml-org/something-else-GGUF"], "")], "")
|
box._on_listed([("repos", [ggml.SUGGESTED_LLM[0],
|
||||||
self.assertEqual(self._repos(box), list(ggml.SUGGESTED_LLM))
|
"ggml-org/something-else-GGUF"], "")], "")
|
||||||
|
self.assertEqual(self._repos(box), list(ggml.SUGGESTED_LLM))
|
||||||
|
|
||||||
def test_a_suggestion_missing_from_the_listing_is_still_offered(self):
|
def test_a_suggestion_missing_from_the_listing_is_still_offered(self):
|
||||||
# The listing is the forty repositories touched most recently, and a
|
# The listing is the forty repositories touched most recently, and a
|
||||||
@@ -1437,10 +1449,11 @@ class LocalModels(DikteTest):
|
|||||||
|
|
||||||
def test_the_switch_brings_the_rest_and_keeps_them_apart(self):
|
def test_the_switch_brings_the_rest_and_keeps_them_apart(self):
|
||||||
box = self.window(cfg.Config()).local_llm
|
box = self.window(cfg.Config()).local_llm
|
||||||
box._on_listed([("repos", [ggml.SUGGESTED_LLM[0],
|
with self._roomy():
|
||||||
"ggml-org/something-else-GGUF"], "")], "")
|
box._on_listed([("repos", [ggml.SUGGESTED_LLM[0],
|
||||||
box.every_repo.setChecked(True)
|
"ggml-org/something-else-GGUF"], "")], "")
|
||||||
rows = self._repos(box)
|
box.every_repo.setChecked(True)
|
||||||
|
rows = self._repos(box)
|
||||||
self.assertEqual(rows[:len(ggml.SUGGESTED_LLM)],
|
self.assertEqual(rows[:len(ggml.SUGGESTED_LLM)],
|
||||||
list(ggml.SUGGESTED_LLM))
|
list(ggml.SUGGESTED_LLM))
|
||||||
# A separator rather than a heading: the box is typed into as well as
|
# A separator rather than a heading: the box is typed into as well as
|
||||||
|
|||||||
Reference in New Issue
Block a user