selftests/unit/utils/stacktrace.py
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See LICENSE for more details.
#
# Copyright: 2016 Red Hat, Inc.
# Author: Lukas Doktor <ldoktor@redhat.com>
"""
avocado.utils.stacktrace unittests
"""
import pickle
import re
import unittest
from avocado.utils import stacktrace
class Unpickable:
"""
Dummy class which does not support pickling
"""
def __getstate__(self):
raise pickle.PickleError
class InClassUnpickable:
"""
Dummy class containing unpickable object inside itself
"""
def __init__(self):
self.troublemaker = Unpickable()
class ListWithUnpickableAttribute(list):
"""
Dummy list class containing also unpickable attribute
"""
def __init__(self, *args, **kwargs):
self.__troublemaker = Unpickable() # pylint: disable=W0238
super().__init__(*args, **kwargs)
class TestUnpickableObject(unittest.TestCase):
"""
Basic selftests for `avocado.utils.stacktrace.str_unpickable_object
"""
def test_raises(self):
self.assertRaises(
ValueError, stacktrace.str_unpickable_object, ([{"foo": set([])}])
)
def test_basic(self):
"""Basic usage"""
def check(exps, obj):
"""Search exps in the output of str_unpickable_object(obj)"""
act = stacktrace.str_unpickable_object(obj)
for exp in exps:
if not re.search(exp, act):
self.fail(f"{exp!r} no match in:\n{act}")
check(["this => .*Unpickable"], Unpickable())
check(
[r"this\[0\]\[0\]\[foo\]\.troublemaker => .*Unpickable"],
[[{"foo": InClassUnpickable()}]],
)
check(
[r"this\[foo\] => \[1, 2, 3\]"],
{"foo": ListWithUnpickableAttribute([1, 2, 3])},
)
check(
[r"this\[foo\]\[3\] => .*Unpickable"],
{"foo": ListWithUnpickableAttribute([1, 2, 3, Unpickable()])},
)
check(
[
r"this\[2\] => .*Unpickable",
r"this\[3\]\[foo\].troublemaker => .*Unpickable",
r"this\[4\]\[0\].troublemaker => .*Unpickable",
],
[
1,
2,
Unpickable(),
{"foo": InClassUnpickable(), "bar": None},
ListWithUnpickableAttribute(
ListWithUnpickableAttribute([InClassUnpickable()])
),
],
)
if __name__ == "__main__":
unittest.main()