[svn] commit: r3093 - in /branches/trac354: ./ src/bin/ src/bin/auth/ src/bin/auth/tests/ src/bin/bind10/ src/bin/bind10/tests/ src/bin/bindctl/ src/bin/cfgmgr/ src/bin/cmdctl/ src/bin/host/ src/bin/loadzone/ src/bin/msgq/ src/bin/tests/ src/bin/usermgr/ src/bin/xfrin/ src/bin/xfrout/ src/bin/zonemgr/ src/lib/bench/ src/lib/bench/tests/ src/lib/datasrc/ src/lib/datasrc/tests/ src/lib/dns/ src/lib/dns/python/ src/lib/dns/python/tests/ src/lib/dns/tests/ src/lib/python/isc/ src/lib/python/isc/utils/

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Oct 1 04:26:23 UTC 2010


Author: jinmei
Date: Fri Oct  1 04:26:22 2010
New Revision: 3093

Log:
sync with trunk

Added:
    branches/trac354/src/bin/tests/
      - copied from r3077, trunk/src/bin/tests/
    branches/trac354/src/lib/dns/opcode.cc
      - copied unchanged from r3077, trunk/src/lib/dns/opcode.cc
    branches/trac354/src/lib/dns/opcode.h
      - copied unchanged from r3077, trunk/src/lib/dns/opcode.h
    branches/trac354/src/lib/dns/python/opcode_python.cc
      - copied unchanged from r3077, trunk/src/lib/dns/python/opcode_python.cc
    branches/trac354/src/lib/dns/python/rcode_python.cc
      - copied unchanged from r3077, trunk/src/lib/dns/python/rcode_python.cc
    branches/trac354/src/lib/dns/python/tests/opcode_python_test.py
      - copied unchanged from r3077, trunk/src/lib/dns/python/tests/opcode_python_test.py
    branches/trac354/src/lib/dns/python/tests/rcode_python_test.py
      - copied unchanged from r3077, trunk/src/lib/dns/python/tests/rcode_python_test.py
    branches/trac354/src/lib/dns/rcode.cc
      - copied unchanged from r3077, trunk/src/lib/dns/rcode.cc
    branches/trac354/src/lib/dns/rcode.h
      - copied unchanged from r3077, trunk/src/lib/dns/rcode.h
    branches/trac354/src/lib/dns/tests/opcode_unittest.cc
      - copied unchanged from r3077, trunk/src/lib/dns/tests/opcode_unittest.cc
    branches/trac354/src/lib/dns/tests/rcode_unittest.cc
      - copied unchanged from r3077, trunk/src/lib/dns/tests/rcode_unittest.cc
    branches/trac354/src/lib/python/isc/utils/
      - copied from r3077, trunk/src/lib/python/isc/utils/
Modified:
    branches/trac354/   (props changed)
    branches/trac354/ChangeLog
    branches/trac354/configure.ac
    branches/trac354/src/bin/Makefile.am
    branches/trac354/src/bin/auth/auth_srv.cc
    branches/trac354/src/bin/auth/tests/auth_srv_unittest.cc
    branches/trac354/src/bin/bind10/bind10.8
    branches/trac354/src/bin/bind10/bind10.py.in
    branches/trac354/src/bin/bind10/bind10.xml
    branches/trac354/src/bin/bind10/tests/args_test.py
    branches/trac354/src/bin/bindctl/bindctl-source.py.in
    branches/trac354/src/bin/cfgmgr/b10-cfgmgr.py.in
    branches/trac354/src/bin/cmdctl/cmdctl.py.in
    branches/trac354/src/bin/host/host.cc
    branches/trac354/src/bin/loadzone/b10-loadzone.py.in
    branches/trac354/src/bin/msgq/msgq.py.in
    branches/trac354/src/bin/usermgr/b10-cmdctl-usermgr.py.in
    branches/trac354/src/bin/xfrin/xfrin.py.in
    branches/trac354/src/bin/xfrout/xfrout.py.in
    branches/trac354/src/bin/zonemgr/zonemgr.py.in
    branches/trac354/src/lib/bench/benchmark_util.cc
    branches/trac354/src/lib/bench/tests/loadquery_unittest.cc
    branches/trac354/src/lib/datasrc/data_source.cc
    branches/trac354/src/lib/datasrc/tests/datasrc_unittest.cc
    branches/trac354/src/lib/datasrc/tests/query_unittest.cc
    branches/trac354/src/lib/dns/Makefile.am
    branches/trac354/src/lib/dns/exceptions.cc
    branches/trac354/src/lib/dns/message.cc
    branches/trac354/src/lib/dns/message.h
    branches/trac354/src/lib/dns/python/Makefile.am
    branches/trac354/src/lib/dns/python/message_python.cc
    branches/trac354/src/lib/dns/python/pydnspp.cc
    branches/trac354/src/lib/dns/python/tests/Makefile.am
    branches/trac354/src/lib/dns/python/tests/message_python_test.py
    branches/trac354/src/lib/dns/python/tests/messagerenderer_python_test.py
    branches/trac354/src/lib/dns/tests/Makefile.am
    branches/trac354/src/lib/dns/tests/edns_unittest.cc
    branches/trac354/src/lib/dns/tests/message_unittest.cc
    branches/trac354/src/lib/python/isc/Makefile.am

