def test_add_exception_appending_exceptions():
    segment = Segment('seg')
    stack = [['path', 'line', 'label']]
    segment.add_exception(exception=Exception("testException"), stack=stack)
    segment.add_exception(exception=Exception("newException"), stack=stack)
    segment.close()

    assert isinstance(segment.cause, dict)
    assert len(segment.cause['exceptions']) == 2
def test_add_exception_cause_resetting():
    segment = Segment('seg')
    subseg = Subsegment('subseg', 'remote', segment)
    exception = Exception("testException")
    stack = [['path', 'line', 'label']]
    subseg.add_exception(exception=exception, stack=stack)
    segment.add_exception(exception=exception, stack=stack)

    segment.add_exception(exception=Exception("newException"), stack=stack)
    subseg.close()
    segment.close()

    seg_cause = segment.cause
    assert isinstance(seg_cause, dict)
    assert 'newException' == seg_cause['exceptions'][0].message
def test_add_exception():
    segment = Segment('seg')
    exception = Exception("testException")
    stack = [['path', 'line', 'label']]
    segment.add_exception(exception=exception, stack=stack)
    segment.close()

    cause = segment.cause
    assert 'exceptions' in cause
    exceptions = cause['exceptions']
    assert len(exceptions) == 1
    assert 'working_directory' in cause
    exception = exceptions[0]
    assert 'testException' == exception.message
    expected_stack = [{'path': 'path', 'line': 'line', 'label': 'label'}]
    assert expected_stack == exception.stack
def test_add_exception_referencing():
    segment = Segment('seg')
    subseg = Subsegment('subseg', 'remote', segment)
    exception = Exception("testException")
    stack = [['path', 'line', 'label']]
    subseg.add_exception(exception=exception, stack=stack)
    segment.add_exception(exception=exception, stack=stack)
    subseg.close()
    segment.close()

    seg_cause = segment.cause
    subseg_cause = subseg.cause

    assert isinstance(subseg_cause, dict)
    if sys.version_info.major == 2:
        assert isinstance(seg_cause, basestring)
    else:
        assert isinstance(seg_cause, str)
    assert seg_cause == subseg_cause['exceptions'][0].id
def test_serialize_segment_with_exception():

    class TestException(Exception):
        def __init__(self, message):
            super(TestException, self).__init__(message)

    segment_one = Segment('test')
    
    stack_one = [
        ('/path/to/test.py', 10, 'module', 'another_function()'),
        ('/path/to/test.py', 3, 'another_function', 'wrong syntax')
    ]
    
    stack_two = [
        ('/path/to/test.py', 11, 'module', 'another_function()'),
        ('/path/to/test.py', 4, 'another_function', 'wrong syntax')
    ]

    exception_one = TestException('test message one')
    exception_two = TestException('test message two')

    segment_one.add_exception(exception_one, stack_one, True)
    segment_one.add_exception(exception_two, stack_two, False)
    
    segment_one.close()
    
    expected_segment_one_dict = {
    "id": segment_one.id,
    "name": "test",
    "start_time": segment_one.start_time,
    "in_progress": False,
    "cause": {
        "working_directory": segment_one.cause['working_directory'],
        "exceptions": [
            {
                "id": exception_one._cause_id,
                "message": "test message one",
                "type": "TestException",
                "remote": True,
                "stack": [
                    {
                        "path": "test.py",
                        "line": 10,
                        "label": "module"
                    },
                    {
                        "path": "test.py",
                        "line": 3,
                        "label": "another_function"
                    }
                ]
            },
            {
                "id": exception_two._cause_id,
                "message": "test message two",
                "type": "TestException",
                "remote": False,
                "stack": [
                    {
                        "path": "test.py",
                        "line": 11,
                        "label": "module"
                    },
                    {
                        "path": "test.py",
                        "line": 4,
                        "label": "another_function"
                    }
                ]
            }
        ]
    },
    "trace_id": segment_one.trace_id,
    "fault": True,
    "end_time": segment_one.end_time
    }

    segment_two = Segment('test')
    subsegment = Subsegment('test', 'local', segment_two)

    subsegment.add_exception(exception_one, stack_one, True)
    subsegment.add_exception(exception_two, stack_two, False)
    subsegment.close()
    
    # will record cause id instead as same exception already recorded in its subsegment
    segment_two.add_exception(exception_one, stack_one, True)
    
    segment_two.close()
    
    expected_segment_two_dict = {
    "id": segment_two.id,
    "name": "test",
    "start_time": segment_two.start_time,
    "in_progress": False,
    "cause": exception_one._cause_id,
    "trace_id": segment_two.trace_id,
    "fault": True,
    "end_time": segment_two.end_time
    }

    actual_segment_one_dict = entity_to_dict(segment_one)
    actual_segment_two_dict = entity_to_dict(segment_two)
    
    assert expected_segment_one_dict == actual_segment_one_dict
    assert expected_segment_two_dict == actual_segment_two_dict