From f440a2cd3ce1b0e5de804a8688234ffcdb17622c 2010-01-17 22:36:19
From: Fernando Perez <Fernando.Perez@berkeley.edu>
Date: 2010-01-17 22:36:19
Subject: [PATCH] Added diagnostics printout at the end of the test suite.

This will make it easier for us to understand problem reports from users.

---

diff --git a/IPython/core/release.py b/IPython/core/release.py
index 2bc9de5..7195454 100644
--- a/IPython/core/release.py
+++ b/IPython/core/release.py
@@ -23,7 +23,7 @@ name = 'ipython'
 development = True    # change this to False to do a release
 version_base = '0.11'
 branch = 'ipython'
-revision = '1340'
+revision = '1346'
 
 if development:
     if branch == 'ipython':
diff --git a/IPython/testing/iptest.py b/IPython/testing/iptest.py
index c8bdce8..946d2c0 100644
--- a/IPython/testing/iptest.py
+++ b/IPython/testing/iptest.py
@@ -23,6 +23,7 @@ will change in the future.
 # Stdlib
 import os
 import os.path as path
+import platform
 import signal
 import sys
 import subprocess
@@ -49,6 +50,7 @@ import nose.plugins.builtin
 from nose.core import TestProgram
 
 # Our own imports
+from IPython.core import release
 from IPython.utils import genutils
 from IPython.utils.platutils import find_cmd, FindCmdError
 from IPython.testing import globalipapp
@@ -100,21 +102,54 @@ def test_for(mod):
     else:
         return True
 
-have_curses = test_for('_curses')
-have_wx = test_for('wx')
-have_wx_aui = test_for('wx.aui')
-have_zi = test_for('zope.interface')
-have_twisted = test_for('twisted')
-have_foolscap = test_for('foolscap')
-have_objc = test_for('objc')
-have_pexpect = test_for('pexpect')
-have_gtk = test_for('gtk')
-have_gobject = test_for('gobject')
+# Global dict where we can store information on what we have and what we don't
+# have available at test run time
+have = {}
+
+have['curses'] = test_for('_curses')
+have['wx'] = test_for('wx')
+have['wx.aui'] = test_for('wx.aui')
+have['zope.interface'] = test_for('zope.interface')
+have['twisted'] = test_for('twisted')
+have['foolscap'] = test_for('foolscap')
+have['objc'] = test_for('objc')
+have['pexpect'] = test_for('pexpect')
+have['gtk'] = test_for('gtk')
+have['gobject'] = test_for('gobject')
 
 #-----------------------------------------------------------------------------
 # Functions and classes
 #-----------------------------------------------------------------------------
 
+def report():
+    """Return a string with a summary report of test-related variables."""
+
+    out = [ genutils.sys_info() ]
+
+    out.append('\nRunning from an installed IPython: %s\n' % INSTALLED)
+
+    avail = []
+    not_avail = []
+    
+    for k, is_avail in have.items():
+        if is_avail:
+            avail.append(k)
+        else:
+            not_avail.append(k)
+
+    if avail:
+        out.append('\nTools and libraries available at test time:\n')
+        avail.sort()
+        out.append('   ' + ' '.join(avail)+'\n')
+
+    if not_avail:
+        out.append('\nTools and libraries NOT available at test time:\n')
+        not_avail.sort()
+        out.append('   ' + ' '.join(not_avail)+'\n')
+        
+    return ''.join(out)
+
+
 def make_exclude():
     """Make patterns of modules and packages to exclude from testing.
     
@@ -149,18 +184,18 @@ def make_exclude():
                   ipjoin('config', 'profile'),
                   ]
 
-    if not have_wx:
+    if not have['wx']:
         exclusions.append(ipjoin('gui'))
         exclusions.append(ipjoin('frontend', 'wx'))
         exclusions.append(ipjoin('lib', 'inputhookwx'))
 
-    if not have_gtk or not have_gobject:
+    if not have['gtk'] or not have['gobject']:
         exclusions.append(ipjoin('lib', 'inputhookgtk'))
 
-    if not have_wx_aui:
+    if not have['wx.aui']:
         exclusions.append(ipjoin('gui', 'wx', 'wxIPython'))
 
-    if not have_objc:
+    if not have['objc']:
         exclusions.append(ipjoin('frontend', 'cocoa'))
 
     if not sys.platform == 'win32':
@@ -175,14 +210,14 @@ def make_exclude():
     if not os.name == 'posix':
         exclusions.append(ipjoin('utils', 'platutils_posix'))
 
-    if not have_pexpect:
+    if not have['pexpect']:
         exclusions.extend([ipjoin('scripts', 'irunner'),
                            ipjoin('lib', 'irunner')])
 
     # This is scary.  We still have things in frontend and testing that
     # are being tested by nose that use twisted.  We need to rethink
     # how we are isolating dependencies in testing.
-    if not (have_twisted and have_zi and have_foolscap):
+    if not (have['twisted'] and have['zope.interface'] and have['foolscap']):
         exclusions.extend(
             [ipjoin('frontend', 'asyncfrontendbase'),
              ipjoin('frontend', 'prefilterfrontend'),
@@ -303,11 +338,11 @@ def make_runners():
     # The machinery in kernel needs twisted for real testing
     trial_pkg_names = []
 
-    if have_wx:
+    if have['wx']:
         nose_pkg_names.append('gui')
 
     # And add twisted ones if conditions are met
-    if have_zi and have_twisted and have_foolscap:
+    if have['zope.interface'] and have['twisted'] and have['foolscap']:
         # Note that we list the kernel here, though the bulk of it is
         # twisted-based, because nose picks up doctests that twisted doesn't.
         nose_pkg_names.append('kernel')
@@ -420,8 +455,11 @@ def run_iptestall():
     # summarize results
     print
     print '*'*70
+    print 'Test suite completed for system with the following information:'
+    print report()
     print 'Ran %s test groups in %.3fs' % (nrunners, t_tests)
     print
+    print 'Status:'
     if not failed:
         print 'OK'
     else:
diff --git a/docs/source/development/testing.txt b/docs/source/development/testing.txt
index c5bdaaf..0a3a9d1 100644
--- a/docs/source/development/testing.txt
+++ b/docs/source/development/testing.txt
@@ -82,10 +82,26 @@ Regardless of how you run things, you should eventually see something like:
 .. code-block:: bash
 
    **********************************************************************
-   Ran 11 test groups in 64.117s
+   Test suite completed for system with the following information:
+   IPython version: 0.11.bzr.r1340
+   BZR revision   : 1340
+   Platform info  : os.name -> posix, sys.platform -> linux2
+		  : Linux-2.6.31-17-generic-i686-with-Ubuntu-9.10-karmic
+   Python info    : 2.6.4 (r264:75706, Dec  7 2009, 18:45:15) 
+   [GCC 4.4.1]
 
-   OK
+   Running from an installed IPython: True
+
+   Tools and libraries available at test time:
+      curses foolscap gobject gtk pexpect twisted wx wx.aui zope.interface
+
+   Tools and libraries NOT available at test time:
+      objc
 
+   Ran 11 test groups in 36.244s
+
+   Status:
+   OK
 
 If not, there will be a message indicating which test group failed and how to
 rerun that group individually.  For example, this tests the