Modified: branches/trac354/ChangeLog
==============================================================================
--- branches/trac354/ChangeLog (original)
+++ branches/trac354/ChangeLog Fri Oct  1 04:26:22 2010
@@ -1,3 +1,13 @@
+  101.	[func]		jinmei
+	src/lib/dns: Completed Opcode and Rcode implementation with more
+	tests and documentation.  API is mostly the same but the
+	validation was a bit tightened. (Trac #351, svn r3056)
+
+  100.  [func]      Michal Vaner
+	Python processes: support naming of python processes so
+	they're not all called python3.
+	(Trac #322, svn r3052)
+
   99.	[func]*		jinmei
 	Introduced a separate EDNS class to encapsulate EDNS related
 	information more cleanly.  The related APIs are changed a bit,

Modified: branches/trac354/configure.ac
==============================================================================
--- branches/trac354/configure.ac (original)
+++ branches/trac354/configure.ac Fri Oct  1 04:26:22 2010
@@ -47,6 +47,12 @@
 if test $enable_shared = no; then
 	AC_MSG_ERROR([BIND 10 requires shared libraries to be built])
 fi
+
+# allow configuring without setproctitle.
+AC_ARG_ENABLE(setproctitle-check,
+AC_HELP_STRING([--disable-setproctitle-check],
+  [do not check for python setproctitle module (used to give nice names to python processes)]),
+  setproctitle_check=$enableval, setproctitle_check=yes)
 
 # OS dependent configuration
 SET_ENV_LIBRARY_PATH=no
@@ -161,6 +167,18 @@
 fi
 AC_SUBST(PYTHON_LIB)
 LDFLAGS=$LDFLAGS_SAVED
+
+# Check for the setproctitle module
+if test "$setproctitle_check" = "yes" ; then
+    AC_MSG_CHECKING(for setproctitle module)
+    if "$PYTHON" -c 'import setproctitle' 2>/dev/null ; then
+        AC_MSG_RESULT(ok)
+    else
+        AC_MSG_RESULT(missing)
+        AC_MSG_ERROR([Missing setproctitle module. Either install it or provide --disable-setproctitle-check.
+In that case we will continue, but naming of python processes will not work.])
+    fi
+fi
 
 # TODO: check for _sqlite3.py module
 
@@ -452,6 +470,7 @@
                  src/bin/zonemgr/Makefile
                  src/bin/zonemgr/tests/Makefile
                  src/bin/usermgr/Makefile
+                 src/bin/tests/Makefile
                  src/lib/Makefile
                  src/lib/bench/Makefile
                  src/lib/bench/example/Makefile
@@ -460,6 +479,8 @@
                  src/lib/cc/tests/Makefile
                  src/lib/python/Makefile
                  src/lib/python/isc/Makefile
+                 src/lib/python/isc/utils/Makefile
+                 src/lib/python/isc/utils/tests/Makefile
                  src/lib/python/isc/datasrc/Makefile
                  src/lib/python/isc/cc/Makefile
                  src/lib/python/isc/cc/tests/Makefile
@@ -518,6 +539,7 @@
            src/bin/msgq/run_msgq.sh
            src/bin/auth/auth.spec.pre
            src/bin/auth/spec_config.h.pre
+           src/bin/tests/process_rename_test.py
            src/lib/config/tests/data_def_unittests_config.h
            src/lib/python/isc/config/tests/config_test
            src/lib/python/isc/cc/tests/cc_test

Modified: branches/trac354/src/bin/Makefile.am
==============================================================================
--- branches/trac354/src/bin/Makefile.am (original)
+++ branches/trac354/src/bin/Makefile.am Fri Oct  1 04:26:22 2010
@@ -1,1 +1,4 @@
-SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout usermgr zonemgr
+SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
+	usermgr zonemgr tests
+
+check-recursive: all-recursive

Modified: branches/trac354/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac354/src/bin/auth/auth_srv.cc (original)
+++ branches/trac354/src/bin/auth/auth_srv.cc Fri Oct  1 04:26:22 2010
@@ -29,6 +29,8 @@
 #include <dns/messagerenderer.h>
 #include <dns/name.h>
 #include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rrset.h>
 #include <dns/rrttl.h>
 #include <dns/message.h>

Modified: branches/trac354/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac354/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac354/src/bin/auth/tests/auth_srv_unittest.cc Fri Oct  1 04:26:22 2010
@@ -22,6 +22,8 @@
 #include <dns/name.h>
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rrclass.h>
 #include <dns/rrtype.h>
 
@@ -114,7 +116,7 @@
     AuthSrvTest() : server(true, xfrout),
                     request_message(Message::RENDER),
                     parse_message(Message::PARSE), default_qid(0x1035),
-                    opcode(Opcode(Opcode::QUERY())), qname("www.example.com"),
+                    opcode(Opcode::QUERY()), qname("www.example.com"),
                     qclass(RRClass::IN()), qtype(RRType::A()),
                     io_message(NULL), endpoint(NULL), request_obuffer(0),
                     request_renderer(request_obuffer),
@@ -280,6 +282,7 @@
 {
     request_message.clear(Message::RENDER);
     request_message.setOpcode(opcode);
+    request_message.setRcode(Rcode::NOERROR());
     request_message.setQid(default_qid);
     request_message.addQuestion(Question(request_name, rrclass, rrtype));
 }
@@ -584,6 +587,7 @@
 TEST_F(AuthSrvTest, notifyEmptyQuestion) {
     request_message.clear(Message::RENDER);
     request_message.setOpcode(Opcode::NOTIFY());
+    request_message.setRcode(Rcode::NOERROR());
     request_message.setHeaderFlag(MessageFlag::AA());
     request_message.setQid(default_qid);
     request_message.toWire(request_renderer);

Modified: branches/trac354/src/bin/bind10/bind10.8
==============================================================================
--- branches/trac354/src/bin/bind10/bind10.8 (original)
+++ branches/trac354/src/bin/bind10/bind10.8 Fri Oct  1 04:26:22 2010
@@ -1,13 +1,22 @@
 '\" t
 .\"     Title: bind10
 .\"    Author: [see the "AUTHORS" section]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.76.0 <http://docbook.sf.net/>
 .\"      Date: July 29, 2010
 .\"    Manual: BIND10
 .\"    Source: BIND10
 .\"  Language: English
 .\"
 .TH "BIND10" "8" "July 29, 2010" "BIND10" "BIND10"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -22,7 +31,7 @@
 bind10 \- BIND 10 boss process
 .SH "SYNOPSIS"
 .HP \w'\fBbind10\fR\ 'u
-\fBbind10\fR [\fB\-a\ \fR\fB\fIaddress\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-address\ \fR\fB\fIaddress\fR\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-verbose\fR]
+\fBbind10\fR [\fB\-a\ \fR\fB\fIaddress\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-address\ \fR\fB\fIaddress\fR\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-pretty\-name\ \fR\fB\fIname\fR\fR] [\fB\-\-verbose\fR]
 .SH "DESCRIPTION"
 .PP
 The
@@ -86,6 +95,15 @@
 must be initially ran as the root user to use this option\&. The default is to run as the current user\&.
 .RE
 .PP
+\fB\-\-pretty\-name \fR\fB\fIname\fR\fR
+.RS 4
+The name this process should have in tools like
+\fBps\fR
+or
+\fBtop\fR\&. This is handy if you have multiple versions/installations of
+\fBbind10\fR\&.
+.RE
+.PP
 \fB\-v\fR, \fB\-\-verbose\fR
 .RS 4
 Display more about what is going on for

Modified: branches/trac354/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac354/src/bin/bind10/bind10.py.in (original)
+++ branches/trac354/src/bin/bind10/bind10.py.in Fri Oct  1 04:26:22 2010
@@ -63,6 +63,10 @@
 import posix
 
 import isc.cc
+import isc.utils.process
+
+# Assign this process some longer name
+isc.utils.process.rename(sys.argv[0])
 
 # This is the version that gets displayed to the user.
 # The VERSION string consists of the module name, the module version
@@ -620,7 +624,11 @@
         parser.values.address = value
     else:
         raise OptionValueError("Unknown option " + opt_str)
-  
+
+def process_rename(option, opt_str, value, parser):
+    """Function that renames the process if it is requested by a option."""
+    isc.utils.process.rename(value)
+
 def main():
     global options
     global boss_of_bind
@@ -646,6 +654,9 @@
                       help="Change user after startup (must run as root)")
     parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
                       help="display more about what is going on")
+    parser.add_option("--pretty-name", type="string", action="callback",
+                      callback=process_rename,
+                      help="Set the process name (displayed in ps, top, ...)")
     (options, args) = parser.parse_args()
     if args:
         parser.print_help()

Modified: branches/trac354/src/bin/bind10/bind10.xml
==============================================================================
--- branches/trac354/src/bin/bind10/bind10.xml (original)
+++ branches/trac354/src/bin/bind10/bind10.xml Fri Oct  1 04:26:22 2010
@@ -56,6 +56,7 @@
       <arg><option>--no-cache</option></arg>
       <arg><option>--port <replaceable>number</replaceable></option></arg>
       <arg><option>--user <replaceable>user</replaceable></option></arg>
+      <arg><option>--pretty-name <replaceable>name</replaceable></option></arg>
       <arg><option>--verbose</option></arg>
     </cmdsynopsis>
   </refsynopsisdiv>
@@ -149,6 +150,17 @@
       </varlistentry>
 
       <varlistentry>
+        <term><option>--pretty-name <replaceable>name</replaceable></option></term>
+
+        <listitem>
+          <para>The name this process should have in tools like
+          <command>ps</command> or <command>top</command>. This
+          is handy if you have multiple versions/installations
+          of <command>bind10</command>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>-v</option>, <option>--verbose</option></term>
         <listitem>
 	  <para>Display more about what is going on for

Modified: branches/trac354/src/bin/bind10/tests/args_test.py
==============================================================================
--- branches/trac354/src/bin/bind10/tests/args_test.py (original)
+++ branches/trac354/src/bin/bind10/tests/args_test.py Fri Oct  1 04:26:22 2010
@@ -130,5 +130,28 @@
         x = bob.wait()
         self.assertTrue(bob.wait() == 0)
 
+    def testPrettyName(self):
+        """Try the --pretty-name option."""
+        CMD_PRETTY_NAME = b'bob-name-test'
+        bob = subprocess.Popen(args=(BIND10_EXE, '--pretty-name',
+            CMD_PRETTY_NAME), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+        started_ok = self._waitForString(bob, '[bind10] BIND 10 started')
+        self.assertTrue(started_ok)
+        ps = subprocess.Popen(args=("ps", "axo", "pid,comm"),
+                              stdout=subprocess.PIPE)
+        s = ps.stdout.readline()
+        command = None
+        while True:
+            s = ps.stdout.readline()
+            if s == '': break
+            (pid,comm) = s.split(None, 1)
+            if int(pid) == bob.pid:
+                command = comm
+                break
+        self.assertEqual(command, CMD_PRETTY_NAME + b'\n')
+        time.sleep(0.1)
+        bob.terminate()
+        bob.wait()
+
 if __name__ == '__main__':
     unittest.main()

Modified: branches/trac354/src/bin/bindctl/bindctl-source.py.in
==============================================================================
--- branches/trac354/src/bin/bindctl/bindctl-source.py.in (original)
+++ branches/trac354/src/bin/bindctl/bindctl-source.py.in Fri Oct  1 04:26:22 2010
@@ -24,6 +24,9 @@
 from bindctl.bindcmd import *
 import pprint
 from optparse import OptionParser, OptionValueError
+import isc.utils.process
+
+isc.utils.process.rename()
 
 __version__ = 'Bindctl'
 

Modified: branches/trac354/src/bin/cfgmgr/b10-cfgmgr.py.in
==============================================================================
--- branches/trac354/src/bin/cfgmgr/b10-cfgmgr.py.in (original)
+++ branches/trac354/src/bin/cfgmgr/b10-cfgmgr.py.in Fri Oct  1 04:26:22 2010
@@ -21,8 +21,11 @@
 
 from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError
 from isc.cc import SessionError
+import isc.utils.process
 import signal
 import os
+
+isc.utils.process.rename()
 
 # If B10_FROM_SOURCE is set in the environment, we use data files
 # from a directory relative to that, otherwise we use the ones

Modified: branches/trac354/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- branches/trac354/src/bin/cmdctl/cmdctl.py.in (original)
+++ branches/trac354/src/bin/cmdctl/cmdctl.py.in Fri Oct  1 04:26:22 2010
@@ -42,12 +42,15 @@
 import time
 import signal
 from isc.config import ccsession
+import isc.utils.process
 from optparse import OptionParser, OptionValueError
 from hashlib import sha1
 try:
     import threading
 except ImportError:
     import dummy_threading as threading
+
+isc.utils.process.rename()
 
 __version__ = 'BIND10'
 URL_PATTERN = re.compile('/([\w]+)(?:/([\w]+))?/?')

Modified: branches/trac354/src/bin/host/host.cc
==============================================================================
--- branches/trac354/src/bin/host/host.cc (original)
+++ branches/trac354/src/bin/host/host.cc Fri Oct  1 04:26:22 2010
@@ -28,6 +28,8 @@
 #include <dns/name.h>
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rrclass.h>
 #include <dns/rrtype.h>
 #include <dns/rrset.h>

Modified: branches/trac354/src/bin/loadzone/b10-loadzone.py.in
==============================================================================
--- branches/trac354/src/bin/loadzone/b10-loadzone.py.in (original)
+++ branches/trac354/src/bin/loadzone/b10-loadzone.py.in Fri Oct  1 04:26:22 2010
@@ -18,9 +18,13 @@
 import sys; sys.path.append ('@@PYTHONPATH@@')
 import re, getopt
 import isc.datasrc
+import isc.utils.process
 from isc.datasrc.master import MasterFile
 import time
 import os
+
+isc.utils.process.rename()
+
 #########################################################################
 # usage: print usage note and exit
 #########################################################################

Modified: branches/trac354/src/bin/msgq/msgq.py.in
==============================================================================
--- branches/trac354/src/bin/msgq/msgq.py.in (original)
+++ branches/trac354/src/bin/msgq/msgq.py.in Fri Oct  1 04:26:22 2010
@@ -31,8 +31,11 @@
 import pprint
 import random
 from optparse import OptionParser, OptionValueError
+import isc.utils.process
 
 import isc.cc
+
+isc.utils.process.rename()
 
 # This is the version that gets displayed to the user.
 __version__ = "v20091030 (Paving the DNS Parking Lot)"

Modified: branches/trac354/src/bin/usermgr/b10-cmdctl-usermgr.py.in
==============================================================================
--- branches/trac354/src/bin/usermgr/b10-cmdctl-usermgr.py.in (original)
+++ branches/trac354/src/bin/usermgr/b10-cmdctl-usermgr.py.in Fri Oct  1 04:26:22 2010
@@ -25,6 +25,9 @@
 import getpass
 import getopt
 import sys
+import isc.utils.process
+
+isc.utils.process.rename()
 
 VERSION_NUMBER = 'bind10'
 DEFAULT_FILE = 'cmdctl-accounts.csv'

Modified: branches/trac354/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac354/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac354/src/bin/xfrin/xfrin.py.in Fri Oct  1 04:26:22 2010
@@ -29,12 +29,15 @@
 from optparse import OptionParser, OptionValueError
 from isc.config.ccsession import *
 from isc.notify import notify_out
+import isc.utils.process
 try:
     from pydnspp import *
 except ImportError as e:
     # C++ loadable module may not be installed; even so the xfrin process
     # must keep running, so we warn about it and move forward.
     sys.stderr.write('[b10-xfrin] failed to import DNS module: %s\n' % str(e))
+
+isc.utils.process.rename()
 
 # If B10_FROM_BUILD is set in the environment, we use data files
 # from a directory relative to that, otherwise we use the ones

Modified: branches/trac354/src/bin/xfrout/xfrout.py.in
==============================================================================
--- branches/trac354/src/bin/xfrout/xfrout.py.in (original)
+++ branches/trac354/src/bin/xfrout/xfrout.py.in Fri Oct  1 04:26:22 2010
@@ -29,6 +29,7 @@
 from isc.log.log import *
 from isc.cc import SessionError, SessionTimeout
 from isc.notify import notify_out
+import isc.utils.process
 import socket
 import select
 import errno
@@ -40,6 +41,8 @@
     # C++ loadable module may not be installed; even so the xfrout process
     # must keep running, so we warn about it and move forward.
     sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e))
