s3:lib/events: make use of tevent_common_loop_timer_delay()
[Samba/gebeck_regimport.git] / lib / testtools / testtools / testcase.py
blobfc5f863bcfceeff2ae0b2f07d1f950bacde9a43f
1 # Copyright (c) 2008-2011 testtools developers. See LICENSE for details.
3 """Test case related stuff."""
5 __metaclass__ = type
6 __all__ = [
7 'clone_test_with_new_id',
8 'ExpectedException',
9 'gather_details',
10 'run_test_with',
11 'skip',
12 'skipIf',
13 'skipUnless',
14 'TestCase',
17 import copy
18 import itertools
19 import sys
20 import types
21 import unittest
23 from testtools import (
24 content,
25 try_import,
27 from testtools.compat import (
28 advance_iterator,
29 reraise,
31 from testtools.matchers import (
32 Annotate,
33 Contains,
34 Equals,
35 MatchesAll,
36 MatchesException,
37 MismatchError,
38 Is,
39 IsInstance,
40 Not,
41 Raises,
43 from testtools.monkey import patch
44 from testtools.runtest import RunTest
45 from testtools.testresult import (
46 ExtendedToOriginalDecorator,
47 TestResult,
50 wraps = try_import('functools.wraps')
52 class TestSkipped(Exception):
53 """Raised within TestCase.run() when a test is skipped."""
54 testSkipped = try_import('unittest2.case.SkipTest', TestSkipped)
55 TestSkipped = try_import('unittest.case.SkipTest', TestSkipped)
58 class _UnexpectedSuccess(Exception):
59 """An unexpected success was raised.
61 Note that this exception is private plumbing in testtools' testcase
62 module.
63 """
64 _UnexpectedSuccess = try_import(
65 'unittest2.case._UnexpectedSuccess', _UnexpectedSuccess)
66 _UnexpectedSuccess = try_import(
67 'unittest.case._UnexpectedSuccess', _UnexpectedSuccess)
69 class _ExpectedFailure(Exception):
70 """An expected failure occured.
72 Note that this exception is private plumbing in testtools' testcase
73 module.
74 """
75 _ExpectedFailure = try_import(
76 'unittest2.case._ExpectedFailure', _ExpectedFailure)
77 _ExpectedFailure = try_import(
78 'unittest.case._ExpectedFailure', _ExpectedFailure)
81 def run_test_with(test_runner, **kwargs):
82 """Decorate a test as using a specific ``RunTest``.
84 e.g.::
86 @run_test_with(CustomRunner, timeout=42)
87 def test_foo(self):
88 self.assertTrue(True)
90 The returned decorator works by setting an attribute on the decorated
91 function. `TestCase.__init__` looks for this attribute when deciding on a
92 ``RunTest`` factory. If you wish to use multiple decorators on a test
93 method, then you must either make this one the top-most decorator, or you
94 must write your decorators so that they update the wrapping function with
95 the attributes of the wrapped function. The latter is recommended style
96 anyway. ``functools.wraps``, ``functools.wrapper`` and
97 ``twisted.python.util.mergeFunctionMetadata`` can help you do this.
99 :param test_runner: A ``RunTest`` factory that takes a test case and an
100 optional list of exception handlers. See ``RunTest``.
101 :param kwargs: Keyword arguments to pass on as extra arguments to
102 'test_runner'.
103 :return: A decorator to be used for marking a test as needing a special
104 runner.
106 def decorator(function):
107 # Set an attribute on 'function' which will inform TestCase how to
108 # make the runner.
109 function._run_test_with = (
110 lambda case, handlers=None:
111 test_runner(case, handlers=handlers, **kwargs))
112 return function
113 return decorator
116 def _copy_content(content_object):
117 """Make a copy of the given content object.
119 The content within ``content_object`` is iterated and saved. This is
120 useful when the source of the content is volatile, a log file in a
121 temporary directory for example.
123 :param content_object: A `content.Content` instance.
124 :return: A `content.Content` instance with the same mime-type as
125 ``content_object`` and a non-volatile copy of its content.
127 content_bytes = list(content_object.iter_bytes())
128 content_callback = lambda: content_bytes
129 return content.Content(content_object.content_type, content_callback)
132 def gather_details(source_dict, target_dict):
133 """Merge the details from ``source_dict`` into ``target_dict``.
135 :param source_dict: A dictionary of details will be gathered.
136 :param target_dict: A dictionary into which details will be gathered.
138 for name, content_object in source_dict.items():
139 new_name = name
140 disambiguator = itertools.count(1)
141 while new_name in target_dict:
142 new_name = '%s-%d' % (name, advance_iterator(disambiguator))
143 name = new_name
144 target_dict[name] = _copy_content(content_object)
147 class TestCase(unittest.TestCase):
148 """Extensions to the basic TestCase.
150 :ivar exception_handlers: Exceptions to catch from setUp, runTest and
151 tearDown. This list is able to be modified at any time and consists of
152 (exception_class, handler(case, result, exception_value)) pairs.
153 :cvar run_tests_with: A factory to make the ``RunTest`` to run tests with.
154 Defaults to ``RunTest``. The factory is expected to take a test case
155 and an optional list of exception handlers.
158 skipException = TestSkipped
160 run_tests_with = RunTest
162 def __init__(self, *args, **kwargs):
163 """Construct a TestCase.
165 :param testMethod: The name of the method to run.
166 :keyword runTest: Optional class to use to execute the test. If not
167 supplied ``RunTest`` is used. The instance to be used is created
168 when run() is invoked, so will be fresh each time. Overrides
169 ``TestCase.run_tests_with`` if given.
171 runTest = kwargs.pop('runTest', None)
172 super(TestCase, self).__init__(*args, **kwargs)
173 self._cleanups = []
174 self._unique_id_gen = itertools.count(1)
175 # Generators to ensure unique traceback ids. Maps traceback label to
176 # iterators.
177 self._traceback_id_gens = {}
178 self.__setup_called = False
179 self.__teardown_called = False
180 # __details is lazy-initialized so that a constructed-but-not-run
181 # TestCase is safe to use with clone_test_with_new_id.
182 self.__details = None
183 test_method = self._get_test_method()
184 if runTest is None:
185 runTest = getattr(
186 test_method, '_run_test_with', self.run_tests_with)
187 self.__RunTest = runTest
188 self.__exception_handlers = []
189 self.exception_handlers = [
190 (self.skipException, self._report_skip),
191 (self.failureException, self._report_failure),
192 (_ExpectedFailure, self._report_expected_failure),
193 (_UnexpectedSuccess, self._report_unexpected_success),
194 (Exception, self._report_error),
196 if sys.version_info < (2, 6):
197 # Catch old-style string exceptions with None as the instance
198 self.exception_handlers.append((type(None), self._report_error))
200 def __eq__(self, other):
201 eq = getattr(unittest.TestCase, '__eq__', None)
202 if eq is not None and not unittest.TestCase.__eq__(self, other):
203 return False
204 return self.__dict__ == other.__dict__
206 def __repr__(self):
207 # We add id to the repr because it makes testing testtools easier.
208 return "<%s id=0x%0x>" % (self.id(), id(self))
210 def addDetail(self, name, content_object):
211 """Add a detail to be reported with this test's outcome.
213 For more details see pydoc testtools.TestResult.
215 :param name: The name to give this detail.
216 :param content_object: The content object for this detail. See
217 testtools.content for more detail.
219 if self.__details is None:
220 self.__details = {}
221 self.__details[name] = content_object
223 def getDetails(self):
224 """Get the details dict that will be reported with this test's outcome.
226 For more details see pydoc testtools.TestResult.
228 if self.__details is None:
229 self.__details = {}
230 return self.__details
232 def patch(self, obj, attribute, value):
233 """Monkey-patch 'obj.attribute' to 'value' while the test is running.
235 If 'obj' has no attribute, then the monkey-patch will still go ahead,
236 and the attribute will be deleted instead of restored to its original
237 value.
239 :param obj: The object to patch. Can be anything.
240 :param attribute: The attribute on 'obj' to patch.
241 :param value: The value to set 'obj.attribute' to.
243 self.addCleanup(patch(obj, attribute, value))
245 def shortDescription(self):
246 return self.id()
248 def skipTest(self, reason):
249 """Cause this test to be skipped.
251 This raises self.skipException(reason). skipException is raised
252 to permit a skip to be triggered at any point (during setUp or the
253 testMethod itself). The run() method catches skipException and
254 translates that into a call to the result objects addSkip method.
256 :param reason: The reason why the test is being skipped. This must
257 support being cast into a unicode string for reporting.
259 raise self.skipException(reason)
261 # skipTest is how python2.7 spells this. Sometime in the future
262 # This should be given a deprecation decorator - RBC 20100611.
263 skip = skipTest
265 def _formatTypes(self, classOrIterable):
266 """Format a class or a bunch of classes for display in an error."""
267 className = getattr(classOrIterable, '__name__', None)
268 if className is None:
269 className = ', '.join(klass.__name__ for klass in classOrIterable)
270 return className
272 def addCleanup(self, function, *arguments, **keywordArguments):
273 """Add a cleanup function to be called after tearDown.
275 Functions added with addCleanup will be called in reverse order of
276 adding after tearDown, or after setUp if setUp raises an exception.
278 If a function added with addCleanup raises an exception, the error
279 will be recorded as a test error, and the next cleanup will then be
280 run.
282 Cleanup functions are always called before a test finishes running,
283 even if setUp is aborted by an exception.
285 self._cleanups.append((function, arguments, keywordArguments))
287 def addOnException(self, handler):
288 """Add a handler to be called when an exception occurs in test code.
290 This handler cannot affect what result methods are called, and is
291 called before any outcome is called on the result object. An example
292 use for it is to add some diagnostic state to the test details dict
293 which is expensive to calculate and not interesting for reporting in
294 the success case.
296 Handlers are called before the outcome (such as addFailure) that
297 the exception has caused.
299 Handlers are called in first-added, first-called order, and if they
300 raise an exception, that will propogate out of the test running
301 machinery, halting test processing. As a result, do not call code that
302 may unreasonably fail.
304 self.__exception_handlers.append(handler)
306 def _add_reason(self, reason):
307 self.addDetail('reason', content.text_content(reason))
309 def assertEqual(self, expected, observed, message=''):
310 """Assert that 'expected' is equal to 'observed'.
312 :param expected: The expected value.
313 :param observed: The observed value.
314 :param message: An optional message to include in the error.
316 matcher = Equals(expected)
317 self.assertThat(observed, matcher, message)
319 failUnlessEqual = assertEquals = assertEqual
321 def assertIn(self, needle, haystack):
322 """Assert that needle is in haystack."""
323 self.assertThat(haystack, Contains(needle))
325 def assertIsNone(self, observed, message=''):
326 """Assert that 'observed' is equal to None.
328 :param observed: The observed value.
329 :param message: An optional message describing the error.
331 matcher = Is(None)
332 self.assertThat(observed, matcher, message)
334 def assertIsNotNone(self, observed, message=''):
335 """Assert that 'observed' is not equal to None.
337 :param observed: The observed value.
338 :param message: An optional message describing the error.
340 matcher = Not(Is(None))
341 self.assertThat(observed, matcher, message)
343 def assertIs(self, expected, observed, message=''):
344 """Assert that 'expected' is 'observed'.
346 :param expected: The expected value.
347 :param observed: The observed value.
348 :param message: An optional message describing the error.
350 matcher = Is(expected)
351 self.assertThat(observed, matcher, message)
353 def assertIsNot(self, expected, observed, message=''):
354 """Assert that 'expected' is not 'observed'."""
355 matcher = Not(Is(expected))
356 self.assertThat(observed, matcher, message)
358 def assertNotIn(self, needle, haystack):
359 """Assert that needle is not in haystack."""
360 matcher = Not(Contains(needle))
361 self.assertThat(haystack, matcher)
363 def assertIsInstance(self, obj, klass, msg=None):
364 if isinstance(klass, tuple):
365 matcher = IsInstance(*klass)
366 else:
367 matcher = IsInstance(klass)
368 self.assertThat(obj, matcher, msg)
370 def assertRaises(self, excClass, callableObj, *args, **kwargs):
371 """Fail unless an exception of class excClass is thrown
372 by callableObj when invoked with arguments args and keyword
373 arguments kwargs. If a different type of exception is
374 thrown, it will not be caught, and the test case will be
375 deemed to have suffered an error, exactly as for an
376 unexpected exception.
378 class ReRaiseOtherTypes(object):
379 def match(self, matchee):
380 if not issubclass(matchee[0], excClass):
381 reraise(*matchee)
382 class CaptureMatchee(object):
383 def match(self, matchee):
384 self.matchee = matchee[1]
385 capture = CaptureMatchee()
386 matcher = Raises(MatchesAll(ReRaiseOtherTypes(),
387 MatchesException(excClass), capture))
388 our_callable = Nullary(callableObj, *args, **kwargs)
389 self.assertThat(our_callable, matcher)
390 return capture.matchee
391 failUnlessRaises = assertRaises
393 def assertThat(self, matchee, matcher, message='', verbose=False):
394 """Assert that matchee is matched by matcher.
396 :param matchee: An object to match with matcher.
397 :param matcher: An object meeting the testtools.Matcher protocol.
398 :raises MismatchError: When matcher does not match thing.
400 matcher = Annotate.if_message(message, matcher)
401 mismatch = matcher.match(matchee)
402 if not mismatch:
403 return
404 existing_details = self.getDetails()
405 for (name, content) in mismatch.get_details().items():
406 full_name = name
407 suffix = 1
408 while full_name in existing_details:
409 full_name = "%s-%d" % (name, suffix)
410 suffix += 1
411 self.addDetail(full_name, content)
412 raise MismatchError(matchee, matcher, mismatch, verbose)
414 def defaultTestResult(self):
415 return TestResult()
417 def expectFailure(self, reason, predicate, *args, **kwargs):
418 """Check that a test fails in a particular way.
420 If the test fails in the expected way, a KnownFailure is caused. If it
421 succeeds an UnexpectedSuccess is caused.
423 The expected use of expectFailure is as a barrier at the point in a
424 test where the test would fail. For example:
425 >>> def test_foo(self):
426 >>> self.expectFailure("1 should be 0", self.assertNotEqual, 1, 0)
427 >>> self.assertEqual(1, 0)
429 If in the future 1 were to equal 0, the expectFailure call can simply
430 be removed. This separation preserves the original intent of the test
431 while it is in the expectFailure mode.
433 # TODO: implement with matchers.
434 self._add_reason(reason)
435 try:
436 predicate(*args, **kwargs)
437 except self.failureException:
438 # GZ 2010-08-12: Don't know how to avoid exc_info cycle as the new
439 # unittest _ExpectedFailure wants old traceback
440 exc_info = sys.exc_info()
441 try:
442 self._report_traceback(exc_info)
443 raise _ExpectedFailure(exc_info)
444 finally:
445 del exc_info
446 else:
447 raise _UnexpectedSuccess(reason)
449 def getUniqueInteger(self):
450 """Get an integer unique to this test.
452 Returns an integer that is guaranteed to be unique to this instance.
453 Use this when you need an arbitrary integer in your test, or as a
454 helper for custom anonymous factory methods.
456 return advance_iterator(self._unique_id_gen)
458 def getUniqueString(self, prefix=None):
459 """Get a string unique to this test.
461 Returns a string that is guaranteed to be unique to this instance. Use
462 this when you need an arbitrary string in your test, or as a helper
463 for custom anonymous factory methods.
465 :param prefix: The prefix of the string. If not provided, defaults
466 to the id of the tests.
467 :return: A bytestring of '<prefix>-<unique_int>'.
469 if prefix is None:
470 prefix = self.id()
471 return '%s-%d' % (prefix, self.getUniqueInteger())
473 def onException(self, exc_info, tb_label='traceback'):
474 """Called when an exception propogates from test code.
476 :seealso addOnException:
478 if exc_info[0] not in [
479 TestSkipped, _UnexpectedSuccess, _ExpectedFailure]:
480 self._report_traceback(exc_info, tb_label=tb_label)
481 for handler in self.__exception_handlers:
482 handler(exc_info)
484 @staticmethod
485 def _report_error(self, result, err):
486 result.addError(self, details=self.getDetails())
488 @staticmethod
489 def _report_expected_failure(self, result, err):
490 result.addExpectedFailure(self, details=self.getDetails())
492 @staticmethod
493 def _report_failure(self, result, err):
494 result.addFailure(self, details=self.getDetails())
496 @staticmethod
497 def _report_skip(self, result, err):
498 if err.args:
499 reason = err.args[0]
500 else:
501 reason = "no reason given."
502 self._add_reason(reason)
503 result.addSkip(self, details=self.getDetails())
505 def _report_traceback(self, exc_info, tb_label='traceback'):
506 id_gen = self._traceback_id_gens.setdefault(
507 tb_label, itertools.count(0))
508 tb_id = advance_iterator(id_gen)
509 if tb_id:
510 tb_label = '%s-%d' % (tb_label, tb_id)
511 self.addDetail(tb_label, content.TracebackContent(exc_info, self))
513 @staticmethod
514 def _report_unexpected_success(self, result, err):
515 result.addUnexpectedSuccess(self, details=self.getDetails())
517 def run(self, result=None):
518 return self.__RunTest(self, self.exception_handlers).run(result)
520 def _run_setup(self, result):
521 """Run the setUp function for this test.
523 :param result: A testtools.TestResult to report activity to.
524 :raises ValueError: If the base class setUp is not called, a
525 ValueError is raised.
527 ret = self.setUp()
528 if not self.__setup_called:
529 raise ValueError(
530 "TestCase.setUp was not called. Have you upcalled all the "
531 "way up the hierarchy from your setUp? e.g. Call "
532 "super(%s, self).setUp() from your setUp()."
533 % self.__class__.__name__)
534 return ret
536 def _run_teardown(self, result):
537 """Run the tearDown function for this test.
539 :param result: A testtools.TestResult to report activity to.
540 :raises ValueError: If the base class tearDown is not called, a
541 ValueError is raised.
543 ret = self.tearDown()
544 if not self.__teardown_called:
545 raise ValueError(
546 "TestCase.tearDown was not called. Have you upcalled all the "
547 "way up the hierarchy from your tearDown? e.g. Call "
548 "super(%s, self).tearDown() from your tearDown()."
549 % self.__class__.__name__)
550 return ret
552 def _get_test_method(self):
553 absent_attr = object()
554 # Python 2.5+
555 method_name = getattr(self, '_testMethodName', absent_attr)
556 if method_name is absent_attr:
557 # Python 2.4
558 method_name = getattr(self, '_TestCase__testMethodName')
559 return getattr(self, method_name)
561 def _run_test_method(self, result):
562 """Run the test method for this test.
564 :param result: A testtools.TestResult to report activity to.
565 :return: None.
567 return self._get_test_method()()
569 def useFixture(self, fixture):
570 """Use fixture in a test case.
572 The fixture will be setUp, and self.addCleanup(fixture.cleanUp) called.
574 :param fixture: The fixture to use.
575 :return: The fixture, after setting it up and scheduling a cleanup for
578 try:
579 fixture.setUp()
580 except:
581 gather_details(fixture.getDetails(), self.getDetails())
582 raise
583 else:
584 self.addCleanup(fixture.cleanUp)
585 self.addCleanup(
586 gather_details, fixture.getDetails(), self.getDetails())
587 return fixture
589 def setUp(self):
590 super(TestCase, self).setUp()
591 self.__setup_called = True
593 def tearDown(self):
594 super(TestCase, self).tearDown()
595 unittest.TestCase.tearDown(self)
596 self.__teardown_called = True
599 class PlaceHolder(object):
600 """A placeholder test.
602 `PlaceHolder` implements much of the same interface as TestCase and is
603 particularly suitable for being added to TestResults.
606 failureException = None
608 def __init__(self, test_id, short_description=None, details=None,
609 outcome='addSuccess', error=None):
610 """Construct a `PlaceHolder`.
612 :param test_id: The id of the placeholder test.
613 :param short_description: The short description of the place holder
614 test. If not provided, the id will be used instead.
615 :param details: Outcome details as accepted by addSuccess etc.
616 :param outcome: The outcome to call. Defaults to 'addSuccess'.
618 self._test_id = test_id
619 self._short_description = short_description
620 self._details = details or {}
621 self._outcome = outcome
622 if error is not None:
623 self._details['traceback'] = content.TracebackContent(error, self)
625 def __call__(self, result=None):
626 return self.run(result=result)
628 def __repr__(self):
629 internal = [self._outcome, self._test_id, self._details]
630 if self._short_description is not None:
631 internal.append(self._short_description)
632 return "<%s.%s(%s)>" % (
633 self.__class__.__module__,
634 self.__class__.__name__,
635 ", ".join(map(repr, internal)))
637 def __str__(self):
638 return self.id()
640 def countTestCases(self):
641 return 1
643 def debug(self):
644 pass
646 def id(self):
647 return self._test_id
649 def _result(self, result):
650 if result is None:
651 return TestResult()
652 else:
653 return ExtendedToOriginalDecorator(result)
655 def run(self, result=None):
656 result = self._result(result)
657 result.startTest(self)
658 outcome = getattr(result, self._outcome)
659 outcome(self, details=self._details)
660 result.stopTest(self)
662 def shortDescription(self):
663 if self._short_description is None:
664 return self.id()
665 else:
666 return self._short_description
669 def ErrorHolder(test_id, error, short_description=None, details=None):
670 """Construct an `ErrorHolder`.
672 :param test_id: The id of the test.
673 :param error: The exc info tuple that will be used as the test's error.
674 This is inserted into the details as 'traceback' - any existing key
675 will be overridden.
676 :param short_description: An optional short description of the test.
677 :param details: Outcome details as accepted by addSuccess etc.
679 return PlaceHolder(test_id, short_description=short_description,
680 details=details, outcome='addError', error=error)
683 # Python 2.4 did not know how to copy functions.
684 if types.FunctionType not in copy._copy_dispatch:
685 copy._copy_dispatch[types.FunctionType] = copy._copy_immutable
688 def clone_test_with_new_id(test, new_id):
689 """Copy a `TestCase`, and give the copied test a new id.
691 This is only expected to be used on tests that have been constructed but
692 not executed.
694 newTest = copy.copy(test)
695 newTest.id = lambda: new_id
696 return newTest
699 def skip(reason):
700 """A decorator to skip unit tests.
702 This is just syntactic sugar so users don't have to change any of their
703 unit tests in order to migrate to python 2.7, which provides the
704 @unittest.skip decorator.
706 def decorator(test_item):
707 if wraps is not None:
708 @wraps(test_item)
709 def skip_wrapper(*args, **kwargs):
710 raise TestCase.skipException(reason)
711 else:
712 def skip_wrapper(test_item):
713 test_item.skip(reason)
714 return skip_wrapper
715 return decorator
718 def skipIf(condition, reason):
719 """Skip a test if the condition is true."""
720 if condition:
721 return skip(reason)
722 def _id(obj):
723 return obj
724 return _id
727 def skipUnless(condition, reason):
728 """Skip a test unless the condition is true."""
729 if not condition:
730 return skip(reason)
731 def _id(obj):
732 return obj
733 return _id
736 class ExpectedException:
737 """A context manager to handle expected exceptions.
739 In Python 2.5 or later::
741 def test_foo(self):
742 with ExpectedException(ValueError, 'fo.*'):
743 raise ValueError('foo')
745 will pass. If the raised exception has a type other than the specified
746 type, it will be re-raised. If it has a 'str()' that does not match the
747 given regular expression, an AssertionError will be raised. If no
748 exception is raised, an AssertionError will be raised.
751 def __init__(self, exc_type, value_re=None):
752 """Construct an `ExpectedException`.
754 :param exc_type: The type of exception to expect.
755 :param value_re: A regular expression to match against the
756 'str()' of the raised exception.
758 self.exc_type = exc_type
759 self.value_re = value_re
761 def __enter__(self):
762 pass
764 def __exit__(self, exc_type, exc_value, traceback):
765 if exc_type is None:
766 raise AssertionError('%s not raised.' % self.exc_type.__name__)
767 if exc_type != self.exc_type:
768 return False
769 if self.value_re:
770 matcher = MatchesException(self.exc_type, self.value_re)
771 mismatch = matcher.match((exc_type, exc_value, traceback))
772 if mismatch:
773 raise AssertionError(mismatch.describe())
774 return True
777 class Nullary(object):
778 """Turn a callable into a nullary callable.
780 The advantage of this over ``lambda: f(*args, **kwargs)`` is that it
781 preserves the ``repr()`` of ``f``.
784 def __init__(self, callable_object, *args, **kwargs):
785 self._callable_object = callable_object
786 self._args = args
787 self._kwargs = kwargs
789 def __call__(self):
790 return self._callable_object(*self._args, **self._kwargs)
792 def __repr__(self):
793 return repr(self._callable_object)
796 # Signal that this is part of the testing framework, and that code from this
797 # should not normally appear in tracebacks.
798 __unittest = True