BIND 10 trac547, updated. bf7bda2a551b71f131bf8d95ca45ef532b1e181e [trac547] remove string.py
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Mar 3 13:05:09 UTC 2011
The branch, trac547 has been updated
via bf7bda2a551b71f131bf8d95ca45ef532b1e181e (commit)
via 7d9c8e5363aeafee5b15d587a2233dbaf80928f6 (commit)
via 72b6c3cdcbcf5297e7ef4ffd46320799ff8cdd4f (commit)
via 858f0d41665d750e284408ac55ebc02ce91504ac (commit)
via e954311771da08833401cd3e698544a8b8288091 (commit)
via 2a2995d6a2650f1bb6f6c53cc77601d53f6baf19 (commit)
via 26f636da289309f157ac28ab67a016fe4554a70f (commit)
via fdd873a19a7d67bd43f1eaf3355c70ba7d9ddb28 (commit)
via 50f3d03023dd36acfcea2b9405b4e5f25168b1c9 (commit)
via 4d0dab8ef67ae01be161ef368c51f934c6017e66 (commit)
via 1111b5f422ab15da56579269f068b92faf5dc79d (commit)
via 057191e211d0dd86c59a57978f0ac8de5b2fafda (commit)
via a954e4550249ebe49108712eeafd0dcc5b852c54 (commit)
via b85d775e7a62775f084b1e94c866a9457bd7c1ed (commit)
via 207be0640babf2e8ad7d81c9cc850ce6023f31f0 (commit)
via 1d1b124fe4b1e2dad2e8c26f0a0cde19c73fa11e (commit)
via 357bf09e266d6a4c694d9d74f94ba144750cf51e (commit)
via b984a0fae34280eb0bcbf506cbd64105c031e42e (commit)
via 47c9b44677507ec70ef82f240df9ec083a9c287c (commit)
via 48eef6b51ec20bbd41409b8d07cca611becb2b0f (commit)
via ab9befdaba1a08df36fef216874b71c3b28ecc28 (commit)
via 74854b31f8a0a16b23c8d9ce4460502b37f4a334 (commit)
from 994ee58d6044415ed6e5e463ff601435e8127ccc (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit bf7bda2a551b71f131bf8d95ca45ef532b1e181e
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Mar 3 21:55:00 2011 +0900
[trac547] remove string.py
commit 7d9c8e5363aeafee5b15d587a2233dbaf80928f6
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Mar 3 21:42:31 2011 +0900
[trac547] add more tests for each class to improve coverage
- check HTTP status, header and body of response
- check validations of address and port of both IPv6/4
- check failure case of some methods of Session object with no socket
commit 72b6c3cdcbcf5297e7ef4ffd46320799ff8cdd4f
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Mar 3 21:36:47 2011 +0900
[trac547] fix B10_FROM_SOURCE
commit 858f0d41665d750e284408ac55ebc02ce91504ac
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Mar 3 21:35:39 2011 +0900
[trac547]
- remove unnecessary StreamWriter
- add creating socket object and executing socket.bind() in creating HTTPServer object
- add some getter methods for unittest
- add dummy HTTP response class DummyHttpResponse for unittest
- add dummy writer method as seemed to write file object
commit e954311771da08833401cd3e698544a8b8288091
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Mar 3 21:31:12 2011 +0900
[trac547]
- add dummy SessionTimeout exception
- add raising SeesionError in creating Session object if sokect.error is raised
- remove printing for debug
- add raising SessinError in group_{un,}subscribe
commit 2a2995d6a2650f1bb6f6c53cc77601d53f6baf19
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Mar 3 21:27:54 2011 +0900
[trac547] add some assertions
commit 26f636da289309f157ac28ab67a016fe4554a70f
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Mar 3 21:27:35 2011 +0900
[trac547] fix bug (counting how many the socket is selected)
commit fdd873a19a7d67bd43f1eaf3355c70ba7d9ddb28
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Mar 3 21:24:06 2011 +0900
[trac547]
- add dummy bind function with validation of address and port
- add status of open/closed
- add dummy address_family
commit 50f3d03023dd36acfcea2b9405b4e5f25168b1c9
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Mar 3 21:22:20 2011 +0900
[trac547] remove unnecessary module
commit 4d0dab8ef67ae01be161ef368c51f934c6017e66
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Thu Mar 3 21:21:43 2011 +0900
[trac547]
- add function to close ModuleCCSession object
- remove try/except statement in creating ModuleCCSession object
- add exceptions of OverflowError and TypeError while select.select
- set http socket object and ModuleCCSession object to None after completing their closes
- move except select.error to proper position
- add some minor changes
commit 1111b5f422ab15da56579269f068b92faf5dc79d
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 20:46:55 2011 +0900
[trac547]
- rename spec files
- add global variables of URL
- refactor creating http socket
- add some minor changes
commit 057191e211d0dd86c59a57978f0ac8de5b2fafda
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 20:44:52 2011 +0900
[trac547]
- rename spec files
- move location of spec files from build dir to source dir
commit a954e4550249ebe49108712eeafd0dcc5b852c54
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 20:42:25 2011 +0900
[trac547] remove finally statement
commit b85d775e7a62775f084b1e94c866a9457bd7c1ed
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 20:40:06 2011 +0900
[trac547] remove an unnecessary item
commit 207be0640babf2e8ad7d81c9cc850ce6023f31f0
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 16:30:45 2011 +0900
[trac547] rename
commit 1d1b124fe4b1e2dad2e8c26f0a0cde19c73fa11e
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 16:30:35 2011 +0900
[trac547] rename
commit 357bf09e266d6a4c694d9d74f94ba144750cf51e
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 16:04:59 2011 +0900
[trac547] rename
commit b984a0fae34280eb0bcbf506cbd64105c031e42e
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 16:04:45 2011 +0900
[trac547] change loading JSON-formatted specfile
commit 47c9b44677507ec70ef82f240df9ec083a9c287c
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 16:03:58 2011 +0900
[trac547] add dummy class, function. variables
commit 48eef6b51ec20bbd41409b8d07cca611becb2b0f
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 16:03:05 2011 +0900
[trac547] remove spec files and templates from test directory
commit ab9befdaba1a08df36fef216874b71c3b28ecc28
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 16:02:21 2011 +0900
[trac547] rename
commit 74854b31f8a0a16b23c8d9ce4460502b37f4a334
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Mar 2 16:01:52 2011 +0900
[trac547] rename
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 10 +-
src/bin/stats/Makefile.am | 28 +--
src/bin/stats/run_b10-stats-httpd.sh.in | 4 +-
src/bin/stats/run_b10-stats.sh.in | 4 +-
...httpd-xml.tpl.pre.in => stats-httpd-xml.tpl.in} | 0
...httpd-xsd.tpl.pre.in => stats-httpd-xsd.tpl.in} | 0
...httpd-xsl.tpl.pre.in => stats-httpd-xsl.tpl.in} | 0
src/bin/stats/stats-httpd.spec.in | 34 +++
src/bin/stats/stats.py.in | 9 +-
src/bin/stats/{stats.spec.pre.in => stats.spec.in} | 0
src/bin/stats/stats_httpd.py.in | 220 +++++++-------
src/bin/stats/stats_httpd.spec.pre.in | 68 -----
src/bin/stats/tests/Makefile.am | 6 +-
src/bin/stats/tests/b10-stats-httpd_test.py | 305 +++++++++++++++-----
src/bin/stats/tests/b10-stats_test.py | 14 +-
src/bin/stats/tests/http/server.py | 55 +++-
src/bin/stats/tests/isc/cc/session.py | 15 +-
src/bin/stats/tests/isc/config/ccsession.py | 20 ++-
src/bin/stats/tests/select.py | 8 +-
src/bin/stats/tests/socket.py | 46 +++-
src/bin/stats/tests/stats_test.in | 4 +-
src/bin/stats/tests/string.py | 25 --
src/bin/stats/tests/testdata/Makefile.am | 26 --
23 files changed, 526 insertions(+), 375 deletions(-)
rename src/bin/stats/{stats-httpd-xml.tpl.pre.in => stats-httpd-xml.tpl.in} (100%)
rename src/bin/stats/{stats-httpd-xsd.tpl.pre.in => stats-httpd-xsd.tpl.in} (100%)
rename src/bin/stats/{stats-httpd-xsl.tpl.pre.in => stats-httpd-xsl.tpl.in} (100%)
create mode 100644 src/bin/stats/stats-httpd.spec.in
rename src/bin/stats/{stats.spec.pre.in => stats.spec.in} (100%)
delete mode 100644 src/bin/stats/stats_httpd.spec.pre.in
delete mode 100644 src/bin/stats/tests/string.py
-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 2bb47c2..c097ac0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -738,11 +738,11 @@ AC_OUTPUT([doc/version.ent
src/bin/zonemgr/run_b10-zonemgr.sh
src/bin/stats/stats.py
src/bin/stats/stats_httpd.py
- src/bin/stats/stats.spec.pre
- src/bin/stats/stats_httpd.spec.pre
- src/bin/stats/stats-httpd-xml.tpl.pre
- src/bin/stats/stats-httpd-xsd.tpl.pre
- src/bin/stats/stats-httpd-xsl.tpl.pre
+ src/bin/stats/stats.spec
+ src/bin/stats/stats-httpd.spec
+ src/bin/stats/stats-httpd-xml.tpl
+ src/bin/stats/stats-httpd-xsd.tpl
+ src/bin/stats/stats-httpd-xsl.tpl
src/bin/stats/run_b10-stats.sh
src/bin/stats/run_b10-stats-httpd.sh
src/bin/stats/tests/stats_test
diff --git a/src/bin/stats/Makefile.am b/src/bin/stats/Makefile.am
index 8868b88..f76503e 100644
--- a/src/bin/stats/Makefile.am
+++ b/src/bin/stats/Makefile.am
@@ -5,15 +5,17 @@ pkglibexecdir = $(libexecdir)/@PACKAGE@
pkglibexec_SCRIPTS = b10-stats b10-stats-httpd
b10_statsdir = $(DESTDIR)$(pkgdatadir)
-b10_stats_DATA = stats.spec stats_httpd.spec
+b10_stats_DATA = stats.spec stats-httpd.spec
b10_stats_DATA += stats-httpd-xml.tpl stats-httpd-xsd.tpl stats-httpd-xsl.tpl
-CLEANFILES = b10-stats stats.pyc stats.spec
-CLEANFILES += b10-stats-httpd stats_httpd.pyc stats_httpd.spec
+CLEANFILES = b10-stats stats.pyc stats.spec
+CLEANFILES += b10-stats-httpd stats_httpd.pyc stats-httpd.spec
CLEANFILES += stats-httpd-xml.tpl stats-httpd-xsd.tpl stats-httpd-xsl.tpl
man_MANS = b10-stats.8 b10-stats-httpd.8
EXTRA_DIST = $(man_MANS) b10-stats.xml b10-stats-httpd.xml
+EXTRA_DIST += stats.spec stats-httpd.spec
+EXTRA_DIST += stats-httpd-xml.tpl stats-httpd-xsd.tpl stats-httpd-xsl.tpl
if ENABLE_MAN
@@ -25,26 +27,6 @@ b10-stats-httpd.8: b10-stats-httpd.xml
endif
-stats.spec: stats.spec.pre
- $(SED) -e "s|@@DATAROOTDIR@@|@datarootdir@|" \
- -e "s|@@PACKAGEDIR@@|@PACKAGE@|" stats.spec.pre >$@
-
-stats_httpd.spec: stats_httpd.spec.pre
- $(SED) -e "s|@@DATAROOTDIR@@|@datarootdir@|" \
- -e "s|@@PACKAGEDIR@@|@PACKAGE@|" stats_httpd.spec.pre >$@
-
-stats-httpd-xml.tpl: stats-httpd-xml.tpl.pre
- $(SED) -e "s|@@DATAROOTDIR@@|@datarootdir@|" \
- -e "s|@@PACKAGEDIR@@|@PACKAGE@|" stats-httpd-xml.tpl.pre >$@
-
-stats-httpd-xsd.tpl: stats-httpd-xsd.tpl.pre
- $(SED) -e "s|@@DATAROOTDIR@@|@datarootdir@|" \
- -e "s|@@PACKAGEDIR@@|@PACKAGE@|" stats-httpd-xsd.tpl.pre >$@
-
-stats-httpd-xsl.tpl: stats-httpd-xsl.tpl.pre
- $(SED) -e "s|@@DATAROOTDIR@@|@datarootdir@|" \
- -e "s|@@PACKAGEDIR@@|@PACKAGE@|" stats-httpd-xsl.tpl.pre >$@
-
# TODO: does this need $$(DESTDIR) also?
# this is done here since configure.ac AC_OUTPUT doesn't expand exec_prefix
b10-stats: stats.py
diff --git a/src/bin/stats/run_b10-stats-httpd.sh.in b/src/bin/stats/run_b10-stats-httpd.sh.in
index 0c42dc8..6a20412 100644
--- a/src/bin/stats/run_b10-stats-httpd.sh.in
+++ b/src/bin/stats/run_b10-stats-httpd.sh.in
@@ -26,8 +26,8 @@ export BIND10_MSGQ_SOCKET_FILE
STATS_PATH=@abs_top_builddir@/src/bin/stats
-B10_FROM_BUILD=${STATS_PATH}
-export B10_FROM_BUILD
+B10_FROM_SOURCE=@abs_top_srcdir@/src/bin/stats
+export B10_FROM_SOURCE
cd ${STATS_PATH}
exec ${PYTHON_EXEC} -O b10-stats-httpd "$@"
diff --git a/src/bin/stats/run_b10-stats.sh.in b/src/bin/stats/run_b10-stats.sh.in
index d41e8f0..4bffd4c 100644
--- a/src/bin/stats/run_b10-stats.sh.in
+++ b/src/bin/stats/run_b10-stats.sh.in
@@ -26,8 +26,8 @@ export BIND10_MSGQ_SOCKET_FILE
STATS_PATH=@abs_top_builddir@/src/bin/stats
-B10_FROM_BUILD=${STATS_PATH}
-export B10_FROM_BUILD
+B10_FROM_SOURCE=@abs_top_srcdir@/src/bin/stats
+export B10_FROM_SOURCE
cd ${STATS_PATH}
exec ${PYTHON_EXEC} -O b10-stats "$@"
diff --git a/src/bin/stats/stats-httpd-xml.tpl.in b/src/bin/stats/stats-httpd-xml.tpl.in
new file mode 100644
index 0000000..7f2cb68
--- /dev/null
+++ b/src/bin/stats/stats-httpd-xml.tpl.in
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?xml-stylesheet type="text/xsl" href="bind10-statistics.xsl"?>
+<!--
+ - Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<stats:stats_data version="1.0"
+ xmlns:stats="http://bind10.isc.org/xsd/bind10-statistics"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://bind10.isc.org/xsd/bind10-statistics bind10-statistics.xsd">
+ $xml_string
+</stats:stats_data>
diff --git a/src/bin/stats/stats-httpd-xml.tpl.pre.in b/src/bin/stats/stats-httpd-xml.tpl.pre.in
deleted file mode 100644
index 7f2cb68..0000000
--- a/src/bin/stats/stats-httpd-xml.tpl.pre.in
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<?xml-stylesheet type="text/xsl" href="bind10-statistics.xsl"?>
-<!--
- - Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
- -
- - Permission to use, copy, modify, and/or distribute this software for any
- - purpose with or without fee is hereby granted, provided that the above
- - copyright notice and this permission notice appear in all copies.
- -
- - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- - PERFORMANCE OF THIS SOFTWARE.
--->
-
-<stats:stats_data version="1.0"
- xmlns:stats="http://bind10.isc.org/xsd/bind10-statistics"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://bind10.isc.org/xsd/bind10-statistics bind10-statistics.xsd">
- $xml_string
-</stats:stats_data>
diff --git a/src/bin/stats/stats-httpd-xsd.tpl.in b/src/bin/stats/stats-httpd-xsd.tpl.in
new file mode 100644
index 0000000..469140f
--- /dev/null
+++ b/src/bin/stats/stats-httpd-xsd.tpl.in
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ - Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<schema targetNamespace="http://bind10.isc.org/xsd/bind10-statistics"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:stats="http://bind10.isc.org/xsd/bind10-statistics">
+ <annotation>
+ <documentation xml:lang="en">XML schema of the statistics
+ data in BIND 10</documentation>
+ </annotation>
+ <element name="stats_data">
+ <annotation>
+ <documentation>A set of statistics data</documentation>
+ </annotation>
+ <complexType>
+ $xsd_string
+ <attribute name="version" type="token" use="optional" default="1.0">
+ <annotation>
+ <documentation>Version number of syntax</documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+</schema>
diff --git a/src/bin/stats/stats-httpd-xsd.tpl.pre.in b/src/bin/stats/stats-httpd-xsd.tpl.pre.in
deleted file mode 100644
index 469140f..0000000
--- a/src/bin/stats/stats-httpd-xsd.tpl.pre.in
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- - Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
- -
- - Permission to use, copy, modify, and/or distribute this software for any
- - purpose with or without fee is hereby granted, provided that the above
- - copyright notice and this permission notice appear in all copies.
- -
- - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- - PERFORMANCE OF THIS SOFTWARE.
--->
-
-<schema targetNamespace="http://bind10.isc.org/xsd/bind10-statistics"
- xmlns="http://www.w3.org/2001/XMLSchema"
- xmlns:stats="http://bind10.isc.org/xsd/bind10-statistics">
- <annotation>
- <documentation xml:lang="en">XML schema of the statistics
- data in BIND 10</documentation>
- </annotation>
- <element name="stats_data">
- <annotation>
- <documentation>A set of statistics data</documentation>
- </annotation>
- <complexType>
- $xsd_string
- <attribute name="version" type="token" use="optional" default="1.0">
- <annotation>
- <documentation>Version number of syntax</documentation>
- </annotation>
- </attribute>
- </complexType>
- </element>
-</schema>
diff --git a/src/bin/stats/stats-httpd-xsl.tpl.in b/src/bin/stats/stats-httpd-xsl.tpl.in
new file mode 100644
index 0000000..9354c78
--- /dev/null
+++ b/src/bin/stats/stats-httpd-xsl.tpl.in
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ - Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:stats="http://bind10.isc.org/xsd/bind10-statistics">
+ <xsl:output method="html" encoding="UTF-8"
+ doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
+ doctype-system=" http://www.w3.org/TR/html4/loose.dtd " />
+ <xsl:template match="/">
+ <html lang="en">
+ <head>
+ <title>BIND 10 Statistics</title>
+ <style type="text/css"><![CDATA[
+table {
+ border: 1px #000000 solid;
+ border-collapse: collapse;
+}
+td, th {
+ padding: 3px 20px;
+ border: 1px #000000 solid;
+}
+]]>
+ </style>
+ </head>
+ <body>
+ <h1>BIND 10 Statistics</h1>
+ <table>
+ <tr>
+ <th>Title</th>
+ <th>Value</th>
+ </tr>
+ <xsl:apply-templates />
+ </table>
+ </body>
+ </html>
+ </xsl:template>
+ $xsl_string
+</xsl:stylesheet>
diff --git a/src/bin/stats/stats-httpd-xsl.tpl.pre.in b/src/bin/stats/stats-httpd-xsl.tpl.pre.in
deleted file mode 100644
index 9354c78..0000000
--- a/src/bin/stats/stats-httpd-xsl.tpl.pre.in
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- - Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
- -
- - Permission to use, copy, modify, and/or distribute this software for any
- - purpose with or without fee is hereby granted, provided that the above
- - copyright notice and this permission notice appear in all copies.
- -
- - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- - PERFORMANCE OF THIS SOFTWARE.
--->
-
-<xsl:stylesheet version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"
- xmlns:stats="http://bind10.isc.org/xsd/bind10-statistics">
- <xsl:output method="html" encoding="UTF-8"
- doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
- doctype-system=" http://www.w3.org/TR/html4/loose.dtd " />
- <xsl:template match="/">
- <html lang="en">
- <head>
- <title>BIND 10 Statistics</title>
- <style type="text/css"><![CDATA[
-table {
- border: 1px #000000 solid;
- border-collapse: collapse;
-}
-td, th {
- padding: 3px 20px;
- border: 1px #000000 solid;
-}
-]]>
- </style>
- </head>
- <body>
- <h1>BIND 10 Statistics</h1>
- <table>
- <tr>
- <th>Title</th>
- <th>Value</th>
- </tr>
- <xsl:apply-templates />
- </table>
- </body>
- </html>
- </xsl:template>
- $xsl_string
-</xsl:stylesheet>
diff --git a/src/bin/stats/stats-httpd.spec.in b/src/bin/stats/stats-httpd.spec.in
new file mode 100644
index 0000000..d769752
--- /dev/null
+++ b/src/bin/stats/stats-httpd.spec.in
@@ -0,0 +1,34 @@
+{
+ "module_spec": {
+ "module_name": "StatsHttpd",
+ "module_description": "Stats HTTP daemon",
+ "config_data": [
+ {
+ "item_name": "listen_on_address",
+ "item_type": "string",
+ "item_optional": true,
+ "item_default": "127.0.0.1",
+ "item_description": "http listen-on address"
+ },
+ {
+ "item_name": "listen_on_port",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 8000,
+ "item_description": "http listen-on port"
+ }
+ ],
+ "commands": [
+ {
+ "command_name": "status",
+ "command_description": "Status of the stats httpd",
+ "command_args": []
+ },
+ {
+ "command_name": "shutdown",
+ "command_description": "Shut down the stats httpd",
+ "command_args": []
+ }
+ ]
+ }
+}
diff --git a/src/bin/stats/stats.py.in b/src/bin/stats/stats.py.in
index dbfde35..ecf8f99 100755
--- a/src/bin/stats/stats.py.in
+++ b/src/bin/stats/stats.py.in
@@ -35,15 +35,16 @@ if __name__ == 'stats': #@@REMOVED@@
import isc.util.process
isc.util.process.rename()
-# If B10_FROM_BUILD is set in the environment, we use data files
+# If B10_FROM_SOURCE is set in the environment, we use data files
# from a directory relative to that, otherwise we use the ones
# installed on the system
-if "B10_FROM_BUILD" in os.environ:
- SPECFILE_LOCATION = os.environ["B10_FROM_BUILD"] + os.sep + "stats.spec"
+if "B10_FROM_SOURCE" in os.environ:
+ SPECFILE_LOCATION = os.environ["B10_FROM_SOURCE"] + os.sep + "stats.spec"
else:
PREFIX = "@prefix@"
DATAROOTDIR = "@datarootdir@"
- SPECFILE_LOCATION = "@datadir@/@PACKAGE@/stats.spec".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
+ SPECFILE_LOCATION = "@datadir@" + os.sep + "@PACKAGE@" + os.sep + "stats.spec"
+ SPECFILE_LOCATION = SPECFILE_LOCATION.replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
class Singleton(type):
"""
diff --git a/src/bin/stats/stats.spec.in b/src/bin/stats/stats.spec.in
new file mode 100644
index 0000000..4d42ebf
--- /dev/null
+++ b/src/bin/stats/stats.spec.in
@@ -0,0 +1,140 @@
+{
+ "module_spec": {
+ "module_name": "Stats",
+ "module_description": "Stats daemon",
+ "config_data": [
+ {
+ "item_name": "report_time",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": "1970-01-01T00:00:00Z",
+ "item_title": "Report time",
+ "item_description": "A date time when stats module reports",
+ "item_format": "date-time"
+ },
+ {
+ "item_name": "bind10.boot_time",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": "1970-01-01T00:00:00Z",
+ "item_title": "bind10.BootTime",
+ "item_description": "A date time when bind10 process starts initially",
+ "item_format": "date-time"
+ },
+ {
+ "item_name": "stats.boot_time",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": "1970-01-01T00:00:00Z",
+ "item_title": "stats.BootTime",
+ "item_description": "A date time when the stats module starts initially or when the stats module restarts",
+ "item_format": "date-time"
+ },
+ {
+ "item_name": "stats.start_time",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": "1970-01-01T00:00:00Z",
+ "item_title": "stats.StartTime",
+ "item_description": "A date time when the stats module starts collecting data or resetting values last time",
+ "item_format": "date-time"
+ },
+ {
+ "item_name": "stats.last_update_time",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": "1970-01-01T00:00:00Z",
+ "item_title": "stats.LastUpdateTime",
+ "item_description": "The latest date time when the stats module receives from other modules like auth server or boss process and so on",
+ "item_format": "date-time"
+ },
+ {
+ "item_name": "stats.timestamp",
+ "item_type": "real",
+ "item_optional": false,
+ "item_default": 0.0,
+ "item_title": "stats.Timestamp",
+ "item_description": "A current time stamp since epoch time (1970-01-01T00:00:00Z)",
+ "item_format": "second"
+ },
+ {
+ "item_name": "stats.lname",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": "",
+ "item_title": "stats.LocalName",
+ "item_description": "A localname of stats module given via CC protocol"
+ },
+ {
+ "item_name": "auth.queries.tcp",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 0,
+ "item_title": "auth.queries.tcp",
+ "item_description": "A number of total query counts which all auth servers receive over TCP since they started initially"
+ },
+ {
+ "item_name": "auth.queries.udp",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 0,
+ "item_title": "auth.queries.udp",
+ "item_description": "A number of total query counts which all auth servers receive over UDP since they started initially"
+ }
+ ],
+ "commands": [
+ {
+ "command_name": "status",
+ "command_description": "identify whether stats module is alive or not",
+ "command_args": []
+ },
+ {
+ "command_name": "show",
+ "command_description": "show the specified/all statistics data",
+ "command_args": [
+ {
+ "item_name": "stats_item_name",
+ "item_type": "string",
+ "item_optional": true,
+ "item_default": ""
+ }
+ ]
+ },
+ {
+ "command_name": "set",
+ "command_description": "set the value of specified name in statistics data",
+ "command_args": [
+ {
+ "item_name": "stats_data",
+ "item_type": "map",
+ "item_optional": false,
+ "item_default": {},
+ "map_item_spec": []
+ }
+ ]
+ },
+ {
+ "command_name": "remove",
+ "command_description": "remove the specified name from statistics data",
+ "command_args": [
+ {
+ "item_name": "stats_item_name",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": ""
+ }
+ ]
+ },
+ {
+ "command_name": "reset",
+ "command_description": "reset all statistics data to default values except for several constant names",
+ "command_args": []
+ },
+ {
+ "command_name": "shutdown",
+ "command_description": "Shut down the stats module",
+ "command_args": []
+ }
+ ]
+ }
+}
diff --git a/src/bin/stats/stats.spec.pre.in b/src/bin/stats/stats.spec.pre.in
deleted file mode 100644
index 4d42ebf..0000000
--- a/src/bin/stats/stats.spec.pre.in
+++ /dev/null
@@ -1,140 +0,0 @@
-{
- "module_spec": {
- "module_name": "Stats",
- "module_description": "Stats daemon",
- "config_data": [
- {
- "item_name": "report_time",
- "item_type": "string",
- "item_optional": false,
- "item_default": "1970-01-01T00:00:00Z",
- "item_title": "Report time",
- "item_description": "A date time when stats module reports",
- "item_format": "date-time"
- },
- {
- "item_name": "bind10.boot_time",
- "item_type": "string",
- "item_optional": false,
- "item_default": "1970-01-01T00:00:00Z",
- "item_title": "bind10.BootTime",
- "item_description": "A date time when bind10 process starts initially",
- "item_format": "date-time"
- },
- {
- "item_name": "stats.boot_time",
- "item_type": "string",
- "item_optional": false,
- "item_default": "1970-01-01T00:00:00Z",
- "item_title": "stats.BootTime",
- "item_description": "A date time when the stats module starts initially or when the stats module restarts",
- "item_format": "date-time"
- },
- {
- "item_name": "stats.start_time",
- "item_type": "string",
- "item_optional": false,
- "item_default": "1970-01-01T00:00:00Z",
- "item_title": "stats.StartTime",
- "item_description": "A date time when the stats module starts collecting data or resetting values last time",
- "item_format": "date-time"
- },
- {
- "item_name": "stats.last_update_time",
- "item_type": "string",
- "item_optional": false,
- "item_default": "1970-01-01T00:00:00Z",
- "item_title": "stats.LastUpdateTime",
- "item_description": "The latest date time when the stats module receives from other modules like auth server or boss process and so on",
- "item_format": "date-time"
- },
- {
- "item_name": "stats.timestamp",
- "item_type": "real",
- "item_optional": false,
- "item_default": 0.0,
- "item_title": "stats.Timestamp",
- "item_description": "A current time stamp since epoch time (1970-01-01T00:00:00Z)",
- "item_format": "second"
- },
- {
- "item_name": "stats.lname",
- "item_type": "string",
- "item_optional": false,
- "item_default": "",
- "item_title": "stats.LocalName",
- "item_description": "A localname of stats module given via CC protocol"
- },
- {
- "item_name": "auth.queries.tcp",
- "item_type": "integer",
- "item_optional": false,
- "item_default": 0,
- "item_title": "auth.queries.tcp",
- "item_description": "A number of total query counts which all auth servers receive over TCP since they started initially"
- },
- {
- "item_name": "auth.queries.udp",
- "item_type": "integer",
- "item_optional": false,
- "item_default": 0,
- "item_title": "auth.queries.udp",
- "item_description": "A number of total query counts which all auth servers receive over UDP since they started initially"
- }
- ],
- "commands": [
- {
- "command_name": "status",
- "command_description": "identify whether stats module is alive or not",
- "command_args": []
- },
- {
- "command_name": "show",
- "command_description": "show the specified/all statistics data",
- "command_args": [
- {
- "item_name": "stats_item_name",
- "item_type": "string",
- "item_optional": true,
- "item_default": ""
- }
- ]
- },
- {
- "command_name": "set",
- "command_description": "set the value of specified name in statistics data",
- "command_args": [
- {
- "item_name": "stats_data",
- "item_type": "map",
- "item_optional": false,
- "item_default": {},
- "map_item_spec": []
- }
- ]
- },
- {
- "command_name": "remove",
- "command_description": "remove the specified name from statistics data",
- "command_args": [
- {
- "item_name": "stats_item_name",
- "item_type": "string",
- "item_optional": false,
- "item_default": ""
- }
- ]
- },
- {
- "command_name": "reset",
- "command_description": "reset all statistics data to default values except for several constant names",
- "command_args": []
- },
- {
- "command_name": "shutdown",
- "command_description": "Shut down the stats module",
- "command_args": []
- }
- ]
- }
-}
diff --git a/src/bin/stats/stats_httpd.py.in b/src/bin/stats/stats_httpd.py.in
index d12c775..29a526d 100644
--- a/src/bin/stats/stats_httpd.py.in
+++ b/src/bin/stats/stats_httpd.py.in
@@ -30,15 +30,24 @@ import isc.cc
import isc.config
import isc.util.process
-# If B10_FROM_BUILD is set in the environment, we use data files
+# If B10_FROM_SOURCE is set in the environment, we use data files
# from a directory relative to that, otherwise we use the ones
# installed on the system
-if "B10_FROM_BUILD" in os.environ:
- SPECFILE_LOCATION = os.environ["B10_FROM_BUILD"] + os.sep + "stats_httpd.spec"
+if "B10_FROM_SOURCE" in os.environ:
+ BASE_LOCATION = os.environ["B10_FROM_SOURCE"]
else:
PREFIX = "@prefix@"
DATAROOTDIR = "@datarootdir@"
- SPECFILE_LOCATION = "@datadir@/@PACKAGE@/stats_httpd.spec".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
+ BASE_LOCATION = "@datadir@" + os.sep + "@PACKAGE@"
+ BASE_LOCATION = BASE_LOCATION.replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
+SPECFILE_LOCATION = BASE_LOCATION + os.sep + "stats-httpd.spec"
+STATS_SPECFILE_LOCATION = BASE_LOCATION + os.sep + "stats.spec"
+XML_TEMPLATE_LOCATION = BASE_LOCATION + os.sep + "stats-httpd-xml.tpl"
+XSD_TEMPLATE_LOCATION = BASE_LOCATION + os.sep + "stats-httpd-xsd.tpl"
+XSL_TEMPLATE_LOCATION = BASE_LOCATION + os.sep + "stats-httpd-xsl.tpl"
+XML_URL_PATH = '/'
+XSD_URL_PATH = '/bind10-statistics.xsd'
+XSL_URL_PATH = '/bind10-statistics.xsl'
MAX_SIZE_OF_TEMPLATE = 102400 # under 100k
@@ -58,13 +67,12 @@ class HttpHandler(http.server.BaseHTTPRequestHandler):
self.send_head()
def send_head(self):
- contents = ''
try:
- if self.path == '/':
+ if self.path == XML_URL_PATH:
contents = self.server.stats_httpd.get_stats_xml()
- elif self.path == '/bind10-statistics.xsd':
+ elif self.path == XSD_URL_PATH:
contents = self.server.stats_httpd.get_stats_xsd()
- elif self.path == '/bind10-statistics.xsl':
+ elif self.path == XSL_URL_PATH:
contents = self.server.stats_httpd.get_stats_xsl()
else:
self.send_error(404)
@@ -77,12 +85,11 @@ class HttpHandler(http.server.BaseHTTPRequestHandler):
self.send_header("Content-type", "text/xml")
self.send_header("Content-Length", len(contents))
self.end_headers()
- assert contents is not None and contents != ''
return contents
def log_message(self, format, *args):
"""
- Change default log format
+ Change the default log format
"""
if self.server.verbose:
self.server.stats_httpd.write_log(
@@ -112,67 +119,72 @@ class StatsHttpd:
def __init__(self, verbose=False):
self.verbose = verbose
self.running = True
- self.exit_code = 0
self.poll_intval = 0.5
self.write_log = sys.stderr.write
- self.ccs = None
+ self.mccs = None
+ self.httpd = None
try:
+ self.open_mccs()
self.load_config()
+ self.load_templates()
self.open_httpd()
except StatsHttpdError as err:
- self.write_log(
- "[b10-stats-httpd] Unexpected error with initializing: %s" % err)
- self.running = False
- self.exit_code = 1
+ raise StatsHttpdError(
+ "error with initializing StatsHttpd: %s" % err)
- def load_config(self, new_config=None):
+ def open_mccs(self):
# create ModuleCCSession
+ self.mccs = isc.config.ModuleCCSession(
+ SPECFILE_LOCATION, self.config_handler, self.command_handler)
+ self.mccs_fd = self.mccs.get_socket()
+ self.cc_session = self.mccs._session
+ self.stats_module_spec = isc.config.module_spec_from_file(STATS_SPECFILE_LOCATION)
+ self.stats_config_spec = self.stats_module_spec.get_config_spec()
+ self.stats_module_name = self.stats_module_spec.get_module_name()
+
+ def close_mccs(self):
+ if self.mccs is None:
+ return
try:
- if self.ccs is None:
- # create ccsession
- self.ccs = isc.config.ModuleCCSession(
- SPECFILE_LOCATION, self.config_handler, self.command_handler)
- self.ccs_fd = self.ccs.get_socket()
- self.cc_session = self.ccs._session
- except isc.config.ccsession.ModuleCCSessionError as err:
- raise StatsHttpdError(err)
+ self.cc_session.group_unsubscribe(self.stats_module_name, "*")
+ except isc.cc.session.SessionError as err:
+ raise StatsHttpdError("error in CCSession: %s\n" % err)
+ self.mccs.close()
+ self.mccs = None
+
+ def load_config(self, new_config=None):
# load config
if new_config is not None:
assert type(new_config) is dict
assert self.config is not None
self.config.update(new_config)
else:
- self.config={}
- self.config.update(
- dict([
- (i['item_name'], self.ccs.get_value(i['item_name'])[0])
- for i in self.ccs.get_module_spec().get_config_spec()
- ]))
- assert self.config is not None
- assert len(self.config) > 0
- assert type(self.config) is dict
- self.stats_module_spec = isc.config.module_spec_from_file(self.config['stats_spec_file'])
- self.stats_config_spec = self.stats_module_spec.get_config_spec()
- self.stats_module_name = self.stats_module_spec.get_module_name()
+ self.config = dict([
+ (i['item_name'], self.mccs.get_value(i['item_name'])[0])
+ for i in self.mccs.get_module_spec().get_config_spec()
+ ])
+ assert self.config is not None and len(self.config) > 0 and type(self.config) is dict
+ assert 'listen_on_address' in self.config
+ assert 'listen_on_port' in self.config
self.http_addr = self.config['listen_on_address']
self.http_port = self.config['listen_on_port']
- # load xml files
- self.load_xml(self.config['xml_template'])
- self.load_xsd(self.config['xsd_template'])
- self.load_xsl(self.config['xsl_template'])
- def open_httpd(self, address_family=socket.AF_INET):
+ def open_httpd(self, address_family=None):
try:
- # try IPv4 at first
- HttpServer.address_family = address_family
+ # try IPv6 as default
+ if address_family is None and socket.has_ipv6:
+ HttpServer.address_family = socket.AF_INET6
+ elif address_family is not None:
+ HttpServer.address_family = address_family
self.httpd = HttpServer(HttpHandler, self, self.verbose)
- except (socket.gaierror, socket.error) as err:
- if type(err) is socket.gaierror and socket.has_ipv6 and HttpServer.address_family is socket.AF_INET:
- # try IPv6 again
- self.open_httpd(address_family=socket.AF_INET6)
+ except (socket.gaierror, socket.error,
+ OverflowError, TypeError) as err:
+ if HttpServer.address_family == socket.AF_INET6:
+ # try IPv4
+ self.open_httpd(address_family=socket.AF_INET)
else:
raise StatsHttpdError(
- "Unexpected error: Invalid address %s: %s: %s\n" %
+ "Invalid address %s: %s: %s\n" %
(self.http_addr, self.http_port, err))
else:
self.http_fd = self.httpd.socket
@@ -182,35 +194,34 @@ class StatsHttpd:
(self.http_addr, self.http_port))
def close_httpd(self):
- if self.http_fd is not None:
- self.http_fd.close()
+ if self.httpd is None:
+ return
+ self.http_fd.close()
+ self.httpd = None
def start(self):
try:
- self.ccs.start()
+ self.mccs.start()
self.cc_session.group_subscribe(self.stats_module_name, "*")
while self.running:
- (rfd, wfd, xfd) = select.select(
- [self.ccs_fd, self.http_fd], [], [], self.poll_intval)
+ try:
+ (rfd, wfd, xfd) = select.select(
+ [self.mccs_fd, self.http_fd], [], [], self.poll_intval)
+ except select.error as err:
+ if err.args[0] == errno.EINTR:
+ (rfd, wfd, xfd) = ([], [], [])
+ else:
+ raise StatsHttpdError(err)
for fd in rfd + xfd:
- if fd == self.ccs_fd:
- self.ccs.check_command(nonblock=False)
+ if fd == self.mccs_fd:
+ self.mccs.check_command(nonblock=False)
elif fd == self.http_fd:
self.httpd.handle_request()
except (isc.cc.session.SessionError,
isc.config.ccsession.ModuleCCSessionError) as err:
- self.write_log(
- "[b10-stats-httpd] Unexpected error with CCSession; %s\n" % err)
- self.running = False
- self.exit_code = 1
- except (select.error, StatsHttpdError) as err:
- if type(err) is select.error and err.args[0] == errno.EINTR:
- (rfd, wfd, xfd) = ([], [], [])
- else:
- self.write_log(
- "[b10-stats-httpd] Unexpected error with selecting; %s\n" % err)
- self.exit_code = 1
- self.running = False
+ raise StatsHttpdError("error in CCSession: %s\n" % err)
+ except StatsHttpdError as err:
+ raise StatsHttpdError("error with selecting; %s\n" % err)
finally:
self.stop()
@@ -218,9 +229,8 @@ class StatsHttpd:
if self.verbose:
self.write_log("[b10-stats-httpd] Shutting down\n")
self.running = False
- self.cc_session.group_unsubscribe(self.stats_module_name, "*")
self.close_httpd()
- self.cc_session.close()
+ self.close_mccs()
def __del__(self):
self.stop()
@@ -230,18 +240,17 @@ class StatsHttpd:
config handler
"""
if self.verbose:
- self.write_log("[b10-stats-httpd] Reloading new config : %s\n" % str(new_config))
+ self.write_log("[b10-stats-httpd] Loading new config : %s\n" % str(new_config))
self.close_httpd()
try:
self.load_config(new_config)
self.open_httpd()
except StatsHttpdError as err:
- self.write_log(
- "[b10-stats-httpd] Unexpected error with reloading config: %s" % err)
- self.running = False
- self.exit_code = 1
+ if self.verbose:
+ self.write_log(
+ "[b10-stats-httpd] Unexpected error with reloading new config: %s" % err)
return isc.config.ccsession.create_answer(
- 1, "Unexpected error with reading config: %s" % err )
+ 1, "Unexpected error with reloading new config: %s" % err)
else:
return isc.config.ccsession.create_answer(0)
@@ -258,7 +267,8 @@ class StatsHttpd:
if self.verbose:
self.write_log("[b10-stats-httpd] Received 'shutdown' command\n")
self.running = False
- return isc.config.ccsession.create_answer(0)
+ return isc.config.ccsession.create_answer(
+ 0, "Stats Httpd is shutting down.")
else:
if self.verbose:
self.write_log("[b10-stats-httpd] Received unknown command\n")
@@ -275,21 +285,14 @@ class StatsHttpd:
(rcode, value) = isc.config.ccsession.parse_answer(answer)
self.cc_session.group_reply(
env, isc.config.ccsession.create_answer(0))
- except isc.cc.SessionTimeout as err:
- raise StatsHttpdError(
- "Unexpected error with stats: SessionTimeout: %s" % err)
- except isc.cc.session.SessionError as err:
- raise StatsHttpdError(
- "Unexpected error with stats: SessionError: %s" % err)
- except isc.config.ccsession.ModuleCCSessionError as err:
- raise StatsHttpdError(
- "Unexpected error with stats: ModuleCCSessionError: %s" % err)
+ except (isc.cc.SessionTimeout,
+ isc.cc.session.SessionError) as err:
+ raise StatsHttpdError(err)
else:
- if rcode != 0:
- raise StatsHttpdError("Unexpected error: can't get data from stats")
- finally:
- assert value is not None
- return value
+ if rcode == 0:
+ return value
+ else:
+ raise StatsHttpdError("can't the stats data")
def get_stats_spec(self):
"""
@@ -297,13 +300,17 @@ class StatsHttpd:
"""
return self.stats_config_spec
- def load_xml(self, template):
- self.xml_template = self.read_template(template)
- self.xml_content = "" # set empty string here
+ def load_templates(self):
+ # open templates
+ self.xml_content = ""
+ self.xsd_content = ""
+ self.xsl_content = ""
+ self.xml_template = self.open_template(XML_TEMPLATE_LOCATION)
+ self.xsd_template = self.open_template(XSD_TEMPLATE_LOCATION)
+ self.xsl_template = self.open_template(XSL_TEMPLATE_LOCATION)
- def load_xsd(self, template):
- self.xsd_template = self.read_template(template)
- root = xml.etree.ElementTree.Element("all") # started with "all" tag
+ # for XSD
+ xsd_root = xml.etree.ElementTree.Element("all") # started with "all" tag
for item in self.get_stats_spec():
element = xml.etree.ElementTree.Element(
"element",
@@ -320,15 +327,14 @@ class StatsHttpd:
annotation.append(appinfo)
annotation.append(documentation)
element.append(annotation)
- root.append(element)
- xsd_string = xml.etree.ElementTree.tostring(root)
+ xsd_root.append(element)
+ xsd_string = xml.etree.ElementTree.tostring(xsd_root)
assert self.xsd_template is not None
self.xsd_content = self.xsd_template.substitute(
xsd_string=xsd_string)
- def load_xsl(self, template):
- self.xsl_template = self.read_template(template)
- root = xml.etree.ElementTree.Element(
+ # for XSL
+ xsd_root = xml.etree.ElementTree.Element(
"xsl:template",
dict(match="*")) # started with xml:template tag
for item in self.get_stats_spec():
@@ -343,8 +349,8 @@ class StatsHttpd:
td2.append(xsl_valueof)
tr.append(td1)
tr.append(td2)
- root.append(tr)
- xsl_string = xml.etree.ElementTree.tostring(root)
+ xsd_root.append(tr)
+ xsl_string = xml.etree.ElementTree.tostring(xsd_root)
assert self.xsl_template is not None
self.xsl_content = self.xsl_template.substitute(
xsl_string=xsl_string)
@@ -371,12 +377,12 @@ class StatsHttpd:
def get_stats_xsl(self):
return self.xsl_content
- def read_template(self, file_name):
+ def open_template(self, file_name):
try:
contents = "".join(
open(file_name, 'r').readlines(MAX_SIZE_OF_TEMPLATE))
except IOError as err:
- raise StatsHttpdError("Unexpected error with opening file; %s" % err)
+ raise StatsHttpdError("error in opening file; %s" % err)
else:
return string.Template(contents)
@@ -396,5 +402,3 @@ if __name__ == "__main__":
+ "is the command channel daemon running?\n")
except KeyboardInterrupt as kie:
sys.stderr.write("[b10-stats-httpd] Interrupted, exiting\n")
- finally:
- sys.exit(stats_httpd.exit_code)
diff --git a/src/bin/stats/stats_httpd.spec.pre.in b/src/bin/stats/stats_httpd.spec.pre.in
deleted file mode 100644
index 956ea95..0000000
--- a/src/bin/stats/stats_httpd.spec.pre.in
+++ /dev/null
@@ -1,68 +0,0 @@
-{
- "module_spec": {
- "module_name": "StatsHttpd",
- "module_description": "Stats HTTP daemon",
- "config_data": [
- {
- "item_name": "stats_spec_file",
- "item_type": "string",
- "item_optional": false,
- "item_default": "@@DATAROOTDIR@@/@@PACKAGEDIR@@/stats.spec",
- "item_description": "the location of stats.spec",
- "item_format": "filename"
- },
- {
- "item_name": "xml_template",
- "item_type": "string",
- "item_optional": false,
- "item_default": "@@DATAROOTDIR@@/@@PACKAGEDIR@@/stats-httpd-xml.tpl",
- "item_description": "the location of xml template",
- "item_format": "filename"
- },
- {
- "item_name": "xsd_template",
- "item_type": "string",
- "item_optional": false,
- "item_default": "@@DATAROOTDIR@@/@@PACKAGEDIR@@/stats-httpd-xsd.tpl",
- "item_description": "the location of xsd template",
- "item_format": "filename"
- },
- {
- "item_name": "xsl_template",
- "item_type": "string",
- "item_optional": false,
- "item_default": "@@DATAROOTDIR@@/@@PACKAGEDIR@@/stats-httpd-xsl.tpl",
- "item_description": "the location of xsl template",
- "item_format": "filename"
- },
- {
- "item_name": "listen_on_address",
- "item_type": "string",
- "item_optional": true,
- "item_default": "127.0.0.1",
- "item_description": "http listen-on address",
- "item_format": "address"
- },
- {
- "item_name": "listen_on_port",
- "item_type": "integer",
- "item_optional": false,
- "item_default": 8000,
- "item_description": "http listen-on port",
- "item_format": "port"
- }
- ],
- "commands": [
- {
- "command_name": "status",
- "command_description": "identify whether the stats httpd is alive or not",
- "command_args": []
- },
- {
- "command_name": "shutdown",
- "command_description": "Shut down the stats httpd",
- "command_args": []
- }
- ]
- }
-}
diff --git a/src/bin/stats/tests/Makefile.am b/src/bin/stats/tests/Makefile.am
index 070ba45..9617027 100644
--- a/src/bin/stats/tests/Makefile.am
+++ b/src/bin/stats/tests/Makefile.am
@@ -1,8 +1,8 @@
SUBDIRS = isc http testdata
PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
PYTESTS = b10-stats_test.py b10-stats-httpd_test.py
-EXTRA_DIST = $(PYTESTS) fake_time.py socket.py select.py string.py
-CLEANFILES = fake_time.pyc socket.pyc select.pyc string.pyc
+EXTRA_DIST = $(PYTESTS) fake_time.py socket.py select.py
+CLEANFILES = fake_time.pyc socket.pyc select.pyc
# test using command-line arguments, so use check-local target instead of TESTS
check-local:
@@ -14,6 +14,6 @@ endif
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/bin/stats:$(abs_top_builddir)/src/bin/stats/tests \
- B10_FROM_BUILD=$(abs_builddir)/testdata \
+ B10_FROM_SOURCE=$(abs_top_srcdir)/src/bin/stats \
$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
done
diff --git a/src/bin/stats/tests/b10-stats-httpd_test.py b/src/bin/stats/tests/b10-stats-httpd_test.py
index 0854306..082f603 100644
--- a/src/bin/stats/tests/b10-stats-httpd_test.py
+++ b/src/bin/stats/tests/b10-stats-httpd_test.py
@@ -20,59 +20,248 @@ import string
import select
import imp
import sys
+import socket
import isc.cc
import stats_httpd
+DUMMY_DATA = {
+ "auth.queries.tcp": 0,
+ "auth.queries.udp": 0,
+ "bind10.boot_time": "1970-01-01T00:00:00Z",
+ "report_time": "2011-02-24T09:08:32Z",
+ "stats.boot_time": "2011-02-24T09:08:21Z",
+ "stats.last_update_time": "2011-02-24T09:08:21Z",
+ "stats.lname": "4d662005_a at fdvm",
+ "stats.start_time": "2011-02-24T09:08:21Z",
+ "stats.timestamp": 1298538512.87378
+ }
+
+def push_answer(stats_httpd):
+ stats_httpd.cc_session.group_sendmsg(
+ { 'result':
+ [ 0, DUMMY_DATA ] }, "Stats")
+
+def pull_query(stats_httpd):
+ (msg, env) = stats_httpd.cc_session.group_recvmsg()
+ if 'result' in msg:
+ (ret, arg) = isc.config.ccsession.parse_answer(msg)
+ else:
+ (ret, arg) = isc.config.ccsession.parse_command(msg)
+ return (ret, arg, env)
+
+class TestHttpHandler(unittest.TestCase):
+
+ def setUp(self):
+ self.verbose = True
+ self.stats_httpd = stats_httpd.StatsHttpd(self.verbose)
+ self.handler = stats_httpd.HttpHandler(None, None, self.stats_httpd.httpd)
+ self.assertTrue(self.stats_httpd.httpd.verbose)
+ self.stats_httpd.cc_session.verbose = False
+
+ def test_do_GET(self):
+
+ # URL is '/'
+ self.handler.path = stats_httpd.XML_URL_PATH
+ push_answer(self.stats_httpd)
+ self.handler.do_GET()
+ (ret, arg, env) = pull_query(self.stats_httpd)
+ self.assertEqual(ret, "show")
+ self.assertIsNone(arg)
+ self.assertTrue('group' in env)
+ self.assertEqual(env['group'], 'Stats')
+ (ret, arg, env) = pull_query(self.stats_httpd)
+ self.assertEqual(ret, 0)
+ self.assertIsNone(arg)
+ self.assertTrue('group' in env)
+ self.assertEqual(env['group'], 'Stats')
+ self.assertEqual(self.handler.response.code, 200)
+ self.assertEqual(self.handler.response.headers["Content-type"], "text/xml")
+ self.assertTrue(self.handler.response.headers["Content-Length"] > 0)
+ self.assertTrue(self.handler.response.wrote_headers)
+ for (k, v) in DUMMY_DATA.items():
+ self.assertRegexpMatches(self.handler.response.body, str(k))
+ self.assertRegexpMatches(self.handler.response.body, str(v))
+
+ # URL is '/bind10-statitics.xsd'
+ self.handler.path = stats_httpd.XSD_URL_PATH
+ self.handler.do_GET()
+ self.assertEqual(self.handler.response.code, 200)
+ self.assertEqual(self.handler.response.headers["Content-type"], "text/xml")
+ self.assertTrue(self.handler.response.headers["Content-Length"] > 0)
+ self.assertTrue(self.handler.response.wrote_headers)
+ for (k, v) in DUMMY_DATA.items():
+ self.assertRegexpMatches(self.handler.response.body, str(k))
+
+ # URL is '/bind10-statitics.xsl'
+ self.handler.path = stats_httpd.XSL_URL_PATH
+ self.handler.do_GET()
+ self.assertEqual(self.handler.response.code, 200)
+ self.assertEqual(self.handler.response.headers["Content-type"], "text/xml")
+ self.assertTrue(self.handler.response.headers["Content-Length"] > 0)
+ self.assertTrue(self.handler.response.wrote_headers)
+ for (k, v) in DUMMY_DATA.items():
+ self.assertRegexpMatches(self.handler.response.body, str(k))
+
+ # NotFound URL
+ self.handler.path = '/path/to/foo/bar'
+ self.handler.do_GET()
+ self.assertEqual(self.handler.response.code, 404)
+
+ # failure case(network problem)
+ self.handler.path = stats_httpd.XML_URL_PATH
+ push_answer(self.stats_httpd)
+ self.assertFalse(self.stats_httpd.cc_session._socket._closed)
+ self.stats_httpd.cc_session._socket._closed = True
+ self.assertRaises(stats_httpd.StatsHttpdError, self.handler.do_GET)
+ self.assertEqual(self.handler.response.code, 500)
+
+ def test_do_HEAD(self):
+ # other url
+ self.handler.path = '/path/to/foo/bar'
+ self.handler.do_HEAD()
+ self.assertEqual(self.handler.response.code, 404)
+
+ def test_log_message(self):
+ # switch write_log function
+ self.stats_httpd.write_log = self.handler.response._write_log
+ log_message = 'ABCDEFG'
+ self.handler.log_message("%s", log_message)
+ self.assertEqual(self.handler.response.log,
+ "[b10-stats-httpd] %s - - [%s] %s\n" %
+ (self.handler.address_string(),
+ self.handler.log_date_time_string(),
+ log_message))
+
+class TestHttpServer(unittest.TestCase):
+ def setUp(self):
+ self.verbose = True
+ self.stats_httpd = stats_httpd.StatsHttpd(self.verbose)
+ self.httpd = stats_httpd.HttpServer(stats_httpd.HttpHandler, self.stats_httpd, self.verbose)
+ self.assertEqual(self.httpd.verbose, self.verbose)
+ self.assertEqual(self.httpd.stats_httpd, self.stats_httpd)
+ self.assertEqual(type(self.httpd._get_handler), stats_httpd.HttpHandler)
+ self.assertEqual(self.httpd._get_server_class,
+ (self.stats_httpd.http_addr, self.stats_httpd.http_port))
+
+class TestStatsHttpdError(unittest.TestCase):
+ def test_raises(self):
+ try:
+ raise stats_httpd.StatsHttpdError('Nothing')
+ except stats_httpd.StatsHttpdError as err:
+ self.assertEqual(str(err), 'Nothing')
+
class TestStatsHttpd(unittest.TestCase):
def setUp(self):
- self.sample_stats_data = {
- "auth.queries.tcp": 0,
- "auth.queries.udp": 0,
- "bind10.boot_time": "1970-01-01T00:00:00Z",
- "report_time": "2011-02-24T09:08:32Z",
- "stats.boot_time": "2011-02-24T09:08:21Z",
- "stats.last_update_time": "2011-02-24T09:08:21Z",
- "stats.lname": "4d662005_a at fdvm",
- "stats.start_time": "2011-02-24T09:08:21Z",
- "stats.timestamp": 1298538512.87378 }
self.verbose = True
+ socket._CLOSED = False
self.stats_httpd = stats_httpd.StatsHttpd(self.verbose)
- self.http_server = self.stats_httpd.httpd
+
+ def tearDown(self):
+ self.stats_httpd.stop()
+
+ def test_init(self):
self.assertTrue(self.stats_httpd.verbose)
self.assertTrue(self.stats_httpd.running)
- self.assertEqual(self.stats_httpd.stats_module_name, "Stats")
- self.assertEqual(type(self.stats_httpd.httpd), stats_httpd.HttpServer)
- self.assertFalse(self.stats_httpd.ccs_fd._closed)
+ self.assertFalse(self.stats_httpd.mccs_fd._closed)
self.assertFalse(self.stats_httpd.http_fd._closed)
- self.assertEqual(self.stats_httpd.ccs_fd.fileno(), id(self.stats_httpd.ccs_fd))
+ self.assertEqual(self.stats_httpd.mccs_fd.fileno(), id(self.stats_httpd.mccs_fd))
self.assertEqual(self.stats_httpd.http_fd.fileno(), id(self.stats_httpd.http_fd))
- self.assertEqual(type(self.stats_httpd.xml_template), string.Template)
- self.assertEqual(type(self.stats_httpd.xsd_template), string.Template)
- self.assertEqual(type(self.stats_httpd.xsl_template), string.Template)
+ socket._CLOSED = True
+ self.assertRaises(isc.cc.session.SessionError,
+ stats_httpd.StatsHttpd)
+ socket._CLOSED = False
- def tearDown(self):
- self.stats_httpd.stop()
- self.assertTrue(self.stats_httpd.ccs_fd._closed)
- self.assertTrue(self.stats_httpd.http_fd._closed)
+ def test_mccs(self):
+ self.stats_httpd.open_mccs()
+ self.assertTrue(isinstance(self.stats_httpd.mccs_fd, socket.socket))
+ self.assertTrue(isinstance(self.stats_httpd.cc_session, isc.cc.session.Session))
+ self.assertTrue(isinstance(self.stats_httpd.stats_module_spec, isc.config.ModuleSpec))
+ for cfg in self.stats_httpd.stats_config_spec:
+ self.assertTrue('item_name' in cfg)
+ self.assertTrue(cfg['item_name'] in DUMMY_DATA)
+ self.assertTrue(len(self.stats_httpd.stats_config_spec), len(DUMMY_DATA))
+
+ def test_load_config(self):
+ self.stats_httpd.load_config()
+ self.assertEqual(self.stats_httpd.http_addr, '127.0.0.1')
+ self.assertEqual(self.stats_httpd.http_port, 8000)
+
+ def test_httpd(self):
+ # dual stack (address is ipv4)
+ socket.has_ipv6 = True
+ (self.stats_httpd.http_addr, self.stats_httpd.http_port) = ('127.0.0.1', 8000)
+ assert stats_httpd.HttpServer.address_family is socket.AF_INET
+ self.stats_httpd.open_httpd()
+ self.assertTrue(isinstance(self.stats_httpd.http_fd, socket.socket))
+ self.stats_httpd.close_httpd()
+ # dual stack (address is ipv6)
+ socket.has_ipv6 = True
+ (self.stats_httpd.http_addr, self.stats_httpd.http_port) = ('::1', 8000)
+ self.stats_httpd.open_httpd()
+ self.assertTrue(isinstance(self.stats_httpd.http_fd, socket.socket))
+ self.stats_httpd.close_httpd()
+
+ # only-ipv4 single stack
+ socket.has_ipv6 = False
+ (self.stats_httpd.http_addr, self.stats_httpd.http_port) = ('127.0.0.1', 8000)
+ self.stats_httpd.open_httpd()
+ self.assertTrue(isinstance(self.stats_httpd.http_fd, socket.socket))
+ self.stats_httpd.close_httpd()
+ (self.stats_httpd.http_addr, self.stats_httpd.http_port) = ('::1', 8000)
+ self.assertRaises(stats_httpd.StatsHttpdError, self.stats_httpd.open_httpd)
+ self.assertTrue(isinstance(self.stats_httpd.http_fd, socket.socket))
+ self.stats_httpd.close_httpd()
- def test_statshttpd_start(self):
+ # hostname
+ (self.stats_httpd.http_addr, self.stats_httpd.http_port) = ('localhost', 8000)
+ self.stats_httpd.open_httpd()
+ self.assertTrue(isinstance(self.stats_httpd.http_fd, socket.socket))
+ self.stats_httpd.close_httpd()
+ (self.stats_httpd.http_addr, self.stats_httpd.http_port) = ('my.host.domain', 8000)
+ self.stats_httpd.open_httpd()
+ self.assertTrue(isinstance(self.stats_httpd.http_fd, socket.socket))
+ self.stats_httpd.close_httpd()
+
+ # port is over flow
+ (self.stats_httpd.http_addr, self.stats_httpd.http_port) = ('', 80000)
+ self.assertRaises(stats_httpd.StatsHttpdError, self.stats_httpd.open_httpd)
+ (self.stats_httpd.http_addr, self.stats_httpd.http_port) = ('', -8000)
+ self.assertRaises(stats_httpd.StatsHttpdError, self.stats_httpd.open_httpd)
+ (self.stats_httpd.http_addr, self.stats_httpd.http_port) = ('', 'ABCDE')
+ self.assertRaises(stats_httpd.StatsHttpdError, self.stats_httpd.open_httpd)
+
+ def test_start(self):
self.assertTrue(self.stats_httpd.running)
- self.stats_httpd.start()
+ self.assertRaises(
+ stats_httpd.StatsHttpdError,
+ self.stats_httpd.start)
self.assertFalse(self.stats_httpd.running)
- self.stats_httpd.running = True
+
+ def test_stop(self):
+ # success case
+ socket._CLOSED = False
+ self.assertTrue(self.stats_httpd.running)
self.stats_httpd.stop()
self.assertFalse(self.stats_httpd.running)
+ self.assertTrue(self.stats_httpd.mccs_fd._closed)
+ self.assertTrue(self.stats_httpd.http_fd._closed)
+ self.assertTrue(self.stats_httpd.cc_session._socket._closed)
+ # failure case
+ self.stats_httpd.cc_session._socket._closed = False
+ self.stats_httpd.open_mccs()
+ self.stats_httpd.cc_session._socket._closed = True
+ self.assertRaises(stats_httpd.StatsHttpdError, self.stats_httpd.stop)
+ self.stats_httpd.cc_session._socket._closed = False
- def test_statshttpd_read_template(self):
+ def test_open_template(self):
self.assertRaises(
stats_httpd.StatsHttpdError,
- self.stats_httpd.read_template,
- '/path/to/foo/bar')
+ self.stats_httpd.open_template, '/path/to/foo/bar')
- def test_statshttpd_commands(self):
+ def test_commands(self):
self.assertEqual(
self.stats_httpd.config_handler(None),
isc.config.ccsession.create_answer(0))
@@ -83,56 +272,38 @@ class TestStatsHttpd(unittest.TestCase):
self.assertTrue(self.stats_httpd.running)
self.stats_httpd.running = True
self.assertEqual(self.stats_httpd.command_handler("shutdown", None),
- isc.config.ccsession.create_answer(0))
+ isc.config.ccsession.create_answer(
+ 0, "Stats Httpd is shutting down."))
self.assertFalse(self.stats_httpd.running)
self.assertEqual(
self.stats_httpd.command_handler("__UNKNOWN_COMMAND__", None),
isc.config.ccsession.create_answer(
1, "Unknown command: __UNKNOWN_COMMAND__"))
- def push_answer(self):
- print(self.stats_httpd.cc_session._clear_ques())
- self.stats_httpd.cc_session.group_sendmsg(
- { 'result':
- [ 0, self.sample_stats_data ] }, "Stats")
-
- def test_stats_spec(self):
- self.push_answer()
+ def test_config(self):
self.assertEqual(
- len(self.stats_httpd.get_stats_data()),
- len(self.sample_stats_data))
- self.assertEqual(type(self.stats_httpd.get_stats_spec()), list)
-
- def test_stats_xml(self):
- self.push_answer()
- self.assertEqual(type(self.stats_httpd.get_stats_xml()), str)
- self.assertEqual(type(self.stats_httpd.get_stats_xsd()), str)
- self.assertEqual(type(self.stats_httpd.get_stats_xsl()), str)
-
- def test_http_handler(self):
- self.assertTrue(self.stats_httpd.httpd.verbose)
- self.stats_httpd.httpd.handler.path = '/'
- self.push_answer()
- self.stats_httpd.httpd.handler.do_GET()
- self.push_answer()
- self.stats_httpd.httpd.handler.do_HEAD()
- self.stats_httpd.httpd.handler.path = '/bind10-statistics.xsd'
- self.stats_httpd.httpd.handler.do_GET()
- self.stats_httpd.httpd.handler.path = '/bind10-statistics.xsl'
- self.stats_httpd.httpd.handler.do_GET()
- self.stats_httpd.httpd.handler.path = '/path/to'
- self.stats_httpd.httpd.handler.do_GET()
- self.stats_httpd.httpd.handler.log_message('%s', 'dummyrequest')
+ self.stats_httpd.config_handler(
+ { 'listen_on_address' : '::1' }),
+ isc.config.ccsession.create_answer(0))
+ self.assertEqual(
+ self.stats_httpd.config_handler(
+ { 'listen_on_port' : 80 }),
+ isc.config.ccsession.create_answer(0))
+ self.assertEqual(
+ self.stats_httpd.config_handler(
+ { 'listen_on_address' : "1.2.3.4",
+ 'listen_on_port' : 54321 }),
+ isc.config.ccsession.create_answer(0))
def test_no_buildpath(self):
"""
- test for not having environment variable "B10_FROM_BUILD"
+ test for no "B10_FROM_SOURCE"
"""
- if "B10_FROM_BUILD" in os.environ:
- tmppath = os.environ["B10_FROM_BUILD"]
- os.environ.pop("B10_FROM_BUILD")
+ if "B10_FROM_SOURCE" in os.environ:
+ tmppath = os.environ["B10_FROM_SOURCE"]
+ os.environ.pop("B10_FROM_SOURCE")
imp.reload(stats_httpd)
- os.environ["B10_FROM_BUILD"] = tmppath
+ os.environ["B10_FROM_SOURCE"] = tmppath
imp.reload(stats_httpd)
if __name__ == "__main__":
diff --git a/src/bin/stats/tests/b10-stats_test.py b/src/bin/stats/tests/b10-stats_test.py
index 6f5b066..cfe6ebc 100644
--- a/src/bin/stats/tests/b10-stats_test.py
+++ b/src/bin/stats/tests/b10-stats_test.py
@@ -528,9 +528,9 @@ class TestStats2(unittest.TestCase):
Test for specfile
"""
- if "B10_FROM_BUILD" in os.environ:
+ if "B10_FROM_SOURCE" in os.environ:
self.assertEqual(stats.SPECFILE_LOCATION,
- os.environ["B10_FROM_BUILD"] + "/stats.spec")
+ os.environ["B10_FROM_SOURCE"] + os.sep + "stats.spec")
imp.reload(stats)
# change path of SPECFILE_LOCATION
stats.SPECFILE_LOCATION = TEST_SPECFILE_LOCATION
@@ -624,13 +624,13 @@ class TestStats2(unittest.TestCase):
def test_osenv(self):
"""
- test for not having environ "B10_FROM_BUILD"
+ test for not having environ "B10_FROM_SOURCE"
"""
- if "B10_FROM_BUILD" in os.environ:
- path = os.environ["B10_FROM_BUILD"]
- os.environ.pop("B10_FROM_BUILD")
+ if "B10_FROM_SOURCE" in os.environ:
+ path = os.environ["B10_FROM_SOURCE"]
+ os.environ.pop("B10_FROM_SOURCE")
imp.reload(stats)
- os.environ["B10_FROM_BUILD"] = path
+ os.environ["B10_FROM_SOURCE"] = path
imp.reload(stats)
def result_ok(*args):
diff --git a/src/bin/stats/tests/http/server.py b/src/bin/stats/tests/http/server.py
index ab3341b..4d4621e 100644
--- a/src/bin/stats/tests/http/server.py
+++ b/src/bin/stats/tests/http/server.py
@@ -15,15 +15,14 @@
import socket
-class StreamWriter:
- """
- This module is a mock-up class of StreamWriter
- """
- def __init__(self):
- pass
+class DummyHttpResponse:
+ def __init__(self, path):
+ self.path = path
+ self.headers={}
- def write(self, obj):
- pass
+ def _write_log(self, msg):
+ assert type(msg) is str
+ self.log = msg
class HTTPServer:
"""
@@ -31,7 +30,9 @@ class HTTPServer:
"""
address_family = socket.AF_INET
def __init__(self, server_class, handler_class):
- self.socket = socket.socket()
+ self.socket = socket.socket(self.address_family)
+ self.server_class = server_class
+ self.socket.bind(self.server_class)
self.handler = handler_class(None, None, self)
def handle_request(self):
@@ -40,30 +41,54 @@ class HTTPServer:
def close(self):
self.socket.close()
+ def _get_handler(self):
+ return self.handler
+
+ def _get_server_class(self):
+ return self.server_class
+
class BaseHTTPRequestHandler:
"""
This module is a mock-up class of http.server.BaseHTTPRequestHandler
"""
def __init__(self, request, client_address, server):
- self.path = "/"
+ self.path = "/path/to"
self.server = server
- self.wfile = StreamWriter()
+ self.response = DummyHttpResponse(path=self.path)
+ self.response.write = self._write
+ self.wfile = self.response
def send_response(self, code=0):
- pass
+ if self.path != self.response.path:
+ self.response = DummyHttpResponse(path=self.path)
+ self.response.code = code
def send_header(self, key, value):
- pass
+ if self.path != self.response.path:
+ self.response = DummyHttpResponse(path=self.path)
+ self.response.headers[key] = value
def end_headers(self):
- pass
+ if self.path != self.response.path:
+ self.response = DummyHttpResponse(path=self.path)
+ self.response.wrote_headers = True
def send_error(self, code, message=None):
- pass
+ if self.path != self.response.path:
+ self.response = DummyHttpResponse(path=self.path)
+ self.response.code = code
+ self.response.body = message
def address_string(self):
return 'dummyhost'
def log_date_time_string(self):
return '[DD/MM/YYYY HH:MI:SS]'
+
+ def _write(self, obj):
+ if self.path != self.response.path:
+ self.response = DummyHttpResponse(path=self.path)
+ assert type(obj) is bytes
+ self.response.body = obj.decode()
+
diff --git a/src/bin/stats/tests/isc/cc/session.py b/src/bin/stats/tests/isc/cc/session.py
index 65c2f03..5bdb2e1 100644
--- a/src/bin/stats/tests/isc/cc/session.py
+++ b/src/bin/stats/tests/isc/cc/session.py
@@ -32,12 +32,18 @@ class Queue():
class SessionError(Exception):
pass
+class SessionTimeout(Exception):
+ pass
+
class Session:
def __init__(self, socket_file=None, verbose=False):
self._lname = _TEST_LNAME
self.message_queue = []
self.old_message_queue = []
- self._socket = socket.socket()
+ try:
+ self._socket = socket.socket()
+ except socket.error as se:
+ raise SessionError(se)
self.verbose = verbose
@property
@@ -50,7 +56,6 @@ class Session:
def _clear_ques(self):
while len(self.message_queue) > 0:
self.dequeue()
- print("msgq: " + str(len(self.message_queue)))
def _next_sequence(self, que=None):
return len(self.message_queue)
@@ -129,7 +134,9 @@ class Session:
return q.msg
def group_subscribe(self, group, instance = "*"):
- pass
+ if self._socket._closed:
+ raise SessionError("Session has been closed.")
def group_unsubscribe(self, group, instance = "*"):
- pass
+ if self._socket._closed:
+ raise SessionError("Session has been closed.")
diff --git a/src/bin/stats/tests/isc/config/ccsession.py b/src/bin/stats/tests/isc/config/ccsession.py
index 1b77952..db2a09f 100644
--- a/src/bin/stats/tests/isc/config/ccsession.py
+++ b/src/bin/stats/tests/isc/config/ccsession.py
@@ -36,6 +36,8 @@ def create_answer(rcode, arg = None):
return { 'result': [ rcode, arg ] }
def parse_command(msg):
+ assert type(msg) is dict
+ assert 'command' in msg
try:
return msg['command'][0], msg['command'][1]
except IndexError:
@@ -48,9 +50,21 @@ def create_command(command_name, params = None):
return {"command": [command_name, params]}
def module_spec_from_file(spec_file, check = True):
- file = open(spec_file)
- module_spec = json.loads(file.read())
- return ModuleSpec(module_spec['module_spec'], check)
+ try:
+ file = open(spec_file)
+ json_str = file.read()
+ module_spec = json.loads(json_str)
+ file.close()
+ return ModuleSpec(module_spec['module_spec'], check)
+ except IOError as ioe:
+ raise ModuleSpecError("JSON read error: " + str(ioe))
+ except ValueError as ve:
+ raise ModuleSpecError("JSON parse error: " + str(ve))
+ except KeyError as err:
+ raise ModuleSpecError("Data definition has no module_spec element")
+
+class ModuleSpecError(Exception):
+ pass
class ModuleSpec:
def __init__(self, module_spec, check = True):
diff --git a/src/bin/stats/tests/select.py b/src/bin/stats/tests/select.py
index 3578473..a33c8be 100644
--- a/src/bin/stats/tests/select.py
+++ b/src/bin/stats/tests/select.py
@@ -30,9 +30,9 @@ def select(rlst, wlst, xlst, timeout):
if type(s) != socket.socket:
raise TypeError("Error: %s must be a dummy socket"
% s.__class__.__name__)
- if s._called > 2:
- raise error(errno.EINTR)
- elif s._called > 1:
- raise error("Something is happened!")
s._called = s._called + 1
+ if s._called > 3:
+ raise error("Something is happened!")
+ elif s._called > 2:
+ raise error(errno.EINTR)
return (rlst, wlst, xlst)
diff --git a/src/bin/stats/tests/socket.py b/src/bin/stats/tests/socket.py
index 8c7bb11..8a82955 100644
--- a/src/bin/stats/tests/socket.py
+++ b/src/bin/stats/tests/socket.py
@@ -13,22 +13,54 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-AF_INET = -0xFFFF
+"""
+This module is a mock-up classes of socket module
+"""
+
+import re
+
+AF_INET = 'IPV4_OK'
+AF_INET6 = 'IPV6_OK'
+_ADDRFAMILY = AF_INET
+has_ipv6 = True
+_CLOSED = False
class gaierror(Exception):
pass
+class error(Exception):
+ pass
+
class socket:
- """
- This module is a mock-up class of socket
- """
- def __init__(self):
- self._closed = False
+
+ def __init__(self, family=None):
+ if family is None:
+ self.address_family = _ADDRFAMILY
+ else:
+ self.address_family = family
+ self._closed = _CLOSED
+ if self._closed:
+ raise error('socket is already closed!')
self._called = 0
- self.has_ipv6 = True
def close(self):
self._closed = True
def fileno(self):
return id(self)
+
+ def bind(self, server_class):
+ (self.server_address, self.server_port) = server_class
+ if self.address_family not in set([AF_INET, AF_INET6]):
+ raise error("Address family not supported by protocol: %s" % self.address_family)
+ if self.address_family == AF_INET6 and not has_ipv6:
+ raise error("Address family not supported in this machine: %s ipv6: %s"
+ % (self.address_family, str(has_ipv6)))
+ if self.address_family == AF_INET and re.search(':', self.server_address) is not None:
+ raise gaierror("Address family for hostname not supported : %s" % str(self.server_address))
+ if self.address_family == AF_INET6 and re.search(':', self.server_address) is None:
+ raise error("Cannot assign requested address : %s" % str(self.server_address))
+ if type(self.server_port) is not int:
+ raise TypeError("an integer is required: %s" % str(self.server_port))
+ if self.server_port < 0 or self.server_port > 65535:
+ raise OverflowError("port number must be 0-65535.: %s" % str(self.server_port))
diff --git a/src/bin/stats/tests/stats_test.in b/src/bin/stats/tests/stats_test.in
index 8686bfa..02b2880 100644
--- a/src/bin/stats/tests/stats_test.in
+++ b/src/bin/stats/tests/stats_test.in
@@ -23,8 +23,8 @@ export PYTHONPATH
TEST_PATH=@abs_top_srcdir@/src/bin/stats/tests
-B10_FROM_BUILD=${TEST_PATH}/testdata
-export B10_FROM_BUILD
+B10_FROM_SOURCE=@abs_top_srcdir@/src/bin/stats
+export B10_FROM_SOURCE
cd ${TEST_PATH}
${PYTHON_EXEC} -O b10-stats_test.py $*
diff --git a/src/bin/stats/tests/string.py b/src/bin/stats/tests/string.py
deleted file mode 100644
index 5ab7f68..0000000
--- a/src/bin/stats/tests/string.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2011 Internet Systems Consortium.
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
-# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
-# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-class Template:
- """
- This module is a mock-up class of Template
- """
- def __init__(self, template):
- self.template = template
-
- def substitute(self, **map):
- return str(self.template)
-
diff --git a/src/bin/stats/tests/testdata/Makefile.am b/src/bin/stats/tests/testdata/Makefile.am
index f92f18f..1b8df6d 100644
--- a/src/bin/stats/tests/testdata/Makefile.am
+++ b/src/bin/stats/tests/testdata/Makefile.am
@@ -1,27 +1 @@
EXTRA_DIST = stats_test.spec
-
-noinst_DATA = stats.spec stats_httpd.spec
-noinst_DATA += stats-httpd-xml.tpl stats-httpd-xsd.tpl stats-httpd-xsl.tpl
-
-CLEANFILES = stats.spec stats_httpd.spec
-CLEANFILES += stats-httpd-xml.tpl stats-httpd-xsd.tpl stats-httpd-xsl.tpl
-
-stats.spec: $(abs_builddir)/../../stats.spec.pre
- $(SED) -e "s|@@DATAROOTDIR@@|@abs_builddir@|" \
- -e "s|@@PACKAGEDIR@@|.|" $(abs_builddir)/../../stats.spec.pre >$@
-
-stats_httpd.spec: $(abs_builddir)/../../stats_httpd.spec.pre
- $(SED) -e "s|@@DATAROOTDIR@@|@abs_builddir@|" \
- -e "s|@@PACKAGEDIR@@|.|" $(abs_builddir)/../../stats_httpd.spec.pre >$@
-
-stats-httpd-xml.tpl: $(abs_builddir)/../../stats-httpd-xml.tpl.pre
- $(SED) -e "s|@@DATAROOTDIR@@|@abs_builddir@|" \
- -e "s|@@PACKAGEDIR@@|.|" $(abs_builddir)/../../stats-httpd-xml.tpl.pre >$@
-
-stats-httpd-xsd.tpl: $(abs_builddir)/../../stats-httpd-xsd.tpl.pre
- $(SED) -e "s|@@DATAROOTDIR@@|@abs_builddir@|" \
- -e "s|@@PACKAGEDIR@@|.|" $(abs_builddir)/../../stats-httpd-xsd.tpl.pre >$@
-
-stats-httpd-xsl.tpl: $(abs_builddir)/../../stats-httpd-xsl.tpl.pre
- $(SED) -e "s|@@DATAROOTDIR@@|@abs_builddir@|" \
- -e "s|@@PACKAGEDIR@@|.|" $(abs_builddir)/../../stats-httpd-xsl.tpl.pre >$@
More information about the bind10-changes
mailing list