+
+isc.utils.process.rename()
 
 if "B10_FROM_BUILD" in os.environ:
     SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"

Modified: branches/trac354/src/bin/zonemgr/zonemgr.py.in
==============================================================================
--- branches/trac354/src/bin/zonemgr/zonemgr.py.in (original)
+++ branches/trac354/src/bin/zonemgr/zonemgr.py.in Fri Oct  1 04:26:22 2010
@@ -36,6 +36,9 @@
 from isc.datasrc import sqlite3_ds
 from optparse import OptionParser, OptionValueError
 from isc.config.ccsession import *
+import isc.utils.process
+
+isc.utils.process.rename()
 
 # If B10_FROM_BUILD is set in the environment, we use data files
 # from a directory relative to that, otherwise we use the ones

Modified: branches/trac354/src/lib/bench/benchmark_util.cc
==============================================================================
--- branches/trac354/src/lib/bench/benchmark_util.cc (original)
+++ branches/trac354/src/lib/bench/benchmark_util.cc Fri Oct  1 04:26:22 2010
@@ -26,6 +26,8 @@
 #include <dns/name.h>
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rrtype.h>
 #include <dns/rrclass.h>
 #include <dns/question.h>

Modified: branches/trac354/src/lib/bench/tests/loadquery_unittest.cc
==============================================================================
--- branches/trac354/src/lib/bench/tests/loadquery_unittest.cc (original)
+++ branches/trac354/src/lib/bench/tests/loadquery_unittest.cc Fri Oct  1 04:26:22 2010
@@ -22,6 +22,8 @@
 #include <dns/buffer.h>
 #include <dns/message.h>
 #include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rrclass.h>
 #include <dns/rrtype.h>
 
@@ -79,7 +81,6 @@
         // Check if the header part indicates an expected standard query.
         EXPECT_EQ(0, message.getQid());
         EXPECT_EQ(Opcode::QUERY(), message.getOpcode());
-        EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
         EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
         EXPECT_FALSE(message.getHeaderFlag(MessageFlag::QR()));
         EXPECT_FALSE(message.getHeaderFlag(MessageFlag::AA()));

Modified: branches/trac354/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac354/src/lib/datasrc/data_source.cc (original)
+++ branches/trac354/src/lib/datasrc/data_source.cc Fri Oct  1 04:26:22 2010
@@ -32,6 +32,7 @@
 #include <dns/buffer.h>
 #include <dns/message.h>
 #include <dns/name.h>
+#include <dns/rcode.h>
 #include <dns/rdataclass.h>
 #include <dns/rrset.h>
 #include <dns/rrsetlist.h>

Modified: branches/trac354/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- branches/trac354/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ branches/trac354/src/lib/datasrc/tests/datasrc_unittest.cc Fri Oct  1 04:26:22 2010
@@ -26,6 +26,8 @@
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
 #include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rdata.h>
 #include <dns/rdataclass.h>
 #include <dns/rrclass.h>

Modified: branches/trac354/src/lib/datasrc/tests/query_unittest.cc
==============================================================================
--- branches/trac354/src/lib/datasrc/tests/query_unittest.cc (original)
+++ branches/trac354/src/lib/datasrc/tests/query_unittest.cc Fri Oct  1 04:26:22 2010
@@ -19,6 +19,7 @@
 #include <dns/buffer.h>
 #include <dns/message.h>
 #include <dns/name.h>
+#include <dns/opcode.h>
 #include <dns/rrtype.h>
 #include <dns/rrclass.h>
 

Modified: branches/trac354/src/lib/dns/Makefile.am
==============================================================================
--- branches/trac354/src/lib/dns/Makefile.am (original)
+++ branches/trac354/src/lib/dns/Makefile.am Fri Oct  1 04:26:22 2010
@@ -69,6 +69,8 @@
 libdns___la_SOURCES += message.h message.cc
 libdns___la_SOURCES += messagerenderer.h messagerenderer.cc
 libdns___la_SOURCES += name.h name.cc
+libdns___la_SOURCES += opcode.h opcode.cc
+libdns___la_SOURCES += rcode.h rcode.cc
 libdns___la_SOURCES += rdata.h rdata.cc
 libdns___la_SOURCES += rrclass.cc
 libdns___la_SOURCES += rrparamregistry.h

Modified: branches/trac354/src/lib/dns/exceptions.cc
==============================================================================
--- branches/trac354/src/lib/dns/exceptions.cc (original)
+++ branches/trac354/src/lib/dns/exceptions.cc Fri Oct  1 04:26:22 2010
@@ -15,7 +15,7 @@
 // $Id$
 
 #include <dns/exceptions.h>
-#include <dns/message.h>
+#include <dns/rcode.h>
 
 namespace isc {
 namespace dns {

Modified: branches/trac354/src/lib/dns/message.cc
==============================================================================
--- branches/trac354/src/lib/dns/message.cc (original)
+++ branches/trac354/src/lib/dns/message.cc Fri Oct  1 04:26:22 2010
@@ -33,6 +33,8 @@
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
 #include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/question.h>
 #include <dns/rdataclass.h>
 #include <dns/rrclass.h>
@@ -62,95 +64,12 @@
 const flags_t FLAG_AD = 0x0020;
 const flags_t FLAG_CD = 0x0010;
 
-//
-// EDNS related constants
-//
-const uint32_t EXTRCODE_MASK = 0xff000000; 
-
 const unsigned int OPCODE_MASK = 0x7800;
 const unsigned int OPCODE_SHIFT = 11;
 const unsigned int RCODE_MASK = 0x000f;
 const unsigned int FLAG_MASK = 0x8ff0;
 
 const unsigned int MESSAGE_REPLYPRESERVE = (FLAG_RD | FLAG_CD);
-
-const Rcode rcodes[] = {
-    Rcode::NOERROR(),
-    Rcode::FORMERR(),
-    Rcode::SERVFAIL(),
-    Rcode::NXDOMAIN(),
-    Rcode::NOTIMP(),
-    Rcode::REFUSED(),
-    Rcode::YXDOMAIN(),
-    Rcode::YXRRSET(),
-    Rcode::NXRRSET(),
-    Rcode::NOTAUTH(),
-    Rcode::NOTZONE(),
-    Rcode::RESERVED11(),
-    Rcode::RESERVED12(),
-    Rcode::RESERVED13(),
-    Rcode::RESERVED14(),
-    Rcode::RESERVED15(),
-    Rcode::BADVERS()
-};
-
-const char *rcodetext[] = {
-    "NOERROR",
-    "FORMERR",
-    "SERVFAIL",
-    "NXDOMAIN",
-    "NOTIMP",
-    "REFUSED",
-    "YXDOMAIN",
-    "YXRRSET",
-    "NXRRSET",
-    "NOTAUTH",
-    "NOTZONE",
-    "RESERVED11",
-    "RESERVED12",
-    "RESERVED13",
-    "RESERVED14",
-    "RESERVED15",
-    "BADVERS"
-};
-
-const Opcode* opcodes[] = {
-    &Opcode::QUERY(),
-    &Opcode::IQUERY(),
-    &Opcode::STATUS(),
-    &Opcode::RESERVED3(),
-    &Opcode::NOTIFY(),
-    &Opcode::UPDATE(),
-    &Opcode::RESERVED6(),
-    &Opcode::RESERVED7(),
-    &Opcode::RESERVED8(),
-    &Opcode::RESERVED9(),
-    &Opcode::RESERVED10(),
-    &Opcode::RESERVED11(),
-    &Opcode::RESERVED12(),
-    &Opcode::RESERVED13(),
-    &Opcode::RESERVED14(),
-    &Opcode::RESERVED15()
-};
-
-const char *opcodetext[] = {
-    "QUERY",
-    "IQUERY",
-    "STATUS",
-    "RESERVED3",
-    "NOTIFY",
-    "UPDATE",
-    "RESERVED6",
-    "RESERVED7",
-    "RESERVED8",
-    "RESERVED9",
-    "RESERVED10",
-    "RESERVED11",
-    "RESERVED12",
-    "RESERVED13",
-    "RESERVED14",
-    "RESERVED15"
-};
 
 const char *sectiontext[] = {
     "QUESTION",
@@ -158,55 +77,6 @@
     "AUTHORITY",
     "ADDITIONAL"
 };
-}
-
-string
-Opcode::toText() const {
-    return (opcodetext[code_]);
-}
-
-namespace {
-// This diagram shows the wire-format representation of the 12-bit extended
-// form RCODEs and its relationship with implementation specific parameters.
-//
-//     0     3               11      15
-//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//    |UNUSED | EXTENDED-RCODE | RCODE |
-//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//                            <= EXTRCODE_SHIFT (4 bits)
-const unsigned int EXTRCODE_SHIFT = 4;
-}
-
-Rcode::Rcode(const uint16_t code) : code_(code) {
-    if (code_ > MAX_RCODE) {
-        isc_throw(OutOfRange, "Rcode is too large to construct: " << code_);
-    }
-}
-
-Rcode::Rcode(const uint8_t code, const uint8_t extended_code) :
-    code_((extended_code << EXTRCODE_SHIFT) | (code & RCODE_MASK))
-{
-    if (code > RCODE_MASK) {
-        isc_throw(OutOfRange,
-                  "Base Rcode is too large to construct: "
-                  << static_cast<unsigned int>(code));
-    }
-}
-
-uint8_t
-Rcode::getExtendedCode() const {
-    return (code_ >> EXTRCODE_SHIFT);
-}
-
-string
-Rcode::toText() const {
-    if (code_ < sizeof(rcodetext) / sizeof (const char *)) {
-        return (rcodetext[code_]);
-    }
-
-    ostringstream oss;
-    oss << code_;
-    return (oss.str());
 }
 
 namespace {
@@ -225,8 +95,16 @@
     // for efficiency?
     Message::Mode mode_;
     qid_t qid_;
-    Rcode rcode_;
+
+    // We want to use NULL for [op,r]code_ to mean the code being not
+    // correctly parsed or set.  We store the real code object in
+    // xxcode_placeholder_ and have xxcode_ refer to it when the object
+    // is valid.
+    const Rcode* rcode_;
+    Rcode rcode_placeholder_;
     const Opcode* opcode_;
+    Opcode opcode_placeholder_;
+
     flags_t flags_;
 
     bool header_parsed_;
@@ -242,12 +120,16 @@
 #endif
 
     void init();
+    void setOpcode(const Opcode& opcode);
+    void setRcode(const Rcode& rcode);
     int parseQuestion(InputBuffer& buffer);
     int parseSection(const Section& section, InputBuffer& buffer);
 };
 
 MessageImpl::MessageImpl(Message::Mode mode) :
-    mode_(mode), rcode_(Rcode::NOERROR())
+    mode_(mode),
+    rcode_placeholder_(Rcode(0)), // as a placeholder the value doesn't matter
+    opcode_placeholder_(Opcode(0)) // ditto
 {
     init();
 }
@@ -256,7 +138,7 @@
 MessageImpl::init() {
     flags_ = 0;
     qid_ = 0;
-    rcode_ = Rcode::NOERROR();  // XXX
+    rcode_ = NULL;
     opcode_ = NULL;
     edns_ = EDNSPtr();
 
@@ -271,6 +153,18 @@
     rrsets_[sectionCodeToId(Section::ADDITIONAL())].clear();
 }
 
+void
+MessageImpl::setOpcode(const Opcode& opcode) {
+    opcode_placeholder_ = opcode;
+    opcode_ = &opcode_placeholder_;
+}
+
+void
+MessageImpl::setRcode(const Rcode& rcode) {
+    rcode_placeholder_ = rcode;
+    rcode_ = &rcode_placeholder_;
+}
+
 Message::Message(Mode mode) :
     impl_(new MessageImpl(mode))
 {}
@@ -318,7 +212,10 @@
 
 const Rcode&
 Message::getRcode() const {
-    return (impl_->rcode_);
+    if (impl_->rcode_ == NULL) {
+        isc_throw(InvalidMessageOperation, "getRcode attempted before set");
+    }
+    return (*impl_->rcode_);
 }
 
 void
@@ -327,11 +224,14 @@
         isc_throw(InvalidMessageOperation,
                   "setRcode performed in non-render mode");
     }
