Esempio n. 1
0
    def test_memory_limit(self):
        """Verify that set_memory_limit works."""

        # memory limit to test, keep small to avoid test slowdown
        mem_cap = 100 * 1024 * 1024
        # memory tolerance: allowed discrepancy between set limit and
        # measured process resources. Note, that we have a static
        # overhead in waste.py for the forking of ps, so while 20M seems
        # large compared to a 100M limit, in a real world example with
        # 8G limit it's fairly small.
        mem_tol = 20 * 1024 * 1024

        waste_mem_py = """
import os
import resource
import subprocess

import pkg.misc as misc

misc.set_memory_limit({0})
i = 0
x = {{}}
try:
        while True:
                i += 1
                x[i] = range(i)
except MemoryError:
        # give us some breathing room (enough so the test with env var works)
        misc.set_memory_limit({0} * 3, allow_override=False)
        print subprocess.check_output(['ps', '-o', 'rss=', '-p',
            str(os.getpid())]).strip()
""".format(str(mem_cap))

        # Re-setting limits which are higher than original limit can
        # only be done by root.
        self.assertTrue(os.geteuid() == 0, "must be root to run this test")

        tmpdir = tempfile.mkdtemp(dir=self.test_root)
        tmpfile = os.path.join(tmpdir, 'waste.py')
        with open(tmpfile, 'w') as f:
            f.write(waste_mem_py)

        res = int(subprocess.check_output(['python2.7', tmpfile]))
        # convert from kB to bytes
        res *= 1024

        self.debug("mem_cap:   " + str(mem_cap))
        self.debug("proc size: " + str(res))

        self.assertTrue(res < mem_cap + mem_tol,
                        "process mem consumption too high")
        self.assertTrue(res > mem_cap - mem_tol,
                        "process mem consumption too low")

        # test if env var works
        os.environ["PKG_CLIENT_MAX_PROCESS_SIZE"] = str(mem_cap * 2)
        res = int(subprocess.check_output(['python2.7', tmpfile]))
        res *= 1024

        self.debug("mem_cap:   " + str(mem_cap))
        self.debug("proc size: " + str(res))

        self.assertTrue(res < mem_cap * 2 + mem_tol,
                        "process mem consumption too high")
        self.assertTrue(res > mem_cap * 2 - mem_tol,
                        "process mem consumption too low")

        # test if invalid env var is handled correctly
        os.environ["PKG_CLIENT_MAX_PROCESS_SIZE"] = "octopus"
        res = int(subprocess.check_output(['python2.7', tmpfile]))
        res *= 1024

        self.debug("mem_cap:   " + str(mem_cap))
        self.debug("proc size: " + str(res))

        self.assertTrue(res < mem_cap + mem_tol,
                        "process mem consumption too high")
        self.assertTrue(res > mem_cap - mem_tol,
                        "process mem consumption too low")
Esempio n. 2
0
    def test_memory_limit(self):
        """Verify that set_memory_limit works."""

        # memory limit to test, keep small to avoid test slowdown
        mem_cap = 100 * 1024 * 1024
        # memory tolerance: allowed discrepancy between set limit and
        # measured process resources. This is specified as a percentage
        # of the cap. This may seem high but in an environment with
        # several GiB available, a few hundred megabytes is sufficient
        # to prove that the memory cap works.
        mem_tol = 185

        waste_mem_py = """
import os
import resource
import subprocess

import pkg.misc as misc

misc.set_memory_limit({0})
i = 0
x = {{}}
try:
        while True:
                i += 1
                x[i] = range(i)
except MemoryError:
        # give us some breathing room (enough so the test with env var works)
        misc.set_memory_limit({0} * 3, allow_override=False)
        print(subprocess.check_output(['ps', '-o', 'rss=', '-p',
            str(os.getpid())], universal_newlines=True).strip())
""".format(str(mem_cap))

        # Re-setting limits which are higher than original limit can
        # only be done by root.
        self.assertTrue(os.geteuid() == 0, "must be root to run this test")

        tmpdir = tempfile.mkdtemp(dir=self.test_root)
        tmpfile = os.path.join(tmpdir, 'waste.py')
        with open(tmpfile, 'w') as f:
            f.write(waste_mem_py)

        res = int(subprocess.check_output(['python3.9', tmpfile]))
        # convert from kB to bytes
        res *= 1024

        self.debug("mem_cap:   " + str(mem_cap))
        self.debug("proc size: " + str(res))

        self.assertTrue(res < mem_cap * (100 + mem_tol) / 100,
                        "process mem consumption too high")
        self.assertTrue(res > mem_cap * mem_tol / 100,
                        "process mem consumption too low")

        # test if env var works
        os.environ["PKG_CLIENT_MAX_PROCESS_SIZE"] = str(mem_cap * 2)
        res = int(subprocess.check_output(['python3.9', tmpfile]))
        res *= 1024

        self.debug("mem_cap:   " + str(mem_cap * 2))
        self.debug("proc size: " + str(res))

        mem_tol += 200

        self.assertTrue(res < mem_cap * 2 * (100 + mem_tol) / 100,
                        "process mem consumption too high")
        #self.assertTrue(res > mem_cap * 2 * mem_tol / 100,
        #    "process mem consumption too low")

        mem_tol -= 200

        # test if invalid env var is handled correctly
        os.environ["PKG_CLIENT_MAX_PROCESS_SIZE"] = "octopus"
        res = int(subprocess.check_output(['python3.9', tmpfile]))
        res *= 1024

        self.debug("mem_cap:   " + str(mem_cap))
        self.debug("proc size: " + str(res))

        self.assertTrue(res < mem_cap * (100 + mem_tol) / 100,
                        "process mem consumption too high")
        self.assertTrue(res > mem_cap * mem_tol / 100,
                        "process mem consumption too low")