OpenSolaris_b135/lib/libdhcpsvc/tests/specs/private.txt

#ident	"%Z%%M%	%I%	%E% SMI" mwc

CDDL HEADER START

The contents of this file are subject to the terms of the
Common Development and Distribution License, Version 1.0 only
(the "License").  You may not use this file except in compliance
with the License.

You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
or http://www.opensolaris.org/os/licensing.
See the License for the specific language governing permissions
and limitations under the License.

When distributing Covered Code, include this CDDL HEADER in each
file and include the License file at usr/src/OPENSOLARIS.LICENSE.
If applicable, add the following below this CDDL HEADER, with the
fields enclosed by brackets "[]" replaced with your own identifying
information: Portions Copyright [yyyy] [name of copyright owner]

CDDL HEADER END

		Enterprise: Private Layer Test Specification
		============================================

ABSTRACT

	This document describes two test specifications intended to be
used in the development of test suite(s) designed to validate the private
layer API described in Section 2.1 of the Enterprise DHCP Service
Architecture Specification (ARCH) [1]. The first specification outlines
testing requirements for the DHCP default file API (ARCH, section 2.1.1)
[1]. The second specification outlines the testing requirements for the
dhcptab and dhcp network container API (ARCH, section 2.1.2) [1]. Each
specification contains a basic sanity test specification, designed to
verify that the API works as designed when fed data in the correct form.
Each specification also contains a full test specification, which
compliments the basic sanity test by providing cases which test the
stability and MT-safeness of the API.

TEST APPLICATION

	Test suite(s) written to these specifications should be run on
an instance of each reference platform on each build of the ON
consolidation. See "Enterprise Reference Platforms" [2] for more
information.

1.0 DHCP default file API Test Specification
	
1.1 ABSTRACT

	This test specification is divided into two subspecifications
outlining the testing requirements for validating the default file API
described in Section 2.1.1 of ARCH [1]. The first specification describes
a basic sanity test, which describes the testing requirements to verify
that the API works as designed when fed data in the correct form. The
second specification describes a full test, which complements the basic
sanity test by defining test requirements which test the error checking
behavior and MT-safeness of the API.

1.2 TEST APPLICATION

	Test suite(s) written to this specification should be run on the
reference platform of each of the supported architectures (sparcv8,
sparcv9, IA32, IA64) for each build of the ON consolidation. See
"Enterprise Reference Platforms" [2].

1.3 TEST PREPARATION

	Prior to running a test suite, install SUNWdhcsr and SUNWdhcsu
on the testing platform. No external setup is required for this test
suite.  Remove any existing default file, /etc/default/dhcp.

1.4 BASIC SANITY TEST

	Description

		This test validates the basic operation of the default
	file API function calls when presented with valid input.

	Test Data

		RESOURCE=files
		PATH=/var/dhcp_test
		RUN_MODE=server
		VERBOSE=TRUE
		RELAY_HOPS=8
		INTERFACES=hme0,le0,qfe3
		ETHERS_COMPAT=FALSE
		ICMP_VERIFY=TRUE
		OFFER_CACHE_TIMEOUT=11
		RESCAN_INTERVAL=61
		LOGGING_FACILITY=6
		BOOTP_COMPAT=FALSE

	Case #1 write_dhcp_defaults:

		Use function to write the test data, using file mode of
	0646. Confirm that data written matches test data. Confirm that
	default file created has 0646 file mode and the function
	returns 0.

	Case #2 read_dhcp_defaults:

		Create default file containing test data. Read data
	using the function. Confirm data contained with dhcp_defaults_t
	matches test data and the function returns 0.

	Case #3 delete_dhcp_defaults:

		Remove the default file using the function. Confirm
	that default file has been removed and the function returns 0.

	Case #4 query_dhcp_defaults:

		Call function, cycling through each test data key.
	Confirm that key is found, and that data returned is correct
	and the function returns 0.

	Case #5: free_dhcp_defaults:

		Using the dhcp_defaults_t built containing the test
	data, confirm that the function returns 0.
	