-    impl_->rcode_ = rcode;
+    impl_->setRcode(rcode);
 }
 
 const Opcode&
 Message::getOpcode() const {
+    if (impl_->opcode_ == NULL) {
+        isc_throw(InvalidMessageOperation, "getOpcode attempted before set");
+    }
     return (*impl_->opcode_);
 }
 
@@ -341,7 +241,7 @@
         isc_throw(InvalidMessageOperation,
                   "setOpcode performed in non-render mode");
     }
-    impl_->opcode_ = &opcode;
+    impl_->setOpcode(opcode);
 }
 
 ConstEDNSPtr
@@ -446,6 +346,14 @@
         isc_throw(InvalidMessageOperation,
                   "Message rendering attempted in non render mode");
     }
+    if (impl_->rcode_ == NULL) {
+        isc_throw(InvalidMessageOperation,
+                  "Message rendering attempted without Rcode set");
+    }
+    if (impl_->opcode_ == NULL) {
+        isc_throw(InvalidMessageOperation,
+                  "Message rendering attempted without Opcode set");
+    }
 
     // reserve room for the header
     renderer.skip(HEADERLEN);
@@ -484,12 +392,12 @@
     // no EDNS has been set we generate a temporary local EDNS and use it.
     if (!renderer.isTruncated()) {
         ConstEDNSPtr local_edns = impl_->edns_;
-        if (!local_edns && impl_->rcode_.getExtendedCode() != 0) {
+        if (!local_edns && impl_->rcode_->getExtendedCode() != 0) {
             local_edns = ConstEDNSPtr(new EDNS());
         }
         if (local_edns) {
             arcount += local_edns->toWire(renderer,
-                                          impl_->rcode_.getExtendedCode());
+                                          impl_->rcode_->getExtendedCode());
         }
     }
  
@@ -512,7 +420,7 @@
 
     uint16_t codes_and_flags =
         (impl_->opcode_->getCode() << OPCODE_SHIFT) & OPCODE_MASK;
-    codes_and_flags |= (impl_->rcode_.getCode() & RCODE_MASK);
+    codes_and_flags |= (impl_->rcode_->getCode() & RCODE_MASK);
     codes_and_flags |= (impl_->flags_ & FLAG_MASK);
     renderer.writeUint16At(codes_and_flags, header_pos);
     header_pos += sizeof(uint16_t);
@@ -541,8 +449,8 @@
 
     impl_->qid_ = buffer.readUint16();
     const uint16_t codes_and_flags = buffer.readUint16();
-    impl_->opcode_ = opcodes[((codes_and_flags & OPCODE_MASK) >> OPCODE_SHIFT)];
-    impl_->rcode_ = rcodes[(codes_and_flags & RCODE_MASK)];
+    impl_->setOpcode(Opcode((codes_and_flags & OPCODE_MASK) >> OPCODE_SHIFT));
+    impl_->setRcode(Rcode(codes_and_flags & RCODE_MASK));
     impl_->flags_ = (codes_and_flags & FLAG_MASK);
     impl_->counts_[Section::QUESTION().getCode()] = buffer.readUint16();
     impl_->counts_[Section::ANSWER().getCode()] = buffer.readUint16();
@@ -677,7 +585,7 @@
             uint8_t extended_rcode;
             edns_ = ConstEDNSPtr(createEDNSFromRR(name, rrclass, rrtype, ttl,
                                                   *rdata, extended_rcode));
-            rcode_ = Rcode(rcode_.getCode(), extended_rcode);
+            setRcode(Rcode(rcode_->getCode(), extended_rcode));
             continue;
         } else {
             vector<RRsetPtr>::iterator it =
@@ -718,11 +626,20 @@
 
 string
 Message::toText() const {
+    if (impl_->rcode_ == NULL) {
+        isc_throw(InvalidMessageOperation,
+                  "Message::toText() attempted without Rcode set");
+    }
+    if (impl_->opcode_ == NULL) {
+        isc_throw(InvalidMessageOperation,
+                  "Message::toText() attempted without Opcode set");
+    }
+
     string s;
 
     s += ";; ->>HEADER<<- opcode: " + impl_->opcode_->toText();
     // for simplicity we don't consider extended rcode (unlike BIND9)
-    s += ", status: " + impl_->rcode_.toText();
+    s += ", status: " + impl_->rcode_->toText();
     s += ", id: " + boost::lexical_cast<string>(impl_->qid_);
     s += "\n;; flags: ";
     if (getHeaderFlag(MessageFlag::QR()))
@@ -948,16 +865,6 @@
 }
 
 ostream&
-operator<<(ostream& os, const Opcode& opcode) {
-    return (os << opcode.toText());
-}
-
-ostream&
-operator<<(ostream& os, const Rcode& rcode) {
-    return (os << rcode.toText());
-}
-
-ostream&
 operator<<(ostream& os, const Message& message) {
     return (os << message.toText());
 }

Modified: branches/trac354/src/lib/dns/message.h
==============================================================================
--- branches/trac354/src/lib/dns/message.h (original)
+++ branches/trac354/src/lib/dns/message.h Fri Oct  1 04:26:22 2010
@@ -82,6 +82,8 @@
 class MessageRenderer;
 class Message;
 class MessageImpl;
+class Opcode;
+class Rcode;
 
 template <typename T>
 struct SectionIteratorImpl;
@@ -160,312 +162,6 @@
     return (f);
 }
 
