Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
50 lines
2.6 KiB
Python
50 lines
2.6 KiB
Python
"""Verify units, PID identity, container/file-cache separation and bounded output."""
|
|
import importlib.util
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
spec = importlib.util.spec_from_file_location('memory_sampler', ROOT / 'tools/sample_server_memory.py')
|
|
sampler = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(sampler)
|
|
|
|
class MemorySamplerTests(unittest.TestCase):
|
|
def test_process_and_container_measurements(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
root = Path(tmp); proc = root / 'proc'; proc.mkdir(); cg = root / 'cgroups'; cg.mkdir()
|
|
(proc / 'meminfo').write_text('MemTotal: 19000000 kB\nMemAvailable: 3000000 kB\nSwapTotal: 0 kB\n')
|
|
pid = proc / '42'; pid.mkdir()
|
|
(pid / 'exe').symlink_to('/game/ArmaReforgerServer')
|
|
(pid / 'status').write_text('Name:\tenfMain\nVmRSS: 7000000 kB\nRssAnon: 6000000 kB\nRssFile: 1000000 kB\n')
|
|
(pid / 'stat').write_text('42 (enf Main) ' + ' '.join(['S'] + ['0']*18 + ['1234']))
|
|
(pid / 'cgroup').write_text('0::/escape\n')
|
|
group = cg / 'escape'; group.mkdir()
|
|
(group / 'memory.current').write_text('9000000000\n')
|
|
(group / 'memory.max').write_text('max\n')
|
|
(group / 'memory.stat').write_text('anon 6000000000\nfile 2500000000\npagetables 123\n')
|
|
(group / 'memory.events').write_text('oom 1\noom_kill 1\n')
|
|
(proc / '99').mkdir() # a process disappears halfway through reading
|
|
result = sampler.snapshot(proc, cg)
|
|
self.assertEqual(result['host_kb']['MemAvailable'], 3000000)
|
|
self.assertEqual(len(result['processes']), 1)
|
|
row = result['processes'][0]
|
|
self.assertEqual((row['pid'], row['start_ticks']), (42, 1234))
|
|
self.assertEqual(row['kb']['VmRSS'], 7000000)
|
|
self.assertEqual(row['memory.max'], 'max')
|
|
self.assertEqual(row['memory.stat'], {'anon': 6000000000, 'file': 2500000000})
|
|
self.assertEqual(row['memory.events']['oom_kill'], 1)
|
|
|
|
def test_rotation_keeps_only_one_previous_file(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
path = Path(tmp) / 'memory.jsonl'
|
|
sampler.append(path, {'sample': 1}, limit=1)
|
|
sampler.append(path, {'sample': 2}, limit=1)
|
|
sampler.append(path, {'sample': 3}, limit=1)
|
|
self.assertIn('3', path.read_text())
|
|
self.assertIn('2', path.with_name('memory.jsonl.1').read_text())
|
|
self.assertEqual(len(list(path.parent.iterdir())), 2)
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|