1.5 FULL TEST

	Description

		This test verifies that the default file API function
	calls respond correctly when presented with incorrect data. It
	also validates the MT-safeness of the API.

	Test Data

		RESOURCE=files
		PATH=/var/dhcp_test
		RUN_MODE=server
		VERBOSE=TRUE
		RELAY_HOPS=8
		INTERFACES=hme0,le0,qfe3
		ETHERS_COMPAT=FALSE
		ICMP_VERIFY=TRUE
		OFFER_CACHE_TIMEOUT=11
		RESCAN_INTERVAL=61
		LOGGING_FACILITY=6
		BOOTP_COMPAT=FALSE

	Case #1 all API function calls:

		Call each of the API functions with invalid argument(s).
	For functions that take more than one argument, call those
	functions once for each argument, providing invalid data for
	each argument in turn. Confirm that functions return -1 and set
	errno to EINVAL.

	Case #2 existing lock file:

		Create /etc/default/.dhcp_defaults_lock. Confirm that
	read_dhcp_defaults and write_dhcp_defaults return -1 and set
	errno to EAGAIN.

	Case #2 read_dhcp_defaults:

		Condition		Expected Result
		=========		===============

		No default file. 	Confirm that the function
					returns -1 and sets errno
					to ENOENT.

		Default file w/		Confirm that the function
		mode set to 000.	returns -1 and sets errno
					to EACCESS.

	Case #3 delete_dhcp_defaults:

		Condition		Expected Result
		=========		===============

		No default file. 	Confirm that the function
					returns -1 and sets errno
					to ENOENT.

		Default file w/		Confirm that the function
		mode set to 000.	returns -1 and sets errno
					to EACCESS.

	Case #3 write_dhcp_defaults:
	
		Condition		Expected Result
		=========		===============

		Default file w/		Confirm that the function
		mode set to 000.	returns -1 and sets errno
					to EACCESS.

	Case #4 Multi-access stress:

		Preparation:

			Generate TUNABLE versions of the default file
		containing unique combinations of defaults (no
		line within the TUNABLE  files are the same). The
		default file will be written/accessed using UFS.

			Tunable default values:

				TUNABLE value:	5
				INTERATE value:	100

			A single multi-threaded test program can be
		written which can be used in the following 3 cases.
		It will write/read a unique version of the default
		file. It will retry a default file operation if EAGAIN
		is returned.

		4.1. Multiple processes

			Run TUNABLE instances of the test program which
		writes / reads a different version of the TUNABLE
		default file possibilities for a tunable (INTERATE)
		number of iterations at once. Once the instances of
		the test program have completed their interations,
		verify that the file consists of exactly one of the
		TUNABLE possible versions of the default file.

		4.2. Multiple threads, single process

			Run a single instance of the test program which
		creates a tunable number of threads (TUNABLE) each of
		which will write and read one of the unique default file
		combinations for a tunable (INTERATE) number of
		interations. Verify that after the program completes,
		exactly one of the TUNABLE possible versions of the
		default files exists.

		4.3. Multiple threads, multiple processes, NFS in use

			Run multiple versions of the test program, each
		using multiple threads, some versions of the test
		program accessing the default directory using NFS,
		others using UFS. Verify after the test programs
		complete that exactly one of the TUNABLE possible
		versions of the default file exists.
			
			Caution: ensure that the number of threads *
		number of processes does not exceed the number of unique
		possible default files.

		4.4. Variation of 4.1-4.3:

			Generate another process which periodically
		snags the default file lock file, and verifies that the
		current version of the default file matches one of the
		unique default file versions.

2.0 dhcptab and dhcp network container API Test Specification

2.1 ABSTRACT
	
	This test specification is divided into two subspecifications
outlining the testing requirements for validating the dhcptab and dhcp
network container API described in Section 2.1.2 of ARCH [1]. The first
specification describes a basic sanity test, which describes the testing
requirements to verify that the API works as designed when fed data in
the correct form with the correct preconditions present. The second
specification describes a full test, which complements the basic sanity
test by defining test requirements which test the error checking
behavior and MT-safeness of the API.

2.2 TEST APPLICATION

	Test suite(s) written to this specification should be run on the
reference platform of each of the supported architectures (sparcv8,
sparcv9, IA32, IA64) for each build of the ON consolidation. See
"Enterprise Reference Platforms" [2].

2.3 TEST PREPARATION
	
	Prior to running a test suite, install SUNWdhcsr and SUNWdhcsu
on the testing platform. Select a public module SUNWdhc{df,db,dn} and
install it. Configure any data service providing service to the public
module. Set the RESOURCE and PATH default file parameters as required by
the public module. Note that if the underlying public module's
environment is appropriately configured, the results of testing the API
should be the same for any other appropriately configured public module.
The public module status can be verified by running the basic sanity
test for the specific public module. The tester should record the
public module environment used during the test.