-/// \brief The \c Opcode class objects represent standard OPCODEs
-/// of the header section of DNS messages.
-///
-/// Note: since there are only 15 possible values, it may make more sense to
-/// simply define an enum type to represent these values.
-///
-/// Constant objects are defined for standard flags.
-class Opcode {
-public:
-    uint16_t getCode() const { return (code_); }
-    bool operator==(const Opcode& other) const
-    { return (code_ == other.code_); }
-    bool operator!=(const Opcode& other) const
-    { return (code_ != other.code_); }
-    std::string toText() const;
-    static const Opcode& QUERY();
-    static const Opcode& IQUERY();
-    static const Opcode& STATUS();
-    static const Opcode& RESERVED3();
-    static const Opcode& NOTIFY();
-    static const Opcode& UPDATE();
-    static const Opcode& RESERVED6();
-    static const Opcode& RESERVED7();
-    static const Opcode& RESERVED8();
-    static const Opcode& RESERVED9();
-    static const Opcode& RESERVED10();
-    static const Opcode& RESERVED11();
-    static const Opcode& RESERVED12();
-    static const Opcode& RESERVED13();
-    static const Opcode& RESERVED14();
-    static const Opcode& RESERVED15();
-private:
-    Opcode(uint16_t code) : code_(code) {}
-    uint16_t code_;
-};
-
-inline const Opcode&
-Opcode::QUERY()
-{
-    static Opcode c(0);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::IQUERY()
-{
-    static Opcode c(1);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::STATUS()
-{
-    static Opcode c(2);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED3()
-{
-    static Opcode c(3);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::NOTIFY()
-{
-    static Opcode c(4);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::UPDATE()
-{
-    static Opcode c(5);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED6()
-{
-    static Opcode c(6);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED7()
-{
-    static Opcode c(7);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED8()
-{
-    static Opcode c(8);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED9()
-{
-    static Opcode c(9);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED10()
-{
-    static Opcode c(10);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED11()
-{
-    static Opcode c(11);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED12()
-{
-    static Opcode c(12);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED13()
-{
-    static Opcode c(13);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED14()
-{
-    static Opcode c(14);
-    return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED15()
-{
-    static Opcode c(15);
-    return (c);
-}
-
-/// \brief The \c Rcode class objects represent standard Response Codes
-/// (RCODEs) of the header section of DNS messages, and extended response
-/// codes as defined in the EDNS specification.
-///
-/// Constant objects are defined for standard flags.
-class Rcode {
-public:
-    Rcode(const uint16_t code);
-    Rcode(const uint8_t code, const uint8_t extended_code);
-    uint16_t getCode() const { return (code_); }
-    uint8_t getExtendedCode() const;
-    bool operator==(const Rcode& other) const { return (code_ == other.code_); }
-    bool operator!=(const Rcode& other) const { return (code_ != other.code_); }
-    std::string toText() const;
-    static const Rcode& NOERROR();
-    static const Rcode& FORMERR();
-    static const Rcode& SERVFAIL();
-    static const Rcode& NXDOMAIN();
-    static const Rcode& NOTIMP();
-    static const Rcode& REFUSED();
-    static const Rcode& YXDOMAIN();
-    static const Rcode& YXRRSET();
-    static const Rcode& NXRRSET();
-    static const Rcode& NOTAUTH();
-    static const Rcode& NOTZONE();
-    static const Rcode& RESERVED11();
-    static const Rcode& RESERVED12();
-    static const Rcode& RESERVED13();
-    static const Rcode& RESERVED14();
-    static const Rcode& RESERVED15();
-    // Extended Rcodes follow (EDNS required):
-    static const Rcode& BADVERS();
-private:
-    uint16_t code_;
-
-    // EDNS-extended RCODEs are 12-bit unsigned integers.
-    static const uint16_t MAX_RCODE = 0xfff;
-};
-
-inline const Rcode&
-Rcode::NOERROR()
-{
-    static Rcode c(0);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::FORMERR()
-{
-    static Rcode c(1);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::SERVFAIL()
-{
-    static Rcode c(2);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::NXDOMAIN()
-{
-    static Rcode c(3);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::NOTIMP()
-{
-    static Rcode c(4);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::REFUSED()
-{
-    static Rcode c(5);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::YXDOMAIN()
-{
-    static Rcode c(6);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::YXRRSET()
-{
-    static Rcode c(7);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::NXRRSET()
-{
-    static Rcode c(8);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::NOTAUTH()
-{
-    static Rcode c(9);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::NOTZONE()
-{
-    static Rcode c(10);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED11()
-{
-    static Rcode c(11);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED12()
-{
-    static Rcode c(12);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED13()
-{
-    static Rcode c(13);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED14()
-{
-    static Rcode c(14);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED15()
-{
-    static Rcode c(15);
-    return (c);
-}
-
-inline const Rcode&
-Rcode::BADVERS()
-{
-    static Rcode c(16);
-    return (c);
-}
-
 /// \brief The \c Section class objects represent DNS message sections such
 /// as the header, question, or answer.
 ///
@@ -644,6 +340,11 @@
     /// included).  In the \c PARSE mode, if the received message contains
     /// an EDNS OPT RR, the corresponding extended code is identified and
     /// returned.
+    ///
+    /// The message must have been properly parsed (in the case of the
+    /// \c PARSE mode) or an \c Rcode has been set (in the case of the
+    /// \c RENDER mode) beforehand.  Otherwise, an exception of class
+    /// \c InvalidMessageOperation will be thrown.
     const Rcode& getRcode() const;
 
     /// \brief Set the Response Code of the message.
@@ -655,6 +356,11 @@
     void setRcode(const Rcode& rcode);
 
     /// \brief Return the OPCODE given in the header section of the message.
+    ///
+    /// The message must have been properly parsed (in the case of the
+    /// \c PARSE mode) or an \c Opcode has been set (in the case of the
+    /// \c RENDER mode) beforehand.  Otherwise, an exception of class
+    /// \c InvalidMessageOperation will be thrown.
     const Opcode& getOpcode() const;
 
     /// \brief Set the OPCODE of the header section of the message.
@@ -750,10 +456,19 @@
     void makeResponse();
 
     /// \brief Convert the Message to a string.
+    ///
+    /// At least \c Opcode and \c Rcode must be validly set in the \c Message
+    /// (as a result of parse in the \c PARSE mode or by explicitly setting
+    /// in the \c RENDER mode);  otherwise, an exception of
+    /// class \c InvalidMessageOperation will be thrown.
     std::string toText() const;
 
     /// \brief Render the message in wire formant into a \c MessageRenderer
     /// object.
+    ///
+    /// This \c Message must be in the \c RENDER mode and both \c Opcode and
+    /// \c Rcode must have been set beforehand; otherwise, an exception of
+    /// class \c InvalidMessageOperation will be thrown.
     void toWire(MessageRenderer& renderer);
 
     /// \brief Parse the header section of the \c Message.
@@ -780,8 +495,6 @@
     MessageImpl* impl_;
 };
 
-std::ostream& operator<<(std::ostream& os, const Opcode& opcode);
-std::ostream& operator<<(std::ostream& os, const Rcode& rcode);
 std::ostream& operator<<(std::ostream& os, const Message& message);
 }
 }

Modified: branches/trac354/src/lib/dns/python/Makefile.am
==============================================================================
--- branches/trac354/src/lib/dns/python/Makefile.am (original)
+++ branches/trac354/src/lib/dns/python/Makefile.am Fri Oct  1 04:26:22 2010
@@ -16,6 +16,8 @@
 EXTRA_DIST += message_python.cc
 EXTRA_DIST += rrclass_python.cc
 EXTRA_DIST += name_python.cc
+EXTRA_DIST += opcode_python.cc
+EXTRA_DIST += rcode_python.cc
 EXTRA_DIST += rrset_python.cc
 EXTRA_DIST += question_python.cc
 EXTRA_DIST += rrttl_python.cc

Modified: branches/trac354/src/lib/dns/python/message_python.cc
==============================================================================
--- branches/trac354/src/lib/dns/python/message_python.cc (original)
+++ branches/trac354/src/lib/dns/python/message_python.cc Fri Oct  1 04:26:22 2010
@@ -188,594 +188,6 @@
 //
 // End of MessageFlag wrapper
 //
-
-
-//
-// Opcode
-//
-class s_Opcode : public PyObject {
-public:
-    const Opcode* opcode;
-};
-
-static int Opcode_init(s_Opcode* self, PyObject* args);
-static void Opcode_destroy(s_Opcode* self);
-
-static PyObject* Opcode_getCode(s_Opcode* self);
-static PyObject* Opcode_toText(s_Opcode* self);
-static PyObject* Opcode_str(PyObject* self);
-static PyObject* Opcode_QUERY(s_Opcode* self);
-static PyObject* Opcode_IQUERY(s_Opcode* self);
-static PyObject* Opcode_STATUS(s_Opcode* self);
-static PyObject* Opcode_RESERVED3(s_Opcode* self);
-static PyObject* Opcode_NOTIFY(s_Opcode* self);
-static PyObject* Opcode_UPDATE(s_Opcode* self);
-static PyObject* Opcode_RESERVED6(s_Opcode* self);
-static PyObject* Opcode_RESERVED7(s_Opcode* self);
-static PyObject* Opcode_RESERVED8(s_Opcode* self);
-static PyObject* Opcode_RESERVED9(s_Opcode* self);
-static PyObject* Opcode_RESERVED10(s_Opcode* self);
-static PyObject* Opcode_RESERVED11(s_Opcode* self);
-static PyObject* Opcode_RESERVED12(s_Opcode* self);
-static PyObject* Opcode_RESERVED13(s_Opcode* self);
-static PyObject* Opcode_RESERVED14(s_Opcode* self);
-static PyObject* Opcode_RESERVED15(s_Opcode* self);
-static PyObject* Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op);
-
-static PyMethodDef Opcode_methods[] = {
-    { "get_code", reinterpret_cast<PyCFunction>(Opcode_getCode), METH_NOARGS, "Returns the code value" },
-    { "to_text", reinterpret_cast<PyCFunction>(Opcode_toText), METH_NOARGS, "Returns the text representation" },
-    { "QUERY", reinterpret_cast<PyCFunction>(Opcode_QUERY), METH_NOARGS | METH_STATIC, "Creates a QUERY Opcode" },
-    { "IQUERY", reinterpret_cast<PyCFunction>(Opcode_IQUERY), METH_NOARGS | METH_STATIC, "Creates a IQUERY Opcode" },
-    { "STATUS", reinterpret_cast<PyCFunction>(Opcode_STATUS), METH_NOARGS | METH_STATIC, "Creates a STATUS Opcode" },
-    { "RESERVED3", reinterpret_cast<PyCFunction>(Opcode_RESERVED3), METH_NOARGS | METH_STATIC, "Creates a RESERVED3 Opcode" },
-    { "NOTIFY", reinterpret_cast<PyCFunction>(Opcode_NOTIFY), METH_NOARGS | METH_STATIC, "Creates a NOTIFY Opcode" },
-    { "UPDATE", reinterpret_cast<PyCFunction>(Opcode_UPDATE), METH_NOARGS | METH_STATIC, "Creates a UPDATE Opcode" },
-    { "RESERVED6", reinterpret_cast<PyCFunction>(Opcode_RESERVED6), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED7", reinterpret_cast<PyCFunction>(Opcode_RESERVED7), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED8", reinterpret_cast<PyCFunction>(Opcode_RESERVED8), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED9", reinterpret_cast<PyCFunction>(Opcode_RESERVED9), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED10", reinterpret_cast<PyCFunction>(Opcode_RESERVED10), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED11", reinterpret_cast<PyCFunction>(Opcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED12", reinterpret_cast<PyCFunction>(Opcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED13", reinterpret_cast<PyCFunction>(Opcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED14", reinterpret_cast<PyCFunction>(Opcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { "RESERVED15", reinterpret_cast<PyCFunction>(Opcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
-    { NULL, NULL, 0, NULL }
-};
-
-static PyTypeObject opcode_type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "pydnspp.Opcode",
-    sizeof(s_Opcode),                   // tp_basicsize
-    0,                                  // tp_itemsize
-    (destructor)Opcode_destroy,         // tp_dealloc
-    NULL,                               // tp_print
-    NULL,                               // tp_getattr
-    NULL,                               // tp_setattr
-    NULL,                               // tp_reserved
-    NULL,                               // tp_repr
-    NULL,                               // tp_as_number
-    NULL,                               // tp_as_sequence
-    NULL,                               // tp_as_mapping
-    NULL,                               // tp_hash 
-    NULL,                               // tp_call
-    Opcode_str,                         // tp_str
-    NULL,                               // tp_getattro
-    NULL,                               // tp_setattro
-    NULL,                               // tp_as_buffer
-    Py_TPFLAGS_DEFAULT,                 // tp_flags
-    "The Opcode class objects represent standard OPCODEs "
-    "of the header section of DNS messages.",
-    NULL,                               // tp_traverse
-    NULL,                               // tp_clear
-    (richcmpfunc)Opcode_richcmp,        // tp_richcompare
-    0,                                  // tp_weaklistoffset
-    NULL,                               // tp_iter
-    NULL,                               // tp_iternext
-    Opcode_methods,                     // tp_methods
-    NULL,                               // tp_members
-    NULL,                               // tp_getset
-    NULL,                               // tp_base
-    NULL,                               // tp_dict
-    NULL,                               // tp_descr_get
-    NULL,                               // tp_descr_set
-    0,                                  // tp_dictoffset
-    (initproc)Opcode_init,              // tp_init
-    NULL,                               // tp_alloc
-    PyType_GenericNew,                  // tp_new
-    NULL,                               // tp_free
-    NULL,                               // tp_is_gc
-    NULL,                               // tp_bases
-    NULL,                               // tp_mro
-    NULL,                               // tp_cache
-    NULL,                               // tp_subclasses
-    NULL,                               // tp_weaklist
-    NULL,                               // tp_del
-    0                                   // tp_version_tag
-};
-
-
-static int
-Opcode_init(s_Opcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
-    PyErr_SetString(PyExc_NotImplementedError,
-                    "Opcode can't be built directly");
-    return (-1);
-}
-
-static void
-Opcode_destroy(s_Opcode* self) {
-    // We only use the consts from Opcode, so don't
-    // delete self->opcode here
-    self->opcode = NULL;
-    Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject*
-Opcode_getCode(s_Opcode* self) {
-    return (Py_BuildValue("I", self->opcode->getCode()));
-}
-
-static PyObject*
-Opcode_toText(s_Opcode* self) {
-    return (Py_BuildValue("s", self->opcode->toText().c_str()));
-}
-
-static PyObject*
-Opcode_str(PyObject* self) {
-    // Simply call the to_text method we already defined
-    return (PyObject_CallMethod(self,
-                               const_cast<char*>("to_text"),
-                                const_cast<char*>("")));
-}
-
-static PyObject*
-Opcode_createStatic(const Opcode& opcode) {
-    s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
-    if (ret != NULL) {
-        ret->opcode = &opcode;
-    }
-    return (ret);
-}
-
-static PyObject*
-Opcode_QUERY(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::QUERY()));
-}
-
-static PyObject*
-Opcode_IQUERY(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::IQUERY()));
-}
-
-static PyObject*
-Opcode_STATUS(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::STATUS()));
-}
-
-static PyObject*
-Opcode_RESERVED3(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED3()));
-}
-
-static PyObject*
-Opcode_NOTIFY(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::NOTIFY()));
-}
-
-static PyObject*
-Opcode_UPDATE(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::UPDATE()));
-}
-
-static PyObject*
-Opcode_RESERVED6(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED6()));
-}
-
-static PyObject*
-Opcode_RESERVED7(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED7()));
-}
-
-static PyObject*
-Opcode_RESERVED8(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED8()));
-}
-
-static PyObject*
-Opcode_RESERVED9(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED9()));
-}
-
-static PyObject*
-Opcode_RESERVED10(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED10()));
-}
-
-static PyObject*
-Opcode_RESERVED11(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED11()));
-}
-
-static PyObject*
-Opcode_RESERVED12(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED12()));
-}
-
-static PyObject*
-Opcode_RESERVED13(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED13()));
-}
-
-static PyObject*
-Opcode_RESERVED14(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED14()));
-}
-
-static PyObject*
-Opcode_RESERVED15(s_Opcode* self UNUSED_PARAM) {
-    return (Opcode_createStatic(Opcode::RESERVED15()));
-}
-
-static PyObject* 
-Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op) {
-    bool c = false;
-
-    // Check for null and if the types match. If different type,
-    // simply return False
-    if (!other || (self->ob_type != other->ob_type)) {
-        Py_RETURN_FALSE;
-    }
-
-    // Only equals and not equals here, unorderable type
-    switch (op) {
-    case Py_LT:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
-        return (NULL);
-        break;
-    case Py_LE:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
-        return (NULL);
-        break;
-    case Py_EQ:
-        c = (*self->opcode == *other->opcode);
-        break;
-    case Py_NE:
-        c = (*self->opcode != *other->opcode);
-        break;
-    case Py_GT:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
-        return (NULL);
-        break;
-    case Py_GE:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
-        return (NULL);
-        break;
-    }
-    if (c)
-        Py_RETURN_TRUE;
-    else
-        Py_RETURN_FALSE;
-}
-
-//
-// End of Opcode wrapper
-//
-
-//
-// Rcode
-//
-
-// We added a helper variable static_code here
-// Since we can create Rcodes dynamically with Rcode(int), but also
-// use the static globals (Rcode::NOERROR() etc), we use this
-// variable to see if the code came from one of the latter, in which
-// case Rcode_destroy should not free it (the other option is to
-// allocate new Rcodes for every use of the static ones, but this
-// seems more efficient).
-class s_Rcode : public PyObject {
-public:
-    const Rcode* rcode;
-    bool static_code;
-};
-
-static int Rcode_init(s_Rcode* self, PyObject* args);
-static void Rcode_destroy(s_Rcode* self);
-
-static PyObject* Rcode_getCode(s_Rcode* self);
-static PyObject* Rcode_getExtendedCode(const s_Rcode* self);
-static PyObject* Rcode_toText(s_Rcode* self);
-static PyObject* Rcode_str(PyObject* self);
-static PyObject* Rcode_NOERROR(s_Rcode* self);
-static PyObject* Rcode_FORMERR(s_Rcode* self);
-static PyObject* Rcode_SERVFAIL(s_Rcode* self);
-static PyObject* Rcode_NXDOMAIN(s_Rcode* self);
-static PyObject* Rcode_NOTIMP(s_Rcode* self);
-static PyObject* Rcode_REFUSED(s_Rcode* self);
-static PyObject* Rcode_YXDOMAIN(s_Rcode* self);
-static PyObject* Rcode_YXRRSET(s_Rcode* self);
-static PyObject* Rcode_NXRRSET(s_Rcode* self);
-static PyObject* Rcode_NOTAUTH(s_Rcode* self);
-static PyObject* Rcode_NOTZONE(s_Rcode* self);
-static PyObject* Rcode_RESERVED11(s_Rcode* self);
-static PyObject* Rcode_RESERVED12(s_Rcode* self);
-static PyObject* Rcode_RESERVED13(s_Rcode* self);
-static PyObject* Rcode_RESERVED14(s_Rcode* self);
-static PyObject* Rcode_RESERVED15(s_Rcode* self);
-static PyObject* Rcode_BADVERS(s_Rcode* self);
-static PyObject* Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op);
-
-static PyMethodDef Rcode_methods[] = {
-    { "get_code", reinterpret_cast<PyCFunction>(Rcode_getCode), METH_NOARGS, "Returns the code value" },
-    { "get_extended_code",
-      reinterpret_cast<PyCFunction>(Rcode_getExtendedCode),
-      METH_NOARGS, "Returns the extended code value." },
-    { "to_text", reinterpret_cast<PyCFunction>(Rcode_toText), METH_NOARGS, "Returns the text representation" },
-    { "NOERROR", reinterpret_cast<PyCFunction>(Rcode_NOERROR), METH_NOARGS | METH_STATIC, "Creates a NOERROR Rcode" },
-    { "FORMERR", reinterpret_cast<PyCFunction>(Rcode_FORMERR), METH_NOARGS | METH_STATIC, "Creates a FORMERR Rcode" },
-    { "SERVFAIL", reinterpret_cast<PyCFunction>(Rcode_SERVFAIL), METH_NOARGS | METH_STATIC, "Creates a SERVFAIL Rcode" },
-    { "NXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_NXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a NXDOMAIN Rcode" },
-    { "NOTIMP", reinterpret_cast<PyCFunction>(Rcode_NOTIMP), METH_NOARGS | METH_STATIC, "Creates a NOTIMP Rcode" },
-    { "REFUSED", reinterpret_cast<PyCFunction>(Rcode_REFUSED), METH_NOARGS | METH_STATIC, "Creates a REFUSED Rcode" },
-    { "YXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_YXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "YXRRSET", reinterpret_cast<PyCFunction>(Rcode_YXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "NXRRSET", reinterpret_cast<PyCFunction>(Rcode_NXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "NOTAUTH", reinterpret_cast<PyCFunction>(Rcode_NOTAUTH), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "NOTZONE", reinterpret_cast<PyCFunction>(Rcode_NOTZONE), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "RESERVED11", reinterpret_cast<PyCFunction>(Rcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "RESERVED12", reinterpret_cast<PyCFunction>(Rcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "RESERVED13", reinterpret_cast<PyCFunction>(Rcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "RESERVED14", reinterpret_cast<PyCFunction>(Rcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "RESERVED15", reinterpret_cast<PyCFunction>(Rcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
-    { "BADVERS", reinterpret_cast<PyCFunction>(Rcode_BADVERS), METH_NOARGS | METH_STATIC, "Creates a BADVERS Rcode" },
-    { NULL, NULL, 0, NULL }
-};
-
-static PyTypeObject rcode_type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "pydnspp.Rcode",
-    sizeof(s_Rcode),                    // tp_basicsize
-    0,                                  // tp_itemsize
-    (destructor)Rcode_destroy,          // tp_dealloc
-    NULL,                               // tp_print
-    NULL,                               // tp_getattr
-    NULL,                               // tp_setattr
-    NULL,                               // tp_reserved
-    NULL,                               // tp_repr
-    NULL,                               // tp_as_number
-    NULL,                               // tp_as_sequence
-    NULL,                               // tp_as_mapping
-    NULL,                               // tp_hash 
-    NULL,                               // tp_call
-    Rcode_str,                          // tp_str
-    NULL,                               // tp_getattro
-    NULL,                               // tp_setattro
-    NULL,                               // tp_as_buffer
-    Py_TPFLAGS_DEFAULT,                 // tp_flags
-    "The Rcode class objects represent standard RCODEs"
-    "of the header section of DNS messages.",
-    NULL,                               // tp_traverse
-    NULL,                               // tp_clear
-    (richcmpfunc)Rcode_richcmp,         // tp_richcompare
-    0,                                  // tp_weaklistoffset
-    NULL,                               // tp_iter
-    NULL,                               // tp_iternext
-    Rcode_methods,                      // tp_methods
-    NULL,                               // tp_members
-    NULL,                               // tp_getset
-    NULL,                               // tp_base
-    NULL,                               // tp_dict
-    NULL,                               // tp_descr_get
-    NULL,                               // tp_descr_set
-    0,                                  // tp_dictoffset
-    (initproc)Rcode_init,               // tp_init
-    NULL,                               // tp_alloc
-    PyType_GenericNew,                  // tp_new
-    NULL,                               // tp_free
-    NULL,                               // tp_is_gc
-    NULL,                               // tp_bases
-    NULL,                               // tp_mro
-    NULL,                               // tp_cache
-    NULL,                               // tp_subclasses
-    NULL,                               // tp_weaklist
-    NULL,                               // tp_del
-    0                                   // tp_version_tag
-};
-
-
-static int
-Rcode_init(s_Rcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
-    uint16_t code = 0;
-    if (PyArg_ParseTuple(args, "h", &code)) {
-        try {
-            self->rcode = new Rcode(code);
-            self->static_code = false;
-        } catch (const isc::OutOfRange&) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "rcode out of range");
-            return (-1);
-        }
-        return (0);
-    } else {
-        return (-1);
-    }
-}
-
-static void
-Rcode_destroy(s_Rcode* self) {
-    // Depending on whether we created the rcode or are referring
-    // to a global static one, we do or do not delete self->rcode here
-    if (!self->static_code) {
-        delete self->rcode;
-    }
-    self->rcode = NULL;
-    Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject*
-Rcode_getCode(s_Rcode* self) {
-    return (Py_BuildValue("I", self->rcode->getCode()));
-}
-
-static PyObject*
-Rcode_getExtendedCode(const s_Rcode* self) {
-    return (Py_BuildValue("B", self->rcode->getExtendedCode()));
-}
-
-static PyObject*
-Rcode_toText(s_Rcode* self) {
-    return (Py_BuildValue("s", self->rcode->toText().c_str()));
-}
-
-static PyObject*
-Rcode_str(PyObject* self) {
-    // Simply call the to_text method we already defined
-    return (PyObject_CallMethod(self,
-                               const_cast<char*>("to_text"),
-                                const_cast<char*>("")));
-}
-
-static PyObject*
-Rcode_createStatic(const Rcode& rcode) {
-    s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
-    if (ret != NULL) {
-        ret->rcode = &rcode;
-        ret->static_code = true;
-    }
-    return (ret);
-}
-
-static PyObject*
-Rcode_NOERROR(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NOERROR()));
-}
-
-static PyObject*
-Rcode_FORMERR(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::FORMERR()));
-}
-
-static PyObject*
-Rcode_SERVFAIL(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::SERVFAIL()));
-}
-
-static PyObject*
-Rcode_NXDOMAIN(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NXDOMAIN()));
-}
-
-static PyObject*
-Rcode_NOTIMP(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NOTIMP()));
-}
-
-static PyObject*
-Rcode_REFUSED(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::REFUSED()));
-}
-
-static PyObject*
-Rcode_YXDOMAIN(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::YXDOMAIN()));
-}
-
-static PyObject*
-Rcode_YXRRSET(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::YXRRSET()));
-}
-
-static PyObject*
-Rcode_NXRRSET(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NXRRSET()));
-}
-
-static PyObject*
-Rcode_NOTAUTH(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NOTAUTH()));
-}
-
-static PyObject*
-Rcode_NOTZONE(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::NOTZONE()));
-}
-
-static PyObject*
-Rcode_RESERVED11(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::RESERVED11()));
-}
-
-static PyObject*
-Rcode_RESERVED12(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::RESERVED12()));
-}
-
-static PyObject*
-Rcode_RESERVED13(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::RESERVED13()));
-}
-
-static PyObject*
-Rcode_RESERVED14(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::RESERVED14()));
-}
-
-static PyObject*
-Rcode_RESERVED15(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::RESERVED15()));
-}
-
-static PyObject*
-Rcode_BADVERS(s_Rcode* self UNUSED_PARAM) {
-    return (Rcode_createStatic(Rcode::BADVERS()));
-}
-
-static PyObject* 
-Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op) {
-    bool c = false;
-
-    // Check for null and if the types match. If different type,
-    // simply return False
-    if (!other || (self->ob_type != other->ob_type)) {
-        Py_RETURN_FALSE;
-    }
-
-    // Only equals and not equals here, unorderable type
-    switch (op) {
-    case Py_LT:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
-        return (NULL);
-        break;
-    case Py_LE:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
-        return (NULL);
-        break;
-    case Py_EQ:
-        c = (*self->rcode == *other->rcode);
-        break;
-    case Py_NE:
-        c = (*self->rcode != *other->rcode);
-        break;
-    case Py_GT:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
-        return (NULL);
-        break;
-    case Py_GE:
-        PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
-        return (NULL);
-        break;
-    }
-    if (c)
-        Py_RETURN_TRUE;
-    else
-        Py_RETURN_FALSE;
-}
-
-//
-// End of Rcode wrapper
-//
-
 
 //
 // Section
