From faae266e89d19f5dfea81db0771b6fa671e9b1ac Mon Sep 17 00:00:00 2001
From: Neil Schemenauer <nascheme@enme.ucalgary.ca>
Date: Fri, 22 Sep 2000 15:26:20 +0000
Subject: - Add test for new SAVEALL debugging flag - Use exceptions rather
 than asserts for failing tests. - Reorganize tests and produce some output if
 verbose option is set.

---
 Lib/test/test_gc.py | 123 +++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 92 insertions(+), 31 deletions(-)

diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py
index e2e6d0c..da0b141 100644
--- a/Lib/test/test_gc.py
+++ b/Lib/test/test_gc.py
@@ -1,18 +1,35 @@
+from test_support import verbose, TestFailed
 import gc
 
+def run_test(name, thunk):
+    if verbose:
+        print "testing %s..." % name,
+    try:
+        thunk()
+    except TestFailed:
+        if verbose:
+            print "failed (expected %s but got %s)" % (result,
+                                                       test_result)
+        raise TestFailed, name
+    else:
+        if verbose:
+            print "ok"
+
 def test_list():
     l = []
     l.append(l)
     gc.collect()
     del l
-    assert gc.collect() == 1
+    if gc.collect() != 1:
+        raise TestFailed
 
 def test_dict():
     d = {}
     d[1] = d
     gc.collect()
     del d
-    assert gc.collect() == 1
+    if gc.collect() != 1:
+        raise TestFailed
 
 def test_tuple():
     # since tuples are immutable we close the loop with a list
@@ -22,7 +39,8 @@ def test_tuple():
     gc.collect()
     del t
     del l
-    assert gc.collect() == 2
+    if gc.collect() != 2:
+        raise TestFailed
 
 def test_class():
     class A:
@@ -30,7 +48,8 @@ def test_class():
     A.a = A
     gc.collect()
     del A
-    assert gc.collect() > 0
+    if gc.collect() == 0:
+        raise TestFailed
 
 def test_instance():
     class A:
@@ -39,7 +58,8 @@ def test_instance():
     a.a = a
     gc.collect()
     del a
-    assert gc.collect() > 0
+    if gc.collect() == 0:
+        raise TestFailed
 
 def test_method():
     # Tricky: self.__init__ is a bound method, it references the instance.
@@ -49,7 +69,8 @@ def test_method():
     a = A()
     gc.collect()
     del a
-    assert gc.collect() > 0
+    if gc.collect() == 0:
+        raise TestFailed
 
 def test_finalizer():
     # A() is uncollectable if it is part of a cycle, make sure it shows up
@@ -64,11 +85,17 @@ def test_finalizer():
     b = B()
     b.b = b
     gc.collect()
-    gc.garbage[:] = []
     del a
     del b
-    assert gc.collect() > 0
-    assert id(gc.garbage[0]) == id_a
+    if gc.collect() == 0:
+        raise TestFailed
+    for obj in gc.garbage:
+        if id(obj) == id_a:
+            del obj.a
+            break
+    else:
+        raise TestFailed
+    gc.garbage.remove(obj)
 
 def test_function():
     # Tricky: f -> d -> f, code should call d.clear() after the exec to
@@ -77,7 +104,29 @@ def test_function():
     exec("def f(): pass\n") in d
     gc.collect()
     del d
-    assert gc.collect() == 2
+    if gc.collect() != 2:
+        raise TestFailed
+
+def test_saveall():
+    # Verify that cyclic garbage like lists show up in gc.garbage if the
+    # SAVEALL option is enabled.
+    debug = gc.get_debug()
+    gc.set_debug(debug | gc.DEBUG_SAVEALL)
+    l = []
+    l.append(l)
+    id_l = id(l)
+    del l
+    gc.collect()
+    try:
+        for obj in gc.garbage:
+            if id(obj) == id_l:
+                del obj[:]
+                break
+        else:
+            raise TestFailed
+        gc.garbage.remove(obj)
+    finally:
+        gc.set_debug(debug)
 
 def test_del():
     # __del__ methods can trigger collection, make this to happen
@@ -96,26 +145,38 @@ def test_del():
     
 
 def test_all():
-
+    run_test("lists", test_list)
+    run_test("dicts", test_dict)
+    run_test("tuples", test_tuple)
+    run_test("classes", test_class)
+    run_test("instances", test_instance)
+    run_test("methods", test_method)
+    run_test("functions", test_function)
+    run_test("finalizers", test_finalizer)
+    run_test("__del__", test_del)
+    run_test("saveall", test_saveall)
+
+def test():
+    if verbose:
+        print "disabling automatic collection"
     enabled = gc.isenabled()
     gc.disable()
-    assert not gc.isenabled()
-
-    test_list()
-    test_dict()
-    test_tuple()
-    test_class()
-    test_instance()
-    test_method()
-    test_finalizer()
-    test_function()
-    test_del()
-
-    # test gc.enable() even if GC is disabled by default
-    gc.enable()
-    assert gc.isenabled()
-    if not enabled:
-        gc.disable()
-
-
-test_all()
+    assert not gc.isenabled() 
+    debug = gc.get_debug()
+    gc.set_debug(debug & ~gc.DEBUG_LEAK) # this test is supposed to leak
+
+    try:
+        test_all()
+    finally:
+        gc.set_debug(debug)
+        # test gc.enable() even if GC is disabled by default
+        if verbose:
+            print "restoring automatic collection"
+        # make sure to always test gc.enable()
+        gc.enable()
+        assert gc.isenabled()
+        if not enabled:
+            gc.disable()
+
+
+test()
-- 
cgit v0.12