2.4 BASIC SANITY TEST

	Description
		
		This test validates the basic operation of the dhcptab
	and dhcp network container API function calls when presented with
	valid input.

	Test Data

	Item			Description		Application
	====			===========		===========
	<network address>	IP address of		*_dn
				network. Ensure
				that appropriate
				subnet mask is
				available in
				netmasks(4).
				Candidate networks
				have to have at
				least 3000 hosts.

	dt records	As follows:			*_dt

	SrootOpt s Vendor=SUNW.Ultra-1 SUNW.i86pc,1,ASCII,1,0
	SrootIP4 s Vendor=SUNW.Ultra-1 SUNW.i86pc,2,IP,1,1
	SrootNM  s Vendor=SUNW.Ultra-1 SUNW.i86pc,3,ASCII,1,0
	SrootPTH s Vendor=SUNW.Ultra-1 SUNW.i86pc,4,ASCII,1,0
	SswapIP4 s Vendor=SUNW.Ultra-1 SUNW.i86pc,5,IP,1,1
	SswapPTH s Vendor=SUNW.Ultra-1 SUNW.i86pc,6,ASCII,1,0
	SbootFIL s Vendor=SUNW.Ultra-1 SUNW.i86pc,7,ASCII,1,0
	Stz      s Vendor=SUNW.Ultra-1 SUNW.i86pc,8,ASCII,1,0
	SbootRS  s Vendor=SUNW.Ultra-1 SUNW.i86pc,9,NUMBER,2,1
	SinstIP4 s Vendor=SUNW.Ultra-1 SUNW.i86pc,10,IP,1,1
	SinstNM  s Vendor=SUNW.Ultra-1 SUNW.i86pc,11,ASCII,1,0
	SinstPTH s Vendor=SUNW.Ultra-1 SUNW.i86pc,12,ASCII,1,0
	SsysidCF s Vendor=SUNW.Ultra-1 SUNW.i86pc,13,ASCII,1,0
	SjumpsCF s Vendor=SUNW.Ultra-1 SUNW.i86pc,14,ASCII,1,0
	Sterm    s Vendor=SUNW.Ultra-1 SUNW.i86pc,15,ASCII,1,0
	Locale   m :UTCoffst=-18000:
	Solaris  m :SrootIP4=129.148.174.27:SrootNM="atlantic": \
	       :SinstIP4=129.148.174.27:SinstNM="atlantic": \
	       :Sterm="xterm":BootSrvA=129.148.174.27:
	sparc    m \
:SrootPTH="/export/s28/solaris1of2.s28s_wos/latest/Solaris_8/Tools/Boot": \
	       :SinstPTH="/export/s28/solaris1of2.s28s_wos/latest":
	sun4u    m :Include=Solaris:Include=sparc:
	i86pc    m :Include=Solaris:SbootFIL="/platform/i86pc/kernel/unix": \
	           :SinstPTH="/export/s28/solaris1of2.s28x_wos/latest": \