@@ -1255,12 +667,18 @@
 
     rcode = static_cast<s_Rcode*>(rcode_type.tp_alloc(&rcode_type, 0));
     if (rcode != NULL) {
-        rcode->rcode = new Rcode(self->message->getRcode());
-        if (rcode->rcode == NULL)
-          {
+        rcode->rcode = NULL;
+        try {
+            rcode->rcode = new Rcode(self->message->getRcode());
+        } catch (const InvalidMessageOperation& imo) {
+            PyErr_SetString(po_InvalidMessageOperation, imo.what());
+        } catch (...) {
+            PyErr_SetString(po_IscException, "Unexpected exception");
+        }
+        if (rcode->rcode == NULL) {
             Py_DECREF(rcode);
             return (NULL);
-          }
+        }
     }
 
     return (rcode);
@@ -1287,15 +705,18 @@
 
     opcode = static_cast<s_Opcode*>(opcode_type.tp_alloc(&opcode_type, 0));
     if (opcode != NULL) {
-        // Note that we do not new and delete for opcodes.
-        // all rcodes point to the statics defined in
-        // message.cc
-        opcode->opcode = &self->message->getOpcode();
-        if (opcode->opcode == NULL)
-          {
+        opcode->opcode = NULL;
+        try {
+            opcode->opcode = new Opcode(self->message->getOpcode());
+        } catch (const InvalidMessageOperation& imo) {
+            PyErr_SetString(po_InvalidMessageOperation, imo.what());
+        } catch (...) {
+            PyErr_SetString(po_IscException, "Unexpected exception");
+        }
+        if (opcode->opcode == NULL) {
             Py_DECREF(opcode);
             return (NULL);
-          }
+        }
     }
 
     return (opcode);
