def test_function_using_tuples(self):
     # tuple records are not compatible with the default OnValue filters.
     recorder = ListRecorder(filter_=lambda x: x[-1] == self.filename)
     monitor = self.monitor_type(recorder, record_type=tuple)
     helper = MonitoringHelper(monitor)
     result = helper.run_on_function()
     self.assertEqual(result, 3)
     template = [
         "3 call gcd 28 {0}",
         "4 return gcd 32 {0}"]
     self.check_records(template, recorder)
예제 #2
0
 def test_function_using_tuples(self):
     # tuple records are not compatible with the default OnValue filters.
     from pikos.cymonitors.function_monitor import FunctionMonitor
     recorder = TextStreamRecorder(
         text_stream=self.stream,
         filter_=lambda x: x[-1] == self.filename)
     monitor = FunctionMonitor(recorder, record_type=tuple)
     helper = MonitoringHelper(monitor)
     result = helper.run_on_function()
     self.assertEqual(result, 3)
     template = [
         "0 call gcd 28 {0}",
         "1 return gcd 32 {0}"]
     self.check_records(template, self.stream)
예제 #3
0
 def test_function_using_tuples(self):
     from pikos.monitors.line_memory_monitor import LineMemoryMonitor
     filename = self.filename
     # tuple records are not compatible with the default OnValue filters.
     recorder = ListRecorder(filter_=lambda x: x[-1] == filename)
     monitor = LineMemoryMonitor(recorder, record_type=tuple)
     helper = MonitoringHelper(monitor)
     result = helper.run_on_function()
     self.assertEqual(result, 3)
     template = [
         "0 gcd 30             while x > 0: {0}",
         "1 gcd 31                 x, y = y % x, x {0}",
         "2 gcd 30             while x > 0: {0}",
         "3 gcd 31                 x, y = y % x, x {0}",
         "4 gcd 30             while x > 0: {0}",
         "5 gcd 32             return y {0}"]
     self.check_records(template, recorder)
예제 #4
0
 def test_function_using_tuples(self):
     filename = self.filename
     # tuple records are not compatible with the default OnValue filters.
     recorder = TextStreamRecorder(
         text_stream=self.stream,
         filter_=lambda x: x[-1] == filename)
     monitor = LineMonitor(recorder, record_type=tuple)
     helper = MonitoringHelper(monitor)
     result = helper.run_on_function()
     self.assertEqual(result, 3)
     template = [
         "0 gcd 30             while x > 0: {0}",
         "1 gcd 31                 x, y = y % x, x {0}",
         "2 gcd 30             while x > 0: {0}",
         "3 gcd 31                 x, y = y % x, x {0}",
         "4 gcd 30             while x > 0: {0}",
         "5 gcd 32             return y {0}"]
     self.check_records(template, self.stream)
예제 #5
0
 def setUp(self):
     self.check_for_psutils()
     from pikos.monitors.line_memory_monitor import LineMemoryMonitor
     self.maxDiff = None
     self.helper = MonitoringHelper()
     self.filename = self.helper.filename
     self.recorder = ListRecorder(
         filter_=OnValue('filename', self.filename))
     self.monitor = LineMemoryMonitor(self.recorder)
     self.helper.monitor = self.monitor
예제 #6
0
 def setUp(self):
     self.maxDiff = None
     self.stream = StringIO.StringIO()
     self.helper = MonitoringHelper()
     self.filename = self.helper.filename
     self.recorder = TextStreamRecorder(
         text_stream=self.stream,
         filter_=OnValue('filename', self.filename))
     self.monitor = LineMonitor(self.recorder)
     self.helper.monitor = self.monitor
예제 #7
0
 def setUp(self):
     self.maxDiff = None
     self.stream = StringIO.StringIO()
     self.helper = MonitoringHelper()
     self.filename = self.helper.filename
     # we only care about the lines that are in this file and we filter
     # the others.
     self.recorder = TextStreamRecorder(
         text_stream=self.stream,
         filter_=OnValue('filename', self.filename))
     self.monitor = FunctionMonitor(self.recorder)
     self.helper.monitor = self.monitor
