11 Using the testnap Utility to Test BRM
Learn how to use the testnap utility to test your Oracle Communications Billing and Revenue Management (BRM) applications and custom code.
Note:
Only the most common testnap functions are covered here. For a complete description, see "testnap".
Topics in this document:
See also:
About testnap
The testnap utility enables a developer to manually interact with the BRM server by establishing a PCM connection with the Connection Manager (CM) and then executing PCM operations by using that connection. Using testnap, a developer can perform the following tasks:
-
Create input flists
-
Save input and output flists
-
Send opcodes
-
View return (output) flists
-
Create, view, modify, and delete objects and their fields
-
Open, commit, and cancel transactions
Opcode Workbench, part of the Developer Center offers similar functionality in a GUI-based application.
About Buffer Numbers
The testnap utility allocates numerous internal buffers, which are used to store object or flist fields. Buffers are referenced by integers of the user's choice. Every time a new buffer is referenced, testnap allocates that new buffer.
-
If you do not specify a buffer number for a command that expects one, you will be prompted for a buffer number.
-
The meta keyword causes testnap to display the size of external buffer fields. By default, the contents of external buffer fields are displayed.
Executing Opcodes
To run opcodes using testnap, use the xop command.
xop opcode number flag buffer number
The input flist is read from a file into buffer 1, which is passed to xop, on the xop command line. See "About Buffer Numbers".
For opcode numbers, see the opcode header files in BRM_home/include/ops.
Reading an Object and Fields
You can use testnap to read objects or fields in an object and write its contents to a file.
See the following:
Reading Fields in an Object
To read fields from an object, each field or row in the field list must be in valid flist format, but the actual values for the last two fields need not be valid.
For example, you have to include " " for STR fields and some number for the TSTAMP field. If a field is blank, the system returns an error. Be sure to include the header line in all flists.
-
Print the flist to ensure that the format is correct and all the fields are filled.
-
Start testnap.
testnap
-
Read the fields.
r fldlist 1 rflds 1
Reading an Object and Writing Its Contents to a File
This example reads the contents of the /account object and writes it in to a file called root.account.
-
Start testnap.
testnap ===> database 0.0.0.1 from pin.conf "userid"
-
Read the object you want.
This example reads the /account object.
testnap robj - $DB /account 1
-
Save output in buffer 1.
s 1
-
Write the contents on buffer 1 into a file, and quit.
This example writes the contents into a file called root.account.
w 1 root.account q
-
Print the contents of the file (root.account in the example) to verify that the file contains the contents of the /account object.
cat root.account
Retrieving Objects
You can use testnap to search for objects and retrieve the contents of the objects, of specific objects, or the Portal object IDs (POIDs) of the objects.
See the following:
Retrieving the Contents of the First Object Found
This example shows how to perform a search and retrieve the contents of the first object found by that search.
cat search 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 201 0 PIN_FLD_ARGS ARRAY [1] 1 PIN_FLD_POID POID [0] 0.0.0.1 /account 1 1 0 PIN_FLD_RESULTS ARRAY [0] testnap r search 1
Retrieving the POID Field of the Objects Found
This example shows how to search for objects and retrieve only the POID field of each object found.
cat search.all_acct 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 201 0 PIN_FLD_ARGS ARRAY [1] 1 PIN_FLD_POID POID [0] 0.0.0.1 /account -1 1 0 PIN_FLD_RESULTS ARRAY [0] 1 PIN_FLD_POID POID [0] 0.0.0.1 /account 0 0 testnap r search.all_acct 2
Creating a New Search Object
You can create a new search object, load it in the database, and use it as a template for your searches.
The following example shows you how to create a new search template.This template can be used in programs to search for search objects in the database.
-
Read an existing search object and save it as a template:
testnap robj - $DB /search 222 # number of field entries allocated 6, used 6 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 222 1 0 PIN_FLD_NAME STR [0] "1 result: sum, 6 arg =, >=, <, =, like, > special search in /event/usage" 0 PIN_FLD_CREATED_T TSTAMP [0] (857152638) Fri Feb 28 09:57:18 1997 0 PIN_FLD_MOD_T TSTAMP [0] (857152638) Fri Feb 28 09:57:18 1997 0 PIN_FLD_FLAGS INT [0] 1 0 PIN_FLD_TEMPLATE STR [0] "select sum( F1 ) from /event/usage where event_total_t.rec_id = 1 and F2 = V2 and F3 >= V3 and F4 < V4 and F5 = V5 and F6 like V6 and F7 > V7" s 1 saved input in buffer 1 w 1 search.template q
-
Edit the template file to suit your needs.
-
Start testnap.
-
Create the new search template, that is, a new search object with the number 977, as shown in the following example:
cat search.template 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 977 0 PIN_FLD_NAME STR [0] "1 arg = search for /search/$1" 0 PIN_FLD_FLAGS INT [0] 1 0 PIN_FLD_TEMPLATE STR [0] "select X from /search/$1 where F1 = V1 " testnap # Read the search template in to buffer 1 r search.template 1 # Create an object using the contents of buffer 1 create 1 poid poid created was: 0.0.0.1 /search 977 0 # Verify that the search object was created robj - $DB /search 977 # number of field entries allocated 6, used 6 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 977 0 0 PIN_FLD_NAME STR [0] "1 arg = search for /search/$1" 0 PIN_FLD_CREATED_T TSTAMP [0] (857521039) Tue Mar 4 16:17:19 1997 0 PIN_FLD_MOD_T TSTAMP [0] (857521039) Tue Mar 4 16:17:19 1997 0 PIN_FLD_FLAGS INT [0] 1 0 PIN_FLD_TEMPLATE STR [0] "select X from /search/$1 where F1 = V1 "
testnap displays /search object 977 from the database.
Retrieving Objects One at a Time
You can use testnap to do a step search. This example shows how to retrieve objects found in a step search one at a time:
t_flist2 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 236 0 0 PIN_FLD_ARGS ARRAY [1] 1 PIN_FLD_PASSWD STR [0] "ozt|%" 0 PIN_FLD_RESULTS ARRAY [1] 1 PIN_FLD_POID POID [0] 0.0.0.0 / 0 0 1 PIN_FLD_LOGIN STR [0] "" 1 PIN_FLD_PASSWD STR [0] "" testnap r t_flist2 1 ssrch 1 # number of field entries allocated 2, used 2 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 236 0 0 PIN_FLD_RESULTS ARRAY [0] allocated 3, used 3 1 PIN_FLD_POID POID [0] 0.0.0.1 /service/pcm_client 1 1 1 PIN_FLD_LOGIN STR [0] "root.0.0.0.1" 1 PIN_FLD_PASSWD STR [0] "ozt|5f4dcc3b5aa765d61d8327deb882cf99" snext buffer: 1 # number of field entries allocated 2, used 2 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 236 0 0 PIN_FLD_RESULTS ARRAY [0] allocated 3, used 3 1 PIN_FLD_POID POID [0] 0.0.0.1 /service/admin_client 2 1 1 PIN_FLD_LOGIN STR [0] "root.0.0.0.1" 1 PIN_FLD_PASSWD STR [0] "ozt|5f4dcc3b5aa765d61d8327deb882cf99" send buffer: 1 # number of field entries allocated 3, used 3 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 236 0 0 PIN_FLD_ARGS ARRAY [1] allocated 1, used 1 1 PIN_FLD_PASSWD STR [0] "ozt|%" 0 PIN_FLD_RESULTS ARRAY [1] allocated 3, used 3 1 PIN_FLD_POID POID [0] 0.0.0.0 / 0 0 1 PIN_FLD_LOGIN STR [0] "" 1 PIN_FLD_PASSWD STR [0] ""
Retrieving a Specific Number of Objects at a Time
You can change the number of elements in the PIN_FLD_RESULTS ARRAY specification to specify the number of objects you want to retrieve at a time.
This example shows retrieving three objects each time:
cat t_flist_arr 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 236 0 0 PIN_FLD_ARGS ARRAY [1] 1 PIN_FLD_PASSWD STR [0] "ozt|%" 0 PIN_FLD_RESULTS ARRAY [3] 1 PIN_FLD_POID POID [0] 0.0.0.0 / 0 0 1 PIN_FLD_LOGIN STR [0] "" 1 PIN_FLD_PASSWD STR [0] "" testnap ===> database 0.0.0.1 from pin.conf "userid" r t_flist_arr 1 ssrch 1 # number of field entries allocated 4, used 4 0 PIN_FLD_POID POID [0] 0.0.0.1 /search 236 0 0 PIN_FLD_RESULTS ARRAY [0] allocated 3, used 3 1 PIN_FLD_POID POID [0] 0.0.0.1 /service/pcm_client 1 1 1 PIN_FLD_LOGIN STR [0] "root.0.0.0.1" 1 PIN_FLD_PASSWD STR [0] "ozt|5f4dcc3b5aa765d61d8327deb882cf99" 0 PIN_FLD_RESULTS ARRAY [1] allocated 3, used 3 1 PIN_FLD_POID POID [0] 0.0.0.1 /service/admin_client 2 1 1 PIN_FLD_LOGIN STR [0] "root.0.0.0.1" 1 PIN_FLD_PASSWD STR [0] "ozt|5f4dcc3b5aa765d61d8327deb882cf99" 0 PIN_FLD_RESULTS ARRAY [2] allocated 3, used 3 1 PIN_FLD_POID POID [0] 0.0.0.1 /service/email 1061 3 1 PIN_FLD_LOGIN STR [0] "kim@csi.com" 1 PIN_FLD_PASSWD STR [0] "ozt|ae2b1fca515949e5d54fb22b8ed95575" q
Creating Objects
To create an object, you must create an flist in a text file or as a here document in a testnap script. The following procedures show two ways to create an object using testnap.
See the following:
Using a Text File to Create an Object
To use a text file to create an object:
-
Create an flist using a text editor with at least the required fields of the object by using the following example:
0 PIN_FLD_POID POID [0] 0.0.0.1 /data 0 0 0 PIN_FLD_NAME STR [0] "example new data object creation" 0 PIN_FLD_BUFFER BUF [0] flag/size/offset 0x0 0 0 NULL data ptr 0 PIN_FLD_HEADER_NUM INT [0] 1234 0 PIN_FLD_HEADER_STR STR [0] "Some sample info in the example" 0 PIN_FLD_PARENT POID [0] 0.0.0.0 0 0
-
Save the file.
In this example, the file is called new_data_flist
-
Start testnap.
pin@demo5-661> testnap ===> database 0.0.0.1 from pin.conf "userid"
-
Read the file into a buffer.
r new_data_flist 1
-
Create an object using that buffer.
create 1 poid created was: 0.0.0.1 /data 8830 0
The POID of the object created is returned.
Using a Here Document to Create an Object
This procedure enables you to combine data and commands in one file:
-
Create a testnap script to read an object from a here document:
# # A testnap script to create a new data object # # Read an flist into buffer 1 using a "here" document # Note the space between "<<" and the "here" token. # Note use of $DB_NO in poid database - takes current database number. r << XXX 1 0 PIN_FLD_POID POID [0] $DB_NO /data 0 0 0 PIN_FLD_NAME STR [0] "example new data object creation" 0 PIN_FLD_BUFFER BUF [0] flag/size/offset 0x0 0 0 NULL data ptr 0 PIN_FLD_HEADER_NUM INT [0] 1234 0 PIN_FLD_HEADER_STR STR [0] "Some sample info in the example" 0 PIN_FLD_PARENT POID [0] 0.0.0.0 0 0 XXX # # Create the object # create 1 poid # # Write the new poid id (from the "in" buffer) # into a file "new_data_poid.<pid_of_this_process>" # w in new_data_poid.$$ #
-
Save the script.
In this example the script is saved as new_data_script.
-
Run the script.
You can either run testnap with the script name as the argument, as shown in this example, or use the < command in testnap.
See testnap for details.
./testnap new_data_script poid created was: 0.0.0.1 /data 9854 0 ls new_data_poid* new_data_poid.3881
-
Display the contents of the file to verify that the output file is created.
cat new_data_poid.3881 # number of field entries allocated 1, used 1 0 PIN_FLD_POID POID [0] 0.0.0.1 /data 9854 0
Manipulating External Buffer Fields
You can use testnap to manipulate the external buffer fields, for example, to read data in a buffer to a file.
See the following:
Reading Data in a Buffer to a File
The procedure in this section shows how to set the root account object's (/account 1) PIN_FLD_INTERNAL_NOTES field, which is an external buffer field in the /account storable class.
In the input flist in the example, the 0x1 flag indicates that the contents of the file are to be written to the object. The size parameter (37), which is required, is the number of bytes in the file. The contents of this file is to be read into the external buffer field.
The offset field, if nonzero, indicates the number of bytes to be skipped in the file before reading size bytes from the file and placing them in the INTERNAL_NOTES field.
-
Set up an input flist that specifies that the contents of the file xbuf.out be placed into the INTERNAL_NOTES field of the root account object when the Write Fields opcode is run.
-
Setup an input flist that will read the INTERNAL_NOTES field of the root account object when the Read Fields opcode is run. The 0x3 flag indicates that the contents of the file are to be read from the object.
-
Perform the Read Fields opcode. The contents of the INTERNAL_NOTES field are written to the newly created file xbuf.in.
Example:
file xbuf.out this is test of xbuf to account 1 0 PIN_FLD_POID POID [0] 0.0.0.1 /account 1 0 0 PIN_FLD_INTERNAL_NOTES BUF [0] flag/size/offset/xbuf_file 0x1 37 0 xbuf.out xbuf.write # number of field entries allocated 45, used 45 0 PIN_FLD_POID POID [0] 0.0.0.1 /account 1 0 0 PIN_FLD_INTERNAL_NOTES BUF [0] flag/size/offset/xbuf_file 0x1 37 0 xbuf.out buf.tst # number of field entries allocated 45, used 45 0 PIN_FLD_POID POID [0] 0.0.0.1 /account 1 0 0 PIN_FLD_INTERNAL_NOTES BUF [0] flag/size/offset/xbuf_file 0x3 0 0 xbuf.in testnap r xbuf.write 1 wflds 1 r xbuf.tst 2 rflds 2 q
Using Buffers to Concatenate Flists
You can use testnap to concatenate flists. For example:
-
Read the contents of two different files into two different buffers (buffer 1 and buffer 2).
-
Write the contents of buffer 1 to a file.
-
Append the contents of buffer 2 to the same file.
Example:
cat bill 0 PIN_FLD_POID POID [0] 0.0.0.1 /bill 1451 0 cat bundle 0 PIN_FLD_POID POID [0] 0.0.0.1 /deal 1123 0 testnap r bill 1 r bundle 2 w 1 billbundle w+ 2 billbundle q cat billbundle # number of field entries allocated 20, used 1 0 PIN_FLD_POID POID [0] 0.0.0.1 /bill 1451 0 # number of field entries allocated 20, used 1 0 PIN_FLD_POID POID [0] 0.0.0.1 /deal 1123 0
Setting up Buffers and Displaying the List of Buffers
You can use testnap to display a list of all the buffers on your system.
In this example, the flists in two different files (bill and bundle) are read into two different buffers. Then the list of all objects in all the buffers are displayed:
cat bill 0 PIN_FLD_POID POID [0] 0.0.0.1 /bill 1451 0 cat bundle 0 PIN_FLD_POID POID [0] 0.0.0.1 /deal 1123 0 pin@demo5-511> testnap ===> database 0.0.0.1 from pin.conf "userid" r bill 1 r bundle 2 l [1] type /bill, poid 1451 [2] type /deal, poid 1123
Sorting an Flist
On UNIX by using the sort option in testnap, you can sort the contents of a buffer.
This example shows how to read an flist into the buffer and sort it:
cat products cat products.sort 0 PIN_FLD_PRODUCTS ARRAY [0] allocated 20, used 1 1 PIN_FLD_QUANTITY NUM [0] 1.000000 testnap ===> database 0.0.0.1 from pin.conf "userid" r products 2 r products.sort 1 sort 2 1
Invoking Shell Commands
On UNIX, you can invoke shell commands from testnap.
This procedure shows how the results of a grep invocation are used to determine what exit code to use.
-
Search the database to see if /service/ip testterm01 is already created.
r << XXX 1 0 PIN_FLD_POID POID [0] $DB_NO /search 236 0 0 PIN_FLD_PARAMETERS STR [0] "ip" 0 PIN_FLD_ARGS ARRAY [1] 1 PIN_FLD_LOGIN STR [0] "testterm01" 0 PIN_FLD_RESULTS ARRAY [0] 1 PIN_FLD_POID POID [0] 0.0.0.0 0 0 1 PIN_FLD_LOGIN STR [0] "" XXX search 1
-
Write the results to a file.
w in out.setup.fm_term.$$/exist.testterm01
Note:
$$ is substituted for the current process id on UNIX, file names in the r, r+, w, w+, and < commands, and in the arguments to the ! command.
-
Use a UNIX shell to perform an if-test on the results of a grep invocation, and then set the exit code accordingly.
! if grep "testterm01" out.setup.fm_term.$$/exist.testterm01 ; then exit 1; else exit 0 ; fi
Troubleshooting testnap
When testnap doesn't run successfully, you see an error message or the nap prompt doesn't appear. Also, you see error messages in the testnap log file located by default in the BRM_home/sys/test directory. The error messages include an error number and the location of where the error occurred.
Check the testnap log file and the cm.log, cm.pinlog, dm_oracle.log, and dm_oracle.pinlog files for details.
Most problems with starting or running testnap involve incorrect parameters in the testnap configuration file.
If testnap doesn't start, you see the following message:
E Thu May B 13:16:31 1999 db2.corp :6029 pcm.c(1.40):90 Connect open failed (4/100) in pcm context open E Thu May B 13:22:07 1999 db2.corp :6033 pcm.c(1.40):90 Connect open failed (4/101) in pcm context open
See the following:
Error 27: Connection Error
This error is caused by one of the following situations:
-
The maximum number of connections have been exceeded. This is indicated by the following message:
(10567): pcp_open, bad connect: Connection refused (10567): login failed 27 ERROR: testnap: pcm_context_open():: err 27, loc 0, pin_errclass 0, field 0/0, rec_id 0, resvd 5
You can resolve the problem by increasing the number of connections in the CM pin.conf file and reconfiguring the CM, or by connecting to a different CM.
-
The DM processes did not start when you tried to start testnap, caused by the following sequence of commands:
pin@demo5-86> pin_ctl start dm_oracle pin@demo5-87> pin_ctl start cm pin@demo5-88> testnap ERROR: testnap: pcm_connect():: err 27, loc 2, pin_errclass 1, field 0/0, rec_id 0, resvd 7
Wait a few seconds for the DM processes to start after typing pin_ctl start cm before starting testnap.
Error 4: Login Failure
Error 4 in the message indicates that login failed because of an incorrect port or host number or incorrect user ID.
Incorrect port number
A message such as the following indicates that the port number specified by the cm_ports entry in the testnap pin.conf file is incorrect:
testnap
(8488): bad receive of login response, err 4
(8488): login failed 4
ERROR: testnap: pcm_context_open():: err 4,
loc 0, pin_errclass 0, field 0/0, rec_id 0, resvd 5
To resolve the problem, make sure that the port number in the cm_ports entry in the testnap pin.conf file matches the cm_ports entry in the CM pin.conf file.
Incorrect user ID
The following message indicates that the database number (db_no) in the userid entry of the testnap pin.conf file is incorrect:
testnap
bad/no "userid" from pin.conf file
ERROR: testnap: pcm context open():: err 4,
loc 0, pin errclass 0, field 0/0, rec_id 0, resvd 3
To resolve the problem, enter the correct database number in the pin.conf file.
Connection refused
The following message indicates that either the testnap pin.conf file has an incorrect port number or hostname in the cm_ports entry or there is no CM running.
testnap
(1215): pcp_open, bad connect: Connection refused
ERROR: testnap: pcm context open():: err 4,
loc 0, pin_errclass 0, field 0/0, rec_id 0, resvd 4
To resolve the problem, make sure that the hostname and port number are correct and that the CM is running.
Incorrect hostname
The following message indicates that the hostname in the testnap pin.conf file is incorrect:
testnap
(6044): pcp_open(), bad gethostbyname("XXX_HOSTNAME"): Error 0
ERROR: testnap: pcm_context_open():: err 4,
loc 0, pin errclass 0, field 0/0, rec_id 0, resvd 3
To resolve the problem, enter the correct hostname.
Incorrect Database Number
The following message indicates that testnap could connect to the DM through the CM, but couldn't access the database, since the database number was incorrect:
testnap
XXX: database 23 from pin.conf "userid"
ERROR: dd vrfy(): pcm read_flds(): 23
Even though the CMs and DMs successfully came up, this is the first point at which the validity of the database number is checked.
To resolve the problem, correct the database number (db_no) in the userid in testnap pin.conf file. Also, ensure that the testnap, CM, and DM pin.conf files have the same database numbers.
Error 26: DM Not Running
The following messages indicate that there is no DM running.
testnap XXX: database 2 from pin.conf "userid" ERROR: dd vrfy(): pcm read_flds(): 26 robj - 0.0.0.2 /account 1 PCM_OP_READ_OBJ failed: err 26, loc 3, pin_errclass I, field 0/16, rec_id 0, resvd 3
To resolve this, start a DM.
Invalid Buffer Index
The following message indicates that there is a parameter missing in the testnap command:
testnap
XXX: database 2 from pin.conf "userid"
robj /account 1
ERROR: invalid buffer index "2"
no object to use for robj
robj
To resolve the problem, be sure to include the "-" in front of the number 0.0.0.2:
robj - 0.0.0.2 /account 1
Error 56: Failed to Connect
If some older DMs started using a different database number are still running and accepting connections from your application, which is trying to use a different database, testnap returns error 56.
In addition, the testnap pinlog file contains the following message:
E Fri May 7 16:14:11 1999 demo5 <no name>:2025 pcm.c(1.46):101 Connect open failed (56/7) in pcm_context_open E Fri May 7 16:14:11 1999 demo5 <no name>:2025 pcm_conn.c(1.3):158 pcm_connect: bad pcm_context_open, err 56
The CM pinlog file contains the following message:
E Fri May 7 16:35:46 1999 demo5 cm:2125 fm_utils_trans.c:114 fm_utils_trans_open error [location=<PIN_ERRLOC_DM:4> class=<PIN_ERRCLASS_APPLICATION:4> errno=<PIN_ERR_WRONG_DATABASE:31> field num=<PIN_FLD_POID:7,16> recid=<0> reserved=<0>]
To resolve the problem, stop all the DMs and restart them.
Use ps -ef | grep dm to find and stop all DMs.
Note:
testnap also returns error 56 when you re-create the database but do not commit your changes in SQL or in init_tables.sql.hostname.