@@ -1486,7 +907,16 @@
 static PyObject*
 Message_toText(s_Message* self) {
     // Py_BuildValue makes python objects from native data
-    return (Py_BuildValue("s", self->message->toText().c_str()));
+    try {
+        return (Py_BuildValue("s", self->message->toText().c_str()));
+    } catch (const InvalidMessageOperation& imo) {
+        PyErr_Clear();
+        PyErr_SetString(po_InvalidMessageOperation, imo.what());
+        return (NULL);
+    } catch (...) {
+        PyErr_SetString(po_IscException, "Unexpected exception");
+        return (NULL);
+    }
 }
 
 static PyObject*

Modified: branches/trac354/src/lib/dns/python/pydnspp.cc
==============================================================================
--- branches/trac354/src/lib/dns/python/pydnspp.cc (original)
+++ branches/trac354/src/lib/dns/python/pydnspp.cc Fri Oct  1 04:26:22 2010
@@ -57,6 +57,8 @@
 #include <dns/python/rrset_python.cc>          // needs Rdata, RRTTL
 #include <dns/python/question_python.cc>       // needs RRClass, RRType, RRTTL,
                                                // Name
+#include <dns/python/opcode_python.cc>
+#include <dns/python/rcode_python.cc>
 #include <dns/python/edns_python.cc>           // needs Messagerenderer, Rcode
 #include <dns/python/message_python.cc>        // needs RRset, Question
 
@@ -128,6 +130,14 @@
         return (NULL);
     }
 
+    if (!initModulePart_Opcode(mod)) {
+        return (NULL);
+    }
+
+    if (!initModulePart_Rcode(mod)) {
+        return (NULL);
+    }
+
     if (!initModulePart_Message(mod)) {
         return (NULL);
     }

Modified: branches/trac354/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- branches/trac354/src/lib/dns/python/tests/Makefile.am (original)
+++ branches/trac354/src/lib/dns/python/tests/Makefile.am Fri Oct  1 04:26:22 2010
@@ -3,6 +3,8 @@
 PYTESTS += messagerenderer_python_test.py
 PYTESTS += name_python_test.py
 PYTESTS += question_python_test.py
+PYTESTS += opcode_python_test.py
+PYTESTS += rcode_python_test.py
 PYTESTS += rdata_python_test.py
 PYTESTS += rrclass_python_test.py
 PYTESTS += rrset_python_test.py

Modified: branches/trac354/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- branches/trac354/src/lib/dns/python/tests/message_python_test.py (original)
+++ branches/trac354/src/lib/dns/python/tests/message_python_test.py Fri Oct  1 04:26:22 2010
@@ -34,163 +34,6 @@
         self.assertEqual(0x0080, MessageFlag.RA().get_bit())
         self.assertEqual(0x0020, MessageFlag.AD().get_bit())
         self.assertEqual(0x0010, MessageFlag.CD().get_bit())