예제 #8
0
 def setUp(self):
     try:
         from pikos.cymonitors.line_monitor import LineMonitor
     except ImportError:
         self.skipTest('Cython LineMonitor is not available')
     self.maxDiff = None
     self.stream = StringIO.StringIO()
     self.helper = MonitoringHelper()
     self.filename = self.helper.filename
     self.recorder = TextStreamRecorder(
         text_stream=self.stream,
         filter_=OnValue('filename', self.filename))
     self.monitor = LineMonitor(self.recorder)
     self.helper.monitor = self.monitor
예제 #9
0
 def setUp(self):
     self.check_for_psutils()
     try:
         from pikos.cymonitors.line_memory_monitor import (
             LineMemoryMonitor)
     except ImportError:
         self.skipTest('Cython LineMemoryMonitor is not available')
     from pikos.cymonitors.line_memory_monitor import LineMemoryMonitor
     self.maxDiff = None
     self.helper = MonitoringHelper()
     self.filename = self.helper.filename
     self.recorder = ListRecorder(
         filter_=OnValue('filename', self.filename))
     self.monitor = LineMemoryMonitor(self.recorder)
     self.helper.monitor = self.monitor
예제 #10
0
 def setUp(self):
     try:
         from pikos.cymonitors.function_monitor import FunctionMonitor
     except ImportError:
         self.skipTest('Cython FunctionMonitor is not available')
     self.maxDiff = None
     self.stream = StringIO.StringIO()
     self.helper = MonitoringHelper()
     self.filename = self.helper.filename
     # we only care about the lines that are in this file and we filter
     # the others.
     self.recorder = TextStreamRecorder(
         text_stream=self.stream,
         filter_=OnValue('filename', self.filename))
     self.monitor = FunctionMonitor(self.recorder)
     self.helper.monitor = self.monitor
 def setUp(self):
     try:
         from pikos.cymonitors.function_memory_monitor import (
             FunctionMemoryMonitor)
     except ImportError:
         self.skipTest('Cython FunctionMemoryMonitor is not available')
     self.monitor_type = FunctionMemoryMonitor
     self.maxDiff = None
     self.helper = MonitoringHelper()
     self.filename = self.helper.filename
     # we only care about the lines that are in this file and we filter
     # the others.
     self.recorder = ListRecorder(
         filter_=OnValue('filename', self.filename))
     self.monitor = self.monitor_type(self.recorder)
     self.helper.monitor = self.monitor