:SrootPTH="/export/s28/solaris1of2.s28x_wos/latest/Solaris_8/Tools/Boot":
	SUNW.i86pc m :Include=i86pc:
	SUNW.Ultra-1 m :SbootFIL="/platform/sun4u/kernel/sparcv9/unix": \
	               :Include=sun4u:
	<network address> m :Subnet=255.255.0.0:Router=172.21.0.2: \
		     :Broadcst=172.21.255.255:
	atlantic m :Include=Locale:Timeserv=129.148.174.27:LeaseTim=3600: \
	           :LeaseNeg:Hostname:DNSdmain="snt.east.sun.com": \
		   :DNSserv=172.21.0.1:
	010800207E8A02 m :Impress=172.22.255.27:

	
	<network address>	Dhcp network container.		*_dn

	dn records		~3000, as follows:		*_dn

	00 00 <network address>+6 172.21.0.2 0 atlantic
			.
			.
			.
	00 00 <network address>+3006 172.21.0.2 0 atlantic



	Case #1 dhcpsvc_errmsg:
		
		Use function in a loop to display all messages
	associated with the error codes in Figure 2 of ARCH [1]. Verify
	that messages are displayed correctly.

	Case #2 enumerate_dd:

		Verify that this function properly enumerates the public
	modules present on the machine under test in
	/usr/lib/inet/dhcp/svc. Free memory (count entries in modules).

	Case #3 status_dd:

		Verify that the selected data store service is correctly
	configured.

	Case #4 capability_dd:

		Verify that this function returns the correct
	capabilities for the public module currently configured for use.
	Note: Some public modules may not support this function, which
	will cause this function to return DSVC_UNSUPPORTED.

	Case #5 open_dd:
		
		Using DSVC_CREATE | DSVC_READ | DSVC_WRITE, create a
	dhcptab container and a dhcp network container (called
	<network address>). Preserve the handles returned for later
	use in the following test cases.

	Case #6 list_dd:

		Verify that this function properly returns the currently
	available DHCP containers (Case #5) in the data service hosting
	the public module. Only those containers created in Case #5
	should exist. Free memory (count entries in listppp).

	Case #7 add_dd_entry:

		Using the handles returned in Case #5, add the test
	data records to the dhcptab and dhcp network containers.

	Case #8 lookup_dd:

		8.1. Verify case #7.

			Using a "count" of -1 and a "query" value set
		using DSVC_QINIT (Figure 5 of ARCH[1]), verify that the
		contents of the dhcptab container and <network address>
		container match the test data. "records" should equal
		the number of records for each container. Note that the
		order of the records returned may not be the same as
		the order in which they were added in case #7.

		8.2 Verify dhcptab container type.

			8.2.1. Look for all records with a DT_QTYPE
			value of "s". Verify that only the "s" type
			records are returned.

			8.2.2. Look for all records with DT_QTYPE value 
			of "m". Verify that only the "m" type records
			are returned.

			8.2.3. Look for DT_QKEY of "atlantic". Verify
			that only the macro "atlantic" is returned.

			8.2.4. Look for DT_QKEY of i86pc and not a
			DT_QTYPE of "m". Verify that only the macro
			"i86pc" is returned.

		8.3 Verify dhcp network container type.

			8.2.1. Look for all records with a DN_QCIP
			of <network address>+100. Verify that only
			one record (with a cip of
			<network address>+100)  is returned.

			8.2.2. Look for all records with DN_QMACRO
			value of "atlantic". Verify that all records
			are returned ("records" == 3000). Note that
			records returned may be in a different order
			than they were added as part of case #7.

	Case #9 modify_dd_entry:
		
		9.1 Modify dhcptab container records

			9.1.1 Using lookup_dd to find the record with a
			DT_QKEY of "Sterm", change the name of the
			record from "Sterm" to "sTERM". Use lookup_dd to
			verify that the original record has been
			renamed.

			9.1.2 Using lookup_dd to find the record with a
			DT_QKEY of "Solaris", change the value portion
			of the record to be:

			:SrootIP4=129.148.174.27:SrootNM="atlantic": \
			:SinstIP4=129.148.174.27:SinstNM="atlantic": \
			:sTERM="sun-cmd":BootSrvA=129.148.174.27:

			Using lookup_dd, reexecute the lookup and verify
			that the value portion of the record has been
			modified correctly.

		9.2 Modify dhcp network container records

			9.2.1 Using lookup_dd to find the record with a
			DN_QCIP of <network address>+10, change the
			lease field to 1/1/2000 and the flags field to
			MANUAL. Use lookup_dd to verify that the
			original record has been changed.

			9.2.2 Using lookup_dd to find the record with a
			DN_QFLAGS of MANUAL. Change the dn_cid field
			to 01080020FFFFFF, dn_flags field to
			MANUAL+AUTOMATIC, dn_sip field to 172.23.0.77,
			dn_lease field to -1, dn_macro field to "happy",
			and the dn_comment field to "This is a test".
			Use lookup_dd to verify that the original record
			has been changed.
		

	Case #10 delete_dd_entry:

		10.1 Delete dhcptab container record

			Using lookup_dd to find the record with a
		DT_QKEY of SUNW.Ultra-1, delete this record. Verify
		using lookup_dd that this record can no longer be found.

		10.2 Delete dhcp network container record

			Using lookup_dd to find the record with a
		DN_QCIP of <network address>+101, delete this record.
		Verify using lookup_dd that this record can no longer be
		found.

	Case #11 close_dd:

		11.1 Close the open instance of the dhcptab container.
		Verify that close_dd returns DSVC_SUCCESS.

		11.2 Close the open instance of the dhcp network
		container <network address>. Verify that close_dd
		returns DSVC_SUCCESS.

	Case #12 remove_dd:

		12.1 Remove the dhcptab container. Verify that it no
		longer exists using list_dd.

		12.2 Remove the dhcp network container <network
		address>. Verify that it no longer exists using list_dd.

2.5 FULL TEST

	Description
		
		This test verifies that the dhcptab and dhcp network
	container API function calls respond correctly when presented with
	incorrect data. It also validates the MT-safeness of the API.
	The test suite should allow any number of concurrent threads or
	test suite processes to be invoked.

	Test Data

	Item			Description		Application
	====			===========		===========
	<network address>	IP address of		*_dn
				network. Ensure
				that appropriate
				subnet mask is
				available in
				netmasks(4).
				Candidate networks
				have to have at
				least 3000 hosts.

	dt records	As follows:			*_dt

	SrootOpt s Vendor=SUNW.Ultra-1 SUNW.i86pc,1,ASCII,1,0
	SrootIP4 s Vendor=SUNW.Ultra-1 SUNW.i86pc,2,IP,1,1
	SrootNM  s Vendor=SUNW.Ultra-1 SUNW.i86pc,3,ASCII,1,0
	SrootPTH s Vendor=SUNW.Ultra-1 SUNW.i86pc,4,ASCII,1,0
	SswapIP4 s Vendor=SUNW.Ultra-1 SUNW.i86pc,5,IP,1,1
	SswapPTH s Vendor=SUNW.Ultra-1 SUNW.i86pc,6,ASCII,1,0
	SbootFIL s Vendor=SUNW.Ultra-1 SUNW.i86pc,7,ASCII,1,0
	Stz      s Vendor=SUNW.Ultra-1 SUNW.i86pc,8,ASCII,1,0
	SbootRS  s Vendor=SUNW.Ultra-1 SUNW.i86pc,9,NUMBER,2,1
	SinstIP4 s Vendor=SUNW.Ultra-1 SUNW.i86pc,10,IP,1,1
	SinstNM  s Vendor=SUNW.Ultra-1 SUNW.i86pc,11,ASCII,1,0
	SinstPTH s Vendor=SUNW.Ultra-1 SUNW.i86pc,12,ASCII,1,0
	SsysidCF s Vendor=SUNW.Ultra-1 SUNW.i86pc,13,ASCII,1,0
	SjumpsCF s Vendor=SUNW.Ultra-1 SUNW.i86pc,14,ASCII,1,0
	Sterm    s Vendor=SUNW.Ultra-1 SUNW.i86pc,15,ASCII,1,0
	Locale   m :UTCoffst=-18000:
	Solaris  m :SrootIP4=129.148.174.27:SrootNM="atlantic": \
	       :SinstIP4=129.148.174.27:SinstNM="atlantic": \
	       :Sterm="xterm":BootSrvA=129.148.174.27:
	sparc    m \
:SrootPTH="/export/s28/solaris1of2.s28s_wos/latest/Solaris_8/Tools/Boot": \
	       :SinstPTH="/export/s28/solaris1of2.s28s_wos/latest":
	sun4u    m :Include=Solaris:Include=sparc:
	i86pc    m :Include=Solaris:SbootFIL="/platform/i86pc/kernel/unix": \
	           :SinstPTH="/export/s28/solaris1of2.s28x_wos/latest": \
:SrootPTH="/export/s28/solaris1of2.s28x_wos/latest/Solaris_8/Tools/Boot":
	SUNW.i86pc m :Include=i86pc:
	SUNW.Ultra-1 m :SbootFIL="/platform/sun4u/kernel/sparcv9/unix": \
	               :Include=sun4u:
	<network address> m :Subnet=255.255.0.0:Router=172.21.0.2: \
		     :Broadcst=172.21.255.255:
	atlantic m :Include=Locale:Timeserv=129.148.174.27:LeaseTim=3600: \
	           :LeaseNeg:Hostname:DNSdmain="snt.east.sun.com": \
		   :DNSserv=172.21.0.1:
	010800207E8A02 m :Impress=172.22.255.27:

	
	<network address>	Dhcp network container.		*_dn

	dn records		~3000, as follows:		*_dn

	00 00 <network address>+6 172.21.0.2 0 atlantic
			.
			.
			.
	00 00 <network address>+3006 172.21.0.2 0 atlantic



	Case #1 all API function calls:

		1.1 Invalid arguments

			Call each of the API functions with invalid
		argument(s). For functions that take more than one
		argument, call those functions once for each argument,
		providing invalid data for each argument in turn.
		Confirm that functions return DSVC_INVAL for all cases
		but dhcpsvc_errmsg. This function should return a
		string of "unknown".

		1.2 No public modules (N/A for dhcpsvc_errmsg)

			Call each of the API functions. Verify that
		DSVC_ENOENT is returned.

		1.3 Permission (N/A for dhcpsvc_errmsg)

			Change the permission of the public module to be 
		unreadable by any user (000).  Verify that DSVC_ACCESS
		is returned. Restore permission of public module.
		
	Case #2 status_dd:

		2.1 Supporting data service not configured.

			Verify that DSVC_SUCCESS is *not* returned.
		Some public modules may not return the same error message
		in this case. All should fail.

		2.2 Configured data service, but unavailable.

			Using a data service-specific method of making
		the data service temporarily unavailable, call the
		function. DSVC_BUSY or DSVC_INTERNAL (different depending
		on implementation) is returned.

		2.3 Configured data service, available.

			Verify that DSVC_SUCCESS is returned.

	Case #3 open_dd:

		Perform the following subcases once each for the dhcptab
	container and dhcp network container described in the test
	data.
		
		3.1 No container

			Call function with DSVC_READ | DSVC_WRITE.
		Verify that DSVC_NOENT is returned.

		3.2 Basic

			Using DSVC_CREATE | DSVC_READ | DSVC_WRITE,
		create a dhcptab container and a dhcp network container
		(called <network address>).

		3.3 NON_BLOCK

			Call function with DSVC_READ | DSVC_WRITE |
		DSVC_NONBLOCK. Depending on whether the public module
		supports it (see module doc), the function should return
		either DSVC_SUCCESS or DSVC_UNSUPPORTED.

		3.4 Container exists

			Using DSVC_CREATE | DSVC_READ | DSVC_WRITE,
		verify that the function returns DSVC_EXISTS.

		Cleanup: Remove the containers using remove_dd.

	Case #4 list_dd:

		4.1 No containers

			Verify that list_dd returns DSVC_NOENT.

	Case #5 add_dd_entry:

		Create and load containers as per Case #5 and Case
	#7 of the Basic Sanity Test.

		5.1 Record exists

			Attempt to add a test data record for the
		dhcptab container and dhcp network container
		respectively. Verify that DSVC_EXISTS is returned.

		5.2 Busy

			Close containers with close_dd. Reopen with
		DSVC_NONBLOCK specified. If success is returned, using a
		data service specific technique for making the service
		busy, attempt to add an additional record to each of the
		two containers. Verify that DSVC_BUSY is returned.
		Remove the busy condition, and reattempt the add. Verify
		that DSVC_SUCCESS is returned. close_dd the containers.

		5.3 Read only

			Reopen the containers with DSVC_READ access
		only. If success is returned, attempt to add a new
		record to each container. Verify that DSVC_ACCESS is
		returned. close_dd the containers.

		Cleanup: Remove the containers using remove_dd.

	Case #5 lookup_dd:

		Create and load containers as per Case #5 and Case #7 of
	the Basic Sanity Test.

		5.1. Record does not exist.

			Produce dhcptab container and dhcp network
		container queries that would not be satisfied by the
		test data. Verify that DSVC_SUCCESS is returned, and
		"records" is 0.

		5.2 Busy

			Close containers with close_dd. Reopen with
		DSVC_NONBLOCK specified. If DSVC_SUCCESS is returned,
		using a data service specific technique for making
		the service busy, attempt to perform a valid lookup of
		records in each of the two containers. Verify that DSVC_BUSY
		is returned.  Remove the busy condition, and reattempt
		the lookups. Verify that DSVC_SUCCESS is returned, and
		that data returned is valid. close_dd the containers.

		5.3 Write only

			Reopen the containers with DSVC_WRITE access
		only. If success is returned, attempt to perform
		lookup_dd's using any syntactically legal query for each
		container type. Verify that DSVC_ACCESS is returned.
		close_dd the containers.

		Cleanup: Remove the containers using remove_dd.

	Case #6 modify_dd_entry:
		
		Create and load containers as per Case #5 and Case #7 of
	the Basic Sanity Test.

		6.1 Unknown record

			Fabricate dn_rec_t / dt_rec_t instances known not
		to exist in the respective containers. Attempt to modify
		the records. Verify that DSVC_NOENT is returned.

		6.2 Update Collision #1
			
			Use lookup_dd to find valid dhcptab and dhcp
		network container records (one each). Change the
		signature on the resultant dt_rec_t / dn_rec_t. Attempt
		to modify records. Verify that DSVC_COLLISION is returned.

		6.3 Update Collision #2

			Use lookup_dd to find valid dhcptab and dhcp
		network container records (one each). Attempt to rename
		the records to names which already exist (dt_key +
		dt_type, dn_cip). Verify that DSVC_EXISTS is returned.

		6.4 Busy

			Close containers with close_dd. Reopen with
		DSVC_NONBLOCK specified. If DSVC_SUCCESS is returned,
		acquire valid dhcptab and dhcp network container
		records using lookup_dd. Using a data service specific
		technique for making the service busy, attempt to
		modify the value (non-key fields) of the records. Verify
		that DSVC_BUSY is returned. Remove the busy condition,
		and reattempt the modifies. Verify that DSVC_SUCCESS
		is returned. Reacquire the records. Verify that the
		contents have been suitably updated. close_dd the
		containers.

		6.5 Read only

			Reopen the containers with DSVC_READ access
		only. If success is returned, locate valid container
		records using the appropriate queries to lookup_dd.
		Modify the contents of a copy of the dt_rec_t /
		dn_rec_t. Attempt to modify the record in the containers.
		Verify that DSVC_ACCESS is returned. close_dd the
		containers.

		Cleanup: Remove the containers using remove_dd.

	Case #7 free_dd:

		This function should be used to release the results of
	lookup_dd calls. Its operation must be validated by running this
	test suite under bcheck with -memuse, and ensuring that no free
	blocks remain after exit. Note that the test suite must be
	written with care to make this case useful (free any allocated
	memory before exit).

	Case #8 delete_dd_entry:

		Create and load containers as per Case #5 and Case #7 of
	the Basic Sanity Test.

		8.1 Unknown record

			Fabricate dn_rec_t / dt_rec_t instances known not
		to exist in the respective containers. Attempt to delete
		the records. Verify that DSVC_NOENT is returned.

		8.2 Busy

			Close containers with close_dd. Reopen with
		DSVC_NONBLOCK specified. If DSVC_SUCCESS is returned,
		acquire valid dhcptab and dhcp network container
		records using lookup_dd. Using a data service specific
		technique for making the service busy, attempt to
		delete the records. Verify that DSVC_BUSY is returned.
		Remove the busy condition, and reattempt the deletes.
		Verify that DSVC_SUCCESS is returned. Attempt to
		reacquire the records. Verify that the records have been
		deleted. close_dd the containers.

		8.3 Read only

			Reopen the containers with DSVC_READ access
		only. If success is returned, locate valid container
		records using the appropriate queries to lookup_dd.
		Attempt to delete the records in the containers.
		Verify that DSVC_ACCESS is returned. close_dd the
		containers.

		Cleanup: Remove the containers using remove_dd.

	Case #9 close_dd:

		9.1 Busy

			Create containers as per Case #5 of the Basic
		Sanity Test, with the exception that DSVC_NONBLOCK is
		specified. If DSVC_SUCCESS is returned, using a data
		service specific technique for making the service busy,
		attempt to close the containers using the handles
		returned by open_dd. Verify that DSVC_BUSY is returned.
		Remove the busy condition, and reattempt the close_dd.
		Verify that DSVC_SUCCESS is returned.

		Cleanup: Remove the containers using remove_dd.

	Case #10 remove_dd:

		Create containers as per Case #5 of the Basic Sanity Test.

		10.1 Unknown container

			Attempt to remove a non-existent dhcp network
		container. Verify that DSVC_NOENT is returned.

		10.2 Busy

			Close containers with close_dd. Reopen with
		DSVC_NONBLOCK specified. If DSVC_SUCCESS is returned,
		using a data service specific technique for making the
		service busy, attempt to remove the containers. Verify
		that DSVC_BUSY is returned. Remove the busy condition,
		close_dd the containers, and reattempt the removes.
		Verify that DSVC_SUCCESS is returned. Verify using
		list_dd that the containers have been removed.

	Case #11 Multi-access stress

			The service provider layer modules underneath
		the private layer are not required to manage reference
		counts for open instances. So while individual private
		layer handles are considered to be MT-safe (and parallel
		access to data containers is suitably protected), an
		application using the private layer API must synchronize
		close and/or container remove operations among threads
		such that no threads hold handles to a container after
		the handle has been closed or the container has been
		removed.

			This case assumes a test which is
		multi-threaded, and can run the following test using
		from 1 to THREADS threads. The test can also be run in
		multiple concurrent processes.

			The goal of this test is to ensure that the API
		is MT-safe with respect to the containers and the
		records contained within those containers. This goal is
		accomplished by verifying that the end result of the
		test is consistent.

			Tunable default values:

				PROCESSES: 20
				THREADS: 20

		11.1 The dhcptab container test

			11.1.1 open_dd

				Create a dhcptab using DSVC_CREATE |
			DSVC_READ | DSVC_WRITE. If DSVC_EXISTS is
			returned, retry the open attempt w/o the
			DSVC_CREATE flag. Log that this event occurred.
			Handle will be used for balance of test. If any
			other error occurs, terminate the test as
			failed.

			11.1.2 add_dd_entry

				Add the test data records to the dhcptab
			container. If DSVC_EXISTS is returned, skip that
			record, and continue attempting to add the other
			records. Log that this event occurred. If any
			other error occurs, terminate the test as
			failed.

			11.1.3 lookup_dd

				Using DT_QKEY of "atlantic" and DT_QTYPE
			of "m", find the atlantic record. Compare its
			value against the test data. If it has
			changed, then output a message to this affect.
			If any error occurs, terminate the test as failed.

			11.1.4 modify_dd_entry

				Using the results of 11.1.3, change the
			record as follows. If it is no different from
			the test data, change the value to:

		:Timeserv=129.148.174.28:LeaseTim=86400: \
		:Hostname:DNSdmain="east.sun.com":DNSserv=172.23.3.3:

				If it doesn't match the test data
			value, change the LeaseTim by incrementing it by
			one. Attempt to update the record. If it fails
			with DSVC_COLLISION, retry 11.1.3 and 11.1.4 for
			three attempts. Log message if modify was
			unsuccessful. If any other error occurs,
			terminate the test as failed.

			11.1.5 delete_dd_entry

				Use lookup_dd to find a DT_QKEY of
			"SjumpsCF" and a  DT_QTYPE of "s". If it does
			not exist, log a message. If it does exist,
			attempt to delete it. If DSVC_NOENT is returned,
			log a message.

			11.1.6 close_dd

				Use close_dd to close the open handle.
			If DSVC_NOENT is returned, log a message.

			11.1.7 epilogue
				
				Compare the resultant dhcptab container
			to the test data. The only differences should be
			a changed value of the atlantic macro as
			expected from 11.1.4 and the SjumpsCF symbol
			should be removed. Any other inconsistency means
			the test has failed.

			Clean up: Remove the dhcptab container.

		11.2 The dhcp network container test

			11.2.1 open_dd

				Create a <network address> dhcp network
			container using DSVC_CREATE | DSVC_READ | DSVC_WRITE.
			If DSVC_EXISTS is returned, retry the open
			attempt w/o the DSVC_CREATE flag. Log that this
			event occurred. Handle will be used for balance
			of test. If any other error occurs, terminate
			the test as failed.

			11.2.2 add_dd_entry

				Add the test data records to the dhcp
			network container. If DSVC_EXISTS is
			returned, skip that record, and continue
			attempting to add the other records. Log that
			this event occurred. If any other error occurs,
			terminate the test as failed.

			11.2.3 lookup_dd

				Find the DN_QCIP of <network address>+102
			record. Compare its value against the test data.
			If it has changed, then output a message to this
			affect. If any error occurs, terminate the test
			as failed.  

			11.2.4 modify_dd_entry

				Using the results of 11.2.3, change the
			record as follows. If it is no different from
			the test data, change the value to:

01DEADBEEF 03 <network address>+102 172.23.3.3 941619403 Solaris

				If it doesn't match the test data
			value, change dn_lease by incrementing it by
			one. Attempt to update the record. If it fails
			with DSVC_COLLISION, retry 11.2.3 and 11.2.4 for
			three attempts. Log message if modify was
			unsuccessful.  If any other error occurs,
			terminate the test as failed.

			11.2.5 delete_dd_entry

				Use lookup_dd to find a DN_QCIP of
			<network address>+1001. If it does not exist,
			log a message. If it does exist, attempt to
			delete it. If DSVC_NOENT is returned, log a
			message.

			11.2.6 close_dd

				Use close_dd to close the open handle.
			If DSVC_NOENT is returned, log a message.

			11.2.7 epilogue
				
				The <network address> dhcp network
			container should be consistent at the end of
			a test run. The only differences should be a
			changed value of the <network address>+102
			record with the value as per 11.2.4 and the
			lease time potentially incremented, as well as
			the <network address>+1001 record missing. 
			Any other inconsistency means the test has
			failed.

			Cleanup: remove <network address> dhcp network
		container.

		11.3 Multi-process run

			Run 11.1 and 11.2 in PROCESSES separate
		processes.

		11.4 Multi-threaded run, single process

			Run 11.1 and 11.2 in THREADS separate threads
		within a single process.

		11.5 Multi-process, Multi-threaded run

			Run 11.1 and 11.2 in PROCESSES separate
		processes  each spawning THREADS separate threads.

REFERENCES

	[1] "Enterprise DHCP Service Architecture Specification", mwc,
	    6/25/1999.

	[2] "Enterprise Reference Hardware Platforms", mwc, 10/23/1999.