-
-class OpcodeTest(unittest.TestCase):
-    def test_init(self):
-        self.assertRaises(NotImplementedError, Opcode)
-
-    def test_get_code(self):
-        self.assertEqual(0, Opcode.QUERY().get_code())
-        self.assertEqual(1, Opcode.IQUERY().get_code())
-        self.assertEqual(2, Opcode.STATUS().get_code())
-        self.assertEqual(3, Opcode.RESERVED3().get_code())
-        self.assertEqual(4, Opcode.NOTIFY().get_code())
-        self.assertEqual(5, Opcode.UPDATE().get_code())
-        self.assertEqual(6, Opcode.RESERVED6().get_code())
-        self.assertEqual(7, Opcode.RESERVED7().get_code())
-        self.assertEqual(8, Opcode.RESERVED8().get_code())
-        self.assertEqual(9, Opcode.RESERVED9().get_code())
-        self.assertEqual(10, Opcode.RESERVED10().get_code())
-        self.assertEqual(11, Opcode.RESERVED11().get_code())
-        self.assertEqual(12, Opcode.RESERVED12().get_code())
-        self.assertEqual(13, Opcode.RESERVED13().get_code())
-        self.assertEqual(14, Opcode.RESERVED14().get_code())
-        self.assertEqual(15, Opcode.RESERVED15().get_code())
-
-    def test_to_text(self):
-        self.assertEqual("QUERY", Opcode.QUERY().to_text())
-        self.assertEqual("QUERY", str(Opcode.QUERY()))
-        self.assertEqual("IQUERY", Opcode.IQUERY().to_text())
-        self.assertEqual("STATUS", Opcode.STATUS().to_text())
-        self.assertEqual("RESERVED3", Opcode.RESERVED3().to_text())
-        self.assertEqual("NOTIFY", Opcode.NOTIFY().to_text())
-        self.assertEqual("UPDATE", Opcode.UPDATE().to_text())
-        self.assertEqual("RESERVED6", Opcode.RESERVED6().to_text())
-        self.assertEqual("RESERVED7", Opcode.RESERVED7().to_text())
-        self.assertEqual("RESERVED8", Opcode.RESERVED8().to_text())
-        self.assertEqual("RESERVED9", Opcode.RESERVED9().to_text())
-        self.assertEqual("RESERVED10", Opcode.RESERVED10().to_text())
-        self.assertEqual("RESERVED11", Opcode.RESERVED11().to_text())
-        self.assertEqual("RESERVED12", Opcode.RESERVED12().to_text())
-        self.assertEqual("RESERVED13", Opcode.RESERVED13().to_text())
-        self.assertEqual("RESERVED14", Opcode.RESERVED14().to_text())
-        self.assertEqual("RESERVED15", Opcode.RESERVED15().to_text())
-
-    def test_richcmp(self):
-        o1 = Opcode.QUERY()
-        o2 = Opcode.NOTIFY()
-        o3 = Opcode.NOTIFY()
-        self.assertTrue(o2 == o3)
-        self.assertFalse(o2 != o3)
-        self.assertTrue(o1 != o2)
-        self.assertFalse(o1 == 1)
-        self.assertFalse(o1 == o2)
-        # can't use assertRaises here...
-        try:
-            o1 < o2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            o1 <= o2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            o1 > o2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            o1 >= o2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-
-class RcodeTest(unittest.TestCase):
-    def test_init(self):
-        self.assertRaises(TypeError, Rcode, "wrong")
-        self.assertRaises(OverflowError, Rcode, 65536)
-        self.assertEqual(Rcode(0).get_code(), 0)
-    
-        self.assertEqual(0, Rcode(0).get_code())
-        self.assertEqual(0xfff, Rcode(0xfff).get_code()) # possible max code
-    
-        # should fail on attempt of construction with an out of range code
-        self.assertRaises(OverflowError, Rcode, 0x1000)
-        self.assertRaises(OverflowError, Rcode, 0xffff)
-
-    def test_get_code(self):
-        self.assertEqual(0, Rcode.NOERROR().get_code())
-        self.assertEqual(1, Rcode.FORMERR().get_code())
-        self.assertEqual(2, Rcode.SERVFAIL().get_code())
-        self.assertEqual(3, Rcode.NXDOMAIN().get_code())
-        self.assertEqual(4, Rcode.NOTIMP().get_code())
-        self.assertEqual(5, Rcode.REFUSED().get_code())
-        self.assertEqual(6, Rcode.YXDOMAIN().get_code())
-        self.assertEqual(7, Rcode.YXRRSET().get_code())
-        self.assertEqual(8, Rcode.NXRRSET().get_code())
-        self.assertEqual(9, Rcode.NOTAUTH().get_code())
-        self.assertEqual(10, Rcode.NOTZONE().get_code())
-        self.assertEqual(11, Rcode.RESERVED11().get_code())
-        self.assertEqual(12, Rcode.RESERVED12().get_code())
-        self.assertEqual(13, Rcode.RESERVED13().get_code())
-        self.assertEqual(14, Rcode.RESERVED14().get_code())
-        self.assertEqual(15, Rcode.RESERVED15().get_code())
-        self.assertEqual(16, Rcode.BADVERS().get_code())
-
-    def test_to_text(self):
-        self.assertEqual("NOERROR", Rcode(0).to_text())
-        self.assertEqual("NOERROR", str(Rcode(0)))
-        self.assertEqual("FORMERR", Rcode(1).to_text())
-        self.assertEqual("SERVFAIL", Rcode(2).to_text())
-        self.assertEqual("NXDOMAIN", Rcode(3).to_text())
-        self.assertEqual("NOTIMP", Rcode(4).to_text())
-        self.assertEqual("REFUSED", Rcode(5).to_text())
-        self.assertEqual("YXDOMAIN", Rcode(6).to_text())
-        self.assertEqual("YXRRSET", Rcode(7).to_text())
-        self.assertEqual("NXRRSET", Rcode(8).to_text())
-        self.assertEqual("NOTAUTH", Rcode(9).to_text())
-        self.assertEqual("NOTZONE", Rcode(10).to_text())
-        self.assertEqual("RESERVED11", Rcode(11).to_text())
-        self.assertEqual("RESERVED12", Rcode(12).to_text())
-        self.assertEqual("RESERVED13", Rcode(13).to_text())
-        self.assertEqual("RESERVED14", Rcode(14).to_text())
-        self.assertEqual("RESERVED15", Rcode(15).to_text())
-        self.assertEqual("BADVERS", Rcode(16).to_text())
-        
-        self.assertEqual("17", Rcode(Rcode.BADVERS().get_code() + 1).to_text())
-        self.assertEqual("4095", Rcode(0xfff).to_text())
-
-    def test_richcmp(self):
-        r1 = Rcode.NOERROR()
-        r2 = Rcode.FORMERR()
-        r3 = Rcode.FORMERR()
-        self.assertTrue(r2 == r3)
-        self.assertTrue(r1 != r2)
-        self.assertFalse(r1 == r2)
-        self.assertFalse(r1 != 1)
-        # can't use assertRaises here...
-        try:
-            r1 < r2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            r1 <= r2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            r1 > r2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
-        try:
-            r1 >= r2
-            self.fail("operation that should have raised an error unexpectedly succeeded")
-        except Exception as err:
-            self.assertEqual(TypeError, type(err))
 
 class SectionTest(unittest.TestCase):
 
@@ -320,6 +163,7 @@
         self.assertRaises(InvalidMessageOperation,
                           self.p.set_rcode, rcode)
         
+        self.assertRaises(InvalidMessageOperation, self.p.get_rcode)
 
     def test_set_opcode(self):
         self.assertRaises(TypeError, self.r.set_opcode, "wrong")
@@ -330,6 +174,8 @@
 
         self.assertRaises(InvalidMessageOperation,
                           self.p.set_opcode, opcode)
+
+        self.assertRaises(InvalidMessageOperation, self.p.get_opcode)
 
     def test_get_edns(self):
         self.assertEqual(None, self.p.get_edns())
@@ -413,6 +259,16 @@
         self.assertEqual(b'\x105\x85\x00\x00\x01\x00\x02\x00\x00\x00\x00\x04test\x07example\x03com\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02\x02',
                          renderer.get_data())
 
+    def test_to_wire_without_opcode(self):
+        self.r.set_rcode(Rcode.NOERROR())
+        self.assertRaises(InvalidMessageOperation, self.r.to_wire,
+                          MessageRenderer())
+
+    def test_to_wire_without_rcode(self):
+        self.r.set_opcode(Opcode.QUERY())
+        self.assertRaises(InvalidMessageOperation, self.r.to_wire,
+                          MessageRenderer())
+
     def test_to_text(self):
         message_render = create_message()
         
@@ -429,6 +285,14 @@
 """
         self.assertEqual(msg_str, message_render.to_text())
         self.assertEqual(msg_str, str(message_render))
+
+    def test_to_text_without_opcode(self):
+        self.r.set_rcode(Rcode.NOERROR())
+        self.assertRaises(InvalidMessageOperation, self.r.to_text)
+
+    def test_to_text_without_rcode(self):
+        self.r.set_opcode(Opcode.QUERY())
+        self.assertRaises(InvalidMessageOperation, self.r.to_text)
 
     def test_from_wire(self):
         self.assertRaises(TypeError, self.r.from_wire, 1)

Modified: branches/trac354/src/lib/dns/python/tests/messagerenderer_python_test.py
==============================================================================
--- branches/trac354/src/lib/dns/python/tests/messagerenderer_python_test.py (original)
+++ branches/trac354/src/lib/dns/python/tests/messagerenderer_python_test.py Fri Oct  1 04:26:22 2010
@@ -32,6 +32,7 @@
         message = Message(Message.RENDER)
         message.set_qid(123)
         message.set_opcode(Opcode.QUERY())
+        message.set_rcode(Rcode.NOERROR())
         message.add_question(Question(name, c, t))
 
         self.message1 = message

Modified: branches/trac354/src/lib/dns/tests/Makefile.am
==============================================================================
--- branches/trac354/src/lib/dns/tests/Makefile.am (original)
+++ branches/trac354/src/lib/dns/tests/Makefile.am Fri Oct  1 04:26:22 2010
@@ -22,6 +22,8 @@
 run_unittests_SOURCES += rrclass_unittest.cc rrtype_unittest.cc
 run_unittests_SOURCES += rrttl_unittest.cc
 run_unittests_SOURCES += dnssectime_unittest.cc
+run_unittests_SOURCES += opcode_unittest.cc
+run_unittests_SOURCES += rcode_unittest.cc
 run_unittests_SOURCES += rdata_unittest.h rdata_unittest.cc
 run_unittests_SOURCES += rdata_in_a_unittest.cc rdata_in_aaaa_unittest.cc
 run_unittests_SOURCES += rdata_ns_unittest.cc rdata_soa_unittest.cc

Modified: branches/trac354/src/lib/dns/tests/edns_unittest.cc
==============================================================================
--- branches/trac354/src/lib/dns/tests/edns_unittest.cc (original)
+++ branches/trac354/src/lib/dns/tests/edns_unittest.cc Fri Oct  1 04:26:22 2010
@@ -24,6 +24,7 @@
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
 #include <dns/name.h>
+#include <dns/rcode.h>
 #include <dns/rdataclass.h>
 #include <dns/rrclass.h>
 #include <dns/rrttl.h>

Modified: branches/trac354/src/lib/dns/tests/message_unittest.cc
==============================================================================
--- branches/trac354/src/lib/dns/tests/message_unittest.cc (original)
+++ branches/trac354/src/lib/dns/tests/message_unittest.cc Fri Oct  1 04:26:22 2010
@@ -22,6 +22,8 @@
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
 #include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
 #include <dns/rdataclass.h>
 #include <dns/rrclass.h>
 #include <dns/rrttl.h>
@@ -77,23 +79,6 @@
     message.fromWire(buffer);
 }
 
-TEST_F(MessageTest, RcodeConstruct) {
-    // normal cases
-    EXPECT_EQ(0, Rcode(0).getCode());
-    EXPECT_EQ(0xfff, Rcode(0xfff).getCode()); // possible max code
-
-    // should fail on attempt of construction with an out of range code
-    EXPECT_THROW(Rcode(0x1000), isc::OutOfRange);
-    EXPECT_THROW(Rcode(0xffff), isc::OutOfRange);
-}
-
-TEST_F(MessageTest, RcodeToText) {
-    EXPECT_EQ("NOERROR", Rcode::NOERROR().toText());
-    EXPECT_EQ("BADVERS", Rcode::BADVERS().toText());
-    EXPECT_EQ("17", Rcode(Rcode::BADVERS().getCode() + 1).toText());
-    EXPECT_EQ("4095", Rcode(Rcode(0xfff)).toText());
-}
-
 TEST_F(MessageTest, getEDNS) {
     EXPECT_FALSE(message_parse.getEDNS()); // by default EDNS isn't set
 
@@ -194,4 +179,29 @@
     EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
                         obuffer.getLength(), &data[0], data.size());
 }
-}
+
+TEST_F(MessageTest, toWireInParseMode) {
+    // toWire() isn't allowed in the parse mode.
+    EXPECT_THROW(message_parse.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toWireWithoutOpcode) {
+    message_render.setRcode(Rcode::NOERROR());
+    EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toWireWithoutRcode) {
+    message_render.setOpcode(Opcode::QUERY());
+    EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toTextWithoutOpcode) {
+    message_render.setRcode(Rcode::NOERROR());
+    EXPECT_THROW(message_render.toText(), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toTextWithoutRcode) {
+    message_render.setOpcode(Opcode::QUERY());
+    EXPECT_THROW(message_render.toText(), InvalidMessageOperation);
+}
+}

Modified: branches/trac354/src/lib/python/isc/Makefile.am
==============================================================================
--- branches/trac354/src/lib/python/isc/Makefile.am (original)
+++ branches/trac354/src/lib/python/isc/Makefile.am Fri Oct  1 04:26:22 2010
@@ -1,4 +1,4 @@
-SUBDIRS = datasrc cc config log notify # Util
+SUBDIRS = datasrc cc config log notify utils # Util
 
 python_PYTHON = __init__.py
 




More information about the bind10-changes mailing list