예제 #12
0
class TestFunctionMonitor(TestCase):

    def setUp(self):
        self.maxDiff = None
        self.stream = StringIO.StringIO()
        self.helper = MonitoringHelper()
        self.filename = self.helper.filename
        # we only care about the lines that are in this file and we filter
        # the others.
        self.recorder = TextStreamRecorder(
            text_stream=self.stream,
            filter_=OnValue('filename', self.filename))
        self.monitor = FunctionMonitor(self.recorder)
        self.helper.monitor = self.monitor

    def test_function(self):
        result = self.helper.run_on_function()
        self.assertEqual(result, 3)
        template = [
            "index type function lineNo filename",
            "-----------------------------------",
            "3 call gcd 28 {0}",
            "4 return gcd 32 {0}"]
        self.check_records(template, self.stream)

    def test_recursive(self):
        result = self.helper.run_on_recursive_function()
        self.assertEqual(result, 1)
        template = [
            "index type function lineNo filename",
            "-----------------------------------",
            "3 call gcd 48 {0}",
            "11 call gcd 48 {0}",
            "19 call gcd 48 {0}",
            "27 call gcd 48 {0}",
            "35 call gcd 48 {0}",
            "43 call gcd 48 {0}",
            "44 return gcd 50 {0}",
            "52 return gcd 50 {0}",
            "60 return gcd 50 {0}",
            "68 return gcd 50 {0}",
            "76 return gcd 50 {0}",
            "84 return gcd 50 {0}"]
        self.check_records(template, self.stream)

    def test_generator(self):
        result = self.helper.run_on_generator()
        output = (0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
        self.assertSequenceEqual(result, output)
        template = [
            "index type function lineNo filename",
            "-----------------------------------",
            "3 call fibonacci 63 {0}",
            "4 c_call range 66 {0}",
            "5 c_return range 66 {0}",
            "6 return fibonacci 67 {0}",
            "19 call fibonacci 67 {0}",
            "20 return fibonacci 67 {0}",
            "34 call fibonacci 67 {0}",
            "35 return fibonacci 67 {0}",
            "49 call fibonacci 67 {0}",
            "50 return fibonacci 67 {0}",
            "64 call fibonacci 67 {0}",
            "65 return fibonacci 67 {0}",
            "79 call fibonacci 67 {0}",
            "80 return fibonacci 67 {0}",
            "94 call fibonacci 67 {0}",
            "95 return fibonacci 67 {0}",
            "109 call fibonacci 67 {0}",
            "110 return fibonacci 67 {0}",
            "124 call fibonacci 67 {0}",
            "125 return fibonacci 67 {0}",
            "139 call fibonacci 67 {0}",
            "140 return fibonacci 67 {0}",
            "154 call fibonacci 67 {0}",
            "155 return fibonacci 68 {0}"]
        self.check_records(template, self.stream)

    def check_records(self, template, stream):
        expected = [line.format(self.filename) for line in template]
        records = ''.join(stream.buflist).splitlines()
        self.assertEqual(records, expected)
class TestFunctionMemoryMonitor(TestCase, TestAssistant):

    def setUp(self):
        self.check_for_psutils()
        from pikos.monitors.function_memory_monitor import (
            FunctionMemoryMonitor)
        self.monitor_type = FunctionMemoryMonitor
        self.maxDiff = None
        self.helper = MonitoringHelper()
        self.filename = self.helper.filename
        self.recorder = ListRecorder(
            filter_=OnValue('filename', self.filename))
        self.monitor = self.monitor_type(self.recorder)
        self.helper.monitor = self.monitor

    def test_function(self):
        result = self.helper.run_on_function()
        self.assertEqual(result, 3)
        template = [
            "3 call gcd 28 {0}",
            "4 return gcd 32 {0}"]
        self.check_records(template, self.recorder)

    def test_recursive(self):
        result = self.helper.run_on_recursive_function()
        self.assertEqual(result, 1)
        template = [
            "3 call gcd 48 {0}",
            "11 call gcd 48 {0}",
            "19 call gcd 48 {0}",
            "27 call gcd 48 {0}",
            "35 call gcd 48 {0}",
            "43 call gcd 48 {0}",
            "44 return gcd 50 {0}",
            "52 return gcd 50 {0}",
            "60 return gcd 50 {0}",
            "68 return gcd 50 {0}",
            "76 return gcd 50 {0}",
            "84 return gcd 50 {0}"]
        self.check_records(template, self.recorder)

    def test_generator(self):
        result = self.helper.run_on_generator()
        output = (0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
        self.assertSequenceEqual(result, output)
        template = [
            "3 call fibonacci 63 {0}",
            "4 c_call range 66 {0}",
            "5 c_return range 66 {0}",
            "6 return fibonacci 67 {0}",
            "19 call fibonacci 67 {0}",
            "20 return fibonacci 67 {0}",
            "34 call fibonacci 67 {0}",
            "35 return fibonacci 67 {0}",
            "49 call fibonacci 67 {0}",
            "50 return fibonacci 67 {0}",
            "64 call fibonacci 67 {0}",
            "65 return fibonacci 67 {0}",
            "79 call fibonacci 67 {0}",
            "80 return fibonacci 67 {0}",
            "94 call fibonacci 67 {0}",
            "95 return fibonacci 67 {0}",
            "109 call fibonacci 67 {0}",
            "110 return fibonacci 67 {0}",
            "124 call fibonacci 67 {0}",
            "125 return fibonacci 67 {0}",
            "139 call fibonacci 67 {0}",
            "140 return fibonacci 67 {0}",
            "154 call fibonacci 67 {0}",
            "155 return fibonacci 68 {0}"]
        self.check_records(template, self.recorder)

    def test_function_using_tuples(self):
        # tuple records are not compatible with the default OnValue filters.
        recorder = ListRecorder(filter_=lambda x: x[-1] == self.filename)
        monitor = self.monitor_type(recorder, record_type=tuple)
        helper = MonitoringHelper(monitor)
        result = helper.run_on_function()
        self.assertEqual(result, 3)
        template = [
            "3 call gcd 28 {0}",
            "4 return gcd 32 {0}"]
        self.check_records(template, recorder)

    def check_for_psutils(self):
        try:
            import psutil  # noqa
        except ImportError:
            self.skipTest('Could not import psutils, skipping test.')

    def check_records(self, template, recorder):
        expected = [line.format(self.filename) for line in template]
        records = self.get_records(recorder)
        self.assertEqual(records, expected)

    def get_records(self, recorder):
        """ Remove the memory related fields.
        """
        records = []
        for record in recorder.records:
            filtered = record[:3] + record[5:]
            records.append(' '.join([str(item) for item in filtered]))
        return records
예제 #14
0
class TestLineMonitor(TestCase):

    def setUp(self):
        self.maxDiff = None
        self.stream = StringIO.StringIO()
        self.helper = MonitoringHelper()
        self.filename = self.helper.filename
        self.recorder = TextStreamRecorder(
            text_stream=self.stream,
            filter_=OnValue('filename', self.filename))
        self.monitor = LineMonitor(self.recorder)
        self.helper.monitor = self.monitor

    def test_function(self):
        result = self.helper.run_on_function()
        self.assertEqual(result, 3)

        template = [
            "index function lineNo line filename",
            "-----------------------------------",
            "0 gcd 30             while x > 0: {0}",
            "1 gcd 31                 x, y = y % x, x {0}",
            "2 gcd 30             while x > 0: {0}",
            "3 gcd 31                 x, y = y % x, x {0}",
            "4 gcd 30             while x > 0: {0}",
            "5 gcd 32             return y {0}"]

        self.check_records(template, self.stream)

    def test_recursive(self):
        result = self.helper.run_on_recursive_function()
        self.assertEqual(result, 1)

        template = [
            "index function lineNo line filename",
            "-----------------------------------",
            "0 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}",
            "8 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}",
            "16 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}",  # noqa
            "24 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}",  # noqa
            "32 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}",  # noqa
            "40 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}"]  # noqa

        self.check_records(template, self.stream)

    def test_generator(self):
        result = self.helper.run_on_generator()
        output = (0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
        self.assertSequenceEqual(result, output)

        template = [
            "index function lineNo line filename",
            "-----------------------------------",
            "0 fibonacci 65             x, y = 0, 1 {0}",
            "1 fibonacci 66             for i in range(items): {0}",
            "2 fibonacci 67                 yield x {0}",
            "11 fibonacci 68                 x, y = y, x + y {0}",
            "12 fibonacci 66             for i in range(items): {0}",
            "13 fibonacci 67                 yield x {0}",
            "22 fibonacci 68                 x, y = y, x + y {0}",
            "23 fibonacci 66             for i in range(items): {0}",
            "24 fibonacci 67                 yield x {0}",
            "33 fibonacci 68                 x, y = y, x + y {0}",
            "34 fibonacci 66             for i in range(items): {0}",
            "35 fibonacci 67                 yield x {0}",
            "44 fibonacci 68                 x, y = y, x + y {0}",
            "45 fibonacci 66             for i in range(items): {0}",
            "46 fibonacci 67                 yield x {0}",
            "55 fibonacci 68                 x, y = y, x + y {0}",
            "56 fibonacci 66             for i in range(items): {0}",
            "57 fibonacci 67                 yield x {0}",
            "66 fibonacci 68                 x, y = y, x + y {0}",
            "67 fibonacci 66             for i in range(items): {0}",
            "68 fibonacci 67                 yield x {0}",
            "77 fibonacci 68                 x, y = y, x + y {0}",
            "78 fibonacci 66             for i in range(items): {0}",
            "79 fibonacci 67                 yield x {0}",
            "88 fibonacci 68                 x, y = y, x + y {0}",
            "89 fibonacci 66             for i in range(items): {0}",
            "90 fibonacci 67                 yield x {0}",
            "99 fibonacci 68                 x, y = y, x + y {0}",
            "100 fibonacci 66             for i in range(items): {0}",
            "101 fibonacci 67                 yield x {0}",
            "110 fibonacci 68                 x, y = y, x + y {0}",
            "111 fibonacci 66             for i in range(items): {0}"]

        self.check_records(template, self.stream)

    def test_function_using_tuples(self):
        filename = self.filename
        # tuple records are not compatible with the default OnValue filters.
        recorder = TextStreamRecorder(
            text_stream=self.stream,
            filter_=lambda x: x[-1] == filename)
        monitor = LineMonitor(recorder, record_type=tuple)
        helper = MonitoringHelper(monitor)
        result = helper.run_on_function()
        self.assertEqual(result, 3)
        template = [
            "0 gcd 30             while x > 0: {0}",
            "1 gcd 31                 x, y = y % x, x {0}",
            "2 gcd 30             while x > 0: {0}",
            "3 gcd 31                 x, y = y % x, x {0}",
            "4 gcd 30             while x > 0: {0}",
            "5 gcd 32             return y {0}"]
        self.check_records(template, self.stream)

    def test_issue2(self):
        """ Test for issue #2.

        The issues is reported in `https://github.com/sjagoe/pikos/issues/2`_

        """
        monitor = self.monitor

        FOO = """
def foo():
    a = []
    for i in range(20):
        a.append(i+sum(a))

foo()
"""

        @monitor.attach
        def boo():
            code = compile(FOO, 'foo', 'exec')
            exec code in globals(), {}

        try:
            boo()
        except TypeError:
            msg = ("Issue #2 -- line monitor fails when exec is used"
                   " on code compiled from a string -- exists.")
            self.fail(msg)

    def check_records(self, template, stream):
        expected = [line.format(self.filename) for line in template]
        records = ''.join(stream.buflist).splitlines()
        self.assertEqual(records, expected)
class TestCFunctionMemoryMonitor(TestCase):
    """ Test for the cython implementation of the FunctionMemoryMonitor.
    """

    def setUp(self):
        try:
            from pikos.cymonitors.function_memory_monitor import (
                FunctionMemoryMonitor)
        except ImportError:
            self.skipTest('Cython FunctionMemoryMonitor is not available')
        self.monitor_type = FunctionMemoryMonitor
        self.maxDiff = None
        self.helper = MonitoringHelper()
        self.filename = self.helper.filename
        # we only care about the lines that are in this file and we filter
        # the others.
        self.recorder = ListRecorder(
            filter_=OnValue('filename', self.filename))
        self.monitor = self.monitor_type(self.recorder)
        self.helper.monitor = self.monitor

    def tearDown(self):
        sys.setprofile(None)

    def test_function(self):
        result = self.helper.run_on_function()
        self.assertEqual(result, 3)
        template = [
            u"0 call gcd 28 {0}",
            u"1 return gcd 32 {0}"]
        self.check_records(template, self.recorder)

    def test_function_using_tuples(self):
        # tuple records are not compatible with the default OnValue filters.
        from pikos.cymonitors.function_memory_monitor import (
            FunctionMemoryMonitor)
        recorder = ListRecorder(filter_=lambda x: x[-1] == self.filename)
        monitor = FunctionMemoryMonitor(recorder, record_type=tuple)
        helper = MonitoringHelper(monitor)
        result = helper.run_on_function()
        self.assertEqual(result, 3)
        template = [
            "0 call gcd 28 {0}",
            "1 return gcd 32 {0}"]
        self.check_records(template, recorder)

    def test_recursive(self):
        result = self.helper.run_on_recursive_function()
        self.assertEqual(result, 1)
        if sys.version_info[:2] == (2, 6):
            # Python 2.6 __enter__ is called through the CALL_FUNCTION
            # bytecode and thus the c __enter__ methods appears in the
            # function events while in 2.7 the behaviour has changed.
            template = [
                u"0 call gcd 48 {0}",
                u"6 call gcd 48 {0}",
                u"12 call gcd 48 {0}",
                u"18 call gcd 48 {0}",
                u"24 call gcd 48 {0}",
                u"30 call gcd 48 {0}",
                u"31 return gcd 50 {0}",
                u"35 return gcd 50 {0}",
                u"39 return gcd 50 {0}",
                u"43 return gcd 50 {0}",
                u"47 return gcd 50 {0}",
                u"51 return gcd 50 {0}"]
        else:
            template = [
                u"0 call gcd 48 {0}",
                u"4 call gcd 48 {0}",
                u"8 call gcd 48 {0}",
                u"12 call gcd 48 {0}",
                u"16 call gcd 48 {0}",
                u"20 call gcd 48 {0}",
                u"21 return gcd 50 {0}",
                u"25 return gcd 50 {0}",
                u"29 return gcd 50 {0}",
                u"33 return gcd 50 {0}",
                u"37 return gcd 50 {0}",
                u"41 return gcd 50 {0}"]
        self.check_records(template, self.recorder)

    def test_generator(self):
        result = self.helper.run_on_generator()
        output = (0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
        self.assertSequenceEqual(result, output)
        template = [
            u"0 call fibonacci 63 {0}",
            u"1 c_call range 66 {0}",
            u"2 c_return range 66 {0}",
            u"3 return fibonacci 67 {0}",
            u"7 call fibonacci 67 {0}",
            u"8 return fibonacci 67 {0}",
            u"13 call fibonacci 67 {0}",
            u"14 return fibonacci 67 {0}",
            u"19 call fibonacci 67 {0}",
            u"20 return fibonacci 67 {0}",
            u"25 call fibonacci 67 {0}",
            u"26 return fibonacci 67 {0}",
            u"31 call fibonacci 67 {0}",
            u"32 return fibonacci 67 {0}",
            u"37 call fibonacci 67 {0}",
            u"38 return fibonacci 67 {0}",
            u"43 call fibonacci 67 {0}",
            u"44 return fibonacci 67 {0}",
            u"49 call fibonacci 67 {0}",
            u"50 return fibonacci 67 {0}",
            u"55 call fibonacci 67 {0}",
            u"56 return fibonacci 67 {0}",
            u"61 call fibonacci 67 {0}",
            u"62 return fibonacci 68 {0}"]
        self.check_records(template, self.recorder)

    def check_for_psutils(self):
        try:
            import psutil  # noqa
        except ImportError:
            self.skipTest('Could not import psutils, skipping test.')

    def check_records(self, template, recorder):
        expected = [line.format(self.filename) for line in template]
        records = self.get_records(recorder)
        self.assertEqual(records, expected)

    def get_records(self, recorder):
        """ Remove the memory related fields.
        """
        records = []
        for record in recorder.records:
            filtered = record[:3] + record[5:]
            records.append(' '.join([str(item) for item in filtered]))
        return records
예제 #16
0
class TestLineMemoryMonitor(TestCase):

    def setUp(self):
        self.check_for_psutils()
        from pikos.monitors.line_memory_monitor import LineMemoryMonitor
        self.maxDiff = None
        self.helper = MonitoringHelper()
        self.filename = self.helper.filename
        self.recorder = ListRecorder(
            filter_=OnValue('filename', self.filename))
        self.monitor = LineMemoryMonitor(self.recorder)
        self.helper.monitor = self.monitor

    def test_function(self):
        result = self.helper.run_on_function()
        self.assertEqual(result, 3)

        template = [
            "0 gcd 30             while x > 0: {0}",
            "1 gcd 31                 x, y = y % x, x {0}",
            "2 gcd 30             while x > 0: {0}",
            "3 gcd 31                 x, y = y % x, x {0}",
            "4 gcd 30             while x > 0: {0}",
            "5 gcd 32             return y {0}"]
        self.check_records(template, self.recorder)

    def test_recursive(self):
        result = self.helper.run_on_recursive_function()
        self.assertEqual(result, 1)

        template = [
            "0 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}",  # noqa
            "8 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}",  # noqa
            "16 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}",  # noqa
            "24 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}",  # noqa
            "32 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}",  # noqa
            "40 gcd 50             return x if y == 0 else gcd(y, (x % y)) {0}"]  # noqa
        self.check_records(template, self.recorder)

    def test_generator(self):
        result = self.helper.run_on_generator()
        output = (0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
        self.assertSequenceEqual(result, output)

        template = [
            "0 fibonacci 65             x, y = 0, 1 {0}",
            "1 fibonacci 66             for i in range(items): {0}",  # noqa
            "2 fibonacci 67                 yield x {0}",
            "11 fibonacci 68                 x, y = y, x + y {0}",  # noqa
            "12 fibonacci 66             for i in range(items): {0}",  # noqa
            "13 fibonacci 67                 yield x {0}",
            "22 fibonacci 68                 x, y = y, x + y {0}",  # noqa
            "23 fibonacci 66             for i in range(items): {0}",  # noqa
            "24 fibonacci 67                 yield x {0}",
            "33 fibonacci 68                 x, y = y, x + y {0}",  # noqa
            "34 fibonacci 66             for i in range(items): {0}",  # noqa
            "35 fibonacci 67                 yield x {0}",
            "44 fibonacci 68                 x, y = y, x + y {0}",  # noqa
            "45 fibonacci 66             for i in range(items): {0}",  # noqa
            "46 fibonacci 67                 yield x {0}",
            "55 fibonacci 68                 x, y = y, x + y {0}",  # noqa
            "56 fibonacci 66             for i in range(items): {0}",  # noqa
            "57 fibonacci 67                 yield x {0}",
            "66 fibonacci 68                 x, y = y, x + y {0}",  # noqa
            "67 fibonacci 66             for i in range(items): {0}",  # noqa
            "68 fibonacci 67                 yield x {0}",
            "77 fibonacci 68                 x, y = y, x + y {0}",  # noqa
            "78 fibonacci 66             for i in range(items): {0}",  # noqa
            "79 fibonacci 67                 yield x {0}",
            "88 fibonacci 68                 x, y = y, x + y {0}",  # noqa
            "89 fibonacci 66             for i in range(items): {0}",  # noqa
            "90 fibonacci 67                 yield x {0}",
            "99 fibonacci 68                 x, y = y, x + y {0}",  # noqa
            "100 fibonacci 66             for i in range(items): {0}",  # noqa
            "101 fibonacci 67                 yield x {0}",
            "110 fibonacci 68                 x, y = y, x + y {0}",  # noqa
            "111 fibonacci 66             for i in range(items): {0}"]  # noqa

        self.check_records(template, self.recorder)

    def test_function_using_tuples(self):
        from pikos.monitors.line_memory_monitor import LineMemoryMonitor
        filename = self.filename
        # tuple records are not compatible with the default OnValue filters.
        recorder = ListRecorder(filter_=lambda x: x[-1] == filename)
        monitor = LineMemoryMonitor(recorder, record_type=tuple)
        helper = MonitoringHelper(monitor)
        result = helper.run_on_function()
        self.assertEqual(result, 3)
        template = [
            "0 gcd 30             while x > 0: {0}",
            "1 gcd 31                 x, y = y % x, x {0}",
            "2 gcd 30             while x > 0: {0}",
            "3 gcd 31                 x, y = y % x, x {0}",
            "4 gcd 30             while x > 0: {0}",
            "5 gcd 32             return y {0}"]
        self.check_records(template, recorder)

    def test_issue2(self):
        """ Test for issue #2.

        """
        monitor = self.monitor

        FOO = """
def foo():
    a = []
    for i in range(20):
        a.append(i+sum(a))

foo()
"""

        @monitor.attach
        def boo():
            code = compile(FOO, 'foo', 'exec')
            exec code in globals(), {}

        try:
            boo()
        except TypeError:
            msg = ("Issue #2 -- line monitor fails when exec is used"
                   " on code compiled from a string -- exists.")
            self.fail(msg)

    def get_records(self, recorder):
        """ Remove the memory related fields.
        """
        records = []
        for record in recorder.records:
            filtered = record[:3] + record[5:]
            records.append(' '.join([str(item) for item in filtered]))
        return records

    def check_for_psutils(self):
        try:
            import psutil  # noqa
        except ImportError:
            self.skipTest('Could not import psutils, skipping test.')

    def check_records(self, template, recorder):
        expected = [line.format(self.filename) for line in template]
        records = self.get_records(recorder)
        self.assertEqual(records, expected)
예제 #17
0
class TestCFunctionMonitor(TestCase):
    """ Test for the cython implementation of the FunctionMonitor
    """

    def setUp(self):
        try:
            from pikos.cymonitors.function_monitor import FunctionMonitor
        except ImportError:
            self.skipTest('Cython FunctionMonitor is not available')
        self.maxDiff = None
        self.stream = StringIO.StringIO()
        self.helper = MonitoringHelper()
        self.filename = self.helper.filename
        # we only care about the lines that are in this file and we filter
        # the others.
        self.recorder = TextStreamRecorder(
            text_stream=self.stream,
            filter_=OnValue('filename', self.filename))
        self.monitor = FunctionMonitor(self.recorder)
        self.helper.monitor = self.monitor

    def tearDown(self):
        sys.setprofile(None)

    def test_function(self):
        result = self.helper.run_on_function()
        self.assertEqual(result, 3)
        template = [
            u"index type function lineNo filename",
            u"-----------------------------------",
            u"0 call gcd 28 {0}",
            u"1 return gcd 32 {0}"]
        self.check_records(template, self.stream)

    def test_function_using_tuples(self):
        # tuple records are not compatible with the default OnValue filters.
        from pikos.cymonitors.function_monitor import FunctionMonitor
        recorder = TextStreamRecorder(
            text_stream=self.stream,
            filter_=lambda x: x[-1] == self.filename)
        monitor = FunctionMonitor(recorder, record_type=tuple)
        helper = MonitoringHelper(monitor)
        result = helper.run_on_function()
        self.assertEqual(result, 3)
        template = [
            "0 call gcd 28 {0}",
            "1 return gcd 32 {0}"]
        self.check_records(template, self.stream)

    def test_recursive(self):
        result = self.helper.run_on_recursive_function()
        self.assertEqual(result, 1)
        if sys.version_info[:2] == (2, 6):
            # Python 2.6 __enter__ is called through the CALL_FUNCTION
            # bytecode and thus the c __enter__ methods appears in the
            # function events while in 2.7 the behaviour has changed.
            template = [
                u"index type function lineNo filename",
                u"-----------------------------------",
                u"0 call gcd 48 {0}",
                u"6 call gcd 48 {0}",
                u"12 call gcd 48 {0}",
                u"18 call gcd 48 {0}",
                u"24 call gcd 48 {0}",
                u"30 call gcd 48 {0}",
                u"31 return gcd 50 {0}",
                u"35 return gcd 50 {0}",
                u"39 return gcd 50 {0}",
                u"43 return gcd 50 {0}",
                u"47 return gcd 50 {0}",
                u"51 return gcd 50 {0}"]
        else:
            template = [
                u"index type function lineNo filename",
                u"-----------------------------------",
                u"0 call gcd 48 {0}",
                u"4 call gcd 48 {0}",
                u"8 call gcd 48 {0}",
                u"12 call gcd 48 {0}",
                u"16 call gcd 48 {0}",
                u"20 call gcd 48 {0}",
                u"21 return gcd 50 {0}",
                u"25 return gcd 50 {0}",
                u"29 return gcd 50 {0}",
                u"33 return gcd 50 {0}",
                u"37 return gcd 50 {0}",
                u"41 return gcd 50 {0}"]
        self.check_records(template, self.stream)

    def test_generator(self):
        result = self.helper.run_on_generator()
        output = (0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
        self.assertSequenceEqual(result, output)
        template = [
            u"index type function lineNo filename",
            u"-----------------------------------",
            u"0 call fibonacci 63 {0}",
            u"1 c_call range 66 {0}",
            u"2 c_return range 66 {0}",
            u"3 return fibonacci 67 {0}",
            u"7 call fibonacci 67 {0}",
            u"8 return fibonacci 67 {0}",
            u"13 call fibonacci 67 {0}",
            u"14 return fibonacci 67 {0}",
            u"19 call fibonacci 67 {0}",
            u"20 return fibonacci 67 {0}",
            u"25 call fibonacci 67 {0}",
            u"26 return fibonacci 67 {0}",
            u"31 call fibonacci 67 {0}",
            u"32 return fibonacci 67 {0}",
            u"37 call fibonacci 67 {0}",
            u"38 return fibonacci 67 {0}",
            u"43 call fibonacci 67 {0}",
            u"44 return fibonacci 67 {0}",
            u"49 call fibonacci 67 {0}",
            u"50 return fibonacci 67 {0}",
            u"55 call fibonacci 67 {0}",
            u"56 return fibonacci 67 {0}",
            u"61 call fibonacci 67 {0}",
            u"62 return fibonacci 68 {0}"]
        self.check_records(template, self.stream)

    def check_records(self, template, stream):
        expected = [line.format(self.filename) for line in template]
        records = ''.join(stream.buflist).splitlines()
        self.assertEqual(records, expected)