Commit dd08c570 authored by Hanno Schlichting's avatar Hanno Schlichting

Remove `Control_Panel/DebugInfo`.

parent c0447b1f
......@@ -21,6 +21,8 @@ Features Added
Restructuring
+++++++++++++
- Remove `Control_Panel/DebugInfo`.
- Remove profiling support via `publisher-profile-file` directive.
- Create new `Products.Sessions` distribution including Products.Sessions
......
......@@ -11,7 +11,6 @@
#
##############################################################################
from cStringIO import StringIO
from logging import getLogger
import os
import sys
......@@ -26,15 +25,12 @@ from App.CacheManager import CacheManager
from App.config import getConfiguration
from App.DavLockManager import DavLockManager
from App.special_dtml import DTMLFile
from App.Undo import UndoSupport
from App.version_txt import version_txt
from DateTime.DateTime import DateTime
from OFS.Folder import Folder
from OFS.SimpleItem import Item
from OFS.SimpleItem import SimpleItem
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from zExceptions import Redirect
from ZPublisher import Publish
LOG = getLogger('ApplicationManager')
......@@ -48,12 +44,12 @@ class DatabaseManager(Item, Implicit):
name = title = 'Database Management'
meta_type = 'Database Management'
manage_options=((
{'label':'Database', 'action':'manage_main'},
{'label':'Activity', 'action':'manage_activity'},
{'label':'Cache Parameters', 'action':'manage_cacheParameters'},
{'label':'Flush Cache', 'action':'manage_cacheGC'},
))
manage_options = ((
{'label': 'Database', 'action': 'manage_main'},
{'label': 'Activity', 'action': 'manage_activity'},
{'label': 'Cache Parameters', 'action': 'manage_cacheParameters'},
{'label': 'Flush Cache', 'action': 'manage_cacheGC'},
))
# These need to be here rather to make tabs work correctly. This
# needs to be revisited.
......@@ -81,9 +77,9 @@ class DatabaseChooser(SimpleItem):
name = title = 'Database Management'
isPrincipiaFolderish = 1
manage_options=(
{'label':'Databases', 'action':'manage_main'},
)
manage_options = (
{'label': 'Databases', 'action': 'manage_main'},
)
manage_main = PageTemplateFile('www/chooseDatabase.pt', globals())
......@@ -126,103 +122,12 @@ class DatabaseChooser(SimpleItem):
InitializeClass(DatabaseChooser)
# refcount snapshot info
_v_rcs = None
_v_rst = None
class DebugManager(Item, Implicit):
""" Debug and profiling information
"""
manage = manage_main = DTMLFile('dtml/debug', globals())
manage_main._setName('manage_main')
id ='DebugInfo'
name = title = 'Debug Information'
meta_type = name
manage_options = ((
{'label': 'Debugging Info', 'action': 'manage_main'},
))
manage_debug = DTMLFile('dtml/debug', globals())
def refcount(self, n=None, t=(type(Implicit), )):
# return class reference info
counts = {}
for m in sys.modules.values():
if m is None:
continue
if 'six.' in m.__name__:
continue
for sym in dir(m):
ob = getattr(m, sym)
if type(ob) in t:
counts[ob] = sys.getrefcount(ob)
pairs = []
for ob, v in counts.items():
if hasattr(ob, '__module__'):
name = '%s.%s' % (ob.__module__, ob.__name__)
else:
name = '%s' % ob.__name__
pairs.append((v, name))
pairs.sort()
pairs.reverse()
if n is not None:
pairs = pairs[:n]
return pairs
def refdict(self):
counts = {}
for v, n in self.refcount():
counts[n] = v
return counts
def rcsnapshot(self):
global _v_rcs
global _v_rst
_v_rcs = self.refdict()
_v_rst = DateTime()
def rcdate(self):
return _v_rst
def rcdeltas(self):
if _v_rcs is None:
self.rcsnapshot()
nc = self.refdict()
rc = _v_rcs
rd = []
for n, c in nc.items():
try:
prev = rc.get(n, 0)
if c > prev:
rd.append((c - prev, (c, prev, n)))
except Exception:
pass
rd.sort()
rd.reverse()
return [{'name': n[1][2],
'delta': n[0],
'pc': n[1][1],
'rc': n[1][0],
} for n in rd]
def dbconnections(self):
import Zope2 # for data
return Zope2.DB.connectionDebugInfo()
def manage_getSysPath(self):
return list(sys.path)
InitializeClass(DebugManager)
class ApplicationManager(Folder, CacheManager):
"""System management
"""
__roles__ = ('Manager',)
isPrincipiaFolderish = 1
Database = DatabaseChooser('Database') # DatabaseManager()
DebugInfo = DebugManager()
DavLocks = DavLockManager()
manage = manage_main = DTMLFile('dtml/cpContents', globals())
......@@ -233,8 +138,6 @@ class ApplicationManager(Folder, CacheManager):
'meta_type': Database.meta_type},
{'id': 'DavLocks',
'meta_type': DavLocks.meta_type},
{'id': 'DebugInfo',
'meta_type': DebugInfo.meta_type},
)
manage_options = ({'label': 'Control Panel', 'action': 'manage_main'}, )
......@@ -273,23 +176,7 @@ class ApplicationManager(Folder, CacheManager):
def manage_app(self, URL2):
"""Return to the main management screen"""
raise Redirect, URL2+'/manage'
def process_time(self, _when=None):
if _when is None:
_when = time.time()
s = int(_when) - self.process_start
d = int(s / 86400)
s = s - (d * 86400)
h = int(s / 3600)
s = s -(h * 3600)
m = int(s / 60)
s = s - (m * 60)
d = d and ('%d day%s' % (d, (d != 1 and 's' or ''))) or ''
h = h and ('%d hour%s' % (h, (h != 1 and 's' or ''))) or ''
m = m and ('%d min' % m) or ''
s = '%d sec' % s
return '%s %s %s %s' % (d, h, m, s)
raise Redirect(URL2 + '/manage')
def thread_get_ident(self):
return get_ident()
......@@ -299,12 +186,12 @@ class ApplicationManager(Folder, CacheManager):
def db_size(self):
s = self._p_jar.db().getSize()
if type(s) is type(''):
if isinstance(s, str):
return s
if s >= 1048576.0:
return '%.1fM' % (s/1048576.0)
return '%.1fK' % (s/1024.0)
return '%.1fM' % (s / 1048576.0)
return '%.1fK' % (s / 1024.0)
@requestmethod('POST')
def manage_pack(self, days=0, REQUEST=None, _when=None):
......@@ -328,21 +215,6 @@ class ApplicationManager(Folder, CacheManager):
def getCLIENT_HOME(self):
return getConfiguration().clienthome
def getServers(self):
# used only for display purposes
# return a sequence of two-tuples. The first element of
# each tuple is the service name, the second is a string repr. of
# the port/socket/other on which it listens
from asyncore import socket_map
l = []
for k,v in socket_map.items():
# this is only an approximation
if hasattr(v, 'port'):
type = str(getattr(v, '__class__', 'unknown'))
port = v.port
l.append((str(type), 'Port: %s' % port))
return l
class AltDatabaseManager(DatabaseManager, CacheManager):
""" Database management DBTab-style
......
......@@ -67,20 +67,6 @@ The Control Panel provides access to system information.
</div>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Network Services
</div>
</td>
<td align="left" valign="top">
<div class="form-text">
<dtml-in getServers>
&dtml-sequence-key; (&dtml-sequence-item;)<br />
</dtml-in>
</div>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
......@@ -93,18 +79,6 @@ The Control Panel provides access to system information.
</div>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Running For
</div>
</td>
<td align="left" valign="top">
<div class="form-text">
&dtml-process_time;
</div>
</td>
</tr>
</table>
</form>
......
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title><dtml-if title>&dtml-title;</dtml-if></title>
<link rel="stylesheet" type="text/css" href="&dtml-BASEPATH1;/manage_page_style.css">
<dtml-if debug_auto_reload>
<meta HTTP-EQUIV="Refresh"
CONTENT="&dtml-debug_auto_reload;;URL=&dtml-URL;?debug_auto_reload=&dtml-debug_auto_reload;">
</dtml-if>
<style type="text/css">
<!--
.header {
font-weight: bold;
font-size: 10pt;
}
.cell {
font-size: 10pt;
}
-->
</style>
</head>
<body bgcolor="#ffffff" link="#000099" alink="#000099" vlink="#000099">
<font face="verdana, helvetica, sans-serif" size="2" color="#333333">
<dtml-var manage_tabs>
<dtml-if update_snapshot>
<dtml-call rcsnapshot>
</dtml-if>
<h3>Debug Information</h3>
<form action="&dtml-URL;" method="GET">
<p>
<ul>
<li>Zope version: &dtml-version_txt;
<li>Python version: &dtml-sys_version;
<li>System Platform: &dtml-sys_platform;
<li>INSTANCE_HOME: &dtml-getINSTANCE_HOME;
<li>CLIENT_HOME: &dtml-getCLIENT_HOME;
<li>Process ID: &dtml-process_id; (&dtml-thread_get_ident;)
<li>Running for: &dtml-process_time;
<li>sys.path: <dtml-in manage_getSysPath><br />&nbsp;
&dtml-sequence-item;
</dtml-in>
<li>Top Refcounts:<br><select name="foo" size="5"><dtml-in
"refcount(100)"><option>&dtml-sequence-item;:
&dtml-sequence-key;</option></dtml-in
></select><br><br>
<table border="1">
<dtml-in rcdeltas mapping>
<dtml-if sequence-start>
<tr>
<th class="header" align="left" valign="top">
Class
</th>
<th class="header" align="left" valign="top">
<dtml-var rcdate fmt="fCommon" null="">
</th>
<th class="header" align="left" valign="top">
<dtml-var ZopeTime fmt="fCommon">
</th>
<th class="header" align="left" valign="top">
Delta
</th>
</tr>
</dtml-if>
<tr>
<td class="cell" align="left" valign="top">
&dtml-name;
</td>
<td class="cell" align="left" valign="top">
&dtml-pc;
</td>
<td class="cell" align="left" valign="top">
&dtml-rc;
</td>
<td class="cell" align="left" valign="top">
+&dtml-delta;
</td>
</tr>
</dtml-in>
</table>
<p><a href="../Database/cache_detail">Cache detail</a> |
<a href="../Database/cache_extreme_detail">Cache extreme detail</a>
</p>
<p><a href="&dtml-URL;?update_snapshot=1">Update Snapshot</a> |
<dtml-if debug_auto_reload>
<a href="&dtml-URL;">Stop auto refresh</a>
<dtml-else>
<a href="&dtml-URL;">Refresh</a> |
Auto refresh interval (seconds):
<input type="text" name="debug_auto_reload" size="3" value="10">
<input type="submit" value="Start auto refresh">
</dtml-if>
</p>
<li>Connections:
<table border="1">
<tr><th>opened</th><th>info</th></tr>
<dtml-in dbconnections mapping>
<tr><td>&dtml-opened;</td><td>&dtml-info;</td></tr>
</dtml-in></table>
</ul>
</p>
</form>
<dtml-var manage_page_footer>
import unittest
class ConfigTestBase:
class ConfigTestBase(object):
def setUp(self):
import App.config
......@@ -12,12 +13,14 @@ class ConfigTestBase:
def _makeConfig(self, **kw):
import App.config
class DummyConfig:
class DummyConfig(object):
pass
App.config._config = config = DummyConfig()
config.dbtab = DummyDBTab(kw)
return config
class FakeConnectionTests(unittest.TestCase):
def _getTargetClass(self):
......@@ -33,6 +36,7 @@ class FakeConnectionTests(unittest.TestCase):
fc = self._makeOne(db, parent_jar)
self.assertTrue(fc.db() is db)
class DatabaseChooserTests(ConfigTestBase, unittest.TestCase):
def _getTargetClass(self):
......@@ -44,8 +48,10 @@ class DatabaseChooserTests(ConfigTestBase, unittest.TestCase):
def _makeRoot(self):
from ExtensionClass import Base
class Root(Base):
_p_jar = None
def getPhysicalRoot(self):
return self
return Root()
......@@ -63,9 +69,9 @@ class DatabaseChooserTests(ConfigTestBase, unittest.TestCase):
def test___getitem___hit(self):
from App.ApplicationManager import AltDatabaseManager
from App.ApplicationManager import FakeConnection
foo=object()
bar=object()
qux=object()
foo = object()
bar = object()
qux = object()
self._makeConfig(foo=foo, bar=bar, qux=qux)
root = self._makeRoot()
dc = self._makeOne('test').__of__(root)
......@@ -86,9 +92,9 @@ class DatabaseChooserTests(ConfigTestBase, unittest.TestCase):
def test___bobo_traverse___hit_db(self):
from App.ApplicationManager import AltDatabaseManager
from App.ApplicationManager import FakeConnection
foo=object()
bar=object()
qux=object()
foo = object()
bar = object()
qux = object()
self._makeConfig(foo=foo, bar=bar, qux=qux)
root = self._makeRoot()
dc = self._makeOne('test').__of__(root)
......@@ -101,9 +107,9 @@ class DatabaseChooserTests(ConfigTestBase, unittest.TestCase):
self.assertTrue(conn.db() is foo)
def test___bobo_traverse___miss_db_hit_attr(self):
foo=object()
bar=object()
qux=object()
foo = object()
bar = object()
qux = object()
self._makeConfig(foo=foo, bar=bar, qux=qux)
root = self._makeRoot()
dc = self._makeOne('test').__of__(root)
......@@ -113,9 +119,9 @@ class DatabaseChooserTests(ConfigTestBase, unittest.TestCase):
def test_tpValues(self):
from App.ApplicationManager import AltDatabaseManager
foo=object()
bar=object()
qux=object()
foo = object()
bar = object()
qux = object()
self._makeConfig(foo=foo, bar=bar, qux=qux)
root = self._makeRoot()
dc = self._makeOne('test').__of__(root)
......@@ -132,118 +138,7 @@ class DatabaseChooserTests(ConfigTestBase, unittest.TestCase):
self.assertEqual(values[2]._p_jar, None)
class DebugManagerTests(unittest.TestCase):
def setUp(self):
import sys
self._sys = sys
self._old_sys_modules = sys.modules.copy()
def tearDown(self):
self._sys.modules.clear()
self._sys.modules.update(self._old_sys_modules)
def _getTargetClass(self):
from App.ApplicationManager import DebugManager
return DebugManager
def _makeOne(self, id):
return self._getTargetClass()(id)
def _makeModuleClasses(self):
import sys
import types
from ExtensionClass import Base
class Foo(Base):
pass
class Bar(Base):
pass
class Baz(Base):
pass
foo = sys.modules['foo'] = types.ModuleType('foo')
foo.Foo = Foo
Foo.__module__ = 'foo'
foo.Bar = Bar
Bar.__module__ = 'foo'
qux = sys.modules['qux'] = types.ModuleType('qux')
qux.Baz = Baz
Baz.__module__ = 'qux'
return Foo, Bar, Baz
def test_refcount_no_limit(self):
import sys
dm = self._makeOne('test')
Foo, Bar, Baz = self._makeModuleClasses()
pairs = dm.refcount()
# XXX : Ugly empiricism here: I don't know why the count is up 1.
foo_count = sys.getrefcount(Foo)
self.assertTrue((foo_count+1, 'foo.Foo') in pairs)
bar_count = sys.getrefcount(Bar)
self.assertTrue((bar_count+1, 'foo.Bar') in pairs)
baz_count = sys.getrefcount(Baz)
self.assertTrue((baz_count+1, 'qux.Baz') in pairs)
def test_refdict(self):
import sys
dm = self._makeOne('test')
Foo, Bar, Baz = self._makeModuleClasses()
mapping = dm.refdict()
# XXX : Ugly empiricism here: I don't know why the count is up 1.
foo_count = sys.getrefcount(Foo)
self.assertEqual(mapping['foo.Foo'], foo_count+1)
bar_count = sys.getrefcount(Bar)
self.assertEqual(mapping['foo.Bar'], bar_count+1)
baz_count = sys.getrefcount(Baz)
self.assertEqual(mapping['qux.Baz'], baz_count+1)
def test_rcsnapshot(self):
import sys
import App.ApplicationManager
from DateTime.DateTime import DateTime
dm = self._makeOne('test')
Foo, Bar, Baz = self._makeModuleClasses()
before = DateTime()
dm.rcsnapshot()
after = DateTime()
# XXX : Ugly empiricism here: I don't know why the count is up 1.
self.assertTrue(before <= App.ApplicationManager._v_rst <= after)
mapping = App.ApplicationManager._v_rcs
foo_count = sys.getrefcount(Foo)
self.assertEqual(mapping['foo.Foo'], foo_count+1)
bar_count = sys.getrefcount(Bar)
self.assertEqual(mapping['foo.Bar'], bar_count+1)
baz_count = sys.getrefcount(Baz)
self.assertEqual(mapping['qux.Baz'], baz_count+1)
def test_rcdate(self):
import App.ApplicationManager
dummy = object()
App.ApplicationManager._v_rst = dummy
dm = self._makeOne('test')
found = dm.rcdate()
App.ApplicationManager._v_rst = None
self.assertTrue(found is dummy)
def test_rcdeltas(self):
dm = self._makeOne('test')
dm.rcsnapshot()
Foo, Bar, Baz = self._makeModuleClasses()
mappings = dm.rcdeltas()
self.assertTrue(len(mappings))
mapping = mappings[0]
self.assertTrue('rc' in mapping)
self.assertTrue('pc' in mapping)
self.assertEqual(mapping['delta'], mapping['rc'] - mapping['pc'])
# def test_dbconnections(self): XXX -- TOO UGLY TO TEST
def test_manage_getSysPath(self):
import sys
dm = self._makeOne('test')
self.assertEqual(dm.manage_getSysPath(), list(sys.path))
class DBProxyTestsBase:
class DBProxyTestsBase(object):
def _makeOne(self):
return self._getTargetClass()()
......@@ -279,13 +174,13 @@ class DBProxyTestsBase:
def test_manage_pack(self):
am = self._makeOne()
jar = am._p_jar = self._makeJar('foo', '')
am.manage_pack(1, _when=86400*2)
am.manage_pack(1, _when=86400 * 2)
self.assertEqual(jar._db._packed, 86400)
class ApplicationManagerTests(ConfigTestBase,
DBProxyTestsBase,
unittest.TestCase,
):
unittest.TestCase):
def setUp(self):
ConfigTestBase.setUp(self)
......@@ -341,56 +236,11 @@ class ApplicationManagerTests(ConfigTestBase,
am = self._makeOne()
try:
am.manage_app('http://example.com/foo')
except Redirect, v:
except Redirect as v:
self.assertEqual(v.args, ('http://example.com/foo/manage',))
else:
self.fail('Redirect not raised')
def test_process_time_seconds(self):
am = self._makeOne()
am.process_start = 0
self.assertEqual(am.process_time(0).strip(), '0 sec')
self.assertEqual(am.process_time(1).strip(), '1 sec')
self.assertEqual(am.process_time(2).strip(), '2 sec')
def test_process_time_minutes(self):
am = self._makeOne()
am.process_start = 0
self.assertEqual(am.process_time(60).strip(), '1 min 0 sec')
self.assertEqual(am.process_time(61).strip(), '1 min 1 sec')
self.assertEqual(am.process_time(62).strip(), '1 min 2 sec')
self.assertEqual(am.process_time(120).strip(), '2 min 0 sec')
self.assertEqual(am.process_time(121).strip(), '2 min 1 sec')
self.assertEqual(am.process_time(122).strip(), '2 min 2 sec')
def test_process_time_hours(self):
am = self._makeOne()
am.process_start = 0
n1 = 60 * 60
n2 = n1 * 2
self.assertEqual(am.process_time(n1).strip(),
'1 hour 0 sec')
self.assertEqual(am.process_time(n1 + 61).strip(),
'1 hour 1 min 1 sec')
self.assertEqual(am.process_time(n2 + 1).strip(),
'2 hours 1 sec')
self.assertEqual(am.process_time(n2 + 122).strip(),
'2 hours 2 min 2 sec')
def test_process_time_days(self):
am = self._makeOne()
am.process_start = 0
n1 = 60 * 60 * 24
n2 = n1 * 2
self.assertEqual(am.process_time(n1).strip(),
'1 day 0 sec')
self.assertEqual(am.process_time(n1 + 3661).strip(),
'1 day 1 hour 1 min 1 sec')
self.assertEqual(am.process_time(n2 + 1).strip(),
'2 days 1 sec')
self.assertEqual(am.process_time(n2 + 7322).strip(),
'2 days 2 hours 2 min 2 sec')
def test_thread_get_ident(self):
import thread
am = self._makeOne()
......@@ -408,49 +258,16 @@ class ApplicationManagerTests(ConfigTestBase,
cldir = config.clienthome = self._makeTempdir()
self.assertEqual(am.getCLIENT_HOME(), cldir)
def test_getServers(self):
from asyncore import socket_map
class DummySocketServer:
def __init__(self, port):
self.port = port
class AnotherSocketServer(DummySocketServer):
pass
class NotAServer:
pass
am = self._makeOne()
_old_socket_map = socket_map.copy()
socket_map.clear()
socket_map['foo'] = DummySocketServer(45)
socket_map['bar'] = AnotherSocketServer(57)
socket_map['qux'] = NotAServer()
try:
pairs = am.getServers()
finally:
socket_map.clear()
socket_map.update(_old_socket_map)
self.assertEqual(len(pairs), 2)
self.assertTrue((str(DummySocketServer), 'Port: 45') in pairs)
self.assertTrue((str(AnotherSocketServer), 'Port: 57') in pairs)
#def test_objectIds(self): XXX -- TOO UGLY TO TEST (BBB for Zope 2.3!!)
class AltDatabaseManagerTests(DBProxyTestsBase,
unittest.TestCase,
):
unittest.TestCase):
def _getTargetClass(self):
from App.ApplicationManager import AltDatabaseManager
return AltDatabaseManager
class DummyDBTab:
class DummyDBTab(object):
def __init__(self, databases=None):
self._databases = databases or {}
......@@ -463,7 +280,8 @@ class DummyDBTab:
def getDatabase(self, name):
return self._databases[name]
class DummyDB:
class DummyDB(object):
_packed = None
......@@ -479,12 +297,3 @@ class DummyDB:
def pack(self, when):
self._packed = when
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(FakeConnectionTests),
unittest.makeSuite(DatabaseChooserTests),
unittest.makeSuite(DebugManagerTests),
unittest.makeSuite(ApplicationManagerTests),
unittest.makeSuite(AltDatabaseManagerTests),
))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment