| Creation Date: | September 25th, 2002 |
| Status: | Production |
| Version: | 1.0 |
The Test Harness is a command line utility that can be used to both performance test and unit test your web provider without the need for an Oracle 9iAS Portal instance. The Test Harness achieves this by sending HTTP requests to a given target and recording information about the response received. Items such as the response itself (in XML format) and the time taken to receive that response are recorded for analysis. More information about Test Harness output can be found in a later section.
Configuration of the Test Harness is completely XML based, the user creates an XML Test Definition file that lists all of the requests (in the form of Request Instances) that they want to send to their web provider along with other configuration information such as, the web provider address, port and path, how many times to run requests and within how many threads. The details of each request (such as the the request headers, parameters and body) can be listed directly inside each Request Instance or the Request Instance can refer to requests listed in a Request Library, an optional XML file that may be used if required. A Request Library lists a re-useable set of request details that can be referenced by any Test Definition. Test Definitions and Request Libraries are described in a little more detail below.
A Test Definition is made up of a number of components of information in an XML format that are required by the Test Harness in order to run. The main component is the Request Instance. There can be any number of Request Instances in a Test Definition, each one contains the details required to create a single HTTP request to send to a web provider. A Request Instance can contain the details of the the request in itself as an Inline Definition or it can reference the details from a library based definition within a Request LIbrary, or even a combination of the two. Request Instances are grouped into one or more Request Groups. A Request Group is simply a way of logically dividing Request Instances into groups, and provides a logical context for things such as thread and cookie management. When the Test Harness is executed you have the option of running all Request Groups or any combination of one or more Request Groups. In the Test Definition you can also reference and use pre-processors that perform some application specific processing on a HTTP request before it is sent to its target, such as validating and making changes if necessary to the XML mark up in a SOAP message contained in a request body. A pre-processor can also make changes to a single request that is run a number of times based on the information received in the last response obtained as a result of the request being sent. For example a response may include header information that needs to be included in the next request to enable a particular feature, for example time stamp information or a key for obtaining data from a cache store.
The Request Instances in a Test Definition may reference Request Definitions in a Request Library, rather than include all of the request details directly in the Request Instance. A Request Library contains only request details and no other configuration information. Using Request Libraries rather than including request details solely inside a Request Instance in a Test Definition enables the details of requests to be re-used without the need to duplicate the request details across Test Definitions. The Request Definitions in a Request Library can be referred to and used by any number of Request Instances in any number of Request Definitions.

The Test Harness requires a small amount of set up, once this is done, it is extremely easy to operate using a supplied script which takes care of all of the Test Harness' dependencies. You simply supply the options you want to use and the path to your Test Definition file on the command line. For some quick start examples of using the Test Harness, see the article Oracle 9iAS Portal Studio Test Harness, Getting Started.
The Test Harness comes with a number of example configuration files that are summarized below. Examples of all of the configuration concepts described in this guide can be found in these files.
You are encouraged to use these example configuration files as a starting point for configuring Test Harness configurations specific to your own needs.
A number of Test Definition files are provided to demonstrate the features of the Test Harness and give you a starting point for creating your own Test Definitions. The Test Definitions include:
All example Test Definitions are contained in the pdktest\examples directory.
Each of the Test Definition files listed above make use of a Request Library file. Two such files have been provided, one for 309 Portal requests and one for 902 Portal requests. The Test Definitions are set up to use the 902 Request Library. The Request Libraries are contained in the pdkTest\rLib directory.
To decide which Request Library to use you need to consider two things - the version of PDK Java used by the web provider and the versions of Oracle 9iAS Portal instances that regularly access it. If the version of the PDK Java used is 3.0.9.x or lower then you should use the sample 309 library (ptl309.xml) . If it's version 9.0.2.x or higher you should use the sample 902 library (ptl902.xml), unless the provider is regularly accessed by a portal version 3.0.9.8.x, in which case you should use the sample 309 library.
If you do need to change your Test Definition file to use the sample 309 library, simply replace references to 'ptl902' in the Test Definition to 'ptl309'.
Note: if you create your own request libraries, placing them in this directory will mean that they are automatically available to the Test Harness.
To set up your environment to run the Test Harness, unzip the pdktest.zip file to a convenient location. This will place a directory called pdktest on your machine that contains all of the Test Harness files. Set an environment variable called PDKTEST_HOME to point to this location. For example, if you extracted to D:\ you would now have a directory called D:\pdktest, which is the value that PDKTEST_HOME should be set to.
The Test Harness provides executable scripts in the bin directory, so to ensure they can be run from anywhere on your file system, append PDKTEST_HOME\bin to your PATH environment variable.
If the Test Harness is to be run on a UNIX based platform, you will need to grant execute permissions to the shell script runTest which can be found in PDKTEST_HOME/bin before you try to run the Test Harness. For example, if you are already in the PDKTEST_HOME directory, issue the following command:
chmod a+x PDKTEST_HOME/runTest
| -n | testname A unique name for this test run. Defaults to a date-time string. |
| The test name is used to provide names for various output files as well as providing an ID for the response log. For example if you supplied the test name "test1", and no response log name, the response log would be called "test1_response.xml". | |
| -g | groupId A comma separated list of group ids. To run all groups, specify --all-groups. |
| These are the ids for the Request Groups in your Test Definition | |
| -p | perfLogFile Name of the performance log file. Defaults to the test name. Disable with --no-perf |
| The performance log provides some analysis of the data retrieved during the test run. | |
| -l | resLogFile Name of the response log file. Defaults to the test name. |
| This is the name you would like your response log to have. | |
| -v | resLogLevel Level of response logging, MIN, HEADERS or ALL. Default is ALL. |
| This specifies how much information you would like included in your response log file. | |
| -c | csvFile Name of the response data csv file. Default - not generated. |
| If you want a CSV file to be generated, supply a name for it using this option. | |
| -s | ctlFile Name of the response data ctl file. Default - not generated. |
| If you want a SQL*Loader file to be generated, supply a name for it using this option. | |
| --no-perf | Specify this to switch off logging of performance data. |
| --all-groups | Specify this to run all groups in the test definition. |
| --verbose | Specifying this produces verbose informational logging. |
To run the Test Harness, you simple issue the following command:
runTest <<options>> <<path to Test Definition>>
If your Test Definition makes use of any Request Libraries, you must ensure they are located on the system classpath to ensure the Test Harness will be able to operate. The simplest way of doing this is to keep your Request Libraries in the PDKTEST_HOME/rlib directory as everything in here will automatically be placed on the system classpath at Test Harness runtime.
The following examples show some of the possibilities of Test Harness usage with the sample Test Definitions provided.
Running all tests in the sanity Test Definition, using the test name 'myTest' and accepting all defaults
runTest -n myTest --all-groups $PDKTEST_HOME\examples\sanityTest.xml
Running the register and show groups in the sanity Test Definition, using the test name 'myTest' and switching off performance statistics generation.
runTest -n myTest -g register,show --no-perf $PDKTEST_HOME\examples\sanityTest.xml
Running all groups in the sanity Test Definition, and generating a csv file and no performance statistics file:
runTest --all-groups -c results.csv --no-perf sanityTest.xml
Running the register group in the HMAC Test Definition, with minimum response output and using defaults on everything else:
runTest -g register -v MIN hmacTest.xml
Running the register, load_20 and deregister groups in the loadTest Test Definition, specifying verbose output and the minimum response log level and generating a SQL*Loader script.
runTest -g register, show_20, deregister -v MIN -s results.ctl --verbose
The Test Harness can produce data in various formats for you to analyze further:
The XML response log is always produced. The log contains a list of response instances that each contain response information for a single Request Instance that has been run by the Test Harness. You can configure the amount of information it will log using the -v option and supplying one of three values; MIN, HEADERS or ALL.
The response log allows you to visually inspect the responses received from the web provider under test, along with the response times. The XML format allows this data to be manipulated for analysis, for example you could parse the XML using the Oracle XML Developer's Kit (XDK) to extract the data in a Java program and perform some kind of analysis, or use an XSL style sheet to transform the data into a different format for analysis.
The Test Harness can generate a Comma Separated Values (CSV) file so that Test Harness data can be manipulated using a spread sheet application. To generate a CSV output file when using the Test Harness, use the -c option, following it with the name you want the file to have. The Request Group, Request ID, Thread and Response Time is recorded in the CSV file for each response received by the Test Harness.
The Test Harness can produce a SQL*Loader script (CTL file) to enable you to load test data into a database for analysis. To generate a SQL*Loader script, use the -v option along with the name you want to give the script file.
Provided with the Test Harness are 2 SQL scripts, one which creates a database table to load the Test Harness data in the SQL*Loader script into (mktable.sql), and the other (getstats.sql) performs some analysis on the data in the table to give you an idea of the kind things that can be done with the data. These two files can be found in the PDKTEST_HOME/bin directory after you have extracted the pdktest zip file.
The Test Harness produces a text file containing some analysis of the data retrieved by the Test Harness. This file is generated by default, but it is possible to switch it off using the --no-perf option, should you not require it. Statistics are grouped by Request Group, and example of the data produced is shown below:
--- Begin Data for Group: show_20--- Client Threads: 20 Total Cycles Successful: 20 Total Cycles Failed: 0 RequestInstance: show_portlet
Total Successful Responses: 4000 Total Failed Responses: 0 Mean Successful Response Time (ms): 365.231 Modal Successful Response Time (ms): 344 Standard Deviation (ms): 112.506 Minimum Response Time (ms): 15 Maximum Response Time (ms): 672 RequestInstance: init_session Total Successful Responses: 20 Total Failed Responses: 0 Mean Successful Response Time (ms): 141.200 Modal Successful Response Time (ms): 15 Standard Deviation (ms): 174.679 Minimum Response Time (ms): 0 Maximum Response Time (ms): 500 Approximation of Requests per Hour: 9886 --- End Data for Group: show_20---
As described in the Product Overview, Test Harness configuration files are XML based. The configuration for a test is stored in a Test Definition file, which contains a number of Request Groups, which themselves contain Request Instances. Each Request Instance is made up of a number of elements including an inline Request Definition or a reference to a Request Definition in a Request Library. If a reference to a Request Definition in a Request Library is made, then additional information may be provided in an inline Request Definition.
The Test Definition is made up mainly of Request Instances grouped into Request Groups. There are also other elements that are required however, the format and elements used in a Test Definition are described below.
Everything in a Test Definition is contained within the Test Definition tag, <testDefinition>.
<defaultHost>my.host.com</defaultHost>
<defaultPort>8888</defaultPort>
<defaultPath>/jpdk/providers/sample</defaultPath>
These default values will apply to all of the Request Instances in the Test Definition, unless they are overridden at a lower level. These elements can be included again at Request Group level (see the section below for information about configuration of Request Groups), in which case the values given at Test Definition level will be replaced by the set of values defined in the Request group, for that Request group only. You can also override the values again at Request Instance Level, where the values defined for that Request Instance will replace any other values defined at a higher level. See the section below on Request Instances for details.
Request Groups are a way of logically grouping Request Instances, and providing a context for thread and cookie management. When running the Test Harness you can chose to run all Request Groups in a Test Definition, a single Request Group, or any combination of Request Groups found in the Test Definition. For example, the sanityTest.xml sample Test Definition (found in pdktest/examples) contains three different Request Groups:
Depending upon what you would like to test, you may want to run all three of these request groups. However, if you already have the provider and portlet registered, you may want to just use the show Request group.
The format of a Request Group is described below. For more information about Request Instances please see the section below.
Everything is contained within a <requestGroup> tag which has an id attribute, used to provide a name for the group so that you can specify which groups to run when executing the Test Harness. You can provide a free text description of the Request Group if you wish, using the <description> tag, but this is optional. If you run the Test Harness supplying your Test Definition file but no options, the Request Groups available to you along with any descriptions will be displayed.
You can supply a host, port and path value for use in a Request Group. These values will override any supplied at Test Definition level and can be overridden by any host, port and path values supplied at Request Instance Level. To define these values for your Request Group, you use the following elements:
<host>my.host.com</host>
<port>8888</port>
<path>/jpdk/providers/sample</path>
There are two more optional tags, <cycles> and <threads>. If no values are specified for either of these elements, their values both default to 1.
The cycles element represents how many times to run the requests in a Request Group. For example, if you had a Request Group with three Request Instances, named inst1 inst2 and inst3, and you specified that you wanted to run five cycles of the Request Group, when the group is run by the Test Harness, it would run inst1, inst2, and inst3, then start with inst1 again until each request in the group has been run five times.
The threads element signifies how many threads should be run for each cycle of a Request Group. The Test Harness will start up the specified number of threads and then run the specified number of cycles within each thread. For example if you specified three cycles and 2 threads, two threads would be started and 3 cycles of the Request Group would be run in each thread. So this would mean that each request was run six times (2 threads x 3 cycles = 6). These two elements help to simulate system load and multiple users.
<requestGroup id="groupName">
<description>Description of the Request Group</description>
<threads>3</threads>
<cycles>5</cycles>
<requestInstance id="register_provider">
<!-- Request Instance Details -->
</requestInstance>
<requestInstance id="register_portlet">
<!-- Request Instance Details -->
</requestInstance>
</requestGroup>
The Test harness manages cookies automatically, there is no need for you to include cookie headers in your Request Definitions. Cookie management is scoped to Request Group level. Within a Request Group management is further scoped to a pre thread, per cycle basis. The Test Harness will parse any set-cookie headers it receives in a response and manage the "Cookie" header of all requests it sends in that cycle.
If you would prefer the Test Harness not to manage cookies automatically, you can include the following at Request Group level:
<manageCookies>false</manageCookies>
Request Instances can only be placed within Request Groups and are contained within the <requestInstance> tag. As described before a Request Instance can obtain its details from a library based or an inline Request Definition, or a combination of the two. A Request Instance "instantiates" information contained in a Request Definition to form a valid HTTP request.
A Request Instance can override the default host port and path settings that might be specified at Test Definition or Request group level. To do this you use the <host>, <port> and <path> tags within the Request Instance. If these tags aren't specified the Request Instance will refer to the default host, port and path settings at the parent level.
You can specify a number of runs for a particular Request Instance using the <runs> tag. this means that each time the Test harness comes to send a Request Instance to its target, it will be sent, serially, the number of times specified by the runs tag. This is another way of simulating load on the target being tested. This tag is optional and if not specified, a default value of 1 will be assumed.
To make your Request Instance refer to a library based Request Definition, you need to specify two elements, the <libraryId> and the <definitionid>. The library ID should refer to the unique name given to a Request library (the library used an element of the same name to specify this) and the definition id refers to the name specified in the ID attribute of a Request Definition in the specified Request Library. If you do not specify a library based Request Definition to use in this way then you should ensure you include an inline definition.
The <inlineDefinition> tag can be used with or instead of referencing a library based definition using the <libraryId> and the <definitionid> tags. For more details concerning this element, see the section, Request Definitions.
A Request Library is made up of a number of Request Definitions and a unique<libraryId> tag. This tag is required in order for the Request Instances in a Test Definition top be able to refer to the library and its Request Definitions.
Request Definitions are defined within <requestDefinition> tags, each of which requires an id attribute to identify it. It is the combination of this and the <libraryId> tag that is used by Request Instances in a Test Definition to refer to library based Request Definitions.
An example of the format of a Request Library is shown below:
<requestLibrary>
<libraryId>Unique library name here</libraryId>
<requestDefinition id="definitionId">
<!-- request definition details -->
</requestDefinition>
<!-- More request definitions -->
</requestLibraray>
In a Request Group, each Request Instance needs a Request Definition so it can obtain the details of that request. There are three different ways of providing a Request Instance with a Request Definition:
Below is an overview of the XML elements that can be used in a Request Definition. These elements are the same for a library based or an inline definition, the only difference being that for an inline definition, the elements must be contained within an <inlineDefinition> tag and for a library based definition, the elements must be placed in a <requestDefinition> tag.
<requestHeaders> <header name="header1" value="value1"/> <header name="header2" value="value2"/> </requestHeaders>
All headers should be included, except for any content length or cookie headers, as these are handled internally by the Test Harness ( cookies are handled unless cookie management is switched off). All attributes in the header element are mandatory.
<requestParameters>
<param name="param1" value="value1"/>
<param name="param2" value="value2"/>
</requestParameters>
Parameters are optional. All attributes in the param element are mandatory.
<formEncodeParams>false</formEncodeParams>
<urlEncodeParams>true</urlEncodeParams>
By default, request parameters are appended to the query string exactly as they are marked up. Use <urlEncodeParams>true</urlEncodeParams> to ensure that they are properly URL encoded. For POST request use <formEncodeParams>false</formEncodeParams> to ensure parameters are encoded onto the request body. Please remember that you cannot set both URL and form encoding to be true in a single request.
<requestMethod>GET</requestMethod>
Use this tag to define the HTTP request method for your request. Currently the Test Harness supports GET and POST request methods.
<requestBody>
Anything placed in this element will be written to the request body.
</requestBody>
The request body tag is optional and there is no default value.
Properties are central to the concept of Request Definition reuse. Request Definitions can refer to properties defined elsewhere in the Test Configuration and thus be reused across Request groups and even Test Definitions
For example in the case of a user name, you could define the property and its value just once and refer to it in various places throughout your Test Definition or Request Library. You could then simply change the configuration to test a web provider as a different user (who may have different customizations, access privileges etc and therefore the test may return different results) just by altering the value of the property that you have defined.
Properties can also be overridden so that you can define a property somewhere (e.g. at Request Library Level) and then change their values at more fine-grained details in the Test Harness (e.g.for a Request Group or a single Request Instance). For example, you could specify a property in your Request Library and then override the value in a Request Instance that references that library just to provide a different value for that single Request Instance. The order of precedence for overriding properties is shown below, starting with the lowest level.
You can specify a property definition as shown below. To override a property, simple re-specify it in the same way at the level you would like to replace the value.
<property name="someName" value="someValue"/>
To include a property value somewhere, you enclose the property name in curly braces and prefix it with the dollar sign as shown below:
${someName}
In a single Request Instance you can refer to a library based definition and update the request details with an inline definition. Depending upon the request element, the details provided in the inline definition will either replace or supplement the value supplied in the library based definition.
| Elements That Override |
Elements That Supplement |
| <formEncodeParams> |
Child nodes of <requestParameters> |
| <urlEncodeParams> |
Child nodes of <headers> |
| <requestMethod> |
|
| <requestBody> |
The Test Harness allows the plugging in of components called pre-processors, that enable target application specific logic to be performed at runtime. A pre-processor can update a Request Instance based upon some set rule or information from the last response received.
Defining and Using Pre-Processors in Test Definitions
There are two steps to using a pre-processor in a test configuration.
Pre-Processors supplied with the Test Harness
The Test Harness is supplied with three pre-processors:
oracle.webdb.testharness.preprocessor.PortalPreProcessor
The Portal pre-processor carries out some Portal specific logic on Request Instances. It is recommended that this pre-processor is used at all times.
oracle.webdb.testharness.preprocessor.VCachePreProcessor
The Validation Caching Pre-Processor enables web providers that make use of validation based caching to be properly tested, when you perform multiple show requests serially through the Test Harness. To specify a cache miss ratio, include the <missRatio> element in you pre-processor definition. This value defines the percentage of requests that should be cache misses.
<preProcessorDefinitions>
<preProcessor class="oracle.webdb.testharness.preprocessor.VCachePreProcessor">
<name>vcache</name>
<!-- The miss ratio specifies an approximate percentage of cache
misses to
make across the number of runs for a request using this pre-processor
-->
<missRatio>10</missRatio>
</preProcessor>
</preProcessorDefinitions>
oracle.webdb.testharness.preprocessor.HMACPreProcessor
The HMAC pre-processor enables a web provider that uses HMAC authentication to be properly tested. To use this pre-processor you need to specify a <sharedKey> element, the value of which should be the same as the shared key defined in your provider's properties file.
<preProcessorDefinitions>
<preProcessor class="oracle.webdb.testharness.preprocessor.HMACPreProcessor">
<name>hmac</name>
<!-- The shared key here should be the same as the shared key
that your provider's
properties file has. If the provider has no shared key, then the
provider
will ignore any HMAC related information -->
<sharedKey>1234567890aBcDeFgHiJ</sharedKey>
</preProcessor>
</preProcessorDefinitions>
It is possible to use the Test Harness as a "Record and Playback" utility by using the recording tunnel which is supplied in the pdkest.zip file to generate configuration files (a Request Library and a Test Definition that refers to that Request Library). The use of this tunnel however, should only be necessary if your needs are not met by the request libraries supplied with the Test Harness.
Unlike the Test Harness itself, you do require access to an Oracle 9iAS Portal Instance to use this utility. The tunnel works by sitting between the Portal and web provider, recording requests and responses that are passed between, converts them to the required XML format and writing that XML to a Request Library file and a Test Definition file.
To run the tunnel you must first follow through the section in Initial Setup. Once this is done, running the tunnel is simple:
runTest -tunnel <<tunnel port>> <<remote host>> <<remote port>>
The option <<tunnel port>> is any port number not in use on the machine running the tunnel. For example if a web provider is installed on http://my.host.com:8888, use the following command to run the tunnel:
runTest -tunnel 1212 my.host.com 8888
To record requests, you need to send requests via your browser as you would normally when calling the test page or registering the provider with an Oracle 9iAS Portal instance, but instead of the web provider's normal port you should use the tunnel port specified when you started up the tunnel. For example, if I started up the tunnel using the command above and the provider I wanted to record requests for was the JPDK sample provider then I would use the following URL for that provider.
http://my.host.com:1212/jpdk/providers/sample
You can use this URL to do anything you would normally do with a web provider, for example, enter it directly into a web browser to display the test page, or use it to register the provider on a Portal, then once the provider is registered you can place it on a page and display it etc. Every action you take using the web provider with the specified tunnel port will result in a Request Definition being created in the the generated Request Library and a Request Instance that refers to the Request Definition in the generated Test Definition.
Once you have performed all of the actions that you would like to record as requests in your Test Definition and Request Library, return to the prompt where you issued the Test Harness tunnel command and press Ctrl-C to stop running the tunnel.
In the directory from where the tunnel was run, three files will have been created definition.xml, request.xml and response.xml. You can discard the response file as this is not needed. The definition file is the Test Definition and the request file is its corresponding Request Library. The Request Definitions in the Request Library will contain some headers that aren't needed, so you should delete them, these are content-length headers and cookie headers. Both of these things are taken care of by the Test Harness at runtime and so are not necessary. There may be quite a few instances of these headers across the Request Definitions in the library so the best way to remove these headers would be to use the search facility in a text editing application.
In addition to this you may want to change other items such as the library ID and Request IDs to something more meaningful to you (the tunnel assigns names inst1, inst2 etc for Request Instances and 1.0, 2.0 etc for Request Definitions). This is entirely optional but remember if you change the Library ID or Request Definition IDs then you must also change these values when they are referred to in the Test Definition file.
A Request Definition directly inside a Request Instance
A Request Definition inside a Request Library
A pre-processor enables application specific logic to be included in Request Instances at run-time in the Test Harness. For example, the Portal Pre-processor will check the validity of XML in SOAP messages. In other situations a Request Instance may need changes to be made based on the last response received (when a single Request Instance is run multiple times), for example the Validation Based Caching pre-processor needs to extract a header from a response and include it in the next run of the request to successfully use the validation based caching features of Oracle 9iAS Portal. The Test Harness supplies three pre-processors:
A property definition is a named value that can be defined and referenced virtually anywhere within a Test Definition or Request Library. Property values can be overridden at different levels within a Test Harness configuration.
A property reference refers to the name of a property definition. At runtime, this reference is replaced with the value given in that property definition.
A Request Definition contains meta data marked up as XML about a HTTP request and is used by a Request instance.
A Request Group is used in order to logically group Request Instances together within a Test Definition and provide a logical context for application logic such as cookie handling and application threads. A Test Definition can have one or more Request Groups and and any number or combination of Request Groups from a single Test Definition can be run in a particular execution of the Test Harness.
A Request Instance represents a HTTP request that can be sent by the Test Harness to a defined target (i.e. a Web Provider). Request instances are listed in XML format in a Test Definition file.
A Request Library is simply a file that lists Request Definitions in XML format. These Request Definitions can be referred to by any number of Request Instances. Therefore the Request Definitions in a Request Library are re-usable, saving time and effort when configuring Test Harness tests.
A Test Definition is an XML file that lists the Request Instances for a particular test. The details for Request Instances may be defined directly inside the Test Definition (known as 'inline') or the Request Instances can refer to a Request Library, in order to obtain its details. If you reference a Request Library it is still possible to provide an inline definition, but in this case the inline definition will augment the details obtained from the Request Library definition. Request Instances are grouped into Request Groups (see below) within the Test Definition. In addition to Request Instances, other configuration information is included in a Test Definition, for example the host port and path of the target the requests are to be sent to, and any pre-processors that should be used.
| Revision History: |
|
| Oracle Corporation World Headquarters 500 Oracle Parkway Redwood Shores, CA 94065, USA http://www.oracle.com/ |
Worldwide Inquiries: 1-800-ORACLE1 Fax 650.506.7200 |
Copyright and Corporate Info |