Merge commit 'remotes/korg/cupcake' into cupcake_to_master
diff --git a/dexdump/Android.mk b/dexdump/Android.mk
index d9fe367..9107638 100644
--- a/dexdump/Android.mk
+++ b/dexdump/Android.mk
@@ -44,7 +44,7 @@
LOCAL_SHARED_LIBRARIES := $(dexdump_shared_libraries) libz liblog
LOCAL_STATIC_LIBRARIES := $(dexdump_static_libraries)
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := debug development
+LOCAL_MODULE_TAGS := debug
LOCAL_LDLIBS +=
include $(BUILD_EXECUTABLE)
diff --git a/dexdump/DexDump.c b/dexdump/DexDump.c
index 0ba3175..a287c5e 100644
--- a/dexdump/DexDump.c
+++ b/dexdump/DexDump.c
@@ -515,7 +515,7 @@
printf(" v%d", pDecInsn->vA);
break;
case kFmt10t: // op +AA
- case kFmt20t: // op +AABBBB
+ case kFmt20t: // op +AAAA
{
s4 targ = (s4) pDecInsn->vA;
printf(" %04x // %c%04x",
@@ -1073,7 +1073,8 @@
goto bail;
mapped = true;
- pDexFile = dexFileParse(map.addr, map.length, kDexParseVerifyChecksum);
+ pDexFile = dexFileParse(map.addr, map.length,
+ kDexParseVerifyChecksum | kDexParseContinueOnError);
if (pDexFile == NULL) {
fprintf(stderr, "ERROR: DEX parse failed\n");
goto bail;
diff --git a/dexopt/OptMain.c b/dexopt/OptMain.c
index 6383b0d..ef339cd 100644
--- a/dexopt/OptMain.c
+++ b/dexopt/OptMain.c
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* Command-line DEX optimization and verification entry point.
*
@@ -50,7 +51,8 @@
* up front for the DEX optimization header.
*/
static int extractAndProcessZip(int zipFd, int cacheFd,
- const char* debugFileName, int isBootstrap, const char* bootClassPath)
+ const char* debugFileName, int isBootstrap, const char* bootClassPath,
+ const char* dexoptFlagStr)
{
ZipArchive zippy;
ZipEntry zipEntry;
@@ -123,7 +125,39 @@
*/
DexClassVerifyMode verifyMode = VERIFY_MODE_ALL;
DexOptimizerMode dexOptMode = OPTIMIZE_MODE_VERIFIED;
- if (dvmPrepForDexOpt(bootClassPath, dexOptMode, verifyMode) != 0) {
+ int dexoptFlags = 0; /* bit flags, from enum DexoptFlags */
+ if (dexoptFlagStr[0] != '\0') {
+ const char* opc;
+ const char* val;
+
+ opc = strstr(dexoptFlagStr, "v="); /* verification */
+ if (opc != NULL) {
+ switch (*(opc+2)) {
+ case 'n': verifyMode = VERIFY_MODE_NONE; break;
+ case 'r': verifyMode = VERIFY_MODE_REMOTE; break;
+ case 'a': verifyMode = VERIFY_MODE_ALL; break;
+ default: break;
+ }
+ }
+
+ opc = strstr(dexoptFlagStr, "o="); /* optimization */
+ if (opc != NULL) {
+ switch (*(opc+2)) {
+ case 'n': dexOptMode = OPTIMIZE_MODE_NONE; break;
+ case 'v': dexOptMode = OPTIMIZE_MODE_VERIFIED; break;
+ case 'a': dexOptMode = OPTIMIZE_MODE_ALL; break;
+ default: break;
+ }
+ }
+
+ opc = strstr(dexoptFlagStr, "m=y"); /* register map */
+ if (opc != NULL) {
+ dexoptFlags |= DEXOPT_GEN_REGISTER_MAPS;
+ }
+ }
+ if (dvmPrepForDexOpt(bootClassPath, dexOptMode, verifyMode,
+ dexoptFlags) != 0)
+ {
LOGE("DexOptZ: VM init failed\n");
goto bail;
}
@@ -169,6 +203,7 @@
* 4. filename of file being optimized (used for debug messages and
* for comparing against BOOTCLASSPATH -- does not need to be
* accessible or even exist)
+ * 5. dexopt flags
*
* The BOOTCLASSPATH environment variable is assumed to hold the correct
* boot class path. If the filename provided appears in the boot class
@@ -184,8 +219,9 @@
int zipFd, cacheFd, vmBuildVersion;
const char* inputFileName;
char* bcpCopy = NULL;
+ const char* dexoptFlagStr;
- if (argc != 5) {
+ if (argc != 6) {
LOGE("Wrong number of args for --zip (found %d)\n", argc);
goto bail;
}
@@ -198,6 +234,8 @@
GET_ARG(cacheFd, strtol, "bad cache fd");
inputFileName = *++argv;
--argc;
+ dexoptFlagStr = *++argv;
+ --argc;
/*
* Check to see if this is a bootstrap class entry. If so, truncate
@@ -237,7 +275,7 @@
}
result = extractAndProcessZip(zipFd, cacheFd, inputFileName,
- isBootstrap, bcp);
+ isBootstrap, bcp, dexoptFlagStr);
bail:
free(bcpCopy);
@@ -351,6 +389,7 @@
bool onlyOptVerifiedDex = false;
DexClassVerifyMode verifyMode;
DexOptimizerMode dexOptMode;
+ int dexoptFlags = 0;
/* ugh -- upgrade these to a bit field if they get any more complex */
if ((flags & DEXOPT_VERIFY_ENABLED) != 0) {
@@ -369,8 +408,13 @@
} else {
dexOptMode = OPTIMIZE_MODE_NONE;
}
+ if ((flags & DEXOPT_GEN_REGISTER_MAP) != 0) {
+ dexoptFlags |= DEXOPT_GEN_REGISTER_MAPS;
+ }
- if (dvmPrepForDexOpt(bootClassPath, dexOptMode, verifyMode) != 0) {
+ if (dvmPrepForDexOpt(bootClassPath, dexOptMode, verifyMode,
+ dexoptFlags) != 0)
+ {
LOGE("VM init failed\n");
goto bail;
}
diff --git a/docs/dalvik-bytecode.html b/docs/dalvik-bytecode.html
index 28e6fb4..4945d60 100644
--- a/docs/dalvik-bytecode.html
+++ b/docs/dalvik-bytecode.html
@@ -24,15 +24,17 @@
such as (but not limited to) the program counter and a reference to the
<code>.dex</code> file that contains the method.
</li>
- <li>The <i>N</i> arguments to a method land in the last <i>N</i> registers
- of the method's invocation frame.
- </li>
<li>Registers are 32 bits wide. Adjacent register pairs are used for 64-bit
values.
</li>
<li>In terms of bitwise representation, <code>(Object) null == (int)
0</code>.
</li>
+ <li>The <i>N</i> arguments to a method land in the last <i>N</i> registers
+ of the method's invocation frame, in order. Wide arguments consume
+ two registers. Instance methods are passed a <code>this</code> reference
+ as their first argument.
+ </li>
</ul>
<li>The storage unit in the instruction stream is a 16-bit unsigned quantity.
Some bits in some instructions are ignored / must-be-zero.
@@ -385,9 +387,13 @@
<td>check-cast vAA, type@BBBB</td>
<td><code>A:</code> reference-bearing register (8 bits)<br/>
<code>B:</code> type index (16 bits)</td>
- <td>Throw if the reference in the given register cannot be cast to the
- indicated type. The type must be a reference type (not a primitive
- type).</td>
+ <td>Throw a <code>ClassCastException</code> if the reference in the
+ given register cannot be cast to the indicated type.
+ <p><b>Note:</b> Since <code>A</code> must always be a reference
+ (and not a primitive value), this will necessarily fail at runtime
+ (that is, it will throw an exception) if <code>B</code> refers to a
+ primitive type.</p>
+ </td>
</tr>
<tr>
<td>20 22c</td>
@@ -397,8 +403,11 @@
<code>C:</code> type index (16 bits)</td>
<td>Store in the given destination register <code>1</code>
if the indicated reference is an instance of the given type,
- or <code>0</code> if not. The type must be a
- reference type (not a primitive type).</td>
+ or <code>0</code> if not.
+ <p><b>Note:</b> Since <code>B</code> must always be a reference
+ (and not a primitive value), this will always result
+ in <code>0</code> being stored if <code>C</code> refers to a primitive
+ type.</td>
</tr>
<tr>
<td>21 12x</td>
@@ -462,7 +471,9 @@
</td>
<td>Fill the given array with the indicated data. The reference must be
to an array of primitives, and the data table must match it in type and
- size.
+ must contain no more elements than will fit in the array. That is,
+ the array may be larger than the table, and if so, only the initial
+ elements of the array are set, leaving the remainder alone.
</td>
</tr>
<tr>
@@ -1159,7 +1170,7 @@
<td>float a;<br/>
int64 result = (int64) a;
</td>
- <td>Conversion of <code>float</code> to <code>int32</code>, using
+ <td>Conversion of <code>float</code> to <code>int64</code>, using
round-toward-zero. The same special case rules as for
<code>float-to-int</code> apply here, except that out-of-range values
get converted to either <code>0x7fffffffffffffff</code> or
diff --git a/docs/dalvik-constraints.html b/docs/dalvik-constraints.html
index b935b0a..105225a 100644
--- a/docs/dalvik-constraints.html
+++ b/docs/dalvik-constraints.html
@@ -472,7 +472,7 @@
<tr>
<td>
- B21
+ A21
</td>
<td>
@@ -487,7 +487,7 @@
<tr>
<td>
- B22
+ A22
</td>
<td>
@@ -504,7 +504,7 @@
<tr>
<td>
- B23
+ A23
</td>
<td>
@@ -640,9 +640,10 @@
</td>
<td>
- A register which stores the result of a <code>new-instance</code>
- instruction must not be used if the same <code>new-instance</code>
- instruction is subsequently encountered.
+ A register which holds the result of a <code>new-instance</code>code>
+ instruction must not be used if the same
+ <code>new-instance</code>code> instruction is again executed before
+ the instance is initialized.
</td>
<td>
diff --git a/docs/debugger.html b/docs/debugger.html
new file mode 100644
index 0000000..6e23f0d
--- /dev/null
+++ b/docs/debugger.html
@@ -0,0 +1,211 @@
+<html>
+<head>
+<title>Dalvik Debugger Support</title>
+</head>
+
+<body>
+<h1>Dalvik Debugger Support</h1>
+
+<p>
+The Dalvik virtual machine supports source-level debugging with many popular
+development environments. Any tool that allows remote debugging over JDWP
+(the
+<a href="http://java.sun.com/javase/6/docs/technotes/guides/jpda/jdwp-spec.html">
+Java Debug Wire Protocol</a>) is expected work. Supported debuggers
+include jdb, Eclipse, IntelliJ, and JSwat.
+</p><p>
+The VM does not support tools based on JVMTI (Java Virtual
+Machine Tool Interface). This is a relatively intrusive approach that
+relies on bytecode insertion, something the Dalvik VM does not currently
+support.
+</p><p>
+Dalvik's implementation of JDWP also includes hooks for supporting
+DDM (Dalvik Debug Monitor) features, notably as implemented by DDMS
+(Dalvik Debug Monitor Server) and the Eclipse ADT plugin. The protocol
+and VM interaction is described in some detail
+<a href="debugmon.html">here</a>.
+</p><p>
+All of the debugger support in the VM lives in the <code>dalvik/vm/jdwp</code>
+directory, and is almost entirely isolated from the rest of the VM sources.
+<code>dalvik/vm/Debugger.c</code> bridges the gap. The goal in doing so
+was to make it easier to re-use the JDWP code in other projects.
+</p><p>
+
+
+<h2>Implementation</h2>
+
+<p>
+Every VM that has debugging enabled starts a "JDWP" thread. The thread
+typically sits idle until DDMS or a debugger connects. The thread is
+only responsible for handling requests from the debugger; VM-initated
+communication, such as notifying the debugger when the VM has stopped at
+a breakpoint, are sent from the affected thread.
+</p><p>
+When the VM is embedded in the Android framework,
+debugging is enabled in the VM unless the system property
+<code>ro.secure</code> is set to </code>1</code>. On these
+"secure" devices, debugging is only enabled in app processes whose
+manifest contains <code>android:debuggable="true"</code> in the
+<code><application></code> element.
+
+</p><p>
+The VM recognizes the difference between a connection from DDMS and a
+connection from a debugger (either directly or in concert with DDMS).
+A connection from DDMS alone doesn't result in a change in VM behavior,
+but when the VM sees debugger packets it allocates additional data
+structures and may switch to a different implementation of the interpreter.
+</p><p>
+Because Dalvik maps bytecode into memory read-only, some common
+techniques are difficult to implement without allocating additional memory.
+For example, suppose the debugger sets a breakpoint in a method. The
+quick way to handle this is to insert a breakpoint instruction directly
+into the code. When the instruction is reached, the breakpoint handler
+engages. Without this, it's necessary to perform an "is there a breakpoint
+here" scan. Even with some optimizations, the debug-enabled interpreter
+is much slower than the regular interpreter (perhaps 5x).
+</p><p>
+The JDWP protocol is stateless, so the VM handles individual debugger
+requests as they arrive, and posts events to the debugger as they happen.
+</p><p>
+
+
+<h2>Debug Data</h2>
+<p> Source code debug data, which includes mappings of source code to
+bytecode and lists describing which registers are used to hold method
+arguments and local variables, are optionally emitted by the Java compiler.
+When <code>dx</code> converts Java bytecode to Dalvik bytecode, it must
+also convert this debug data.
+</p><p>
+<code>dx</code> must also ensure that it doesn't perform operations
+that confuse the debugger. For example, re-using registers that hold
+method arguments and the "<code>this</code>" pointer is allowed in
+Dalvik bytecode if the values are never used or no longer needed.
+This can be very confusing for the debugger (and the programmer)
+since the values have method scope and aren't expected to disappear. For
+this reason, <code>dx</code> generates sub-optimal code in some situations
+when debugging support is enabled.
+</p><p>
+Some of the debug data is used for other purposes; in particular, having
+filename and line number data is necessary for generating useful exception
+stack traces. This data can be omitted by <code>dx</code> to make the DEX
+file smaller.
+</p><p>
+
+
+<h2>Usage</h2>
+
+<p>
+The Dalvik VM supports many of the same command-line flags that other popular
+desktop VMs do. To start a VM with debugging enabled, you add a command-line
+flag with some basic options. The basic incantation looks something
+like this:
+
+<pre>-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y</pre>
+or
+<pre>-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y</pre>
+
+</p><p>
+After the initial prefix, options are provided as name=value pairs. The
+options currently supported by the Dalvik VM are:
+<dl>
+ <dt>transport (no default)</dt>
+ <dd>Communication transport mechanism to use. Dalvik supports
+ TCP/IP sockets (<code>dt_socket</code>) and connection over USB
+ through ADB (<code>dt_android_adb</code>).
+ </dd>
+
+ <dt>server (default='n')</dt>
+ <dd>Determines whether the VM acts as a client or a server. When
+ acting as a server, the VM waits for a debugger to connect to it.
+ When acting as a client, the VM attempts to connect to a waiting
+ debugger.
+ </dd>
+
+ <dt>suspend (default='n')</dt>
+ <dd>If set to 'y', the VM will wait for a debugger connection
+ before executing application code. When the debugger connects (or
+ when the VM finishes connecting to the debugger), the VM tells the
+ debugger that it has suspended, and will not proceed until told
+ to resume. If set to 'n', the VM just plows ahead.
+ </dd>
+
+ <dt>address (default="")</dt>
+ <dd>This must be <code>hostname:port</code> when <code>server=n</code>,
+ but can be just <code>port</code> when <code>server=y</code>. This
+ specifies the IP address and port number to connect or listen to.
+ <br>
+ Listening on port 0 has a special meaning: try to
+ listen on port 8000; if that fails, try 8001, 8002, and so on. (This
+ behavior is non-standard and may be removed from a future release.)
+ <br>This option has no meaning for <code>transport=dt_android_adb</code>.
+ </dd>
+
+ <dt>help (no arguments)</dt>
+ <dd>If this is the only option, a brief usage message is displayed.
+ </dd>
+
+ <dt>launch, onthrow, oncaught, timeout</dt>
+ <dd>These options are accepted but ignored.
+ </dd>
+</dl>
+
+</p><p>
+To debug a program on an Android device using DDMS over USB, you could
+use a command like this:
+<pre>% dalvikvm -agentlib:jdwp=transport=dt_android_adb,suspend=y,server=y -cp /data/foo.jar Foo</pre>
+
+This tells the Dalvik VM to run the program with debugging enabled, listening
+for a connection from DDMS, and waiting for a debugger. The program will show
+up with an app name of "?" in the process list, because it wasn't started
+from the Android application framework. From here you would connect your
+debugger to the appropriate DDMS listen port (e.g.
+<code>jdb -attach localhost:8700</code> after selecting it in the app list).
+
+</p><p>
+To debug a program on an Android device using TCP/IP bridged across ADB,
+you would first need to set up forwarding:
+<pre>% adb forward tcp:8000 tcp:8000
+% adb shell dalvikvm -agentlib:jdwp=transport=dt_socket,address=8000,suspend=y,server=y -cp /data/foo.jar Foo</pre>
+and then <code>jdb -attach localhost:8000</code>.
+</p><p>
+(In the above examples, the VM will be suspended when you attach. In jdb,
+type <code>cont</code> to continue.)
+</p><p>
+The DDMS integration makes the <code>dt_android_adb</code> transport much
+more convenient when debugging on an Android device, but when working with
+Dalvik on the desktop it makes sense to use the TCP/IP transport.
+</p><p>
+
+
+<h2>Known Issues and Limitations</h2>
+
+</p><p>
+Most of the optional features JDWP allows are not implemented. These
+include field access watchpoints and better tracking of monitors.
+</p><p>
+Not all JDWP requests are implemented. In particular, anything that
+never gets emitted by the debuggers we've used is not supported and will
+result in error messages being logged. Support will be added when a
+use case is uncovered.
+</p><p>
+
+</p><p>
+The debugger and garbage collector are somewhat loosely
+integrated at present. The VM currently guarantees that any object the
+debugger is aware of will not be garbage collected until after the
+debugger disconnects. This can result in a build-up over time while the
+debugger is connected.
+</p><p>
+The situation is exacerbated by a flaw in the exception processing code,
+which results in nearly all exceptions being added to the "do not discard"
+list, even if the debugger never sees them. Having a debugger attached
+to a program that throws lots of exceptions can result in out-of-memory
+errors. This will be fixed in a future release.
+</p><p>
+
+
+<address>Copyright © 2009 The Android Open Source Project</address>
+</p>
+
+</body>
+</html>
diff --git a/docs/embedded-vm-control.html b/docs/embedded-vm-control.html
index 7812041..f90f0e5 100644
--- a/docs/embedded-vm-control.html
+++ b/docs/embedded-vm-control.html
@@ -111,21 +111,21 @@
<p>There are two command-line flags that control the just-in-time
verification and optimization,
<code>-Xverify</code> and <code>-Xdexopt</code>. The Android framework
-configures these based on the <code>dalvik.vm.verify-bytecode</code>
+configures these based on the <code>dalvik.vm.dexopt-flags</code>
property.
<p>If you set:
-<pre>adb shell setprop dalvik.vm.verify-bytecode true</pre>
+<pre>adb shell setprop dalvik.vm.dexopt-flags v=a,o=v</pre>
then the framework will pass <code>-Xverify:all -Xdexopt:verified</code>
to the VM. This enables verification, and only optimizes classes that
successfully verified. This is the safest setting, and is the default.
-<p>If <code>dalvik.vm.verify-bytecode</code> is set to <code>false</code>,
-the framework passes <code>-Xverify:none -Xdexopt:verified</code> to disable
-verification. (We could pass in <code>-Xdexopt:all</code>, but that wouldn't
-necessarily optimize more of the code, since classes that fail
-verification may well be skipped by the optimizer for the same reasons.)
-Classes will not be verified by <code>dexopt</code>, and unverified code
-will be loaded and executed.
+<p>You could also set <code>dalvik.vm.dexopt-flags</code> to <code>v=n</code>
+to have the framework pass <code>-Xverify:none -Xdexopt:verified</code>
+to disable verification. (We could pass in <code>-Xdexopt:all</code> to
+allow optimization, but that wouldn't necessarily optimize more of the
+code, since classes that fail verification may well be skipped by the
+optimizer for the same reasons.) Classes will not be verified by
+<code>dexopt</code>, and unverified code will be loaded and executed.
<p>Enabling verification will make the <code>dexopt</code> command
take significantly longer, because the verification process is fairly slow.
@@ -143,6 +143,10 @@
This removes the cached versions of the DEX files. Remember to
stop and restart the runtime (<code>adb shell stop; adb shell start</code>).
+<p>(Previous version of the runtime supported the boolean
+<code>dalvik.vm.verify-bytecode</code> property, but that has been
+superceded by <code>dalvik.vm.dexopt-flags</code>.)</p>
+
<h2><a name="execmode">Execution Mode</a></h2>
diff --git a/docs/instruction-formats.html b/docs/instruction-formats.html
index 941689e..d7bf690 100644
--- a/docs/instruction-formats.html
+++ b/docs/instruction-formats.html
@@ -366,15 +366,15 @@
<tr>
<td>B|A|<i>op</i> DDCC H|G|F|E</td>
<td>35fs</td>
- <td><i>[<code>B=5</code>] <code>op</code></i> vB, {vE, vF, vG, vH, vA},
+ <td><i>[<code>B=5</code>] <code>op</code></i> {vE, vF, vG, vH, vA},
vtaboff@CC, iface@DD<br/>
- <i>[<code>B=4</code>] <code>op</code></i> vB, {vE, vF, vG, vH},
+ <i>[<code>B=4</code>] <code>op</code></i> {vE, vF, vG, vH},
vtaboff@CC, iface@DD<br/>
- <i>[<code>B=3</code>] <code>op</code></i> vB, {vE, vF, vG},
+ <i>[<code>B=3</code>] <code>op</code></i> {vE, vF, vG},
vtaboff@CC, iface@DD<br/>
- <i>[<code>B=2</code>] <code>op</code></i> vB, {vE, vF},
+ <i>[<code>B=2</code>] <code>op</code></i> {vE, vF},
vtaboff@CC, iface@DD<br/>
- <i>[<code>B=1</code>] <code>op</code></i> vB, {vE},
+ <i>[<code>B=1</code>] <code>op</code></i> {vE},
vtaboff@CC, iface@DD<br/>
</td>
<td><i>(suggested format for statically linked <code>invoke-interface</code>
diff --git a/docs/jni-tips.html b/docs/jni-tips.html
index 423bca9..e2c3b85 100644
--- a/docs/jni-tips.html
+++ b/docs/jni-tips.html
@@ -22,6 +22,8 @@
</li>
<li> <a href="#Arrays">Primitive Arrays</a>
</li>
+<li> <a href="#RegionCalls">Region Calls</a>
+</li>
<li> <a href="#Exceptions">Exceptions</a>
</li>
@@ -29,6 +31,8 @@
</li>
<li> <a href="#Native_Libraries">Native Libraries</a>
</li>
+<li> <a href="#64bit">64-bit Considerations</a>
+</li>
<li> <a href="#Unsupported">Unsupported Features</a>
</ul>
@@ -219,7 +223,9 @@
is guaranteed to be valid until the corresponding <code>Release</code> call
is issued (which implies that, if the data wasn't copied, the array object
will be pinned down and can't be relocated as part of compacting the heap).
-<strong>You must Release every array you Get.</strong>
+<strong>You must Release every array you Get.</strong> Also, if the Get
+call fails, you must ensure that your code doesn't try to Release a NULL
+pointer later.
</p><p>
You can determine whether or not the data was copied by passing in a
non-NULL pointer for the <code>isCopy</code> argument. This is rarely
@@ -272,6 +278,45 @@
</p><p>
+</p><h2><a name="RegionCalls"> Region Calls </a></h2>
+
+<p>
+There is an alternative to calls like <code>Get<Type>ArrayElements</code>
+and <code>GetStringChars</code> that may be very helpful when all you want
+to do is copy data in or out. Consider the following:
+<pre>
+ jbyte* data = env->GetByteArrayElements(array, NULL);
+ if (data != NULL) {
+ memcpy(buffer, data, len);
+ env->ReleaseByteArrayElements(array, data, JNI_ABORT);
+ }
+</pre>
+<p>
+This grabs the array, copies the first <code>len</code> byte
+elements out of it, and then releases the array. Depending upon the VM
+policies the <code>Get</code> call will either pin or copy the array contents.
+We copy the data (for perhaps a second time), then call Release; in this case
+we use <code>JNI_ABORT</code> so there's no chance of a third copy.
+</p><p>
+We can accomplish the same thing with this:
+<pre>
+ env->GetByteArrayRegion(array, 0, len, buffer);
+</pre>
+</p><p>
+This accomplishes the same thing, with several advantages:
+<ul>
+ <li>Requires one JNI call instead of 3, reducing overhead.
+ <li>Doesn't require pinning or extra data copies.
+ <li>Reduces the risk of programmer error -- no need to match up
+ <code>Get</code> and <code>Release</code> calls.
+</ul>
+</p><p>
+Similarly, you can use the <code>Set<Type>ArrayRegion</code> call
+to copy data into an array, and <code>GetStringRegion</code> or
+<code>GetStringUTFRegion</code> to copy characters out of a
+<code>String</code>.
+
+
</p><h2><a name="Exceptions"> Exceptions </a></h2>
<p>
<strong>You may not call most JNI functions while an exception is pending.</strong>
@@ -380,7 +425,7 @@
it continues on.
</dl></blockquote>
-</p><p>
+
</p><p>
</p><h2><a name="Native_Libraries"> Native Libraries </a></h2>
<p>
@@ -422,7 +467,7 @@
</p><p>
Dalvik does support "discovery" of native methods that are named in a
specific way (see <a href="http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp615">
- the JNI spec</a> for details), but this is less a less desirable
+ the JNI spec</a> for details), but this is a less desirable
approach. It requires more space in the shared object symbol table,
loading is slower because it requires string searches through all of the
loaded shared libraries, and if a method signature is wrong you won't know
@@ -430,6 +475,19 @@
</p><p>
+</p><h2><a name="64bit"> 64-bit Considerations </a></h2>
+
+<p>
+Android is currently expected to run on 32-bit platforms. In theory it
+could be built for a 64-bit system, but that is not a goal at this time.
+For the most part this isn't something that you will need to worry about
+when interacting with native code,
+but it becomes significant if you plan to store pointers to native
+structures in integer fields in an object. To support architectures
+that use 64-bit pointers, <strong>you need to stash your native pointers in a
+<code>long</code> field rather than an <code>int</code></strong>.
+
+
</p><h2><a name="Unsupported"> Unsupported Features </a></h2>
<p>All JNI 1.6 features are supported, with the following exceptions:
<ul>
diff --git a/docs/libraries.html b/docs/libraries.html
index 9fd199c..e1c3035 100644
--- a/docs/libraries.html
+++ b/docs/libraries.html
@@ -34,7 +34,7 @@
<ul>
<li><a href="#vm-specific">Dalvik VM-specific libraries</a></li>
- <li><a href="#interop">Jave programming language interoperability
+ <li><a href="#interop">Java programming language interoperability
libraries</a></li>
</ul>
diff --git a/dx/src/com/android/dx/Version.java b/dx/src/com/android/dx/Version.java
index c745d34..02dc7b2 100644
--- a/dx/src/com/android/dx/Version.java
+++ b/dx/src/com/android/dx/Version.java
@@ -21,5 +21,5 @@
*/
public class Version {
/** non-null; version string */
- public static final String VERSION = "1.1";
+ public static final String VERSION = "1.2";
}
diff --git a/dx/src/com/android/dx/dex/code/LocalIntroduction.java b/dx/src/com/android/dx/dex/code/LocalEnd.java
similarity index 61%
copy from dx/src/com/android/dx/dex/code/LocalIntroduction.java
copy to dx/src/com/android/dx/dex/code/LocalEnd.java
index c085a5e..c19a8dc 100644
--- a/dx/src/com/android/dx/dex/code/LocalIntroduction.java
+++ b/dx/src/com/android/dx/dex/code/LocalEnd.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,30 +21,22 @@
import com.android.dx.rop.code.SourcePosition;
/**
- * Pseudo-instruction which is used to introduce a new local variable. That
- * is, an instance of this class in an instruction stream indicates that
- * starting with the subsequent instruction, the indicated variable
- * is set.
+ * Pseudo-instruction which is used to explicitly end the mapping of a
+ * register to a named local variable. That is, an instance of this
+ * class in an instruction stream indicates that starting with the
+ * subsequent instruction, the indicated variable is no longer valid.
*/
-public final class LocalIntroduction extends ZeroSizeInsn {
+public final class LocalEnd extends ZeroSizeInsn {
/**
- * non-null; register spec representing the local variable introduced
- * by this instance
+ * non-null; register spec representing the local variable ended
+ * by this instance. <b>Note:</b> Technically, only the register
+ * number needs to be recorded here as the rest of the information
+ * is implicit in the ambient local variable state, but other code
+ * will check the other info for consistency.
*/
private final RegisterSpec local;
/**
- * Returns the local variable listing string for a single register spec.
- *
- * @param spec non-null; the spec to convert
- * @return non-null; the string form
- */
- public static String localString(RegisterSpec spec) {
- return spec.regString() + ' ' + spec.getLocalItem().toString() + ": " +
- spec.getTypeBearer().toHuman();
- }
-
- /**
* Constructs an instance. The output address of this instance is initially
* unknown (<code>-1</code>).
*
@@ -52,7 +44,7 @@
* @param local non-null; register spec representing the local
* variable introduced by this instance
*/
- public LocalIntroduction(SourcePosition position, RegisterSpec local) {
+ public LocalEnd(SourcePosition position, RegisterSpec local) {
super(position);
if (local == null) {
@@ -65,17 +57,17 @@
/** {@inheritDoc} */
@Override
public DalvInsn withRegisterOffset(int delta) {
- return new LocalIntroduction(getPosition(), local.withOffset(delta));
+ return new LocalEnd(getPosition(), local.withOffset(delta));
}
/** {@inheritDoc} */
@Override
public DalvInsn withRegisters(RegisterSpecList registers) {
- return new LocalIntroduction(getPosition(), local);
+ return new LocalEnd(getPosition(), local);
}
/**
- * Gets the register spec representing the local variable introduced
+ * Gets the register spec representing the local variable ended
* by this instance.
*
* @return non-null; the register spec
@@ -93,6 +85,6 @@
/** {@inheritDoc} */
@Override
protected String listingString0(boolean noteIndices) {
- return "local-intro " + localString(local);
+ return "local-end " + LocalStart.localString(local);
}
}
diff --git a/dx/src/com/android/dx/dex/code/LocalList.java b/dx/src/com/android/dx/dex/code/LocalList.java
index 16c0192..4614fc4 100644
--- a/dx/src/com/android/dx/dex/code/LocalList.java
+++ b/dx/src/com/android/dx/dex/code/LocalList.java
@@ -23,7 +23,9 @@
import com.android.dx.rop.type.Type;
import com.android.dx.util.FixedSizeList;
+import java.io.PrintStream;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* List of local variables. Each local variable entry indicates a
@@ -34,174 +36,9 @@
/** non-null; empty instance */
public static final LocalList EMPTY = new LocalList(0);
- /**
- * Constructs an instance for the given method, based on the given
- * block order and intermediate local information.
- *
- * @param insns non-null; instructions to convert
- * @return non-null; the constructed list
- */
- public static LocalList make(DalvInsnList insns) {
- ArrayList<Entry> result = new ArrayList<Entry>(100);
- int codeSize = insns.codeSize();
- int sz = insns.size();
- RegisterSpecSet state = null;
- int stateMax = 0;
-
- for (int i = 0; i < sz; i++) {
- DalvInsn insn = insns.get(i);
-
- if (insn instanceof LocalSnapshot) {
- RegisterSpecSet newState = ((LocalSnapshot) insn).getLocals();
- boolean first = (state == null);
-
- if (first) {
- stateMax = newState.getMaxSize();
- }
-
- for (int j = 0; j < stateMax; j++) {
- RegisterSpec oldSpec = first ? null : state.get(j);
- RegisterSpec newSpec = newState.get(j);
- boolean oldEnds = false;
- boolean newStarts = false;
-
- if (oldSpec == null) {
- if (newSpec != null) {
- /*
- * This is a newly-introduced local, not
- * replacing an existing local.
- */
- newStarts = true;
- }
- } else if (newSpec == null) {
- /*
- * This is a local going out of scope, with no
- * replacement.
- */
- oldEnds = true;
- } else if (!oldSpec.equals(newSpec)) {
- /*
- * This is a local going out of scope, immediately
- * replaced by a different local.
- */
- oldEnds = true;
- newStarts = true;
- }
-
- if (oldEnds) {
- endScope(result, oldSpec, insn.getAddress());
- }
-
- if (newStarts) {
- startScope(result, newSpec, insn.getAddress(),
- codeSize);
- }
- }
-
- state = newState;
- } else if (insn instanceof LocalIntroduction) {
- RegisterSpec newSpec = ((LocalIntroduction) insn).getLocal();
- RegisterSpec oldSpec = state.get(newSpec);
-
- boolean oldEnds = false;
- boolean newStarts = false;
-
- if (oldSpec == null) {
- /*
- * This is a newly-introduced local, not replacing an
- * existing local.
- */
- newStarts = true;
- } else if (!oldSpec.equals(newSpec)) {
- /*
- * This is a local going out of scope, immediately
- * replaced by a different local.
- */
- oldEnds = true;
- newStarts = true;
- }
-
- if (newStarts) {
- int address = insn.getAddress();
-
- if (oldEnds) {
- endScope(result, oldSpec, address);
- }
-
- startScope(result, newSpec, address, codeSize);
-
- if (state.isImmutable()) {
- state = state.mutableCopy();
- }
-
- state.put(newSpec);
- }
- }
- }
-
- int resultSz = result.size();
-
- if (resultSz == 0) {
- return EMPTY;
- }
-
- LocalList resultList = new LocalList(resultSz);
-
- for (int i = 0; i < resultSz; i++) {
- resultList.set(i, result.get(i));
- }
-
- resultList.setImmutable();
- return resultList;
- }
-
- /**
- * Helper for {@link #make}, to indicate that the given variable has
- * been introduced.
- *
- * @param result non-null; result in-progress
- * @param spec non-null; register spec for the variable in question
- * @param startAddress >= 0; address at which the scope starts
- * (inclusive)
- * @param endAddress > startAddress; initial scope end address
- * (exclusive)
- */
- private static void startScope(ArrayList<Entry> result, RegisterSpec spec,
- int startAddress, int endAddress) {
- result.add(new Entry(startAddress, endAddress, spec));
- }
-
- /**
- * Helper for {@link #make}, to indicate that the given variable's
- * scope has closed.
- *
- * @param result non-null; result in-progress
- * @param spec non-null; register spec for the variable in question
- * @param endAddress >= 0; address at which the scope ends (exclusive)
- */
- private static void endScope(ArrayList<Entry> result, RegisterSpec spec,
- int endAddress) {
- int sz = result.size();
-
- for (int i = sz - 1; i >= 0; i--) {
- Entry e = result.get(i);
- if (e.matches(spec)) {
- if (e.getStart() == endAddress) {
- /*
- * It turns out that the indicated entry doesn't actually
- * cover any code.
- */
- result.remove(i);
- } else {
- result.set(i, e.withEnd(endAddress));
- }
- return;
- }
- }
-
- throw new RuntimeException("unmatched variable: " + spec);
- }
-
+ /** whether to run the self-check code */
+ private static final boolean DEBUG = false;
+
/**
* Constructs an instance. All indices initially contain <code>null</code>.
*
@@ -227,18 +64,6 @@
* Sets the entry at the given index.
*
* @param n >= 0, < size(); which index
- * @param start >= 0; start address
- * @param end > start; end address (exclusive)
- * @param spec non-null; register spec representing the variable
- */
- public void set(int n, int start, int end, RegisterSpec spec) {
- set0(n, new Entry(start, end, spec));
- }
-
- /**
- * Sets the entry at the given index.
- *
- * @param n >= 0, < size(); which index
* @param entry non-null; the entry to set at <code>n</code>
*/
public void set(int n, Entry entry) {
@@ -246,35 +71,79 @@
}
/**
+ * Does a human-friendly dump of this instance.
+ *
+ * @param out non-null; where to dump
+ * @param prefix non-null; prefix to attach to each line of output
+ */
+ public void debugPrint(PrintStream out, String prefix) {
+ int sz = size();
+
+ for (int i = 0; i < sz; i++) {
+ out.print(prefix);
+ out.println(get(i));
+ }
+ }
+
+ /**
+ * Disposition of a local entry.
+ */
+ public static enum Disposition {
+ /** local started (introduced) */
+ START,
+
+ /** local ended without being replaced */
+ END_SIMPLY,
+
+ /** local ended because it was directly replaced */
+ END_REPLACED,
+
+ /** local ended because it was moved to a different register */
+ END_MOVED,
+
+ /**
+ * local ended because the previous local clobbered this one
+ * (because it is category-2)
+ */
+ END_CLOBBERED_BY_PREV,
+
+ /**
+ * local ended because the next local clobbered this one
+ * (because this one is a category-2)
+ */
+ END_CLOBBERED_BY_NEXT;
+ }
+
+ /**
* Entry in a local list.
*/
- public static class Entry {
- /** >= 0; start address */
- private final int start;
+ public static class Entry implements Comparable<Entry> {
+ /** >= 0; address */
+ private final int address;
- /** > start; end address (exclusive) */
- private final int end;
+ /** non-null; disposition of the local */
+ private final Disposition disposition;
/** non-null; register spec representing the variable */
private final RegisterSpec spec;
- /** non-null; variable type */
+ /** non-null; variable type (derived from {@code spec}) */
private final CstType type;
-
+
/**
* Constructs an instance.
*
- * @param start >= 0; start address
- * @param end > start; end address (exclusive)
+ * @param address >= 0; address
+ * @param disposition non-null; disposition of the local
* @param spec non-null; register spec representing the variable
*/
- public Entry(int start, int end, RegisterSpec spec) {
- if (start < 0) {
- throw new IllegalArgumentException("start < 0");
+ public Entry(int address, Disposition disposition, RegisterSpec spec) {
+ if (address < 0) {
+ throw new IllegalArgumentException("address < 0");
}
- if (end <= start) {
- throw new IllegalArgumentException("end <= start");
+ if (disposition == null) {
+ throw new NullPointerException("disposition == null");
}
try {
@@ -287,37 +156,78 @@
throw new NullPointerException("spec == null");
}
- this.start = start;
- this.end = end;
+ this.address = address;
+ this.disposition = disposition;
this.spec = spec;
+ this.type = CstType.intern(spec.getType());
+ }
- if (spec.getType() == Type.KNOWN_NULL) {
- /*
- * KNOWN_NULL's descriptor is '<null>', which we do
- * not want to emit. Everything else is as expected.
- */
- this.type = CstType.OBJECT;
- } else {
- this.type = CstType.intern(spec.getType());
+ /** {@inheritDoc} */
+ public String toString() {
+ return Integer.toHexString(address) + " " + disposition + " " +
+ spec;
+ }
+
+ /** {@inheritDoc} */
+ public boolean equals(Object other) {
+ if (!(other instanceof Entry)) {
+ return false;
}
+
+ return (compareTo((Entry) other) == 0);
}
/**
- * Gets the start address.
+ * Compares by (in priority order) address, end then start
+ * disposition (variants of end are all consistered
+ * equivalent), and spec.
*
- * @return >= 0; the start address
+ * @param other non-null; entry to compare to
+ * @return {@code -1..1}; standard result of comparison
*/
- public int getStart() {
- return start;
+ public int compareTo(Entry other) {
+ if (address < other.address) {
+ return -1;
+ } else if (address > other.address) {
+ return 1;
+ }
+
+ boolean thisIsStart = isStart();
+ boolean otherIsStart = other.isStart();
+
+ if (thisIsStart != otherIsStart) {
+ return thisIsStart ? 1 : -1;
+ }
+
+ return spec.compareTo(other.spec);
}
/**
- * Gets the end address (exclusive).
+ * Gets the address.
*
- * @return > start; the end address (exclusive)
+ * @return >= 0; the address
*/
- public int getEnd() {
- return end;
+ public int getAddress() {
+ return address;
+ }
+
+ /**
+ * Gets the disposition.
+ *
+ * @return non-null; the disposition
+ */
+ public Disposition getDisposition() {
+ return disposition;
+ }
+
+ /**
+ * Gets whether this is a local start. This is just shorthand for
+ * {@code getDisposition() == Disposition.START}.
+ *
+ * @return {@code true} iff this is a start
+ */
+ public boolean isStart() {
+ return disposition == Disposition.START;
}
/**
@@ -372,8 +282,8 @@
* @return <code>true</code> iff this instance matches
* <code>spec</code>
*/
- public boolean matches(RegisterSpec spec) {
- return spec.equals(this.spec);
+ public boolean matches(RegisterSpec otherSpec) {
+ return spec.equalsUsingSimpleType(otherSpec);
}
/**
@@ -385,18 +295,619 @@
* <code>other</code>
*/
public boolean matches(Entry other) {
- return other.spec.equals(this.spec);
+ return matches(other.spec);
}
/**
- * Returns an instance just like this one, except with the end
- * address altered to be the one given.
+ * Returns an instance just like this one but with the disposition
+ * set as given
*
- * @param newEnd > getStart(); the end address of the new instance
+ * @param disposition non-null; the new disposition
* @return non-null; an appropriately-constructed instance
*/
- public Entry withEnd(int newEnd) {
- return new Entry(start, newEnd, spec);
+ public Entry withDisposition(Disposition disposition) {
+ if (disposition == this.disposition) {
+ return this;
+ }
+
+ return new Entry(address, disposition, spec);
}
}
+
+ /**
+ * Constructs an instance for the given method, based on the given
+ * block order and intermediate local information.
+ *
+ * @param insns non-null; instructions to convert
+ * @return non-null; the constructed list
+ */
+ public static LocalList make(DalvInsnList insns) {
+ int sz = insns.size();
+
+ /*
+ * Go through the insn list, looking for all the local
+ * variable pseudoinstructions, splitting out LocalSnapshots
+ * into separate per-variable starts, adding explicit ends
+ * wherever a variable is replaced or moved, and collecting
+ * these and all the other local variable "activity"
+ * together into an output list (without the other insns).
+ *
+ * Note: As of this writing, this method won't be handed any
+ * insn lists that contain local ends, but I (danfuzz) expect
+ * that to change at some point, when we start feeding that
+ * info explicitly into the rop layer rather than only trying
+ * to infer it. So, given that expectation, this code is
+ * written to deal with them.
+ */
+
+ MakeState state = new MakeState(sz);
+
+ for (int i = 0; i < sz; i++) {
+ DalvInsn insn = insns.get(i);
+
+ if (insn instanceof LocalSnapshot) {
+ RegisterSpecSet snapshot =
+ ((LocalSnapshot) insn).getLocals();
+ state.snapshot(insn.getAddress(), snapshot);
+ } else if (insn instanceof LocalStart) {
+ RegisterSpec local = ((LocalStart) insn).getLocal();
+ state.startLocal(insn.getAddress(), local);
+ } else if (insn instanceof LocalEnd) {
+ RegisterSpec local = ((LocalEnd) insn).getLocal();
+ state.endLocal(insn.getAddress(), local);
+ }
+ }
+
+ LocalList result = state.finish();
+
+ if (DEBUG) {
+ debugVerify(result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Debugging helper that verifies the constraint that a list doesn't
+ * contain any redundant local starts and that local ends that are
+ * due to replacements are properly annotated.
+ */
+ private static void debugVerify(LocalList locals) {
+ try {
+ debugVerify0(locals);
+ } catch (RuntimeException ex) {
+ int sz = locals.size();
+ for (int i = 0; i < sz; i++) {
+ System.err.println(locals.get(i));
+ }
+ throw ex;
+ }
+
+ }
+
+ /**
+ * Helper for {@link #debugVerify} which does most of the work.
+ */
+ private static void debugVerify0(LocalList locals) {
+ int sz = locals.size();
+ Entry[] active = new Entry[65536];
+
+ for (int i = 0; i < sz; i++) {
+ Entry e = locals.get(i);
+ int reg = e.getRegister();
+
+ if (e.isStart()) {
+ Entry already = active[reg];
+
+ if ((already != null) && e.matches(already)) {
+ throw new RuntimeException("redundant start at " +
+ Integer.toHexString(e.getAddress()) + ": got " +
+ e + "; had " + already);
+ }
+
+ active[reg] = e;
+ } else {
+ if (active[reg] == null) {
+ throw new RuntimeException("redundant end at " +
+ Integer.toHexString(e.getAddress()));
+ }
+
+ int addr = e.getAddress();
+ boolean foundStart = false;
+
+ for (int j = i + 1; j < sz; j++) {
+ Entry test = locals.get(j);
+ if (test.getAddress() != addr) {
+ break;
+ }
+ if (test.getRegisterSpec().getReg() == reg) {
+ if (test.isStart()) {
+ if (e.getDisposition()
+ != Disposition.END_REPLACED) {
+ throw new RuntimeException(
+ "improperly marked end at " +
+ Integer.toHexString(addr));
+ }
+ foundStart = true;
+ } else {
+ throw new RuntimeException(
+ "redundant end at " +
+ Integer.toHexString(addr));
+ }
+ }
+ }
+
+ if (!foundStart &&
+ (e.getDisposition() == Disposition.END_REPLACED)) {
+ throw new RuntimeException(
+ "improper end replacement claim at " +
+ Integer.toHexString(addr));
+ }
+
+ active[reg] = null;
+ }
+ }
+ }
+
+ /**
+ * Intermediate state when constructing a local list.
+ */
+ public static class MakeState {
+ /** non-null; result being collected */
+ private final ArrayList<Entry> result;
+
+ /**
+ * >= 0; running count of nulled result entries, to help with
+ * sizing the final list
+ */
+ private int nullResultCount;
+
+ /** null-ok; current register mappings */
+ private RegisterSpecSet regs;
+
+ /** null-ok; result indices where local ends are stored */
+ private int[] endIndices;
+
+ /** >= 0; last address seen */
+ private int lastAddress;
+
+ /**
+ * >= 0; result index where the first element for the most
+ * recent address is stored
+ */
+ private int startIndexForAddress;
+
+ /**
+ * Constructs an instance.
+ */
+ public MakeState(int initialSize) {
+ result = new ArrayList<Entry>(initialSize);
+ nullResultCount = 0;
+ regs = null;
+ endIndices = null;
+ lastAddress = 0;
+ startIndexForAddress = 0;
+ }
+
+ /**
+ * Checks the address and other vitals as a prerequisite to
+ * further processing.
+ *
+ * @param address >= 0; address about to be processed
+ * @param reg >= 0; register number about to be processed
+ */
+ private void aboutToProcess(int address, int reg) {
+ boolean first = (endIndices == null);
+
+ if ((address == lastAddress) && !first) {
+ return;
+ }
+
+ if (address < lastAddress) {
+ throw new RuntimeException("shouldn't happen");
+ }
+
+ if (first || (reg >= endIndices.length)) {
+ /*
+ * This is the first allocation of the state set and
+ * index array, or we need to grow. (The latter doesn't
+ * happen much; in fact, we have only ever observed
+ * it happening in test cases, never in "real" code.)
+ */
+ int newSz = reg + 1;
+ RegisterSpecSet newRegs = new RegisterSpecSet(newSz);
+ int[] newEnds = new int[newSz];
+ Arrays.fill(newEnds, -1);
+
+ if (!first) {
+ newRegs.putAll(regs);
+ System.arraycopy(endIndices, 0, newEnds, 0,
+ endIndices.length);
+ }
+
+ regs = newRegs;
+ endIndices = newEnds;
+ }
+ }
+
+ /**
+ * Sets the local state at the given address to the given snapshot.
+ * The first call on this instance must be to this method, so that
+ * the register state can be properly sized.
+ *
+ * @param address >= 0; the address
+ * @param specs non-null; spec set representing the locals
+ */
+ public void snapshot(int address, RegisterSpecSet specs) {
+ int sz = specs.getMaxSize();
+ aboutToProcess(address, sz - 1);
+
+ for (int i = 0; i < sz; i++) {
+ RegisterSpec oldSpec = regs.get(i);
+ RegisterSpec newSpec = filterSpec(specs.get(i));
+
+ if (oldSpec == null) {
+ if (newSpec != null) {
+ startLocal(address, newSpec);
+ }
+ } else if (newSpec == null) {
+ endLocal(address, oldSpec);
+ } else if (! newSpec.equalsUsingSimpleType(oldSpec)) {
+ endLocal(address, oldSpec);
+ startLocal(address, newSpec);
+ }
+ }
+ }
+
+ /**
+ * Starts a local at the given address.
+ *
+ * @param address >= 0; the address
+ * @param startedLocal non-null; spec representing the started local
+ */
+ public void startLocal(int address, RegisterSpec startedLocal) {
+ int regNum = startedLocal.getReg();
+
+ startedLocal = filterSpec(startedLocal);
+ aboutToProcess(address, regNum);
+
+ RegisterSpec existingLocal = regs.get(regNum);
+
+ if (startedLocal.equalsUsingSimpleType(existingLocal)) {
+ // Silently ignore a redundant start.
+ return;
+ }
+
+ RegisterSpec movedLocal = regs.findMatchingLocal(startedLocal);
+ if (movedLocal != null) {
+ /*
+ * The same variable was moved from one register to another.
+ * So add an end for its old location.
+ */
+ addOrUpdateEnd(address, Disposition.END_MOVED, movedLocal);
+ }
+
+ int endAt = endIndices[regNum];
+
+ if (existingLocal != null) {
+ /*
+ * There is an existing (but non-matching) local.
+ * Add an explicit end for it.
+ */
+ add(address, Disposition.END_REPLACED, existingLocal);
+ } else if (endAt >= 0) {
+ /*
+ * Look for an end local for the same register at the
+ * same address. If found, then update it or delete
+ * it, depending on whether or not it represents the
+ * same variable as the one being started.
+ */
+ Entry endEntry = result.get(endAt);
+ if (endEntry.getAddress() == address) {
+ if (endEntry.matches(startedLocal)) {
+ /*
+ * There was already an end local for the same
+ * variable at the same address. This turns
+ * out to be superfluous, as we are starting
+ * up the exact same local. This situation can
+ * happen when a single local variable got
+ * somehow "split up" during intermediate
+ * processing. In any case, rather than represent
+ * the end-then-start, just remove the old end.
+ */
+ result.set(endAt, null);
+ nullResultCount++;
+ regs.put(startedLocal);
+ endIndices[regNum] = -1;
+ return;
+ } else {
+ /*
+ * There was a different variable ended at the
+ * same address. Update it to indicate that
+ * it was ended due to a replacement (rather than
+ * ending for no particular reason).
+ */
+ endEntry = endEntry.withDisposition(
+ Disposition.END_REPLACED);
+ result.set(endAt, endEntry);
+ }
+ }
+ }
+
+ /*
+ * The code above didn't find and remove an unnecessary
+ * local end, so we now have to add one or more entries to
+ * the output to capture the transition.
+ */
+
+ /*
+ * If the local just below (in the register set at reg-1)
+ * is of category-2, then it is ended by this new start.
+ */
+ if (regNum > 0) {
+ RegisterSpec justBelow = regs.get(regNum - 1);
+ if ((justBelow != null) && justBelow.isCategory2()) {
+ addOrUpdateEnd(address,
+ Disposition.END_CLOBBERED_BY_NEXT,
+ justBelow);
+ }
+ }
+
+ /*
+ * Similarly, if this local is category-2, then the local
+ * just above (if any) is ended by the start now being
+ * emitted.
+ */
+ if (startedLocal.isCategory2()) {
+ RegisterSpec justAbove = regs.get(regNum + 1);
+ if (justAbove != null) {
+ addOrUpdateEnd(address,
+ Disposition.END_CLOBBERED_BY_PREV,
+ justAbove);
+ }
+ }
+
+ /*
+ * TODO: Add an end for the same local in a different reg,
+ * if any (that is, if the local migrates from vX to vY,
+ * we should note that as a local end in vX).
+ */
+
+ add(address, Disposition.START, startedLocal);
+ }
+
+ /**
+ * Ends a local at the given address.
+ *
+ * @param address >= 0; the address
+ * @param endedLocal non-null; spec representing the local being ended
+ */
+ public void endLocal(int address, RegisterSpec endedLocal) {
+ int regNum = endedLocal.getReg();
+
+ endedLocal = filterSpec(endedLocal);
+ aboutToProcess(address, regNum);
+
+ int endAt = endIndices[regNum];
+
+ if (endAt >= 0) {
+ /*
+ * The local in the given register is already ended.
+ * Silently return without adding anything to the result.
+ */
+ return;
+ }
+
+ // Check for start and end at the same address.
+ if (checkForEmptyRange(address, endedLocal)) {
+ return;
+ }
+
+ add(address, Disposition.END_SIMPLY, endedLocal);
+ }
+
+ /**
+ * Helper for {@link #endLocal}, which handles the cases where
+ * and end local is issued at the same address as a start local
+ * for the same register. If this case is found, then this
+ * method will remove the start (as the local was never actually
+ * active), update the {@link #endIndices} to be accurate, and
+ * if needed update the newly-active end to reflect an altered
+ * disposition.
+ *
+ * @param address >= 0; the address
+ * @param endedLocal non-null; spec representing the local being ended
+ * @return {@code true} iff this method found the case in question
+ * and adjusted things accordingly
+ */
+ private boolean checkForEmptyRange(int address,
+ RegisterSpec endedLocal) {
+ int at = result.size() - 1;
+ Entry entry;
+
+ // Look for a previous entry at the same address.
+ for (/*at*/; at >= 0; at--) {
+ entry = result.get(at);
+
+ if (entry == null) {
+ continue;
+ }
+
+ if (entry.getAddress() != address) {
+ // We didn't find any match at the same address.
+ return false;
+ }
+
+ if (entry.matches(endedLocal)) {
+ break;
+ }
+ }
+
+ /*
+ * In fact, we found that the endedLocal had started at the
+ * same address, so do all the requisite cleanup.
+ */
+
+ regs.remove(endedLocal);
+ result.set(at, null);
+ nullResultCount++;
+
+ int regNum = endedLocal.getReg();
+ boolean found = false;
+ entry = null;
+
+ // Now look back further to update where the register ended.
+ for (at--; at >= 0; at--) {
+ entry = result.get(at);
+
+ if (entry == null) {
+ continue;
+ }
+
+ if (entry.getRegisterSpec().getReg() == regNum) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ // We found an end for the same register.
+ endIndices[regNum] = at;
+
+ if (entry.getAddress() == address) {
+ /*
+ * It's still the same address, so update the
+ * disposition.
+ */
+ result.set(at,
+ entry.withDisposition(Disposition.END_SIMPLY));
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Converts a given spec into the form acceptable for use in a
+ * local list. This, in particular, transforms the "known
+ * null" type into simply {@code Object}. This method needs to
+ * be called for any spec that is on its way into a locals
+ * list.
+ *
+ * <p>This isn't necessarily the cleanest way to achieve the
+ * goal of not representing known nulls in a locals list, but
+ * it gets the job done.</p>
+ *
+ * @param orig null-ok; the original spec
+ * @return null-ok; an appropriately modified spec, or the
+ * original if nothing needs to be done
+ */
+ private static RegisterSpec filterSpec(RegisterSpec orig) {
+ if ((orig != null) && (orig.getType() == Type.KNOWN_NULL)) {
+ return orig.withType(Type.OBJECT);
+ }
+
+ return orig;
+ }
+
+ /**
+ * Adds an entry to the result, updating the adjunct tables
+ * accordingly.
+ *
+ * @param address >= 0; the address
+ * @param disposition non-null; the disposition
+ * @param spec non-null; spec representing the local
+ */
+ private void add(int address, Disposition disposition,
+ RegisterSpec spec) {
+ int regNum = spec.getReg();
+
+ result.add(new Entry(address, disposition, spec));
+
+ if (disposition == Disposition.START) {
+ regs.put(spec);
+ endIndices[regNum] = -1;
+ } else {
+ regs.remove(spec);
+ endIndices[regNum] = result.size() - 1;
+ }
+ }
+
+ /**
+ * Adds or updates an end local (changing its disposition).
+ *
+ * @param address >= 0; the address
+ * @param disposition non-null; the disposition
+ * @param spec non-null; spec representing the local
+ */
+ private void addOrUpdateEnd(int address, Disposition disposition,
+ RegisterSpec spec) {
+ if (disposition == Disposition.START) {
+ throw new RuntimeException("shouldn't happen");
+ }
+
+ int regNum = spec.getReg();
+ int endAt = endIndices[regNum];
+
+ if (endAt >= 0) {
+ Entry endEntry = result.get(endAt);
+ if ((endEntry.getAddress() == address) &&
+ endEntry.getRegisterSpec().equals(spec)) {
+ result.set(endAt, endEntry.withDisposition(disposition));
+ regs.remove(spec);
+ return;
+ }
+ }
+
+ add(address, disposition, spec);
+ }
+
+ /**
+ * Finishes processing altogether and gets the result.
+ *
+ * @return non-null; the result list
+ */
+ public LocalList finish() {
+ aboutToProcess(Integer.MAX_VALUE, 0);
+
+ int resultSz = result.size();
+ int finalSz = resultSz - nullResultCount;
+
+ if (finalSz == 0) {
+ return EMPTY;
+ }
+
+ /*
+ * Collect an array of only the non-null entries, and then
+ * sort it to get a consistent order for everything: Local
+ * ends and starts for a given address could come in any
+ * order, but we want ends before starts as well as
+ * registers in order (within ends or starts).
+ */
+
+ Entry[] resultArr = new Entry[finalSz];
+
+ if (resultSz == finalSz) {
+ result.toArray(resultArr);
+ } else {
+ int at = 0;
+ for (Entry e : result) {
+ if (e != null) {
+ resultArr[at++] = e;
+ }
+ }
+ }
+
+ Arrays.sort(resultArr);
+
+ LocalList resultList = new LocalList(finalSz);
+
+ for (int i = 0; i < finalSz; i++) {
+ resultList.set(i, resultArr[i]);
+ }
+
+ resultList.setImmutable();
+ return resultList;
+ }
+ }
}
diff --git a/dx/src/com/android/dx/dex/code/LocalSnapshot.java b/dx/src/com/android/dx/dex/code/LocalSnapshot.java
index 616104a..19a9baa 100644
--- a/dx/src/com/android/dx/dex/code/LocalSnapshot.java
+++ b/dx/src/com/android/dx/dex/code/LocalSnapshot.java
@@ -87,7 +87,7 @@
RegisterSpec spec = locals.get(i);
if (spec != null) {
sb.append("\n ");
- sb.append(LocalIntroduction.localString(spec));
+ sb.append(LocalStart.localString(spec));
}
}
diff --git a/dx/src/com/android/dx/dex/code/LocalIntroduction.java b/dx/src/com/android/dx/dex/code/LocalStart.java
similarity index 88%
rename from dx/src/com/android/dx/dex/code/LocalIntroduction.java
rename to dx/src/com/android/dx/dex/code/LocalStart.java
index c085a5e..22e20f8 100644
--- a/dx/src/com/android/dx/dex/code/LocalIntroduction.java
+++ b/dx/src/com/android/dx/dex/code/LocalStart.java
@@ -24,9 +24,9 @@
* Pseudo-instruction which is used to introduce a new local variable. That
* is, an instance of this class in an instruction stream indicates that
* starting with the subsequent instruction, the indicated variable
- * is set.
+ * is bound.
*/
-public final class LocalIntroduction extends ZeroSizeInsn {
+public final class LocalStart extends ZeroSizeInsn {
/**
* non-null; register spec representing the local variable introduced
* by this instance
@@ -52,7 +52,7 @@
* @param local non-null; register spec representing the local
* variable introduced by this instance
*/
- public LocalIntroduction(SourcePosition position, RegisterSpec local) {
+ public LocalStart(SourcePosition position, RegisterSpec local) {
super(position);
if (local == null) {
@@ -65,13 +65,13 @@
/** {@inheritDoc} */
@Override
public DalvInsn withRegisterOffset(int delta) {
- return new LocalIntroduction(getPosition(), local.withOffset(delta));
+ return new LocalStart(getPosition(), local.withOffset(delta));
}
/** {@inheritDoc} */
@Override
public DalvInsn withRegisters(RegisterSpecList registers) {
- return new LocalIntroduction(getPosition(), local);
+ return new LocalStart(getPosition(), local);
}
/**
@@ -93,6 +93,6 @@
/** {@inheritDoc} */
@Override
protected String listingString0(boolean noteIndices) {
- return "local-intro " + localString(local);
+ return "local-start " + localString(local);
}
}
diff --git a/dx/src/com/android/dx/dex/code/OutputFinisher.java b/dx/src/com/android/dx/dex/code/OutputFinisher.java
index f90e970..73eecf8 100644
--- a/dx/src/com/android/dx/dex/code/OutputFinisher.java
+++ b/dx/src/com/android/dx/dex/code/OutputFinisher.java
@@ -111,8 +111,8 @@
return true;
}
}
- } else if (insn instanceof LocalIntroduction) {
- RegisterSpec spec = ((LocalIntroduction) insn).getLocal();
+ } else if (insn instanceof LocalStart) {
+ RegisterSpec spec = ((LocalStart) insn).getLocal();
if (hasLocalInfo(spec)) {
return true;
}
@@ -168,8 +168,8 @@
for (int i = 0; i < size; i++) {
addConstants(result, specs.get(i));
}
- } else if (insn instanceof LocalIntroduction) {
- RegisterSpec spec = ((LocalIntroduction) insn).getLocal();
+ } else if (insn instanceof LocalStart) {
+ RegisterSpec spec = ((LocalStart) insn).getLocal();
addConstants(result, spec);
}
}
diff --git a/dx/src/com/android/dx/dex/code/RopTranslator.java b/dx/src/com/android/dx/dex/code/RopTranslator.java
index 2edfce7..f3dfe0b 100644
--- a/dx/src/com/android/dx/dex/code/RopTranslator.java
+++ b/dx/src/com/android/dx/dex/code/RopTranslator.java
@@ -457,7 +457,8 @@
* @param resultReg null-ok; the real result to use (ignore the insn's)
* @return non-null; the instruction's complete register list
*/
- private static RegisterSpecList getRegs(Insn insn, RegisterSpec resultReg) {
+ private static RegisterSpecList getRegs(Insn insn,
+ RegisterSpec resultReg) {
RegisterSpecList regs = insn.getSources();
if (insn.getOpcode().isCommutative()
@@ -703,7 +704,8 @@
if (hasResult != (realResult != null)) {
throw new RuntimeException(
- "Insn with result/move-result-pseudo mismatch " + insn);
+ "Insn with result/move-result-pseudo mismatch " +
+ insn);
}
if ((rop.getOpcode() == RegOps.NEW_ARRAY) &&
@@ -854,7 +856,7 @@
}
/**
- * Adds a {@link LocalIntroduction} to the output if the given
+ * Adds a {@link LocalStart} to the output if the given
* instruction in fact introduces a local variable.
*
* @param insn non-null; instruction in question
@@ -863,7 +865,7 @@
RegisterSpec spec = locals.getAssignment(insn);
if (spec != null) {
- addOutput(new LocalIntroduction(insn.getPosition(), spec));
+ addOutput(new LocalStart(insn.getPosition(), spec));
}
}
}
diff --git a/dx/src/com/android/dx/dex/file/DebugInfoDecoder.java b/dx/src/com/android/dx/dex/file/DebugInfoDecoder.java
index f630f1c..3ffd276 100644
--- a/dx/src/com/android/dx/dex/file/DebugInfoDecoder.java
+++ b/dx/src/com/android/dx/dex/file/DebugInfoDecoder.java
@@ -16,6 +16,8 @@
package com.android.dx.dex.file;
+import com.android.dx.dex.code.DalvCode;
+import com.android.dx.dex.code.DalvInsnList;
import com.android.dx.dex.code.LocalList;
import com.android.dx.dex.code.PositionList;
import com.android.dx.rop.cst.CstMethodRef;
@@ -41,20 +43,28 @@
public class DebugInfoDecoder {
/** encoded debug info */
private final byte[] encoded;
+
/** positions decoded */
private final ArrayList<PositionEntry> positions;
+
/** locals decoded */
private final ArrayList<LocalEntry> locals;
+
/** size of code block in code units */
private final int codesize;
+
/** indexed by register, the last local variable live in a reg */
private final LocalEntry[] lastEntryForReg;
+
/** method descriptor of method this debug info is for */
private final Prototype desc;
+
/** true if method is static */
private final boolean isStatic;
+
/** dex file this debug info will be stored in */
private final DexFile file;
+
/**
* register size, in register units, of the register space
* used by this method
@@ -81,8 +91,11 @@
* @param ref method descriptor of method this debug info is for
* @param file dex file this debug info will be stored in
*/
- DebugInfoDecoder (byte[] encoded, int codesize, int regSize,
+ DebugInfoDecoder(byte[] encoded, int codesize, int regSize,
boolean isStatic, CstMethodRef ref, DexFile file) {
+ if (encoded == null) {
+ throw new NullPointerException("encoded == null");
+ }
this.encoded = encoded;
this.isStatic = isStatic;
@@ -90,24 +103,37 @@
this.file = file;
this.regSize = regSize;
- positions = new ArrayList();
- locals = new ArrayList();
+ positions = new ArrayList<PositionEntry>();
+ locals = new ArrayList<LocalEntry>();
this.codesize = codesize;
lastEntryForReg = new LocalEntry[regSize];
- thisStringIdx = file.getStringIds().indexOf(new CstUtf8("this"));
+ int idx = -1;
+
+ try {
+ idx = file.getStringIds().indexOf(new CstUtf8("this"));
+ } catch (IllegalArgumentException ex) {
+ /*
+ * Silently tolerate not finding "this". It just means that
+ * no method has local variable info that looks like
+ * a standard instance method.
+ */
+ }
+
+ thisStringIdx = idx;
}
/**
* An entry in the resulting postions table
*/
- static class PositionEntry {
+ static private class PositionEntry {
/** bytecode address */
- int address;
- /** line number */
- int line;
+ public int address;
- PositionEntry(int address, int line) {
+ /** line number */
+ public int line;
+
+ public PositionEntry(int address, int line) {
this.address = address;
this.line = line;
}
@@ -116,37 +142,40 @@
/**
* An entry in the resulting locals table
*/
- static class LocalEntry {
- LocalEntry(int start, int reg, int nameIndex, int typeIndex,
- int signatureIndex) {
- this.start = start;
+ static private class LocalEntry {
+ /** address of event */
+ public int address;
+
+ /** {@code true} iff it's a local start */
+ public boolean isStart;
+
+ /** register number */
+ public int reg;
+
+ /** index of name in strings table */
+ public int nameIndex;
+
+ /** index of type in types table */
+ public int typeIndex;
+
+ /** index of type signature in strings table */
+ public int signatureIndex;
+
+ public LocalEntry(int address, boolean isStart, int reg, int nameIndex,
+ int typeIndex, int signatureIndex) {
+ this.address = address;
+ this.isStart = isStart;
this.reg = reg;
this.nameIndex = nameIndex;
this.typeIndex = typeIndex;
this.signatureIndex = signatureIndex;
}
- /** start of address range */
- int start;
-
- /**
- * End of address range. Initialized to MAX_VALUE here but will
- * be set to no more than 1 + max bytecode address of method.
- */
- int end = Integer.MAX_VALUE;
-
- /** register number */
- int reg;
-
- /** index of name in strings table */
- int nameIndex;
-
- /** index of type in types table */
- int typeIndex;
-
- /** index of type signature in strings table */
- int signatureIndex;
-
+ public String toString() {
+ return String.format("[%x %s v%d %04x %04x %04x]",
+ address, isStart ? "start" : "end", reg,
+ nameIndex, typeIndex, signatureIndex);
+ }
}
/**
@@ -166,13 +195,6 @@
* @return locals list in ascending address order.
*/
public List<LocalEntry> getLocals() {
- // TODO move this loop:
- // Any variable that didnt end ends now
- for (LocalEntry local: locals) {
- if (local.end == Integer.MAX_VALUE) {
- local.end = codesize;
- }
- }
return locals;
}
@@ -229,8 +251,8 @@
if (!isStatic) {
// Start off with implicit 'this' entry
- LocalEntry thisEntry
- = new LocalEntry(0, curReg, thisStringIdx, 0, 0);
+ LocalEntry thisEntry =
+ new LocalEntry(0, true, curReg, thisStringIdx, 0, 0);
locals.add(thisEntry);
lastEntryForReg[curReg] = thisEntry;
curReg++;
@@ -242,15 +264,19 @@
int nameIdx = readStringIndex(bs);
- if(nameIdx == -1) {
- // unnamed parameter
+ if (nameIdx == -1) {
+ /*
+ * Unnamed parameter; often but not always filled in by an
+ * extended start op after the prologue
+ */
+ le = new LocalEntry(0, true, curReg, -1, 0, 0);
} else {
- // final '0' should be idx of paramType.getDescriptor()
- le = new LocalEntry(0, curReg, nameIdx, 0, 0);
- locals.add(le);
- lastEntryForReg[curReg] = le;
+ // TODO: Final 0 should be idx of paramType.getDescriptor().
+ le = new LocalEntry(0, true, curReg, nameIdx, 0, 0);
}
+ locals.add(le);
+ lastEntryForReg[curReg] = le;
curReg += paramType.getCategory();
}
@@ -269,15 +295,7 @@
int nameIdx = readStringIndex(bs);
int typeIdx = readStringIndex(bs);
LocalEntry le = new LocalEntry(
- address, reg, nameIdx, typeIdx, 0);
-
- // a "start" is implicitly the "end" of whatever was
- // previously defined in the register
- if (lastEntryForReg[reg] != null
- && lastEntryForReg[reg].end == Integer.MAX_VALUE) {
-
- lastEntryForReg[reg].end = address;
- }
+ address, true, reg, nameIdx, typeIdx, 0);
locals.add(le);
lastEntryForReg[reg] = le;
@@ -290,21 +308,7 @@
int typeIdx = readStringIndex(bs);
int sigIdx = readStringIndex(bs);
LocalEntry le = new LocalEntry(
- address, reg, nameIdx, typeIdx, sigIdx);
-
- // a "start" is implicitly the "end" of whatever was
- // previously defined in the register
- if (lastEntryForReg[reg] != null
- && lastEntryForReg[reg].end == Integer.MAX_VALUE) {
-
- lastEntryForReg[reg].end = address;
-
- // A 0-length entry. Almost certainly a "this"
- // with a signature.
- if (lastEntryForReg[reg].start == address) {
- locals.remove(lastEntryForReg[reg]);
- }
- }
+ address, true, reg, nameIdx, typeIdx, sigIdx);
locals.add(le);
lastEntryForReg[reg] = le;
@@ -319,16 +323,17 @@
try {
prevle = lastEntryForReg[reg];
- if (lastEntryForReg[reg].end == Integer.MAX_VALUE) {
- throw new RuntimeException ("nonsensical "
- + "RESTART_LOCAL on live register v"+reg);
+ if (prevle.isStart) {
+ throw new RuntimeException("nonsensical "
+ + "RESTART_LOCAL on live register v"
+ + reg);
}
- le = new LocalEntry(address, reg,
- prevle.nameIndex, prevle.typeIndex, 0);
+ le = new LocalEntry(address, true, reg,
+ prevle.nameIndex, prevle.typeIndex, 0);
} catch (NullPointerException ex) {
- throw new RuntimeException
- ("Encountered RESTART_LOCAL on new v" +reg);
+ throw new RuntimeException(
+ "Encountered RESTART_LOCAL on new v" + reg);
}
locals.add(le);
@@ -338,20 +343,27 @@
case DBG_END_LOCAL: {
int reg = readUnsignedLeb128(bs);
- boolean found = false;
- for (int i = locals.size() - 1; i >= 0; i--) {
- if (locals.get(i).reg == reg) {
- locals.get(i).end = address;
- found = true;
- break;
+ LocalEntry prevle;
+ LocalEntry le;
+
+ try {
+ prevle = lastEntryForReg[reg];
+
+ if (!prevle.isStart) {
+ throw new RuntimeException("nonsensical "
+ + "END_LOCAL on dead register v" + reg);
}
+
+ le = new LocalEntry(address, false, reg,
+ prevle.nameIndex, prevle.typeIndex,
+ prevle.signatureIndex);
+ } catch (NullPointerException ex) {
+ throw new RuntimeException(
+ "Encountered END_LOCAL on new v" + reg);
}
- if (!found) {
- throw new RuntimeException(
- "Encountered LOCAL_END without local start: v"
- + reg);
- }
+ locals.add(le);
+ lastEntryForReg[reg] = le;
}
break;
@@ -403,40 +415,48 @@
* throwing an exception if they do not match. Used to validate the
* encoder.
*
- * @param linecodes encoded debug info
- * @param codeSize size of insn block in code units
- * @param countRegisters size of used register block in register units
- * @param pl position list to verify against
- * @param ll locals list to verify against.
+ * @param info encoded debug info
+ * @param file non-null; file to refer to during decoding
+ * @param ref non-null; method whose info is being decoded
+ * @param code non-null; original code object that was encoded
+ * @param isStatic whether the method is static
*/
- public static void validateEncode(byte[] linecodes, int codeSize,
- int countRegisters, PositionList pl, LocalList ll,
- boolean isStatic, CstMethodRef ref, DexFile file) {
-
+ public static void validateEncode(byte[] info, DexFile file,
+ CstMethodRef ref, DalvCode code, boolean isStatic) {
+ PositionList pl = code.getPositions();
+ LocalList ll = code.getLocals();
+ DalvInsnList insns = code.getInsns();
+ int codeSize = insns.codeSize();
+ int countRegisters = insns.getRegistersSize();
+
try {
- validateEncode0(linecodes, codeSize, countRegisters,
+ validateEncode0(info, codeSize, countRegisters,
isStatic, ref, file, pl, ll);
} catch (RuntimeException ex) {
-// System.err.println(ex.toString()
-// + " while processing " + ref.toHuman());
+ System.err.println("instructions:");
+ insns.debugPrint(System.err, " ", true);
+ System.err.println("local list:");
+ ll.debugPrint(System.err, " ");
throw ExceptionWithContext.withContext(ex,
"while processing " + ref.toHuman());
}
}
-
- private static void validateEncode0(byte[] linecodes, int codeSize,
+ private static void validateEncode0(byte[] info, int codeSize,
int countRegisters, boolean isStatic, CstMethodRef ref,
DexFile file, PositionList pl, LocalList ll) {
DebugInfoDecoder decoder
- = new DebugInfoDecoder(linecodes, codeSize, countRegisters,
+ = new DebugInfoDecoder(info, codeSize, countRegisters,
isStatic, ref, file);
decoder.decode();
- List<PositionEntry> decodedEntries;
+ /*
+ * Go through the decoded position entries, matching up
+ * with original entries.
+ */
- decodedEntries = decoder.getPositionList();
+ List<PositionEntry> decodedEntries = decoder.getPositionList();
if (decodedEntries.size() != pl.size()) {
throw new RuntimeException(
@@ -444,7 +464,7 @@
+ decodedEntries.size() + " expected " + pl.size());
}
- for (PositionEntry entry: decodedEntries) {
+ for (PositionEntry entry : decodedEntries) {
boolean found = false;
for (int i = pl.size() - 1; i >= 0; i--) {
PositionList.Entry ple = pl.get(i);
@@ -462,41 +482,111 @@
}
}
- List<LocalEntry> decodedLocals;
+ /*
+ * Go through the original local list, in order, matching up
+ * with decoded entries.
+ */
- decodedLocals = decoder.getLocals();
-
+ List<LocalEntry> decodedLocals = decoder.getLocals();
+ int thisStringIdx = decoder.thisStringIdx;
+ int decodedSz = decodedLocals.size();
int paramBase = decoder.getParamBase();
- int matchedLocalsEntries = 0;
+ /*
+ * Preflight to fill in any parameters that were skipped in
+ * the prologue (including an implied "this") but then
+ * identified by full signature.
+ */
+ for (int i = 0; i < decodedSz; i++) {
+ LocalEntry entry = decodedLocals.get(i);
+ int idx = entry.nameIndex;
- for (LocalEntry entry: decodedLocals) {
- boolean found = false;
- for (int i = ll.size() - 1; i >= 0; i--) {
- LocalList.Entry le = ll.get(i);
-
- /*
- * If an entry is a method parameter, then the original
- * entry may not be marked as starting at 0. However, the
- * end address shuld still match.
- */
- if ((entry.start == le.getStart()
- || (entry.start == 0 && entry.reg >= paramBase))
- && entry.end == le.getEnd()
- && entry.reg == le.getRegister()) {
- found = true;
- matchedLocalsEntries++;
- break;
+ if ((idx < 0) || (idx == thisStringIdx)) {
+ for (int j = i + 1; j < decodedSz; j++) {
+ LocalEntry e2 = decodedLocals.get(j);
+ if (e2.address != 0) {
+ break;
+ }
+ if ((entry.reg == e2.reg) && e2.isStart) {
+ decodedLocals.set(i, e2);
+ decodedLocals.remove(j);
+ decodedSz--;
+ break;
+ }
}
}
+ }
+
+ int origSz = ll.size();
+ int decodeAt = 0;
+ boolean problem = false;
- if (!found) {
- throw new RuntimeException("Could not match local entry");
+ for (int i = 0; i < origSz; i++) {
+ LocalList.Entry origEntry = ll.get(i);
+
+ if (origEntry.getDisposition()
+ == LocalList.Disposition.END_REPLACED) {
+ /*
+ * The encoded list doesn't represent replacements, so
+ * ignore them for the sake of comparison.
+ */
+ continue;
}
+
+ LocalEntry decodedEntry;
+
+ do {
+ decodedEntry = decodedLocals.get(decodeAt);
+ if (decodedEntry.nameIndex >= 0) {
+ break;
+ }
+ /*
+ * A negative name index means this is an anonymous
+ * parameter, and we shouldn't expect to see it in the
+ * original list. So, skip it.
+ */
+ decodeAt++;
+ } while (decodeAt < decodedSz);
+
+ int decodedAddress = decodedEntry.address;
+
+ if (decodedEntry.reg != origEntry.getRegister()) {
+ System.err.println("local register mismatch at orig " + i +
+ " / decoded " + decodeAt);
+ problem = true;
+ break;
+ }
+
+ if (decodedEntry.isStart != origEntry.isStart()) {
+ System.err.println("local start/end mismatch at orig " + i +
+ " / decoded " + decodeAt);
+ problem = true;
+ break;
+ }
+
+ /*
+ * The secondary check here accounts for the fact that a
+ * parameter might not be marked as starting at 0 in the
+ * original list.
+ */
+ if ((decodedAddress != origEntry.getAddress())
+ && !((decodedAddress == 0)
+ && (decodedEntry.reg >= paramBase))) {
+ System.err.println("local address mismatch at orig " + i +
+ " / decoded " + decodeAt);
+ problem = true;
+ break;
+ }
+
+ decodeAt++;
}
- if (matchedLocalsEntries != ll.size()) {
- throw new RuntimeException("Locals tables did not match");
+ if (problem) {
+ System.err.println("decoded locals:");
+ for (LocalEntry e : decodedLocals) {
+ System.err.println(" " + e);
+ }
+ throw new RuntimeException("local table problem");
}
}
diff --git a/dx/src/com/android/dx/dex/file/DebugInfoEncoder.java b/dx/src/com/android/dx/dex/file/DebugInfoEncoder.java
index cf0fb23..780e18d 100644
--- a/dx/src/com/android/dx/dex/file/DebugInfoEncoder.java
+++ b/dx/src/com/android/dx/dex/file/DebugInfoEncoder.java
@@ -55,8 +55,12 @@
public final class DebugInfoEncoder {
private static final boolean DEBUG = false;
- private final PositionList positionlist;
- private final LocalList locallist;
+ /** null-ok; positions (line numbers) to encode */
+ private final PositionList positions;
+
+ /** null-ok; local variables to encode */
+ private final LocalList locals;
+
private final ByteArrayAnnotatedOutput output;
private final DexFile file;
private final int codeSize;
@@ -92,8 +96,8 @@
/**
* Creates an instance.
*
- * @param pl null-ok
- * @param ll null-ok
+ * @param pl null-ok; positions (line numbers) to encode
+ * @param ll null-ok; local variables to encode
* @param file null-ok; may only be <code>null</code> if simply using
* this class to do a debug print
* @param codeSize
@@ -104,9 +108,8 @@
public DebugInfoEncoder(PositionList pl, LocalList ll,
DexFile file, int codeSize, int regSize,
boolean isStatic, CstMethodRef ref) {
-
- this.positionlist = pl;
- this.locallist = ll;
+ this.positions = pl;
+ this.locals = ll;
this.file = file;
output = new ByteArrayAnnotatedOutput();
this.desc = ref.getPrototype();
@@ -190,18 +193,11 @@
private byte[] convert0() throws IOException {
ArrayList<PositionList.Entry> sortedPositions = buildSortedPositions();
- ArrayList<LocalList.Entry> sortedLocalsStart = buildLocalsStart();
-
- // Parameter locals are removed from sortedLocalsStart here.
- ArrayList<LocalList.Entry> methodArgs
- = extractMethodArguments(sortedLocalsStart);
-
- ArrayList<LocalList.Entry> sortedLocalsEnd
- = buildLocalsEnd(sortedLocalsStart);
+ ArrayList<LocalList.Entry> methodArgs = extractMethodArguments();
emitHeader(sortedPositions, methodArgs);
- // TODO: Make this mark the actual prologue end.
+ // TODO: Make this mark be the actual prologue end.
output.writeByte(DBG_SET_PROLOGUE_END);
if (annotateTo != null || debugPrint != null) {
@@ -209,56 +205,37 @@
}
int szp = sortedPositions.size();
- int szl = sortedLocalsStart.size();
+ int szl = locals.size();
// Current index in sortedPositions
int curp = 0;
- // Current index in sortedLocalsStart
- int curls = 0;
- // Current index in sortedLocalsEnd
- int curle = 0;
+ // Current index in locals
+ int curl = 0;
for (;;) {
/*
* Emit any information for the current address.
*/
- curle = emitLocalEndsAtAddress(curle, sortedLocalsEnd, curls,
- sortedLocalsStart);
-
- /*
- * Our locals-sorted-by-range-end has reached the end
- * of the code block. Ignore everything else.
- */
- if (address == codeSize) {
- curle = szl;
- }
-
- curls = emitLocalStartsAtAddress(curls, sortedLocalsStart);
-
+ curl = emitLocalsAtAddress(curl);
curp = emitPositionsAtAddress(curp, sortedPositions);
/*
* Figure out what the next important address is.
*/
- int nextAddrLS = Integer.MAX_VALUE;
- int nextAddrLE = Integer.MAX_VALUE;
- int nextAddrP = Integer.MAX_VALUE;
+ int nextAddrL = Integer.MAX_VALUE; // local variable
+ int nextAddrP = Integer.MAX_VALUE; // position (line number)
- if (curls < szl) {
- nextAddrLS = sortedLocalsStart.get(curls).getStart();
- }
-
- if (curle < szl) {
- nextAddrLE = sortedLocalsEnd.get(curle).getEnd();
+ if (curl < szl) {
+ nextAddrL = locals.get(curl).getAddress();
}
if (curp < szp) {
nextAddrP = sortedPositions.get(curp).getAddress();
}
- int next = Math.min(nextAddrP, Math.min(nextAddrLS, nextAddrLE));
+ int next = Math.min(nextAddrP, nextAddrL);
// No next important address == done.
if (next == Integer.MAX_VALUE) {
@@ -270,7 +247,7 @@
* block, stop here. Those are implied anyway.
*/
if (next == codeSize
- && nextAddrLS == Integer.MAX_VALUE
+ && nextAddrL == Integer.MAX_VALUE
&& nextAddrP == Integer.MAX_VALUE) {
break;
}
@@ -285,99 +262,30 @@
emitEndSequence();
- byte[] result = output.toByteArray();
-
- if (DEBUG) {
- int origSize = 0;
- int newSize = result.length;
-
- if (positionlist != null) {
- origSize += (positionlist.size() * 6);
- }
-
- if (locallist != null) {
- origSize += (4 * 5 * locallist.size());
- }
-
- System.err.printf(
- "Lines+Locals table was %d bytes is now %d bytes\n",
- origSize, newSize);
- }
-
- return result;
+ return output.toByteArray();
}
/**
- * Emits all local ends that occur at the current <code>address</code>
+ * Emits all local variable activity that occurs at the current
+ * {@link #address} starting at the given index into {@code
+ * locals} and including all subsequent activity at the same
+ * address.
*
- * @param curle Current index in sortedLocalsEnd
- * @param sortedLocalsEnd Locals, sorted by ascending end address
- * @param curls Current index in sortedLocalsStart
- * @param sortedLocalsStart Locals, sorted by ascending start address
- * @return new value for <code>curle</code>
+ * @param curl Current index in locals
+ * @return new value for <code>curl</code>
* @throws IOException
*/
- private int emitLocalEndsAtAddress(int curle,
- ArrayList<LocalList.Entry> sortedLocalsEnd, int curls,
- ArrayList<LocalList.Entry> sortedLocalsStart)
+ private int emitLocalsAtAddress(int curl)
throws IOException {
+ int sz = locals.size();
- int szl = sortedLocalsEnd.size();
+ // TODO: Don't emit ends implied by starts.
- // Ignore "local ends" at end of code.
- while (curle < szl
- && sortedLocalsEnd.get(curle).getEnd() == address
- && address != codeSize) {
-
- boolean skipLocalEnd = false;
-
- /*
- * Check to see if there's a range-start that appears at
- * the same address for the same register. If so, the
- * end-range is implicit so skip it.
- */
- for (int j = curls; j < szl
- && sortedLocalsStart.get(j).getStart() == address
- ; j++) {
-
- if (sortedLocalsStart.get(j).getRegister()
- == sortedLocalsEnd.get(curle).getRegister()) {
- skipLocalEnd = true;
-
- if (DEBUG) {
- System.err.printf("skip local end v%d\n",
- sortedLocalsEnd.get(curle).getRegister());
- }
- curle++;
- break;
- }
- }
-
- if (!skipLocalEnd) {
- emitLocalEnd(sortedLocalsEnd.get(curle++));
- }
- }
- return curle;
- }
-
- /**
- * Emits all local starts that occur at the current <code>address</code>
- *
- * @param curls Current index in sortedLocalsStart
- * @param sortedLocalsStart Locals, sorted by ascending start address
- * @return new value for <code>curls</code>
- * @throws IOException
- */
- private int emitLocalStartsAtAddress(int curls,
- ArrayList<LocalList.Entry> sortedLocalsStart)
- throws IOException {
-
- int szl = sortedLocalsStart.size();
-
- while (curls < szl
- && sortedLocalsStart.get(curls).getStart() == address) {
- LocalList.Entry lle = sortedLocalsStart.get(curls++);
- LocalList.Entry prevlle = lastEntryForReg[lle.getRegister()];
+ while ((curl < sz)
+ && (locals.get(curl).getAddress() == address)) {
+ LocalList.Entry lle = locals.get(curl++);
+ int reg = lle.getRegister();
+ LocalList.Entry prevlle = lastEntryForReg[reg];
if (lle == prevlle) {
/*
@@ -386,23 +294,47 @@
* lastEntryForReg array.
*/
continue;
- } else if (prevlle != null && lle.matches(prevlle)) {
- if (prevlle.getEnd() == lle.getStart()) {
+ }
+
+ // At this point we have a new entry one way or another.
+ lastEntryForReg[reg] = lle;
+
+ if (lle.isStart()) {
+ if ((prevlle != null) && lle.matches(prevlle)) {
/*
- * An adjacent range with the same register.
- * The previous emitLocalEndsAtAddress() call skipped
- * this local end, so we'll skip this local start as well.
+ * The previous local in this register has the same
+ * name and type as the one being introduced now, so
+ * use the more efficient "restart" form.
*/
- continue;
- } else {
+ if (prevlle.isStart()) {
+ /*
+ * We should never be handed a start when a
+ * a matching local is already active.
+ */
+ throw new RuntimeException("shouldn't happen");
+ }
emitLocalRestart(lle);
+ } else {
+ emitLocalStart(lle);
}
} else {
- lastEntryForReg[lle.getRegister()] = lle;
- emitLocalStart(lle);
+ /*
+ * Only emit a local end if it is *not* due to a direct
+ * replacement. Direct replacements imply an end of the
+ * previous local in the same register.
+ *
+ * TODO: Make sure the runtime can deal with implied
+ * local ends from category-2 interactions, and when so,
+ * also stop emitting local ends for those cases.
+ */
+ if (lle.getDisposition()
+ != LocalList.Disposition.END_REPLACED) {
+ emitLocalEnd(lle);
+ }
}
}
- return curls;
+
+ return curl;
}
/**
@@ -533,7 +465,7 @@
* a LOCAL_RESTART_EXTENDED
*/
- for (LocalList.Entry arg: lastEntryForReg) {
+ for (LocalList.Entry arg : lastEntryForReg) {
if (arg == null) {
continue;
}
@@ -552,11 +484,11 @@
* @return A sorted positions list
*/
private ArrayList<PositionList.Entry> buildSortedPositions() {
- int sz = (positionlist == null) ? 0 : positionlist.size();
+ int sz = (positions == null) ? 0 : positions.size();
ArrayList<PositionList.Entry> result = new ArrayList(sz);
for (int i = 0; i < sz; i++) {
- result.add(positionlist.get(i));
+ result.add(positions.get(i));
}
// Sort ascending by address.
@@ -573,58 +505,6 @@
}
/**
- * Builds a list of locals entries sorted by ascending start address.
- *
- * @return A sorted locals list list
- */
- private ArrayList<LocalList.Entry> buildLocalsStart() {
- int sz = (locallist == null) ? 0 : locallist.size();
- ArrayList<LocalList.Entry> result = new ArrayList(sz);
-
- // Add all the entries
- for (int i = 0; i < sz; i++) {
- LocalList.Entry e = locallist.get(i);
- result.add(locallist.get(i));
- }
-
- // Sort ascending by start address.
- Collections.sort (result, new Comparator<LocalList.Entry>() {
- public int compare (LocalList.Entry a, LocalList.Entry b) {
- return a.getStart() - b.getStart();
- }
-
- public boolean equals (Object obj) {
- return obj == this;
- }
- });
- return result;
- }
-
- /**
- * Builds a list of locals entries sorted by ascending end address.
- *
- * @param list locals list in any order
- * @return a sorted locals list
- */
- private ArrayList<LocalList.Entry> buildLocalsEnd(
- ArrayList<LocalList.Entry> list) {
-
- ArrayList<LocalList.Entry> sortedLocalsEnd = new ArrayList(list);
-
- // Sort ascending by end address.
- Collections.sort (sortedLocalsEnd, new Comparator<LocalList.Entry>() {
- public int compare (LocalList.Entry a, LocalList.Entry b) {
- return a.getEnd() - b.getEnd();
- }
-
- public boolean equals (Object obj) {
- return obj == this;
- }
- });
- return sortedLocalsEnd;
- }
-
- /**
* Gets the register that begins the method's parameter range (including
* the 'this' parameter for non-static methods). The range continues until
* <code>regSize</code>
@@ -641,24 +521,18 @@
* from the input list and sorted by ascending register in the
* returned list.
*
- * @param sortedLocals locals list, sorted by ascending start address,
- * to process; left unmodified
* @return list of non-<code>this</code> method argument locals,
* sorted by ascending register
*/
- private ArrayList<LocalList.Entry> extractMethodArguments (
- ArrayList<LocalList.Entry> sortedLocals) {
-
+ private ArrayList<LocalList.Entry> extractMethodArguments() {
ArrayList<LocalList.Entry> result
= new ArrayList(desc.getParameterTypes().size());
-
int argBase = getParamBase();
-
BitSet seen = new BitSet(regSize - argBase);
+ int sz = locals.size();
- int sz = sortedLocals.size();
for (int i = 0; i < sz; i++) {
- LocalList.Entry e = sortedLocals.get(i);
+ LocalList.Entry e = locals.get(i);
int reg = e.getRegister();
if (reg < argBase) {
@@ -675,12 +549,12 @@
}
// Sort by ascending register.
- Collections.sort (result, new Comparator<LocalList.Entry>() {
- public int compare (LocalList.Entry a, LocalList.Entry b) {
+ Collections.sort(result, new Comparator<LocalList.Entry>() {
+ public int compare(LocalList.Entry a, LocalList.Entry b) {
return a.getRegister() - b.getRegister();
}
- public boolean equals (Object obj) {
+ public boolean equals(Object obj) {
return obj == this;
}
});
@@ -817,7 +691,7 @@
output.writeByte(DBG_START_LOCAL);
- emitUnsignedLeb128 (entry.getRegister());
+ emitUnsignedLeb128(entry.getRegister());
emitStringIndex(entry.getName());
emitTypeIndex(entry.getType());
@@ -846,7 +720,7 @@
output.writeByte(DBG_START_LOCAL_EXTENDED);
- emitUnsignedLeb128 (entry.getRegister());
+ emitUnsignedLeb128(entry.getRegister());
emitStringIndex(entry.getName());
emitTypeIndex(entry.getType());
emitStringIndex(entry.getSignature());
@@ -939,7 +813,7 @@
if (annotateTo != null || debugPrint != null) {
annotate(1,
- String.format ("%04x: line %d", address, line));
+ String.format("%04x: line %d", address, line));
}
}
@@ -958,10 +832,10 @@
if (deltaLines < DBG_LINE_BASE
|| deltaLines > (DBG_LINE_BASE + DBG_LINE_RANGE -1)) {
- throw new RuntimeException ("Parameter out of range");
+ throw new RuntimeException("Parameter out of range");
}
- return (deltaLines - DBG_LINE_BASE)
+ return (deltaLines - DBG_LINE_BASE)
+ (DBG_LINE_RANGE * deltaAddress) + DBG_FIRST_SPECIAL;
}
diff --git a/dx/src/com/android/dx/dex/file/DebugInfoItem.java b/dx/src/com/android/dx/dex/file/DebugInfoItem.java
index b074593..0e4329b 100644
--- a/dx/src/com/android/dx/dex/file/DebugInfoItem.java
+++ b/dx/src/com/android/dx/dex/file/DebugInfoItem.java
@@ -141,6 +141,37 @@
*/
private byte[] encode(DexFile file, String prefix, PrintWriter debugPrint,
AnnotatedOutput out, boolean consume) {
+ byte[] result = encode0(file, prefix, debugPrint, out, consume);
+
+ if (ENABLE_ENCODER_SELF_CHECK && (file != null)) {
+ try {
+ DebugInfoDecoder.validateEncode(result, file, ref, code,
+ isStatic);
+ } catch (RuntimeException ex) {
+ // Reconvert, annotating to System.err.
+ encode0(file, "", new PrintWriter(System.err, true), null,
+ false);
+ throw ex;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Helper for {@link #encode} to do most of the work.
+ *
+ * @param file null-ok; file to refer to during encoding
+ * @param prefix null-ok; prefix to attach to each line of output
+ * @param debugPrint null-ok; if specified, an alternate output for
+ * annotations
+ * @param out null-ok; if specified, where annotations should go
+ * @param consume whether to claim to have consumed output for
+ * <code>out</code>
+ * @return non-null; the encoded array
+ */
+ private byte[] encode0(DexFile file, String prefix, PrintWriter debugPrint,
+ AnnotatedOutput out, boolean consume) {
PositionList positions = code.getPositions();
LocalList locals = code.getLocals();
DalvInsnList insns = code.getInsns();
@@ -156,13 +187,8 @@
if ((debugPrint == null) && (out == null)) {
result = encoder.convert();
} else {
- result = encoder.convertAndAnnotate(
- prefix, debugPrint, out, consume);
- }
-
- if (ENABLE_ENCODER_SELF_CHECK && (file != null)) {
- DebugInfoDecoder.validateEncode(encoded, codeSize,
- regSize, positions, locals, isStatic, ref, file);
+ result = encoder.convertAndAnnotate(prefix, debugPrint, out,
+ consume);
}
return result;
diff --git a/dx/src/com/android/dx/rop/code/LocalItem.java b/dx/src/com/android/dx/rop/code/LocalItem.java
index b1e1a4b..bac6ce2 100644
--- a/dx/src/com/android/dx/rop/code/LocalItem.java
+++ b/dx/src/com/android/dx/rop/code/LocalItem.java
@@ -22,7 +22,6 @@
* A local variable item: either a name or a signature or both.
*/
public class LocalItem implements Comparable<LocalItem> {
-
/** null-ok; local variable name */
private final CstUtf8 name;
@@ -38,7 +37,7 @@
* @param signature null-ok; local variable signature
* @return non-null; appropriate instance.
*/
- public static LocalItem make (CstUtf8 name, CstUtf8 signature) {
+ public static LocalItem make(CstUtf8 name, CstUtf8 signature) {
if (name == null && signature == null) {
return null;
}
@@ -52,14 +51,14 @@
* @param name null-ok; local variable name
* @param signature null-ok; local variable signature
*/
- private LocalItem (CstUtf8 name, CstUtf8 signature) {
+ private LocalItem(CstUtf8 name, CstUtf8 signature) {
this.name = name;
this.signature = signature;
}
/** {@inheritDoc} */
@Override
- public boolean equals (Object other) {
+ public boolean equals(Object other) {
if (!(other instanceof LocalItem)) {
return false;
}
@@ -89,7 +88,7 @@
}
/** {@inheritDoc} */
- public int compareTo (LocalItem local) {
+ public int compareTo(LocalItem local) {
int ret;
ret = compareHandlesNulls(name, local.name);
@@ -106,7 +105,7 @@
/** {@inheritDoc} */
@Override
- public int hashCode () {
+ public int hashCode() {
return (name == null ? 0 : name.hashCode()) * 31
+ (signature == null ? 0 : signature.hashCode());
}
@@ -121,7 +120,7 @@
}
return "[" + (name == null ? "" : name.toQuoted())
- + "|" + (signature == null ? "" : signature.toQuoted());
+ + "|" + (signature == null ? "" : signature.toQuoted());
}
/**
diff --git a/dx/src/com/android/dx/rop/code/RegisterSpec.java b/dx/src/com/android/dx/rop/code/RegisterSpec.java
index 09f7f18..73af91f 100644
--- a/dx/src/com/android/dx/rop/code/RegisterSpec.java
+++ b/dx/src/com/android/dx/rop/code/RegisterSpec.java
@@ -29,7 +29,7 @@
* destinations of register-based operations.
*/
public final class RegisterSpec
- implements TypeBearer, ToHuman {
+ implements TypeBearer, ToHuman, Comparable<RegisterSpec> {
/** non-null; string to prefix register numbers with */
public static final String PREFIX = "v";
@@ -97,7 +97,8 @@
* @param local non-null; the associated local variable
* @return non-null; an appropriately-constructed instance
*/
- public static RegisterSpec make(int reg, TypeBearer type, LocalItem local) {
+ public static RegisterSpec make(int reg, TypeBearer type,
+ LocalItem local) {
if (local == null) {
throw new NullPointerException("local == null");
}
@@ -172,6 +173,43 @@
}
/**
+ * Like {@code equals}, but only consider the simple types of the
+ * registers. That is, this compares {@code getType()} on the types
+ * to ignore whatever arbitrary extra stuff might be carried around
+ * by an outer {@link TypeBearer}.
+ *
+ * @param other null-ok; spec to compare to
+ * @return {@code true} iff {@code this} and {@code other} are equal
+ * in the stated way
+ */
+ public boolean equalsUsingSimpleType(RegisterSpec other) {
+ if (!matchesVariable(other)) {
+ return false;
+ }
+
+ return (reg == other.reg);
+ }
+
+ /**
+ * Like {@link #equalsUsingSimpleType} but ignoring the register number.
+ * This is useful to determine if two instances refer to the "same"
+ * local variable.
+ *
+ * @param other null-ok; spec to compare to
+ * @return {@code true} iff {@code this} and {@code other} are equal
+ * in the stated way
+ */
+ public boolean matchesVariable(RegisterSpec other) {
+ if (other == null) {
+ return false;
+ }
+
+ return type.getType().equals(other.type.getType())
+ && ((local == other.local)
+ || ((local != null) && local.equals(other.local)));
+ }
+
+ /**
* Helper for {@link #equals} and {@link #ForComparison.equals},
* which actually does the test.
*
@@ -188,6 +226,35 @@
|| ((this.local != null) && this.local.equals(local)));
}
+ /**
+ * Compares by (in priority order) register number, unwrapped type
+ * (that is types not {@link TypeBearer}s, and local info.
+ *
+ * @param other non-null; spec to compare to
+ * @return {@code -1..1}; standard result of comparison
+ */
+ public int compareTo(RegisterSpec other) {
+ if (this.reg < other.reg) {
+ return -1;
+ } else if (this.reg > other.reg) {
+ return 1;
+ }
+
+ int compare = type.getType().compareTo(other.type.getType());
+
+ if (compare != 0) {
+ return compare;
+ }
+
+ if (this.local == null) {
+ return (other.local == null) ? 0 : -1;
+ } else if (other.local == null) {
+ return 1;
+ }
+
+ return this.local.compareTo(other.local);
+ }
+
/** {@inheritDoc} */
@Override
public int hashCode() {
@@ -292,6 +359,8 @@
* Gets the category of this instance's type. This is just a convenient
* shorthand for <code>getType().getCategory()</code>.
*
+ * @see #isCategory1
+ * @see #isCategory2
* @return 1..2; the category of this instance's type
*/
public int getCategory() {
@@ -299,6 +368,30 @@
}
/**
+ * Gets whether this instance's type is category 1. This is just a
+ * convenient shorthand for <code>getType().isCategory1()</code>.
+ *
+ * @see #getCategory
+ * @see #isCategory2
+ * @return whether or not this instance's type is of category 1
+ */
+ public boolean isCategory1() {
+ return type.getType().isCategory1();
+ }
+
+ /**
+ * Gets whether this instance's type is category 2. This is just a
+ * convenient shorthand for <code>getType().isCategory2()</code>.
+ *
+ * @see #getCategory
+ * @see #isCategory1
+ * @return whether or not this instance's type is of category 2
+ */
+ public boolean isCategory2() {
+ return type.getType().isCategory2();
+ }
+
+ /**
* Gets the string form for just the register number of this instance.
*
* @return non-null; the register string form
@@ -323,16 +416,16 @@
* are <code>equals()</code>, then the intersection's type bearer
* is the one from this instance. Otherwise, the intersection's
* type bearer is the <code>getType()</code> of this instance.</li>
- * <li>If the locals are <code>equals()</code>, then the local info of the
- * intersection is the local info of this instance. Otherwise, the local info
- * of the intersection is <code>null</code>.</li>
+ * <li>If the locals are <code>equals()</code>, then the local info
+ * of the intersection is the local info of this instance. Otherwise,
+ * the local info of the intersection is <code>null</code>.</li>
* </ul>
*
* @param other null-ok; instance to intersect with (or <code>null</code>)
- * @param localPrimary whether local variables are primary to
- * the intersection; if <code>true</code>, then the only non-null
- * results occur when registers being intersected have equal local infos (or
- * both have <code>null</code> local infos)
+ * @param localPrimary whether local variables are primary to the
+ * intersection; if <code>true</code>, then the only non-null
+ * results occur when registers being intersected have equal local
+ * infos (or both have <code>null</code> local infos)
* @return null-ok; the intersection
*/
public RegisterSpec intersect(RegisterSpec other, boolean localPrimary) {
@@ -346,7 +439,8 @@
}
LocalItem resultLocal =
- ((local == null) || !local.equals(other.getLocalItem())) ? null : local;
+ ((local == null) || !local.equals(other.getLocalItem()))
+ ? null : local;
boolean sameName = (resultLocal == local);
if (localPrimary && !sameName) {
diff --git a/dx/src/com/android/dx/rop/code/RegisterSpecSet.java b/dx/src/com/android/dx/rop/code/RegisterSpecSet.java
index 4eb2f65..adc77c3 100644
--- a/dx/src/com/android/dx/rop/code/RegisterSpecSet.java
+++ b/dx/src/com/android/dx/rop/code/RegisterSpecSet.java
@@ -187,16 +187,47 @@
}
/**
+ * Returns the spec in this set that's currently associated with a
+ * given local (type, name, and signature), or {@code null} if there is
+ * none. This ignores the register number of the given spec but
+ * matches on everything else.
+ *
+ * @param spec non-null; local to look for
+ * @return null-ok; first register found that matches, if any
+ */
+ public RegisterSpec findMatchingLocal(RegisterSpec spec) {
+ int length = specs.length;
+
+ for (int reg = 0; reg < length; reg++) {
+ RegisterSpec s = specs[reg];
+
+ if (s == null) {
+ continue;
+ }
+
+ if (spec.matchesVariable(s)) {
+ return s;
+ }
+ }
+
+ return null;
+ }
+
+ /**
* Returns the spec in this set that's currently associated with a given
- * name, or null if there is none.
+ * local (name and signature), or {@code null} if there is none.
*
* @param local non-null; local item to search for
- * @return null-ok; first register found with name.
+ * @return null-ok; first register found with matching name and signature
*/
public RegisterSpec localItemToSpec(LocalItem local) {
- for (int reg = 0; reg < specs.length; reg++) {
- if (specs[reg] != null && local.equals(specs[reg].getLocalItem())) {
- return specs[reg];
+ int length = specs.length;
+
+ for (int reg = 0; reg < length; reg++) {
+ RegisterSpec spec = specs[reg];
+
+ if ((spec != null) && local.equals(spec.getLocalItem())) {
+ return spec;
}
}
@@ -260,6 +291,22 @@
}
/**
+ * Put the entire contents of the given set into this one.
+ *
+ * @param set non-null; the set to put into this instance
+ */
+ public void putAll(RegisterSpecSet set) {
+ int max = set.getMaxSize();
+
+ for (int i = 0; i < max; i++) {
+ RegisterSpec spec = set.get(i);
+ if (spec != null) {
+ put(spec);
+ }
+ }
+ }
+
+ /**
* Intersects this instance with the given one, modifying this
* instance. The intersection consists of the pairwise
* {@link RegisterSpec#intersect} of corresponding elements from
diff --git a/libcore/archive/src/main/java/java/util/zip/ZipInputStream.java b/libcore/archive/src/main/java/java/util/zip/ZipInputStream.java
index 8c6a4c5..262fa3f 100644
--- a/libcore/archive/src/main/java/java/util/zip/ZipInputStream.java
+++ b/libcore/archive/src/main/java/java/util/zip/ZipInputStream.java
@@ -58,7 +58,9 @@
static final int ZIPLocalHeaderVersionNeeded = 20;
- private boolean zipClosed = false;
+ // BEGI android-removed
+ // private boolean zipClosed = false;
+ // END android-removed
private boolean entriesEnd = false;
@@ -101,11 +103,12 @@
*/
@Override
public void close() throws IOException {
- if (zipClosed != true) {
+ // BEGIN android-changed
+ if (closed != true) {
closeEntry(); // Close the current entry
- zipClosed = true;
super.close();
}
+ // END android-changed
}
/**
@@ -116,9 +119,11 @@
* @since Android 1.0
*/
public void closeEntry() throws IOException {
- if (zipClosed) {
+ // BEGIN android-changed
+ if (closed) {
throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
}
+ // END android-changed
if (currentEntry == null) {
return;
}
@@ -261,6 +266,9 @@
}
currentEntry.setExtra(e);
}
+ // BEGIN android-added
+ eof = false;
+ // END android-added
return currentEntry;
}
@@ -268,9 +276,11 @@
@Override
public int read(byte[] buffer, int start, int length) throws IOException {
- if (zipClosed) {
+ // BEGIN android-changed
+ if (closed) {
throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
}
+ // END android-changed
if (inf.finished() || currentEntry == null) {
return -1;
}
@@ -280,11 +290,17 @@
if (currentEntry.compressionMethod == STORED) {
int csize = (int) currentEntry.size;
if (inRead >= csize) {
+ // BEGIN android-added
+ eof = true;
+ // END android-added
return -1;
}
if (lastRead >= len) {
lastRead = 0;
if ((len = in.read(buf)) == -1) {
+ // BEGIN android-added
+ eof = true;
+ // END android-added
return -1;
}
entryIn += len;
@@ -360,22 +376,15 @@
*/
@Override
public int available() throws IOException {
- if (zipClosed) {
+ // BEGIN android-changed
+ if (closed) {
throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
}
if (currentEntry == null) {
return 1;
}
- if (currentEntry.compressionMethod == STORED) {
- if (inRead >= currentEntry.size) {
- return 0;
- }
- } else {
- if (inf.finished()) {
- return 0;
- }
- }
- return 1;
+ return super.available();
+ // END android-changed
}
/**
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java
new file mode 100644
index 0000000..77fbb15
--- /dev/null
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.archive.tests.java.util.jar;
+
+import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import junit.framework.TestCase;
+
+import tests.support.Support_Exec;
+import tests.support.resource.Support_Resources;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.jar.JarFile;
+
+
+@TestTargetClass(JarOutputStream.class)
+@AndroidOnly("dalvik vm specific")
+public class DalvikExecTest extends TestCase {
+
+ String execDalvik1 (String classpath, String mainClass, String arg1)
+ throws IOException, InterruptedException {
+
+ ArrayList<String> cmdLine = new ArrayList<String>(10);
+
+ String base = System.getenv("OUT");
+ cmdLine.add(base + "/system/bin/dalvikvm");
+
+ cmdLine.add("-Djava.io.tmpdir=/tmp/mc");
+ cmdLine.add("-Duser.language=en");
+ cmdLine.add("-Duser.region=US");
+
+ if ("true".equals(System.getenv("TARGET_SIMULATOR"))) {
+ // Test against SIMULATOR:
+// cmdLine.add("-Xmx512M");
+// cmdLine.add("-Xcheck:jni");
+ cmdLine.add("-Xbootclasspath:" + System.getProperty("java.boot.class.path"));
+ } else {
+ // Test against EMULATOR:
+ }
+
+ cmdLine.add("-classpath");
+ cmdLine.add(classpath);
+ cmdLine.add(mainClass);
+
+ if (arg1 != null) cmdLine.add(arg1);
+
+ Object[] res = Support_Exec.execAndDigestOutput(
+ cmdLine.toArray(new String[cmdLine.size()]),
+ null );
+ return Support_Exec.getProcessOutput(res, true);
+ }
+
+ String execDalvik (String classpath, String mainClass)
+ throws IOException, InterruptedException {
+ return execDalvik1(classpath, mainClass, null);
+ }
+
+ @TestTargets ({
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ notes = "Execute an existing JAR on dalvikvm using -classpath option.",
+ clazz = Runtime.class,
+ method = "exec",
+ args = {java.lang.String[].class}
+ )
+ })
+ public void test_execExistingJar () throws IOException, InterruptedException {
+ String res;
+ File jarFile;
+ if (System.getProperty("java.vendor").contains("Android")) {
+ //
+ // Test against Android:
+ //
+ File tempDir = Support_Resources.createTempFolder();
+ jarFile = Support_Resources.copyFile(
+ tempDir, null, "cts_dalvikExecTest.jar" );
+ res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.HelloWorld");
+ assertEquals("Hello Android World!", "Hello Android World!\n", res);
+
+ res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.ResourceDumper");
+ assertTrue("Android Resource Dumper started",
+ res.contains("Android Resource Dumper started"));
+ assertTrue("This Resource contains some text.",
+ res.contains("This Resource contains some text."));
+ } else {
+ //
+ // Test against RI:
+ //
+ // Do nothing!
+ }
+ }
+
+
+ @TestTargets ({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "putNextEntry",
+ args = {java.util.zip.ZipEntry.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "JarOutputStream",
+ args = {java.io.OutputStream.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ notes = "Create a temp file, fill it with contents according to Dalvik JAR format, and execute it on dalvikvm using -classpath option.",
+ clazz = Runtime.class,
+ method = "exec",
+ args = {java.lang.String[].class}
+ )
+ })
+ public void test_execCreatedJar () throws IOException, InterruptedException {
+ File jarFile = File.createTempFile("cts_dalvikExecTest_", ".jar");
+ jarFile.deleteOnExit();
+
+ // Create a JAR output stream on the temp file:
+ JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(jarFile));
+
+ // Define the entry for the classes.dex:
+ jarOut.putNextEntry(new JarEntry("classes.dex"));
+
+ // Fill in the classes.dex contents, i.e. the Dalvik executable code:
+ // (See below for the detailed source code contents.)
+ Support_Resources.writeResourceToStream("cts_dalvikExecTest_classes.dex", jarOut);
+
+ // Now add a resource file:
+ //
+ jarOut.putNextEntry(new JarEntry("dalvikExecTest/myResource"));
+ jarOut.write("This Resource contains some text.".getBytes());
+
+ // Close the stream to the completed JAR file.
+ jarOut.close();
+
+ // The resulting JAR file contains the classes listed at the end of this text,
+ // like the 'cts_dalvikExecTest.jar' as part of the resources, too.
+
+ String res;
+
+ res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.HelloWorld");
+ assertEquals("Hello Android World!", "Hello Android World!\n", res);
+
+ res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.ResourceDumper");
+ assertTrue("Android Resource Dumper started",
+ res.contains("Android Resource Dumper started"));
+ assertTrue("This Resource contains some text.",
+ res.contains("This Resource contains some text."));
+ }
+
+
+ @TestTargets ({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "putNextEntry",
+ args = {java.util.zip.ZipEntry.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "JarOutputStream",
+ args = {java.io.OutputStream.class, java.util.jar.Manifest.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ clazz = Runtime.class,
+ method = "exec",
+ args = {java.lang.String[].class}
+ )
+ })
+ /**
+ * This test does quite the same as test_execCreatedJar, but includes a manifest.
+ * Note however that the Dalvik JAR format does not require this manifest.
+ * We just test whether the manifest is placed correctly within the JAR by
+ * dumping its contents read as a simple text resource.
+ * No! We can't do that so easily either, as there are other (parent) JARs
+ * with a manifest inside, taken with precedence.
+ * So we will reopen the JAR as a JarFile and check the manifest
+ * with a top level end-to-end approach.
+ */
+ public void test_execCreatedJarWithManifest () throws IOException, InterruptedException {
+ File jarFile = File.createTempFile("cts_dalvikExecTest_", ".jar");
+ jarFile.deleteOnExit();
+
+ // Create the manifest:
+ Manifest manifest = new Manifest();
+ Attributes attrs = manifest.getMainAttributes();
+ attrs.put(Attributes.Name.MANIFEST_VERSION, "3.1415962");
+ attrs.put(Attributes.Name.MAIN_CLASS, "dalvikExecTest.HelloWorld");
+ attrs.put(Attributes.Name.CLASS_PATH, jarFile.getName());
+
+ // Create a JAR output stream on the temp file using the manifest:
+ JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(jarFile), manifest);
+
+ // Define the entry for the classes.dex:
+ jarOut.putNextEntry(new JarEntry("classes.dex"));
+
+ // Fill in the classes.dex contents, i.e. the Dalvik executable code:
+ // (See below for the detailed source code contents.)
+ Support_Resources.writeResourceToStream("cts_dalvikExecTest_classes.dex", jarOut);
+
+ // Now add a resource file:
+ //
+ jarOut.putNextEntry(new JarEntry("dalvikExecTest/myResource"));
+ jarOut.write("This Resource contains some text.".getBytes());
+
+ // Close the stream to the completed JAR file.
+ jarOut.close();
+
+ // The resulting JAR file contains the classes listed at the end of this text,
+ // like the 'cts_dalvikExecTest.jar' as part of the resources, too.
+
+ String res;
+
+ res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.HelloWorld");
+ assertEquals("Hello Android World!", "Hello Android World!\n", res);
+
+ res = execDalvik(jarFile.getAbsolutePath(), "dalvikExecTest.ResourceDumper");
+ assertTrue("Android Resource Dumper started",
+ res.contains("Android Resource Dumper started"));
+ assertTrue("This Resource contains some text.",
+ res.contains("This Resource contains some text."));
+
+ // And now reread the manifest:
+ //
+ JarFile jarIn = new JarFile(jarFile);
+ manifest = jarIn.getManifest();
+ attrs = manifest.getMainAttributes();
+ assertEquals("MANIFEST_VERSION must match!", "3.1415962",
+ attrs.get(Attributes.Name.MANIFEST_VERSION));
+ assertEquals("MAIN_CLASS must match!", "dalvikExecTest.HelloWorld",
+ attrs.get(Attributes.Name.MAIN_CLASS));
+ assertEquals("CLASS_PATH must match!", jarFile.getName(),
+ attrs.get(Attributes.Name.CLASS_PATH));
+ }
+
+
+ /*
+ * The following two classes are added, here, only for completeness.
+ * They form the contents of the dalvikExecTest package contained
+ * in the 'cts_dalvikExecTest_classes.dex' resource file.
+ */
+ /**
+ * @hide
+ */
+ public static class HelloWorld {
+
+ public static void main(String[] args) {
+ System.out.println("Hello Android World!");
+ }
+
+ }
+
+ public static class ResourceDumper {
+
+ static ByteArrayOutputStream outputFrom (InputStream input) throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte[] buffer = new byte[512];
+ int total = 0;
+ int count;
+ count = input.read(buffer);
+ while (count != -1) {
+ out.write(buffer, 0, count);
+ total = total + count;
+ count = input.read(buffer);
+ }
+ return out;
+ }
+
+ public static void main(String[] args) throws IOException {
+ System.out.print("Android Resource Dumper started ");
+ String fileName;
+ if (args.length >= 1) {
+ fileName = args[0];
+ System.out.format("for argument '%s'.\n", fileName);
+ } else {
+ System.out.print("standard ");
+ fileName = "myResource";
+ System.out.println("for standard 'myResource'.");
+ }
+ InputStream is = ResourceDumper.class.getResourceAsStream(fileName);
+ if (is != null) {
+ System.out.println("Resource obtained and being dumped:");
+ System.out.println(outputFrom(is).toString());
+ }
+ }
+
+ }
+
+}
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java
index 4204ed6..4c209d1 100644
--- a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java
@@ -17,8 +17,7 @@
package org.apache.harmony.archive.tests.java.util.jar;
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.BrokenTest;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -47,13 +46,12 @@
*
*/
@TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
+ level = TestLevel.ADDITIONAL,
notes = "Regression functional test. Exception checking missed.",
method = "putNextEntry",
args = {java.util.zip.ZipEntry.class}
)
- @BrokenTest("Support_Exec.execJava is not so simple to use: Harmony Test cannot be easily adapted.")
- @AndroidOnly("dalvik vm specific")
+ @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
public void test_1562() throws Exception {
// create the manifest
Manifest man = new Manifest();
@@ -92,13 +90,12 @@
* @throws Exception in case of troubles
*/
@TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
+ level = TestLevel.ADDITIONAL,
notes = "Functional test.",
method = "JarOutputStream",
args = {java.io.OutputStream.class, java.util.jar.Manifest.class}
)
- @BrokenTest("Support_Exec.execJava is not so simple to use: Harmony Test cannot be easily adapted.")
- @AndroidOnly("dalvik vm specific")
+ @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
public void test_jar_class_path() throws Exception {
File fooJar = File.createTempFile("hyts_", ".jar");
File barJar = File.createTempFile("hyts_", ".jar");
@@ -169,13 +166,12 @@
* @throws Exception in case of troubles
*/
@TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
+ level = TestLevel.ADDITIONAL,
notes = "Functional test.",
method = "JarOutputStream",
args = {java.io.OutputStream.class, java.util.jar.Manifest.class}
)
- @BrokenTest("Support_Exec.execJava is not so simple to use: Harmony Test cannot be easily adapted.")
- @AndroidOnly("dalvik vm specific")
+ @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
public void test_main_class_in_another_jar() throws Exception {
File fooJar = File.createTempFile("hyts_", ".jar");
File barJar = File.createTempFile("hyts_", ".jar");
@@ -213,13 +209,12 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
+ level = TestLevel.ADDITIONAL,
notes = "Functional test.",
method = "JarOutputStream",
args = {java.io.OutputStream.class, java.util.jar.Manifest.class}
)
- @BrokenTest("Support_Exec.execJava is not so simple to use: Harmony Test cannot be easily adapted.")
- @AndroidOnly("dalvik vm specific")
+ @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
public void test_classpath() throws Exception {
File resources = Support_Resources.createTempFolder();
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java
index e5edfe0..497b897 100644
--- a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java
@@ -18,6 +18,7 @@
package org.apache.harmony.archive.tests.java.util.jar;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -72,6 +73,8 @@
private final String jarName3 = "hyts_manifest1.jar";
private final String jarName4 = "hyts_signed.jar";
+
+ private final String jarName5 = "hyts_signed_inc.jar";
private final String entryName = "foo/bar/A.class";
@@ -623,6 +626,10 @@
method = "getInputStream",
args = {java.util.zip.ZipEntry.class}
)
+ @AndroidOnly("This test doesn't pass on RI. If entry size is set up " +
+ "incorrectly, SecurityException is thrown. " +
+ "But SecurityException is thrown on RI only " +
+ "if jar file is signed incorreclty.")
public void test_getInputStreamLjava_util_jar_JarEntry_subtest0() {
File signedFile = null;
try {
@@ -652,8 +659,7 @@
} catch (Exception e) {
fail("Exception during test 4: " + e);
}
-
- boolean exception = false;
+
try {
JarFile jar = new JarFile(signedFile);
JarEntry entry = new JarEntry(entryName3);
@@ -662,12 +668,30 @@
// BEGIN android-added
byte[] dummy = getAllBytesFromStream(in);
// END android-added
+ fail("SecurityException should be thrown.");
} catch (SecurityException e) {
- exception = true;
+ // expected
} catch (Exception e) {
fail("Exception during test 5: " + e);
}
- assertTrue("Failed to throw SecurityException", exception);
+
+ try {
+ Support_Resources.copyFile(resources, null, jarName5);
+ signedFile = new File(resources, jarName5);
+ } catch (Exception e) {
+ fail("Failed to create local file 5: " + e);
+ }
+
+ try {
+ JarFile jar = new JarFile(signedFile);
+ JarEntry entry = new JarEntry(entryName3);
+ InputStream in = jar.getInputStream(entry);
+ fail("SecurityException should be thrown.");
+ } catch (SecurityException e) {
+ // expected
+ } catch (Exception e) {
+ fail("Exception during test 5: " + e);
+ }
}
/*
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarInputStreamTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarInputStreamTest.java
index 1a8c753..64e0e1a 100644
--- a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarInputStreamTest.java
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarInputStreamTest.java
@@ -180,7 +180,6 @@
args = {}
)
@KnownFailure("IOException not thrown when using getNextJarEntry() after close().")
- // This is the original test_getNextJarEntry including the failing section.
public void test_getNextJarEntry_Ex() throws Exception {
final Set<String> desired = new HashSet<String>(Arrays
.asList(new String[] {
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java
index a416847..e652137 100644
--- a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java
@@ -44,8 +44,7 @@
* @tests java.util.jar.JarOutputStream#putNextEntry(java.util.zip.ZipEntry)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
+ level = TestLevel.PARTIAL_COMPLETE,
method = "putNextEntry",
args = {java.util.zip.ZipEntry.class}
)
@@ -112,7 +111,7 @@
args[0] = "-jar";
args[1] = outputJar.getAbsolutePath();
-// It's not that simple to execute a JAR agains Dalvik VM (see JarExecTest):
+// It's not that simple to execute a JAR against Dalvik VM (see DalvikExecTest):
//
// try {
// // execute the JAR and read the result
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200PackerTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200PackerTest.java
index 355fd27..0d72108 100644
--- a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200PackerTest.java
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200PackerTest.java
@@ -25,6 +25,8 @@
import tests.support.resource.Support_Resources;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -128,9 +130,7 @@
assertTrue(packFile2.length()>packFile3.length());
}
-/*
- * java.beans.* not implemented yet on android platform
- * class MyPCL implements PropertyChangeListener {
+ class MyPCL implements PropertyChangeListener {
boolean flag = false;
public boolean isCalled() {
@@ -141,15 +141,14 @@
flag = true;
}
}
-@TestInfo(
- level = TestLevel.COMPLETE,
-
- targets = {
- @TestTarget(
- methodName = "addPropertyChangeListener",
- methodArgs = {java.beans.PropertyChangeListener.class}
- )
- })
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "addPropertyChangeListener",
+ args = {java.beans.PropertyChangeListener.class}
+ )
+ @KnownFailure("No Implementation in Android!")
public void testAddPropertyChangeListener() {
MyPCL pcl = new MyPCL();
packer.addPropertyChangeListener(pcl);
@@ -158,15 +157,13 @@
assertTrue(pcl.isCalled());
}
-@TestInfo(
- level = TestLevel.COMPLETE,
-
- targets = {
- @TestTarget(
- methodName = "removePropertyChangeListener",
- methodArgs = {java.beans.PropertyChangeListener.class}
- )
- })
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "removePropertyChangeListener",
+ args = {java.beans.PropertyChangeListener.class}
+ )
+ @KnownFailure("No Implementation in Android!")
public void testRemovePropertyChangeListener() {
MyPCL pcl = new MyPCL();
packer.addPropertyChangeListener(pcl);
@@ -175,7 +172,7 @@
properties.put(Packer.EFFORT, "7");
assertFalse(pcl.isCalled());
}
-*/
+
@Override
protected void setUp() {
packer = Pack200.newPacker();
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200UnpackerTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200UnpackerTest.java
index 4d5ede3..c1f9813 100644
--- a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200UnpackerTest.java
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200UnpackerTest.java
@@ -25,6 +25,8 @@
import tests.support.resource.Support_Resources;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -176,9 +178,8 @@
assertEquals(jarEntries, new JarFile(jarFile2).size());
assertEquals(jarEntries, new JarFile(jarFile3).size());
}
-/*
- * java.beans.* not implemented yet on android platform
- * class MyPCL implements PropertyChangeListener {
+
+ class MyPCL implements PropertyChangeListener {
boolean flag = false;
public boolean isCalled() {
@@ -190,15 +191,13 @@
}
}
-@TestInfo(
- level = TestLevel.COMPLETE,
-
- targets = {
- @TestTarget(
- methodName = "addPropertyChangeListener",
- methodArgs = {java.beans.PropertyChangeListener.class}
- )
- })
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "addPropertyChangeListener",
+ args = {java.beans.PropertyChangeListener.class}
+ )
+ @KnownFailure("No Implementation in Android!")
public void testAddPropertyChangeListener() {
MyPCL pcl = new MyPCL();
unpacker.addPropertyChangeListener(pcl);
@@ -207,15 +206,13 @@
assertTrue(pcl.isCalled());
}
-@TestInfo(
- level = TestLevel.COMPLETE,
-
- targets = {
- @TestTarget(
- methodName = "removePropertyChangeListener",
- methodArgs = {java.beans.PropertyChangeListener.class}
- )
- })
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "removePropertyChangeListener",
+ args = {java.beans.PropertyChangeListener.class}
+ )
+ @KnownFailure("No Implementation in Android!")
public void testRemovePropertyChangeListener() {
MyPCL pcl = new MyPCL();
unpacker.addPropertyChangeListener(pcl);
@@ -224,7 +221,7 @@
properties.put(Unpacker.PROGRESS, "7");
assertFalse(pcl.isCalled());
}
-*/
+
@Override
protected void setUp() {
unpacker = Pack200.newUnpacker();
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java
index 109ac02..c6f07de 100644
--- a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java
@@ -17,8 +17,7 @@
package org.apache.harmony.archive.tests.java.util.jar;
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.BrokenTest;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -45,13 +44,12 @@
@TestTargetClass(ZipOutputStream.class)
public class ZipExecTest extends junit.framework.TestCase {
@TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
+ level = TestLevel.ADDITIONAL,
notes = "Regression functional test. Exception checking missed.",
method = "putNextEntry",
args = {java.util.zip.ZipEntry.class}
)
- @BrokenTest("Support_Exec.execJava is not so simple to use: Harmony Test cannot be easily adapted.")
- @AndroidOnly("dalvik vm specific")
+ @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
public void test_1562() throws Exception {
Manifest man = new Manifest();
Attributes att = man.getMainAttributes();
@@ -91,13 +89,12 @@
* @throws Exception in case of troubles
*/
@TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
+ level = TestLevel.ADDITIONAL,
notes = "Functional test.",
method = "ZipOutputStream",
args = {java.io.OutputStream.class}
)
- @BrokenTest("Support_Exec.execJava is not so simple to use: Harmony Test cannot be easily adapted.")
- @AndroidOnly("dalvik vm specific")
+ @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
public void test_zip_class_path() throws Exception {
File fooZip = File.createTempFile("hyts_", ".zip");
File barZip = File.createTempFile("hyts_", ".zip");
@@ -169,13 +166,12 @@
@TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
+ level = TestLevel.ADDITIONAL,
notes = "Functional test.",
method = "ZipOutputStream",
args = {java.io.OutputStream.class}
)
- @BrokenTest("Support_Exec.execJava is not so simple to use: Harmony Test cannot be easily adapted.")
- @AndroidOnly("dalvik vm specific")
+ @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
public void test_zip_jar_mix() throws Exception {
File fooJar = File.createTempFile("hyts_", ".jar");
File barZip = File.createTempFile("hyts_", ".zip");
@@ -213,13 +209,12 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
+ level = TestLevel.ADDITIONAL,
notes = "Functional test.",
method = "ZipOutputStream",
args = {java.io.OutputStream.class}
)
- @BrokenTest("Support_Exec.execJava is not so simple to use: Harmony Test cannot be easily adapted.")
- @AndroidOnly("dalvik vm specific")
+ @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
public void test_zip_jar_mix_1() throws Exception {
File fooZip = File.createTempFile("hyts_", ".zip");
File barJar = File.createTempFile("hyts_", ".jar");
@@ -265,13 +260,12 @@
* @throws Exception in case of troubles
*/
@TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
+ level = TestLevel.ADDITIONAL,
notes = "Functional test.",
method = "ZipOutputStream",
args = {java.io.OutputStream.class}
)
- @BrokenTest("Support_Exec.execJava is not so simple to use: Harmony Test cannot be easily adapted.")
- @AndroidOnly("dalvik vm specific")
+ @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
public void test_main_class_in_another_zip() throws Exception {
File fooZip = File.createTempFile("hyts_", ".zip");
File barZip = File.createTempFile("hyts_", ".zip");
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterInputStreamTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterInputStreamTest.java
index 2e91510..2de996e 100644
--- a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterInputStreamTest.java
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterInputStreamTest.java
@@ -17,7 +17,6 @@
package org.apache.harmony.archive.tests.java.util.zip;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -36,7 +35,6 @@
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
-import java.util.zip.ZipException;
@TestTargetClass(InflaterInputStream.class)
public class InflaterInputStreamTest extends TestCase {
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
index 3fe23a7..468a803 100644
--- a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
@@ -17,8 +17,8 @@
package org.apache.harmony.archive.tests.java.util.zip;
-import dalvik.annotation.AndroidOnly;
import dalvik.annotation.KnownFailure;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -28,6 +28,7 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -40,10 +41,9 @@
@TestTargetClass(ZipFile.class)
public class ZipFileTest extends junit.framework.TestCase {
- // BEGIN android-added
public byte[] getAllBytesFromStream(InputStream is) throws IOException {
ByteArrayOutputStream bs = new ByteArrayOutputStream();
- byte[] buf = new byte[666];
+ byte[] buf = new byte[512];
int iRead;
int off;
while (is.available() > 0) {
@@ -53,8 +53,6 @@
return bs.toByteArray();
}
- // END android-added
-
// the file hyts_zipFile.zip in setup must be included as a resource
private String tempFileName;
@@ -67,7 +65,10 @@
public void checkPermission(Permission perm) {
- if (perm.getActions().equals(forbidenPermissionAction)) {
+ // only check if it's a FilePermission because Locale checks
+ // for a PropertyPermission with action"read" to get system props.
+ if (perm instanceof FilePermission
+ && perm.getActions().equals(forbidenPermissionAction)) {
throw new SecurityException();
}
}
@@ -327,7 +328,7 @@
method = "getEntry",
args = {java.lang.String.class}
)
- @AndroidOnly("God knows why!")
+ @BrokenTest("Needs investigation. AndroidOnly?")
public void test_getEntryLjava_lang_String_AndroidOnly() throws IOException {
java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
assertNotNull("Could not obtain ZipEntry", zentry);
@@ -349,7 +350,8 @@
method = "getEntry",
args = {java.lang.String.class}
)
- @KnownFailure("Android does not throw IllegalStateException when using getEntry() after close().")
+ @KnownFailure("Android does not throw IllegalStateException when using "
+ + "getEntry() after close().")
public void test_getEntryLjava_lang_String_Ex() throws IOException {
java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
assertNotNull("Could not obtain ZipEntry", zentry);
@@ -434,7 +436,8 @@
method = "size",
args = {}
)
- @KnownFailure("IllegalStateException not thrown when using ZipFile.size() after close().")
+ @KnownFailure("IllegalStateException not thrown when using ZipFile.size() "
+ + "after close().")
public void test_size() throws IOException {
assertEquals(6, zfile.size());
zfile.close();
@@ -453,7 +456,6 @@
@Override
protected void setUp() {
try {
- // BEGIN android-changed
// Create a local copy of the file since some tests want to alter
// information.
tempFileName = System.getProperty("java.io.tmpdir");
@@ -471,7 +473,6 @@
f.delete();
InputStream is = Support_Resources.getStream("hyts_ZipFile.zip");
FileOutputStream fos = new FileOutputStream(f);
- // END android-changed
byte[] rbuf = getAllBytesFromStream(is);
fos.write(rbuf, 0, rbuf.length);
is.close();
diff --git a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipInputStreamTest.java b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipInputStreamTest.java
index bdab74a..ac332fa 100644
--- a/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipInputStreamTest.java
+++ b/libcore/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipInputStreamTest.java
@@ -174,7 +174,8 @@
method = "close",
args = {}
)
- @KnownFailure("The behaviour is different from RI, but not neccessarily wrong.")
+ @KnownFailure("after an exception has been thrown wile reading a "
+ + "call to close also throws an exception.")
public void test_closeAfterException() throws Exception {
File resources = Support_Resources.createTempFolder();
Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
@@ -192,7 +193,7 @@
// expected
}
- zis1.close(); // Android throws exception here, but RI only when getNextEntry/read/skip are called.
+ zis1.close();
try {
zis1.getNextEntry();
fail("IOException expected");
@@ -346,31 +347,31 @@
method = "available",
args = {}
)
- @KnownFailure("Needs investigation!!!")
public void test_available() throws Exception {
File resources = Support_Resources.createTempFolder();
- Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
- File fl = new File(resources, "Broken_manifest.jar");
+ Support_Resources.copyFile(resources, null, "hyts_ZipFile.zip");
+ File fl = new File(resources, "hyts_ZipFile.zip");
FileInputStream fis = new FileInputStream(fl);
ZipInputStream zis1 = new ZipInputStream(fis);
+ ZipEntry entry = zis1.getNextEntry();
+ assertNotNull("No entry in the archive.", entry);
+ long entrySize = entry.getSize();
+ assertTrue("Entry size was < 1", entrySize > 0);
int i = 0;
-System.out.println(fl.length());
- for (i = 0; i < fl.length(); i++) {
-//System.out.println(i);
+ for (i = 0; i < entrySize; i++) {
zis1.skip(1);
-//System.out.println("Skipped 1");
-int avail = zis1.available();
-//System.out.println(avail);
- if (zis1.available() == 0) break; // RI breaks at i = 0 already; Android loops till the end!
-//System.out.println("Looping...");
+ if (zis1.available() == 0) break;
}
- if (i == fl.length()) {
- fail("ZipInputStream.available or ZipInputStream.skip does not working properly");
+ if (i != entrySize) {
+ fail("ZipInputStream.available or ZipInputStream.skip does not " +
+ "working properly. Only skipped " + i +
+ " bytes instead of " + entrySize);
}
- assertTrue(zis1.available() == 0);
zis1.skip(1);
+ assertTrue(zis1.available() == 0);
+ zis1.closeEntry();
assertFalse(zis.available() == 0);
zis1.close();
try {
diff --git a/libcore/auth/src/main/java/javax/security/auth/callback/CallbackHandler.java b/libcore/auth/src/main/java/javax/security/auth/callback/CallbackHandler.java
index a71c558..952b81a 100644
--- a/libcore/auth/src/main/java/javax/security/auth/callback/CallbackHandler.java
+++ b/libcore/auth/src/main/java/javax/security/auth/callback/CallbackHandler.java
@@ -17,6 +17,8 @@
package javax.security.auth.callback;
+import java.io.IOException;
+
/**
* Needs to be implemented by classes that want to handle authentication
* {@link Callback}s. A single method {@link #handle(Callback[])} must be
@@ -49,6 +51,6 @@
* if the {@code CallbackHandler} is not able to handle a
* specific {@code Callback}
*/
- void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException;
+ void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException;
}
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/BadPaddingExceptionTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/BadPaddingExceptionTest.java
index 4dcc314..6297392 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/BadPaddingExceptionTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/BadPaddingExceptionTest.java
@@ -39,18 +39,6 @@
@TestTargetClass(BadPaddingException.class)
public class BadPaddingExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for BadPaddingExceptionTests.
- *
- * @param arg0
- */
- public BadPaddingExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
index 72d7c81..56e83c6 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
@@ -53,12 +53,15 @@
class Mock_CipherSpi extends myCipherSpi {
@Override
- protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException {
- return super.engineDoFinal(input, inputOffset, inputLen);
+ protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
+ throws IllegalBlockSizeException, BadPaddingException {
+ return super.engineDoFinal(input, inputOffset, inputLen);
}
@Override
- protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
+ int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
return super.engineDoFinal(input, inputOffset, inputLen, output, outputOffset);
}
@@ -83,17 +86,20 @@
}
@Override
- protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
+ protected void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
super.engineInit(opmode, key, random);
}
@Override
- protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
super.engineInit(opmode, key, params, random);
}
@Override
- protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
super.engineInit(opmode, key, params, random);
}
@@ -113,7 +119,8 @@
}
@Override
- protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException {
+ protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
+ int outputOffset) throws ShortBufferException {
return super.engineUpdate(input, inputOffset, inputLen, output, outputOffset);
}
@@ -121,28 +128,20 @@
protected int engineGetKeySize(Key key) throws InvalidKeyException {
return super.engineGetKeySize(key);
}
-
+
@Override
protected byte[] engineWrap(Key key) throws InvalidKeyException, IllegalBlockSizeException {
return super.engineWrap(key);
}
-
+
@Override
- protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException {
+ protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)
+ throws InvalidKeyException, NoSuchAlgorithmException {
return super.engineUnwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType);
}
}
/**
- * Constructor for CipherSpiTests.
- *
- * @param arg0
- */
- public CipherSpiTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>CipherSpi</code> constructor
* Assertion: constructs CipherSpi
*/
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
index f06fa54..1245eb3 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
@@ -17,7 +17,6 @@
package org.apache.harmony.crypto.tests.javax.crypto;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -787,7 +786,6 @@
args = {byte[].class, int.class, int.class, byte[].class, int.class}
)
})
- @KnownFailure("Fixed in ToT")
public void testDoFinalbyteArrayintintbyteArrayint() throws Exception {
byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
byte[] b1 = new byte[30];
@@ -1190,7 +1188,6 @@
args = {byte[].class, java.lang.String.class, int.class}
)
})
- @KnownFailure("Fixed in ToT")
public void test_unwrap$BLjava_lang_StringI () throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
IllegalBlockSizeException {
@@ -1408,7 +1405,6 @@
method = "doFinal",
args = {byte[].class, int.class}
)
- @KnownFailure("Fixed in ToT")
public void test_doFinal$BI() throws Exception {
byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
byte[] b1 = new byte[30];
@@ -1580,7 +1576,6 @@
method = "doFinal",
args = {byte[].class, int.class, int.class, byte[].class}
)
- @KnownFailure("Fixed in ToT")
public void test_doFinal$BII$B() throws Exception {
byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
byte[] b1 = new byte[30];
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismExceptionTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismExceptionTest.java
index 99901ac..a26e605 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismExceptionTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismExceptionTest.java
@@ -40,18 +40,6 @@
*/
public class ExemptionMechanismExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for ExemptionMechanismExceptionTests.
- *
- * @param arg0
- */
- public ExemptionMechanismExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismSpiTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismSpiTest.java
index e694e55..793edcb 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismSpiTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismSpiTest.java
@@ -89,15 +89,6 @@
}
/**
- * Constructor for ExemptionMechanismSpiTests.
- *
- * @param arg0
- */
- public ExemptionMechanismSpiTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>ExemptionMechanismSpi</code> constructor Assertion:
* constructs ExemptionMechanismSpi
* @throws Exception
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/IllegalBlockSizeExceptionTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/IllegalBlockSizeExceptionTest.java
index d99e003..b98297d 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/IllegalBlockSizeExceptionTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/IllegalBlockSizeExceptionTest.java
@@ -40,18 +40,6 @@
*/
public class IllegalBlockSizeExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for IllegalBlockSizeExceptionTests.
- *
- * @param arg0
- */
- public IllegalBlockSizeExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementSpiTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementSpiTest.java
index 6617ea1..3954608 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementSpiTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementSpiTest.java
@@ -22,11 +22,6 @@
package org.apache.harmony.crypto.tests.javax.crypto;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
@@ -34,13 +29,17 @@
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.KeyAgreementSpi;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
-import javax.crypto.KeyAgreementSpi;
+
+import junit.framework.TestCase;
import org.apache.harmony.crypto.tests.support.MyKeyAgreementSpi;
-import junit.framework.TestCase;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
@TestTargetClass(KeyAgreementSpi.class)
/**
@@ -52,7 +51,8 @@
class Mock_KeyAgreementSpi extends MyKeyAgreementSpi {
@Override
- protected Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException {
+ protected Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException,
+ IllegalStateException {
return super.engineDoPhase(key, lastPhase);
}
@@ -62,12 +62,14 @@
}
@Override
- protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException {
+ protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException,
+ NoSuchAlgorithmException, InvalidKeyException {
return super.engineGenerateSecret(algorithm);
}
@Override
- protected int engineGenerateSecret(byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException {
+ protected int engineGenerateSecret(byte[] sharedSecret, int offset)
+ throws IllegalStateException, ShortBufferException {
return super.engineGenerateSecret(sharedSecret, offset);
}
@@ -77,18 +79,11 @@
}
@Override
- protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
super.engineInit(key, params, random);
}
-
- }
- /**
- * Constructor for KeyAgreementSpiTests.
- *
- * @param arg0
- */
- public KeyAgreementSpiTest(String arg0) {
- super(arg0);
+
}
/**
@@ -113,10 +108,8 @@
} catch (IllegalStateException e) {
}
byte[] bb = kaSpi.engineGenerateSecret();
- assertEquals("Length is not 0", bb.length, 0);
- assertEquals("Returned integer is not 0",
- kaSpi.engineGenerateSecret(new byte[1], 10),
- -1);
+ assertEquals("Length is not 0", bb.length, 0);
+ assertEquals("Returned integer is not 0", kaSpi.engineGenerateSecret(new byte[1], 10), -1);
assertNull("Not null result", kaSpi.engineGenerateSecret("aaa"));
try {
kaSpi.engineGenerateSecret("");
@@ -134,6 +127,6 @@
kaSpi.engineInit(key, params, new SecureRandom());
fail("IllegalArgumentException must be thrown");
} catch (IllegalArgumentException e) {
- }
+ }
}
}
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
index ed57596..220c6c6 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
@@ -22,6 +22,7 @@
package org.apache.harmony.crypto.tests.javax.crypto;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -921,6 +922,7 @@
method = "engineGenerateSecret",
args = {java.lang.String.class}
)})
+ @KnownFailure("Does not throw expected exception")
public void test_generateSecretLjava_lang_String() throws Exception {
if (!DEFSupported) {
fail(NotSupportMsg);
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorSpiTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorSpiTest.java
index bcf2635..0605986 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorSpiTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorSpiTest.java
@@ -44,48 +44,36 @@
*/
public class KeyGeneratorSpiTest extends TestCase {
-class Mock_KeyGeneratorSpi extends MyKeyGeneratorSpi {
+ class Mock_KeyGeneratorSpi extends MyKeyGeneratorSpi {
- @Override
- protected SecretKey engineGenerateKey() {
- return super.engineGenerateKey();
- }
+ @Override
+ protected SecretKey engineGenerateKey() {
+ return super.engineGenerateKey();
+ }
- @Override
- protected void engineInit(SecureRandom random) {
- super.engineInit(random);
- }
+ @Override
+ protected void engineInit(SecureRandom random) {
+ super.engineInit(random);
+ }
- @Override
- protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException {
- super.engineInit(params, random);
- }
+ @Override
+ protected void engineInit(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+ super.engineInit(params, random);
+ }
- @Override
- protected void engineInit(int keysize, SecureRandom random) {
- super.engineInit(keysize, random);
- }
-
-}
- /**
- * Constructor for KeyGeneratorSpiTests.
- *
- * @param arg0
- */
- public KeyGeneratorSpiTest(String arg0) {
- super(arg0);
+ @Override
+ protected void engineInit(int keysize, SecureRandom random) {
+ super.engineInit(keysize, random);
+ }
+
}
/**
* Test for <code>KeyGeneratorSpi</code> constructor Assertion: constructs
* KeyGeneratorSpi
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "KeyGeneratorSpi",
- args = {}
- )
+ @TestTargetNew(level = TestLevel.COMPLETE, notes = "", method = "KeyGeneratorSpi", args = {})
public void testKeyGeneratorSpi01() throws InvalidAlgorithmParameterException {
Mock_KeyGeneratorSpi kgSpi = new Mock_KeyGeneratorSpi();
assertNull("Not null result", kgSpi.engineGenerateKey());
@@ -99,17 +87,18 @@
fail("IllegalArgumentException must be thrown");
} catch (IllegalArgumentException e) {
}
- AlgorithmParameterSpec aps = null;
+ AlgorithmParameterSpec aps = null;
try {
kgSpi.engineInit(aps, new SecureRandom());
- fail("InvalidAlgorithmParameterException must be thrown when parameter is null");
- } catch (InvalidAlgorithmParameterException e) {
- }
- aps = new APSpecSpi();
- kgSpi.engineInit(aps, new SecureRandom());
+ fail("InvalidAlgorithmParameterException must be thrown when parameter is null");
+ } catch (InvalidAlgorithmParameterException e) {
+ }
+ aps = new APSpecSpi();
+ kgSpi.engineInit(aps, new SecureRandom());
}
}
+
class APSpecSpi implements AlgorithmParameterSpec {
-
+
}
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacSpiTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacSpiTest.java
index d7a2ec1..270adaa 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacSpiTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacSpiTest.java
@@ -160,15 +160,6 @@
}
-/**
- * Constructor for MacSpiTests.
- *
- * @param arg0
- */
- public MacSpiTest(String arg0) {
- super(arg0);
- }
-
/**
* Test for <code>MacSpi</code> constructor
* Assertion: constructs MacSpi
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NoSuchPaddingExceptionTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NoSuchPaddingExceptionTest.java
index 01418c8..da4a94d 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NoSuchPaddingExceptionTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NoSuchPaddingExceptionTest.java
@@ -40,18 +40,6 @@
*/
public class NoSuchPaddingExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for NoSuchPaddingExceptionTests.
- *
- * @param arg0
- */
- public NoSuchPaddingExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactorySpiTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactorySpiTest.java
index 4b383d7..bcc05a2 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactorySpiTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactorySpiTest.java
@@ -16,9 +16,9 @@
*/
/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
+ * @author Vera Y. Petrashkova
+ * @version $Revision$
+ */
package org.apache.harmony.crypto.tests.javax.crypto;
@@ -36,10 +36,8 @@
import junit.framework.TestCase;
-
/**
* Tests for <code>SecretKeyFactorySpi</code> class constructors and methods.
- *
*/
@TestTargetClass(SecretKeyFactorySpi.class)
@@ -52,7 +50,8 @@
}
@Override
- protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec) throws InvalidKeySpecException {
+ protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec)
+ throws InvalidKeySpecException {
return super.engineGetKeySpec(key, keySpec);
}
@@ -60,31 +59,15 @@
protected SecretKey engineTranslateKey(SecretKey key) throws InvalidKeyException {
return super.engineTranslateKey(key);
}
-
+
}
/**
- * Constructor for SecretKeyfactorySpiTests.
- *
- * @param arg0
- */
- public SecretKeyFactorySpiTest(String arg0) {
- super(arg0);
- }
-
- /**
- *
* Test for <code>SecretKeyFactorySpi</code> constructor Assertion:
* constructs SecretKeyFactorySpi
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "SecretKeyFactorySpi",
- args = {}
- )
- public void testSecretKeyFactorySpi01() throws InvalidKeyException,
- InvalidKeySpecException {
+ @TestTargetNew(level = TestLevel.COMPLETE, notes = "", method = "SecretKeyFactorySpi", args = {})
+ public void testSecretKeyFactorySpi01() throws InvalidKeyException, InvalidKeySpecException {
Mock_SecretKeyFactorySpi skfSpi = new Mock_SecretKeyFactorySpi();
SecretKey sk = null;
assertNull("Not null result", skfSpi.engineTranslateKey(sk));
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyTest.java
index 7941972..4e34ed2 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyTest.java
@@ -40,15 +40,6 @@
public class SecretKeyTest extends TestCase {
/**
- * Constructor for SecretKeyTest.
- *
- * @param arg0
- */
- public SecretKeyTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>serialVersionUID</code> field
*/
@TestTargetNew(
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ShortBufferExceptionTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ShortBufferExceptionTest.java
index 9121275..4390994 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ShortBufferExceptionTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ShortBufferExceptionTest.java
@@ -38,18 +38,6 @@
*/
public class ShortBufferExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for ShortBufferExceptionTests.
- *
- * @param arg0
- */
- public ShortBufferExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java
index 1ba0d00..862cced 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java
@@ -38,7 +38,6 @@
suite.addTestSuite(CipherAesWrapTest.class);
suite.addTestSuite(CipherDESedeTest.class);
suite.addTestSuite(CipherDESedeWrapTest.class);
- suite.addTestSuite(CipherSymmetricKeyThread.class);
suite.addTestSuite(CipherPBETest.class);
suite.addTestSuite(CipherRSATest.class);
suite.addTestSuite(KeyGeneratorFunctionalTest.class);
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java
index 446ade3..ce62332 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java
@@ -21,7 +21,6 @@
import junit.framework.TestCase;
-
import targets.Cipher;
@TestTargetClass(Cipher.AES.class)
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java
index 0e7e7e1..2c75abd 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java
@@ -21,7 +21,6 @@
import junit.framework.TestCase;
-
import targets.Cipher;
@TestTargetClass(Cipher.AESWrap.class)
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java
index 27113c6..c6053b6 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java
@@ -21,7 +21,6 @@
import junit.framework.TestCase;
-
import targets.Cipher;
@TestTargetClass(Cipher.DESede.class)
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeWrapTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeWrapTest.java
index 05eed26..e2c9c9e 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeWrapTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeWrapTest.java
@@ -21,7 +21,6 @@
import junit.framework.TestCase;
-
import targets.Cipher;
@TestTargetClass(Cipher.DESedeWrap.class)
@@ -33,7 +32,7 @@
method = "method",
args = {}
)
- public void _test_DESedeWrap() {
+ public void test_DESedeWrap() {
CipherWrapThread DESedeWrap = new CipherWrapThread("DESedeWrap",
new int[]{112, 168},
new String[] {"CBC"},
@@ -43,15 +42,4 @@
assertEquals(DESedeWrap.getFailureMessages(), 0, DESedeWrap.getTotalFailuresNumber());
}
-
- public void test_DESede() {
- CipherWrapThread DESedeWrap = new CipherWrapThread("DESede",
- new int[]{112, 168},
- new String[] {"CBC"},
- new String[]{"NoPadding"});
-
- DESedeWrap.launcher();
-
- assertEquals(DESedeWrap.getFailureMessages(), 0, DESedeWrap.getTotalFailuresNumber());
- }
}
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDesTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDesTest.java
index 3417d92..7b11ae9 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDesTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDesTest.java
@@ -21,7 +21,6 @@
import junit.framework.TestCase;
-
import targets.Cipher;
@TestTargetClass(Cipher.DES.class)
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java
index 5f97064..a3fb3c2 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java
@@ -21,13 +21,8 @@
import junit.framework.TestCase;
-
import targets.Cipher;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.SecretKeyFactory;
-
@TestTargetClass(Cipher.PBE.class)
public class CipherPBETest extends TestCase {
// 2 cases checked
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSATest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSATest.java
index 3071287..90cb956 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSATest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSATest.java
@@ -21,7 +21,6 @@
import junit.framework.TestCase;
-
import targets.Cipher;
@TestTargetClass(Cipher.RSA.class)
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java
index fbb5f64..d0e5f6a 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java
@@ -15,28 +15,23 @@
*/
package org.apache.harmony.crypto.tests.javax.crypto.func;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
import junit.framework.TestCase;
+import targets.KeyAgreement;
-import java.math.BigInteger;
-import java.security.AlgorithmParameterGenerator;
-import java.security.AlgorithmParameters;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Formatter;
-
-import javax.crypto.KeyAgreement;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.DHParameterSpec;
-
+@TestTargetClass(KeyAgreement.DH.class)
public class KeyAgreementFunctionalTest extends TestCase {
- public void test_() throws Exception {
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_KeyAgreement() throws Exception {
String[] algArray = {"DES", "DESede"};
KeyAgreementThread kat = new KeyAgreementThread(algArray);
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorFunctionalTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorFunctionalTest.java
index 87546a9..dde6fbd 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorFunctionalTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorFunctionalTest.java
@@ -22,13 +22,8 @@
import junit.framework.TestCase;
-
import targets.KeyGenerator;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-
@TestTargetClass(KeyGenerator.AES.class)
public class KeyGeneratorFunctionalTest extends TestCase {
@TestTargets({
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacFunctionalTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacFunctionalTest.java
index 0736c3d..bfe486a 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacFunctionalTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacFunctionalTest.java
@@ -15,16 +15,54 @@
*/
package org.apache.harmony.crypto.tests.javax.crypto.func;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
import junit.framework.TestCase;
+import targets.Mac;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
+@TestTargetClass(Mac.HMACMD5.class)
public class MacFunctionalTest extends TestCase {
- public void test_() throws Exception {
+@TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = Mac.HMACSHA1.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = Mac.HMACSHA256.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = Mac.HMACSHA384.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = Mac.HMACSHA512.class,
+ method = "method",
+ args = {}
+ )
+})
+ public void test_Mac() throws Exception {
String[] algArray = {"HMACSHA1", "HMACSHA256", "HMACSHA384",
"HMACSHA512", "HMACMD5"};
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryFunctionalTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryFunctionalTest.java
index e2ec4bc..286bb5b 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryFunctionalTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryFunctionalTest.java
@@ -15,20 +15,39 @@
*/
package org.apache.harmony.crypto.tests.javax.crypto.func;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
import junit.framework.TestCase;
+import targets.SecretKeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.KeySpec;
-
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.DESKeySpec;
-import javax.crypto.spec.DESedeKeySpec;
-import javax.crypto.spec.PBEKeySpec;
-
+@TestTargetClass(SecretKeyFactory.DES.class)
public class SecretKeyFactoryFunctionalTest extends TestCase {
-
+@TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = SecretKeyFactory.DESede.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = SecretKeyFactory.PBEWITHMD5ANDDES.class,
+ method = "method",
+ args = {}
+ )
+})
public void test_() throws Exception {
String[] algArray = {"DES", "DESede", "PBEWITHMD5ANDDES",
"PBEWithSHA1AndDESede", "PBEWithSHA1AndRC2_40"};
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java
index 9ab8d02..f47d693 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java
@@ -22,20 +22,19 @@
package org.apache.harmony.crypto.tests.javax.crypto.interfaces;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
import javax.crypto.interfaces.DHKey;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.spec.DHParameterSpec;
import junit.framework.TestCase;
-
-import java.math.BigInteger;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
/**
@@ -46,15 +45,6 @@
public class DHPrivateKeyTest extends TestCase {
/**
- * Constructor for DHPrivateKey.
- *
- * @param arg0
- */
- public DHPrivateKeyTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>serialVersionUID</code> field
*/
@TestTargetNew(
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
index 274a221..2ca738e 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
@@ -46,15 +46,6 @@
public class DHPublicKeyTest extends TestCase {
/**
- * Constructor for DHPublicKey.
- *
- * @param arg0
- */
- public DHPublicKeyTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>serialVersionUID</code> field
*/
@TestTargetNew(
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/PBEKeyTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/PBEKeyTest.java
index cee9634..43d9265 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/PBEKeyTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/PBEKeyTest.java
@@ -42,15 +42,6 @@
/**
- * Constructor for PBEKey.
- *
- * @param arg0
- */
- public PBEKeyTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>serialVersionUID</code> field
*/
@TestTargetNew(
diff --git a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java
index f7a762f..5eeb76f 100644
--- a/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java
+++ b/libcore/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java
@@ -22,7 +22,6 @@
package org.apache.harmony.crypto.tests.javax.crypto.spec;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -161,7 +160,6 @@
method = "SecretKeySpec",
args = {byte[].class, int.class, int.class, java.lang.String.class}
)
- @KnownFailure("Constructor does not check if offset is negative")
public void testSecretKeySpec3() {
byte[] key = new byte[] {1, 2, 3, 4, 5};
int offset = 1;
diff --git a/libcore/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java b/libcore/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java
index b8be0cb..c00e37b 100644
--- a/libcore/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java
+++ b/libcore/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java
@@ -51,7 +51,7 @@
* not provided, the class identified in @TestTargetClass is used by the
* test progress doclet.
*/
- Class<?> clazz(); // default void.class;
+ Class<?> clazz() default void.class;
/**
* Specifies the level of coverage the tested API method has.
diff --git a/libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java b/libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java
index cb2f76d..73e6fe4 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java
@@ -95,7 +95,7 @@
/**
* Complete initialization on first use of the class loader.
*/
- private void ensureInit() {
+ private synchronized void ensureInit() {
if (mInitialized) {
return;
}
@@ -195,13 +195,21 @@
else
sourceFileName = sourcePathName.substring(lastSlash+1);
- /* replace ".jar", ".zip", whatever with ".odex" */
+ /*
+ * Replace ".jar", ".zip", whatever with ".dex". We don't want to
+ * use ".odex", because the build system uses that for files that
+ * are paired with resource-only jar files. If the VM can assume
+ * that there's no classes.dex in the matching jar, it doesn't need
+ * to open the jar to check for updated dependencies, providing a
+ * slight performance boost at startup. The use of ".dex" here
+ * matches the use on files in /data/dalvik-cache.
+ */
int lastDot = sourceFileName.lastIndexOf(".");
if (lastDot < 0)
newStr.append(sourceFileName);
else
newStr.append(sourceFileName, 0, lastDot);
- newStr.append(".odex");
+ newStr.append(".dex");
if (VERBOSE_DEBUG)
System.out.println("Output file will be " + newStr.toString());
diff --git a/libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java b/libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java
index 94edfa1..c80aef8 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java
@@ -102,7 +102,7 @@
this.libPath = libPath;
}
- private void ensureInit() {
+ private synchronized void ensureInit() {
if (initialized) {
return;
}
diff --git a/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java b/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java
index 9034ac1..023cd6a 100644
--- a/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/libcore/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -16,6 +16,8 @@
package dalvik.system;
+import java.io.IOException;
+
/**
* Provides access to some VM-specific debug features. Though this class and
* many of its members are public, this class is meant to be wrapped in a more
@@ -240,6 +242,18 @@
*/
public static native int getLoadedClassCount();
+ /**
+ * Dump "hprof" data to the specified file. This will cause a GC.
+ *
+ * The VM may create a temporary file in the same directory.
+ *
+ * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof").
+ * @throws UnsupportedOperationException if the VM was built without
+ * HPROF support.
+ * @throws IOException if an error occurs while opening or writing files.
+ */
+ public static native void dumpHprofData(String fileName) throws IOException;
+
/* don't ask */
static native void printThis(Object thisThing, int count, int thing);
diff --git a/libcore/dom/src/test/java/org/w3c/domts/JUnitTestCaseAdapter.java b/libcore/dom/src/test/java/org/w3c/domts/JUnitTestCaseAdapter.java
index 6180147..7110792 100644
--- a/libcore/dom/src/test/java/org/w3c/domts/JUnitTestCaseAdapter.java
+++ b/libcore/dom/src/test/java/org/w3c/domts/JUnitTestCaseAdapter.java
@@ -13,10 +13,15 @@
package org.w3c.domts;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
@@ -30,14 +35,132 @@
public class JUnitTestCaseAdapter extends TestCase implements DOMTestFramework {
private DOMTestCase test;
+
+
+ private static DOMTestDocumentBuilderFactory defaultFactory = null;
public JUnitTestCaseAdapter(DOMTestCase test) {
super(test.getTargetURI());
test.setFramework(this);
this.test = test;
}
+//BEGIN android-added
+ public JUnitTestCaseAdapter() {
+
+ }
+
+ private String errorMessage = null;
+ private boolean failed = false;
+
+ @Override
+ public void setName(String name) {
+ super.setName(name);
+ if (test == null) {
+ try {
+ URI uri = new URI(name);
+ String path = uri.getPath();
+ path = path.replaceAll("/", ".");
+ Class<?> clazz = null;
+ int pos = path.indexOf('.');
+ while (pos != -1) {
+ try {
+ clazz = Class.forName("org.w3c.domts." + path);
+ break;
+ } catch (ClassNotFoundException e) {
+ // do nothing
+ }
+ path = path.substring(pos + 1);
+ }
+ if (clazz == null) {
+ errorMessage = "class not found for test: " + name;
+ failed = true;
+ return;
+ }
+ if (defaultFactory == null) {
+ defaultFactory = new JAXPDOMTestDocumentBuilderFactory(null,
+ JAXPDOMTestDocumentBuilderFactory.getConfiguration1());
+ }
+
+ Constructor<?> constructor = clazz.getConstructor(new Class<?>[] {
+ DOMTestDocumentBuilderFactory.class
+ });
+
+ test = (DOMTestCase)constructor.newInstance(new Object[] {
+ defaultFactory
+ });
+ test.setFramework(this);
+
+ } catch (URISyntaxException e) {
+ failed = true;
+ errorMessage = e.getMessage();
+ if (errorMessage == null) {
+ errorMessage = "" + e.toString();
+ }
+ } catch (IllegalAccessException e) {
+ failed = true;
+ errorMessage = e.getMessage();
+ if (errorMessage == null) {
+ errorMessage = "" + e.toString();
+ }
+ } catch (InstantiationException e) {
+ failed = true;
+ errorMessage = e.getMessage();
+ if (errorMessage == null) {
+ errorMessage = "" + e.toString();
+ }
+ } catch (DOMTestIncompatibleException e) {
+ failed = true;
+ errorMessage = e.getMessage();
+ if (errorMessage == null) {
+ errorMessage = "" + e.toString();
+ }
+ } catch (SecurityException e) {
+ failed = true;
+ errorMessage = e.getMessage();
+ if (errorMessage == null) {
+ errorMessage = "" + e.toString();
+ }
+ } catch (NoSuchMethodException e) {
+ failed = true;
+ errorMessage = e.getMessage();
+ if (errorMessage == null) {
+ errorMessage = "" + e.toString();
+ }
+ } catch (IllegalArgumentException e) {
+ failed = true;
+ errorMessage = e.getMessage();
+ if (errorMessage == null) {
+ errorMessage = "" + e.toString();
+ }
+ } catch (InvocationTargetException e) {
+ failed = true;
+ Throwable t = e.getCause();
+ if (t != null) {
+ errorMessage = t.getMessage();
+ if (errorMessage == null) {
+ errorMessage = "" + t.toString();
+ }
+ } else {
+ errorMessage = e.getMessage();
+ if (errorMessage == null) {
+ errorMessage = "" + e.toString();
+ }
+ }
+ }
+ }
+ }
+//END android-added
protected void runTest() throws Throwable {
+ //BEGIN android-added
+ if (failed) {
+ if (errorMessage != null) {
+ fail(errorMessage);
+ } else {
+ fail("init failed");
+ }
+ }
+ //END android-added
test.runTest();
int mutationCount = test.getMutationCount();
if (mutationCount != 0) {
diff --git a/libcore/dom/src/test/java/org/w3c/domts/level1/core/alltests.java b/libcore/dom/src/test/java/org/w3c/domts/level1/core/alltests.java
index d5a7516..2c907f2 100644
--- a/libcore/dom/src/test/java/org/w3c/domts/level1/core/alltests.java
+++ b/libcore/dom/src/test/java/org/w3c/domts/level1/core/alltests.java
@@ -50,19 +50,19 @@
sink.addTest(attrcreatedocumentfragment.class);
sink.addTest(attrcreatetextnode.class);
sink.addTest(attrcreatetextnode2.class);
- sink.addTest(attrdefaultvalue.class);
+// sink.addTest(attrdefaultvalue.class); //javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(attreffectivevalue.class);
// sink.addTest(attrentityreplacement.class);
sink.addTest(attrname.class);
sink.addTest(attrnextsiblingnull.class);
- sink.addTest(attrnotspecifiedvalue.class);
+// sink.addTest(attrnotspecifiedvalue.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(attrparentnodenull.class);
sink.addTest(attrprevioussiblingnull.class);
// sink.addTest(attrsetvaluenomodificationallowederr.class);
// sink.addTest(attrsetvaluenomodificationallowederrEE.class);
sink.addTest(attrspecifiedvalue.class);
sink.addTest(attrspecifiedvaluechanged.class);
- sink.addTest(attrspecifiedvalueremove.class);
+// sink.addTest(attrspecifiedvalueremove.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(cdatasectiongetdata.class);
// sink.addTest(cdatasectionnormalize.class);
sink.addTest(characterdataappenddata.class);
@@ -113,7 +113,7 @@
sink.addTest(documentcreatedocumentfragment.class);
sink.addTest(documentcreateelement.class);
sink.addTest(documentcreateelementcasesensitive.class);
- sink.addTest(documentcreateelementdefaultattr.class);
+// sink.addTest(documentcreateelementdefaultattr.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(documentcreateentityreference.class);
// sink.addTest(documentcreateentityreferenceknown.class);
sink.addTest(documentcreateprocessinginstruction.class);
@@ -156,18 +156,18 @@
sink.addTest(elementinvalidcharacterexception.class);
sink.addTest(elementnormalize.class);
sink.addTest(elementnotfounderr.class);
- sink.addTest(elementremoveattribute.class);
+// sink.addTest(elementremoveattribute.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(elementremoveattributeaftercreate.class);
sink.addTest(elementremoveattributenode.class);
// sink.addTest(elementremoveattributenodenomodificationallowederr.class);
// sink.addTest(elementremoveattributenodenomodificationallowederrEE.class);
// sink.addTest(elementremoveattributenomodificationallowederr.class);
// sink.addTest(elementremoveattributenomodificationallowederrEE.class);
- sink.addTest(elementremoveattributerestoredefaultvalue.class);
+// sink.addTest(elementremoveattributerestoredefaultvalue.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
// sink.addTest(elementreplaceattributewithself.class);
// sink.addTest(elementreplaceexistingattribute.class);
sink.addTest(elementreplaceexistingattributegevalue.class);
- sink.addTest(elementretrieveallattributes.class);
+// sink.addTest(elementretrieveallattributes.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(elementretrieveattrvalue.class);
sink.addTest(elementretrievetagname.class);
// sink.addTest(elementsetattributenodenomodificationallowederr.class);
@@ -184,8 +184,8 @@
sink.addTest(namednodemapinuseattributeerr.class);
sink.addTest(namednodemapnotfounderr.class);
sink.addTest(namednodemapnumberofnodes.class);
- sink.addTest(namednodemapremovenameditem.class);
- sink.addTest(namednodemapremovenameditemgetvalue.class);
+// sink.addTest(namednodemapremovenameditem.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
+// sink.addTest(namednodemapremovenameditemgetvalue.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(namednodemapremovenameditemreturnnodevalue.class);
sink.addTest(namednodemapreturnattrnode.class);
sink.addTest(namednodemapreturnfirstitem.class);
diff --git a/libcore/dom/src/test/java/org/w3c/domts/level2/core/alltests.java b/libcore/dom/src/test/java/org/w3c/domts/level2/core/alltests.java
index 2eb9368..8aaf13b 100644
--- a/libcore/dom/src/test/java/org/w3c/domts/level2/core/alltests.java
+++ b/libcore/dom/src/test/java/org/w3c/domts/level2/core/alltests.java
@@ -47,7 +47,7 @@
* @param sink test sink
*/
public void build(DOMTestSink sink) {
- sink.addTest(attrgetownerelement01.class);
+// sink.addTest(attrgetownerelement01.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(attrgetownerelement02.class);
sink.addTest(attrgetownerelement03.class);
sink.addTest(attrgetownerelement04.class);
@@ -94,8 +94,8 @@
sink.addTest(documentgetelementsbytagnameNS05.class);
// sink.addTest(documentimportnode01.class);
sink.addTest(documentimportnode02.class);
- sink.addTest(documentimportnode03.class);
- sink.addTest(documentimportnode04.class);
+// sink.addTest(documentimportnode03.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
+// sink.addTest(documentimportnode04.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(documentimportnode05.class);
sink.addTest(documentimportnode06.class);
sink.addTest(documentimportnode07.class);
@@ -129,13 +129,13 @@
sink.addTest(domimplementationhasfeature02.class);
sink.addTest(elementgetattributenodens01.class);
sink.addTest(elementgetattributenodens02.class);
- sink.addTest(elementgetattributenodens03.class);
- sink.addTest(elementgetattributens02.class);
+// sink.addTest(elementgetattributenodens03.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
+// sink.addTest(elementgetattributens02.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(elementgetelementsbytagnamens02.class);
sink.addTest(elementgetelementsbytagnamens04.class);
sink.addTest(elementgetelementsbytagnamens05.class);
sink.addTest(elementhasattribute01.class);
- sink.addTest(elementhasattribute02.class);
+// sink.addTest(elementhasattribute02.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(elementhasattribute03.class);
sink.addTest(elementhasattribute04.class);
// sink.addTest(elementhasattributens01.class);
@@ -155,14 +155,14 @@
sink.addTest(elementsetattributens05.class);
sink.addTest(elementsetattributens08.class);
sink.addTest(elementsetattributensurinull.class);
- sink.addTest(getAttributeNS01.class);
+// sink.addTest(getAttributeNS01.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(getAttributeNS02.class);
sink.addTest(getAttributeNS03.class);
sink.addTest(getAttributeNS04.class);
sink.addTest(getAttributeNS05.class);
sink.addTest(getAttributeNodeNS01.class);
sink.addTest(getAttributeNodeNS02.class);
- sink.addTest(getElementById01.class);
+// sink.addTest(getElementById01.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(getElementById02.class);
// sink.addTest(getElementsByTagNameNS01.class);
sink.addTest(getElementsByTagNameNS02.class);
@@ -183,13 +183,13 @@
// sink.addTest(getNamedItemNS03.class);
// sink.addTest(getNamedItemNS04.class);
sink.addTest(hasAttribute01.class);
- sink.addTest(hasAttribute02.class);
+// sink.addTest(hasAttribute02.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(hasAttribute03.class);
- sink.addTest(hasAttribute04.class);
+// sink.addTest(hasAttribute04.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(hasAttributeNS01.class);
sink.addTest(hasAttributeNS02.class);
sink.addTest(hasAttributeNS03.class);
- sink.addTest(hasAttributeNS04.class);
+// sink.addTest(hasAttributeNS04.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(hasAttributeNS05.class);
sink.addTest(hasAttributes01.class);
sink.addTest(hasAttributes02.class);
@@ -206,7 +206,7 @@
sink.addTest(importNode04.class);
// sink.addTest(importNode05.class);
// sink.addTest(importNode06.class);
- sink.addTest(importNode07.class);
+// sink.addTest(importNode07.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(importNode08.class);
// sink.addTest(importNode09.class);
sink.addTest(importNode10.class);
@@ -241,7 +241,7 @@
sink.addTest(namednodemapgetnameditemns05.class);
sink.addTest(namednodemapgetnameditemns06.class);
sink.addTest(namednodemapremovenameditemns01.class);
- sink.addTest(namednodemapremovenameditemns02.class);
+// sink.addTest(namednodemapremovenameditemns02.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(namednodemapremovenameditemns03.class);
// sink.addTest(namednodemapremovenameditemns04.class);
// sink.addTest(namednodemapremovenameditemns05.class);
@@ -260,7 +260,7 @@
// sink.addTest(namednodemapsetnameditemns09.class);
// sink.addTest(namednodemapsetnameditemns10.class);
// sink.addTest(namednodemapsetnameditemns11.class);
- sink.addTest(namespaceURI01.class);
+// sink.addTest(namespaceURI01.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(namespaceURI02.class);
sink.addTest(namespaceURI03.class);
sink.addTest(namespaceURI04.class);
@@ -282,7 +282,7 @@
sink.addTest(nodesetprefix01.class);
sink.addTest(nodesetprefix02.class);
sink.addTest(nodesetprefix03.class);
- sink.addTest(nodesetprefix04.class);
+// sink.addTest(nodesetprefix04.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(nodesetprefix05.class);
sink.addTest(nodesetprefix06.class);
sink.addTest(nodesetprefix07.class);
@@ -305,7 +305,7 @@
sink.addTest(prefix11.class);
sink.addTest(publicId01.class);
// sink.addTest(removeAttributeNS01.class);
- sink.addTest(removeAttributeNS02.class);
+// sink.addTest(removeAttributeNS02.class); // javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
sink.addTest(removeNamedItemNS01.class);
sink.addTest(removeNamedItemNS02.class);
// sink.addTest(removeNamedItemNS03.class);
diff --git a/libcore/icu/src/main/java/com/ibm/icu4jni/math/BigDecimal.java b/libcore/icu/src/main/java/com/ibm/icu4jni/math/BigDecimal.java
deleted file mode 100644
index 4460b19..0000000
--- a/libcore/icu/src/main/java/com/ibm/icu4jni/math/BigDecimal.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.ibm.icu4jni.math;
-
-public class BigDecimal extends Number {
-
- @Override
- public double doubleValue() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public float floatValue() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int intValue() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public long longValue() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public String toString() {
- return "";
- }
-
-}
diff --git a/libcore/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java b/libcore/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
index ddd4062..5bee1fd 100644
--- a/libcore/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
+++ b/libcore/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java
@@ -31,12 +31,12 @@
import java.util.Locale;
public class DecimalFormat extends NumberFormat {
-
+
private int addr;
-
+
private DecimalFormatSymbols symbols;
-
- // fix to be icu4j conform (harmony wants this field to exist)
+
+ // fix to be icu4j conform (harmony wants this field to exist)
// for serialization of java.text.DecimalFormat
@SuppressWarnings("unused")
private boolean useExponentialNotation = false;
@@ -47,7 +47,7 @@
private boolean negSuffNull;
private boolean posPrefNull;
private boolean posSuffNull;
-
+
public DecimalFormat(String pattern, DecimalFormatSymbols icuSymbols) {
this.addr = icuSymbols.getAddr();
this.symbols = icuSymbols;
@@ -58,7 +58,7 @@
public int hashCode() {
return super.hashCode() * 37 + this.getPositivePrefix().hashCode();
}
-
+
@Override
public Object clone() {
String pat = this.toPattern();
@@ -73,7 +73,7 @@
newdf.setGroupingSize(this.getGroupingSize());
return newdf;
}
-
+
@Override
public boolean equals(Object object) {
if (object == this) {
@@ -87,10 +87,10 @@
if(obj.addr == this.addr) {
return true;
}
-
+
boolean result = super.equals(object);
-
+
result &= obj.toPattern().equals(this.toPattern());
result &= obj.isDecimalSeparatorAlwaysShown() == this.isDecimalSeparatorAlwaysShown();
result &= obj.getGroupingSize() == this.getGroupingSize();
@@ -114,34 +114,37 @@
result &= thisCurr == null;
}
result &= obj.getDecimalFormatSymbols().equals(this.getDecimalFormatSymbols());
-
+
return result;
}
@Override
public StringBuffer format(Object value, StringBuffer buffer, FieldPosition field) {
-
+
if(!(value instanceof Number)) {
throw new IllegalArgumentException();
}
if(buffer == null || field == null) {
throw new NullPointerException();
}
-
+
String fieldType = getFieldType(field.getFieldAttribute());
-
+
Number number = (Number) value;
-
+
if(number instanceof BigInteger) {
BigInteger valBigInteger = (BigInteger) number;
- String result = NativeDecimalFormat.format(this.addr,
+ String result = NativeDecimalFormat.format(this.addr,
valBigInteger.toString(10), field, fieldType, null, 0);
return buffer.append(result);
} else if(number instanceof BigDecimal) {
BigDecimal valBigDecimal = (BigDecimal) number;
- String result = NativeDecimalFormat.format(this.addr,
- valBigDecimal.unscaledValue().toString(10), field,
- fieldType, null, valBigDecimal.scale());
+ StringBuilder val = new StringBuilder();
+ val.append(valBigDecimal.unscaledValue().toString(10));
+ int scale = valBigDecimal.scale();
+ scale = makeScalePositive(scale, val);
+ String result = NativeDecimalFormat.format(this.addr,
+ val.toString(), field, fieldType, null, scale);
return buffer.append(result);
} else {
double dv = number.doubleValue();
@@ -151,7 +154,7 @@
fieldType, null);
return buffer.append(result);
}
- String result = NativeDecimalFormat.format(this.addr, dv, field,
+ String result = NativeDecimalFormat.format(this.addr, dv, field,
fieldType, null);
return buffer.append(result);
}
@@ -163,14 +166,14 @@
if(buffer == null || field == null) {
throw new NullPointerException();
}
-
+
String fieldType = getFieldType(field.getFieldAttribute());
-
- String result = NativeDecimalFormat.format(this.addr, value, field,
+
+ String result = NativeDecimalFormat.format(this.addr, value, field,
fieldType, null);
-
+
buffer.append(result.toCharArray(), 0, result.length());
-
+
return buffer;
}
@@ -180,14 +183,14 @@
if(buffer == null || field == null) {
throw new NullPointerException();
}
-
+
String fieldType = getFieldType(field.getFieldAttribute());
-
- String result = NativeDecimalFormat.format(this.addr, value, field,
+
+ String result = NativeDecimalFormat.format(this.addr, value, field,
fieldType, null);
-
+
buffer.append(result.toCharArray(), 0, result.length());
-
+
return buffer;
}
@@ -223,16 +226,19 @@
Number number = (Number) object;
String text = null;
StringBuffer attributes = new StringBuffer();
-
+
if(number instanceof BigInteger) {
BigInteger valBigInteger = (BigInteger) number;
- text = NativeDecimalFormat.format(this.addr,
+ text = NativeDecimalFormat.format(this.addr,
valBigInteger.toString(10), null, null, attributes, 0);
} else if(number instanceof BigDecimal) {
BigDecimal valBigDecimal = (BigDecimal) number;
- text = NativeDecimalFormat.format(this.addr,
- valBigDecimal.unscaledValue().toString(10), null,null,
- attributes, valBigDecimal.scale());
+ StringBuilder val = new StringBuilder();
+ val.append(valBigDecimal.unscaledValue().toString(10));
+ int scale = valBigDecimal.scale();
+ scale = makeScalePositive(scale, val);
+ text = NativeDecimalFormat.format(this.addr, val.toString(), null,
+ null, attributes, scale);
} else {
double dv = number.doubleValue();
long lv = number.longValue();
@@ -240,11 +246,11 @@
text = NativeDecimalFormat.format(this.addr, lv, null,
null, attributes);
} else {
- text = NativeDecimalFormat.format(this.addr, dv, null,
+ text = NativeDecimalFormat.format(this.addr, dv, null,
null, attributes);
}
}
-
+
AttributedString as = new AttributedString(text.toString());
String[] attrs = attributes.toString().split(";");
@@ -258,11 +264,22 @@
as.addAttribute(attribute, attribute, Integer.parseInt(attrs[3*i+1]),
Integer.parseInt(attrs[3*i+2]));
}
-
+
// return the CharacterIterator from AttributedString
return as.getIterator();
}
+ private int makeScalePositive(int scale, StringBuilder val) {
+ if (scale < 0) {
+ scale = -scale;
+ for (int i = scale; i > 0; i--) {
+ val.append('0');
+ }
+ scale = 0;
+ }
+ return scale;
+ }
+
public String toLocalizedPattern() {
return NativeDecimalFormat.toPatternImpl(this.addr, true);
}
@@ -275,30 +292,30 @@
public Number parse(String string, ParsePosition position) {
return NativeDecimalFormat.parse(addr, string, position);
}
-
+
// start getter and setter
@Override
public int getMaximumFractionDigits() {
- return NativeDecimalFormat.getAttribute(this .addr,
+ return NativeDecimalFormat.getAttribute(this .addr,
UNumberFormatAttribute.UNUM_MAX_FRACTION_DIGITS.ordinal());
}
@Override
public int getMaximumIntegerDigits() {
- return NativeDecimalFormat.getAttribute(this .addr,
+ return NativeDecimalFormat.getAttribute(this .addr,
UNumberFormatAttribute.UNUM_MAX_INTEGER_DIGITS.ordinal());
}
@Override
public int getMinimumFractionDigits() {
- return NativeDecimalFormat.getAttribute(this .addr,
+ return NativeDecimalFormat.getAttribute(this .addr,
UNumberFormatAttribute.UNUM_MIN_FRACTION_DIGITS.ordinal());
}
@Override
public int getMinimumIntegerDigits() {
- return NativeDecimalFormat.getAttribute(this .addr,
+ return NativeDecimalFormat.getAttribute(this .addr,
UNumberFormatAttribute.UNUM_MIN_INTEGER_DIGITS.ordinal());
}
@@ -308,12 +325,12 @@
}
public int getGroupingSize() {
- return NativeDecimalFormat.getAttribute(this.addr,
+ return NativeDecimalFormat.getAttribute(this.addr,
UNumberFormatAttribute.UNUM_GROUPING_SIZE.ordinal());
}
public int getMultiplier() {
- return NativeDecimalFormat.getAttribute(this.addr,
+ return NativeDecimalFormat.getAttribute(this.addr,
UNumberFormatAttribute.UNUM_MULTIPLIER.ordinal());
}
@@ -321,7 +338,7 @@
if (negPrefNull) {
return null;
}
- return NativeDecimalFormat.getTextAttribute(this.addr,
+ return NativeDecimalFormat.getTextAttribute(this.addr,
UNumberFormatTextAttribute.UNUM_NEGATIVE_PREFIX.ordinal());
}
@@ -329,7 +346,7 @@
if (negSuffNull) {
return null;
}
- return NativeDecimalFormat.getTextAttribute(this.addr,
+ return NativeDecimalFormat.getTextAttribute(this.addr,
UNumberFormatTextAttribute.UNUM_NEGATIVE_SUFFIX.ordinal());
}
@@ -337,7 +354,7 @@
if (posPrefNull) {
return null;
}
- return NativeDecimalFormat.getTextAttribute(this.addr,
+ return NativeDecimalFormat.getTextAttribute(this.addr,
UNumberFormatTextAttribute.UNUM_POSITIVE_PREFIX.ordinal());
}
@@ -345,24 +362,24 @@
if (posSuffNull) {
return null;
}
- return NativeDecimalFormat.getTextAttribute(this.addr,
+ return NativeDecimalFormat.getTextAttribute(this.addr,
UNumberFormatTextAttribute.UNUM_POSITIVE_SUFFIX.ordinal());
}
public boolean isDecimalSeparatorAlwaysShown() {
- return NativeDecimalFormat.getAttribute(this.addr,
+ return NativeDecimalFormat.getAttribute(this.addr,
UNumberFormatAttribute.UNUM_DECIMAL_ALWAYS_SHOWN.ordinal()) != 0;
}
@Override
public boolean isParseIntegerOnly() {
- return NativeDecimalFormat.getAttribute(this.addr,
+ return NativeDecimalFormat.getAttribute(this.addr,
UNumberFormatAttribute.UNUM_PARSE_INT_ONLY.ordinal()) != 0;
}
@Override
public boolean isGroupingUsed() {
- return NativeDecimalFormat.getAttribute(this.addr,
+ return NativeDecimalFormat.getAttribute(this.addr,
UNumberFormatAttribute.UNUM_GROUPING_USED.ordinal()) != 0;
}
@@ -376,7 +393,7 @@
public void setDecimalSeparatorAlwaysShown(boolean value) {
int i = value ? -1 : 0;
- NativeDecimalFormat.setAttribute(this.addr,
+ NativeDecimalFormat.setAttribute(this.addr,
UNumberFormatAttribute.UNUM_DECIMAL_ALWAYS_SHOWN.ordinal(), i);
}
@@ -465,10 +482,10 @@
@Override
public void setParseIntegerOnly(boolean value) {
int i = value ? -1 : 0;
- NativeDecimalFormat.setAttribute(this.addr,
+ NativeDecimalFormat.setAttribute(this.addr,
UNumberFormatAttribute.UNUM_PARSE_INT_ONLY.ordinal(), i);
}
-
+
static protected String getFieldType(Format.Field field) {
if(field == null) {
return null;
@@ -508,7 +525,7 @@
}
return null;
}
-
+
protected Format.Field getField(String type) {
if(type.equals("")) {
return null;
diff --git a/libcore/icu/src/main/native/ConverterInterface.c b/libcore/icu/src/main/native/ConverterInterface.c
index 3996146..d7f5c9b 100644
--- a/libcore/icu/src/main/native/ConverterInterface.c
+++ b/libcore/icu/src/main/native/ConverterInterface.c
@@ -805,9 +805,13 @@
}
printf("canonical name for %s\n", canonicalName);
-#endif
- (*env)->SetObjectArrayElement(env,ret,i,(*env)->NewStringUTF(env,canonicalName));
- /*printf("canonical name : %s at %i\n", name,i); */
+#endif
+ // BEGIN android-changed
+ jstring canonName = (*env)->NewStringUTF(env,canonicalName);
+ (*env)->SetObjectArrayElement(env,ret,i,canonName);
+ (*env)->DeleteLocalRef(env, canonName);
+ // END android-changed
+ /*printf("canonical name : %s at %i\n", name,i); */
canonicalName[0]='\0';/* nul terminate */
}
return (ret);
@@ -881,7 +885,11 @@
(*env)->FindClass(env,"java/lang/String"),
(*env)->NewStringUTF(env,""));
for(;--j>=0;) {
- (*env)->SetObjectArrayElement(env,ret,j,(*env)->NewStringUTF(env,aliasArray[j]));
+ // BEGIN android-changed
+ jstring alias = (*env)->NewStringUTF(env, aliasArray[j]);
+ (*env)->SetObjectArrayElement(env, ret, j, alias);
+ (*env)->DeleteLocalRef(env, alias);
+ // END android-changed
}
}
}
diff --git a/libcore/icu/src/main/native/DecimalFormatInterface.cpp b/libcore/icu/src/main/native/DecimalFormatInterface.cpp
index 243efeb..6221826 100644
--- a/libcore/icu/src/main/native/DecimalFormatInterface.cpp
+++ b/libcore/icu/src/main/native/DecimalFormatInterface.cpp
@@ -28,6 +28,8 @@
#include <string.h>
#include "cutils/log.h"
+#define LOG_TAG "DecimalFormatInterface"
+
static UBool icuError(JNIEnv *env, UErrorCode errorcode)
{
const char *emsg = u_errorName(errorcode);
@@ -48,13 +50,13 @@
default :
exception = env->FindClass("java/lang/RuntimeException");
}
-
+
return (env->ThrowNew(exception, emsg) != 0);
}
return 0;
}
-static jint openDecimalFormatImpl(JNIEnv *env, jclass clazz, jstring locale,
+static jint openDecimalFormatImpl(JNIEnv *env, jclass clazz, jstring locale,
jstring pattern) {
// the errorcode returned by unum_open
@@ -68,9 +70,9 @@
const char *localeChars = env->GetStringUTFChars(locale, NULL);
// open a default type number format
- UNumberFormat *fmt = unum_open(UNUM_PATTERN_DECIMAL, pattChars, pattLen,
+ UNumberFormat *fmt = unum_open(UNUM_PATTERN_DECIMAL, pattChars, pattLen,
localeChars, NULL, &status);
-
+
// release the allocated strings
env->ReleaseStringChars(pattern, pattChars);
env->ReleaseStringUTFChars(locale, localeChars);
@@ -86,20 +88,20 @@
static void closeDecimalFormatImpl(JNIEnv *env, jclass clazz, jint addr) {
- // get the pointer to the number format
+ // get the pointer to the number format
UNumberFormat *fmt = (UNumberFormat *)(int)addr;
// close this number format
unum_close(fmt);
}
-static void setSymbol(JNIEnv *env, jclass clazz, jint addr, jint symbol,
+static void setSymbol(JNIEnv *env, jclass clazz, jint addr, jint symbol,
jstring text) {
-
+
// the errorcode returned by unum_setSymbol
UErrorCode status = U_ZERO_ERROR;
- // get the pointer to the number format
+ // get the pointer to the number format
UNumberFormat *fmt = (UNumberFormat *)(int)addr;
// prepare the symbol string for the call to unum_setSymbol
@@ -107,9 +109,9 @@
int textLen = env->GetStringLength(text);
// set the symbol
- unum_setSymbol(fmt, (UNumberFormatSymbol) symbol, textChars, textLen,
+ unum_setSymbol(fmt, (UNumberFormatSymbol) symbol, textChars, textLen,
&status);
-
+
// release previously allocated space
env->ReleaseStringChars(text, textChars);
@@ -124,14 +126,14 @@
// the errorcode returned by unum_getSymbol
UErrorCode status = U_ZERO_ERROR;
- // get the pointer to the number format
+ // get the pointer to the number format
UNumberFormat *fmt = (UNumberFormat *)(int)addr;
UChar* result = NULL;
resultlength=0;
// find out how long the result will be
- reslenneeded=unum_getSymbol(fmt, (UNumberFormatSymbol) symbol, result,
+ reslenneeded=unum_getSymbol(fmt, (UNumberFormatSymbol) symbol, result,
resultlength, &status);
result = NULL;
@@ -139,7 +141,7 @@
status=U_ZERO_ERROR;
resultlength=reslenneeded+1;
result=(UChar*)malloc(sizeof(UChar) * resultlength);
- reslenneeded=unum_getSymbol(fmt, (UNumberFormatSymbol) symbol, result,
+ reslenneeded=unum_getSymbol(fmt, (UNumberFormatSymbol) symbol, result,
resultlength, &status);
}
if (icuError(env, status) != FALSE) {
@@ -152,17 +154,17 @@
return res;
}
-
-static void setAttribute(JNIEnv *env, jclass clazz, jint addr, jint symbol,
+
+static void setAttribute(JNIEnv *env, jclass clazz, jint addr, jint symbol,
jint value) {
-
+
UNumberFormat *fmt = (UNumberFormat *)(int)addr;
unum_setAttribute(fmt, (UNumberFormatAttribute) symbol, value);
}
-
+
static jint getAttribute(JNIEnv *env, jclass clazz, jint addr, jint symbol) {
-
+
UNumberFormat *fmt = (UNumberFormat *)(int)addr;
int res = unum_getAttribute(fmt, (UNumberFormatAttribute) symbol);
@@ -170,27 +172,27 @@
return res;
}
-static void setTextAttribute(JNIEnv *env, jclass clazz, jint addr, jint symbol,
+static void setTextAttribute(JNIEnv *env, jclass clazz, jint addr, jint symbol,
jstring text) {
// the errorcode returned by unum_setTextAttribute
UErrorCode status = U_ZERO_ERROR;
- // get the pointer to the number format
+ // get the pointer to the number format
UNumberFormat *fmt = (UNumberFormat *)(int)addr;
const UChar *textChars = env->GetStringChars(text, NULL);
int textLen = env->GetStringLength(text);
- unum_setTextAttribute(fmt, (UNumberFormatTextAttribute) symbol, textChars,
+ unum_setTextAttribute(fmt, (UNumberFormatTextAttribute) symbol, textChars,
textLen, &status);
-
+
env->ReleaseStringChars(text, textChars);
icuError(env, status);
}
-static jstring getTextAttribute(JNIEnv *env, jclass clazz, jint addr,
+static jstring getTextAttribute(JNIEnv *env, jclass clazz, jint addr,
jint symbol) {
uint32_t resultlength, reslenneeded;
@@ -198,14 +200,14 @@
// the errorcode returned by unum_getTextAttribute
UErrorCode status = U_ZERO_ERROR;
- // get the pointer to the number format
+ // get the pointer to the number format
UNumberFormat *fmt = (UNumberFormat *)(int)addr;
UChar* result = NULL;
resultlength=0;
// find out how long the result will be
- reslenneeded=unum_getTextAttribute(fmt, (UNumberFormatTextAttribute) symbol,
+ reslenneeded=unum_getTextAttribute(fmt, (UNumberFormatTextAttribute) symbol,
result, resultlength, &status);
result = NULL;
@@ -213,8 +215,8 @@
status=U_ZERO_ERROR;
resultlength=reslenneeded+1;
result=(UChar*)malloc(sizeof(UChar) * resultlength);
- reslenneeded=unum_getTextAttribute(fmt,
- (UNumberFormatTextAttribute) symbol, result, resultlength,
+ reslenneeded=unum_getTextAttribute(fmt,
+ (UNumberFormatTextAttribute) symbol, result, resultlength,
&status);
}
if (icuError(env, status) != FALSE) {
@@ -228,13 +230,13 @@
return res;
}
-static void applyPatternImpl(JNIEnv *env, jclass clazz, jint addr,
+static void applyPatternImpl(JNIEnv *env, jclass clazz, jint addr,
jboolean localized, jstring pattern) {
// the errorcode returned by unum_applyPattern
UErrorCode status = U_ZERO_ERROR;
- // get the pointer to the number format
+ // get the pointer to the number format
UNumberFormat *fmt = (UNumberFormat *)(int)addr;
const UChar *pattChars = env->GetStringChars(pattern, NULL);
@@ -247,7 +249,7 @@
icuError(env, status);
}
-static jstring toPatternImpl(JNIEnv *env, jclass clazz, jint addr,
+static jstring toPatternImpl(JNIEnv *env, jclass clazz, jint addr,
jboolean localized) {
uint32_t resultlength, reslenneeded;
@@ -255,7 +257,7 @@
// the errorcode returned by unum_toPattern
UErrorCode status = U_ZERO_ERROR;
- // get the pointer to the number format
+ // get the pointer to the number format
UNumberFormat *fmt = (UNumberFormat *)(int)addr;
UChar* result = NULL;
@@ -269,7 +271,7 @@
status=U_ZERO_ERROR;
resultlength=reslenneeded+1;
result=(UChar*)malloc(sizeof(UChar) * resultlength);
- reslenneeded=unum_toPattern(fmt, localized, result, resultlength,
+ reslenneeded=unum_toPattern(fmt, localized, result, resultlength,
&status);
}
if (icuError(env, status) != FALSE) {
@@ -282,19 +284,19 @@
return res;
}
-
-static jstring formatLong(JNIEnv *env, jclass clazz, jint addr, jlong value,
+
+static jstring formatLong(JNIEnv *env, jclass clazz, jint addr, jlong value,
jobject field, jstring fieldType, jobject attributes) {
const char * fieldPositionClassName = "java/text/FieldPosition";
const char * stringBufferClassName = "java/lang/StringBuffer";
jclass fieldPositionClass = env->FindClass(fieldPositionClassName);
jclass stringBufferClass = env->FindClass(stringBufferClassName);
- jmethodID setBeginIndexMethodID = env->GetMethodID(fieldPositionClass,
+ jmethodID setBeginIndexMethodID = env->GetMethodID(fieldPositionClass,
"setBeginIndex", "(I)V");
- jmethodID setEndIndexMethodID = env->GetMethodID(fieldPositionClass,
+ jmethodID setEndIndexMethodID = env->GetMethodID(fieldPositionClass,
"setEndIndex", "(I)V");
- jmethodID appendMethodID = env->GetMethodID(stringBufferClass,
+ jmethodID appendMethodID = env->GetMethodID(stringBufferClass,
"append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
const char * fieldName = NULL;
@@ -329,7 +331,7 @@
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
- result = (UChar*)malloc(sizeof(UChar) * (reslenneeded + 1));
+ result = (UChar*)malloc(sizeof(UChar) * (reslenneeded + 1));
res->extract(result, reslenneeded + 1, status);
}
@@ -391,18 +393,18 @@
return resulting;
}
-static jstring formatDouble(JNIEnv *env, jclass clazz, jint addr, jdouble value,
+static jstring formatDouble(JNIEnv *env, jclass clazz, jint addr, jdouble value,
jobject field, jstring fieldType, jobject attributes) {
const char * fieldPositionClassName = "java/text/FieldPosition";
const char * stringBufferClassName = "java/lang/StringBuffer";
jclass fieldPositionClass = env->FindClass(fieldPositionClassName);
jclass stringBufferClass = env->FindClass(stringBufferClassName);
- jmethodID setBeginIndexMethodID = env->GetMethodID(fieldPositionClass,
+ jmethodID setBeginIndexMethodID = env->GetMethodID(fieldPositionClass,
"setBeginIndex", "(I)V");
- jmethodID setEndIndexMethodID = env->GetMethodID(fieldPositionClass,
+ jmethodID setEndIndexMethodID = env->GetMethodID(fieldPositionClass,
"setEndIndex", "(I)V");
- jmethodID appendMethodID = env->GetMethodID(stringBufferClass,
+ jmethodID appendMethodID = env->GetMethodID(stringBufferClass,
"append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
const char * fieldName = NULL;
@@ -437,7 +439,7 @@
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
- result = (UChar*)malloc(sizeof(UChar) * (reslenneeded + 1));
+ result = (UChar*)malloc(sizeof(UChar) * (reslenneeded + 1));
res->extract(result, reslenneeded + 1, status);
@@ -499,26 +501,18 @@
return resulting;
}
-
-static jstring formatDigitList(JNIEnv *env, jclass clazz, jint addr, jstring value,
+
+static jstring formatDigitList(JNIEnv *env, jclass clazz, jint addr, jstring value,
jobject field, jstring fieldType, jobject attributes, jint scale) {
- //const char * valueUTF = env->GetStringUTFChars(value, NULL);
- //LOGI("ENTER formatDigitList: %s", valueUTF);
- //env->ReleaseStringUTFChars(value, valueUTF);
+ // const char * valueUTF = env->GetStringUTFChars(value, NULL);
+ // LOGI("ENTER formatDigitList: %s, scale: %d", valueUTF, scale);
+ // env->ReleaseStringUTFChars(value, valueUTF);
- // prepare the classes and method ids
- const char * fieldPositionClassName = "java/text/FieldPosition";
- const char * stringBufferClassName = "java/lang/StringBuffer";
- jclass fieldPositionClass = env->FindClass(fieldPositionClassName);
- jclass stringBufferClass = env->FindClass(stringBufferClassName);
- jmethodID setBeginIndexMethodID = env->GetMethodID(fieldPositionClass,
- "setBeginIndex", "(I)V");
- jmethodID setEndIndexMethodID = env->GetMethodID(fieldPositionClass,
- "setEndIndex", "(I)V");
- jmethodID appendMethodID = env->GetMethodID(stringBufferClass,
- "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
-
+ if (scale < 0) {
+ icuError(env, U_ILLEGAL_ARGUMENT_ERROR);
+ return NULL;
+ }
const char * fieldName = NULL;
if(fieldType != NULL) {
@@ -527,21 +521,37 @@
uint32_t reslenneeded;
- jboolean isInteger = (scale == 0);
-
// prepare digit list
- const char *digits = env->GetStringUTFChars(value, NULL);
- // length must be string lengt + 2 because there's an additional
- // character in front of the string ("+" or "-") and a \0 at the end
- DigitList *digitList = new DigitList(strlen(digits) + 2);
- digitList->fCount = strlen(digits);
- strcpy(digitList->fDigits, digits);
- env->ReleaseStringUTFChars(value, digits);
+ const char *valueChars = env->GetStringUTFChars(value, NULL);
- digitList->fDecimalAt = digitList->fCount - scale;
- digitList->fIsPositive = (*digits != '-');
- digitList->fRoundingMode = DecimalFormat::kRoundHalfUp;
+ bool isInteger = (scale == 0);
+ bool isPositive = (*valueChars != '-');
+
+ // skip the '-' if the number is negative
+ const char *digits = (isPositive ? valueChars : valueChars + 1);
+ int length = strlen(digits);
+
+ // The length of our digit list buffer must be the actual string length + 3,
+ // because ICU will append some additional characters at the head and at the
+ // tail of the string, in order to keep strtod() happy:
+ //
+ // - The sign "+" or "-" is appended at the head
+ // - The exponent "e" and the "\0" terminator is appended at the tail
+ //
+ // In retrospect, the changes to ICU's DigitList that were necessary for
+ // big numbers look a bit hacky. It would make sense to rework all this
+ // once ICU 4.x has been integrated into Android. Ideally, big number
+ // support would make it into ICU itself, so we don't need our private
+ // fix anymore.
+ DigitList digitList(length + 3);
+ digitList.fCount = length;
+ strcpy(digitList.fDigits, digits);
+ env->ReleaseStringUTFChars(value, valueChars);
+
+ digitList.fDecimalAt = digitList.fCount - scale;
+ digitList.fIsPositive = isPositive;
+ digitList.fRoundingMode = DecimalFormat::kRoundHalfUp;
UChar *result = NULL;
@@ -553,40 +563,42 @@
UErrorCode status = U_ZERO_ERROR;
DecimalFormat::AttributeBuffer *attrBuffer = NULL;
- attrBuffer = (DecimalFormat::AttributeBuffer *) malloc(sizeof(DecimalFormat::AttributeBuffer));
+ attrBuffer = (DecimalFormat::AttributeBuffer *) calloc(sizeof(DecimalFormat::AttributeBuffer), 1);
attrBuffer->bufferSize = 128;
- attrBuffer->buffer = (char *) malloc(129 * sizeof(char));
- attrBuffer->buffer[0] = '\0';
+ attrBuffer->buffer = (char *) calloc(129 * sizeof(char), 1);
DecimalFormat *fmt = (DecimalFormat *)(int)addr;
- UnicodeString *res = new UnicodeString();
+ UnicodeString res;
- fmt->subformat(*res, fp, attrBuffer, *digitList, isInteger);
- delete digitList;
+ fmt->subformat(res, fp, attrBuffer, digitList, isInteger);
- reslenneeded = res->extract(NULL, 0, status);
+ reslenneeded = res.extract(NULL, 0, status);
if(status==U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
- result = (UChar*)malloc(sizeof(UChar) * (reslenneeded + 1));
+ result = (UChar*)malloc(sizeof(UChar) * (reslenneeded + 1));
- res->extract(result, reslenneeded + 1, status);
+ res.extract(result, reslenneeded + 1, status);
if (icuError(env, status) != FALSE) {
+ if(fieldType != NULL) {
+ env->ReleaseStringUTFChars(fieldType, fieldName);
+ }
free(result);
free(attrBuffer->buffer);
free(attrBuffer);
- delete(res);
return NULL;
}
} else {
+ if(fieldType != NULL) {
+ env->ReleaseStringUTFChars(fieldType, fieldName);
+ }
free(attrBuffer->buffer);
free(attrBuffer);
- delete(res);
- return NULL;
+ return NULL;
}
int attrLength = (strlen(attrBuffer->buffer) + 1 );
@@ -595,6 +607,12 @@
// check if we want to get all attributes
if(attributes != NULL) {
+ // prepare the classes and method ids
+ const char * stringBufferClassName = "java/lang/StringBuffer";
+ jclass stringBufferClass = env->FindClass(stringBufferClassName);
+ jmethodID appendMethodID = env->GetMethodID(stringBufferClass,
+ "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+
jstring attrString = env->NewStringUTF(attrBuffer->buffer + 1); // cut off the leading ';'
env->CallObjectMethod(attributes, appendMethodID, attrString);
}
@@ -612,6 +630,18 @@
}
if(resattr != NULL && strcmp(resattr, fieldName) == 0) {
+
+ // prepare the classes and method ids
+ const char * fieldPositionClassName =
+ "java/text/FieldPosition";
+ jclass fieldPositionClass = env->FindClass(
+ fieldPositionClassName);
+ jmethodID setBeginIndexMethodID = env->GetMethodID(
+ fieldPositionClass, "setBeginIndex", "(I)V");
+ jmethodID setEndIndexMethodID = env->GetMethodID(
+ fieldPositionClass, "setEndIndex", "(I)V");
+
+
resattr = strtok(NULL, delimiter);
begin = (int) strtol(resattr, NULL, 10);
resattr = strtok(NULL, delimiter);
@@ -632,16 +662,14 @@
free(attrBuffer->buffer);
free(attrBuffer);
free(result);
- delete(res);
-
- //const char * resultUTF = env->GetStringUTFChars(resulting, NULL);
- //LOGI("RETURN formatDigitList: %s", resultUTF);
- //env->ReleaseStringUTFChars(resulting, resultUTF);
+ // const char * resultUTF = env->GetStringUTFChars(resulting, NULL);
+ // LOGI("RETURN formatDigitList: %s", resultUTF);
+ // env->ReleaseStringUTFChars(resulting, resultUTF);
return resulting;
}
-static jobject parse(JNIEnv *env, jclass clazz, jint addr, jstring text,
+static jobject parse(JNIEnv *env, jclass clazz, jint addr, jstring text,
jobject position) {
const char * textUTF = env->GetStringUTFChars(text, NULL);
@@ -666,11 +694,11 @@
jclass bigDecimalClass = env->FindClass(bigDecimalClassName);
jclass bigIntegerClass = env->FindClass(bigIntegerClassName);
- jmethodID getIndexMethodID = env->GetMethodID(parsePositionClass,
+ jmethodID getIndexMethodID = env->GetMethodID(parsePositionClass,
"getIndex", "()I");
- jmethodID setIndexMethodID = env->GetMethodID(parsePositionClass,
+ jmethodID setIndexMethodID = env->GetMethodID(parsePositionClass,
"setIndex", "(I)V");
- jmethodID setErrorIndexMethodID = env->GetMethodID(parsePositionClass,
+ jmethodID setErrorIndexMethodID = env->GetMethodID(parsePositionClass,
"setErrorIndex", "(I)V");
jmethodID longInitMethodID = env->GetMethodID(longClass, "<init>", "(J)V");
@@ -682,8 +710,8 @@
bool resultAssigned;
int parsePos = env->CallIntMethod(position, getIndexMethodID, NULL);
- // make sure the ParsePosition is valid. Actually icu4c would parse a number
- // correctly even if the parsePosition is set to -1, but since the RI fails
+ // make sure the ParsePosition is valid. Actually icu4c would parse a number
+ // correctly even if the parsePosition is set to -1, but since the RI fails
// for that case we have to fail too
if(parsePos < 0 || parsePos > strlength) {
return NULL;
@@ -693,9 +721,9 @@
const UnicodeString src((UChar*)str, strlength, strlength);
ParsePosition pp;
-
+
pp.setIndex(parsePos);
-
+
DigitList digits;
((const DecimalFormat*)fmt)->parse(src, resultAssigned, res, pp, FALSE, digits);
@@ -705,8 +733,8 @@
if(pp.getErrorIndex() == -1) {
parsePos = pp.getIndex();
} else {
- env->CallVoidMethod(position, setErrorIndexMethodID,
- (jint) pp.getErrorIndex());
+ env->CallVoidMethod(position, setErrorIndexMethodID,
+ (jint) pp.getErrorIndex());
return NULL;
}
@@ -731,17 +759,17 @@
case Formattable::kDouble:
resultDouble = res.getDouble();
env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
- return env->NewObject(doubleClass, dblInitMethodID,
+ return env->NewObject(doubleClass, dblInitMethodID,
(jdouble) resultDouble);
case Formattable::kLong:
resultLong = res.getLong();
env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
- return env->NewObject(longClass, longInitMethodID,
+ return env->NewObject(longClass, longInitMethodID,
(jlong) resultLong);
case Formattable::kInt64:
resultInt64 = res.getInt64();
env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
- return env->NewObject(longClass, longInitMethodID,
+ return env->NewObject(longClass, longInitMethodID,
(jlong) resultInt64);
default:
return NULL;
@@ -791,7 +819,7 @@
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
- {"openDecimalFormatImpl", "(Ljava/lang/String;Ljava/lang/String;)I",
+ {"openDecimalFormatImpl", "(Ljava/lang/String;Ljava/lang/String;)I",
(void*) openDecimalFormatImpl},
{"closeDecimalFormatImpl", "(I)V", (void*) closeDecimalFormatImpl},
{"setSymbol", "(IILjava/lang/String;)V", (void*) setSymbol},
@@ -802,22 +830,22 @@
{"getTextAttribute", "(II)Ljava/lang/String;", (void*) getTextAttribute},
{"applyPatternImpl", "(IZLjava/lang/String;)V", (void*) applyPatternImpl},
{"toPatternImpl", "(IZ)Ljava/lang/String;", (void*) toPatternImpl},
- {"format",
- "(IJLjava/text/FieldPosition;Ljava/lang/String;Ljava/lang/StringBuffer;)Ljava/lang/String;",
+ {"format",
+ "(IJLjava/text/FieldPosition;Ljava/lang/String;Ljava/lang/StringBuffer;)Ljava/lang/String;",
(void*) formatLong},
- {"format",
- "(IDLjava/text/FieldPosition;Ljava/lang/String;Ljava/lang/StringBuffer;)Ljava/lang/String;",
+ {"format",
+ "(IDLjava/text/FieldPosition;Ljava/lang/String;Ljava/lang/StringBuffer;)Ljava/lang/String;",
(void*) formatDouble},
- {"format",
- "(ILjava/lang/String;Ljava/text/FieldPosition;Ljava/lang/String;Ljava/lang/StringBuffer;I)Ljava/lang/String;",
+ {"format",
+ "(ILjava/lang/String;Ljava/text/FieldPosition;Ljava/lang/String;Ljava/lang/StringBuffer;I)Ljava/lang/String;",
(void*) formatDigitList},
- {"parse",
- "(ILjava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;",
+ {"parse",
+ "(ILjava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;",
(void*) parse},
{"cloneImpl", "(I)I", (void*) cloneImpl}
};
int register_com_ibm_icu4jni_text_NativeDecimalFormat(JNIEnv* env) {
- return jniRegisterNativeMethods(env,
- "com/ibm/icu4jni/text/NativeDecimalFormat", gMethods,
+ return jniRegisterNativeMethods(env,
+ "com/ibm/icu4jni/text/NativeDecimalFormat", gMethods,
NELEM(gMethods));
}
diff --git a/libcore/icu/src/main/native/ResourceInterface.cpp b/libcore/icu/src/main/native/ResourceInterface.cpp
index 562f480..5f9d442 100644
--- a/libcore/icu/src/main/native/ResourceInterface.cpp
+++ b/libcore/icu/src/main/native/ResourceInterface.cpp
@@ -157,17 +157,31 @@
ures_close(currency);
ures_close(currencyMap);
ures_close(supplData);
- return NULL;
+ return env->NewStringUTF("None");
}
- UResourceBundle *currencyId = ures_getByKey(currencyElem, "id", NULL, &status);
- if(U_FAILURE(status)) {
+ // check if there is a to date. If there is, the currency isn't used anymore.
+ UResourceBundle *currencyTo = ures_getByKey(currencyElem, "to", NULL, &status);
+ if(!U_FAILURE(status)) {
+ // return and let the ResourceBundle throw an exception
ures_close(currencyElem);
ures_close(currency);
ures_close(currencyMap);
ures_close(supplData);
return NULL;
}
+ status = U_ZERO_ERROR;
+ ures_close(currencyTo);
+
+ UResourceBundle *currencyId = ures_getByKey(currencyElem, "id", NULL, &status);
+ if(U_FAILURE(status)) {
+ // No id defined for this country
+ ures_close(currencyElem);
+ ures_close(currency);
+ ures_close(currencyMap);
+ ures_close(supplData);
+ return env->NewStringUTF("None");
+ }
int length;
const jchar *id = ures_getString(currencyId, &length, &status);
@@ -177,7 +191,7 @@
ures_close(currency);
ures_close(currencyMap);
ures_close(supplData);
- return NULL;
+ return env->NewStringUTF("None");
}
ures_close(currencyId);
@@ -187,7 +201,7 @@
ures_close(supplData);
if(length == 0) {
- return NULL;
+ return env->NewStringUTF("None");
}
return env->NewString(id, length);
}
@@ -1227,7 +1241,11 @@
counter++;
// integer pattern derived from number pattern
- decSepOffset = u_strcspn(pattern, (jchar *)".\0");
+ // We need to convert a C string literal to a UChar string for u_strcspn.
+ static const char c_decSep[] = ".";
+ UChar decSep[sizeof(c_decSep)];
+ u_charsToUChars(c_decSep, decSep, sizeof(c_decSep));
+ decSepOffset = u_strcspn(pattern, decSep);
tmpPattern = (jchar *) malloc((decSepOffset + 1) * sizeof(jchar));
u_strncpy(tmpPattern, pattern, decSepOffset);
integerPattern = env->NewString(tmpPattern, decSepOffset);
diff --git a/libcore/libcore/security/src/test/resources/serialization/tests/security/cert/CertificateTest.golden.ser b/libcore/libcore/security/src/test/resources/serialization/tests/security/cert/CertificateTest.golden.ser
deleted file mode 100644
index b5bc9e0..0000000
--- a/libcore/libcore/security/src/test/resources/serialization/tests/security/cert/CertificateTest.golden.ser
+++ /dev/null
Binary files differ
diff --git a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
index 4334317..3ff1fc9 100644
--- a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
+++ b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
@@ -17,6 +17,7 @@
package org.apache.harmony.logging.tests.java.util.logging;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -885,6 +886,7 @@
args = {java.util.logging.LogRecord.class}
)
})
+ @AndroidOnly("This test fails on RI. Doesn't parse special pattern \"%t/%h.")
public void testInvalidParams() throws IOException {
// %t and %p parsing can add file separator automatically
diff --git a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java
index c1afeca..ba2345d 100644
--- a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java
+++ b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java
@@ -17,6 +17,7 @@
package org.apache.harmony.logging.tests.java.util.logging;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestTargetNew;
@@ -160,6 +161,10 @@
method = "formatMessage",
args = {LogRecord.class}
)
+ @AndroidOnly("The RI fails in this test because it uses a MessageFormat " +
+ "to format the message even though it doesn't contain \"{0\". " +
+ "The spec says that this would indicate that a MessageFormat " +
+ "should be used and else no formatting should be done.")
public void testFormatMessage() {
assertEquals(MSG, f.formatMessage(r));
diff --git a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java
index 0b882f0..5868b1f 100644
--- a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java
+++ b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java
@@ -51,13 +51,6 @@
private static String className = HandlerTest.class.getName();
/*
- * @see TestCase#setUp()
- */
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- /*
* @see TestCase#tearDown()
*/
protected void tearDown() throws Exception {
@@ -65,15 +58,6 @@
CallVerificationStack.getInstance().clear();
}
- /**
- * Constructor for HandlerTest.
- *
- * @param arg0
- */
- public HandlerTest(String arg0) {
- super(arg0);
- }
-
/*
* Test the constructor.
*/
diff --git a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
index 8be31e9..0702d51 100644
--- a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
+++ b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
@@ -17,11 +17,20 @@
package org.apache.harmony.logging.tests.java.util.logging;
-//import android.access.IPropertyChangeEvent;
-//import android.access.;
-import dalvik.annotation.*;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
+import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
@@ -36,12 +45,6 @@
import java.util.logging.Logger;
import java.util.logging.LoggingPermission;
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
-import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
-
/**
*
* add/get logger(dot)
@@ -56,7 +59,7 @@
LogManager manager = LogManager.getLogManager();
- // MockPropertyChangeListener listener;
+ MockPropertyChangeListener listener;
Properties props;
@@ -77,6 +80,7 @@
/*
* @see TestCase#setUp()
*/
+ @Override
protected void setUp() throws Exception {
super.setUp();
mockManager = new MockLogManager();
@@ -100,6 +104,7 @@
/*
* @see TestCase#tearDown()
*/
+ @Override
protected void tearDown() throws Exception {
super.tearDown();
handler = null;
@@ -161,7 +166,7 @@
Enumeration<String> enumar = mockManager.getLoggerNames();
int i = 0;
while (enumar.hasMoreElements()) {
- String name = (String)enumar.nextElement();
+ String name = enumar.nextElement();
i++;
assertEquals(FOO, name);
}
@@ -379,7 +384,7 @@
args = {java.lang.String.class}
)
})
- public void testAddGetLogger_addRoot() throws IOException {
+ public void testAddGetLogger_addRoot() {
Logger foo = new MockLogger(FOO, null);
Logger fooChild = new MockLogger(FOO + ".child", null);
Logger other = new MockLogger("other", null);
@@ -426,7 +431,12 @@
public void test_addLoggerLLogger_Security() throws Exception {
// regression test for Harmony-1286
SecurityManager originalSecurityManager = System.getSecurityManager();
- System.setSecurityManager(new SecurityManager());
+ System.setSecurityManager(new SecurityManager() {
+ @Override
+ public void checkPermission(Permission perm) {
+
+ }
+ });
try {
LogManager manager = LogManager.getLogManager();
manager.addLogger(new MockLogger("mock", null));
@@ -461,6 +471,7 @@
assertEquals(Level.FINE, root.getLevel());
assertEquals("", root.getName());
assertSame(root.getParent(), null);
+ // This test sometimes fails if other tests are run before this one.
assertNull(root.getResourceBundle());
assertNull(root.getResourceBundleName());
assertTrue(root.getUseParentHandlers());
@@ -516,7 +527,7 @@
Enumeration<String> enumar = mockManager.getLoggerNames();
int i = 0;
while (enumar.hasMoreElements()) {
- String name = (String)enumar.nextElement();
+ String name = enumar.nextElement();
i++;
assertEquals("name logger should be equal to foreseen name", FOO, name);
}
@@ -672,6 +683,12 @@
notes = "Verifies SecurityException.",
method = "getLogManager",
args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies SecurityException.",
+ method = "addPropertyChangeListener",
+ args = {java.beans.PropertyChangeListener.class}
)
})
public void testLoggingPermission() throws IOException {
@@ -701,22 +718,22 @@
fail("should throw SecurityException");
} catch (SecurityException e) {
}
- // try {
- // mockManager
- // .addPropertyChangeListener(new MockPropertyChangeListener());
- // fail("should throw SecurityException");
- // } catch (SecurityException e) {
- // }
- // try {
- // mockManager.addPropertyChangeListener(null);
- // fail("should throw NPE");
- // } catch (NullPointerException e) {
- // }
- // try {
- // mockManager.removePropertyChangeListener(null);
- // fail("should throw SecurityException");
- // } catch (SecurityException e) {
- // }
+ try {
+ mockManager
+ .addPropertyChangeListener(new MockPropertyChangeListener());
+ fail("should throw SecurityException");
+ } catch (SecurityException e) {
+ }
+ try {
+ mockManager.addPropertyChangeListener(null);
+ fail("should throw NPE");
+ } catch (NullPointerException e) {
+ }
+ try {
+ mockManager.removePropertyChangeListener(null);
+ fail("should throw SecurityException");
+ } catch (SecurityException e) {
+ }
try {
mockManager.reset();
fail("should throw SecurityException");
@@ -777,6 +794,7 @@
assertEquals(0, root.getHandlers().length);
assertEquals(Level.INFO, root.getLevel());
manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ manager.reset();
}
@TestTargetNew(
@@ -858,33 +876,32 @@
args = {java.io.InputStream.class}
)
public void testReadConfigurationInputStream() throws IOException {
- // mock LogManager
- InputStream stream = EnvironmentHelper.PropertiesToInputStream(props);
-
+
Logger foo = new MockLogger(FOO, null);
assertNull(foo.getLevel());
assertTrue(mockManager.addLogger(foo));
- Logger fo = new MockLogger("LogManagerTestFoo2", null);
+ Logger fo = new MockLogger(FOO + "2", null);
fo.setLevel(Level.ALL);
assertTrue(mockManager.addLogger(fo));
Handler h = new ConsoleHandler();
Level l = h.getLevel();
- assertSame(Level.OFF, h.getLevel());
+ assertSame(Level.INFO, h.getLevel());
// read configuration from stream
+ InputStream stream = EnvironmentHelper.PropertiesToInputStream(props);
mockManager.readConfiguration(stream);
stream.close();
- // level DO has effect
+ // level DOES have an effect on LogManagerTestFoo
assertEquals(Level.WARNING, foo.getLevel());
// for non specified logger, level is reset to null
assertNull(fo.getLevel());
// read properties don't affect handler
- assertSame(Level.OFF, h.getLevel());
+ assertSame(Level.INFO, h.getLevel());
assertSame(l, h.getLevel());
}
@@ -925,7 +942,6 @@
args = {java.io.InputStream.class}
)
public void testReadConfigurationInputStream_root() throws IOException {
- InputStream stream = EnvironmentHelper.PropertiesToInputStream(props);
manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
Logger logger = new MockLogger("testReadConfigurationInputStream_root.foo", null);
@@ -946,69 +962,99 @@
// }
// after read stream
+ InputStream stream = EnvironmentHelper.PropertiesToInputStream(props);
manager.readConfiguration(stream);
+ stream.close();
assertEquals(Level.FINE, root.getLevel());
assertEquals(2, root.getHandlers().length);
assertNull(logger.getLevel());
assertEquals(0, logger.getHandlers().length);
- stream.close();
+ manager.reset();
}
- // public void testAddRemovePropertyChangeListener() throws Exception {
- // MockPropertyChangeListener listener1 = new MockPropertyChangeListener();
- // MockPropertyChangeListener listener2 = new MockPropertyChangeListener();
- // // add same listener1 two times
- // mockManager.addPropertyChangeListener(listener1);
- // mockManager.addPropertyChangeListener(listener1);
- // mockManager.addPropertyChangeListener(listener2);
- //
- // assertNull(listener1.getEvent());
- // assertNull(listener2.getEvent());
- // mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
- // // if (!hasConfigClass) {
- // assertNotNull(listener1.getEvent());
- // assertNotNull(listener2.getEvent());
- // // }
- //
- // listener1.reset();
- // listener2.reset();
- //
- // // remove listener1, no effect
- // mockManager.removePropertyChangeListener(listener1);
- // mockManager.readConfiguration(EnvironmentHelper
- // .PropertiesToInputStream(props));
- // assertNotNull(listener1.getEvent());
- // assertNotNull(listener2.getEvent());
- // listener1.reset();
- // listener2.reset();
- //
- // // remove listener1 again and it works
- // mockManager.removePropertyChangeListener(listener1);
- // mockManager.readConfiguration(EnvironmentHelper
- // .PropertiesToInputStream(props));
- // assertNull(listener1.getEvent());
- // assertNotNull(listener2.getEvent());
- // listener2.reset();
- //
- // // reset don't produce event
- // mockManager.reset();
- // assertNull(listener2.getEvent());
- //
- // mockManager.removePropertyChangeListener(listener2);
- // mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
- // assertNull(listener1.getEvent());
- // assertNull(listener2.getEvent());
- // }
- //
- // public void testAddRemovePropertyChangeListener_null() {
- // // seems nothing happened
- // try{
- // mockManager.addPropertyChangeListener(null);
- // fail("Should throw NPE");
- // }catch(NullPointerException e){
- // }
- // mockManager.removePropertyChangeListener(null);
- // }
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addPropertyChangeListener",
+ args = {java.beans.PropertyChangeListener.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "removePropertyChangeListener",
+ args = {java.beans.PropertyChangeListener.class}
+ )
+ })
+ public void testAddRemovePropertyChangeListener() throws Exception {
+ MockPropertyChangeListener listener1 = new MockPropertyChangeListener();
+ MockPropertyChangeListener listener2 = new MockPropertyChangeListener();
+ // add same listener1 two times
+ mockManager.addPropertyChangeListener(listener1);
+ mockManager.addPropertyChangeListener(listener1);
+ mockManager.addPropertyChangeListener(listener2);
+
+ assertNull(listener1.getEvent());
+ assertNull(listener2.getEvent());
+ mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ // if (!hasConfigClass) {
+ assertNotNull(listener1.getEvent());
+ assertNotNull(listener2.getEvent());
+ // }
+
+ listener1.reset();
+ listener2.reset();
+
+ // remove listener1, no effect
+ mockManager.removePropertyChangeListener(listener1);
+ mockManager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ assertNotNull(listener1.getEvent());
+ assertNotNull(listener2.getEvent());
+ listener1.reset();
+ listener2.reset();
+
+ // remove listener1 again and it works
+ mockManager.removePropertyChangeListener(listener1);
+ mockManager.readConfiguration(EnvironmentHelper
+ .PropertiesToInputStream(props));
+ assertNull(listener1.getEvent());
+ assertNotNull(listener2.getEvent());
+ listener2.reset();
+
+ // reset don't produce event
+ mockManager.reset();
+ assertNull(listener2.getEvent());
+
+ mockManager.removePropertyChangeListener(listener2);
+ mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
+ assertNull(listener1.getEvent());
+ assertNull(listener2.getEvent());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "addPropertyChangeListener",
+ args = {java.beans.PropertyChangeListener.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "removePropertyChangeListener",
+ args = {java.beans.PropertyChangeListener.class}
+ )
+ })
+ public void testAddRemovePropertyChangeListener_null() {
+ // seems nothing happened
+ try{
+ mockManager.addPropertyChangeListener(null);
+ fail("Should throw NPE");
+ }catch(NullPointerException e){
+ }
+ mockManager.removePropertyChangeListener(null);
+ }
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
@@ -1126,6 +1172,7 @@
assertEquals(Level.FINE, manager.getLogger("").getLevel());
} finally {
System.setErr(err);
+ manager.reset();
}
}
@@ -1219,6 +1266,7 @@
} catch (Exception e) {
e.printStackTrace();
}
+ manager.reset();
}
}
@@ -1250,6 +1298,7 @@
} catch (Exception e) {
e.printStackTrace();
}
+ manager.reset();
}
}
@@ -1295,6 +1344,7 @@
} catch (Exception e) {
e.printStackTrace();
}
+ manager.reset();
}
}
@@ -1397,24 +1447,24 @@
}
}
- // public static class MockPropertyChangeListener implements
- // IPropertyChangeListener {
- //
- // IPropertyChangeEvent event = null;
- //
- // public void propertyChange(IPropertyChangeEvent event) {
- // this.event = event;
- // }
- //
- // public IPropertyChangeEvent getEvent() {
- // return event;
- // }
- //
- // public void reset() {
- // event = null;
- // }
- //
- // }
+ public static class MockPropertyChangeListener implements
+ PropertyChangeListener {
+
+ PropertyChangeEvent event = null;
+
+ public void propertyChange(PropertyChangeEvent event) {
+ this.event = event;
+ }
+
+ public PropertyChangeEvent getEvent() {
+ return event;
+ }
+
+ public void reset() {
+ event = null;
+ }
+
+ }
public static class MockSecurityManagerLogPermission extends SecurityManager {
diff --git a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java
index 046a7a8..ca288dd 100644
--- a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java
+++ b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java
@@ -17,7 +17,7 @@
package org.apache.harmony.logging.tests.java.util.logging;
-import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -91,15 +91,6 @@
super.tearDown();
}
- /**
- * Constructor for LoggerTest.
- *
- * @param arg0
- */
- public LoggerTest(String arg0) {
- super(arg0);
- }
-
/*
* Test the global logger
*/
@@ -442,8 +433,10 @@
method = "getLogger",
args = {java.lang.String.class}
)
- @AndroidOnly("getResourceBundle and getResourceBundleName methods return " +
- "null on RI for Logger with empty string name.")
+ @BrokenTest("This fails on RI and Android." +
+ "getResourceBundle and getResourceBundleName methods return " +
+ "null on RI for Logger with empty string name. On the RI " +
+ "getHandlers() returns a non empty array.")
public void testGetLogger_Empty() {
assertNotNull(LogManager.getLogManager().getLogger(""));
Logger log = Logger.getLogger("");
diff --git a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java
index d8ee15f..917a898 100644
--- a/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java
+++ b/libcore/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java
@@ -17,6 +17,7 @@
package org.apache.harmony.logging.tests.java.util.logging;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -263,6 +264,8 @@
args = {}
)
})
+ @AndroidOnly("This test fails on RI. Output doesn't contain " +
+ "<message/>.")
public void testInvalidParameter() {
formatter.getTail(null);
try {
diff --git a/libcore/luni-kernel/src/main/java/java/lang/Class.java b/libcore/luni-kernel/src/main/java/java/lang/Class.java
index dc5f1e1..70ae3c1 100644
--- a/libcore/luni-kernel/src/main/java/java/lang/Class.java
+++ b/libcore/luni-kernel/src/main/java/java/lang/Class.java
@@ -653,7 +653,21 @@
}
}
- throw new NoSuchMethodException(getSimpleName());
+ // BEGIN android-changed
+ StringBuilder sb = new StringBuilder();
+ sb.append(getSimpleName());
+ sb.append('(');
+ boolean first = true;
+ for (Class<?> p : parameterTypes) {
+ if (!first) {
+ sb.append(',');
+ }
+ first = false;
+ sb.append(p.getSimpleName());
+ }
+ sb.append(')');
+ throw new NoSuchMethodException(sb.toString());
+ // END android-changed
}
/**
diff --git a/libcore/luni-kernel/src/main/java/java/lang/ClassLoader.java b/libcore/luni-kernel/src/main/java/java/lang/ClassLoader.java
index 95bfd41..822fade 100644
--- a/libcore/luni-kernel/src/main/java/java/lang/ClassLoader.java
+++ b/libcore/luni-kernel/src/main/java/java/lang/ClassLoader.java
@@ -14,6 +14,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package java.lang;
@@ -69,7 +84,7 @@
*/
static private class SystemClassLoader {
public static ClassLoader loader = ClassLoader.createSystemClassLoader();
- };
+ }
/**
* The parent ClassLoader.
@@ -192,12 +207,7 @@
* @since Android 1.0
*/
protected ClassLoader() {
- SecurityManager smgr = System.getSecurityManager();
- if (smgr != null) {
- smgr.checkCreateClassLoader();
- }
-
- parent = getSystemClassLoader();
+ this(getSystemClassLoader(), false);
}
/**
@@ -213,15 +223,22 @@
* @since Android 1.0
*/
protected ClassLoader(ClassLoader parentLoader) {
+ this(parentLoader, false);
+ }
+
+ /*
+ * constructor for the BootClassLoader which needs parent to be null.
+ */
+ ClassLoader(ClassLoader parentLoader, boolean nullAllowed) {
SecurityManager smgr = System.getSecurityManager();
if (smgr != null) {
smgr.checkCreateClassLoader();
}
-
- // TODO Shouldn't we check for null values here?
- // if (parent == null) {
- // throw new NullPointerException();
- // }
+
+ if (parentLoader == null && !nullAllowed) {
+ throw new NullPointerException(
+ "Parent ClassLoader may not be null");
+ }
parent = parentLoader;
}
@@ -437,9 +454,7 @@
public URL getResource(String resName) {
URL resource = null;
- if (parent != null) {
- resource = parent.getResource(resName);
- }
+ resource = parent.getResource(resName);
if (resource == null) {
resource = findResource(resName);
@@ -464,12 +479,8 @@
*/
@SuppressWarnings("unchecked")
public Enumeration<URL> getResources(String resName) throws IOException {
- Enumeration first = EmptyEnumeration.getInstance();
- if (parent != null) {
- first = parent.getResources(resName);
- }
-
+ Enumeration first = parent.getResources(resName);
Enumeration second = findResources(resName);
return new TwoEnumerationsInOne(first, second);
@@ -553,9 +564,7 @@
if (clazz == null) {
try {
- if (parent != null) {
- clazz = parent.loadClass(className, false);
- }
+ clazz = parent.loadClass(className, false);
} catch (ClassNotFoundException e) {
// Don't want to see this.
}
@@ -726,7 +735,9 @@
protected Package[] getPackages() {
synchronized (packages) {
Collection<Package> col = packages.values();
- return (Package[])col.toArray();
+ Package[] result = new Package[col.size()];
+ col.toArray(result);
+ return result;
}
}
@@ -1038,7 +1049,7 @@
}
public BootClassLoader() {
- super(null);
+ super(null, true);
}
@Override
@@ -1099,6 +1110,27 @@
return null;
}
+ @Override
+ public URL getResource(String resName) {
+ return findResource(resName);
+ }
+
+ @Override
+ protected Class<?> loadClass(String className, boolean resolve)
+ throws ClassNotFoundException {
+ Class<?> clazz = findLoadedClass(className);
+
+ if (clazz == null) {
+ clazz = findClass(className);
+ }
+
+ return clazz;
+ }
+
+ @Override
+ public Enumeration<URL> getResources(String resName) throws IOException {
+ return findResources(resName);
+ }
}
/**
diff --git a/libcore/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java b/libcore/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java
index 4381877..0178276 100644
--- a/libcore/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java
+++ b/libcore/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java
@@ -55,7 +55,6 @@
* @see Method
* @see ReflectPermission
*
- * @since 1.2
* @since Android 1.0
*/
public class AccessibleObject implements AnnotatedElement {
diff --git a/libcore/luni-kernel/src/main/java/java/lang/reflect/Constructor.java b/libcore/luni-kernel/src/main/java/java/lang/reflect/Constructor.java
index 54fac6a..c6927eb 100644
--- a/libcore/luni-kernel/src/main/java/java/lang/reflect/Constructor.java
+++ b/libcore/luni-kernel/src/main/java/java/lang/reflect/Constructor.java
@@ -133,7 +133,6 @@
*
* @return the string representation of the constructor's declaration
*
- * @since 1.5
* @since Android 1.0
*/
public String toGenericString() {
@@ -187,7 +186,6 @@
* if any parameter type points to a type that cannot be
* instantiated for some reason
*
- * @since 1.5
* @since Android 1.0
*/
public Type[] getGenericParameterTypes() {
@@ -209,7 +207,6 @@
* @throws MalformedParameterizedTypeException
* if any exception type points to a type that cannot be
* instantiated for some reason
- * @since 1.5
* @since Android 1.0
*/
public Type[] getGenericExceptionTypes() {
@@ -232,7 +229,6 @@
*
* @return an array of arrays of {@code Annotation} instances
*
- * @since 1.5
* @since Android 1.0
*/
public Annotation[][] getParameterAnnotations() {
@@ -253,7 +249,6 @@
* @return {@code true} if a vararg is declare, otherwise
* {@code false}
*
- * @since 1.5
* @since Android 1.0
*/
public boolean isVarArgs() {
diff --git a/libcore/luni-kernel/src/main/java/java/lang/reflect/Field.java b/libcore/luni-kernel/src/main/java/java/lang/reflect/Field.java
index a6c930b..0ea16df 100644
--- a/libcore/luni-kernel/src/main/java/java/lang/reflect/Field.java
+++ b/libcore/luni-kernel/src/main/java/java/lang/reflect/Field.java
@@ -132,7 +132,6 @@
* Indicates whether or not this field is synthetic.
*
* @return {@code true} if this field is synthetic, {@code false} otherwise
- * @since 1.5
* @since Android 1.0
*/
public boolean isSynthetic() {
@@ -145,7 +144,6 @@
* generic type.
*
* @return the string representation of this field
- * @since 1.5
* @since Android 1.0
*/
public String toGenericString() {
@@ -168,7 +166,6 @@
*
* @return {@code true} if this field is an enumeration constant, {@code
* false} otherwise
- * @since 1.5
* @since Android 1.0
*/
public boolean isEnumConstant() {
@@ -187,7 +184,6 @@
* @throws MalformedParameterizedTypeException
* if the generic type points to a type that cannot be
* instantiated for some reason
- * @since 1.5
* @since Android 1.0
*/
public Type getGenericType() {
diff --git a/libcore/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java b/libcore/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java
index 4b3f409..3791191 100644
--- a/libcore/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java
+++ b/libcore/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java
@@ -16,16 +16,14 @@
package tests.api.org.apache.harmony.kernel.dalvik;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
+import java.lang.reflect.Field;
import junit.framework.Assert;
import junit.framework.TestCase;
-
import sun.misc.Unsafe;
-
-import java.lang.reflect.Field;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
/**
* Tests for the <code>park()</code> functionality of {@link Unsafe}.
@@ -33,6 +31,7 @@
@TestTargetClass(Unsafe.class)
public class ThreadsTest extends TestCase {
private static Unsafe UNSAFE = null;
+ private static RuntimeException INITIALIZEFAILED = null;
static {
/*
@@ -47,9 +46,9 @@
UNSAFE = (Unsafe) field.get(null);
} catch (NoSuchFieldException ex) {
- throw new RuntimeException(ex);
+ INITIALIZEFAILED = new RuntimeException(ex);
} catch (IllegalAccessException ex) {
- throw new RuntimeException(ex);
+ INITIALIZEFAILED = new RuntimeException(ex);
}
}
@@ -290,4 +289,10 @@
UNSAFE.unpark(thread);
}
}
+
+ @Override
+ protected void setUp() throws Exception {
+ if (INITIALIZEFAILED != null)
+ throw INITIALIZEFAILED;
+ }
}
diff --git a/libcore/luni/src/main/java/java/io/BufferedInputStream.java b/libcore/luni/src/main/java/java/io/BufferedInputStream.java
index 1720366..0b9afc3 100644
--- a/libcore/luni/src/main/java/java/io/BufferedInputStream.java
+++ b/libcore/luni/src/main/java/java/io/BufferedInputStream.java
@@ -108,7 +108,7 @@
Logger.global.info(
"Default buffer size used in BufferedInputStream " +
"constructor. It would be " +
- "better to be explicit if a 8k buffer is required.");
+ "better to be explicit if an 8k buffer is required.");
// END android-added
}
diff --git a/libcore/luni/src/main/java/java/io/BufferedOutputStream.java b/libcore/luni/src/main/java/java/io/BufferedOutputStream.java
index 55419d1..835d13f 100644
--- a/libcore/luni/src/main/java/java/io/BufferedOutputStream.java
+++ b/libcore/luni/src/main/java/java/io/BufferedOutputStream.java
@@ -80,7 +80,7 @@
Logger.global.info(
"Default buffer size used in BufferedOutputStream " +
"constructor. It would be " +
- "better to be explicit if a 8k buffer is required.");
+ "better to be explicit if an 8k buffer is required.");
// END android-added
}
diff --git a/libcore/luni/src/main/java/java/io/BufferedReader.java b/libcore/luni/src/main/java/java/io/BufferedReader.java
index c490b89..e82e538 100644
--- a/libcore/luni/src/main/java/java/io/BufferedReader.java
+++ b/libcore/luni/src/main/java/java/io/BufferedReader.java
@@ -80,7 +80,7 @@
Logger.global.info(
"Default buffer size used in BufferedReader " +
"constructor. It would be " +
- "better to be explicit if a 8k-char buffer is required.");
+ "better to be explicit if an 8k-char buffer is required.");
// END android-added
}
diff --git a/libcore/luni/src/main/java/java/io/BufferedWriter.java b/libcore/luni/src/main/java/java/io/BufferedWriter.java
index 66bfcc9..761b9c5 100644
--- a/libcore/luni/src/main/java/java/io/BufferedWriter.java
+++ b/libcore/luni/src/main/java/java/io/BufferedWriter.java
@@ -80,7 +80,7 @@
Logger.global.info(
"Default buffer size used in BufferedWriter " +
"constructor. It would be " +
- "better to be explicit if a 8k-char buffer is required.");
+ "better to be explicit if an 8k-char buffer is required.");
// END android-added
}
diff --git a/libcore/luni/src/main/java/java/lang/VMThread.java b/libcore/luni/src/main/java/java/lang/VMThread.java
index 8e789cb..6d7bef0 100644
--- a/libcore/luni/src/main/java/java/lang/VMThread.java
+++ b/libcore/luni/src/main/java/java/lang/VMThread.java
@@ -16,6 +16,9 @@
package java.lang;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
class VMThread
{
Thread thread;
@@ -47,20 +50,25 @@
VMThread.create(thread, stacksize);
}
+ private static final String UNSUPPORTED_THREAD_METHOD
+ = "Deprecated Thread methods are not supported.";
+
/**
* Suspends the Thread.
*/
+ @SuppressWarnings("ThrowableInstanceNeverThrown")
void suspend() {
- throw new UnsupportedOperationException(
- "Deprecated Thread methods are not supported.");
+ Logger.global.log(Level.SEVERE, UNSUPPORTED_THREAD_METHOD,
+ new UnsupportedOperationException());
}
/**
* Resumes the Thread, assuming it is suspended.
*/
+ @SuppressWarnings("ThrowableInstanceNeverThrown")
void resume() {
- throw new UnsupportedOperationException(
- "Deprecated Thread methods are not supported.");
+ Logger.global.log(Level.SEVERE, UNSUPPORTED_THREAD_METHOD,
+ new UnsupportedOperationException());
}
/**
@@ -72,9 +80,10 @@
/**
* Stops the Thread, passing it a Throwable (which might be ThreadDeath).
*/
+ @SuppressWarnings("ThrowableInstanceNeverThrown")
void stop(Throwable throwable) {
- throw new UnsupportedOperationException(
- "Deprecated Thread methods are not supported.");
+ Logger.global.log(Level.SEVERE, UNSUPPORTED_THREAD_METHOD,
+ new UnsupportedOperationException());
}
native void setPriority(int newPriority);
diff --git a/libcore/luni/src/main/java/java/lang/reflect/AnnotatedElement.java b/libcore/luni/src/main/java/java/lang/reflect/AnnotatedElement.java
index 23093c5..1f081b9 100644
--- a/libcore/luni/src/main/java/java/lang/reflect/AnnotatedElement.java
+++ b/libcore/luni/src/main/java/java/lang/reflect/AnnotatedElement.java
@@ -22,7 +22,6 @@
/**
* This interface provides reflective access to annotation information.
*
- * @since 1.5
* @since Android 1.0
*/
public interface AnnotatedElement {
diff --git a/libcore/luni/src/main/java/java/lang/reflect/GenericArrayType.java b/libcore/luni/src/main/java/java/lang/reflect/GenericArrayType.java
index d47d7f2..81fb39f 100644
--- a/libcore/luni/src/main/java/java/lang/reflect/GenericArrayType.java
+++ b/libcore/luni/src/main/java/java/lang/reflect/GenericArrayType.java
@@ -21,7 +21,6 @@
* This interface represents an array type with a component type that is either
* a parameterized type or a type variable.
*
- * @since 1.5
* @since Android 1.0
*/
public interface GenericArrayType extends Type {
diff --git a/libcore/luni/src/main/java/java/lang/reflect/GenericDeclaration.java b/libcore/luni/src/main/java/java/lang/reflect/GenericDeclaration.java
index 6f2dcb3..c7cedcf 100644
--- a/libcore/luni/src/main/java/java/lang/reflect/GenericDeclaration.java
+++ b/libcore/luni/src/main/java/java/lang/reflect/GenericDeclaration.java
@@ -19,7 +19,6 @@
/**
* Common interface for language constructs that declare type parameters.
*
- * @since 1.5
* @since Android 1.0
*/
public interface GenericDeclaration {
diff --git a/libcore/luni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java b/libcore/luni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
index 5691565..bb901fd 100644
--- a/libcore/luni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
+++ b/libcore/luni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
@@ -21,7 +21,6 @@
* Indicates that a malformed signature has been encountered via a reflective
* method.
*
- * @since 1.5
* @since Android 1.0
*/
public class GenericSignatureFormatError extends ClassFormatError {
diff --git a/libcore/luni/src/main/java/java/lang/reflect/MalformedParameterizedTypeException.java b/libcore/luni/src/main/java/java/lang/reflect/MalformedParameterizedTypeException.java
index d8f8096..7dfbc6f 100644
--- a/libcore/luni/src/main/java/java/lang/reflect/MalformedParameterizedTypeException.java
+++ b/libcore/luni/src/main/java/java/lang/reflect/MalformedParameterizedTypeException.java
@@ -21,7 +21,6 @@
* Indicates that a malformed parameterized type has been encountered by a
* reflective method.
*
- * @since 1.5
* @since Android 1.0
*/
public class MalformedParameterizedTypeException extends RuntimeException {
diff --git a/libcore/luni/src/main/java/java/lang/reflect/ParameterizedType.java b/libcore/luni/src/main/java/java/lang/reflect/ParameterizedType.java
index 349464a..3d03921 100644
--- a/libcore/luni/src/main/java/java/lang/reflect/ParameterizedType.java
+++ b/libcore/luni/src/main/java/java/lang/reflect/ParameterizedType.java
@@ -21,7 +21,6 @@
* This interface represents a parameterized type such as {@code
* 'Set<String>'}.
*
- * @since 1.5
* @since Android 1.0
*/
public interface ParameterizedType extends Type {
diff --git a/libcore/luni/src/main/java/java/lang/reflect/Type.java b/libcore/luni/src/main/java/java/lang/reflect/Type.java
index f0c6142..abd4978 100644
--- a/libcore/luni/src/main/java/java/lang/reflect/Type.java
+++ b/libcore/luni/src/main/java/java/lang/reflect/Type.java
@@ -19,7 +19,6 @@
/**
* Common interface implemented by all Java types.
*
- * @since 1.5
* @since Android 1.0
*/
public interface Type {
diff --git a/libcore/luni/src/main/java/java/lang/reflect/TypeVariable.java b/libcore/luni/src/main/java/java/lang/reflect/TypeVariable.java
index aef7ac9..99aca77 100644
--- a/libcore/luni/src/main/java/java/lang/reflect/TypeVariable.java
+++ b/libcore/luni/src/main/java/java/lang/reflect/TypeVariable.java
@@ -25,7 +25,6 @@
* @param <D>
* the generic declaration that declares this type variable
*
- * @since 1.5
* @since Android 1.0
*/
public interface TypeVariable<D extends GenericDeclaration> extends Type {
diff --git a/libcore/luni/src/main/java/java/lang/reflect/WildcardType.java b/libcore/luni/src/main/java/java/lang/reflect/WildcardType.java
index 2b913d0..72a022d 100644
--- a/libcore/luni/src/main/java/java/lang/reflect/WildcardType.java
+++ b/libcore/luni/src/main/java/java/lang/reflect/WildcardType.java
@@ -23,7 +23,6 @@
* multiple upper bounded wildcard {@code '? extends Closeable & Flushable'} or
* the lower bounded wildcard {@code '? super OutputStream'}.
*
- * @since 1.5
* @since Android 1.0
*/
public interface WildcardType extends Type {
diff --git a/libcore/luni/src/main/java/java/net/InetAddress.java b/libcore/luni/src/main/java/java/net/InetAddress.java
index d6b6978..72c7669 100644
--- a/libcore/luni/src/main/java/java/net/InetAddress.java
+++ b/libcore/luni/src/main/java/java/net/InetAddress.java
@@ -160,9 +160,6 @@
*/
@Override
public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
// BEGIN android-changed
if (!(obj instanceof InetAddress)) {
return false;
@@ -217,10 +214,11 @@
// Added change taken from newer harmony concerning zero length hostname.
// Added special handling for localhost, since it doesn't work properly.
// TODO Get rid of this later...
- if (host == null || 0 == host.length() ||
+ if (host == null || 0 == host.length() ||
"localhost".equalsIgnoreCase(host)) {
- return new InetAddress[] { preferIPv6Addresses() ? Inet6Address.LOOPBACK
- : LOOPBACK };
+ return new InetAddress[] { preferIPv6Addresses()
+ ? Inet6Address.LOOPBACK
+ : LOOPBACK };
}
// END android-changed
@@ -229,13 +227,28 @@
if (security != null) {
security.checkConnect(host, -1);
}
- if (Socket.preferIPv4Stack()) {
- return getAliasesByNameImpl(host);
+ // BEGIN android-changed
+ byte[][] rawAddresses = getallbyname(host,
+ Socket.preferIPv4Stack());
+ InetAddress[] returnedAddresses = new
+ InetAddress[rawAddresses.length];
+ for (int i = 0; i < rawAddresses.length; i++) {
+ byte[] rawAddress = rawAddresses[i];
+ if (rawAddress.length == 16) {
+ returnedAddresses[i] = new Inet6Address(rawAddress, host);
+ } else if (rawAddress.length == 4) {
+ returnedAddresses[i] = new Inet4Address(rawAddress, host);
+ } else {
+ // Cannot happen, because the underlying code only returns
+ // addresses that are 4 or 16 bytes long.
+ throw new AssertionError("Impossible address length " +
+ rawAddress.length);
+ }
}
// ok we may have to re-order to make sure the
// preferIPv6Addresses is respected
- InetAddress[] returnedAddresses = getAliasesByNameImpl(host);
+ // END android-changed
InetAddress[] orderedAddresses = null;
if (returnedAddresses != null) {
orderedAddresses = new InetAddress[returnedAddresses.length];
@@ -513,63 +526,26 @@
return anInetAddress;
}
- // BEGIN android-changed
+ // BEGIN android-added
/**
* Multiplies value by 1 billion.
*/
private static long secondsToNanos(int ttl) {
return (long) ttl * 1000000000;
}
- // END android-changed
+ // END android-added
- /**
- * Query the IP stack for aliases for the host. The host is in string name
- * form. If the host does not have aliases (only multihomed hosts do),
- * return an array with a single {@code InetAddress} constructed from the
- * host name & address.
- *
- * @param name
- * the host name to lookup.
- * @throws UnknownHostException
- * if an error occurs during lookup.
- */
- // BEGIN android-changed
+ // BEGIN android-deleted
// static native InetAddress[] getAliasesByNameImpl(String name)
// throws UnknownHostException;
- static InetAddress[] getAliasesByNameImpl(String name)
- throws UnknownHostException {
- // TODO Probably a bit inefficient. Provide native later.
- InetAddress addr = getHostByNameImpl(name, false);
+ // END android-deleted
- String[] aliases = getaliasesbyname(name);
-
- if (aliases.length == 0) {
- // If no alias addresses where found (only multihosts do have them)
- // return the address with the name
- byte[] address = addr.getAddress();
- InetAddress[] result = new InetAddress[1];
- result[0] = (address.length == 4 ?
- new Inet4Address(address, name) :
- new Inet6Address(address, name));
- return result;
- }
-
- InetAddress[] result = new InetAddress[aliases.length];
- for (int i = 0; i < result.length; i++) {
- byte[] address = addr.getAddress();
- result[i] = (address.length == 4 ?
- new Inet4Address(address, aliases[i]) :
- new Inet6Address(address, aliases[i]));
- }
-
- return result;
- }
-
+ // BEGIN android-changed
/**
- * Wrapper for libc call. It is assumed to be thread-safe, which is
- * in fact the case on Android.
+ * Resolves a host name to its IP addresses. Thread safe.
*/
- private static native String[] getaliasesbyname(String name);
+ private static native byte[][] getallbyname(String name,
+ boolean preferIPv4Stack);
// END android-changed
/**
@@ -585,23 +561,13 @@
// throws UnknownHostException;
static InetAddress getHostByAddrImpl(byte[] addr)
throws UnknownHostException {
- // TODO Probably inefficient. Provide native later.
- String ipaddr = (addr[0] & 0xff) + "." + (addr[1] & 0xff) + "."
- + (addr[2] & 0xff) + "." + (addr[3] & 0xff);
- String host = gethostbyaddr(ipaddr);
-
- if (host == null) {
- throw new UnknownHostException(ipaddr);
- }
-
- return new InetAddress(addr, host);
+ return new InetAddress(addr, gethostbyaddr(addr));
}
/**
- * Wrapper for libc call. It is assumed to be thread-safe, which is
- * in fact the case on Android.
+ * Resolves an IP address to a hostname. Thread safe.
*/
- private static native String gethostbyaddr(String addr);
+ private static native String gethostbyaddr(byte[] addr);
// END android-changed
static int inetAddr(String host) throws UnknownHostException {
@@ -615,7 +581,8 @@
* exception, so this value should not be used as an argument. See also
* inetAddr(String).
*/
-// static native int inetAddrImpl(String host) throws UnknownHostException;
+ // BEGIN android-changed
+ // static native int inetAddrImpl(String host) throws UnknownHostException;
static int inetAddrImpl(String host) throws UnknownHostException {
// TODO Probably not exactly what we want, and also inefficient. Provide native later.
try {
@@ -631,12 +598,14 @@
throw new UnknownHostException(host);
}
}
+ // END android-changed
/**
* Convert a binary address into a string containing an Ipv4 Internet
* Protocol dotted address.
*/
-// static native String inetNtoaImpl(int hipAddr);
+ // BEGIN android-changed
+ // static native String inetNtoaImpl(int hipAddr);
static String inetNtoaImpl(int hipAddr) {
// TODO Inefficient and probably wrong. Provide proper (native?) implementation later.
int a = (hipAddr >> 24) & 0xFF;
@@ -646,6 +615,7 @@
return "" + a + "." + b + "." + c + "." + d;
}
+ // END android-changed
/**
* Query the IP stack for the host address. The host is in string name form.
@@ -664,35 +634,22 @@
static InetAddress getHostByNameImpl(String name,
boolean preferIPv6Address) throws UnknownHostException {
// TODO Mapped Harmony to Android native. Get rid of indirection later.
- return new InetAddress(gethostbyname(name, preferIPv6Address), name);
+ return getAllByName(name)[0];
}
-
- /**
- * Wrapper for libc call. It is assumed to be thread-safe, which is
- * in fact the case on Android. Either returns a raw address or throws
- * UnknownHostException.
- */
- private native static byte[] gethostbyname(String host, boolean preferIPv6Addresses);
// END android-changed
/**
- * Query the IP stack for the host machine name.
+ * Gets the host name of the system.
*
- * @return String the host machine name
+ * @return String the system hostname
*/
// BEGIN android-changed
- // static native String getHostNameImpl();
static String getHostNameImpl() {
// TODO Mapped Harmony to Android native. Get rid of indirection later.
return gethostname();
}
-
- /**
- * Wrapper for libc call. It is assumed to be thread-safe, which is
- * in fact the case on Android.
- */
- private native static String gethostname();
+ static native String gethostname();
// END android-changed
static String getHostNameInternal(String host) throws UnknownHostException {
@@ -1037,7 +994,7 @@
// if (!reachable) {
reachable = isReachableByTCP(this, null, timeout);
// }
- // END adnroid-changed
+ // END android-changed
} else {
// Not Bind to any address
if (null == netif.addresses) {
diff --git a/libcore/luni/src/main/java/java/net/SocketPermission.java b/libcore/luni/src/main/java/java/net/SocketPermission.java
index 9112590..72d77e7 100644
--- a/libcore/luni/src/main/java/java/net/SocketPermission.java
+++ b/libcore/luni/src/main/java/java/net/SocketPermission.java
@@ -14,6 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+// BEGIN andorid-note
+// This class was copied from a newer version of harmony
+// END andorid-note
package java.net;
@@ -140,7 +143,7 @@
setActions(action);
actions = toCanonicalActionString(action);
// Use host since we are only checking for port presence
- parsePort(host);
+ parsePort(host, hostName);
}
/**
@@ -238,6 +241,7 @@
} else if (action.equals(actionNames[SP_ACCEPT])) {
actionsMask |= SP_ACCEPT;
} else if (action.equals(actionNames[SP_RESOLVE])) {
+ // do nothing
} else {
throw new IllegalArgumentException(Msg.getString("K0048", //$NON-NLS-1$
action));
@@ -297,70 +301,61 @@
public PermissionCollection newPermissionCollection() {
return new SocketPermissionCollection();
}
-
+
/**
- * Parses the port string into the lower and higher bound of the port range.
- *
+ * Parse the port, including the minPort, maxPort
+ * @param hostPort the host[:port] one
+ * @param host the host name we just get
+ * @throws IllegalArgumentException If the port is not a positive number or minPort
+ * is not less than or equal maxPort
*/
- private void parsePort(String hostString) throws IllegalArgumentException {
- int negidx = -1;
- int len = -1;
- int lastIdx = hostString.lastIndexOf(':');
- int idx = hostString.indexOf(':');
- int endOfIPv6Addr = hostString.lastIndexOf(']');
- if ((endOfIPv6Addr == -1) && (idx != lastIdx)) {
- // there are no square braces, but there are more than one ':' which
- // implies an IPv6 address with no port, or an illegal argument
- // check for valid IPv6 address
- if (Inet6Util.isValidIP6Address(hostString)) {
- return;
- }
- // throw an invalid argument exception
- throw new IllegalArgumentException(Msg.getString("K004a")); //$NON-NLS-1$
- }
- // if there is a colon and it occurs after the ']' then there is a port
- // to be parsed
- if ((lastIdx > -1) && (lastIdx > endOfIPv6Addr)) {
- try {
- len = hostString.length();
- // if hostString ends with ":*", such as "localhost:*"
- // the port range should be 0-65535
- if (hostString.endsWith(":*")) { //$NON-NLS-1$
- portMin = 0;
- portMax = 65535;
- return;
- }
- // look for a '-' after the colon
- negidx = hostString.indexOf('-', lastIdx);
- if (negidx == lastIdx + 1) {
- portMax = Integer.parseInt(hostString.substring(
- lastIdx + 2, len));
- } else {
- // A port range was provided
- if (negidx != -1 && (negidx != len - 1)) {
- portMin = Integer.parseInt(hostString.substring(
- lastIdx + 1, negidx));
- portMax = Integer.parseInt(hostString.substring(
- negidx + 1, len));
- } else {
- if (negidx == -1) {
- portMin = Integer.parseInt(hostString.substring(
- lastIdx + 1, len));
- portMax = portMin;
- } else {
- portMin = Integer.parseInt(hostString.substring(
- lastIdx + 1, negidx));
- }
- }
- }
- if (portMax < portMin) {
- throw new IllegalArgumentException(Msg.getString("K0049")); //$NON-NLS-1$
- }
+ private void parsePort(String hostPort, String host) throws IllegalArgumentException {
+ String port = hostPort.substring(host.length());
+ String emptyString = ""; //$NON-NLS-1$
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(Msg.getString("K004a")); //$NON-NLS-1$
- }
- }
+ if (emptyString.equals(port)) {
+ // Not specified
+ portMin = 80;
+ portMax = 80;
+ return;
+ }
+
+ if (":*".equals(port)) {
+ // The port range should be 0-65535
+ portMin = 0;
+ portMax = 65535;
+ return;
+ }
+
+ // Omit ':'
+ port = port.substring(1);
+ int negIdx = port.indexOf('-');
+ String strPortMin = emptyString;
+ String strPortMax = emptyString;
+ if (-1 == negIdx) {
+ // No neg mark, only one number
+ strPortMin = port;
+ strPortMax = port;
+ } else {
+ strPortMin = port.substring(0, negIdx);
+ strPortMax = port.substring(negIdx + 1);
+ if (emptyString.equals(strPortMin)) {
+ strPortMin = "0";
+ }
+ if (emptyString.equals(strPortMax)) {
+ strPortMax = "65535";
+ }
+ }
+ try {
+ portMin = Integer.valueOf(strPortMin).intValue();
+ portMax = Integer.valueOf(strPortMax).intValue();
+
+ if (portMin > portMax) {
+ throw new IllegalArgumentException(Msg.getString("K0049") + " " + port); //$NON-NLS-1$
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(Msg.getString("K004a") + " " + port); //$NON-NLS-1$
+ }
}
/**
@@ -400,13 +395,26 @@
try {
ipString = InetAddress.getHostNameInternal(hostName);
} catch (UnknownHostException e) {
+ // ignore
}
resolved = true;
}
return ipString;
}
+ /**
+ * Get the host part from the host[:port] one.
+ * The host should be
+ * host = (hostname | IPv4address | IPv6reference | IPv6 in full uncompressed form)
+ * The wildcard "*" may be included once in a DNS name host specification. If it is included,
+ * it must be in the leftmost position
+ *
+ * @param host
+ * @return
+ * @throws IllegalArgumentException if the host is invalid.
+ */
private String getHostString(String host) throws IllegalArgumentException {
+ host = host.trim();
int idx = -1;
idx = host.indexOf(':');
isPartialWild = (host.length() > 0 && host.charAt(0) == '*');
@@ -423,22 +431,46 @@
}
int lastIdx = host.lastIndexOf(':');
- if ((idx > -1) && (idx == lastIdx)) {
- host = host.substring(0, idx);
- } else {
- // likely host is or contains an IPv6 address
- if (lastIdx != -1) {
- if (Inet6Util.isValidIP6Address(host)) {
- return host.toLowerCase();
- } else if (Inet6Util.isValidIP6Address(host.substring(0,
- lastIdx))) {
- host = host.substring(0, lastIdx);
- } else {
- throw new IllegalArgumentException(Msg.getString("K004a")); //$NON-NLS-1$
+
+ if (idx == lastIdx) {
+ if (-1 != idx) {
+ // only one colon, should be port
+ host = host.substring(0, idx);
+ }
+ return host.toLowerCase();
+ }
+ // maybe ipv6
+ boolean isFirstBracket = (host.charAt(0) == '[');
+ if (!isFirstBracket) {
+ // No bracket, should be in full form
+ int colonNum = 0;
+ for (int i = 0; i < host.length(); ++i) {
+ if (host.charAt(i) == ':') {
+ colonNum++;
}
}
+ // Get rid of the colon before port
+ if (8 == colonNum) {
+ host = host.substring(0, lastIdx);
+ }
+ if (Inet6Util.isIP6AddressInFullForm(host)) {
+ return host.toLowerCase();
+ }
+ throw new IllegalArgumentException(Msg.getString("K004a") + " "
+ + host);
}
- return host.toLowerCase();
+ // forward bracket found
+ int bbracketIdx = host.indexOf(']');
+ if (-1 == bbracketIdx) {
+ // no back bracket found, wrong
+ throw new IllegalArgumentException(Msg.getString("K004a") + " "
+ + host);
+ }
+ host = host.substring(0, bbracketIdx + 1);
+ if (Inet6Util.isValidIP6Address(host)) {
+ return host.toLowerCase();
+ }
+ throw new IllegalArgumentException(Msg.getString("K004a") + " " + host);
}
/**
@@ -474,7 +506,7 @@
portMax = HIGHEST_PORT;
actionsMask = SP_RESOLVE;
hostName = getHostString(getName());
- parsePort(getName());
+ parsePort(getName(), hostName);
setActions(actions);
}
}
diff --git a/libcore/luni/src/main/java/java/net/URLConnection.java b/libcore/luni/src/main/java/java/net/URLConnection.java
index ce92aad..6c1a192 100644
--- a/libcore/luni/src/main/java/java/net/URLConnection.java
+++ b/libcore/luni/src/main/java/java/net/URLConnection.java
@@ -840,9 +840,12 @@
* @since Android 1.0
*/
public void setDefaultUseCaches(boolean newValue) {
- if (connected) {
- throw new IllegalAccessError(Msg.getString("K0037")); //$NON-NLS-1$
- }
+ // BEGIN android-removed
+ // Setting the default doesn't concern the current connection.
+ // if (connected) {
+ // throw new IllegalAccessError(Msg.getString("K0037")); //$NON-NLS-1$
+ // }
+ // END android-removed
defaultUseCaches = newValue;
}
diff --git a/libcore/luni/src/main/java/java/util/ArrayList.java b/libcore/luni/src/main/java/java/util/ArrayList.java
index 5ea316a..3bae372 100644
--- a/libcore/luni/src/main/java/java/util/ArrayList.java
+++ b/libcore/luni/src/main/java/java/util/ArrayList.java
@@ -112,7 +112,7 @@
* @param object
* the object to add.
* @throws IndexOutOfBoundsException
- * when {@code location < 0 || >= size()}
+ * when {@code location < 0 || > size()}
* @since Android 1.0
*/
@Override
diff --git a/libcore/luni/src/main/java/java/util/Arrays.java b/libcore/luni/src/main/java/java/util/Arrays.java
index d8aa6ee..6af24b0 100644
--- a/libcore/luni/src/main/java/java/util/Arrays.java
+++ b/libcore/luni/src/main/java/java/util/Arrays.java
@@ -27,9 +27,6 @@
*/
public class Arrays {
- /* Specifies when to switch to insertion sort */
- private static final int SIMPLE_LENGTH = 7;
-
private static class ArrayList<E> extends AbstractList<E> implements
List<E>, Serializable, RandomAccess {
@@ -131,7 +128,7 @@
}
@Override
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked", "SuspiciousSystemArraycopy"})
public <T> T[] toArray(T[] contents) {
int size = size();
if (size > contents.length) {
@@ -2373,6 +2370,41 @@
}
}
+// BEGIN android-changed
+
+ /*
+ * <p>If this platform has an optimizing VM, check whether ComparableTimSort
+ * offers any performance benefit over TimSort in conjunction with a
+ * comparator that returns:
+ * {@code ((Comparable)first).compareTo(Second)}.
+ * If not, you are better off deleting ComparableTimSort to eliminate the
+ * code duplication. In other words, the commented out code below
+ * is the preferable implementation for sorting arrays of comparbles if it
+ * offers sufficient performance.
+ */
+
+// /**
+// * A comparator that implements the natural order of a group of
+// * mutually comparable elements. Using this comparator saves us
+// * from duplicating most of the code in this file (one version for
+// * commparables, one for explicit comparators).
+// */
+// private static final Comparator<Object> NATURAL_ORDER =
+// new Comparator<Object>() {
+// @SuppressWarnings("unchecked")
+// public int compare(Object first, Object second) {
+// return ((Comparable<Object>)first).compareTo(second);
+// }
+// };
+//
+// public static void sort(Object[] a) {
+// sort(a, 0, a.length, NATURAL_ORDER);
+// }
+//
+// public static void sort(Object[] a, int fromIndex, int toIndex) {
+// sort(a, fromIndex, toIndex, NATURAL_ORDER);
+// }
+
/**
* Sorts the specified array in ascending natural order.
*
@@ -2385,7 +2417,7 @@
* @since Android 1.0
*/
public static void sort(Object[] array) {
- sort(0, array.length, array);
+ ComparableTimSort.sort(array);
}
/**
@@ -2410,507 +2442,7 @@
* @since Android 1.0
*/
public static void sort(Object[] array, int start, int end) {
- if (array == null) {
- throw new NullPointerException();
- }
- checkBounds(array.length, start, end);
- sort(start, end, array);
- }
-
- private static void sort(int fromIndex, int toIndex, Object[] array) {
- int length = toIndex - fromIndex;
- if (length <= 0) {
- return;
- }
- if (array instanceof String[]) {
- stableStringSort((String[]) array, fromIndex, toIndex);
- } else {
- Object[] out = new Object[toIndex];
- System.arraycopy(array, fromIndex, out, fromIndex, length);
- mergeSort(out, array, fromIndex, toIndex);
- }
- }
-
- /**
- * Swaps the elements at the specified positions in the specified array.
- *
- * @param a -
- * the index of one element to be swapped.
- * @param b -
- * the index of the other element to be swapped.
- * @param arr -
- * the array in which to swap elements.
- */
- private static void swap(int a, int b, Object[] arr) {
- Object tmp = arr[a];
- arr[a] = arr[b];
- arr[b] = tmp;
- }
-
- /**
- * Sorts the specified range of the specified array of {@code Objects}. The range to
- * be sorted extends from index {@code fromIndex}, inclusive, to index {@code toIndex},
- * exclusive. (If {@code fromIndex==toIndex}, the range to be sorted is empty.) This
- * sort is guaranteed to be stable: equal elements will not be reordered as
- * a result of the sort.
- *
- * The sorting algorithm is a mergesort with exponential search (in which
- * the merge is performed by exponential search). This algorithm offers
- * guaranteed {@code n*log(n)} performance and in average case faster then any
- * mergesort in which the merge is performed by linear search.
- *
- * @param in -
- * the array for sorting.
- * @param out -
- * the result, sorted array.
- * @param fromIndex -
- * the index of the first element (inclusive) to be sorted.
- * @param toIndex -
- * the index of the last element (exclusive) to be sorted.
- */
- @SuppressWarnings("unchecked")
- private static void mergeSort(Object[] in, Object[] out, int fromIndex,
- int toIndex) {
- int len = toIndex - fromIndex;
- // use insertion sort for small arrays
- if (len <= SIMPLE_LENGTH) {
- for (int i = fromIndex + 1; i < toIndex; i++) {
- Comparable<Object> current = (Comparable<Object>) out[i];
- Object prev = out[i - 1];
- if (current.compareTo(prev) < 0) {
- int j = i;
- do {
- out[j--] = prev;
- } while (j > fromIndex
- && current.compareTo(prev = out[j - 1]) < 0);
- out[j] = current;
- }
- }
- return;
- }
- int med = (toIndex + fromIndex) >> 1;
- mergeSort(out, in, fromIndex, med);
- mergeSort(out, in, med, toIndex);
-
- // merging
-
- // if arrays are already sorted - no merge
- if (((Comparable<Object>) in[med]).compareTo(in[med - 1]) >= 0) {
- System.arraycopy(in, fromIndex, out, fromIndex, len);
- return;
- }
- int r = med, i = fromIndex;
-
- // use merging with exponential search
- do {
- Comparable<Object> fromVal = (Comparable<Object>) in[fromIndex];
- Comparable<Object> rVal = (Comparable<Object>) in[r];
- if (fromVal.compareTo(rVal) <= 0) {
- int l_1 = find(in, rVal, -1, fromIndex + 1, med - 1);
- int toCopy = l_1 - fromIndex + 1;
- System.arraycopy(in, fromIndex, out, i, toCopy);
- i += toCopy;
- out[i++] = rVal;
- r++;
- fromIndex = l_1 + 1;
- } else {
- int r_1 = find(in, fromVal, 0, r + 1, toIndex - 1);
- int toCopy = r_1 - r + 1;
- System.arraycopy(in, r, out, i, toCopy);
- i += toCopy;
- out[i++] = fromVal;
- fromIndex++;
- r = r_1 + 1;
- }
- } while ((toIndex - r) > 0 && (med - fromIndex) > 0);
-
- // copy rest of array
- if ((toIndex - r) <= 0) {
- System.arraycopy(in, fromIndex, out, i, med - fromIndex);
- } else {
- System.arraycopy(in, r, out, i, toIndex - r);
- }
- }
-
- /**
- * Sorts the specified range of the specified array of objects. The range to
- * be sorted extends from index fromIndex, inclusive, to index toIndex,
- * exclusive. (If fromIndex==toIndex, the range to be sorted is empty.) This
- * sort is guaranteed to be stable: equal elements will not be reordered as
- * a result of the sort.
- *
- * The sorting algorithm is a mergesort with exponential search (in which
- * the merge is performed by exponential search). This algorithm offers
- * guaranteed n*log(n) performance and in average case faster then any
- * mergesort in which the merge is performed by linear search.
- *
- * @param in -
- * the array for sorting.
- * @param out -
- * the result, sorted array.
- * @param fromIndex -
- * the index of the first element (inclusive) to be sorted.
- * @param toIndex -
- * the index of the last element (exclusive) to be sorted.
- * @param c -
- * the comparator to determine the order of the array.
- */
- @SuppressWarnings("unchecked")
- private static void mergeSort(Object[] in, Object[] out, int fromIndex,
- int toIndex, Comparator c) {
- int len = toIndex - fromIndex;
- // use insertion sort for small arrays
- if (len <= SIMPLE_LENGTH) {
- for (int i = fromIndex + 1; i < toIndex; i++) {
- Object current = out[i];
- Object prev = out[i - 1];
- if (c.compare(prev, current) > 0) {
- int j = i;
- do {
- out[j--] = prev;
- } while (j > fromIndex
- && (c.compare(prev = out[j - 1], current) > 0));
- out[j] = current;
- }
- }
- return;
- }
- int med = (toIndex + fromIndex) >> 1;
- mergeSort(out, in, fromIndex, med, c);
- mergeSort(out, in, med, toIndex, c);
-
- // merging
-
- // if arrays are already sorted - no merge
- if (c.compare(in[med], in[med - 1]) >= 0) {
- System.arraycopy(in, fromIndex, out, fromIndex, len);
- return;
- }
- int r = med, i = fromIndex;
-
- // use merging with exponential search
- do {
- Object fromVal = in[fromIndex];
- Object rVal = in[r];
- if (c.compare(fromVal, rVal) <= 0) {
- int l_1 = find(in, rVal, -1, fromIndex + 1, med - 1, c);
- int toCopy = l_1 - fromIndex + 1;
- System.arraycopy(in, fromIndex, out, i, toCopy);
- i += toCopy;
- out[i++] = rVal;
- r++;
- fromIndex = l_1 + 1;
- } else {
- int r_1 = find(in, fromVal, 0, r + 1, toIndex - 1, c);
- int toCopy = r_1 - r + 1;
- System.arraycopy(in, r, out, i, toCopy);
- i += toCopy;
- out[i++] = fromVal;
- fromIndex++;
- r = r_1 + 1;
- }
- } while ((toIndex - r) > 0 && (med - fromIndex) > 0);
-
- // copy rest of array
- if ((toIndex - r) <= 0) {
- System.arraycopy(in, fromIndex, out, i, med - fromIndex);
- } else {
- System.arraycopy(in, r, out, i, toIndex - r);
- }
- }
-
- /**
- * Finds the place where the element should be inserted into the specified
- * range of the specified sorted array so that the resulting array would
- * remain sorted. Uses an exponential search algorithm.
- *
- * @param arr -
- * the array with a sorted range
- *
- * @param val -
- * the object to be inserted
- *
- * @param l -
- * the index of the first element (inclusive)
- *
- * @param r -
- * the index of the last element (inclusive)
- *
- * @param bnd -
- * A specifier to indicate how to treat the case where the
- * array range contains an element or elements equal to
- * {@code val}. "{@code -1}" indicates that val should be placed at
- * the index greater than the indices of any elements equal to
- * {@code val}. "{@code 0}" - indicates that val should be placed at
- * the index less than the indices of any elements equal to
- * {@code val}.
- *
- */
- @SuppressWarnings("unchecked")
- private static int find(Object[] arr, Comparable val, int bnd, int l, int r) {
- int m = l;
- int d = 1;
- while (m <= r) {
- if (val.compareTo(arr[m]) > bnd) {
- l = m + 1;
- } else {
- r = m - 1;
- break;
- }
- m += d;
- d <<= 1;
- }
- while (l <= r) {
- m = (l + r) >> 1;
- if (val.compareTo(arr[m]) > bnd) {
- l = m + 1;
- } else {
- r = m - 1;
- }
- }
- return l - 1;
- }
-
- /**
- * Finds the place where the element should be inserted into the specified
- * range of the specified sorted array so that the resulting array would
- * remain sorted. Uses an exponential search algorithm.
- *
- * @param arr -
- * the array with a sorted range
- *
- * @param val -
- * the object to be inserted
- *
- * @param l -
- * the index of the first element (inclusive)
- *
- * @param r -
- * the index of the last element (inclusive)
- *
- * @param bnd -
- * A specifier to indicate how to treat the case where the
- * array range contains an element or elements equal to
- * {@code val}. "{@code -1}" indicates that val should be placed at
- * the index greater than the indices of any elements equal to
- * {@code val}. "{@code 0}" - indicates that val should be placed at
- * the index less than the indices of any elements equal to
- * {@code val}.
- *
- * @param c -
- * the {@code Comparator} to determine the ordering of the array.
- */
- @SuppressWarnings("unchecked")
- private static int find(Object[] arr, Object val, int bnd, int l, int r,
- Comparator c) {
- int m = l;
- int d = 1;
- while (m <= r) {
- if (c.compare(val, arr[m]) > bnd) {
- l = m + 1;
- } else {
- r = m - 1;
- break;
- }
- m += d;
- d <<= 1;
- }
- while (l <= r) {
- m = (l + r) >> 1;
- if (c.compare(val, arr[m]) > bnd) {
- l = m + 1;
- } else {
- r = m - 1;
- }
- }
- return l - 1;
- }
-
- /*
- * returns the median index.
- */
- private static int medChar(int a, int b, int c, String[] arr, int id) {
- int ac = charAt(arr[a], id);
- int bc = charAt(arr[b], id);
- int cc = charAt(arr[c], id);
- return ac < bc ? (bc < cc ? b : (ac < cc ? c : a))
- : (bc < cc ? (ac < cc ? a : c) : b);
-
- }
-
- /*
- * Returns the char value at the specified index of string or -1 if the
- * index more than the length of this string.
- */
- private static int charAt(String str, int i) {
- if (i >= str.length()) {
- return -1;
- }
- return str.charAt(i);
- }
-
- /**
- * Copies object from one array to another array with reverse of objects
- * order. Source and destination arrays may be the same.
- *
- * @param src -
- * the source array.
- * @param from -
- * starting position in the source array.
- * @param dst -
- * the destination array.
- * @param to -
- * starting position in the destination array.
- * @param len -
- * the number of array elements to be copied.
- */
- private static void copySwap(Object[] src, int from, Object[] dst, int to,
- int len) {
- if (src == dst && from + len > to) {
- int new_to = to + len - 1;
- for (; from < to; from++, new_to--, len--) {
- dst[new_to] = src[from];
- }
- for (; len > 1; from++, new_to--, len -= 2) {
- swap(from, new_to, dst);
- }
-
- } else {
- to = to + len - 1;
- for (; len > 0; from++, to--, len--) {
- dst[to] = src[from];
- }
- }
- }
-
- /**
- * Sorts the specified range of the specified {@code String} array.
- *
- * @param arr -
- * the array to be sorted
- * @param fromIndex -
- * the index of the first element (inclusive) to be sorted.
- * @param toIndex -
- * the index of the last element (exclusive) to be sorted.
- */
- private static void stableStringSort(String[] arr, int fromIndex,
- int toIndex) {
- stableStringSort(arr, arr, new String[toIndex], fromIndex, toIndex, 0);
- }
-
- /**
- * Sorts the specified range of the specified {@code String} array. Use stable
- * ternary quick sort algorithm.
- *
- * @param arr -
- * the array to be sorted
- * @param src -
- * auxiliary array
- * @param dst -
- * auxiliary array
- * @param fromIndex -
- * the index of the first element (inclusive) to be sorted.
- * @param toIndex -
- * the index of the last element (exclusive) to be sorted.
- * @param chId -
- * index of {@code char} for current sorting
- */
- private static void stableStringSort(String[] arr, String[] src,
- String[] dst, int fromIndex, int toIndex, int chId) {
- int length = toIndex - fromIndex;
- // use insertion sort for small arrays
- if (length < SIMPLE_LENGTH) {
- if (src == arr) {
- for (int i = fromIndex + 1; i < toIndex; i++) {
- String current = arr[i];
- String prev = arr[i - 1];
- if (current.compareTo(prev) < 0) {
- int j = i;
- do {
- arr[j--] = prev;
- } while (j > fromIndex
- && current.compareTo(prev = arr[j - 1]) < 0);
- arr[j] = current;
- }
- }
- } else {
- int end = toIndex - 1;
- dst[fromIndex] = src[end--];
- for (int i = fromIndex + 1; i < toIndex; i++, end--) {
- String current = src[end];
- String prev;
- int j = i;
- while (j > fromIndex
- && current.compareTo(prev = dst[j - 1]) < 0) {
- dst[j--] = prev;
- }
- dst[j] = current;
- }
- }
- return;
- }
- // Approximate median
- int s;
- int mid = fromIndex + length / 2;
- int lo = fromIndex;
- int hi = toIndex - 1;
- if (length > 40) {
- s = length / 8;
- lo = medChar(lo, lo + s, lo + s * 2, src, chId);
- mid = medChar(mid - s, mid, mid + s, src, chId);
- hi = medChar(hi, hi - s, hi - s * 2, src, chId);
- }
- mid = medChar(lo, mid, hi, src, chId);
- // median found
- // create 4 pointers <a (in star of src) ,
- // =b(in start of dst), >c (in end of dst)
- // i - current element;
- int midVal = charAt(src[mid], chId);
- int a, b, c;
- a = b = fromIndex;
- c = toIndex - 1;
- int cmp;
-
- for (int i = fromIndex; i < toIndex; i++) {
- String el = src[i];
- cmp = charAt(el, chId) - midVal;
- if (cmp < 0) {
- src[a] = el;
- a++;
- } else if (cmp > 0) {
- dst[c] = el;
- c--;
- } else {
- dst[b] = el;
- b++;
- }
- }
-
- s = b - fromIndex;
- if (s > 0) {
- if (arr == src) {
- System.arraycopy(dst, fromIndex, arr, a, s);
- } else {
- copySwap(dst, fromIndex, arr, a, s);
- }
-
- if (b >= toIndex && midVal == -1) {
- return;
- }
- stableStringSort(arr, arr, arr == dst ? src : dst, a, a + s,
- chId + 1);
- }
-
- s = a - fromIndex;
- if (s > 0) {
- stableStringSort(arr, src, dst, fromIndex, a, chId);
- }
-
- c++;
- s = toIndex - c;
- if (s > 0) {
- stableStringSort(arr, dst, src, c, toIndex, chId);
- }
+ ComparableTimSort.sort(array, start, end);
}
/**
@@ -2937,23 +2469,7 @@
*/
public static <T> void sort(T[] array, int start, int end,
Comparator<? super T> comparator) {
- if (array == null) {
- throw new NullPointerException();
- }
- checkBounds(array.length, start, end);
- sort(start, end, array, comparator);
- }
-
- private static <T> void sort(int start, int end, T[] array,
- Comparator<? super T> comparator) {
- if (comparator == null) {
- sort(start, end, array);
- } else {
- int length = end - start;
- Object[] out = new Object[end];
- System.arraycopy(array, start, out, start, length);
- mergeSort(out, array, start, end, comparator);
- }
+ TimSort.sort(array, start, end, comparator);
}
/**
@@ -2970,9 +2486,11 @@
* @since Android 1.0
*/
public static <T> void sort(T[] array, Comparator<? super T> comparator) {
- sort(0, array.length, array, comparator);
+ TimSort.sort(array, comparator);
}
+// END android-changed
+
/**
* Sorts the specified array in ascending numerical order.
*
diff --git a/libcore/luni/src/main/java/java/util/ComparableTimSort.java b/libcore/luni/src/main/java/java/util/ComparableTimSort.java
new file mode 100644
index 0000000..882add1
--- /dev/null
+++ b/libcore/luni/src/main/java/java/util/ComparableTimSort.java
@@ -0,0 +1,891 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util;
+
+/**
+ * This is a near duplicate of {@link TimSort}, modified for use with
+ * arrays of objects that implement {@link Comparable}, instead of using
+ * explicit comparators.
+ *
+ * <p>If you are using an optimizing VM, you may find that ComparableTimSort
+ * offers no performance benefit over TimSort in conjunction with a
+ * comparator that simply returns {@code ((Comparable)first).compareTo(Second)}.
+ * If this is the case, you are better off deleting ComparableTimSort to
+ * eliminate the code duplication. (See Arrays.java for details.)
+ */
+class ComparableTimSort {
+ /**
+ * This is the minimum sized sequence that will be merged. Shorter
+ * sequences will be lengthened by calling binarySort. If the entire
+ * array is less than this length, no merges will be performed.
+ *
+ * This constant should be a power of two. It was 64 in Tim Peter's C
+ * implementation, but 32 was empirically determined to work better in
+ * this implementation. In the unlikely event that you set this constant
+ * to be a number that's not a power of two, you'll need to change the
+ * {@link #minRunLength} computation.
+ *
+ * If you decrease this constant, you must change the stackLen
+ * computation in the TimSort constructor, or you risk an
+ * ArrayOutOfBounds exception. See listsort.txt for a discussion
+ * of the minimum stack length required as a function of the length
+ * of the array being sorted and the minimum merge sequence length.
+ */
+ private static final int MIN_MERGE = 32;
+
+ /**
+ * The array being sorted.
+ */
+ private final Object[] a;
+
+ /**
+ * When we get into galloping mode, we stay there until both runs win less
+ * often than MIN_GALLOP consecutive times.
+ */
+ private static final int MIN_GALLOP = 7;
+
+ /**
+ * This controls when we get *into* galloping mode. It is initialized
+ * to MIN_GALLOP. The mergeLo and mergeHi methods nudge it higher for
+ * random data, and lower for highly structured data.
+ */
+ private int minGallop = MIN_GALLOP;
+
+ /**
+ * Maximum initial size of tmp array, which is used for merging. The array
+ * can grow to accommodate demand.
+ *
+ * Unlike Tim's original C version, we do not allocate this much storage
+ * when sorting smaller arrays. This change was required for performance.
+ */
+ private static final int INITIAL_TMP_STORAGE_LENGTH = 256;
+
+ /**
+ * Temp storage for merges.
+ */
+ private Object[] tmp;
+
+ /**
+ * A stack of pending runs yet to be merged. Run i starts at
+ * address base[i] and extends for len[i] elements. It's always
+ * true (so long as the indices are in bounds) that:
+ *
+ * runBase[i] + runLen[i] == runBase[i + 1]
+ *
+ * so we could cut the storage for this, but it's a minor amount,
+ * and keeping all the info explicit simplifies the code.
+ */
+ private int stackSize = 0; // Number of pending runs on stack
+ private final int[] runBase;
+ private final int[] runLen;
+
+ /**
+ * Asserts have been placed in if-statements for performace. To enable them,
+ * set this field to true and enable them in VM with a command line flag.
+ * If you modify this class, please do test the asserts!
+ */
+ private static final boolean DEBUG = false;
+
+ /**
+ * Creates a TimSort instance to maintain the state of an ongoing sort.
+ *
+ * @param a the array to be sorted
+ */
+ private ComparableTimSort(Object[] a) {
+ this.a = a;
+
+ // Allocate temp storage (which may be increased later if necessary)
+ int len = a.length;
+ @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
+ Object[] newArray = new Object[len < 2 * INITIAL_TMP_STORAGE_LENGTH ?
+ len >>> 1 : INITIAL_TMP_STORAGE_LENGTH];
+ tmp = newArray;
+
+ /*
+ * Allocate runs-to-be-merged stack (which cannot be expanded). The
+ * stack length requirements are described in listsort.txt. The C
+ * version always uses the same stack length (85), but this was
+ * measured to be too expensive when sorting "mid-sized" arrays (e.g.,
+ * 100 elements) in Java. Therefore, we use smaller (but sufficiently
+ * large) stack lengths for smaller arrays. The "magic numbers" in the
+ * computation below must be changed if MIN_MERGE is decreased. See
+ * the MIN_MERGE declaration above for more information.
+ */
+ int stackLen = (len < 120 ? 5 :
+ len < 1542 ? 10 :
+ len < 119151 ? 19 : 40);
+ runBase = new int[stackLen];
+ runLen = new int[stackLen];
+ }
+
+ /*
+ * The next two methods (which are package private and static) constitute
+ * the entire API of this class. Each of these methods obeys the contract
+ * of the public method with the same signature in java.util.Arrays.
+ */
+
+ static void sort(Object[] a) {
+ sort(a, 0, a.length);
+ }
+
+ static void sort(Object[] a, int lo, int hi) {
+ rangeCheck(a.length, lo, hi);
+ int nRemaining = hi - lo;
+ if (nRemaining < 2)
+ return; // Arrays of size 0 and 1 are always sorted
+
+ // If array is small, do a "mini-TimSort" with no merges
+ if (nRemaining < MIN_MERGE) {
+ int initRunLen = countRunAndMakeAscending(a, lo, nRemaining);
+ binarySort(a, lo, hi, lo + initRunLen);
+ return;
+ }
+
+ /**
+ * March over the array once, left to right, finding natural runs,
+ * extending short natural runs to minRun elements, and merging runs
+ * to maintain stack invariant.
+ */
+ ComparableTimSort ts = new ComparableTimSort(a);
+ int minRun = minRunLength(nRemaining);
+ do {
+ // Identify next run
+ int runLen = countRunAndMakeAscending(a, lo, hi);
+
+ // If run is short, extend to min(minRun, nRemaining)
+ if (runLen < minRun) {
+ int force = nRemaining <= minRun ? nRemaining : minRun;
+ binarySort(a, lo, lo + force, lo + runLen);
+ runLen = force;
+ }
+
+ // Push run onto pending-run stack, and maybe merge
+ ts.pushRun(lo, runLen);
+ ts.mergeCollapse();
+
+ // Advance to find next run
+ lo += runLen;
+ nRemaining -= runLen;
+ } while (nRemaining != 0);
+
+ // Merge all remaining runs to complete sort
+ if (DEBUG) assert lo == hi;
+ ts.mergeForceCollapse();
+ if (DEBUG) assert ts.stackSize == 1;
+ }
+
+ /**
+ * Sorts the specified portion of the specified array using a binary
+ * insertion sort. This is the best method for sorting small numbers
+ * of elements. It requires O(n log n) compares, but O(n^2) data
+ * movement (worst case).
+ *
+ * If the initial part of the specified range is already sorted,
+ * this method can take advantage of it: the method assumes that the
+ * elements from index {@code lo}, inclusive, to {@code start},
+ * exclusive are already sorted.
+ *
+ * @param a the array in which a range is to be sorted
+ * @param lo the index of the first element in the range to be sorted
+ * @param hi the index after the last element in the range to be sorted
+ * @param start the index of the first element in the range that is
+ * not already known to be sorted (@code lo <= start <= hi}
+ */
+ @SuppressWarnings("fallthrough")
+ private static void binarySort(Object[] a, int lo, int hi, int start) {
+ if (DEBUG) assert lo <= start && start <= hi;
+ if (start == lo)
+ start++;
+ for ( ; start < hi; start++) {
+ @SuppressWarnings("unchecked")
+ Comparable<Object> pivot = (Comparable) a[start];
+
+ // Set left (and right) to the index where a[start] (pivot) belongs
+ int left = lo;
+ int right = start;
+ if (DEBUG) assert left <= right;
+ /*
+ * Invariants:
+ * pivot >= all in [lo, left).
+ * pivot < all in [right, start).
+ */
+ while (left < right) {
+ int mid = (left + right) >>> 1;
+ if (pivot.compareTo(a[mid]) < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ if (DEBUG) assert left == right;
+
+ /*
+ * The invariants still hold: pivot >= all in [lo, left) and
+ * pivot < all in [left, start), so pivot belongs at left. Note
+ * that if there are elements equal to pivot, left points to the
+ * first slot after them -- that's why this sort is stable.
+ * Slide elements over to make room to make room for pivot.
+ */
+ int n = start - left; // The number of elements to move
+ // Switch is just an optimization for arraycopy in default case
+ switch(n) {
+ case 2: a[left + 2] = a[left + 1];
+ case 1: a[left + 1] = a[left];
+ break;
+ default: System.arraycopy(a, left, a, left + 1, n);
+ }
+ a[left] = pivot;
+ }
+ }
+
+ /**
+ * Returns the length of the run beginning at the specified position in
+ * the specified array and reverses the run if it is descending (ensuring
+ * that the run will always be ascending when the method returns).
+ *
+ * A run is the longest ascending sequence with:
+ *
+ * a[lo] <= a[lo + 1] <= a[lo + 2] <= ...
+ *
+ * or the longest descending sequence with:
+ *
+ * a[lo] > a[lo + 1] > a[lo + 2] > ...
+ *
+ * For its intended use in a stable mergesort, the strictness of the
+ * definition of "descending" is needed so that the call can safely
+ * reverse a descending sequence without violating stability.
+ *
+ * @param a the array in which a run is to be counted and possibly reversed
+ * @param lo index of the first element in the run
+ * @param hi index after the last element that may be contained in the run.
+ It is required that @code{lo < hi}.
+ * @return the length of the run beginning at the specified position in
+ * the specified array
+ */
+ @SuppressWarnings("unchecked")
+ private static int countRunAndMakeAscending(Object[] a, int lo, int hi) {
+ if (DEBUG) assert lo < hi;
+ int runHi = lo + 1;
+ if (runHi == hi)
+ return 1;
+
+ // Find end of run, and reverse range if descending
+ if (((Comparable) a[runHi++]).compareTo(a[lo]) < 0) { // Descending
+ while(runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0)
+ runHi++;
+ reverseRange(a, lo, runHi);
+ } else { // Ascending
+ while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) >= 0)
+ runHi++;
+ }
+
+ return runHi - lo;
+ }
+
+ /**
+ * Reverse the specified range of the specified array.
+ *
+ * @param a the array in which a range is to be reversed
+ * @param lo the index of the first element in the range to be reversed
+ * @param hi the index after the last element in the range to be reversed
+ */
+ private static void reverseRange(Object[] a, int lo, int hi) {
+ hi--;
+ while (lo < hi) {
+ Object t = a[lo];
+ a[lo++] = a[hi];
+ a[hi--] = t;
+ }
+ }
+
+ /**
+ * Returns the minimum acceptable run length for an array of the specified
+ * length. Natural runs shorter than this will be extended with
+ * {@link #binarySort}.
+ *
+ * Roughly speaking, the computation is:
+ *
+ * If n < MIN_MERGE, return n (it's too small to bother with fancy stuff).
+ * Else if n is an exact power of 2, return MIN_MERGE/2.
+ * Else return an int k, MIN_MERGE/2 <= k <= MIN_MERGE, such that n/k
+ * is close to, but strictly less than, an exact power of 2.
+ *
+ * For the rationale, see listsort.txt.
+ *
+ * @param n the length of the array to be sorted
+ * @return the length of the minimum run to be merged
+ */
+ private static int minRunLength(int n) {
+ if (DEBUG) assert n >= 0;
+ int r = 0; // Becomes 1 if any 1 bits are shifted off
+ while (n >= MIN_MERGE) {
+ r |= (n & 1);
+ n >>= 1;
+ }
+ return n + r;
+ }
+
+ /**
+ * Pushes the specified run onto the pending-run stack.
+ *
+ * @param runBase index of the first element in the run
+ * @param runLen the number of elements in the run
+ */
+ private void pushRun(int runBase, int runLen) {
+ this.runBase[stackSize] = runBase;
+ this.runLen[stackSize] = runLen;
+ stackSize++;
+ }
+
+ /**
+ * Examines the stack of runs waiting to be merged and merges adjacent runs
+ * until the stack invariants are reestablished:
+ *
+ * 1. runLen[i - 3] > runLen[i - 2] + runLen[i - 1]
+ * 2. runLen[i - 2] > runLen[i - 1]
+ *
+ * This method is called each time a new run is pushed onto the stack,
+ * so the invariants are guaranteed to hold for i < stackSize upon
+ * entry to the method.
+ */
+ private void mergeCollapse() {
+ while (stackSize > 1) {
+ int n = stackSize - 2;
+ if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) {
+ if (runLen[n - 1] < runLen[n + 1])
+ n--;
+ mergeAt(n);
+ } else if (runLen[n] <= runLen[n + 1]) {
+ mergeAt(n);
+ } else {
+ break; // Invariant is established
+ }
+ }
+ }
+
+ /**
+ * Merges all runs on the stack until only one remains. This method is
+ * called once, to complete the sort.
+ */
+ private void mergeForceCollapse() {
+ while (stackSize > 1) {
+ int n = stackSize - 2;
+ if (n > 0 && runLen[n - 1] < runLen[n + 1])
+ n--;
+ mergeAt(n);
+ }
+ }
+
+ /**
+ * Merges the two runs at stack indices i and i+1. Run i must be
+ * the penultimate or antepenultimate run on the stack. In other words,
+ * i must be equal to stackSize-2 or stackSize-3.
+ *
+ * @param i stack index of the first of the two runs to merge
+ */
+ @SuppressWarnings("unchecked")
+ private void mergeAt(int i) {
+ if (DEBUG) assert stackSize >= 2;
+ if (DEBUG) assert i >= 0;
+ if (DEBUG) assert i == stackSize - 2 || i == stackSize - 3;
+
+ int base1 = runBase[i];
+ int len1 = runLen[i];
+ int base2 = runBase[i + 1];
+ int len2 = runLen[i + 1];
+ if (DEBUG) assert len1 > 0 && len2 > 0;
+ if (DEBUG) assert base1 + len1 == base2;
+
+ /*
+ * Record the length of the combined runs; if i is the 3rd-last
+ * run now, also slide over the last run (which isn't involved
+ * in this merge). The current run (i+1) goes away in any case.
+ */
+ runLen[i] = len1 + len2;
+ if (i == stackSize - 3) {
+ runBase[i + 1] = runBase[i + 2];
+ runLen[i + 1] = runLen[i + 2];
+ }
+ stackSize--;
+
+ /*
+ * Find where the first element of run2 goes in run1. Prior elements
+ * in run1 can be ignored (because they're already in place).
+ */
+ int k = gallopRight((Comparable<Object>) a[base2], a, base1, len1, 0);
+ if (DEBUG) assert k >= 0;
+ base1 += k;
+ len1 -= k;
+ if (len1 == 0)
+ return;
+
+ /*
+ * Find where the last element of run1 goes in run2. Subsequent elements
+ * in run2 can be ignored (because they're already in place).
+ */
+ len2 = gallopLeft((Comparable<Object>) a[base1 + len1 - 1], a,
+ base2, len2, len2 - 1);
+ if (DEBUG) assert len2 >= 0;
+ if (len2 == 0)
+ return;
+
+ // Merge remaining runs, using tmp array with min(len1, len2) elements
+ if (len1 <= len2)
+ mergeLo(base1, len1, base2, len2);
+ else
+ mergeHi(base1, len1, base2, len2);
+ }
+
+ /**
+ * Locates the position at which to insert the specified key into the
+ * specified sorted range; if the range contains an element equal to key,
+ * returns the index of the leftmost equal element.
+ *
+ * @param key the key whose insertion point to search for
+ * @param a the array in which to search
+ * @param base the index of the first element in the range
+ * @param len the length of the range; must be > 0
+ * @param hint the index at which to begin the search, 0 <= hint < n.
+ * The closer hint is to the result, the faster this method will run.
+ * @return the int k, 0 <= k <= n such that a[b + k - 1] < key <= a[b + k],
+ * pretending that a[b - 1] is minus infinity and a[b + n] is infinity.
+ * In other words, key belongs at index b + k; or in other words,
+ * the first k elements of a should precede key, and the last n - k
+ * should follow it.
+ */
+ private static int gallopLeft(Comparable<Object> key, Object[] a,
+ int base, int len, int hint) {
+ if (DEBUG) assert len > 0 && hint >= 0 && hint < len;
+
+ int lastOfs = 0;
+ int ofs = 1;
+ if (key.compareTo(a[base + hint]) > 0) {
+ // Gallop right until a[base+hint+lastOfs] < key <= a[base+hint+ofs]
+ int maxOfs = len - hint;
+ while (ofs < maxOfs && key.compareTo(a[base + hint + ofs]) > 0) {
+ lastOfs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) // int overflow
+ ofs = maxOfs;
+ }
+ if (ofs > maxOfs)
+ ofs = maxOfs;
+
+ // Make offsets relative to base
+ lastOfs += hint;
+ ofs += hint;
+ } else { // key <= a[base + hint]
+ // Gallop left until a[base+hint-ofs] < key <= a[base+hint-lastOfs]
+ final int maxOfs = hint + 1;
+ while (ofs < maxOfs && key.compareTo(a[base + hint - ofs]) <= 0) {
+ lastOfs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) // int overflow
+ ofs = maxOfs;
+ }
+ if (ofs > maxOfs)
+ ofs = maxOfs;
+
+ // Make offsets relative to base
+ int tmp = lastOfs;
+ lastOfs = hint - ofs;
+ ofs = hint - tmp;
+ }
+ if (DEBUG) assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
+
+ /*
+ * Now a[base+lastOfs] < key <= a[base+ofs], so key belongs somewhere
+ * to the right of lastOfs but no farther right than ofs. Do a binary
+ * search, with invariant a[base + lastOfs - 1] < key <= a[base + ofs].
+ */
+ lastOfs++;
+ while (lastOfs < ofs) {
+ int m = lastOfs + ((ofs - lastOfs) >>> 1);
+
+ if (key.compareTo(a[base + m]) > 0)
+ lastOfs = m + 1; // a[base + m] < key
+ else
+ ofs = m; // key <= a[base + m]
+ }
+ if (DEBUG) assert lastOfs == ofs; // so a[base + ofs - 1] < key <= a[base + ofs]
+ return ofs;
+ }
+
+ /**
+ * Like gallopLeft, except that if the range contains an element equal to
+ * key, gallopRight returns the index after the rightmost equal element.
+ *
+ * @param key the key whose insertion point to search for
+ * @param a the array in which to search
+ * @param base the index of the first element in the range
+ * @param len the length of the range; must be > 0
+ * @param hint the index at which to begin the search, 0 <= hint < n.
+ * The closer hint is to the result, the faster this method will run.
+ * @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k]
+ */
+ private static int gallopRight(Comparable<Object> key, Object[] a,
+ int base, int len, int hint) {
+ if (DEBUG) assert len > 0 && hint >= 0 && hint < len;
+
+ int ofs = 1;
+ int lastOfs = 0;
+ if (key.compareTo(a[base + hint]) < 0) {
+ // Gallop left until a[b+hint - ofs] <= key < a[b+hint - lastOfs]
+ int maxOfs = hint + 1;
+ while (ofs < maxOfs && key.compareTo(a[base + hint - ofs]) < 0) {
+ lastOfs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) // int overflow
+ ofs = maxOfs;
+ }
+ if (ofs > maxOfs)
+ ofs = maxOfs;
+
+ // Make offsets relative to b
+ int tmp = lastOfs;
+ lastOfs = hint - ofs;
+ ofs = hint - tmp;
+ } else { // a[b + hint] <= key
+ // Gallop right until a[b+hint + lastOfs] <= key < a[b+hint + ofs]
+ int maxOfs = len - hint;
+ while (ofs < maxOfs && key.compareTo(a[base + hint + ofs]) >= 0) {
+ lastOfs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) // int overflow
+ ofs = maxOfs;
+ }
+ if (ofs > maxOfs)
+ ofs = maxOfs;
+
+ // Make offsets relative to b
+ lastOfs += hint;
+ ofs += hint;
+ }
+ if (DEBUG) assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
+
+ /*
+ * Now a[b + lastOfs] <= key < a[b + ofs], so key belongs somewhere to
+ * the right of lastOfs but no farther right than ofs. Do a binary
+ * search, with invariant a[b + lastOfs - 1] <= key < a[b + ofs].
+ */
+ lastOfs++;
+ while (lastOfs < ofs) {
+ int m = lastOfs + ((ofs - lastOfs) >>> 1);
+
+ if (key.compareTo(a[base + m]) < 0)
+ ofs = m; // key < a[b + m]
+ else
+ lastOfs = m + 1; // a[b + m] <= key
+ }
+ if (DEBUG) assert lastOfs == ofs; // so a[b + ofs - 1] <= key < a[b + ofs]
+ return ofs;
+ }
+
+ /**
+ * Merges two adjacent runs in place, in a stable fashion. The first
+ * element of the first run must be greater than the first element of the
+ * second run (a[base1] > a[base2]), and the last element of the first run
+ * (a[base1 + len1-1]) must be greater than all elements of the second run.
+ *
+ * For performance, this method should be called only when len1 <= len2;
+ * its twin, mergeHi should be called if len1 >= len2. (Either method
+ * may be called if len1 == len2.)
+ *
+ * @param base1 index of first element in first run to be merged
+ * @param len1 length of first run to be merged (must be > 0)
+ * @param base2 index of first element in second run to be merged
+ * (must be aBase + aLen)
+ * @param len2 length of second run to be merged (must be > 0)
+ */
+ @SuppressWarnings("unchecked")
+ private void mergeLo(int base1, int len1, int base2, int len2) {
+ if (DEBUG) assert len1 > 0 && len2 > 0 && base1 + len1 == base2;
+
+ // Copy first run into temp array
+ Object[] a = this.a; // For performance
+ Object[] tmp = ensureCapacity(len1);
+ System.arraycopy(a, base1, tmp, 0, len1);
+
+ int cursor1 = 0; // Indexes into tmp array
+ int cursor2 = base2; // Indexes int a
+ int dest = base1; // Indexes int a
+
+ // Move first element of second run and deal with degenerate cases
+ a[dest++] = a[cursor2++];
+ if (--len2 == 0) {
+ System.arraycopy(tmp, cursor1, a, dest, len1);
+ return;
+ }
+ if (len1 == 1) {
+ System.arraycopy(a, cursor2, a, dest, len2);
+ a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
+ return;
+ }
+
+ int minGallop = this.minGallop; // Use local variable for performance
+ outer:
+ while (true) {
+ int count1 = 0; // Number of times in a row that first run won
+ int count2 = 0; // Number of times in a row that second run won
+
+ /*
+ * Do the straightforward thing until (if ever) one run starts
+ * winning consistently.
+ */
+ do {
+ if (DEBUG) assert len1 > 1 && len2 > 0;
+ if (((Comparable) a[cursor2]).compareTo(tmp[cursor1]) < 0) {
+ a[dest++] = a[cursor2++];
+ count2++;
+ count1 = 0;
+ if (--len2 == 0)
+ break outer;
+ } else {
+ a[dest++] = tmp[cursor1++];
+ count1++;
+ count2 = 0;
+ if (--len1 == 1)
+ break outer;
+ }
+ } while ((count1 | count2) < minGallop);
+
+ /*
+ * One run is winning so consistently that galloping may be a
+ * huge win. So try that, and continue galloping until (if ever)
+ * neither run appears to be winning consistently anymore.
+ */
+ do {
+ if (DEBUG) assert len1 > 1 && len2 > 0;
+ count1 = gallopRight((Comparable) a[cursor2], tmp, cursor1, len1, 0);
+ if (count1 != 0) {
+ System.arraycopy(tmp, cursor1, a, dest, count1);
+ dest += count1;
+ cursor1 += count1;
+ len1 -= count1;
+ if (len1 <= 1) // len1 == 1 || len1 == 0
+ break outer;
+ }
+ a[dest++] = a[cursor2++];
+ if (--len2 == 0)
+ break outer;
+
+ count2 = gallopLeft((Comparable) tmp[cursor1], a, cursor2, len2, 0);
+ if (count2 != 0) {
+ System.arraycopy(a, cursor2, a, dest, count2);
+ dest += count2;
+ cursor2 += count2;
+ len2 -= count2;
+ if (len2 == 0)
+ break outer;
+ }
+ a[dest++] = tmp[cursor1++];
+ if (--len1 == 1)
+ break outer;
+ minGallop--;
+ } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
+ if (minGallop < 0)
+ minGallop = 0;
+ minGallop += 2; // Penalize for leaving gallop mode
+ } // End of "outer" loop
+ this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field
+
+ if (len1 == 1) {
+ if (DEBUG) assert len2 > 0;
+ System.arraycopy(a, cursor2, a, dest, len2);
+ a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
+ } else if (len1 == 0) {
+ throw new IllegalArgumentException(
+ "Comparison method violates its general contract!");
+ } else {
+ if (DEBUG) assert len2 == 0;
+ if (DEBUG) assert len1 > 1;
+ System.arraycopy(tmp, cursor1, a, dest, len1);
+ }
+ }
+
+ /**
+ * Like mergeLo, except that this method should be called only if
+ * len1 >= len2; mergeLo should be called if len1 <= len2. (Either method
+ * may be called if len1 == len2.)
+ *
+ * @param base1 index of first element in first run to be merged
+ * @param len1 length of first run to be merged (must be > 0)
+ * @param base2 index of first element in second run to be merged
+ * (must be aBase + aLen)
+ * @param len2 length of second run to be merged (must be > 0)
+ */
+ @SuppressWarnings("unchecked")
+ private void mergeHi(int base1, int len1, int base2, int len2) {
+ if (DEBUG) assert len1 > 0 && len2 > 0 && base1 + len1 == base2;
+
+ // Copy second run into temp array
+ Object[] a = this.a; // For performance
+ Object[] tmp = ensureCapacity(len2);
+ System.arraycopy(a, base2, tmp, 0, len2);
+
+ int cursor1 = base1 + len1 - 1; // Indexes into a
+ int cursor2 = len2 - 1; // Indexes into tmp array
+ int dest = base2 + len2 - 1; // Indexes into a
+
+ // Move last element of first run and deal with degenerate cases
+ a[dest--] = a[cursor1--];
+ if (--len1 == 0) {
+ System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2);
+ return;
+ }
+ if (len2 == 1) {
+ dest -= len1;
+ cursor1 -= len1;
+ System.arraycopy(a, cursor1 + 1, a, dest + 1, len1);
+ a[dest] = tmp[cursor2];
+ return;
+ }
+
+ int minGallop = this.minGallop; // Use local variable for performance
+ outer:
+ while (true) {
+ int count1 = 0; // Number of times in a row that first run won
+ int count2 = 0; // Number of times in a row that second run won
+
+ /*
+ * Do the straightforward thing until (if ever) one run
+ * appears to win consistently.
+ */
+ do {
+ if (DEBUG) assert len1 > 0 && len2 > 1;
+ if (((Comparable) tmp[cursor2]).compareTo(a[cursor1]) < 0) {
+ a[dest--] = a[cursor1--];
+ count1++;
+ count2 = 0;
+ if (--len1 == 0)
+ break outer;
+ } else {
+ a[dest--] = tmp[cursor2--];
+ count2++;
+ count1 = 0;
+ if (--len2 == 1)
+ break outer;
+ }
+ } while ((count1 | count2) < minGallop);
+
+ /*
+ * One run is winning so consistently that galloping may be a
+ * huge win. So try that, and continue galloping until (if ever)
+ * neither run appears to be winning consistently anymore.
+ */
+ do {
+ if (DEBUG) assert len1 > 0 && len2 > 1;
+ count1 = len1 - gallopRight((Comparable) tmp[cursor2], a, base1, len1, len1 - 1);
+ if (count1 != 0) {
+ dest -= count1;
+ cursor1 -= count1;
+ len1 -= count1;
+ System.arraycopy(a, cursor1 + 1, a, dest + 1, count1);
+ if (len1 == 0)
+ break outer;
+ }
+ a[dest--] = tmp[cursor2--];
+ if (--len2 == 1)
+ break outer;
+
+ count2 = len2 - gallopLeft((Comparable) a[cursor1], tmp, 0, len2, len2 - 1);
+ if (count2 != 0) {
+ dest -= count2;
+ cursor2 -= count2;
+ len2 -= count2;
+ System.arraycopy(tmp, cursor2 + 1, a, dest + 1, count2);
+ if (len2 <= 1)
+ break outer; // len2 == 1 || len2 == 0
+ }
+ a[dest--] = a[cursor1--];
+ if (--len1 == 0)
+ break outer;
+ minGallop--;
+ } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
+ if (minGallop < 0)
+ minGallop = 0;
+ minGallop += 2; // Penalize for leaving gallop mode
+ } // End of "outer" loop
+ this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field
+
+ if (len2 == 1) {
+ if (DEBUG) assert len1 > 0;
+ dest -= len1;
+ cursor1 -= len1;
+ System.arraycopy(a, cursor1 + 1, a, dest + 1, len1);
+ a[dest] = tmp[cursor2]; // Move first elt of run2 to front of merge
+ } else if (len2 == 0) {
+ throw new IllegalArgumentException(
+ "Comparison method violates its general contract!");
+ } else {
+ if (DEBUG) assert len1 == 0;
+ if (DEBUG) assert len2 > 0;
+ System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2);
+ }
+ }
+
+ /**
+ * Ensures that the external array tmp has at least the specified
+ * number of elements, increasing its size if necessary. The size
+ * increases exponentially to ensure amortized linear time complexity.
+ *
+ * @param minCapacity the minimum required capacity of the tmp array
+ * @return tmp, whether or not it grew
+ */
+ private Object[] ensureCapacity(int minCapacity) {
+ if (tmp.length < minCapacity) {
+ // Compute smallest power of 2 > minCapacity
+ int newSize = minCapacity;
+ newSize |= newSize >> 1;
+ newSize |= newSize >> 2;
+ newSize |= newSize >> 4;
+ newSize |= newSize >> 8;
+ newSize |= newSize >> 16;
+ newSize++;
+
+ if (newSize < 0) // Not bloody likely!
+ newSize = minCapacity;
+ else
+ newSize = Math.min(newSize, a.length >>> 1);
+
+ @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
+ Object[] newArray = new Object[newSize];
+ tmp = newArray;
+ }
+ return tmp;
+ }
+
+ /**
+ * Checks that fromIndex and toIndex are in range, and throws an
+ * appropriate exception if they aren't.
+ *
+ * @param arrayLen the length of the array
+ * @param fromIndex the index of the first element of the range
+ * @param toIndex the index after the last element of the range
+ * @throws IllegalArgumentException if fromIndex > toIndex
+ * @throws ArrayIndexOutOfBoundsException if fromIndex < 0
+ * or toIndex > arrayLen
+ */
+ private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) {
+ if (fromIndex > toIndex)
+ throw new IllegalArgumentException("fromIndex(" + fromIndex +
+ ") > toIndex(" + toIndex+")");
+ if (fromIndex < 0)
+ throw new ArrayIndexOutOfBoundsException(fromIndex);
+ if (toIndex > arrayLen)
+ throw new ArrayIndexOutOfBoundsException(toIndex);
+ }
+}
diff --git a/libcore/luni/src/main/java/java/util/TimSort.java b/libcore/luni/src/main/java/java/util/TimSort.java
new file mode 100644
index 0000000..9c27ddc
--- /dev/null
+++ b/libcore/luni/src/main/java/java/util/TimSort.java
@@ -0,0 +1,924 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util;
+
+/**
+ * A stable, adaptive, iterative mergesort that requires far fewer than
+ * n lg(n) comparisons when running on partially sorted arrays, while
+ * offering performance comparable to a traditional mergesort when run
+ * on random arrays. Like all proper mergesorts, this sort is stable and
+ * runs O(n log n) time (worst case). In the worst case, this sort requires
+ * temporary storage space for n/2 object references; in the best case,
+ * it requires only a small constant amount of space.
+ *
+ * This implementation was adapted from Tim Peters's list sort for
+ * Python, which is described in detail here:
+ *
+ * http://svn.python.org/projects/python/trunk/Objects/listsort.txt
+ *
+ * Tim's C code may be found here:
+ *
+ * http://svn.python.org/projects/python/trunk/Objects/listobject.c
+ *
+ * The underlying techniques are described in this paper (and may have
+ * even earlier origins):
+ *
+ * "Optimistic Sorting and Information Theoretic Complexity"
+ * Peter McIlroy
+ * SODA (Fourth Annual ACM-SIAM Symposium on Discrete Algorithms),
+ * pp 467-474, Austin, Texas, 25-27 January 1993.
+ *
+ * While the API to this class consists solely of static methods, it is
+ * (privately) instantiable; a TimSort instance holds the state of an ongoing
+ * sort, assuming the input array is large enough to warrant the full-blown
+ * TimSort. Small arrays are sorted in place, using a binary insertion sort.
+ */
+class TimSort<T> {
+ /**
+ * This is the minimum sized sequence that will be merged. Shorter
+ * sequences will be lengthened by calling binarySort. If the entire
+ * array is less than this length, no merges will be performed.
+ *
+ * This constant should be a power of two. It was 64 in Tim Peter's C
+ * implementation, but 32 was empirically determined to work better in
+ * this implementation. In the unlikely event that you set this constant
+ * to be a number that's not a power of two, you'll need to change the
+ * {@link #minRunLength} computation.
+ *
+ * If you decrease this constant, you must change the stackLen
+ * computation in the TimSort constructor, or you risk an
+ * ArrayOutOfBounds exception. See listsort.txt for a discussion
+ * of the minimum stack length required as a function of the length
+ * of the array being sorted and the minimum merge sequence length.
+ */
+ private static final int MIN_MERGE = 32;
+
+ /**
+ * The array being sorted.
+ */
+ private final T[] a;
+
+ /**
+ * The comparator for this sort.
+ */
+ private final Comparator<? super T> c;
+
+ /**
+ * When we get into galloping mode, we stay there until both runs win less
+ * often than MIN_GALLOP consecutive times.
+ */
+ private static final int MIN_GALLOP = 7;
+
+ /**
+ * This controls when we get *into* galloping mode. It is initialized
+ * to MIN_GALLOP. The mergeLo and mergeHi methods nudge it higher for
+ * random data, and lower for highly structured data.
+ */
+ private int minGallop = MIN_GALLOP;
+
+ /**
+ * Maximum initial size of tmp array, which is used for merging. The array
+ * can grow to accommodate demand.
+ *
+ * Unlike Tim's original C version, we do not allocate this much storage
+ * when sorting smaller arrays. This change was required for performance.
+ */
+ private static final int INITIAL_TMP_STORAGE_LENGTH = 256;
+
+ /**
+ * Temp storage for merges.
+ */
+ private T[] tmp; // Actual runtime type will be Object[], regardless of T
+
+ /**
+ * A stack of pending runs yet to be merged. Run i starts at
+ * address base[i] and extends for len[i] elements. It's always
+ * true (so long as the indices are in bounds) that:
+ *
+ * runBase[i] + runLen[i] == runBase[i + 1]
+ *
+ * so we could cut the storage for this, but it's a minor amount,
+ * and keeping all the info explicit simplifies the code.
+ */
+ private int stackSize = 0; // Number of pending runs on stack
+ private final int[] runBase;
+ private final int[] runLen;
+
+ /**
+ * Asserts have been placed in if-statements for performace. To enable them,
+ * set this field to true and enable them in VM with a command line flag.
+ * If you modify this class, please do test the asserts!
+ */
+ private static final boolean DEBUG = false;
+
+ /**
+ * Creates a TimSort instance to maintain the state of an ongoing sort.
+ *
+ * @param a the array to be sorted
+ * @param c the comparator to determine the order of the sort
+ */
+ private TimSort(T[] a, Comparator<? super T> c) {
+ this.a = a;
+ this.c = c;
+
+ // Allocate temp storage (which may be increased later if necessary)
+ int len = a.length;
+ @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
+ T[] newArray = (T[]) new Object[len < 2 * INITIAL_TMP_STORAGE_LENGTH ?
+ len >>> 1 : INITIAL_TMP_STORAGE_LENGTH];
+ tmp = newArray;
+
+ /*
+ * Allocate runs-to-be-merged stack (which cannot be expanded). The
+ * stack length requirements are described in listsort.txt. The C
+ * version always uses the same stack length (85), but this was
+ * measured to be too expensive when sorting "mid-sized" arrays (e.g.,
+ * 100 elements) in Java. Therefore, we use smaller (but sufficiently
+ * large) stack lengths for smaller arrays. The "magic numbers" in the
+ * computation below must be changed if MIN_MERGE is decreased. See
+ * the MIN_MERGE declaration above for more information.
+ */
+ int stackLen = (len < 120 ? 5 :
+ len < 1542 ? 10 :
+ len < 119151 ? 19 : 40);
+ runBase = new int[stackLen];
+ runLen = new int[stackLen];
+ }
+
+ /*
+ * The next two methods (which are package private and static) constitute
+ * the entire API of this class. Each of these methods obeys the contract
+ * of the public method with the same signature in java.util.Arrays.
+ */
+
+ static <T> void sort(T[] a, Comparator<? super T> c) {
+ sort(a, 0, a.length, c);
+ }
+
+ static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c) {
+ if (c == null) {
+ Arrays.sort(a, lo, hi);
+ return;
+ }
+
+ rangeCheck(a.length, lo, hi);
+ int nRemaining = hi - lo;
+ if (nRemaining < 2)
+ return; // Arrays of size 0 and 1 are always sorted
+
+ // If array is small, do a "mini-TimSort" with no merges
+ if (nRemaining < MIN_MERGE) {
+ int initRunLen = countRunAndMakeAscending(a, lo, nRemaining, c);
+ binarySort(a, lo, hi, lo + initRunLen, c);
+ return;
+ }
+
+ /**
+ * March over the array once, left to right, finding natural runs,
+ * extending short natural runs to minRun elements, and merging runs
+ * to maintain stack invariant.
+ */
+ TimSort<T> ts = new TimSort<T>(a, c);
+ int minRun = minRunLength(nRemaining);
+ do {
+ // Identify next run
+ int runLen = countRunAndMakeAscending(a, lo, hi, c);
+
+ // If run is short, extend to min(minRun, nRemaining)
+ if (runLen < minRun) {
+ int force = nRemaining <= minRun ? nRemaining : minRun;
+ binarySort(a, lo, lo + force, lo + runLen, c);
+ runLen = force;
+ }
+
+ // Push run onto pending-run stack, and maybe merge
+ ts.pushRun(lo, runLen);
+ ts.mergeCollapse();
+
+ // Advance to find next run
+ lo += runLen;
+ nRemaining -= runLen;
+ } while (nRemaining != 0);
+
+ // Merge all remaining runs to complete sort
+ if (DEBUG) assert lo == hi;
+ ts.mergeForceCollapse();
+ if (DEBUG) assert ts.stackSize == 1;
+ }
+
+ /**
+ * Sorts the specified portion of the specified array using a binary
+ * insertion sort. This is the best method for sorting small numbers
+ * of elements. It requires O(n log n) compares, but O(n^2) data
+ * movement (worst case).
+ *
+ * If the initial part of the specified range is already sorted,
+ * this method can take advantage of it: the method assumes that the
+ * elements from index {@code lo}, inclusive, to {@code start},
+ * exclusive are already sorted.
+ *
+ * @param a the array in which a range is to be sorted
+ * @param lo the index of the first element in the range to be sorted
+ * @param hi the index after the last element in the range to be sorted
+ * @param start the index of the first element in the range that is
+ * not already known to be sorted (@code lo <= start <= hi}
+ * @param c comparator to used for the sort
+ */
+ @SuppressWarnings("fallthrough")
+ private static <T> void binarySort(T[] a, int lo, int hi, int start,
+ Comparator<? super T> c) {
+ if (DEBUG) assert lo <= start && start <= hi;
+ if (start == lo)
+ start++;
+ for ( ; start < hi; start++) {
+ T pivot = a[start];
+
+ // Set left (and right) to the index where a[start] (pivot) belongs
+ int left = lo;
+ int right = start;
+ if (DEBUG) assert left <= right;
+ /*
+ * Invariants:
+ * pivot >= all in [lo, left).
+ * pivot < all in [right, start).
+ */
+ while (left < right) {
+ int mid = (left + right) >>> 1;
+ if (c.compare(pivot, a[mid]) < 0)
+ right = mid;
+ else
+ left = mid + 1;
+ }
+ if (DEBUG) assert left == right;
+
+ /*
+ * The invariants still hold: pivot >= all in [lo, left) and
+ * pivot < all in [left, start), so pivot belongs at left. Note
+ * that if there are elements equal to pivot, left points to the
+ * first slot after them -- that's why this sort is stable.
+ * Slide elements over to make room to make room for pivot.
+ */
+ int n = start - left; // The number of elements to move
+ // Switch is just an optimization for arraycopy in default case
+ switch(n) {
+ case 2: a[left + 2] = a[left + 1];
+ case 1: a[left + 1] = a[left];
+ break;
+ default: System.arraycopy(a, left, a, left + 1, n);
+ }
+ a[left] = pivot;
+ }
+ }
+
+ /**
+ * Returns the length of the run beginning at the specified position in
+ * the specified array and reverses the run if it is descending (ensuring
+ * that the run will always be ascending when the method returns).
+ *
+ * A run is the longest ascending sequence with:
+ *
+ * a[lo] <= a[lo + 1] <= a[lo + 2] <= ...
+ *
+ * or the longest descending sequence with:
+ *
+ * a[lo] > a[lo + 1] > a[lo + 2] > ...
+ *
+ * For its intended use in a stable mergesort, the strictness of the
+ * definition of "descending" is needed so that the call can safely
+ * reverse a descending sequence without violating stability.
+ *
+ * @param a the array in which a run is to be counted and possibly reversed
+ * @param lo index of the first element in the run
+ * @param hi index after the last element that may be contained in the run.
+ It is required that @code{lo < hi}.
+ * @param c the comparator to used for the sort
+ * @return the length of the run beginning at the specified position in
+ * the specified array
+ */
+ private static <T> int countRunAndMakeAscending(T[] a, int lo, int hi,
+ Comparator<? super T> c) {
+ if (DEBUG) assert lo < hi;
+ int runHi = lo + 1;
+ if (runHi == hi)
+ return 1;
+
+ // Find end of run, and reverse range if descending
+ if (c.compare(a[runHi++], a[lo]) < 0) { // Descending
+ while(runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)
+ runHi++;
+ reverseRange(a, lo, runHi);
+ } else { // Ascending
+ while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0)
+ runHi++;
+ }
+
+ return runHi - lo;
+ }
+
+ /**
+ * Reverse the specified range of the specified array.
+ *
+ * @param a the array in which a range is to be reversed
+ * @param lo the index of the first element in the range to be reversed
+ * @param hi the index after the last element in the range to be reversed
+ */
+ private static void reverseRange(Object[] a, int lo, int hi) {
+ hi--;
+ while (lo < hi) {
+ Object t = a[lo];
+ a[lo++] = a[hi];
+ a[hi--] = t;
+ }
+ }
+
+ /**
+ * Returns the minimum acceptable run length for an array of the specified
+ * length. Natural runs shorter than this will be extended with
+ * {@link #binarySort}.
+ *
+ * Roughly speaking, the computation is:
+ *
+ * If n < MIN_MERGE, return n (it's too small to bother with fancy stuff).
+ * Else if n is an exact power of 2, return MIN_MERGE/2.
+ * Else return an int k, MIN_MERGE/2 <= k <= MIN_MERGE, such that n/k
+ * is close to, but strictly less than, an exact power of 2.
+ *
+ * For the rationale, see listsort.txt.
+ *
+ * @param n the length of the array to be sorted
+ * @return the length of the minimum run to be merged
+ */
+ private static int minRunLength(int n) {
+ if (DEBUG) assert n >= 0;
+ int r = 0; // Becomes 1 if any 1 bits are shifted off
+ while (n >= MIN_MERGE) {
+ r |= (n & 1);
+ n >>= 1;
+ }
+ return n + r;
+ }
+
+ /**
+ * Pushes the specified run onto the pending-run stack.
+ *
+ * @param runBase index of the first element in the run
+ * @param runLen the number of elements in the run
+ */
+ private void pushRun(int runBase, int runLen) {
+ this.runBase[stackSize] = runBase;
+ this.runLen[stackSize] = runLen;
+ stackSize++;
+ }
+
+ /**
+ * Examines the stack of runs waiting to be merged and merges adjacent runs
+ * until the stack invariants are reestablished:
+ *
+ * 1. runLen[i - 3] > runLen[i - 2] + runLen[i - 1]
+ * 2. runLen[i - 2] > runLen[i - 1]
+ *
+ * This method is called each time a new run is pushed onto the stack,
+ * so the invariants are guaranteed to hold for i < stackSize upon
+ * entry to the method.
+ */
+ private void mergeCollapse() {
+ while (stackSize > 1) {
+ int n = stackSize - 2;
+ if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) {
+ if (runLen[n - 1] < runLen[n + 1])
+ n--;
+ mergeAt(n);
+ } else if (runLen[n] <= runLen[n + 1]) {
+ mergeAt(n);
+ } else {
+ break; // Invariant is established
+ }
+ }
+ }
+
+ /**
+ * Merges all runs on the stack until only one remains. This method is
+ * called once, to complete the sort.
+ */
+ private void mergeForceCollapse() {
+ while (stackSize > 1) {
+ int n = stackSize - 2;
+ if (n > 0 && runLen[n - 1] < runLen[n + 1])
+ n--;
+ mergeAt(n);
+ }
+ }
+
+ /**
+ * Merges the two runs at stack indices i and i+1. Run i must be
+ * the penultimate or antepenultimate run on the stack. In other words,
+ * i must be equal to stackSize-2 or stackSize-3.
+ *
+ * @param i stack index of the first of the two runs to merge
+ */
+ private void mergeAt(int i) {
+ if (DEBUG) assert stackSize >= 2;
+ if (DEBUG) assert i >= 0;
+ if (DEBUG) assert i == stackSize - 2 || i == stackSize - 3;
+
+ int base1 = runBase[i];
+ int len1 = runLen[i];
+ int base2 = runBase[i + 1];
+ int len2 = runLen[i + 1];
+ if (DEBUG) assert len1 > 0 && len2 > 0;
+ if (DEBUG) assert base1 + len1 == base2;
+
+ /*
+ * Record the length of the combined runs; if i is the 3rd-last
+ * run now, also slide over the last run (which isn't involved
+ * in this merge). The current run (i+1) goes away in any case.
+ */
+ runLen[i] = len1 + len2;
+ if (i == stackSize - 3) {
+ runBase[i + 1] = runBase[i + 2];
+ runLen[i + 1] = runLen[i + 2];
+ }
+ stackSize--;
+
+ /*
+ * Find where the first element of run2 goes in run1. Prior elements
+ * in run1 can be ignored (because they're already in place).
+ */
+ int k = gallopRight(a[base2], a, base1, len1, 0, c);
+ if (DEBUG) assert k >= 0;
+ base1 += k;
+ len1 -= k;
+ if (len1 == 0)
+ return;
+
+ /*
+ * Find where the last element of run1 goes in run2. Subsequent elements
+ * in run2 can be ignored (because they're already in place).
+ */
+ len2 = gallopLeft(a[base1 + len1 - 1], a, base2, len2, len2 - 1, c);
+ if (DEBUG) assert len2 >= 0;
+ if (len2 == 0)
+ return;
+
+ // Merge remaining runs, using tmp array with min(len1, len2) elements
+ if (len1 <= len2)
+ mergeLo(base1, len1, base2, len2);
+ else
+ mergeHi(base1, len1, base2, len2);
+ }
+
+ /**
+ * Locates the position at which to insert the specified key into the
+ * specified sorted range; if the range contains an element equal to key,
+ * returns the index of the leftmost equal element.
+ *
+ * @param key the key whose insertion point to search for
+ * @param a the array in which to search
+ * @param base the index of the first element in the range
+ * @param len the length of the range; must be > 0
+ * @param hint the index at which to begin the search, 0 <= hint < n.
+ * The closer hint is to the result, the faster this method will run.
+ * @param c the comparator used to order the range, and to search
+ * @return the int k, 0 <= k <= n such that a[b + k - 1] < key <= a[b + k],
+ * pretending that a[b - 1] is minus infinity and a[b + n] is infinity.
+ * In other words, key belongs at index b + k; or in other words,
+ * the first k elements of a should precede key, and the last n - k
+ * should follow it.
+ */
+ private static <T> int gallopLeft(T key, T[] a, int base, int len, int hint,
+ Comparator<? super T> c) {
+ if (DEBUG) assert len > 0 && hint >= 0 && hint < len;
+ int lastOfs = 0;
+ int ofs = 1;
+ if (c.compare(key, a[base + hint]) > 0) {
+ // Gallop right until a[base+hint+lastOfs] < key <= a[base+hint+ofs]
+ int maxOfs = len - hint;
+ while (ofs < maxOfs && c.compare(key, a[base + hint + ofs]) > 0) {
+ lastOfs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) // int overflow
+ ofs = maxOfs;
+ }
+ if (ofs > maxOfs)
+ ofs = maxOfs;
+
+ // Make offsets relative to base
+ lastOfs += hint;
+ ofs += hint;
+ } else { // key <= a[base + hint]
+ // Gallop left until a[base+hint-ofs] < key <= a[base+hint-lastOfs]
+ final int maxOfs = hint + 1;
+ while (ofs < maxOfs && c.compare(key, a[base + hint - ofs]) <= 0) {
+ lastOfs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) // int overflow
+ ofs = maxOfs;
+ }
+ if (ofs > maxOfs)
+ ofs = maxOfs;
+
+ // Make offsets relative to base
+ int tmp = lastOfs;
+ lastOfs = hint - ofs;
+ ofs = hint - tmp;
+ }
+ if (DEBUG) assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
+
+ /*
+ * Now a[base+lastOfs] < key <= a[base+ofs], so key belongs somewhere
+ * to the right of lastOfs but no farther right than ofs. Do a binary
+ * search, with invariant a[base + lastOfs - 1] < key <= a[base + ofs].
+ */
+ lastOfs++;
+ while (lastOfs < ofs) {
+ int m = lastOfs + ((ofs - lastOfs) >>> 1);
+
+ if (c.compare(key, a[base + m]) > 0)
+ lastOfs = m + 1; // a[base + m] < key
+ else
+ ofs = m; // key <= a[base + m]
+ }
+ if (DEBUG) assert lastOfs == ofs; // so a[base + ofs - 1] < key <= a[base + ofs]
+ return ofs;
+ }
+
+ /**
+ * Like gallopLeft, except that if the range contains an element equal to
+ * key, gallopRight returns the index after the rightmost equal element.
+ *
+ * @param key the key whose insertion point to search for
+ * @param a the array in which to search
+ * @param base the index of the first element in the range
+ * @param len the length of the range; must be > 0
+ * @param hint the index at which to begin the search, 0 <= hint < n.
+ * The closer hint is to the result, the faster this method will run.
+ * @param c the comparator used to order the range, and to search
+ * @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k]
+ */
+ private static <T> int gallopRight(T key, T[] a, int base, int len,
+ int hint, Comparator<? super T> c) {
+ if (DEBUG) assert len > 0 && hint >= 0 && hint < len;
+
+ int ofs = 1;
+ int lastOfs = 0;
+ if (c.compare(key, a[base + hint]) < 0) {
+ // Gallop left until a[b+hint - ofs] <= key < a[b+hint - lastOfs]
+ int maxOfs = hint + 1;
+ while (ofs < maxOfs && c.compare(key, a[base + hint - ofs]) < 0) {
+ lastOfs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) // int overflow
+ ofs = maxOfs;
+ }
+ if (ofs > maxOfs)
+ ofs = maxOfs;
+
+ // Make offsets relative to b
+ int tmp = lastOfs;
+ lastOfs = hint - ofs;
+ ofs = hint - tmp;
+ } else { // a[b + hint] <= key
+ // Gallop right until a[b+hint + lastOfs] <= key < a[b+hint + ofs]
+ int maxOfs = len - hint;
+ while (ofs < maxOfs && c.compare(key, a[base + hint + ofs]) >= 0) {
+ lastOfs = ofs;
+ ofs = (ofs << 1) + 1;
+ if (ofs <= 0) // int overflow
+ ofs = maxOfs;
+ }
+ if (ofs > maxOfs)
+ ofs = maxOfs;
+
+ // Make offsets relative to b
+ lastOfs += hint;
+ ofs += hint;
+ }
+ if (DEBUG) assert -1 <= lastOfs && lastOfs < ofs && ofs <= len;
+
+ /*
+ * Now a[b + lastOfs] <= key < a[b + ofs], so key belongs somewhere to
+ * the right of lastOfs but no farther right than ofs. Do a binary
+ * search, with invariant a[b + lastOfs - 1] <= key < a[b + ofs].
+ */
+ lastOfs++;
+ while (lastOfs < ofs) {
+ int m = lastOfs + ((ofs - lastOfs) >>> 1);
+
+ if (c.compare(key, a[base + m]) < 0)
+ ofs = m; // key < a[b + m]
+ else
+ lastOfs = m + 1; // a[b + m] <= key
+ }
+ if (DEBUG) assert lastOfs == ofs; // so a[b + ofs - 1] <= key < a[b + ofs]
+ return ofs;
+ }
+
+ /**
+ * Merges two adjacent runs in place, in a stable fashion. The first
+ * element of the first run must be greater than the first element of the
+ * second run (a[base1] > a[base2]), and the last element of the first run
+ * (a[base1 + len1-1]) must be greater than all elements of the second run.
+ *
+ * For performance, this method should be called only when len1 <= len2;
+ * its twin, mergeHi should be called if len1 >= len2. (Either method
+ * may be called if len1 == len2.)
+ *
+ * @param base1 index of first element in first run to be merged
+ * @param len1 length of first run to be merged (must be > 0)
+ * @param base2 index of first element in second run to be merged
+ * (must be aBase + aLen)
+ * @param len2 length of second run to be merged (must be > 0)
+ */
+ private void mergeLo(int base1, int len1, int base2, int len2) {
+ if (DEBUG) assert len1 > 0 && len2 > 0 && base1 + len1 == base2;
+
+ // Copy first run into temp array
+ T[] a = this.a; // For performance
+ T[] tmp = ensureCapacity(len1);
+ System.arraycopy(a, base1, tmp, 0, len1);
+
+ int cursor1 = 0; // Indexes into tmp array
+ int cursor2 = base2; // Indexes int a
+ int dest = base1; // Indexes int a
+
+ // Move first element of second run and deal with degenerate cases
+ a[dest++] = a[cursor2++];
+ if (--len2 == 0) {
+ System.arraycopy(tmp, cursor1, a, dest, len1);
+ return;
+ }
+ if (len1 == 1) {
+ System.arraycopy(a, cursor2, a, dest, len2);
+ a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
+ return;
+ }
+
+ Comparator<? super T> c = this.c; // Use local variable for performance
+ int minGallop = this.minGallop; // " " " " "
+ outer:
+ while (true) {
+ int count1 = 0; // Number of times in a row that first run won
+ int count2 = 0; // Number of times in a row that second run won
+
+ /*
+ * Do the straightforward thing until (if ever) one run starts
+ * winning consistently.
+ */
+ do {
+ if (DEBUG) assert len1 > 1 && len2 > 0;
+ if (c.compare(a[cursor2], tmp[cursor1]) < 0) {
+ a[dest++] = a[cursor2++];
+ count2++;
+ count1 = 0;
+ if (--len2 == 0)
+ break outer;
+ } else {
+ a[dest++] = tmp[cursor1++];
+ count1++;
+ count2 = 0;
+ if (--len1 == 1)
+ break outer;
+ }
+ } while ((count1 | count2) < minGallop);
+
+ /*
+ * One run is winning so consistently that galloping may be a
+ * huge win. So try that, and continue galloping until (if ever)
+ * neither run appears to be winning consistently anymore.
+ */
+ do {
+ if (DEBUG) assert len1 > 1 && len2 > 0;
+ count1 = gallopRight(a[cursor2], tmp, cursor1, len1, 0, c);
+ if (count1 != 0) {
+ System.arraycopy(tmp, cursor1, a, dest, count1);
+ dest += count1;
+ cursor1 += count1;
+ len1 -= count1;
+ if (len1 <= 1) // len1 == 1 || len1 == 0
+ break outer;
+ }
+ a[dest++] = a[cursor2++];
+ if (--len2 == 0)
+ break outer;
+
+ count2 = gallopLeft(tmp[cursor1], a, cursor2, len2, 0, c);
+ if (count2 != 0) {
+ System.arraycopy(a, cursor2, a, dest, count2);
+ dest += count2;
+ cursor2 += count2;
+ len2 -= count2;
+ if (len2 == 0)
+ break outer;
+ }
+ a[dest++] = tmp[cursor1++];
+ if (--len1 == 1)
+ break outer;
+ minGallop--;
+ } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
+ if (minGallop < 0)
+ minGallop = 0;
+ minGallop += 2; // Penalize for leaving gallop mode
+ } // End of "outer" loop
+ this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field
+
+ if (len1 == 1) {
+ if (DEBUG) assert len2 > 0;
+ System.arraycopy(a, cursor2, a, dest, len2);
+ a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge
+ } else if (len1 == 0) {
+ throw new IllegalArgumentException(
+ "Comparison method violates its general contract!");
+ } else {
+ if (DEBUG) assert len2 == 0;
+ if (DEBUG) assert len1 > 1;
+ System.arraycopy(tmp, cursor1, a, dest, len1);
+ }
+ }
+
+ /**
+ * Like mergeLo, except that this method should be called only if
+ * len1 >= len2; mergeLo should be called if len1 <= len2. (Either method
+ * may be called if len1 == len2.)
+ *
+ * @param base1 index of first element in first run to be merged
+ * @param len1 length of first run to be merged (must be > 0)
+ * @param base2 index of first element in second run to be merged
+ * (must be aBase + aLen)
+ * @param len2 length of second run to be merged (must be > 0)
+ */
+ private void mergeHi(int base1, int len1, int base2, int len2) {
+ if (DEBUG) assert len1 > 0 && len2 > 0 && base1 + len1 == base2;
+
+ // Copy second run into temp array
+ T[] a = this.a; // For performance
+ T[] tmp = ensureCapacity(len2);
+ System.arraycopy(a, base2, tmp, 0, len2);
+
+ int cursor1 = base1 + len1 - 1; // Indexes into a
+ int cursor2 = len2 - 1; // Indexes into tmp array
+ int dest = base2 + len2 - 1; // Indexes into a
+
+ // Move last element of first run and deal with degenerate cases
+ a[dest--] = a[cursor1--];
+ if (--len1 == 0) {
+ System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2);
+ return;
+ }
+ if (len2 == 1) {
+ dest -= len1;
+ cursor1 -= len1;
+ System.arraycopy(a, cursor1 + 1, a, dest + 1, len1);
+ a[dest] = tmp[cursor2];
+ return;
+ }
+
+ Comparator<? super T> c = this.c; // Use local variable for performance
+ int minGallop = this.minGallop; // " " " " "
+ outer:
+ while (true) {
+ int count1 = 0; // Number of times in a row that first run won
+ int count2 = 0; // Number of times in a row that second run won
+
+ /*
+ * Do the straightforward thing until (if ever) one run
+ * appears to win consistently.
+ */
+ do {
+ if (DEBUG) assert len1 > 0 && len2 > 1;
+ if (c.compare(tmp[cursor2], a[cursor1]) < 0) {
+ a[dest--] = a[cursor1--];
+ count1++;
+ count2 = 0;
+ if (--len1 == 0)
+ break outer;
+ } else {
+ a[dest--] = tmp[cursor2--];
+ count2++;
+ count1 = 0;
+ if (--len2 == 1)
+ break outer;
+ }
+ } while ((count1 | count2) < minGallop);
+
+ /*
+ * One run is winning so consistently that galloping may be a
+ * huge win. So try that, and continue galloping until (if ever)
+ * neither run appears to be winning consistently anymore.
+ */
+ do {
+ if (DEBUG) assert len1 > 0 && len2 > 1;
+ count1 = len1 - gallopRight(tmp[cursor2], a, base1, len1, len1 - 1, c);
+ if (count1 != 0) {
+ dest -= count1;
+ cursor1 -= count1;
+ len1 -= count1;
+ System.arraycopy(a, cursor1 + 1, a, dest + 1, count1);
+ if (len1 == 0)
+ break outer;
+ }
+ a[dest--] = tmp[cursor2--];
+ if (--len2 == 1)
+ break outer;
+
+ count2 = len2 - gallopLeft(a[cursor1], tmp, 0, len2, len2 - 1, c);
+ if (count2 != 0) {
+ dest -= count2;
+ cursor2 -= count2;
+ len2 -= count2;
+ System.arraycopy(tmp, cursor2 + 1, a, dest + 1, count2);
+ if (len2 <= 1) // len2 == 1 || len2 == 0
+ break outer;
+ }
+ a[dest--] = a[cursor1--];
+ if (--len1 == 0)
+ break outer;
+ minGallop--;
+ } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP);
+ if (minGallop < 0)
+ minGallop = 0;
+ minGallop += 2; // Penalize for leaving gallop mode
+ } // End of "outer" loop
+ this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field
+
+ if (len2 == 1) {
+ if (DEBUG) assert len1 > 0;
+ dest -= len1;
+ cursor1 -= len1;
+ System.arraycopy(a, cursor1 + 1, a, dest + 1, len1);
+ a[dest] = tmp[cursor2]; // Move first elt of run2 to front of merge
+ } else if (len2 == 0) {
+ throw new IllegalArgumentException(
+ "Comparison method violates its general contract!");
+ } else {
+ if (DEBUG) assert len1 == 0;
+ if (DEBUG) assert len2 > 0;
+ System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2);
+ }
+ }
+
+ /**
+ * Ensures that the external array tmp has at least the specified
+ * number of elements, increasing its size if necessary. The size
+ * increases exponentially to ensure amortized linear time complexity.
+ *
+ * @param minCapacity the minimum required capacity of the tmp array
+ * @return tmp, whether or not it grew
+ */
+ private T[] ensureCapacity(int minCapacity) {
+ if (tmp.length < minCapacity) {
+ // Compute smallest power of 2 > minCapacity
+ int newSize = minCapacity;
+ newSize |= newSize >> 1;
+ newSize |= newSize >> 2;
+ newSize |= newSize >> 4;
+ newSize |= newSize >> 8;
+ newSize |= newSize >> 16;
+ newSize++;
+
+ if (newSize < 0) // Not bloody likely!
+ newSize = minCapacity;
+ else
+ newSize = Math.min(newSize, a.length >>> 1);
+
+ @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
+ T[] newArray = (T[]) new Object[newSize];
+ tmp = newArray;
+ }
+ return tmp;
+ }
+
+ /**
+ * Checks that fromIndex and toIndex are in range, and throws an
+ * appropriate exception if they aren't.
+ *
+ * @param arrayLen the length of the array
+ * @param fromIndex the index of the first element of the range
+ * @param toIndex the index after the last element of the range
+ * @throws IllegalArgumentException if fromIndex > toIndex
+ * @throws ArrayIndexOutOfBoundsException if fromIndex < 0
+ * or toIndex > arrayLen
+ */
+ private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) {
+ if (fromIndex > toIndex)
+ throw new IllegalArgumentException("fromIndex(" + fromIndex +
+ ") > toIndex(" + toIndex+")");
+ if (fromIndex < 0)
+ throw new ArrayIndexOutOfBoundsException(fromIndex);
+ if (toIndex > arrayLen)
+ throw new ArrayIndexOutOfBoundsException(toIndex);
+ }
+}
diff --git a/libcore/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java b/libcore/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
index 2718199..1f7589d 100644
--- a/libcore/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
+++ b/libcore/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
@@ -150,8 +150,6 @@
* Lists of Strings.
*
* @return an unmodifiable map of the headers
- *
- * @since 1.4
*/
public Map<String, List<String>> getFieldMap() {
Map<String, List<String>> result = new HashMap<String, List<String>>(
diff --git a/libcore/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java b/libcore/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
index 76432e6..6f5a2be 100644
--- a/libcore/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
+++ b/libcore/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
@@ -141,23 +141,41 @@
throwClosed();
}
- return is.read();
+ int result = is.read();
+ if (useCaches && cacheOut != null) {
+ cacheOut.write(result);
+ }
+ return result;
}
public int read(byte[] b, int off, int len) throws IOException {
if (closed) {
throwClosed();
}
-
- return is.read(b, off, len);
+ int result = is.read(b, off, len);
+ if (result > 0) {
+ // if user has set useCache to true and cache exists, writes to
+ // it
+ if (useCaches && cacheOut != null) {
+ cacheOut.write(b, off, result);
+ }
+ }
+ return result;
}
public int read(byte[] b) throws IOException {
if (closed) {
throwClosed();
}
-
- return is.read(b);
+ int result = is.read(b);
+ if (result > 0) {
+ // if user has set useCache to true and cache exists, writes to
+ // it
+ if (useCaches && cacheOut != null) {
+ cacheOut.write(b, 0, result);
+ }
+ }
+ return result;
}
public long skip(long n) throws IOException {
@@ -178,6 +196,9 @@
public void close() {
closed = true;
+ if (useCaches && cacheRequest != null) {
+ cacheRequest.abort();
+ }
}
public void mark(int readLimit) {
@@ -1000,8 +1021,6 @@
* header field values associated with that key name.
*
* @return the mapping of header field names to values
- *
- * @since 1.4
*/
@Override
public Map<String, List<String>> getHeaderFields() {
diff --git a/libcore/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java b/libcore/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java
index b062aee..8c8257b 100644
--- a/libcore/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java
+++ b/libcore/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java
@@ -144,7 +144,10 @@
}
- static String hexCharacters = "0123456789ABCDEF";
+ // BEGIN android-changed
+ static char[] hexCharacters = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
+ '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+ // END android-changed
public static String createIPAddrStringFromByteArray(byte ipByteArray[]) {
if (ipByteArray.length == 4) {
@@ -160,15 +163,31 @@
return addressToString(bytesToInt(ipv4ByteArray, 0));
}
StringBuilder buffer = new StringBuilder();
- for (int i = 0; i < ipByteArray.length; i++) {
- int j = (ipByteArray[i] & 0xf0) >>> 4;
- buffer.append(hexCharacters.charAt(j));
- j = ipByteArray[i] & 0x0f;
- buffer.append(hexCharacters.charAt(j));
- if (i % 2 != 0 && (i + 1) < ipByteArray.length) {
+ // BEGIN android-changed
+ for (int i = 0; i < 8; i++) { // ipByteArray.length / 2
+
+ int num = (ipByteArray[2 * i] & 0xff) << 8;
+ num ^= ipByteArray[2 * i + 1] & 0xff;
+
+ // count the digits to display without leading 0
+ int count = 1, j = num;
+ while ((j >>>= 4) != 0) {
+ count++;
+ }
+
+ char[] buf = new char[count];
+ do {
+ int t = num & 0x0f;
+ buf[--count] = hexCharacters[t];
+ num >>>= 4;
+ } while (count > 0);
+
+ buffer.append(buf);
+ if ((i + 1) < 8) { // ipByteArray.length / 2
buffer.append(":");
}
}
+ // END android-changed
return buffer.toString();
}
return null;
@@ -293,6 +312,21 @@
+ ((value >> 8) & 0xff) + "." + (value & 0xff);
}
+ // BEGIN android-added
+ // copied from a newer version of harmony
+ public static boolean isIP6AddressInFullForm(String ipAddress) {
+ if (isValidIP6Address(ipAddress)) {
+ int doubleColonIndex = ipAddress.indexOf("::");
+ if (doubleColonIndex >= 0) {
+ // Simplified form which contains ::
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+ // END android-added
+
public static boolean isValidIP6Address(String ipAddress) {
int length = ipAddress.length();
boolean doubleColon = false;
@@ -501,4 +535,5 @@
}
// END android-changed
}
+
}
diff --git a/libcore/luni/src/main/native/java_net_InetAddress.cpp b/libcore/luni/src/main/native/java_net_InetAddress.cpp
index a7693cd..cf026bc 100644
--- a/libcore/luni/src/main/native/java_net_InetAddress.cpp
+++ b/libcore/luni/src/main/native/java_net_InetAddress.cpp
@@ -33,6 +33,8 @@
#include <sys/socket.h>
+static jclass byteArrayClass = NULL;
+
static jstring InetAddress_gethostname(JNIEnv* env, jobject obj)
{
char name[256];
@@ -57,10 +59,24 @@
}
}
-static jbyteArray getHostByNameAdb(JNIEnv* env, const char* name)
+static void logIpString(struct addrinfo* ai, const char* name)
+{
+ char ipString[INET6_ADDRSTRLEN];
+ int result = getnameinfo(ai->ai_addr, ai->ai_addrlen, ipString,
+ sizeof(ipString), NULL, 0, NI_NUMERICHOST);
+ if (result == 0) {
+ LOGD("%s: %s (family %d, proto %d)", name, ipString, ai->ai_family,
+ ai->ai_protocol);
+ } else {
+ LOGE("%s: getnameinfo: %s", name, gai_strerror(result));
+ }
+}
+
+static jobjectArray getAllByNameUsingAdb(JNIEnv* env, const char* name)
{
struct in_addr outaddr;
- jbyteArray out = NULL;
+ jobjectArray addressArray = NULL;
+ jbyteArray byteArray;
#if 0
LOGI("ADB networking: -gethostbyname err %d addr 0x%08x %u.%u.%u.%u",
@@ -70,155 +86,214 @@
#endif
if (adb_networking_gethostbyname(name, &outaddr) >= 0) {
- out = env->NewByteArray(4);
- env->SetByteArrayRegion(out, 0, 4, (jbyte*) &outaddr.s_addr);
+ addressArray = env->NewObjectArray(1, byteArrayClass, NULL);
+ byteArray = env->NewByteArray(4);
+ if (addressArray && byteArray) {
+ env->SetByteArrayRegion(byteArray, 0, 4, (jbyte*) &outaddr.s_addr);
+ env->SetObjectArrayElement(addressArray, 1, byteArray);
+ }
}
-
- return out;
+ return addressArray;
}
-static jbyteArray getHostByNameGetAddrInfo(JNIEnv* env, const char* name, jboolean preferIPv6Address)
+static jobjectArray getAllByNameUsingDns(JNIEnv* env, const char* name,
+ jboolean preferIPv4Stack)
{
- struct addrinfo hints, *res = NULL;
- jbyteArray out = NULL;
+ struct addrinfo hints, *addressList = NULL, *addrInfo;
+ jobjectArray addressArray = NULL;
memset(&hints, 0, sizeof(hints));
- hints.ai_family = preferIPv6Address ? AF_UNSPEC : AF_INET;
+ /*
+ * IPv4 only for now until the socket code supports IPv6; otherwise, the
+ * resolver will create two separate requests, one for IPv4 and one,
+ * currently unnecessary, for IPv6.
+ */
+ hints.ai_family = AF_INET;
+ /*
+ * If we don't specify a socket type, every address will appear twice, once
+ * for SOCK_STREAM and one for SOCK_DGRAM. Since we do not return the family
+ * anyway, just pick one.
+ */
+ hints.ai_socktype = SOCK_STREAM;
- int ret = getaddrinfo(name, NULL, &hints, &res);
- if (ret == 0 && res) {
- struct sockaddr* saddr = res[0].ai_addr;
- size_t addrlen = 0;
- void* rawaddr;
-
- switch (res[0].ai_family) {
- // Find the raw address length and start pointer.
- case AF_INET6:
- addrlen = 16;
- rawaddr = &((struct sockaddr_in6*) saddr)->sin6_addr.s6_addr;
- break;
- case AF_INET:
- addrlen = 4;
- rawaddr = &((struct sockaddr_in*) saddr)->sin_addr.s_addr;
- break;
- default:
- // Do nothing. addrlength = 0, so we will return NULL.
- break;
+ int result = getaddrinfo(name, NULL, &hints, &addressList);
+ if (result == 0 && addressList) {
+ // Count results so we know how to size the output array.
+ int addressCount = 0;
+ for (addrInfo = addressList; addrInfo; addrInfo = addrInfo->ai_next) {
+ if (addrInfo->ai_family == AF_INET ||
+ addrInfo->ai_family == AF_INET6) {
+ addressCount++;
+ }
}
- if (addrlen) {
- out = env->NewByteArray(addrlen);
- env->SetByteArrayRegion(out, 0, addrlen, (jbyte*) rawaddr);
+ // Prepare output array.
+ addressArray = env->NewObjectArray(addressCount, byteArrayClass, NULL);
+ if (addressArray == NULL) {
+ // Appropriate exception will be thrown.
+ LOGE("getAllByNameUsingDns: could not allocate output array");
+ freeaddrinfo(addrInfo);
+ return NULL;
}
- } else if (ret == EAI_SYSTEM && errno == EACCES) {
+
+ // Examine returned addresses one by one, save them in the output array.
+ int index = 0;
+ for (addrInfo = addressList; addrInfo; addrInfo = addrInfo->ai_next) {
+ struct sockaddr* address = addrInfo->ai_addr;
+ size_t addressLength = 0;
+ void* rawAddress;
+
+ switch (addrInfo->ai_family) {
+ // Find the raw address length and start pointer.
+ case AF_INET6:
+ addressLength = 16;
+ rawAddress =
+ &((struct sockaddr_in6*) address)->sin6_addr.s6_addr;
+ logIpString(addrInfo, name);
+ break;
+ case AF_INET:
+ addressLength = 4;
+ rawAddress =
+ &((struct sockaddr_in*) address)->sin_addr.s_addr;
+ logIpString(addrInfo, name);
+ break;
+ default:
+ // Unknown address family. Skip this address.
+ LOGE("getAllByNameUsingDns: Unknown address family %d",
+ addrInfo->ai_family);
+ continue;
+ }
+
+ // Convert each IP address into a Java byte array.
+ jbyteArray bytearray = env->NewByteArray(addressLength);
+ if (bytearray == NULL) {
+ // Out of memory error will be thrown on return.
+ LOGE("getAllByNameUsingDns: Can't allocate %d-byte array",
+ addressLength);
+ addressArray = NULL;
+ break;
+ }
+ env->SetByteArrayRegion(bytearray, 0, addressLength,
+ (jbyte*) rawAddress);
+ env->SetObjectArrayElement(addressArray, index, bytearray);
+ env->DeleteLocalRef(bytearray);
+ index++;
+ }
+ } else if (result == EAI_SYSTEM && errno == EACCES) {
/* No permission to use network */
jniThrowException(
- env, "java/lang/SecurityException",
- "Permission denied (maybe missing INTERNET permission)");
+ env, "java/lang/SecurityException",
+ "Permission denied (maybe missing INTERNET permission)");
+ } else {
+ // Do nothing. Return value will be null and the caller will throw an
+ // UnknownHostExeption.
}
- if (res) {
- freeaddrinfo(res);
+ if (addressList) {
+ freeaddrinfo(addressList);
}
- return out;
+ return addressArray;
}
-jbyteArray InetAddress_gethostbyname(JNIEnv* env, jobject obj, jstring nameStr, jboolean preferIPv6Address)
+jobjectArray InetAddress_getallbyname(JNIEnv* env, jobject obj,
+ jstring javaName,
+ jboolean preferIPv4Stack)
{
- if (nameStr == NULL) {
+ if (javaName == NULL) {
throwNullPointerException(env);
- return 0;
+ return NULL;
}
- const char* name = env->GetStringUTFChars(nameStr, NULL);
- jbyteArray out = NULL;
+ const char* name = env->GetStringUTFChars(javaName, NULL);
+ jobjectArray out = NULL;
char useAdbNetworkingProperty[PROPERTY_VALUE_MAX];
char adbConnected[PROPERTY_VALUE_MAX];
- property_get ("android.net.use-adb-networking",
+ property_get("android.net.use-adb-networking",
useAdbNetworkingProperty, "");
- property_get ("adb.connected",
+ property_get("adb.connected",
adbConnected, "");
// Any non-empty string value for use-adb-networking is considered "set"
if ((strlen(useAdbNetworkingProperty) > 0)
&& (strlen(adbConnected) > 0) ) {
- out = getHostByNameAdb(env, name);
+ out = getAllByNameUsingAdb(env, name);
} else {
- out = getHostByNameGetAddrInfo(env, name, preferIPv6Address);
+ out = getAllByNameUsingDns(env, name, preferIPv4Stack);
}
if (!out) {
LOGI("Unknown host %s, throwing UnknownHostException", name);
jniThrowException(env, "java/net/UnknownHostException", name);
}
- env->ReleaseStringUTFChars(nameStr, name);
+ env->ReleaseStringUTFChars(javaName, name);
return out;
}
-static jstring InetAddress_gethostbyaddr(JNIEnv* env, jobject obj, jstring addrStr)
+static jstring InetAddress_gethostbyaddr(JNIEnv* env, jobject obj,
+ jbyteArray javaAddress)
{
- if (addrStr == NULL) {
- throwNullPointerException(env);
- return false;
- }
-
- jstring result;
- const char* addr = env->GetStringUTFChars(addrStr, NULL);
-
- struct hostent* ent = gethostbyaddr(addr, strlen(addr), AF_INET);
-
- if (ent != NULL && ent->h_name != NULL) {
- result = env->NewStringUTF(ent->h_name);
- } else {
- result = NULL;
- }
-
- env->ReleaseStringUTFChars(addrStr, addr);
-
- return result;
-}
-
-
-static jobjectArray InetAddress_getaliasesbyname(JNIEnv* env, jobject obj, jstring nameStr)
-{
- if (nameStr == NULL) {
+ if (javaAddress == NULL) {
throwNullPointerException(env);
return NULL;
}
- jclass clazz = env->FindClass("java/lang/String");
- if (clazz == NULL) {
- jniThrowException(env, "java/lang/ClassNotFoundException", "couldn't find class java.lang.String");
+ size_t addrlen = env->GetArrayLength(javaAddress);
+ jbyte* rawAddress = env->GetByteArrayElements(javaAddress, NULL);
+ if (rawAddress == NULL) {
+ throwNullPointerException(env);
return NULL;
}
- jobjectArray result;
-
- const char* name = env->GetStringUTFChars(nameStr, NULL);
-
- struct hostent* ent = gethostbyname(name);
-
- if (ent != NULL) {
- // Count aliases
- int count = 0;
- while (ent->h_aliases[count] != NULL) {
- count++;
- }
-
- // Create an array of String objects and fill it.
- result = env->NewObjectArray(count, clazz, NULL);
- int i;
- for (i = 0; i < count; i++) {
- env->SetObjectArrayElement(result, i, env->NewStringUTF(ent->h_aliases[i]));
- }
- } else {
- result = env->NewObjectArray(0, clazz, NULL);
+ // Convert the raw address bytes into a socket address structure.
+ struct sockaddr_storage ss;
+ struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss;
+ size_t socklen;
+ switch (addrlen) {
+ case 4:
+ socklen = sizeof(struct sockaddr_in);
+ memset(sin, 0, sizeof(struct sockaddr_in));
+ sin->sin_family = AF_INET;
+ memcpy(&sin->sin_addr.s_addr, rawAddress, 4);
+ break;
+ case 16:
+ socklen = sizeof(struct sockaddr_in6);
+ memset(sin6, 0, sizeof(struct sockaddr_in6));
+ sin6->sin6_family = AF_INET6;
+ memcpy(&sin6->sin6_addr.s6_addr, rawAddress, 4);
+ break;
+ default:
+ jniThrowException(env, "java/net/UnknownHostException",
+ "Invalid address length");
+ return NULL;
}
- env->ReleaseStringUTFChars(nameStr, name);
+
+ // Convert the socket address structure to an IP string for logging.
+ int ret;
+ char ipstr[INET6_ADDRSTRLEN];
+ ret = getnameinfo((struct sockaddr *) &ss, socklen, ipstr, sizeof(ipstr),
+ NULL, 0, NI_NUMERICHOST);
+ if (ret) {
+ LOGE("gethostbyaddr: getnameinfo: %s", gai_strerror(ret));
+ return NULL;
+ }
+
+ // Look up the IP address from the socket address structure.
+ jstring result = NULL;
+ char name[NI_MAXHOST];
+ ret = getnameinfo((struct sockaddr *) &ss, socklen, name, sizeof(name),
+ NULL, 0, 0);
+ if (ret == 0) {
+ LOGI("gethostbyaddr: getnameinfo: %s = %s", ipstr, name);
+ result = env->NewStringUTF(name);
+ } else {
+ LOGE("gethostbyaddr: getnameinfo: unknown host %s: %s", ipstr,
+ gai_strerror(ret));
+ }
return result;
}
@@ -228,18 +303,24 @@
*/
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
- { "getaliasesbyname", "(Ljava/lang/String;)[Ljava/lang/String;",
- (void*) InetAddress_getaliasesbyname },
- { "gethostbyaddr", "(Ljava/lang/String;)Ljava/lang/String;",
+ { "gethostbyaddr", "([B)Ljava/lang/String;",
(void*) InetAddress_gethostbyaddr },
- { "gethostbyname", "(Ljava/lang/String;Z)[B",
- (void*) InetAddress_gethostbyname },
+ { "getallbyname", "(Ljava/lang/String;Z)[[B",
+ (void*) InetAddress_getallbyname },
{ "gethostname", "()Ljava/lang/String;",
- (void*) InetAddress_gethostname }
+ (void*) InetAddress_gethostname },
};
extern "C" int register_java_net_InetAddress(JNIEnv* env)
{
+ jclass tempClass = env->FindClass("[B");
+ if (tempClass) {
+ byteArrayClass = (jclass) env->NewGlobalRef(tempClass);
+ }
+ if (!byteArrayClass) {
+ LOGE("register_java_net_InetAddress: cannot allocate byte array class");
+ return -1;
+ }
return jniRegisterNativeMethods(env, "java/net/InetAddress",
gMethods, NELEM(gMethods));
}
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AllTests.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AllTests.java
index a81be7e..b4f3e5f 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AllTests.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AllTests.java
@@ -93,7 +93,6 @@
suite.addTestSuite(RuntimePermissionTest.class);
suite.addTestSuite(RuntimeTest.class);
suite.addTestSuite(SecurityExceptionTest.class);
- suite.addTestSuite(SecurityManager2Test.class);
suite.addTestSuite(SecurityManagerTest.class);
suite.addTestSuite(ShortTest.class);
suite.addTestSuite(StackOverflowErrorTest.class);
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CharacterImplTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CharacterImplTest.java
index 1ba3f2e..93e3abb 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CharacterImplTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CharacterImplTest.java
@@ -16,6 +16,7 @@
package org.apache.harmony.luni.tests.java.lang;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -32,6 +33,7 @@
method = "valueOf",
args = {char.class}
)
+ @AndroidOnly("valueOf doesn't return the same values on RI.")
public void test_valueOfC() {
// test the cache range
for (char c = '\u0000'; c < 512; c++) {
@@ -40,7 +42,7 @@
assertEquals(e, a);
// WARN: this assertion may not be valid on other JREs
- assertEquals(Character.valueOf(c), Character.valueOf(c));
+ assertSame(Character.valueOf(c), Character.valueOf(c));
}
// test the rest of the chars
for (int c = '\u0512'; c <= Character.MAX_VALUE; c++) {
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java
index 0f3ea2d..9d9a086 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java
@@ -18,6 +18,7 @@
package org.apache.harmony.luni.tests.java.lang;
import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -123,7 +124,8 @@
method = "clearAssertionStatus",
args = {}
)
- @KnownFailure("clearAssertionStatus method is not supported.")
+ @KnownFailure("Android doesn't support assertions to be activated " +
+ "through the api")
public void test_clearAssertionStatus() {
String className = getClass().getPackage().getName() + ".TestAssertions";
String className1 = getClass().getPackage().getName() + ".TestAssertions1";
@@ -399,8 +401,8 @@
method = "loadClass",
args = {java.lang.String.class}
)
- @KnownFailure("Both threads try to define class; " +
- "findClass method is not supported.")
+ @BrokenTest("Both threads try to define class. But defineClass is not " +
+ "supported on Adnroid. so both seem to succeed defining the class.")
public void test_loadClass_concurrentLoad() throws Exception
{
Object lock = new Object();
@@ -552,6 +554,8 @@
fail("IOException getting stream for resource : " + e.getMessage());
}
+
+
assertNull(ClassLoader.getSystemClassLoader().
getResource("not.found.resource"));
}
@@ -602,7 +606,7 @@
* @tests java.lang.ClassLoader#getSystemClassLoader()
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.SUFFICIENT,
notes = "",
method = "getSystemClassLoader",
args = {}
@@ -611,6 +615,7 @@
// Test for method java.lang.ClassLoader
// java.lang.ClassLoader.getSystemClassLoader()
ClassLoader cl = ClassLoader.getSystemClassLoader();
+
java.io.InputStream is = cl.getResourceAsStream("hyts_Foo.c");
assertNotNull("Failed to find resource from system classpath", is);
try {
@@ -618,6 +623,44 @@
} catch (java.io.IOException e) {
}
+ SecurityManager sm = new SecurityManager() {
+ public void checkPermission(Permission perm) {
+ if(perm.getName().equals("getClassLoader")) {
+ throw new SecurityException();
+ }
+ }
+ };
+
+ SecurityManager oldManager = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ ClassLoader.getSystemClassLoader();
+ } catch(SecurityException se) {
+ //expected
+ } finally {
+ System.setSecurityManager(oldManager);
+ }
+/*
+ * // java.lang.Error is not thrown on RI, but it's specified.
+ *
+ * String keyProp = "java.system.class.loader";
+ * String oldProp = System.getProperty(keyProp);
+ * System.setProperty(keyProp, "java.test.UnknownClassLoader");
+ * boolean isFailed = false;
+ * try {
+ * ClassLoader.getSystemClassLoader();
+ * isFailed = true;
+ * } catch(java.lang.Error e) {
+ * //expected
+ * } finally {
+ * if(oldProp == null) {
+ * System.clearProperty(keyProp);
+ * } else {
+ * System.setProperty(keyProp, oldProp);
+ * }
+ * }
+ * assertFalse("java.lang.Error was not thrown.", isFailed);
+ */
}
/**
@@ -700,7 +743,6 @@
method = "getSystemResources",
args = {java.lang.String.class}
)
- @KnownFailure("Can't find existent resource.")
public void test_getSystemResources() {
String textResource = "HelloWorld.txt";
@@ -726,6 +768,7 @@
method = "getPackage",
args = {java.lang.String.class}
)
+ @KnownFailure("PackageClassLoader.getPackage returns null.")
public void test_getPackageLjava_lang_String() {
PackageClassLoader pcl = new PackageClassLoader();
@@ -761,8 +804,9 @@
method = "getPackages",
args = {}
)
- @KnownFailure("ClassCastException is thrown during casting Object " +
- "to Package.")
+ @KnownFailure("The package canot be found. Seems like the cache is not " +
+ "shared between the class loaders. But this test seems to " +
+ "expect exactly that. this tests works on the RI.")
public void test_getPackages() {
PackageClassLoader pcl = new PackageClassLoader();
@@ -842,7 +886,6 @@
method = "getResources",
args = {java.lang.String.class}
)
- @KnownFailure("Can't find existent resource.")
public void test_getResourcesLjava_lang_String() {
Enumeration<java.net.URL> urls = null;
FileInputStream fis = null;
@@ -939,6 +982,7 @@
method = "findClass",
args = {java.lang.String.class}
)
+ @AndroidOnly("findClass method throws ClassNotFoundException exception.")
public void test_findClass(){
try {
@@ -964,6 +1008,7 @@
method = "findLibrary",
args = {java.lang.String.class}
)
+ @AndroidOnly("findLibrary method is not supported, it returns null.")
public void test_findLibrary() {
PackageClassLoader pcl = new PackageClassLoader();
assertNull(pcl.findLibrary("libjvm.so"));
@@ -975,6 +1020,7 @@
method = "findResource",
args = {java.lang.String.class}
)
+ @AndroidOnly("findResource method is not supported, it returns null.")
public void test_findResourceLjava_lang_String() {
assertNull(new PackageClassLoader().findResource("hyts_Foo.c"));
}
@@ -985,6 +1031,8 @@
method = "findResources",
args = {java.lang.String.class}
)
+ @AndroidOnly("findResources method is not supported, it returns " +
+ "empty Enumeration.")
public void test_findResourcesLjava_lang_String() throws IOException {
assertFalse(new PackageClassLoader().findResources("hyts_Foo.c").
hasMoreElements());
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassTest.java
index d58a0e9..c33a8e3 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassTest.java
@@ -47,19 +47,27 @@
import tests.support.resource.Support_Resources;
import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@SuppressWarnings("deprecation")
-@TestTargetClass(Class.class)
+@TestTargetClass(Class.class)
public class ClassTest extends junit.framework.TestCase {
- public static final String FILENAME =
+ public static final String FILENAME =
ClassTest.class.getPackage().getName().replace('.', '/') +
"/test#.properties";
-
+
+ final String packageName = getClass().getPackage().getName();
+ final String classNameInitError1 = packageName + ".TestClass1";
+ final String classNameInitError2 = packageName + ".TestClass1B";
+ final String classNameLinkageError = packageName + ".TestClass";
+ final String sourceJARfile = "illegalClasses.jar";
+ final String illegalClassName = "illegalClass";
+
static class StaticMember$Class {
class Member2$A {
}
@@ -103,54 +111,54 @@
public static class SubTestClass extends TestClass {
}
-
+
interface Intf1 {
public int field1 = 1;
public int field2 = 1;
void test();
}
-
+
interface Intf2 {
public int field1 = 1;
void test();
}
-
+
interface Intf3 extends Intf1 {
public int field1 = 1;
}
-
+
interface Intf4 extends Intf1, Intf2 {
public int field1 = 1;
void test2(int a, Object b);
}
-
+
interface Intf5 extends Intf1 {
}
-
+
class Cls1 implements Intf2 {
public int field1 = 2;
public int field2 = 2;
public void test() {
}
}
-
+
class Cls2 extends Cls1 implements Intf1 {
public int field1 = 2;
@Override
public void test() {
}
}
-
+
class Cls3 implements Intf3, Intf4 {
public void test() {
}
public void test2(int a, Object b) {
}
}
-
+
static class Cls4 {
-
- }
+
+ }
@TestTargetNew(
level = TestLevel.COMPLETE,
@@ -162,14 +170,14 @@
Annotation [] annotations = PublicTestClass.class.getAnnotations();
assertEquals(1, annotations.length);
assertEquals(TestAnnotation.class, annotations[0].annotationType());
-
+
annotations = ExtendTestClass.class.getAnnotations();
assertEquals(2, annotations.length);
-
+
for(int i = 0; i < annotations.length; i++) {
Class<? extends Annotation> type = annotations[i].annotationType();
- assertTrue("Annotation's type " + i + ": " + type,
- type.equals(Deprecated.class) ||
+ assertTrue("Annotation's type " + i + ": " + type,
+ type.equals(Deprecated.class) ||
type.equals(TestAnnotation.class));
}
}
@@ -183,9 +191,10 @@
method = "forName",
args = {java.lang.String.class}
)
- @AndroidOnly("harmony specific: test with 'org.apache.harmony.luni.tests.java.lang.TestClass1'")
+ @AndroidOnly("harmony specific: test with " +
+ "'org.apache.harmony.luni.tests.java.lang.TestClass1'")
public void test_forNameLjava_lang_String() throws Exception {
-
+
assertSame("Class for name failed for java.lang.Object",
Object.class, Class.forName("java.lang.Object"));
assertSame("Class for name failed for [[Ljava.lang.Object;",
@@ -243,25 +252,24 @@
fail();
} catch (ClassNotFoundException e) {
}
-
+
//regression test for JIRA 2162
try {
Class.forName("%");
fail("should throw ClassNotFoundException.");
} catch (ClassNotFoundException e) {
}
-
+
//Regression Test for HARMONY-3332
String securityProviderClassName;
int count = 1;
while ((securityProviderClassName = Security
.getProperty("security.provider." + count++)) != null) {
Class.forName(securityProviderClassName);
- }
-
+ }
+
try {
- Class.forName(
- "org.apache.harmony.luni.tests.java.lang.TestClass1");
+ Class.forName(classNameInitError1);
fail("ExceptionInInitializerError or ClassNotFoundException " +
"expected.");
} catch (java.lang.ExceptionInInitializerError ie) {
@@ -280,80 +288,78 @@
public void test_forNameLjava_lang_StringLbooleanLClassLoader() throws Exception {
ClassLoader pcl = getClass().getClassLoader();
-
+
Class<?> [] classes = {PublicTestClass.class, ExtendTestClass.class,
ExtendTestClass1.class, TestInterface.class, String.class};
-
+
for(int i = 0; i < classes.length; i++) {
Class<?> clazz = Class.forName(classes[i].getName(), true, pcl);
assertEquals(classes[i], clazz);
-
+
clazz = Class.forName(classes[i].getName(), false, pcl);
assertEquals(classes[i], clazz);
}
-
+
for(int i = 0; i < classes.length; i++) {
- Class<?> clazz = Class.forName(classes[i].getName(), true,
+ Class<?> clazz = Class.forName(classes[i].getName(), true,
ClassLoader.getSystemClassLoader());
assertEquals(classes[i], clazz);
-
- clazz = Class.forName(classes[i].getName(), false,
+
+ clazz = Class.forName(classes[i].getName(), false,
ClassLoader.getSystemClassLoader());
assertEquals(classes[i], clazz);
}
-
+
try {
Class.forName(null, true, pcl);
fail("NullPointerException is not thrown.");
} catch(NullPointerException npe) {
//expected
}
-
+
try {
Class.forName("NotExistClass", true, pcl);
fail("ClassNotFoundException is not thrown for non existent class.");
} catch(ClassNotFoundException cnfe) {
//expected
- }
-
+ }
+
try {
Class.forName("String", false, pcl);
fail("ClassNotFoundException is not thrown for non existent class.");
} catch(ClassNotFoundException cnfe) {
//expected
- }
-
+ }
+
try {
- Class.forName("org.apache.harmony.luni.tests.java.PublicTestClass",
+ Class.forName("org.apache.harmony.luni.tests.java.PublicTestClass",
false, pcl);
fail("ClassNotFoundException is not thrown for non existent class.");
} catch(ClassNotFoundException cnfe) {
//expected
- }
+ }
}
-
+
@TestTargetNew(
level = TestLevel.SUFFICIENT,
notes = "",
method = "forName",
args = {java.lang.String.class, boolean.class, java.lang.ClassLoader.class}
)
- @KnownFailure("Class.forName does not work with an URLClassLoader; " +
- "the VMClassLoader does not support loading classes from a " +
- "(jar) byte array.")
- public void test_forNameLjava_lang_StringLbooleanLClassLoader_FailsOnAndroid() throws Exception {
+ @AndroidOnly("Class.forName method throws ClassNotFoundException on " +
+ "Android.")
+ public void test_forNameLjava_lang_StringLbooleanLClassLoader_AndroidOnly() throws Exception {
// Android doesn't support loading class files from a jar.
- File resources = Support_Resources.createTempFolder();
try {
- Support_Resources.copyFile(resources, null, "illegalClasses.jar");
- File file = new File(resources.toString() + "/illegalClasses.jar");
- URL url = new URL("file:" + file.getPath());
- ClassLoader loader = new URLClassLoader(new URL[] { url },
+ URL url = getClass().getClassLoader().getResource(
+ packageName.replace(".", "/") + "/" + sourceJARfile);
+
+ ClassLoader loader = new URLClassLoader(new URL[] { url },
getClass().getClassLoader());
try {
- Class.forName("TestClass", true, loader);
+ Class.forName(classNameLinkageError, true, loader);
fail("LinkageError or ClassNotFoundException expected.");
} catch (java.lang.LinkageError le) {
// Expected for the RI.
@@ -365,20 +371,18 @@
}
try {
- Class.forName(
- "org.apache.harmony.luni.tests.java.lang.TestClass1B",
+ Class.forName(classNameInitError2,
true, getClass().getClassLoader());
fail("ExceptionInInitializerError or ClassNotFoundException " +
"should be thrown.");
} catch (java.lang.ExceptionInInitializerError ie) {
// Expected for the RI.
-/* Remove this comment to let the test pass on Android.
+ // Remove this comment to let the test pass on Android.
} catch (java.lang.ClassNotFoundException ce) {
// Expected for Android.
-*/
}
}
-
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -386,15 +390,15 @@
args = {java.lang.Class.class}
)
public void test_getAnnotation() {
- TestAnnotation target = PublicTestClass.class.getAnnotation(TestAnnotation.class);
+ TestAnnotation target = PublicTestClass.class.getAnnotation(TestAnnotation.class);
assertEquals(target.value(), PublicTestClass.class.getName());
-
+
assertNull(PublicTestClass.class.getAnnotation(Deprecated.class));
-
+
Deprecated target2 = ExtendTestClass.class.getAnnotation(Deprecated.class);
assertNotNull(target2);
- }
-
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -404,17 +408,17 @@
public void test_getDeclaredAnnotations() {
Annotation [] annotations = PublicTestClass.class.getDeclaredAnnotations();
assertEquals(1, annotations.length);
-
+
annotations = ExtendTestClass.class.getDeclaredAnnotations();
assertEquals(2, annotations.length);
annotations = TestInterface.class.getDeclaredAnnotations();
assertEquals(0, annotations.length);
-
+
annotations = String.class.getDeclaredAnnotations();
- assertEquals(0, annotations.length);
- }
-
+ assertEquals(0, annotations.length);
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -424,13 +428,13 @@
public void test_getEnclosingClass() {
Class clazz = ExtendTestClass.class.getEnclosingClass();
assertNull(clazz);
-
+
assertEquals(getClass(), Cls1.class.getEnclosingClass());
assertEquals(getClass(), Intf1.class.getEnclosingClass());
assertEquals(getClass(), Cls4.class.getEnclosingClass());
- }
-
-
+ }
+
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -440,18 +444,18 @@
public void test_getEnclosingMethod() {
Method clazz = ExtendTestClass.class.getEnclosingMethod();
assertNull(clazz);
-
+
PublicTestClass ptc = new PublicTestClass();
try {
assertEquals("getEnclosingMethod returns incorrect method.",
- PublicTestClass.class.getMethod("getLocalClass",
+ PublicTestClass.class.getMethod("getLocalClass",
(Class []) null),
ptc.getLocalClass().getClass().getEnclosingMethod());
} catch(NoSuchMethodException nsme) {
fail("NoSuchMethodException was thrown.");
}
- }
-
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -459,13 +463,13 @@
args = {}
)
public void test_getEnclosingConstructor() {
-
+
PublicTestClass ptc = new PublicTestClass();
- assertEquals("getEnclosingConstructor method returns incorrect class.",
- PublicTestClass.class.getConstructors()[0],
+ assertEquals("getEnclosingConstructor method returns incorrect class.",
+ PublicTestClass.class.getConstructors()[0],
ptc.clazz.getClass().getEnclosingConstructor());
-
+
assertNull("getEnclosingConstructor should return null for local " +
"class declared in method.",
ptc.getLocalClass().getClass().getEnclosingConstructor());
@@ -474,8 +478,8 @@
"class declared in method.",
ExtendTestClass.class.getEnclosingConstructor());
}
-
-
+
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -491,7 +495,7 @@
assertEquals(TestEnum.values()[i], constants[i]);
}
assertEquals(0, TestEmptyEnum.class.getEnumConstants().length);
- }
+ }
public enum TestEnum {
ONE, TWO, THREE
}
@@ -507,86 +511,116 @@
public void test_getGenericInterfaces() {
Type [] types = ExtendTestClass1.class.getGenericInterfaces();
assertEquals(0, types.length);
-
- Class [] interfaces = {TestInterface.class, Serializable.class,
+
+ Class [] interfaces = {TestInterface.class, Serializable.class,
Cloneable.class};
types = PublicTestClass.class.getGenericInterfaces();
assertEquals(interfaces.length, types.length);
for(int i = 0; i < types.length; i++) {
assertEquals(interfaces[i], types[i]);
}
-
+
types = TestInterface.class.getGenericInterfaces();
- assertEquals(0, types.length);
-
+ assertEquals(0, types.length);
+
types = List.class.getGenericInterfaces();
assertEquals(1, types.length);
assertEquals(Collection.class, ((ParameterizedType)types[0]).getRawType());
-
+
assertEquals(0, int.class.getGenericInterfaces().length);
- assertEquals(0, void.class.getGenericInterfaces().length);
+ assertEquals(0, void.class.getGenericInterfaces().length);
}
-
+
@TestTargetNew(
level = TestLevel.SUFFICIENT,
notes = "GenericSignatureFormatError, TypeNotPresentException, MalformedParameterizedTypeException are not verified.",
method = "getGenericSuperclass",
args = {}
- )
+ )
public void test_getGenericSuperclass () {
- assertEquals(PublicTestClass.class,
+ assertEquals(PublicTestClass.class,
ExtendTestClass.class.getGenericSuperclass());
- assertEquals(ExtendTestClass.class,
- ExtendTestClass1.class.getGenericSuperclass());
+ assertEquals(ExtendTestClass.class,
+ ExtendTestClass1.class.getGenericSuperclass());
assertEquals(Object.class, PublicTestClass.class.getGenericSuperclass());
assertEquals(Object.class, String.class.getGenericSuperclass());
assertEquals(null, TestInterface.class.getGenericSuperclass());
-
- ParameterizedType type = (ParameterizedType) Vector.class.getGenericSuperclass();
+
+ ParameterizedType type = (ParameterizedType) Vector.class.getGenericSuperclass();
assertEquals(AbstractList.class, type.getRawType());
}
-
+
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
+ level = TestLevel.SUFFICIENT,
method = "getPackage",
args = {}
)
- @KnownFailure("Class.getPackage does not work with an URLClassLoader; " +
- "the VMClassLoader does not support loading classes from a " +
- "(jar) byte array.")
+ @AndroidOnly("Uses dalvik.system.PathClassLoader.")
public void test_getPackage() {
- assertEquals(Package.getPackage("org.apache.harmony.luni.tests.java.lang"),
- PublicTestClass.class.getPackage());
+ Package thisPackage = getClass().getPackage();
+ assertEquals("org.apache.harmony.luni.tests.java.lang",
+ thisPackage.getName());
+
+ Package stringPackage = String.class.getPackage();
+ assertNotNull("java.lang", stringPackage.getName());
+
+ String hyts_package_name = "hyts_package_dex.jar";
File resources = Support_Resources.createTempFolder();
- try {
- Support_Resources.copyFile(resources, null, "illegalClasses.jar");
- File file = new File(resources.toString() + "/illegalClasses.jar");
- URL url = new URL("file:" + file.getPath());
- ClassLoader loader = new URLClassLoader(new URL[] { url }, null);
+ Support_Resources.copyFile(resources, "Package", hyts_package_name);
- try {
- Class<?> clazz = loader.loadClass("IllegalClass");
- Package pack = clazz.getPackage();
- assertNull(pack);
- } catch(ClassNotFoundException cne) {
- fail("ClassNotFoundException was thrown for IllegalClass.");
- }
+ String resPath = resources.toString();
+ if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\')
+ resPath = resPath.substring(1);
+
+ try {
+
+ URL resourceURL = new URL("file:/" + resPath + "/Package/"
+ + hyts_package_name);
+
+ ClassLoader cl = new dalvik.system.PathClassLoader(
+ resourceURL.getPath(), getClass().getClassLoader());
+
+ Class clazz = cl.loadClass("C");
+ assertNull("getPackage for C.class should return null",
+ clazz.getPackage());
+
+ clazz = cl.loadClass("a.b.C");
+ Package cPackage = clazz.getPackage();
+ assertNotNull("getPackage for a.b.C.class should not return null",
+ cPackage);
+
+ /*
+ * URLClassLoader doesn't work on Android for jar files
+ *
+ * URL url = getClass().getClassLoader().getResource(
+ * packageName.replace(".", "/") + "/" + sourceJARfile);
+ *
+ * ClassLoader loader = new URLClassLoader(new URL[] { url }, null);
+ *
+ * try {
+ * Class<?> clazz = loader.loadClass(illegalClassName);
+ * Package pack = clazz.getPackage();
+ * assertNull(pack);
+ * } catch(ClassNotFoundException cne) {
+ * fail("ClassNotFoundException was thrown for " + illegalClassName);
+ * }
+ */
} catch(Exception e) {
fail("Unexpected exception was thrown: " + e.toString());
}
}
-
+
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "getProtectionDomain",
args = {}
- )
- @KnownFailure("There is no protection domain set.")
+ )
+ @BrokenTest("There is no protection domain set in Android.")
public void test_getProtectionDomain() {
ProtectionDomain pd = PublicTestClass.class.getProtectionDomain();
assertNotNull("Test 1: Protection domain expected to be set.", pd);
-
+
SecurityManager sm = new SecurityManager() {
public void checkPermission(Permission perm) {
@@ -612,19 +646,19 @@
notes = "",
method = "getSigners",
args = {}
- )
+ )
public void test_getSigners() {
assertNull(void.class.getSigners());
assertNull(PublicTestClass.class.getSigners());
}
-
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "getSimpleName",
args = {}
- )
+ )
public void test_getSimpleName() {
assertEquals("PublicTestClass", PublicTestClass.class.getSimpleName());
assertEquals("void", void.class.getSimpleName());
@@ -636,44 +670,44 @@
notes = "",
method = "getTypeParameters",
args = {}
- )
+ )
public void test_getTypeParameters() {
assertEquals(0, PublicTestClass.class.getTypeParameters().length);
TypeVariable [] tv = TempTestClass1.class.getTypeParameters();
assertEquals(1, tv.length);
assertEquals(Object.class, tv[0].getBounds()[0]);
-
+
TempTestClass2<String> tc = new TempTestClass2<String>();
tv = tc.getClass().getTypeParameters();
assertEquals(1, tv.length);
assertEquals(String.class, tv[0].getBounds()[0]);
}
-
- class TempTestClass1<T> {
+
+ class TempTestClass1<T> {
}
-
- class TempTestClass2<S extends String> extends TempTestClass1<S> {
+
+ class TempTestClass2<S extends String> extends TempTestClass1<S> {
}
-
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "isAnnotation",
args = {}
- )
+ )
public void test_isAnnotation() {
assertTrue(Deprecated.class.isAnnotation());
assertTrue(TestAnnotation.class.isAnnotation());
assertFalse(PublicTestClass.class.isAnnotation());
assertFalse(String.class.isAnnotation());
}
-
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "isAnnotationPresent",
args = {java.lang.Class.class}
- )
+ )
public void test_isAnnotationPresent() {
assertTrue(PublicTestClass.class.isAnnotationPresent(TestAnnotation.class));
assertFalse(ExtendTestClass1.class.isAnnotationPresent(TestAnnotation.class));
@@ -681,51 +715,51 @@
assertTrue(ExtendTestClass.class.isAnnotationPresent(TestAnnotation.class));
assertTrue(ExtendTestClass.class.isAnnotationPresent(Deprecated.class));
}
-
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "isAnonymousClass",
args = {}
- )
+ )
public void test_isAnonymousClass() {
assertFalse(PublicTestClass.class.isAnonymousClass());
assertTrue((new Thread() {}).getClass().isAnonymousClass());
- }
-
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "isEnum",
args = {}
- )
+ )
public void test_isEnum() {
assertFalse(PublicTestClass.class.isEnum());
assertFalse(ExtendTestClass.class.isEnum());
assertTrue(TestEnum.ONE.getClass().isEnum());
assertTrue(TestEnum.class.isEnum());
- }
-
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "isLocalClass",
args = {}
- )
+ )
public void test_isLocalClass() {
assertFalse(ExtendTestClass.class.isLocalClass());
assertFalse(TestInterface.class.isLocalClass());
assertFalse(TestEnum.class.isLocalClass());
class InternalClass {}
assertTrue(InternalClass.class.isLocalClass());
- }
+ }
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "isMemberClass",
args = {}
- )
+ )
public void test_isMemberClass() {
assertFalse(ExtendTestClass.class.isMemberClass());
assertFalse(TestInterface.class.isMemberClass());
@@ -733,23 +767,23 @@
assertTrue(TestEnum.class.isMemberClass());
assertTrue(StaticMember$Class.class.isMemberClass());
}
-
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "isSynthetic",
args = {}
- )
+ )
public void test_isSynthetic() {
- assertFalse("Returned true for non synthetic class.",
+ assertFalse("Returned true for non synthetic class.",
ExtendTestClass.class.isSynthetic());
- assertFalse("Returned true for non synthetic class.",
+ assertFalse("Returned true for non synthetic class.",
TestInterface.class.isSynthetic());
- assertFalse("Returned true for non synthetic class.",
+ assertFalse("Returned true for non synthetic class.",
String.class.isSynthetic());
-
+
String className = "org.apache.harmony.luni.tests.java.lang.ClassLoaderTest$1";
-
+
/*
*try {
* assertTrue("Returned false for synthetic class.",
@@ -759,18 +793,18 @@
* fail("Class " + className + " can't be found.");
*}
*/
-
- }
-
+
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "isInstance",
args = {java.lang.Object.class}
- )
+ )
public void test_isInstance() {
}
-
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
@@ -779,38 +813,37 @@
)
public void test_getCanonicalName() {
String name = int[].class.getCanonicalName();
- Class [] classArray = { int.class, int[].class, String.class,
+ Class [] classArray = { int.class, int[].class, String.class,
PublicTestClass.class, TestInterface.class,
ExtendTestClass.class };
- String [] classNames = {"int", "int[]", "java.lang.String",
+ String [] classNames = {"int", "int[]", "java.lang.String",
"org.apache.harmony.luni.tests.java.lang.PublicTestClass",
"org.apache.harmony.luni.tests.java.lang.TestInterface",
"org.apache.harmony.luni.tests.java.lang.ExtendTestClass"};
-
+
for(int i = 0; i < classArray.length; i++) {
assertEquals(classNames[i], classArray[i].getCanonicalName());
- }
- }
-
+ }
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "getClassLoader",
args = {}
)
- @KnownFailure("getClassLoader() does not return null for primitive types.")
public void test_getClassLoader() {
-
- assertEquals(ExtendTestClass.class.getClassLoader(),
+
+ assertEquals(ExtendTestClass.class.getClassLoader(),
PublicTestClass.class.getClassLoader());
-
+
assertNull(int.class.getClassLoader());
assertNull(void.class.getClassLoader());
-
+
SecurityManager sm = new SecurityManager() {
public void checkPermission(Permission perm) {
- if ((perm instanceof RuntimePermission) &&
+ if ((perm instanceof RuntimePermission) &&
perm.getName().equals("getClassLoader")) {
throw new SecurityException();
}
@@ -826,8 +859,8 @@
} finally {
System.setSecurityManager(oldSm);
}
- }
-
+ }
+
/**
* @tests java.lang.Class#getClasses()
*/
@@ -850,7 +883,7 @@
method = "getClasses",
args = {}
)
- @KnownFailure("Class.forName does not work with an URLClassLoader; " +
+ @BrokenTest("Class.forName does not work with an URLClassLoader; " +
"the VMClassLoader does not support loading classes from a " +
"(jar) byte array.")
public void test_getClasses_subtest0() {
@@ -1027,7 +1060,7 @@
/* Remove this comment to let the test pass on Android.
} catch (java.lang.ClassNotFoundException ce) {
// Expected for Android.
-*/
+*/
} catch (Exception e) {
if (e instanceof RuntimeException)
throw (RuntimeException) e;
@@ -1069,7 +1102,7 @@
throws NoSuchMethodException {
Constructor constr = TestClass.class.getConstructor(new Class[0]);
assertNotNull(constr);
- assertEquals("org.apache.harmony.luni.tests.java.lang.ClassTest$TestClass",
+ assertEquals("org.apache.harmony.luni.tests.java.lang.ClassTest$TestClass",
constr.getName());
try {
TestClass.class.getConstructor(Object.class);
@@ -1077,11 +1110,11 @@
} catch (NoSuchMethodException e) {
// Correct - constructor with obj is private
}
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.getConstructor(new Class[0]);
+ TestClass.class.getConstructor(new Class[0]);
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
@@ -1102,11 +1135,11 @@
public void test_getConstructors() throws Exception {
Constructor[] c = TestClass.class.getConstructors();
assertEquals("Incorrect number of constructors returned", 1, c.length);
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.getConstructors();
+ TestClass.class.getConstructors();
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
@@ -1125,36 +1158,36 @@
args = {}
)
public void test_getDeclaredClasses() {
-
+
Class [] declClasses = Object.class.getDeclaredClasses();
assertEquals("Incorrect length of declared classes array is returned " +
"for Object.", 0, declClasses.length);
-
- declClasses = PublicTestClass.class.getDeclaredClasses();
+
+ declClasses = PublicTestClass.class.getDeclaredClasses();
assertEquals(2, declClasses.length);
-
+
assertEquals(0, int.class.getDeclaredClasses().length);
- assertEquals(0, void.class.getDeclaredClasses().length);
-
- for(int i = 0; i < declClasses.length; i++) {
+ assertEquals(0, void.class.getDeclaredClasses().length);
+
+ for(int i = 0; i < declClasses.length; i++) {
Constructor<?> constr = declClasses[i].getDeclaredConstructors()[0];
constr.setAccessible(true);
PublicTestClass publicClazz = new PublicTestClass();
try {
Object o = constr.newInstance(publicClazz);
- assertTrue("Returned incorrect class: " + o.toString(),
+ assertTrue("Returned incorrect class: " + o.toString(),
o.toString().startsWith("PrivateClass"));
} catch(Exception e) {
fail("Unexpected exception was thrown: " + e.toString());
}
}
-
-
- declClasses = TestInterface.class.getDeclaredClasses();
+
+
+ declClasses = TestInterface.class.getDeclaredClasses();
assertEquals(0, declClasses.length);
-
+
SecurityManager sm = new SecurityManager() {
-
+
final String forbidenPermissionName = "user.dir";
public void checkPermission(Permission perm) {
@@ -1162,36 +1195,36 @@
throw new SecurityException();
}
}
-
+
public void checkMemberAccess(Class<?> clazz,
int which) {
if(clazz.equals(TestInterface.class)) {
throw new SecurityException();
}
}
-
+
public void checkPackageAccess(String pkg) {
if(pkg.equals(PublicTestClass.class.getPackage())) {
throw new SecurityException();
}
}
-
+
};
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestInterface.class.getDeclaredClasses();
+ TestInterface.class.getDeclaredClasses();
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
} finally {
System.setSecurityManager(oldSm);
}
-
+
}
-
-
+
+
/**
* @tests java.lang.Class#getDeclaredConstructor(java.lang.Class[])
*/
@@ -1205,18 +1238,18 @@
Constructor<TestClass> c = TestClass.class.getDeclaredConstructor(new Class[0]);
assertNull("Incorrect constructor returned", c.newInstance().cValue());
c = TestClass.class.getDeclaredConstructor(Object.class);
-
+
try {
TestClass.class.getDeclaredConstructor(String.class);
fail("NoSuchMethodException should be thrown.");
} catch(NoSuchMethodException nsme) {
//expected
}
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.getDeclaredConstructor(Object.class);
+ TestClass.class.getDeclaredConstructor(Object.class);
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
@@ -1237,11 +1270,11 @@
public void test_getDeclaredConstructors() throws Exception {
Constructor[] c = TestClass.class.getDeclaredConstructors();
assertEquals("Incorrect number of constructors returned", 2, c.length);
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.getDeclaredConstructors();
+ TestClass.class.getDeclaredConstructors();
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
@@ -1259,30 +1292,28 @@
method = "getDeclaredField",
args = {java.lang.String.class}
)
- @KnownFailure("Should throw NullPointerException instead of " +
- "NoSuchFieldException.")
public void test_getDeclaredFieldLjava_lang_String() throws Exception {
Field f = TestClass.class.getDeclaredField("pubField");
assertEquals("Returned incorrect field", 2, f.getInt(new TestClass()));
-
+
try {
TestClass.class.getDeclaredField(null);
fail("NullPointerException is not thrown.");
} catch(NullPointerException npe) {
//expected
}
-
+
try {
TestClass.class.getDeclaredField("NonExistentField");
- fail("NoSuchFieldException is not thrown.");
+ fail("NoSuchFieldException is not thrown.");
} catch(NoSuchFieldException nsfe) {
//expected
}
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.getDeclaredField("pubField");
+ TestClass.class.getDeclaredField("pubField");
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
@@ -1306,11 +1337,11 @@
f = SubTestClass.class.getDeclaredFields();
// Declared fields do not include inherited
assertEquals("Returned incorrect number of fields", 0, f.length);
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.getDeclaredFields();
+ TestClass.class.getDeclaredFields();
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
@@ -1329,32 +1360,30 @@
method = "getDeclaredMethod",
args = {java.lang.String.class, java.lang.Class[].class}
)
- @KnownFailure("Should throw NullPointerException instead of " +
- "NoSuchMethodException.")
public void test_getDeclaredMethodLjava_lang_String$Ljava_lang_Class() throws Exception {
Method m = TestClass.class.getDeclaredMethod("pubMethod", new Class[0]);
assertEquals("Returned incorrect method", 2, ((Integer) (m.invoke(new TestClass())))
.intValue());
m = TestClass.class.getDeclaredMethod("privMethod", new Class[0]);
-
+
try {
TestClass.class.getDeclaredMethod(null, new Class[0]);
fail("NullPointerException is not thrown.");
} catch(NullPointerException npe) {
//expected
}
-
+
try {
TestClass.class.getDeclaredMethod("NonExistentMethod", new Class[0]);
fail("NoSuchMethodException is not thrown.");
} catch(NoSuchMethodException nsme) {
//expected
}
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.getDeclaredMethod("pubMethod", new Class[0]);
+ TestClass.class.getDeclaredMethod("pubMethod", new Class[0]);
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
@@ -1377,11 +1406,11 @@
assertEquals("Returned incorrect number of methods", 3, m.length);
m = SubTestClass.class.getDeclaredMethods();
assertEquals("Returned incorrect number of methods", 0, m.length);
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.getDeclaredMethods();
+ TestClass.class.getDeclaredMethods();
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
@@ -1413,37 +1442,34 @@
method = "getField",
args = {java.lang.String.class}
)
- @KnownFailure("Should return a Field object that reflects the public " +
- "field of the interface represented by this Class object too, " +
- "but it throws a NoSuchFieldException.")
public void test_getFieldLjava_lang_String() throws Exception {
Field f = TestClass.class.getField("pubField");
assertEquals("Returned incorrect field", 2, f.getInt(new TestClass()));
-
+
f = PublicTestClass.class.getField("TEST_FIELD");
- assertEquals("Returned incorrect field", "test field",
+ assertEquals("Returned incorrect field", "test field",
f.get(new PublicTestClass()));
-
+
f = PublicTestClass.class.getField("TEST_INTERFACE_FIELD");
- assertEquals("Returned incorrect field", 0,
+ assertEquals("Returned incorrect field", 0,
f.getInt(new PublicTestClass()));
-
+
try {
f = TestClass.class.getField("privField");
fail("Private field access failed to throw exception");
} catch (NoSuchFieldException e) {
// Correct
}
-
+
try {
TestClass.class.getField(null);
fail("NullPointerException is thrown.");
} catch(NullPointerException npe) {
//expected
}
-
+
SecurityManager sm = new SecurityManager() {
-
+
final String forbidenPermissionName = "user.dir";
public void checkPermission(Permission perm) {
@@ -1451,26 +1477,26 @@
throw new SecurityException();
}
}
-
+
public void checkMemberAccess(Class<?> clazz,
int which) {
if(clazz.equals(TestClass.class)) {
throw new SecurityException();
}
}
-
+
public void checkPackageAccess(String pkg) {
if(pkg.equals(TestClass.class.getPackage())) {
throw new SecurityException();
}
}
-
+
};
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.getField("pubField");
+ TestClass.class.getField("pubField");
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
@@ -1488,21 +1514,19 @@
method = "getFields",
args = {}
)
- @KnownFailure("Fails because public static fields declared in an " +
- "interface implemented by the class are not recognized.")
- public void test_getFields_FailsOnAndroid() throws Exception {
+ public void test_getFields2() throws Exception {
Field[] f;
Field expected = null;
-
+
f = PublicTestClass.class.getFields();
assertEquals("Test 1: Incorrect number of fields;", 2, f.length);
-
+
f = Cls2.class.getFields();
- assertEquals("Test 2: Incorrect number of fields;", 6, f.length);
+ assertEquals("Test 2: Incorrect number of fields;", 6, f.length);
f = Cls3.class.getFields();
- assertEquals("Test 2: Incorrect number of fields;", 5, f.length);
-
+ assertEquals("Test 2: Incorrect number of fields;", 5, f.length);
+
for (Field field : f) {
if (field.toString().equals("public static final int org.apache" +
".harmony.luni.tests.java.lang.ClassTest$Intf3.field1")) {
@@ -1513,9 +1537,9 @@
if (expected == null) {
fail("Test 3: getFields() did not return all fields.");
}
- assertEquals("Test 4: Incorrect field;", expected,
+ assertEquals("Test 4: Incorrect field;", expected,
Cls3.class.getField("field1"));
-
+
expected = null;
for (Field field : f) {
if(field.toString().equals("public static final int org.apache" +
@@ -1527,7 +1551,7 @@
if (expected == null) {
fail("Test 5: getFields() did not return all fields.");
}
- assertEquals("Test 6: Incorrect field;", expected,
+ assertEquals("Test 6: Incorrect field;", expected,
Cls3.class.getField("field2"));
}
@@ -1546,11 +1570,11 @@
f = SubTestClass.class.getFields();
// Check inheritance of pub fields
assertEquals("Test 2: Incorrect number of fields;", 2, f.length);
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.getFields();
+ TestClass.class.getFields();
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected
@@ -1592,20 +1616,20 @@
.contains(Cloneable.class)
&& interfaceList.contains(Serializable.class)
&& interfaceList.contains(List.class));
-
+
Class [] interfaces1 = Cls1.class.getInterfaces();
assertEquals(1, interfaces1.length);
assertEquals(Intf2.class, interfaces1[0]);
-
+
Class [] interfaces2 = Cls2.class.getInterfaces();
assertEquals(1, interfaces2.length);
assertEquals(Intf1.class, interfaces2[0]);
-
+
Class [] interfaces3 = Cls3.class.getInterfaces();
assertEquals(2, interfaces3.length);
- assertEquals(Intf3.class, interfaces3[0]);
- assertEquals(Intf4.class, interfaces3[1]);
-
+ assertEquals(Intf3.class, interfaces3[0]);
+ assertEquals(Intf4.class, interfaces3[1]);
+
Class [] interfaces4 = Cls4.class.getInterfaces();
assertEquals(0, interfaces4.length);
}
@@ -1623,11 +1647,11 @@
Method m = TestClass.class.getMethod("pubMethod", new Class[0]);
assertEquals("Returned incorrect method", 2, ((Integer) (m.invoke(new TestClass())))
.intValue());
-
+
m = ExtendTestClass1.class.getMethod("getCount", new Class[0]);
assertEquals("Returned incorrect method", 0, ((Integer) (m.invoke(new ExtendTestClass1())))
.intValue());
-
+
try {
m = TestClass.class.getMethod("privMethod", new Class[0]);
fail("Failed to throw exception accessing private method");
@@ -1635,7 +1659,7 @@
// Correct
return;
}
-
+
try {
m = TestClass.class.getMethod("init", new Class[0]);
fail("Failed to throw exception accessing to init method");
@@ -1643,14 +1667,14 @@
// Correct
return;
}
-
+
try {
TestClass.class.getMethod("pubMethod", new Class[0]);
fail("NullPointerException is not thrown.");
} catch(NullPointerException npe) {
//expected
}
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
@@ -1680,7 +1704,7 @@
assertEquals("Returned incorrect number of sub-class methods",
2 + Object.class.getMethods().length, m.length);
// Number of inherited methods
-
+
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
@@ -1696,7 +1720,7 @@
Cls2.class.getMethods().length);
assertEquals("Incorrect number of methods", 11,
Cls3.class.getMethods().length);
-
+
Method expected = null;
Method[] methods = Cls2.class.getMethods();
for (Method method : methods) {
@@ -1710,7 +1734,7 @@
fail("getMethods() did not return all methods");
}
assertEquals(expected, Cls2.class.getMethod("test"));
-
+
expected = null;
methods = Cls3.class.getMethods();
for (Method method : methods) {
@@ -1724,7 +1748,7 @@
fail("getMethods() did not return all methods");
}
assertEquals(expected, Cls3.class.getMethod("test"));
-
+
expected = null;
methods = Cls3.class.getMethods();
for (Method method : methods) {
@@ -1739,7 +1763,7 @@
fail("getMethods() did not return all methods");
}
- assertEquals(expected, Cls3.class.getMethod("test2", int.class,
+ assertEquals(expected, Cls3.class.getMethod("test2", int.class,
Object.class));
assertEquals("Incorrect number of methods", 1,
@@ -1835,23 +1859,7 @@
ClassLoader pcl = getClass().getClassLoader();
Class<?> clazz = pcl.loadClass("org.apache.harmony.luni.tests.java.lang.ClassTest");
assertNotNull(clazz.getResourceAsStream("HelloWorld1.txt"));
-/*
- InputStream str = Object.class.getResourceAsStream("Class.class");
- assertNotNull("java.lang.Object couldn't find Class.class with " +
- "getResource...", str);
- assertTrue("Cannot read single byte", str.read() != -1);
- assertEquals("Cannot read multiple bytes", 5, str.read(new byte[5]));
- str.close();
-
-
- InputStream str2 = getClass().getResourceAsStream("ClassTest.class");
- assertNotNull("Can't find resource", str2);
- assertTrue("Cannot read single byte", str2.read() != -1);
- assertEquals("Cannot read multiple bytes", 5, str2.read(new byte[5]));
- str2.close();
-*/
-
try {
getClass().getResourceAsStream(null);
fail("NullPointerException is not thrown.");
@@ -1916,21 +1924,21 @@
clazz1 = Object.class;
clazz2 = Class.class;
- assertTrue("returned false for superclass",
+ assertTrue("returned false for superclass",
clazz1.isAssignableFrom(clazz2));
clazz1 = TestClass.class;
- assertTrue("returned false for same class",
+ assertTrue("returned false for same class",
clazz1.isAssignableFrom(clazz1));
clazz1 = Runnable.class;
clazz2 = Thread.class;
- assertTrue("returned false for implemented interface",
+ assertTrue("returned false for implemented interface",
clazz1.isAssignableFrom(clazz2));
-
- assertFalse("returned true not assignable classes",
+
+ assertFalse("returned true not assignable classes",
Integer.class.isAssignableFrom(String.class));
-
+
try {
clazz1.isAssignableFrom(null);
fail("NullPointerException is not thrown.");
@@ -1973,17 +1981,17 @@
args = {}
)
public void test_isPrimitive() {
- assertFalse("Interface type claims to be primitive.",
+ assertFalse("Interface type claims to be primitive.",
Runnable.class.isPrimitive());
- assertFalse("Object type claims to be primitive.",
+ assertFalse("Object type claims to be primitive.",
Object.class.isPrimitive());
- assertFalse("Prim Array type claims to be primitive.",
+ assertFalse("Prim Array type claims to be primitive.",
int[].class.isPrimitive());
- assertFalse("Array type claims to be primitive.",
+ assertFalse("Array type claims to be primitive.",
Object[].class.isPrimitive());
- assertTrue("Prim type claims not to be primitive.",
+ assertTrue("Prim type claims not to be primitive.",
int.class.isPrimitive());
- assertFalse("Object type claims to be primitive.",
+ assertFalse("Object type claims to be primitive.",
Object.class.isPrimitive());
}
@@ -2013,14 +2021,14 @@
} catch (InstantiationException e) {
// expected
}
-
+
try {
TestClass3.class.newInstance();
fail("IllegalAccessException is not thrown.");
} catch(IllegalAccessException iae) {
//expected
}
-
+
try {
TestClass1C.class.newInstance();
fail("ExceptionInInitializerError should be thrown.");
@@ -2038,12 +2046,11 @@
method = "newInstance",
args = {}
)
- @KnownFailure("SecurityException is not thrown.")
- public void test_newInstance_FailsOnAndroid() throws Exception {
+ public void test_newInstance2() throws Exception {
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- TestClass.class.newInstance();
+ TestClass.class.newInstance();
fail("Test 1: SecurityException expected.");
} catch (SecurityException e) {
// expected
@@ -2051,7 +2058,7 @@
System.setSecurityManager(oldSm);
}
}
-
+
/**
* @tests java.lang.Class#toString()
*/
@@ -2077,7 +2084,7 @@
assertEquals("Class toString printed wrong value",
"class [Ljava.lang.Object;", clazz.toString());
}
-
+
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
@@ -2089,16 +2096,16 @@
InputStream in = getClass().getResourceAsStream("/" + FILENAME);
assertNotNull(in);
in.close();
-
+
in = getClass().getResourceAsStream(FILENAME);
assertNull(in);
-
+
in = this.getClass().getClassLoader().getResourceAsStream(
FILENAME);
assertNotNull(in);
- in.close();
+ in.close();
}
-
+
/*
* Regression test for HARMONY-2644:
* Load system and non-system array classes via Class.forName()
@@ -2109,8 +2116,6 @@
method = "forName",
args = {java.lang.String.class}
)
- @KnownFailure("Class.forName(String) returns null for invalid class " +
- "names instead of throwing a ClassNotFoundException.")
public void test_forName_arrays() throws Exception {
Class<?> c1 = getClass();
String s = c1.getName();
@@ -2120,7 +2125,7 @@
assertSame(a1, a2.getComponentType());
Class<?> l4 = Class.forName("[[[[[J");
assertSame(long[][][][][].class, l4);
-
+
try{
Class<?> clazz = Class.forName("[;");
fail("1: " + clazz);
@@ -2146,35 +2151,33 @@
fail("6:" + clazz);
} catch (ClassNotFoundException ok) {}
}
-
+
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "asSubclass",
args = {java.lang.Class.class}
- )
+ )
public void test_asSubclass1() {
- assertEquals(ExtendTestClass.class,
+ assertEquals(ExtendTestClass.class,
ExtendTestClass.class.asSubclass(PublicTestClass.class));
-
- assertEquals(PublicTestClass.class,
+
+ assertEquals(PublicTestClass.class,
PublicTestClass.class.asSubclass(TestInterface.class));
-
- assertEquals(ExtendTestClass1.class,
- ExtendTestClass1.class.asSubclass(PublicTestClass.class));
-
- assertEquals(PublicTestClass.class,
+
+ assertEquals(ExtendTestClass1.class,
+ ExtendTestClass1.class.asSubclass(PublicTestClass.class));
+
+ assertEquals(PublicTestClass.class,
PublicTestClass.class.asSubclass(PublicTestClass.class));
}
-
+
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "asSubclass",
args = {java.lang.Class.class}
- )
- @KnownFailure("The implementation does not check the validity of the " +
- "requested cast.")
+ )
public void test_asSubclass2() {
try {
PublicTestClass.class.asSubclass(ExtendTestClass.class);
@@ -2190,55 +2193,53 @@
// Expected.
}
}
-
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "cast",
args = {java.lang.Object.class}
- )
- @KnownFailure("The implementation does not check the validity of the " +
- "requested cast.")
+ )
public void test_cast() {
Object o = PublicTestClass.class.cast(new ExtendTestClass());
assertTrue(o instanceof ExtendTestClass);
-
+
try {
ExtendTestClass.class.cast(new PublicTestClass());
fail("Test 1: ClassCastException expected.");
} catch(ClassCastException cce) {
//expected
}
-
+
try {
ExtendTestClass.class.cast(new String());
fail("ClassCastException is not thrown.");
} catch(ClassCastException cce) {
//expected
}
- }
-
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "desiredAssertionStatus",
args = {}
- )
+ )
public void test_desiredAssertionStatus() {
- Class [] classArray = { Object.class, Integer.class,
- String.class, PublicTestClass.class,
+ Class [] classArray = { Object.class, Integer.class,
+ String.class, PublicTestClass.class,
ExtendTestClass.class, ExtendTestClass1.class};
for(int i = 0; i < classArray.length; i++) {
- assertFalse("assertion status for " + classArray[i],
+ assertFalse("assertion status for " + classArray[i],
classArray[i].desiredAssertionStatus());
- }
- }
+ }
+ }
-
-
+
+
SecurityManager sm = new SecurityManager() {
-
+
final String forbidenPermissionName = "user.dir";
public void checkPermission(Permission perm) {
@@ -2246,19 +2247,19 @@
throw new SecurityException();
}
}
-
+
public void checkMemberAccess(Class<?> clazz,
int which) {
if(clazz.equals(TestClass.class)) {
throw new SecurityException();
}
}
-
+
public void checkPackageAccess(String pkg) {
if(pkg.equals(TestClass.class.getPackage())) {
throw new SecurityException();
}
}
-
+
};
}
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/DoubleTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/DoubleTest.java
index 2740b85..3b2d405 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/DoubleTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/DoubleTest.java
@@ -17,7 +17,6 @@
package org.apache.harmony.luni.tests.java.lang;
import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -542,6 +541,8 @@
method = "parseDouble",
args = {java.lang.String.class}
)
+ @KnownFailure("parseDouble returns different value on Android " +
+ "for 0x44b52d02c7e14af6L, it returns 1.0e23.")
public void test_parseDoubleLjava_lang_String() {
assertEquals("Incorrect double returned, expected zero.", 0.0, Double
.parseDouble("2.4703282292062327208828439643411e-324"), 0.0);
@@ -858,11 +859,10 @@
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
+ notes = "Regression test for hotfix in native code of double parser.",
method = "parseDouble",
args = {java.lang.String.class}
)
- @KnownFailure("Hot fix is submitted to ToT.")
public void test_parseDouble_LString_AndroidRegression() {
// Android regression test
long startTime = System.currentTimeMillis();
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumTest.java
index ccaddeb..94b495f 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumTest.java
@@ -275,10 +275,10 @@
method = "!SerializationGolden",
args = {}
)
- public void _test_compatibilitySerialization_inClass_Complex_Harmony() throws Exception{
+ public void test_compatibilitySerialization_inClass_Complex_Harmony() throws Exception{
// TODO migrate to the new testing framework
assertTrue(SerializationTester.assertCompabilityEquals(new MockEnum2(),
- "serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.harmony.ser"));
+ "/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.harmony.ser"));
}
/**
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java
index 4d5f04d..02bed3c 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java
@@ -17,8 +17,6 @@
package org.apache.harmony.luni.tests.java.lang;
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -796,9 +794,6 @@
method = "pow",
args = {double.class, double.class}
)
- @KnownFailure("Math.pow(double a, double b) returns 1.0 if " +
- "the absolute value of the first argument equals 1 and " +
- "the second argument is infinite. It should return NaN.")
public void test_powDD() {
// Test for method double java.lang.Math.pow(double, double)
assertTrue("pow returned incorrect value",
@@ -825,9 +820,9 @@
Math.pow(0.9, Double.POSITIVE_INFINITY));
assertEquals("pow returned incorrect value", Double.NaN,
- Math.pow(1.0, Double.NEGATIVE_INFINITY));
+ Math.pow(1.0, Double.NEGATIVE_INFINITY));
assertEquals("pow returned incorrect value", Double.NaN,
- Math.pow(1.0, Double.POSITIVE_INFINITY));
+ Math.pow(1.0, Double.POSITIVE_INFINITY));
assertEquals("pow returned incorrect value", 0.0, Math.pow(0, 1));
assertEquals("pow returned incorrect value", 0.0,
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java
index 11139cd..b1b7408 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java
@@ -27,6 +27,8 @@
import java.net.URLClassLoader;
import java.lang.annotation.Annotation;
+import java.lang.annotation.Annotation;
+
import tests.support.resource.Support_Resources;
@TestTargetClass(Package.class)
@@ -38,16 +40,31 @@
Class clazz;
+ // URLClassLoader doesn't load classes from jar.
+ // use PathClassLoader
+ boolean USE_PATH_CLASS_LOADER = true;
+
Package getTestPackage(String resourceJar, String className)
throws Exception {
+
+ if (USE_PATH_CLASS_LOADER) {
+ resourceJar = resourceJar.substring(0, resourceJar.indexOf(".")) +
+ "_dex.jar";
+ }
Support_Resources.copyFile(resources, "Package", resourceJar);
URL resourceURL = new URL("file:/" + resPath + "/Package/"
+ resourceJar);
- URLClassLoader ucl = new URLClassLoader(new URL[] { resourceURL }, null);
-
- clazz = Class.forName(className, true, ucl);
- return clazz.getPackage();
+ ClassLoader cl = null;
+ if(USE_PATH_CLASS_LOADER) {
+ cl = new dalvik.system.PathClassLoader(
+ resourceURL.getPath(), getClass().getClassLoader());
+ } else {
+ cl = new URLClassLoader(new URL[] { resourceURL },
+ getClass().getClassLoader());
+ }
+ clazz = cl.loadClass(className);
+ return clazz.getPackage();
}
@Override
@@ -110,6 +127,7 @@
args = {}
)
})
+ @KnownFailure("get methods don't work.")
public void test_helper_Attributes() throws Exception {
Package p = getTestPackage("hyts_all_attributes.jar", "p.C");
@@ -241,7 +259,7 @@
method = "getPackage",
args = {java.lang.String.class}
)
- @KnownFailure("Package information missing on android")
+ @KnownFailure("Real package information missing on android.")
public void test_getPackageLjava_lang_String() throws Exception {
assertSame("Package getPackage failed for java.lang", Package
.getPackage("java.lang"), Package.getPackage("java.lang"));
@@ -284,7 +302,6 @@
method = "hashCode",
args = {}
)
- @KnownFailure("Package information missing on android")
public void test_hashCode() {
Package p1 = Package.getPackage("java.lang");
if (p1 != null) {
@@ -301,6 +318,7 @@
method = "isCompatibleWith",
args = {java.lang.String.class}
)
+ @KnownFailure("isCompatibleWith returns incorrect value.")
public void test_isCompatibleWithLjava_lang_String() throws Exception {
Package p = getTestPackage("hyts_c.jar", "p.C");
@@ -357,6 +375,7 @@
method = "isSealed",
args = {}
)
+ @KnownFailure("isSealed method returns false for sealed package.")
public void test_isSealed() throws Exception {
Package p = getTestPackage("hyts_pq.jar", "p.q.C");
assertTrue("Package isSealed returns wrong boolean", p.isSealed());
@@ -374,6 +393,7 @@
method = "isSealed",
args = {java.net.URL.class}
)
+ @KnownFailure("isSealed method returns false for sealed package.")
public void test_isSealedLjava_net_URL() throws Exception {
Package p = getTestPackage("hyts_c.jar", "p.C");
assertFalse("Package isSealed returns wrong boolean (1)", p
@@ -404,7 +424,7 @@
method = "getAnnotation",
args = {java.lang.Class.class}
)
- @KnownFailure("Problem in android with loading class from jar")
+ @KnownFailure("Class loader can't retrieve information about annotations.")
public void test_getAnnotation() throws Exception {
String annotationName = "a.b.PackageAnnotation";
Package p = getTestPackage("hyts_package.jar", annotationName);
@@ -422,6 +442,7 @@
method = "getAnnotations",
args = {}
)
+ @KnownFailure("Class loader can't retrieve information about annotations.")
public void test_getAnnotations() throws Exception {
String annotationName = "a.b.PackageAnnotation";
Package p = getTestPackage("hyts_package.jar", annotationName);
@@ -439,6 +460,7 @@
method = "getDeclaredAnnotations",
args = {}
)
+ @KnownFailure("Class loader can't retrieve information about annotations.")
public void test_getDeclaredAnnotations() throws Exception {
String annotationName = "a.b.PackageAnnotation";
Package p = getTestPackage("hyts_package.jar", annotationName);
@@ -457,6 +479,7 @@
method = "isAnnotationPresent",
args = {java.lang.Class.class}
)
+ @KnownFailure("Class loader can't retrieve information about annotations.")
public void test_isAnnotationPresent() throws Exception {
String annotationName = "a.b.PackageAnnotation";
Package p = getTestPackage("hyts_package.jar", annotationName);
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java
index c4066d2..2f2b823 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java
@@ -17,8 +17,6 @@
package org.apache.harmony.luni.tests.java.lang;
-import tests.support.resource.Support_Resources;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -34,6 +32,8 @@
import java.util.Arrays;
import java.util.Vector;
+import tests.support.resource.Support_Resources;
+
@TestTargetClass(Runtime.class)
public class RuntimeTest extends junit.framework.TestCase {
@@ -46,6 +46,8 @@
static boolean flag = false;
static boolean ranFinalize = false;
+
+ int statusCode = -1;
class HasFinalizer {
String internalString;
@@ -71,24 +73,10 @@
}
/**
- * @tests java.lang.Runtime#exit(int)
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "This method never returns normally, and can't be tested.",
- method = "exit",
- args = {int.class}
- )
- public void test_exitI() {
- // Test for method void java.lang.Runtime.exit(int)
- assertTrue("Can't really test this", true);
- }
-
- /**
* @tests java.lang.Runtime#exec(java.lang.String)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.ADDITIONAL,
notes = "",
method = "exec",
args = {java.lang.String.class}
@@ -111,8 +99,26 @@
args = {}
)
public void test_freeMemory() {
- // Test for method long java.lang.Runtime.freeMemory()
- assertTrue("freeMemory returned nonsense value", r.freeMemory() > 0);
+ try {
+ long before = r.freeMemory();
+ Vector<StringBuffer> v = new Vector<StringBuffer>();
+ for (int i = 1; i < 10; i++)
+ v.addElement(new StringBuffer(10000));
+ long after = r.freeMemory();
+ v = null;
+ r.gc();
+ assertTrue("freeMemory should return less value after " +
+ "creating an object", after < before);
+ long afterGC = r.freeMemory();
+ assertTrue("freeMemory should not return less value after " +
+ "creating an object", afterGC > after);
+ } catch (Exception e) {
+ System.out.println("Out of memory during freeMemory test: "
+ + e.getMessage());
+ r.gc();
+ } finally {
+ r.gc();
+ }
}
/**
@@ -141,7 +147,7 @@
assertTrue("space was not reclaimed", (r.totalMemory() - r
.freeMemory()) < secondRead);
} catch (Throwable t) {
- System.out.println("Out of memory during freeMemory test");
+ System.out.println("Out of memory during gc test");
r.gc();
r.gc();
}
@@ -158,7 +164,7 @@
)
public void test_getRuntime() {
// Test for method java.lang.Runtime java.lang.Runtime.getRuntime()
- assertTrue("Used to test", true);
+ assertNotNull(Runtime.getRuntime());
}
/**
@@ -206,9 +212,6 @@
method = "addShutdownHook",
args = {java.lang.Thread.class}
)
- @KnownFailure("IllegalArgumentException is not thrown if " +
- "hook is already registered, and addShutdownHook is " +
- "called again. ToT fixed.")
public void test_addShutdownHook() {
Thread thrException = new Thread () {
public void run() {
@@ -710,23 +713,11 @@
}
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- notes = "Can't be tested. This method terminates the currently running JVM",
- method = "halt",
- args = {int.class}
- )
- public void test_halt() {
- // TODO Can't be tested.
- // This method terminates the currently running JVM.
- }
-
- @TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "runFinalizersOnExit",
args = {boolean.class}
)
- @KnownFailure("Security checking is missed. ToT fixed.")
public void test_runFinalizersOnExit() {
Runtime.getRuntime().runFinalizersOnExit(true);
@@ -758,7 +749,6 @@
method = "removeShutdownHook",
args = {java.lang.Thread.class}
)
- @KnownFailure("Security checking is missed. ToT fixed.")
public void test_removeShutdownHookLjava_lang_Thread() {
Thread thr1 = new Thread () {
public void run() {
@@ -847,7 +837,6 @@
method = "traceMethodCalls",
args = {boolean.class}
)
- @KnownFailure("java.lang.InternalError occurs. ToT fixed.")
public void test_traceMethodCalls() {
Runtime.getRuntime().traceMethodCalls(false);
Runtime.getRuntime().traceMethodCalls(true);
@@ -866,7 +855,6 @@
method = "getLocalizedInputStream",
args = {java.io.InputStream.class}
)
- @KnownFailure("ToT fixed.")
public void test_getLocalizedInputStream() {
String simpleString = "Heart \u2f3c";
byte[] expected = {72, 0, 101, 0, 97, 0, 114, 0, 116, 0, 32, 0, 60, 47};
@@ -903,7 +891,6 @@
method = "getLocalizedOutputStream",
args = {java.io.OutputStream.class}
)
- @KnownFailure("ToT fixed.")
public void test_getLocalizedOutputStream() {
String simpleString = "Heart \u2f3c";
byte[] expected = {72, 0, 101, 0, 97, 0, 114, 0, 116, 0, 32, 0, 60, 47};
@@ -942,8 +929,6 @@
method = "load",
args = {java.lang.String.class}
)
- @KnownFailure("UnsatisfiedLinkError is not thrown for non existent " +
- "library. ToT fixed.")
public void test_load() {
try {
@@ -967,7 +952,7 @@
}
public void checkLink(String lib) {
- if (lib.endsWith("libTestLibrary.so")) {
+ if (lib.endsWith("libjvm.so")) {
throw new SecurityException();
}
}
@@ -976,7 +961,7 @@
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- Runtime.getRuntime().load("libTestLibrary.so");
+ Runtime.getRuntime().load("libjvm.so");
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
@@ -1013,7 +998,7 @@
}
public void checkLink(String lib) {
- if (lib.endsWith("libTestLibrary.so")) {
+ if (lib.endsWith("libjvm.so")) {
throw new SecurityException();
}
}
@@ -1022,7 +1007,7 @@
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
- Runtime.getRuntime().loadLibrary("libTestLibrary.so");
+ Runtime.getRuntime().loadLibrary("libjvm.so");
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
@@ -1031,6 +1016,76 @@
}
}
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "This method never returns normally, " +
+ "and can't be tested. Only SecurityException can be checked.",
+ method = "exit",
+ args = {int.class}
+ )
+ public void test_exit() {
+ statusCode = -1;
+ SecurityManager sm = new SecurityManager() {
+
+ public void checkPermission(Permission perm) {
+
+ }
+
+ public void checkExit(int status) {
+ statusCode = status;
+ throw new SecurityException();
+ }
+ };
+
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ r.exit(0);
+ fail("SecurityException should be thrown.");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ assertTrue("Incorrect status code was received: " + statusCode,
+ statusCode == 0);
+ System.setSecurityManager(oldSm);
+ }
+
+ }
+
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "Can't be tested. This method terminates the currently " +
+ "running VM. Only SecurityException can be checked.",
+ method = "halt",
+ args = {int.class}
+ )
+ public void test_halt() {
+ statusCode = -1;
+ SecurityManager sm = new SecurityManager() {
+
+ public void checkPermission(Permission perm) {
+
+ }
+
+ public void checkExit(int status) {
+ statusCode = status;
+ throw new SecurityException();
+ }
+ };
+
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ r.halt(0);
+ fail("SecurityException should be thrown.");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ assertTrue("Incorrect status code was received: " + statusCode,
+ statusCode == 0);
+ System.setSecurityManager(oldSm);
+ }
+ }
public RuntimeTest() {
}
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManager2Test.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManager2Test.java
deleted file mode 100644
index 9c70c87..0000000
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManager2Test.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.tests.java.lang;
-
-import dalvik.annotation.BrokenTest;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
-import java.security.Permission;
-
-import tests.support.Support_Exec;
-
-@TestTargetClass(SecurityManager.class)
-public class SecurityManager2Test extends TestCase {
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "SecurityManager",
- args = {}
- )
- @BrokenTest("Support_Exec.execJava is not so simple to use: Harmony Test cannot be easily adapted.")
- public void test_SecurityManager_via_SystemProperty() throws Exception {
- String[] arg = new String[] {
- "-Djava.security.manager=" + MySecurityManager.class.getName(),
- TestForSystemProperty.class.getName() };
-
- Support_Exec.execJava(arg, null, true);
- }
-
- public static class TestForSystemProperty {
-
- public static void main(String[] args) {
- assertEquals(MySecurityManager.class, System.getSecurityManager()
- .getClass());
- }
- }
-
- /**
- * Custom security manager
- */
- public static class MySecurityManager extends SecurityManager {
- public void checkPermission(Permission perm) {
- }
- }
-}
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManagerTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManagerTest.java
index 3f40541..be5aa41 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManagerTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManagerTest.java
@@ -16,7 +16,6 @@
package org.apache.harmony.luni.tests.java.lang;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -215,7 +214,6 @@
method = "checkMemberAccess",
args = {java.lang.Class.class, int.class}
)
- @KnownFailure("ToT fixed.")
public void test_checkMemberAccessLjava_lang_ClassI() {
// enable all but one check
mutableSM.addPermission(new AllPermission());
@@ -510,7 +508,6 @@
method = "checkConnect",
args = {java.lang.String.class, int.class}
)
- @KnownFailure("ToT fixed.")
public void test_checkConnectLjava_lang_StringI() {
String hostName = "localhost";
int port = 1024;
@@ -569,7 +566,6 @@
method = "checkConnect",
args = {java.lang.String.class, int.class, java.lang.Object.class}
)
- @KnownFailure("ToT fixed.")
@SuppressWarnings("nls")
public void test_checkConnectLjava_lang_String_int_Ljava_lang_Object() {
// enable all but one check
@@ -1558,7 +1554,6 @@
method = "getClassContext",
args = {}
)
- @KnownFailure("ToT fixed.")
public void test_getClassContext() {
Class [] stack = {MockSecurityManager.class,
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringTest.java
index 6c995bb..4ad0c52 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringTest.java
@@ -17,15 +17,14 @@
package org.apache.harmony.luni.tests.java.lang;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
import junit.framework.TestCase;
import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Constructor;
+import java.math.BigDecimal;
@TestTargetClass(String.class)
public class StringTest extends TestCase {
@@ -701,4 +700,40 @@
} catch (IndexOutOfBoundsException e) {
}
}
+
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ notes = "Regression test for some existing bugs and crashes",
+ method = "format",
+ args = { String.class, Object[].class }
+ )
+ public void testProblemCases() {
+ BigDecimal[] input = new BigDecimal[] {
+ new BigDecimal("20.00000"),
+ new BigDecimal("20.000000"),
+ new BigDecimal(".2"),
+ new BigDecimal("2"),
+ new BigDecimal("-2"),
+ new BigDecimal("200000000000000000000000"),
+ new BigDecimal("20000000000000000000000000000000000000000000000000")
+ };
+
+ String[] output = new String[] {
+ "20.00",
+ "20.00",
+ "0.20",
+ "2.00",
+ "-2.00",
+ "200000000000000000000000.00",
+ "20000000000000000000000000000000000000000000000000.00"
+ };
+
+ for (int i = 0; i < input.length; i++) {
+ String result = String.format("%.2f", input[i]);
+ assertEquals("Format test for \"" + input[i] + "\" failed, " +
+ "expected=" + output[i] + ", " +
+ "actual=" + result, output[i], result);
+ }
+ }
+
}
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SystemTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SystemTest.java
index b1b3c5f..2c65f52 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SystemTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SystemTest.java
@@ -17,7 +17,6 @@
package org.apache.harmony.luni.tests.java.lang;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -51,7 +50,6 @@
method = "setIn",
args = {java.io.InputStream.class}
)
- @KnownFailure("Security checking is missed. ToT fixed.")
public void test_setInLjava_io_InputStream() {
InputStream orgIn = System.in;
InputStream in = new ByteArrayInputStream(new byte[0]);
@@ -90,7 +88,6 @@
method = "setOut",
args = {java.io.PrintStream.class}
)
- @KnownFailure("Security checking is missed. ToT fixed.")
public void test_setOutLjava_io_PrintStream() {
PrintStream orgOut = System.out;
PrintStream out = new PrintStream(new ByteArrayOutputStream());
@@ -129,7 +126,6 @@
method = "setErr",
args = {java.io.PrintStream.class}
)
- @KnownFailure("Security checking is missed. ToT fixed.")
public void test_setErrLjava_io_PrintStream() {
PrintStream orgErr = System.err;
PrintStream err = new PrintStream(new ByteArrayOutputStream());
@@ -170,8 +166,6 @@
args = {java.lang.Object.class, int.class, java.lang.Object.class,
int.class, int.class}
)
- @KnownFailure("Doesn't throw IndexOutOfBoundsException for boundary value " +
- "of src position. Failure in native code, doesn't check overflow.")
public void test_arraycopyLjava_lang_ObjectILjava_lang_ObjectII() {
// Test for method void java.lang.System.arraycopy(java.lang.Object,
// int, java.lang.Object, int, int)
@@ -684,7 +678,6 @@
method = "inheritedChannel",
args = {}
)
- @KnownFailure("Security checking is missed. ToT fixed.")
public void test_inheritedChannel() throws IOException {
Channel iChannel = System.inheritedChannel();
assertNull("Incorrect value of channel", iChannel);
@@ -747,7 +740,6 @@
method = "runFinalizersOnExit",
args = {boolean.class}
)
- @KnownFailure("Security checking is missed. ToT fixed.")
@SuppressWarnings("deprecation")
public void test_runFinalizersOnExitZ() {
// Can we call the method at least?
@@ -1001,9 +993,6 @@
method = "getenv",
args = {}
)
- @KnownFailure("getenv() method returns empty map, " +
- "because getEnvByIndex always returns null. " +
- "ToT fixed.")
public void test_getenv() {
// String[] props = { "PATH", "HOME", "USER"};
@@ -1090,7 +1079,6 @@
method = "load",
args = {java.lang.String.class}
)
- @KnownFailure("UnsatisfiedLinkError is not thrown. ToT fixed.")
public void test_load() {
try {
new TestLibrary().checkString();
@@ -1142,7 +1130,6 @@
method = "loadLibrary",
args = {java.lang.String.class}
)
- @KnownFailure("Security checking is missed. ToT fixed.")
public void test_loadLibrary() {
try {
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TestLibrary.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TestLibrary.java
index 12eb1fc..2748223 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TestLibrary.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TestLibrary.java
@@ -16,6 +16,12 @@
package org.apache.harmony.luni.tests.java.lang;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
class TestLibrary {
private native String printName();
@@ -25,7 +31,20 @@
return false;
}
- static {
- Runtime.getRuntime().load(TestLibrary.class.getResource("/libTestLibrary.so").getPath());
+ TestLibrary() {
+ InputStream in = TestLibrary.class.getResourceAsStream("/libTestLibrary.so");
+ try {
+ File tmp = File.createTempFile("libTestLibrary", "so");
+ tmp.deleteOnExit();
+ FileOutputStream out = new FileOutputStream(tmp);
+ while (in.available() > 0) {
+ out.write(in.read()); // slow
+ }
+ in.close();
+ out.close();
+ Runtime.getRuntime().load(tmp.getAbsolutePath());
+ } catch (FileNotFoundException e) {
+ } catch (IOException e) {
+ }
}
}
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadGroupTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadGroupTest.java
index 9afa4a9..39bc92d 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadGroupTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadGroupTest.java
@@ -17,9 +17,7 @@
package org.apache.harmony.luni.tests.java.lang;
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestTargets;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -83,8 +81,6 @@
method = "ThreadGroup",
args = {java.lang.String.class}
)
- @KnownFailure("Security checking is missed. " +
- "checkAccess method should be invoked.")
public void test_ConstructorLjava_lang_String() {
// Test for method java.lang.ThreadGroup(java.lang.String)
@@ -131,8 +127,6 @@
method = "ThreadGroup",
args = {java.lang.ThreadGroup.class, java.lang.String.class}
)
- @KnownFailure("Security checking is missed. " +
- "checkAccess method should be invoked.")
public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() {
// Test for method java.lang.ThreadGroup(java.lang.ThreadGroup,
// java.lang.String)
@@ -207,8 +201,6 @@
method = "activeCount",
args = {}
)
- @KnownFailure("Active thread count is not increased after starting of " +
- "the thread from ThreadGroup.")
public void test_activeCount() {
// Test for method int java.lang.ThreadGroup.activeCount()
ThreadGroup tg = new ThreadGroup("activeCount");
@@ -250,7 +242,7 @@
0, tg.activeGroupCount());
Thread t1 = new Thread(tg, new Runnable() {
public void run() {
- // TODO Auto-generated method stub
+
}
});
assertEquals("Incorrect number of groups",
@@ -293,8 +285,6 @@
method = "checkAccess",
args = {}
)
- @KnownFailure("Security checking is missed. " +
- "checkAccess method should be invoked.")
public void test_checkAccess() {
// Test for method void java.lang.ThreadGroup.checkAccess()
@@ -334,8 +324,6 @@
method = "enumerate",
args = {java.lang.Thread[].class}
)
- @KnownFailure("Security checking is missed. " +
- "checkAccess method should be invoked.")
public void test_enumerateLThreadArray() {
int numThreads = initialThreadGroup.activeCount();
Thread[] listOfThreads = new Thread[numThreads];
@@ -362,7 +350,6 @@
method = "enumerate",
args = {java.lang.Thread[].class, boolean.class}
)
- @KnownFailure("Depends of activeCount failure.")
public void test_enumerateLThreadArrayLZ() {
int numThreads = initialThreadGroup.activeCount();
Thread[] listOfThreads = new Thread[numThreads];
@@ -440,8 +427,6 @@
method = "enumerate",
args = {java.lang.ThreadGroup[].class}
)
- @KnownFailure("Security checking is missed. " +
- "checkAccess method should be invoked.")
public void test_enumerateLThreadGroupArray() {
int numGroupThreads = initialThreadGroup.activeGroupCount();
ThreadGroup[] listOfGroups = new ThreadGroup[numGroupThreads];
@@ -480,8 +465,6 @@
method = "enumerate",
args = {java.lang.ThreadGroup[].class, boolean.class}
)
- @KnownFailure("Security checking is missed. " +
- "checkAccess method should be invoked.")
public void test_enumerateLThreadGroupArrayLZ() {
ThreadGroup thrGroup = new ThreadGroup("Test Group 1");
Vector<MyThread> subThreads = populateGroupsWithThreads(thrGroup, 3);
@@ -551,8 +534,6 @@
method = "destroy",
args = {}
)
- @KnownFailure("the daemon thread group is not get destroyed " +
- " if the last daemon's child is destroyed.")
public void test_destroy() {
// Test for method void java.lang.ThreadGroup.destroy()
@@ -773,7 +754,6 @@
method = "getParent",
args = {}
)
- @KnownFailure("checkAccess method is called with incorrect group???")
public void test_getParent() {
// Test for method java.lang.ThreadGroup
// java.lang.ThreadGroup.getParent()
@@ -838,8 +818,6 @@
method = "interrupt",
args = {}
)
- @KnownFailure("Security checking is missed. " +
- "checkAccess method should be invoked.")
public void test_interrupt() {
Thread.setDefaultUncaughtExceptionHandler(this);
@@ -1019,9 +997,8 @@
method = "resume",
args = {}
)
- @KnownFailure("Failure depends on activeCount().")
@SuppressWarnings("deprecation")
- @AndroidOnly("Thread.resume is implemented on some RI")
+ @BrokenTest("Thread.resume is implemented on some RI")
public void test_resume() throws OutOfMemoryError {
// Test for method void java.lang.ThreadGroup.resume()
final ThreadGroup originalCurrent = getInitialThreadGroup();
@@ -1087,8 +1064,6 @@
method = "setDaemon",
args = {boolean.class}
)
- @KnownFailure("Security checking is missed. " +
- "checkAccess method should be invoked.")
public void test_setDaemonZ() {
// Test for method void java.lang.ThreadGroup.setDaemon(boolean)
daemonTests();
@@ -1119,8 +1094,6 @@
method = "setMaxPriority",
args = {int.class}
)
- @KnownFailure("Security checking is missed. " +
- "checkAccess method should be invoked.")
public void test_setMaxPriorityI() {
// Test for method void java.lang.ThreadGroup.setMaxPriority(int)
final ThreadGroup originalCurrent = getInitialThreadGroup();
@@ -1262,7 +1235,7 @@
method = "stop",
args = {}
)
- @AndroidOnly("stop() method not implemented. throws UnsupportedOperationException.")
+ @BrokenTest("stop() method not implemented.")
@SuppressWarnings("deprecation")
public void test_stop() throws OutOfMemoryError {
// Test for method void java.lang.ThreadGroup.stop()
@@ -1331,7 +1304,7 @@
method = "suspend",
args = {}
)
- @AndroidOnly("suspend() method not implemented. throws UnsupportedOperationException.")
+ @BrokenTest("suspend() method not implemented.")
@SuppressWarnings("deprecation")
public void test_suspend() throws OutOfMemoryError {
// Test for method void java.lang.ThreadGroup.suspend()
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadTest.java
index 588106c..b290555 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadTest.java
@@ -24,7 +24,6 @@
import java.util.Map;
import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -1971,7 +1970,6 @@
method = "getState",
args = {}
)
- @KnownFailure("ToT FIXED")
public void test_getState() {
Thread.State state = Thread.currentThread().getState();
assertNotNull(state);
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/HttpURLConnectionTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/HttpURLConnectionTest.java
index 29d26da..968a056 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/HttpURLConnectionTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/HttpURLConnectionTest.java
@@ -17,7 +17,6 @@
package org.apache.harmony.luni.tests.java.net;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -28,12 +27,10 @@
import java.io.OutputStream;
import java.net.CacheRequest;
import java.net.CacheResponse;
-import java.net.DatagramSocket;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.ResponseCache;
-import java.net.SocketException;
import java.net.SocketPermission;
import java.net.URI;
import java.net.URL;
@@ -592,7 +589,6 @@
method = "setUseCaches",
args = {boolean.class}
)
- @KnownFailure("getInputStream doesn't call get method of cache")
public void test_UseCache_HttpURLConnection_NonCached() throws IOException {
ResponseCache.setDefault(new MockNonCachedResponseCache());
uc = (HttpURLConnection) url.openConnection();
@@ -600,7 +596,6 @@
// default useCaches is true
assertTrue(uc.getUseCaches());
uc.setDoInput(true);
- uc.connect();
// make sure ResponseCache.get/put is called
isGetCalled = false;
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/Inet6AddressTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/Inet6AddressTest.java
index 1b2aa22..498c486 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/Inet6AddressTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/Inet6AddressTest.java
@@ -18,12 +18,10 @@
package org.apache.harmony.luni.tests.java.net;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import java.io.Serializable;
-import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
@@ -1173,23 +1171,57 @@
args = {}
)
public void test_getHostAddress() throws Exception {
- InetAddress addr = Inet6Address.getByName("localhost");
- assertEquals("127.0.0.1", addr.getHostAddress());
-
- addr = Inet6Address.getByName("127.0.0.1");
- assertEquals("127.0.0.1", addr.getHostAddress());
-
- addr = Inet6Address.getByName("224.0.0.0");
- assertEquals("224.0.0.0", addr.getHostAddress());
-
- addr = Inet6Address.getByName("1");
- assertEquals("0.0.0.1", addr.getHostAddress());
-
- addr = Inet6Address.getByName("1.1");
- assertEquals("1.0.0.1", addr.getHostAddress());
-
- addr = Inet6Address.getByName("1.1.1");
- assertEquals("1.1.0.1", addr.getHostAddress());
+ InetAddress aAddr = Inet6Address.getByName("localhost");
+ assertEquals("127.0.0.1", aAddr.getHostAddress());
+
+ aAddr = Inet6Address.getByName("127.0.0.1");
+ assertEquals("127.0.0.1", aAddr.getHostAddress());
+
+ aAddr = Inet6Address.getByName("224.0.0.0");
+ assertEquals("224.0.0.0", aAddr.getHostAddress());
+
+ aAddr = Inet6Address.getByName("1");
+ assertEquals("0.0.0.1", aAddr.getHostAddress());
+
+ aAddr = Inet6Address.getByName("1.1");
+ assertEquals("1.0.0.1", aAddr.getHostAddress());
+
+ aAddr = Inet6Address.getByName("1.1.1");
+ assertEquals("1.1.0.1", aAddr.getHostAddress());
+
+ byte[] bAddr = { (byte) 0xFE, (byte) 0x80, 0, 0, 0, 0, 0, 0, 0x02, 0x11,
+ 0x25, (byte) 0xFF, (byte) 0xFE, (byte) 0xF8, (byte) 0x7C,
+ (byte) 0xB2 };
+ aAddr = Inet6Address.getByAddress(bAddr);
+ assertEquals("fe80:0:0:0:211:25ff:fef8:7cb2", aAddr.getHostAddress());
+
+ byte[] cAddr = { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+ aAddr = Inet6Address.getByAddress(cAddr);
+ assertEquals("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", aAddr.getHostAddress());
+
+ byte[] dAddr = { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
+ aAddr = Inet6Address.getByAddress(dAddr);
+ assertEquals("0:0:0:0:0:0:0:0", aAddr.getHostAddress());
+
+ byte[] eAddr = { (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
+ (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
+ (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b,
+ (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f};
+ aAddr = Inet6Address.getByAddress(eAddr);
+ assertEquals("1:203:405:607:809:a0b:c0d:e0f", aAddr.getHostAddress());
+
+ byte[] fAddr = { (byte) 0x00, (byte) 0x10, (byte) 0x20, (byte) 0x30,
+ (byte) 0x40, (byte) 0x50, (byte) 0x60, (byte) 0x70,
+ (byte) 0x80, (byte) 0x90, (byte) 0xa0, (byte) 0xb0,
+ (byte) 0xc0, (byte) 0xd0, (byte) 0xe0, (byte) 0xf0};
+ aAddr = Inet6Address.getByAddress(fAddr);
+ assertEquals("10:2030:4050:6070:8090:a0b0:c0d0:e0f0", aAddr.getHostAddress());
}
@TestTargetNew(
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetSocketAddressTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetSocketAddressTest.java
index 15f3a5a..b979628 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetSocketAddressTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/InetSocketAddressTest.java
@@ -15,6 +15,7 @@
*/
package org.apache.harmony.luni.tests.java.net;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -323,7 +324,8 @@
method = "!SerializationGolden",
args = {}
)
- public void _testSerializationCompatibility() throws Exception {
+ @KnownFailure("Problem with deserialization of Localhost vs. localhost")
+ public void testSerializationCompatibility() throws Exception {
Object[] testCases = {
InetSocketAddress.createUnresolved("badhost", 1000), // unresolved
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
index 51189ff..7a6c505 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
@@ -32,39 +32,36 @@
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
import java.io.File;
import java.io.FilePermission;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import java.lang.reflect.Field;
-import java.net.ContentHandler;
-import java.net.ContentHandlerFactory;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
import java.net.FileNameMap;
import java.net.HttpURLConnection;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
+import java.net.ResponseCache;
import java.net.SocketPermission;
import java.net.SocketTimeoutException;
+import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.UnknownServiceException;
-import java.security.AllPermission;
import java.security.Permission;
import java.util.Arrays;
import java.util.Calendar;
-import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
-import java.util.Vector;
-import java.util.logging.StreamHandler;
@TestTargetClass(
value = URLConnection.class,
@@ -98,8 +95,18 @@
private URLConnection gifURLCon;
private URL gifURL;
+
+ public boolean isGetCalled;
+
+ public boolean isPutCalled;
-
+ private Map<String, List<String>> mockHeaderMap;
+
+ private InputStream mockIs = new MockInputStream();
+
+ public boolean isCacheWriteCalled;
+
+ public boolean isAbortCalled;
/**
* @tests {@link java.net.URLConnection#addRequestProperty(String, String)}
@@ -255,6 +262,98 @@
};
}
}
+
+ class MockCachedResponseCache extends ResponseCache {
+
+ public CacheResponse get(URI arg0, String arg1, Map arg2)
+ throws IOException {
+ if (null == arg0 || null == arg1 || null == arg2) {
+ throw new NullPointerException();
+ }
+ isGetCalled = true;
+ return new MockCacheResponse();
+ }
+
+ public CacheRequest put(URI arg0, URLConnection arg1)
+ throws IOException {
+ if (null == arg0 || null == arg1) {
+ throw new NullPointerException();
+ }
+ isPutCalled = true;
+ return new MockCacheRequest();
+ }
+ }
+
+ class MockNonCachedResponseCache extends ResponseCache {
+
+ public CacheResponse get(URI arg0, String arg1, Map arg2)
+ throws IOException {
+ isGetCalled = true;
+ return null;
+ }
+
+ public CacheRequest put(URI arg0, URLConnection arg1)
+ throws IOException {
+ isPutCalled = true;
+ return new MockCacheRequest();
+ }
+ }
+
+ class MockCacheRequest extends CacheRequest {
+
+ public OutputStream getBody() throws IOException {
+ isCacheWriteCalled = true;
+ return new MockOutputStream();
+ }
+
+ public void abort() {
+ isAbortCalled = true;
+ }
+
+ }
+
+ class MockInputStream extends InputStream {
+
+ public int read() throws IOException {
+ return 4711;
+ }
+
+ public int read(byte[] arg0, int arg1, int arg2) throws IOException {
+ return 1;
+ }
+
+ public int read(byte[] arg0) throws IOException {
+ return 1;
+ }
+
+ }
+
+ class MockOutputStream extends OutputStream {
+
+ public void write(int b) throws IOException {
+ isCacheWriteCalled = true;
+ }
+
+ public void write(byte[] b, int off, int len) throws IOException {
+ isCacheWriteCalled = true;
+ }
+
+ public void write(byte[] b) throws IOException {
+ isCacheWriteCalled = true;
+ }
+ }
+
+ class MockCacheResponse extends CacheResponse {
+
+ public Map<String, List<String>> getHeaders() throws IOException {
+ return mockHeaderMap;
+ }
+
+ public InputStream getBody() throws IOException {
+ return mockIs;
+ }
+ }
+
private static int port;
@@ -274,6 +373,7 @@
URLConnection uc2;
+ @Override
public void setUp() throws Exception {
super.setUp();
@@ -298,6 +398,7 @@
}
+ @Override
public void tearDown()throws Exception {
super.tearDown();
((HttpURLConnection) uc).disconnect();
@@ -367,7 +468,7 @@
args = {}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.SUFFICIENT,
notes = "From harmony branch.",
method = "setAllowUserInteraction",
args = {boolean.class}
@@ -391,6 +492,44 @@
//ok
}
+ // test if setAllowUserInteraction works
+ URL serverURL = new URL("http://onearth.jpl.nasa.gov/landsat.cgi");
+
+ // connect to server
+ URLConnection uc2 = serverURL.openConnection();
+ HttpURLConnection conn = (HttpURLConnection) uc2;
+ uc2.setAllowUserInteraction(true);
+
+ uc2.setDoInput(true);
+ uc2.setDoOutput(true);
+
+ // get reference to stream to post to
+ OutputStream os = uc2.getOutputStream();
+
+ InputStream in = uc2.getInputStream();
+
+
+ int contentLength = uc2.getContentLength();
+ String contentType = uc2.getContentType();
+ int numBytesRead = 0;
+ int allBytesRead = 0;
+
+ byte[] buffer = new byte[4096];
+
+ do {
+
+ numBytesRead = in.read(buffer);
+ allBytesRead += allBytesRead + numBytesRead;
+
+ } while (numBytesRead > 0);
+
+ assertTrue(allBytesRead > 0);
+
+ uc2.connect();
+
+ numBytesRead = in.read(buffer);
+
+ assertEquals(-1, numBytesRead);
}
/**
@@ -643,12 +782,11 @@
),
@TestTargetNew(
level = TestLevel.COMPLETE,
- notes = "From harmony branch. Test Fails: undocumented exception IlligalAccessError",
+ notes = "From harmony branch.",
method = "setDefaultAllowUserInteraction",
args = {boolean.class}
)
})
- @KnownFailure("needs investigation")
public void test_getDefaultAllowUserInteraction() throws IOException {
boolean oldSetting = URLConnection.getDefaultAllowUserInteraction();
@@ -662,20 +800,10 @@
URLConnection.getDefaultAllowUserInteraction());
URLConnection.setDefaultAllowUserInteraction(oldSetting);
-
- uc.connect();
-
- // check if undocumented exception is thrown
- try {
- uc.setDefaultUseCaches(oldSetting);
- } catch ( IllegalAccessError e) {
- fail("Undocumented exception thrown "+e.getMessage());
- }
-
}
/**
- * @tests {@link java.net.URLConnection#getDefaultRequestProperty(java.lang.String)}
+ * @tests {@link java.net.URLConnection#getDefaultRequestProperty(String)}
*/
@TestTargets({
@TestTargetNew(
@@ -709,7 +837,7 @@
/**
* @throws IOException
- * @tests{@link java.net.URLConnection#getDefaultUseCaches()}
+ * @tests {@link java.net.URLConnection#getDefaultUseCaches()}
*/
@TestTargets({
@TestTargetNew(
@@ -725,25 +853,63 @@
args = {boolean.class}
)
})
- @KnownFailure("The final call to connect throws an unexpected Exception")
- public void test_getDefaultUseCaches() throws IOException {
+ public void test_getDefaultUseCaches_CachedRC() throws IOException {
boolean oldSetting = uc.getDefaultUseCaches();
-
+
+ ResponseCache old = ResponseCache.getDefault();
+ ResponseCache rc = new MockCachedResponseCache();
+ ResponseCache.setDefault(rc);
+
+ // Recreate the connection so that we get the cache from ResponseCache.
+ uc2 = url2.openConnection();
+
+ uc2.setUseCaches(true);
+
uc.setDefaultUseCaches(false);
+
+ // uc unaffected
+ assertTrue(uc.getUseCaches());
+ // uc2 unaffected
+ assertTrue(uc2.getUseCaches());
+
+ //test get
assertFalse("getDefaultUseCaches should have returned false", uc
.getDefaultUseCaches());
-
- uc.setDefaultUseCaches(true);
- assertTrue("getDefaultUseCaches should have returned true", uc
- .getDefaultUseCaches());
-
- uc.setDefaultUseCaches(oldSetting);
+ // subsequent connections should have default value
+ URL url3 = new URL(Support_Configuration.hTTPURLyahoo);
+ URLConnection uc3 = url3.openConnection();
+ assertFalse(uc3.getUseCaches());
+
+ // test if uc does not chash but uc2 does
+ isGetCalled = false;
+ isPutCalled = false;
+
+ // test uc
+ uc.setDoOutput(true);
+
+ assertFalse(isGetCalled);
uc.connect();
+ assertFalse(isGetCalled);
+ assertFalse(isPutCalled);
+ OutputStream os = uc.getOutputStream();
+ assertFalse(isPutCalled);
+ assertFalse(isGetCalled);
- // check if undocumented exception is thrown
-
+ os.close();
+
+ isGetCalled = false;
+ isPutCalled = false;
+
+ //uc2 should be unaffected
+ uc2.setDoOutput(true);
+ assertFalse(isGetCalled);
+ uc2.connect();
+ assertTrue(isGetCalled);
+ assertFalse(isPutCalled);
+
uc.setDefaultUseCaches(oldSetting);
+ ResponseCache.setDefault(null);
}
/**
@@ -833,6 +999,8 @@
method = "getExpiration",
args = {}
)
+ @KnownFailure("URLConnection.getExpiration crashes because the returned" +
+ " expiration date doesn't seems to be parsable.")
public void test_getExpiration() throws IOException {
URL url3 = new URL(Support_Configuration.hTTPURLwExpiration);
URLConnection uc3 = url3.openConnection();
@@ -1038,6 +1206,7 @@
method = "getHeaderField",
args = {java.lang.String.class}
)
+ @BrokenTest("Flaky due to third party servers used to do the test.")
public void test_getHeaderFieldLjava_lang_String() {
String hf;
int hfDefault;
@@ -1437,10 +1606,7 @@
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
- notes = "Test fails: checking file://data/local/tmp/hyts_htmltest.html " +
- "with file:/data/local/tmp/openStreamTest15770.txt expected: " +
- "<...html> but was:<...plain>\n" +
- "",
+ notes = "",
method = "guessContentTypeFromName",
args = {java.lang.String.class}
)
@@ -1478,21 +1644,28 @@
method = "guessContentTypeFromStream",
args = {java.io.InputStream.class}
)
- @BrokenTest("Also fails on the RI.")
+ @BrokenTest("MIME type application xml is not supported: only text html."+
+ " Should be implemented if compatibility is required. The RI" +
+ " on the other hand doesn't recognise the '<head' tag.")
public void test_guessContentTypeFromStreamLjava_io_InputStream()
throws IOException {
String[] headers = new String[] { "<html>", "<head>", " <head ",
- "<body", "<BODY ", "<!DOCTYPE html", "<?xml " };
- String[] expected = new String[] { "text/html", "text/html",
- "text/html", "text/html", "text/html", "text/html",
- "application/xml" };
+ "<body", "<BODY ", //"<!DOCTYPE html",
+ "<?xml " };
+ String[] expected = new String[] { "text/html","text/html", "text/html",
+ "text/html","text/html", "application/xml" };
- String[] encodings = new String[] { "ASCII", "UTF-8", "UTF-16BE",
- "UTF-16LE", "UTF-32BE", "UTF-32LE" };
+ String[] encodings = new String[] { "ASCII", "UTF-8",
+ //"UTF-16BE", not supported
+ //"UTF-16LE", not supported
+ //"UTF-32BE", not supported encoding
+ //"UTF-32LE" not supported encoding
+ };
for (int i = 0; i < headers.length; i++) {
for (String enc : encodings) {
- InputStream is = new ByteArrayInputStream(toBOMBytes(
- headers[i], enc));
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ String encodedString = new String(headers[i].getBytes(), enc);
+ InputStream is = new ByteArrayInputStream(encodedString.getBytes());
String mime = URLConnection.guessContentTypeFromStream(is);
assertEquals("checking " + headers[i] + " with " + enc,
expected[i], mime);
@@ -1506,7 +1679,7 @@
} catch (NullPointerException e) {
// expected
}
-
+ /* not supported
// Test magic bytes
byte[][] bytes = new byte[][] { { 'P', 'K' }, { 'G', 'I' } };
expected = new String[] { "application/zip", "image/gif" };
@@ -1516,6 +1689,7 @@
assertEquals(expected[i], URLConnection
.guessContentTypeFromStream(is));
}
+ */
}
// /**
@@ -1774,7 +1948,6 @@
args = {}
)
})
- @KnownFailure("uc2.getContent returns null")
public void test_setReadTimeoutI() throws Exception {
assertEquals(0, uc.getReadTimeout());
uc.setReadTimeout(0);
@@ -1798,9 +1971,12 @@
byte[] ba = new byte[600];
- uc2.setReadTimeout(50);
+ uc2.setReadTimeout(5);
+ uc2.setDoInput(true);
+ uc2.connect();
+
try {
- ((InputStream) uc2.getContent()).read(ba, 0, 600);
+ ((InputStream) uc2.getInputStream()).read(ba, 0, 600);
} catch (SocketTimeoutException e) {
//ok
} catch ( UnknownServiceException e) {
@@ -1837,11 +2013,12 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
- method = "getInputStream",
- args = {}
- )
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "getInputStream",
+ args = {}
+ )
+ @BrokenTest("Flaky test due to the use of third party servers")
public void testGetInputStream() throws IOException {
fileURLCon.setDoInput(true);
fileURLCon.connect();
@@ -1898,33 +2075,7 @@
System.setSecurityManager(old_sm);
}
- }
-
- private byte[] toBOMBytes(String text, String enc) throws IOException {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
- if (enc.equals("UTF-8")) {
- bos.write(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF });
- }
- if (enc.equals("UTF-16BE")) {
- bos.write(new byte[] { (byte) 0xFE, (byte) 0xFF });
- }
- if (enc.equals("UTF-16LE")) {
- bos.write(new byte[] { (byte) 0xFF, (byte) 0xFE });
- }
- if (enc.equals("UTF-32BE")) {
- bos.write(new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0xFE,
- (byte) 0xFF });
- }
- if (enc.equals("UTF-32LE")) {
- bos.write(new byte[] { (byte) 0xFF, (byte) 0xFE, (byte) 0x00,
- (byte) 0x00 });
- }
-
- bos.write(text.getBytes(enc));
- return bos.toByteArray();
- }
-
+ }
private URLConnection openGifURLConnection() throws IOException {
String cts = System.getProperty("java.io.tmpdir");
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLTest.java
index f16f881..1e38d90 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLTest.java
@@ -53,6 +53,7 @@
import java.net.URLStreamHandlerFactory;
import java.security.Permission;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
@TestTargetClass(URL.class)
@@ -528,7 +529,6 @@
method = "toURI",
args = {}
)
- @BrokenTest("cannot think of case which throws URISyntaxException on a valid URL")
public void testToURI() throws MalformedURLException, URISyntaxException {
String testHTTPURLString = "http://www.gamelan.com/pages/";
String testFTPURLString = "ftp://myname@host.dom/etc/motd";
@@ -540,12 +540,42 @@
assertEquals(testHTTPURI.toString(),testHTTPURLString);
assertEquals(testFTPURI.toString(),testFTPURLString);
- try {
- URL urlQuery = new URL("jar:file:tests/resources/hyts_att.jar!/NoAttributes.txt");
- urlQuery.toURI();
- fail("Exception expected");
- } catch (URISyntaxException e) {
- // ok
+ //Exception test
+ String[] constructorTestsInvalid = new String[] {
+ "http:///a path#frag", // space char in path, not in escaped
+ // octet form, with no host
+ "http://host/a[path#frag", // an illegal char, not in escaped
+ // octet form, should throw an
+ // exception
+ "http://host/a%path#frag", // invalid escape sequence in path
+ "http://host/a%#frag", // incomplete escape sequence in path
+
+ "http://host#a frag", // space char in fragment, not in
+ // escaped octet form, no path
+ "http://host/a#fr#ag", // illegal char in fragment
+ "http:///path#fr%ag", // invalid escape sequence in fragment,
+ // with no host
+ "http://host/path#frag%", // incomplete escape sequence in
+ // fragment
+
+ "http://host/path?a query#frag", // space char in query, not
+ // in escaped octet form
+ "http://host?query%ag", // invalid escape sequence in query, no
+ // path
+ "http:///path?query%", // incomplete escape sequence in query,
+ // with no host
+
+ "mailto:user^name@fklkf.com" // invalid char in scheme
+ };
+
+ for (String malformedURI : Arrays.asList(constructorTestsInvalid)) {
+ try {
+ URL urlQuery = new URL("http://host/a%path#frag");
+ urlQuery.toURI();
+ fail("Exception expected");
+ } catch (URISyntaxException e) {
+ // ok
+ }
}
}
@@ -554,83 +584,81 @@
*/
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
- notes = "Proxy does not work. Neither Proxy HTTP nor Proxy SOCKS work.",
+ notes = "See ExcludedProxyTest.",
method = "openConnection",
args = {java.net.Proxy.class}
)
- @BrokenTest("Hangs in RI and fails in Android")
+ @BrokenTest("the host address isn't working anymore")
public void testOpenConnectionProxy() throws IOException {
- URL gSearch = new URL("http://www.google.ch/");
- HttpURLConnection uc = null;
- int port = Support_PortManager.getNextPort();
- SocketAddress addr1 = new InetSocketAddress("test.domain.org", port);
- startServer("test.domain.org", port);
- Proxy proxy1 = new Proxy(Proxy.Type.SOCKS, addr1);
- Socket sock = new Socket(proxy1);
- try {
- uc = (HttpURLConnection) gSearch.openConnection(
- );
- uc.connect();
- uc.getResponseCode();
- assertEquals(uc.getURL(), gSearch);
- } finally {
- uc.disconnect();
- }
+ // create Proxy
- SocketAddress addr2 = new InetSocketAddress("test.domain.org", 2130);
- Proxy proxy2 = new Proxy(Proxy.Type.HTTP, addr2);
- Socket sock2 = new Socket(proxy1);
+ System.setProperty("http.proxyHost",
+ Support_Configuration.ProxyServerTestHost);
+ System.setProperty("http.proxyPort", "80");
+
+ URL u2 = new URL("http://"
+ + Support_Configuration.ProxyServerTestHost
+ + "/cgi-bin/test.pl");
+
+ SocketAddress addr1 = new InetSocketAddress(Support_Configuration.ProxyServerTestHost, 80);
+ Proxy proxy1 = new Proxy(Proxy.Type.HTTP, addr1);
- try {
-
- Proxy proxyList[] = { proxy1, proxy2
- };
- for (int i = 0; i < proxyList.length; ++i) {
- String posted = "just a test";
- URL u = new URL("http://www.test.domain.org:2130");
- java.net.HttpURLConnection conn = (java.net.HttpURLConnection) u
- .openConnection(proxyList[i]);
- conn.setDoOutput(true);
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Content-length", String.valueOf(posted
- .length()));
-
- OutputStream out = conn.getOutputStream();
- out.write(posted.getBytes());
- out.close();
-
- conn.getResponseCode();
- InputStream is = conn.getInputStream();
- String response = "";
- byte[] b = new byte[1024];
- int count = 0;
- while ((count = is.read(b)) > 0) {
- response += new String(b, 0, count);
- }
- assertTrue("Response to POST method invalid", response
- .equals(posted));
- }
-
- URL httpUrl = new URL("http://abc.com");
- URL jarUrl = new URL("jar:"
- + Support_Resources.getResourceURL("/JUC/lf.jar!/plus.bmp"));
- URL ftpUrl = new URL("ftp://" + Support_Configuration.FTPTestAddress
- + "/nettest.txt");
- URL fileUrl = new URL("file://abc");
- URL[] urlList = { httpUrl, jarUrl, ftpUrl, fileUrl };
- for (int i = 0; i < urlList.length; ++i) {
- try {
- urlList[i].openConnection(null);
- } catch (IllegalArgumentException iae) {
- // expected
- }
- }
- // should not throw exception
- fileUrl.openConnection(Proxy.NO_PROXY);
- } finally {
- sock.close();
+ // create test input
+ String posted = "just a test";
+
+ // perform test
+ java.net.HttpURLConnection conn = (java.net.HttpURLConnection) u2
+ .openConnection(proxy1);
+ conn.setDoOutput(true);
+ conn.setRequestMethod("POST");
+ conn.setConnectTimeout(3000);
+
+ OutputStream out = conn.getOutputStream();
+ out.write(posted.getBytes());
+ out.close();
+
+
+ /*
+ InputStream in = conn.getErrorStream();
+ if (in != null ){
+ BufferedReader r = new BufferedReader(new InputStreamReader(in), 200);
+ String line;
+ while((line = r.readLine())!= null) {
+ System.err.println(line);
}
+ }
+ */
+
+ conn.getResponseCode();
+ InputStream is = conn.getInputStream();
+ String response = "";
+ byte[] b = new byte[1024];
+ int count = 0;
+ while ((count = is.read(b)) > 0) {
+ response += new String(b, 0, count);
+ }
+ assertTrue("Response to POST method invalid", response
+ .equals(posted));
+
+ // Exception test
+ URL httpUrl = new URL("http://abc.com");
+ URL jarUrl = new URL("jar:"
+ + Support_Resources.getResourceURL("/JUC/lf.jar!/plus.bmp"));
+ URL ftpUrl = new URL("ftp://" + Support_Configuration.FTPTestAddress
+ + "/nettest.txt");
+ URL fileUrl = new URL("file://abc");
+ URL[] urlList = { httpUrl, jarUrl, ftpUrl, fileUrl };
+ for (int i = 0; i < urlList.length; ++i) {
+ try {
+ urlList[i].openConnection(null);
+ } catch (IllegalArgumentException iae) {
+ // expected
+ }
+ }
+ // should not throw exception too
+ fileUrl.openConnection(Proxy.NO_PROXY);
+
}
/**
@@ -1036,21 +1064,30 @@
InputStream is;
String s;
- /* throws nullpointer exception: failed or not failed test? Debatable
+ // Cannot make this test fail if no exception is thrown: Debatable
+ /*
try {
u = new URL("http", "www.yahoo.com", 8080, "test.html#foo",
null);
fail("No error occurred");
} catch (MalformedURLException e) {
// ok
+ } catch (NullPointerException e) {
+ // ok
}
*/
TestURLStreamHandler lh = new TestURLStreamHandler();
+
+ u = new URL("http", "www.yahoo.com", 8080, "test.html#foo",
+ lh);
+
try {
new URL(null, "1", 0, "file", lh);
- fail("NullPointerException expected, but nothing was thrown!");
+ fail("Exception expected, but nothing was thrown!");
+ } catch (MalformedURLException e) {
+ // ok
} catch (NullPointerException e) {
// Expected NullPointerException
}
@@ -1066,37 +1103,42 @@
method = "getContent",
args = {java.lang.Class[].class}
)
- @BrokenTest("both RI and android fail on getcontent which returns null.")
public void test_getContent_LJavaLangClass() throws Exception {
-
+
File sampleFile = createTempHelloWorldFile();
-
+
byte[] ba;
String s;
+ InputStream is = null;
+
+ try {
+ u = new URL("file:///data/tmp/hyts_htmltest.html");
+ is = (InputStream) u.getContent(new Class[] {InputStream.class});
+ is.read(ba = new byte[4096]);
+ fail("No error occurred reading from nonexisting file");
+ } catch (IOException e) {
+ // ok
+ }
+
+ try {
+ u = new URL("file:///data/tmp/hyts_htmltest.html");
+ is = (InputStream) u.getContent(new Class[] {
+ String.class, InputStream.class});
+ is.read(ba = new byte[4096]);
+ fail("No error occurred reading from nonexisting file");
+ } catch (IOException e) {
+ // ok
+ }
+
+ // Check for null
u = sampleFile.toURL();
u.openConnection();
assertNotNull(u);
- s = (String) u.getContent(new Class[] { String.class });
- assertNotNull(s);
- assertTrue("Incorrect content " + u
- + " does not contain: \"Hello World\"",
- s.indexOf("Hello World") >= 0);
-
- //Exception test
- InputStream is = null;
-
- try {
- u = new URL("file:///data/tmp/hyts_htmltest.html");
-// u.openConnection();
- is = (InputStream) u.getContent(new Class[] { InputStream.class });
- is.read(ba = new byte[4096]);
- fail("No error occurred reading from nonexisting file");
- } catch (IOException e) {
- //ok
- }
-
+ s = (String) u.getContent(new Class[] {String.class});
+ assertNull(s);
+
}
/**
diff --git a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractMapTest.java b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractMapTest.java
index 8f2cd27..e5e3c11 100644
--- a/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractMapTest.java
+++ b/libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractMapTest.java
@@ -21,7 +21,6 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.KnownFailure;
import java.util.AbstractMap;
import java.util.AbstractSet;
@@ -405,7 +404,6 @@
method = "putAll",
args = {java.util.Map.class}
)
- @KnownFailure("ToT fixed")
public void test_putAllLMap() {
Hashtable ht = new Hashtable();
AbstractMap amt = new AMT();
@@ -431,7 +429,6 @@
method = "equals",
args = {java.lang.Object.class}
)
- @KnownFailure("ToT fixed")
public void test_equalsLjava_lang_Object() {
AbstractMap amt1 = new AMT();
AbstractMap amt2 = new AMT();
diff --git a/libcore/luni/src/test/java/tests/TestSuiteFactory.java b/libcore/luni/src/test/java/tests/TestSuiteFactory.java
index 15d0ea9..4f4a479 100644
--- a/libcore/luni/src/test/java/tests/TestSuiteFactory.java
+++ b/libcore/luni/src/test/java/tests/TestSuiteFactory.java
@@ -19,6 +19,7 @@
import dalvik.annotation.AndroidOnly;
import dalvik.annotation.KnownFailure;
+import junit.extensions.TestSetup;
import junit.framework.AssertionFailedError;
import junit.framework.Protectable;
import junit.framework.Test;
@@ -39,7 +40,7 @@
* a sample command line:
*
* /usr/lib/jvm/java-1.5.0-sun/bin/java -Xmx1024m -Dcts.listOnlyFailingTests=true
- * -Dcts.ignoreKnownFailure=false -Dcts.runOnDalvikVM=false
+ * -Dcts.includeKnownFailure=false -Dcts.runOnDalvikVM=false
* -Dcts.allowUnderscoreTests=false -Dcts.useEnhancedJunit=true
* -Dcts.collectOnly=false
* -cp
@@ -59,8 +60,9 @@
static boolean _useEnhancedJunit = false;
static boolean _allowUnderscoreTests = false;
static boolean _runOnDalvikVM = true;
- static boolean _ignoreKnowFailure = false;
+ static boolean _includeKnowFailure = false;
static boolean _listOnlyFailingTests = false;
+ static boolean _useSuppliedTestResult = false;
static int _maxRunningTimePerTest = 15000; // 15 seconds
static {
@@ -69,16 +71,17 @@
_collectOnly = System.getProperty("cts.collectOnly", "false").equals("true");
_allowUnderscoreTests= System.getProperty("cts.allowUnderscoreTests", "false").equals("true");
_runOnDalvikVM = System.getProperty("cts.runOnDalvikVM", "true").equals("true");
- _ignoreKnowFailure = System.getProperty("cts.ignoreKnownFailure", "false").equals("true");
+ _includeKnowFailure = System.getProperty("cts.includeKnownFailure", "false").equals("true");
_maxRunningTimePerTest = Integer.parseInt(System.getProperty("cts.maxRunningTimePerTest", "15000"));
_listOnlyFailingTests = System.getProperty("cts.listOnlyFailingTests", "false").equals("true");
+ _useSuppliedTestResult = System.getProperty("cts.useSuppliedTestResult", "false").equals("true");
System.out.println("TestSuiteFactory: v0.97");
System.out.println("TestSuiteFactory: using cts.useEnhancedJunit: "+_useEnhancedJunit);
System.out.println("TestSuiteFactory: using cts.collectOnly: "+_collectOnly);
System.out.println("TestSuiteFactory: max allowed running time per test (using Thread.stop()) (cts.maxRunningTimePerTest): "+_maxRunningTimePerTest);
System.out.println("TestSuiteFactory: run tests on a dalvik vm (cts.runOnDalvikVM): "+_runOnDalvikVM);
- System.out.println("TestSuiteFactory: ignore @KnowFailure when running on dalvik vm (cts.ignoreKnownFailure): "+_ignoreKnowFailure);
+ System.out.println("TestSuiteFactory: include @KnowFailure when running on dalvik vm (cts.includeKnownFailure): "+_includeKnowFailure);
System.out.println("TestSuiteFactory: include '_test...' methods in test run (cts.allowUnderscoreTests): "+_allowUnderscoreTests);
System.out.println("TestSuiteFactory: list only failing tests (cts.listOnlyFailingTests): "+_listOnlyFailingTests);
System.out.println();
@@ -175,7 +178,15 @@
private static int testCnt = 0;
public void runTest(Test test, final TestResult dummy_result) {
- TestResult aresult = new TestResult();
+
+ if (TestSuiteFactory._useSuppliedTestResult) {
+ if (test instanceof TestSetup) {
+ test = ((TestSetup)test).getTest();
+ }
+ test.run(dummy_result);
+ return;
+ }
+
TestResult eresult = new TestResult() {
private String msg;
private boolean error = false;
@@ -195,7 +206,7 @@
// @AndroidOnly("Because...") if the test is Android-specific, succeeds on Android but fails on the JDK.
try {
Annotation[] annosClass = testcase.getClass().getDeclaredAnnotations();
- Method runMethod= testcase.getClass().getMethod(testcase.getName(), (Class[]) null);
+ Method runMethod= testcase.getClass().getMethod(testcase.getName());
Annotation[] annosMethod = runMethod.getDeclaredAnnotations();
Annotation[] annos = null;
for (int i = 0; i < 2; i++) {
@@ -223,7 +234,7 @@
!TestSuiteFactory._collectOnly
&& (
(TestSuiteFactory._runOnDalvikVM &&
- (TestSuiteFactory._ignoreKnowFailure || !knownFailure)
+ (TestSuiteFactory._includeKnowFailure || !knownFailure)
)
||
(!TestSuiteFactory._runOnDalvikVM && !androidOnly)
@@ -293,7 +304,7 @@
if (!TestSuiteFactory._runOnDalvikVM && androidOnly) {
msg+= "ignoring on RI since @AndroidOnly: "+((AndroidOnly)aAndroidOnly).value();
}
- if (TestSuiteFactory._runOnDalvikVM && knownFailure && !TestSuiteFactory._ignoreKnowFailure) {
+ if (TestSuiteFactory._runOnDalvikVM && knownFailure && !TestSuiteFactory._includeKnowFailure) {
msg += "ignoring on dalvik since @KnownFailure: "+((KnownFailure)aKnownFailure).value();
}
}
diff --git a/libcore/luni/src/test/java/tests/api/java/io/AllTests.java b/libcore/luni/src/test/java/tests/api/java/io/AllTests.java
index 295d4d8..2747ab2 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/AllTests.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/AllTests.java
@@ -90,13 +90,11 @@
suite.addTestSuite(RandomAccessFileTest.class);
suite.addTestSuite(SequenceInputStreamTest.class);
suite.addTestSuite(SerializablePermissionTest.class);
- suite.addTestSuite(SerializationStressTest.class);
+ suite.addTestSuite(SerializationStressTest0.class);
suite.addTestSuite(SerializationStressTest1.class);
suite.addTestSuite(SerializationStressTest2.class);
suite.addTestSuite(SerializationStressTest3.class);
suite.addTestSuite(SerializationStressTest4.class);
- suite.addTestSuite(SerializationStressTest4.class);
- suite.addTestSuite(SerializationStressTest5.class);
suite.addTestSuite(StreamCorruptedExceptionTest.class);
suite.addTestSuite(StreamTokenizerTest.class);
suite.addTestSuite(StringBufferInputStreamTest.class);
diff --git a/libcore/luni/src/test/java/tests/api/java/io/BufferedInputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/BufferedInputStreamTest.java
index 6e2076c..d5ab18e 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/BufferedInputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/BufferedInputStreamTest.java
@@ -400,21 +400,21 @@
bis.read(new byte[0], -1, -1);
fail("should throw IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException e) {
- //expected
+ // Expected
}
try {
bis.read(new byte[0], 1, -1);
fail("should throw IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException e) {
- //expected
+ // Expected
}
try {
bis.read(new byte[0], 1, 1);
fail("should throw IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException e) {
- //expected
+ // Expected
}
bis.close();
diff --git a/libcore/luni/src/test/java/tests/api/java/io/BufferedOutputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/BufferedOutputStreamTest.java
index fb09643..3b727a5 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/BufferedOutputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/BufferedOutputStreamTest.java
@@ -165,7 +165,7 @@
method = "write",
args = {byte[].class, int.class, int.class}
)
- public void test_write_$BII_Exception() throws IOException {
+ public void test_write$BII_Exception() throws IOException {
OutputStream bos = new BufferedOutputStream(new ByteArrayOutputStream());
byte[] nullByteArray = null;
byte[] byteArray = new byte[10];
@@ -179,23 +179,23 @@
try {
bos.write(byteArray, -1, 1);
- fail("Test 2: ArrayIndexOutOfBoundsException expected.");
- } catch (ArrayIndexOutOfBoundsException e) {
- // Expected.
+ fail("Test 2: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
try {
bos.write(byteArray, 0, -1);
- fail("Test 3: ArrayIndexOutOfBoundsException expected.");
- } catch (ArrayIndexOutOfBoundsException e) {
- // Expected.
+ fail("Test 3: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
try {
bos.write(byteArray, 1, 10);
- fail("Test 4: ArrayIndexOutOfBoundsException expected.");
- } catch (ArrayIndexOutOfBoundsException e) {
- // Expected.
+ fail("Test 4: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
}
diff --git a/libcore/luni/src/test/java/tests/api/java/io/BufferedReaderTest.java b/libcore/luni/src/test/java/tests/api/java/io/BufferedReaderTest.java
index 50bb44e..b1a5755 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/BufferedReaderTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/BufferedReaderTest.java
@@ -326,6 +326,39 @@
} catch (IOException e) {
fail("Unexpected: " + e);
}
+ }
+
+ /**
+ * @tests java.io.BufferedReader#read(char[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "The test verifies read(char[] cbuf, int off, int len) method.",
+ method = "read",
+ args = {char[].class, int.class, int.class}
+ )
+ public void test_read$CII_Exception() throws Exception {
+ br = new BufferedReader(new Support_StringReader(testString));
+ try{
+ br.read(new char[10], -1, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try{
+ br.read(new char[10], 0, -1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try{
+ br.read(new char[10], 10, 1);
+ fail("should throw IndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
//regression for HARMONY-831
try{
diff --git a/libcore/luni/src/test/java/tests/api/java/io/BufferedWriterTest.java b/libcore/luni/src/test/java/tests/api/java/io/BufferedWriterTest.java
index 4c58318..d8ea5a8 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/BufferedWriterTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/BufferedWriterTest.java
@@ -219,42 +219,42 @@
bw.write(charArray, -1, 0);
fail("Test 2: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
try {
bw.write(charArray, 0, -1);
fail("Test 3: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
try {
bw.write(charArray, charArray.length + 1, 0);
fail("Test 4: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
try {
bw.write(charArray, charArray.length, 1);
fail("Test 5: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
try {
bw.write(charArray, 0, charArray.length + 1);
fail("Test 6: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
try {
bw.write(charArray, 1, charArray.length);
fail("Test 7: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
bw.close();
diff --git a/libcore/luni/src/test/java/tests/api/java/io/ByteArrayInputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/ByteArrayInputStreamTest.java
index a9a20d5..eaf4c48 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/ByteArrayInputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/ByteArrayInputStreamTest.java
@@ -19,6 +19,7 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.InputStream;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -233,21 +234,21 @@
is.read(buf1 , -1, 1);
fail("Test 3: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
try {
is.read(buf1 , 1, -1);
fail("Test 4: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
try {
is.read(buf1, 1, buf1.length);
fail("Test 5: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
}
diff --git a/libcore/luni/src/test/java/tests/api/java/io/ByteArrayOutputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/ByteArrayOutputStreamTest.java
index 2848a50..b2a4e21 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/ByteArrayOutputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/ByteArrayOutputStreamTest.java
@@ -276,31 +276,25 @@
try {
bos.write(target, -1, 1);
fail("Test 1: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
- assertEquals(
- "IndexOutOfBoundsException rather than a subclass expected;",
- IndexOutOfBoundsException.class, t.getClass());
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
try {
bos.write(target, 0, -1);
fail("Test 2: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
- assertEquals(
- "IndexOutOfBoundsException rather than a subclass expected;",
- IndexOutOfBoundsException.class, t.getClass());
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
try {
bos.write(target, 1, target.length);
fail("Test 3: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
- assertEquals(
- "IndexOutOfBoundsException rather than a subclass expected;",
- IndexOutOfBoundsException.class, t.getClass());
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
try {
bos.write(null, 1, 1);
fail("Test 4: NullPointerException expected.");
- } catch (NullPointerException t) {
+ } catch (NullPointerException e) {
// Expected.
}
}
diff --git a/libcore/luni/src/test/java/tests/api/java/io/CharArrayReaderTest.java b/libcore/luni/src/test/java/tests/api/java/io/CharArrayReaderTest.java
index 114e32a..e94f74b 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/CharArrayReaderTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/CharArrayReaderTest.java
@@ -211,21 +211,21 @@
cr.read(c , -1, 1);
fail("Test 3: ArrayIndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
try {
cr.read(c , 1, -1);
fail("Test 4: ArrayIndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
try {
cr.read(c, 1, c.length);
fail("Test 5: ArrayIndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
- // Expected.
+ // Expected
}
cr.close();
diff --git a/libcore/luni/src/test/java/tests/api/java/io/CharArrayWriterTest.java b/libcore/luni/src/test/java/tests/api/java/io/CharArrayWriterTest.java
index a398303..5c7d355 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/CharArrayWriterTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/CharArrayWriterTest.java
@@ -219,28 +219,25 @@
try {
cw.write(target, -1, 1);
fail("Test 1: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
- assertEquals("IndexOutOfBoundsException rather than a subclass expected;",
- IndexOutOfBoundsException.class, t.getClass());
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
try {
cw.write(target, 0, -1);
fail("Test 2: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
- assertEquals("IndexOutOfBoundsException rather than a subclass expected;",
- IndexOutOfBoundsException.class, t.getClass());
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
try {
cw.write(target, 1, target.length);
fail("Test 3: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
- assertEquals("IndexOutOfBoundsException rather than a subclass expected;",
- IndexOutOfBoundsException.class, t.getClass());
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
try {
cw.write((char[]) null, 1, 1);
fail("Test 4: NullPointerException expected.");
- } catch (NullPointerException t) {
+ } catch (NullPointerException e) {
// Expected.
}
}
diff --git a/libcore/luni/src/test/java/tests/api/java/io/DataInputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/DataInputStreamTest.java
index cda04a7..cde968a 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/DataInputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/DataInputStreamTest.java
@@ -112,7 +112,7 @@
* @tests java.io.DataInputStream#read(byte[], int, int)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.PARTIAL_COMPLETE,
method = "read",
args = {byte[].class, int.class, int.class}
)
@@ -149,6 +149,43 @@
}
/**
+ * @tests java.io.DataInputStream#read(byte[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "read",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void test_read$BII_Exception() throws IOException {
+ byte rbytes[] = new byte[testLength - 5];
+
+ os.write(fileString.getBytes());
+ os.close();
+ openDataInputStream();
+
+ try {
+ dis.read(rbytes, -1, 1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ dis.read(rbytes, 0, -1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ dis.read(rbytes, rbytes.length, 1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
* @tests java.io.DataInputStream#readFully(byte[])
*/
@TestTargetNew(
diff --git a/libcore/luni/src/test/java/tests/api/java/io/FileOutputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/FileOutputStreamTest.java
index f2773ae..eb14a3c 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/FileOutputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/FileOutputStreamTest.java
@@ -344,27 +344,37 @@
try {
fos.write(new byte[1], -1, 0);
fail("Test 2: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException e) {}
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
try {
fos.write(new byte[1], 0, -1);
fail("Test 3: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException e) {}
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
try {
fos.write(new byte[1], 0, 5);
fail("Test 4: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException e) {}
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
try {
fos.write(new byte[10], Integer.MAX_VALUE, 5);
fail("Test 5: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException e) {}
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
try {
fos.write(new byte[10], 5, Integer.MAX_VALUE);
fail("Test 6: IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException e) {}
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
fos.close();
try {
diff --git a/libcore/luni/src/test/java/tests/api/java/io/FileTest.java b/libcore/luni/src/test/java/tests/api/java/io/FileTest.java
index 817249a..85c4bc4 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/FileTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/FileTest.java
@@ -1097,8 +1097,9 @@
args = {}
)
public void test_getPath() {
- System.setProperty("user.home", System.getProperty("java.io.tmpdir"));
- String base = System.getProperty("user.home");
+ String oldUserDir = System.getProperty("java.io.tmpdir");
+ System.setProperty("user.dir", System.getProperty("java.io.tmpdir"));
+ String base = System.getProperty("user.dir");
String fname;
File f1;
if (!base.regionMatches((base.length() - 1), slash, 0, 1))
@@ -1122,6 +1123,7 @@
f2.delete();
f3.delete();
f4.delete();
+ System.setProperty("user.dir", oldUserDir);
}
/**
@@ -2099,27 +2101,27 @@
f1.createNewFile();
long orgTime = f1.lastModified();
// Subtracting 100 000 milliseconds from the orgTime of File f1
- f1.setLastModified(orgTime - 100000);
+ assertTrue(f1.setLastModified(orgTime - 100000));
long lastModified = f1.lastModified();
assertTrue("Test 1: LastModifed time incorrect: " + lastModified,
lastModified == (orgTime - 100000));
// Subtracting 10 000 000 milliseconds from the orgTime of File f1
- f1.setLastModified(orgTime - 10000000);
+ assertTrue(f1.setLastModified(orgTime - 10000000));
lastModified = f1.lastModified();
assertTrue("Test 2: LastModifed time incorrect: " + lastModified,
lastModified == (orgTime - 10000000));
// Adding 100 000 milliseconds to the orgTime of File f1
- f1.setLastModified(orgTime + 100000);
+ assertTrue(f1.setLastModified(orgTime + 100000));
lastModified = f1.lastModified();
assertTrue("Test 3: LastModifed time incorrect: " + lastModified,
lastModified == (orgTime + 100000));
// Adding 10 000 000 milliseconds from the orgTime of File f1
- f1.setLastModified(orgTime + 10000000);
+ assertTrue(f1.setLastModified(orgTime + 10000000));
lastModified = f1.lastModified();
assertTrue("Test 4: LastModifed time incorrect: " + lastModified,
lastModified == (orgTime + 10000000));
// Trying to set time to an exact number
- f1.setLastModified(315550800000L);
+ assertTrue(f1.setLastModified(315550800000L));
lastModified = f1.lastModified();
assertTrue("Test 5: LastModified time incorrect: " + lastModified,
lastModified == 315550800000L);
@@ -2139,6 +2141,9 @@
fail("IllegalArgumentException not thrown.");
} catch (IllegalArgumentException e) {
}
+
+ File f2 = new File("/does not exist.txt");
+ assertFalse(f2.setLastModified(42));
} catch (IOException e) {
fail("Unexpected IOException during test : " + e.getMessage());
} finally {
@@ -2338,7 +2343,7 @@
)
public void test_toURI2() {
- File f = new File(System.getProperty("ctsdir"), "a/b/c/../d/e/./f");
+ File f = new File(System.getProperty("java.io.tmpdir"), "a/b/c/../d/e/./f");
String path = f.getAbsolutePath();
path = path.replace(File.separatorChar, '/');
diff --git a/libcore/luni/src/test/java/tests/api/java/io/FilterOutputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/FilterOutputStreamTest.java
index 8062ac0..ab0bebc 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/FilterOutputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/FilterOutputStreamTest.java
@@ -188,6 +188,41 @@
}
/**
+ * @tests java.io.FilterOutputStream#write(byte[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "write",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void test_write$BII_Exception() throws IOException {
+ Support_OutputStream sos = new Support_OutputStream(testLength);
+ os = new FilterOutputStream(sos);
+ byte[] buf = new byte[10];
+
+ try {
+ os.write(buf, -1, 1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ try {
+ os.write(buf, 0, -1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ try {
+ os.write(buf, 10, 1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+ }
+
+ /**
* @tests java.io.FilterOutputStream#write(int)
*/
@TestTargetNew(
diff --git a/libcore/luni/src/test/java/tests/api/java/io/FilterReaderTest.java b/libcore/luni/src/test/java/tests/api/java/io/FilterReaderTest.java
index 3a58e74..14313d0 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/FilterReaderTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/FilterReaderTest.java
@@ -17,8 +17,10 @@
package tests.api.java.io;
+import java.io.ByteArrayInputStream;
import java.io.FilterReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -161,7 +163,7 @@
* @tests java.io.FilterReader#read(char[], int, int)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Verifies read(char[], int, int).",
method = "read",
args = {char[].class, int.class, int.class}
@@ -173,6 +175,44 @@
}
/**
+ * @tests java.io.FilterReader#read(char[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies read(char[], int, int).",
+ method = "read",
+ args = {char[].class, int.class, int.class}
+ )
+ public void test_read$CII_Exception() throws IOException {
+ byte[] bbuffer = new byte[20];
+ char[] buffer = new char[10];
+
+ fr = new MyFilterReader(new InputStreamReader(
+ new ByteArrayInputStream(bbuffer)));
+
+ try {
+ fr.read(buffer, 0, -1);
+ fail("Test 1: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ try {
+ fr.read(buffer, -1, 1);
+ fail("Test 2: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ try {
+ fr.read(buffer, 10, 1);
+ fail("Test 3: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+ }
+
+ /**
* @tests java.io.FilterReader#ready()
*/
@TestTargetNew(
diff --git a/libcore/luni/src/test/java/tests/api/java/io/FilterWriterTest.java b/libcore/luni/src/test/java/tests/api/java/io/FilterWriterTest.java
index 37d6991..6fcb57d 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/FilterWriterTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/FilterWriterTest.java
@@ -17,8 +17,14 @@
package tests.api.java.io;
+import tests.api.java.io.FilterReaderTest.MyFilterReader;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.FilterWriter;
import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -147,6 +153,43 @@
}
/**
+ * @tests java.io.FilterReader#read(char[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies write(char[], int, int).",
+ method = "write",
+ args = {char[].class, int.class, int.class}
+ )
+ public void test_write$CII_Exception() throws IOException {
+ char[] buffer = new char[10];
+
+ fw = new MyFilterWriter(new OutputStreamWriter(
+ new ByteArrayOutputStream()));
+
+ try {
+ fw.write(buffer, 0, -1);
+ fail("Test 1: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ try {
+ fw.write(buffer, -1, 1);
+ fail("Test 2: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ try {
+ fw.write(buffer, 10, 1);
+ fail("Test 3: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+ }
+
+ /**
* @tests java.io.FilterWriter#write(char[], int, int)
*/
@TestTargetNew(
diff --git a/libcore/luni/src/test/java/tests/api/java/io/InputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/InputStreamTest.java
index 40fbc88..0a87df4 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/InputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/InputStreamTest.java
@@ -200,23 +200,23 @@
method = "read",
args = {byte[].class, int.class, int.class}
)
- public void test_read$BII_IllegalArgument() throws IOException {
+ public void test_read$BII_Exception() throws IOException {
byte[] b = new byte[10];
int bytesRead = 0;
// Test 1: Invalid offset.
try {
bytesRead = is.read(b, -1, 5);
- fail("Test 1: ArrayIndexOutOfBoundsException expected.");
- } catch (ArrayIndexOutOfBoundsException e) {
+ fail("Test 1: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
// expected
}
// Test 2: Invalid length.
try {
bytesRead = is.read(b, 5, -1);
- fail("Test 2: ArrayIndexOutOfBoundsException expected.");
- } catch (ArrayIndexOutOfBoundsException e) {
+ fail("Test 2: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
// expected
}
@@ -224,16 +224,16 @@
// than the length of b).
try {
bytesRead = is.read(b, 6, 5);
- fail("Test 3: ArrayIndexOutOfBoundsException expected.");
- } catch (ArrayIndexOutOfBoundsException e) {
+ fail("Test 3: IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
// expected
}
// Test 4: Border case.
try {
bytesRead = is.read(b, 6, 4);
- } catch (ArrayIndexOutOfBoundsException e) {
- fail("Test 4: Unexpected ArrayIndexOutOfBoundsException.");
+ } catch (IndexOutOfBoundsException e) {
+ fail("Test 4: Unexpected IndexOutOfBoundsException.");
}
assertEquals("Test 4:", bytesRead, 4);
diff --git a/libcore/luni/src/test/java/tests/api/java/io/LineNumberInputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/LineNumberInputStreamTest.java
index d95dd74..491def9 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/LineNumberInputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/LineNumberInputStreamTest.java
@@ -152,7 +152,7 @@
* @tests java.io.LineNumberInputStream#read(byte[], int, int)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.PARTIAL_COMPLETE,
method = "read",
args = {byte[].class, int.class, int.class}
)
@@ -172,6 +172,39 @@
}
/**
+ * @tests java.io.LineNumberInputStream#read(byte[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "read",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void test_read$BII_Exception() throws IOException {
+ byte[] buf = new byte[10];
+
+ try {
+ lnis.read(buf, -1, 1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ try {
+ lnis.read(buf, 0, -1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ try {
+ lnis.read(buf, 10, 1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+ }
+
+ /**
* @tests java.io.LineNumberInputStream#reset()
*/
@TestTargetNew(
diff --git a/libcore/luni/src/test/java/tests/api/java/io/LineNumberReaderTest.java b/libcore/luni/src/test/java/tests/api/java/io/LineNumberReaderTest.java
index ace864e..3e1ca4a 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/LineNumberReaderTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/LineNumberReaderTest.java
@@ -146,7 +146,7 @@
* @tests java.io.LineNumberReader#read(char[], int, int)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.PARTIAL_COMPLETE,
method = "read",
args = {char[].class, int.class, int.class}
)
@@ -169,6 +169,40 @@
}
/**
+ * @tests java.io.LineNumberReader#read(char[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "read",
+ args = {char[].class, int.class, int.class}
+ )
+ public void test_read$CII_Exception() throws IOException {
+ lnr = new LineNumberReader(new StringReader(text));
+ char[] c = new char[10];
+
+ try {
+ lnr.read(c, -1, 1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ try {
+ lnr.read(c, 0, -1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+
+ try {
+ lnr.read(c, 10, 1);
+ fail("IndexOutOfBoundsException expected.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected.
+ }
+ }
+
+ /**
* @tests java.io.LineNumberReader#readLine()
*/
@TestTargetNew(
diff --git a/libcore/luni/src/test/java/tests/api/java/io/ObjectInputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/ObjectInputStreamTest.java
index d091158..2258507 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/ObjectInputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/ObjectInputStreamTest.java
@@ -350,14 +350,36 @@
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
- notes = "Checks IOException.",
+ notes = "Checks Exceptions.",
method = "read",
args = {byte[].class, int.class, int.class}
)
- public void test_read$BII_IOException() throws IOException {
+ public void test_read$BII_Exception() throws IOException {
byte[] buf = new byte[testLength];
oos.writeObject(testString);
oos.close();
+
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ try {
+ ois.read(buf, 0, -1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ ois.read(buf, -1,1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ ois.read(buf, testLength, 1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ ois.close();
+
Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
ois = new ObjectInputStream(sis);
@@ -450,7 +472,7 @@
method = "readFully",
args = {byte[].class}
)
- public void test_readFully$B_IOException() throws IOException {
+ public void test_readFully$B_Exception() throws IOException {
byte[] buf = new byte[testLength];
oos.writeObject(testString);
oos.close();
@@ -502,14 +524,35 @@
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
- notes = "Checks IOException.",
+ notes = "Checks Exceptions.",
method = "readFully",
args = {byte[].class, int.class, int.class}
)
- public void test_readFully$BII_IOException() throws IOException {
+ public void test_readFully$BII_Exception() throws IOException {
byte[] buf = new byte[testLength];
oos.writeObject(testString);
oos.close();
+
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ try {
+ ois.readFully(buf, 0, -1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ ois.readFully(buf, -1,1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ ois.readFully(buf, testLength, 1);
+ fail("IndexOutOfBoundsException was not thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ ois.close();
Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
ois = new ObjectInputStream(sis);
diff --git a/libcore/luni/src/test/java/tests/api/java/io/ObjectOutputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/ObjectOutputStreamTest.java
index 51ac740..e8042ca 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/ObjectOutputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/ObjectOutputStreamTest.java
@@ -1032,6 +1032,28 @@
ois.close();
assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
10));
+
+ ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+ try {
+ ois.read(buf, 0, -1);
+ fail("IndexOutOfBoundsException not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ ois.read(buf, -1, 1);
+ fail("IndexOutOfBoundsException not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ ois.read(buf, 10, 1);
+ fail("IndexOutOfBoundsException not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ ois.close();
+
}
/**
diff --git a/libcore/luni/src/test/java/tests/api/java/io/PipedInputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/PipedInputStreamTest.java
index 89f6bef..1f35f97 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/PipedInputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/PipedInputStreamTest.java
@@ -20,6 +20,7 @@
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -383,31 +384,25 @@
public void test_read$BII_3() throws IOException {
PipedInputStream obj = new PipedInputStream();
try {
- obj.read(new byte[0], -1, 0);
+ obj.read(new byte[10], -1, 1);
fail("IndexOutOfBoundsException expected.");
- } catch (ArrayIndexOutOfBoundsException t) {
- fail("IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertTrue(e.getClass().equals(IndexOutOfBoundsException.class));
}
- }
-
- /**
- * @tests java.io.PipedInputStream#read(byte[], int, int)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Tests invalid combination of offset and length arguments.",
- method = "read",
- args = {byte[].class, int.class, int.class}
- )
- public void test_read$BII_4() throws IOException {
- PipedInputStream obj = new PipedInputStream();
try {
- obj.read(new byte[10], 2, 9);
+ obj.read(new byte[10], 0, -1);
fail("IndexOutOfBoundsException expected.");
- } catch (ArrayIndexOutOfBoundsException t) {
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertTrue(e.getClass().equals(IndexOutOfBoundsException.class));
+ }
+ try {
+ obj.read(new byte[10], 9, 2);
fail("IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ assertTrue(e.getClass().equals(IndexOutOfBoundsException.class));
}
}
@@ -420,6 +415,7 @@
method = "receive",
args = {int.class}
)
+ @BrokenTest("Test hangs indefinitely on the RI")
public void test_receive() throws IOException {
pis = new PipedInputStream();
pos = new PipedOutputStream();
diff --git a/libcore/luni/src/test/java/tests/api/java/io/PipedOutputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/PipedOutputStreamTest.java
index 19c1f95..44d7e27 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/PipedOutputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/PipedOutputStreamTest.java
@@ -259,6 +259,7 @@
}
out.close();
+ out = new PipedOutputStream();
try {
rt = new Thread(reader = new PReader(out));
rt.start();
@@ -270,16 +271,6 @@
fail("Test 5: Unexpected IOException: " + e.getMessage());
}
-/* Test disabled due to incomplete implementation, see ticket #92.
- rt.interrupt();
-
- try {
- out.write(testString.getBytes(), 0, 5);
- fail("Test 6: IOException expected.");
- } catch (IOException e) {
- // Expected.
- }
-*/
reader.getReader().close();
try {
out.write(testString.getBytes(), 0, 5);
diff --git a/libcore/luni/src/test/java/tests/api/java/io/PipedReaderTest.java b/libcore/luni/src/test/java/tests/api/java/io/PipedReaderTest.java
index f1d8ea8..f67790b 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/PipedReaderTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/PipedReaderTest.java
@@ -298,81 +298,28 @@
method = "read",
args = {char[].class, int.class, int.class}
)
- public void test_read$CII_2() throws IOException{
+ public void test_read$CII_Exception() throws IOException{
PipedWriter pw = new PipedWriter();
- PipedReader obj = null;
+ PipedReader obj = new PipedReader(pw);
try {
- obj = new PipedReader(pw);
- obj.read(new char[0], 0, -1);
+ obj.read(new char[10], 0, -1);
fail("IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
+ } catch (IndexOutOfBoundsException e) {
// Expected.
- assertEquals(
- "IndexOutOfBoundsException rather than a subclass expected.",
- IndexOutOfBoundsException.class, t.getClass());
}
- }
-
- /**
- * @tests java.io.PipedReader#read(char[], int, int)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
- method = "read",
- args = {char[].class, int.class, int.class}
- )
- public void test_read$CII_3() throws IOException {
- PipedWriter pw = new PipedWriter();
- PipedReader obj = null;
try {
- obj = new PipedReader(pw);
- obj.read(new char[0], -1, 0);
+ obj.read(new char[10], -1, 1);
fail("IndexOutOfBoundsException expected.");
- } catch (ArrayIndexOutOfBoundsException t) {
- fail("IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
+ } catch (IndexOutOfBoundsException e) {
// Expected.
- }
- }
-
- /**
- * @tests java.io.PipedReader#read(char[], int, int)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
- method = "read",
- args = {char[].class, int.class, int.class}
- )
- public void test_read$CII_4() throws IOException {
- PipedWriter pw = new PipedWriter();
- PipedReader obj = null;
+ }
try {
- obj = new PipedReader(pw);
obj.read(new char[10], 2, 9);
fail("IndexOutOfBoundsException expected.");
- } catch (ArrayIndexOutOfBoundsException t) {
- fail("IndexOutOfBoundsException expected.");
- } catch (IndexOutOfBoundsException t) {
+ } catch (IndexOutOfBoundsException e) {
// Expected.
}
- }
-
- /**
- * @tests java.io.PipedReader#read(char[], int, int)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
- method = "read",
- args = {char[].class, int.class, int.class}
- )
- public void test_read$CII_5() throws IOException{
- PipedWriter pw = new PipedWriter();
- PipedReader obj = null;
try {
- obj = new PipedReader(pw);
obj.read(null, 0, 1);
fail("NullPointerException expected.");
} catch (NullPointerException e) {
@@ -389,7 +336,7 @@
method = "read",
args = {}
)
- public void test_read$CII_6() throws Exception {
+ public void test_read$CII_2() throws Exception {
Thread writerThread;
PipedWriter pw;
PWriter2 pwriter;
diff --git a/libcore/luni/src/test/java/tests/api/java/io/PipedWriterTest.java b/libcore/luni/src/test/java/tests/api/java/io/PipedWriterTest.java
index c51c353..263d9b2 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/PipedWriterTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/PipedWriterTest.java
@@ -17,6 +17,7 @@
package tests.api.java.io;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -256,13 +257,10 @@
pw = new PipedWriter(new PipedReader());
try {
- pw.write(testBuf, -1, 10);
+ pw.write(testBuf, -1, 1);
fail("Test 2: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
// Expected.
- assertEquals(
- "Test 2: IndexOutOfBoundsException rather than a subclass expected.",
- IndexOutOfBoundsException.class, e.getClass());
}
try {
@@ -270,9 +268,6 @@
fail("Test 3: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
// Expected.
- assertEquals(
- "Test 3: IndexOutOfBoundsException rather than a subclass expected.",
- IndexOutOfBoundsException.class, e.getClass());
}
try {
@@ -280,9 +275,6 @@
fail("Test 4: IndexOutOfBoundsException expected.");
} catch (IndexOutOfBoundsException e) {
// Expected.
- assertEquals(
- "Test 4: IndexOutOfBoundsException rather than a subclass expected.",
- IndexOutOfBoundsException.class, e.getClass());
}
pw.close();
@@ -326,6 +318,7 @@
method = "write",
args = {char[].class, int.class, int.class}
)
+ @BrokenTest("Hangs on RI")
public void test_write$CII_MultiThread() throws Exception {
final PipedReader pr = new PipedReader();
final PipedWriter pw = new PipedWriter();
@@ -429,6 +422,7 @@
method = "write",
args = {int.class}
)
+ @BrokenTest("Hangs on RI")
public void test_writeI_MultiThread() throws IOException {
final PipedReader pr = new PipedReader();
final PipedWriter pw = new PipedWriter();
diff --git a/libcore/luni/src/test/java/tests/api/java/io/PrintStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
index db0e142..ccc0bc1 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
@@ -815,6 +815,27 @@
bis.read(rbytes, 0, fileString.length());
assertTrue("Incorrect bytes written", new String(rbytes, 0, fileString
.length()).equals(fileString));
+
+ try {
+ os.write(rbytes, -1, 1);
+ fail("IndexOutOfBoundsException should have been thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ os.write(rbytes, 0, -1);
+ fail("IndexOutOfBoundsException should have been thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+
+ try {
+ os.write(rbytes, 1, rbytes.length);
+ fail("IndexOutOfBoundsException should have been thrown.");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
}
/**
diff --git a/libcore/luni/src/test/java/tests/api/java/io/PrintWriterTest.java b/libcore/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
index 9957f0b..2796e7b 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
@@ -843,7 +843,7 @@
* @tests java.io.PrintWriter#write(char[], int, int)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "write",
args = {char[].class, int.class, int.class}
@@ -867,6 +867,38 @@
}
/**
+ * @tests java.io.PrintWriter#write(char[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "write",
+ args = {char[].class, int.class, int.class}
+ )
+ public void test_write$CII_Exception() {
+ // Test for method void java.io.PrintWriter.write(char [], int, int)
+ char[] chars = new char[10];
+ try {
+ pw.write(chars, 0, -1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ pw.write(chars, -1, 1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ pw.write(chars, 10, 1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
* @tests java.io.PrintWriter#write(int)
*/
@TestTargetNew(
diff --git a/libcore/luni/src/test/java/tests/api/java/io/PushbackInputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/PushbackInputStreamTest.java
index 267fbaa..8625664 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/PushbackInputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/PushbackInputStreamTest.java
@@ -181,7 +181,7 @@
* @tests java.io.PushbackInputStream#read(byte[], int, int)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "read",
args = {byte[].class, int.class, int.class}
@@ -204,6 +204,40 @@
}
/**
+ * @tests java.io.PushbackInputStream#read(byte[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "read",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void test_read$BII_Exception() throws IOException {
+ PushbackInputStream tobj;
+ byte[] buf = new byte[10];
+
+ tobj = new PushbackInputStream(underlying);
+ try {
+ tobj.read(buf, -1, 1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ tobj.read(buf, 0, -1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ tobj.read(buf, 10, 1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
* @tests java.io.PushbackInputStream#skip(long)
*/
@TestTargetNew(
@@ -344,6 +378,30 @@
} catch (IOException e) {
fail("IOException during unread test : " + e.getMessage());
}
+
+ try {
+ byte[] buf = new byte[10];
+ pis.unread(buf, 0, -1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ byte[] buf = new byte[10];
+ pis.unread(buf, -1, 1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ try {
+ byte[] buf = new byte[10];
+ pis.unread(buf, 10, 1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
}
/**
diff --git a/libcore/luni/src/test/java/tests/api/java/io/PushbackReaderTest.java b/libcore/luni/src/test/java/tests/api/java/io/PushbackReaderTest.java
index 5c13663..12ffce7 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/PushbackReaderTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/PushbackReaderTest.java
@@ -593,11 +593,23 @@
public void test_unread_$CII_ArrayIndexOutOfBoundsException() throws IOException {
//a pushback reader with one character buffer
pbr = new PushbackReader(new StringReader(pbString));
-
+
try {
- pbr.unread(new char[pbString.length()], -1 , -1);
+ pbr.unread(new char[pbString.length()], -1 , 1);
fail("should throw ArrayIndexOutOfBoundsException");
- } catch (ArrayIndexOutOfBoundsException e) {
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ pbr.unread(new char[pbString.length()], 0 , -1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ pbr.unread(new char[10], 10 , 1);
+ fail("should throw ArrayIndexOutOfBoundsException");
+ } catch (IndexOutOfBoundsException e) {
// expected
}
}
diff --git a/libcore/luni/src/test/java/tests/api/java/io/SequenceInputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/SequenceInputStreamTest.java
index 2ddfb42..f05507e 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/SequenceInputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/SequenceInputStreamTest.java
@@ -299,7 +299,7 @@
method = "read",
args = {byte[].class, int.class, int.class}
)
- public void test_read$BII_exc() throws IOException {
+ public void test_read$BII_Excpetion() throws IOException {
byte[] buf = new byte[4];
si.read(buf, 0, 2);
si.read(buf, 2, 1);
@@ -313,6 +313,29 @@
} catch (IOException e) {
// expected
}
+
+ buf = new byte[10];
+ simple1 = new Support_ASimpleInputStream(s1);
+ simple2 = new Support_ASimpleInputStream(s2);
+ si = new SequenceInputStream(simple1, simple2);
+ try {
+ si.read(buf, -1, 1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ si.read(buf, 0, -1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ si.read(buf, 1, 10);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
}
/**
diff --git a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest.java b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest.java
index 0bbf205..45d92bd 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest.java
@@ -17,7 +17,7 @@
package tests.api.java.io;
-import dalvik.annotation.TestTargets;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -95,29 +95,40 @@
protected transient ByteArrayOutputStream bao;
- // -----------------------------------------------------------------------------------
+ protected void t_MixPrimitivesAndObjects() throws IOException,
+ ClassNotFoundException {
+ int i = 7;
+ String s1 = "string 1";
+ String s2 = "string 2";
+ byte[] bytes = { 1, 2, 3 };
- private static class ObjectInputStreamSubclass extends ObjectInputStream {
- private Vector resolvedClasses = new Vector();
+ oos.writeInt(i);
+ oos.writeObject(s1);
+ oos.writeUTF(s2);
+ oos.writeObject(bytes);
+ oos.close();
+ try {
+ ois = new ObjectInputStream(loadStream());
- public ObjectInputStreamSubclass(InputStream in) throws IOException,
- StreamCorruptedException {
- super(in);
- }
+ int j = ois.readInt();
+ assertTrue("Wrong int :" + j, i == j);
- public Class resolveClass(ObjectStreamClass osClass)
- throws IOException, ClassNotFoundException {
- Class result = super.resolveClass(osClass);
- resolvedClasses.addElement(result);
- return result;
- }
+ String l1 = (String) ois.readObject();
+ assertTrue("Wrong obj String :" + l1, s1.equals(l1));
- public Class[] resolvedClasses() {
- return (Class[]) resolvedClasses.toArray(new Class[resolvedClasses
- .size()]);
+ String l2 = (String) ois.readUTF();
+ assertTrue("Wrong UTF String :" + l2, s2.equals(l2));
+
+ byte[] bytes2 = (byte[]) ois.readObject();
+ assertTrue("Wrong byte[]", Arrays.equals(bytes, bytes2));
+
+ } finally {
+ ois.close();
}
}
+ // -----------------------------------------------------------------------------------
+
static final Map TABLE = new Hashtable();
static final Map MAP = new HashMap();
@@ -165,41 +176,47 @@
"S-TEST");
static final Calendar CALENDAR = new GregorianCalendar(TIME_ZONE);
+
+ static Exception INITIALIZE_EXCEPTION = null;
static {
- TABLE.put("one", "1");
- TABLE.put("two", "2");
- TABLE.put("three", "3");
- MAP.put("one", "1");
- MAP.put("two", "2");
- MAP.put("three", "3");
- LINKEDMAP.put("one", "1");
- LINKEDMAP.put("two", "2");
- LINKEDMAP.put("three", "3");
- IDENTITYMAP.put("one", "1");
- IDENTITYMAP.put("two", "2");
- IDENTITYMAP.put("three", "3");
- LINKEDSET.add("one");
- LINKEDSET.add("two");
- LINKEDSET.add("three");
- TREE.put("one", "1");
- TREE.put("two", "2");
- TREE.put("three", "3");
- PERMCOL.add(PERM);
- // To make sure they all use the same Calendar
- CALENDAR.setTimeZone(new SimpleTimeZone(0, "GMT"));
- CALENDAR.set(1999, Calendar.JUNE, 23, 15, 47, 13);
- CALENDAR.set(Calendar.MILLISECOND, 553);
- DATEFORM.setCalendar(CALENDAR);
- java.text.DateFormatSymbols symbols = new java.text.DateFormatSymbols();
- symbols.setZoneStrings(new String[][] { { "a", "b", "c", "d" },
- { "e", "f", "g", "h" } });
- ((java.text.SimpleDateFormat) DATEFORM).setDateFormatSymbols(symbols);
- DATEFORM.setNumberFormat(new java.text.DecimalFormat("#.#;'-'#.#"));
- DATEFORM.setTimeZone(TimeZone.getTimeZone("EST"));
- ((java.text.DecimalFormat) NUMBERFORM).applyPattern("#.#;'-'#.#");
- MESSAGE.setFormat(0, DATEFORM);
- MESSAGE.setFormat(1, DATEFORM);
+ try {
+ TABLE.put("one", "1");
+ TABLE.put("two", "2");
+ TABLE.put("three", "3");
+ MAP.put("one", "1");
+ MAP.put("two", "2");
+ MAP.put("three", "3");
+ LINKEDMAP.put("one", "1");
+ LINKEDMAP.put("two", "2");
+ LINKEDMAP.put("three", "3");
+ IDENTITYMAP.put("one", "1");
+ IDENTITYMAP.put("two", "2");
+ IDENTITYMAP.put("three", "3");
+ LINKEDSET.add("one");
+ LINKEDSET.add("two");
+ LINKEDSET.add("three");
+ TREE.put("one", "1");
+ TREE.put("two", "2");
+ TREE.put("three", "3");
+ PERMCOL.add(PERM);
+ // To make sure they all use the same Calendar
+ CALENDAR.setTimeZone(new SimpleTimeZone(0, "GMT"));
+ CALENDAR.set(1999, Calendar.JUNE, 23, 15, 47, 13);
+ CALENDAR.set(Calendar.MILLISECOND, 553);
+ DATEFORM.setCalendar(CALENDAR);
+ java.text.DateFormatSymbols symbols = new java.text.DateFormatSymbols();
+ symbols.setZoneStrings(new String[][] { { "a", "b", "c", "d" },
+ { "e", "f", "g", "h" } });
+ ((java.text.SimpleDateFormat) DATEFORM).setDateFormatSymbols(symbols);
+ DATEFORM.setNumberFormat(new java.text.DecimalFormat("#.#;'-'#.#"));
+ DATEFORM.setTimeZone(TimeZone.getTimeZone("EST"));
+ ((java.text.DecimalFormat) NUMBERFORM).applyPattern("#.#;'-'#.#");
+ MESSAGE.setFormat(0, DATEFORM);
+ MESSAGE.setFormat(1, DATEFORM);
+ } catch (Exception e) {
+ INITIALIZE_EXCEPTION = e;
+ }
}
public SerializationStressTest() {
@@ -256,6 +273,9 @@
* is called before a test is executed.
*/
protected void setUp() {
+ if (INITIALIZE_EXCEPTION != null) {
+ throw new ExceptionInInitializerError(INITIALIZE_EXCEPTION);
+ }
try {
if (xdump) {
oos = new ObjectOutputStream(new FileOutputStream(xFileName
@@ -281,965 +301,5 @@
}
}
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_1_Constructor() {
- // Test for method java.io.ObjectOutputStream(java.io.OutputStream)
-
- try {
- oos.close();
- oos = new ObjectOutputStream(new ByteArrayOutputStream());
- oos.close();
- } catch (Exception e) {
- fail("Failed to create ObjectOutputStream : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_2_close() {
- // Test for method void java.io.ObjectOutputStream.close()
- try {
- oos.close();
- oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
- oos.close();
- oos.writeChar('T');
- oos.writeObject(FOO);
- // Writing to a closed stream does not cause problems. This is
- // the expected behavior
- } catch (IOException e) {
- fail("Operation on closed stream threw IOException : "
- + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_3_defaultWriteObject() {
- // Test for method void java.io.ObjectOutputStream.defaultWriteObject()
-
- try {
- oos.defaultWriteObject();
- } catch (NotActiveException e) {
- // Correct
- return;
- } catch (IOException e) {
- }
- fail(
- "Failed to throw NotActiveException when invoked outside readObject");
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_4_flush() {
- // Test for method void java.io.ObjectOutputStream.flush()
- try {
- oos.close();
- oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
- int size = bao.size();
- oos.writeByte(127);
- assertTrue("Data flushed already", bao.size() == size);
- oos.flush();
- assertTrue("Failed to flush data", bao.size() > size);
- // we don't know how many bytes are actually written for 1 byte,
- // so we test > <before>
- oos.close();
- oos = null;
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_5_reset() {
- // Test for method void java.io.ObjectOutputStream.reset()
- try {
- String o = "HelloWorld";
- oos.writeObject(o);
- oos.writeObject(o);
- oos.reset();
- oos.writeObject(o);
- ois = new ObjectInputStream(loadStream());
- ois.close();
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_6_write() {
- // Test for method void java.io.ObjectOutputStream.write(byte [], int,
- // int)
- try {
- byte[] buf = new byte[255];
- byte[] output = new byte[255];
- for (int i = 0; i < output.length; i++)
- output[i] = (byte) i;
- oos.write(output, 0, output.length);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- ois.readFully(buf);
- ois.close();
- for (int i = 0; i < output.length; i++)
- if (buf[i] != output[i])
- fail("Read incorrect byte: " + i);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_6a_write() {
- // Test for method void java.io.ObjectOutputStream.write(byte [], int,
- // int)
- try {
- byte[] buf = new byte[256];
- byte[] output = new byte[256];
- for (int i = 0; i < output.length; i++)
- output[i] = (byte) (i & 0xff);
- oos.write(output, 0, output.length);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- ois.readFully(buf);
- ois.close();
- for (int i = 0; i < output.length; i++)
- if (buf[i] != output[i])
- fail("Read incorrect byte: " + i);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_7_write() {
- // Test for method void java.io.ObjectOutputStream.write(int)
- try {
- byte[] buf = new byte[10];
- oos.write('T');
- oos.close();
- ois = new ObjectInputStream(loadStream());
- assertEquals("Read incorrect byte", 'T', ois.read());
- ois.close();
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_8_write() {
- // Test for method void java.io.ObjectOutputStream.write(byte [])
- try {
- byte[] buf = new byte[10];
- oos.write("HelloWorld".getBytes());
- oos.close();
- ois = new ObjectInputStream(loadStream());
- ois.read(buf, 0, 10);
- ois.close();
- assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0, 10)
- );
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_9_writeBoolean() {
- // Test for method void java.io.ObjectOutputStream.writeBoolean(boolean)
- try {
- oos.writeBoolean(true);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- assertTrue("Wrote incorrect byte value", ois.readBoolean());
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_10_writeByte() {
- // Test for method void java.io.ObjectOutputStream.writeByte(int)
- try {
- oos.writeByte(127);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- assertEquals("Wrote incorrect byte value", 127, ois.readByte());
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_11_writeBytes() {
- // Test for method void
- // java.io.ObjectOutputStream.writeBytes(java.lang.String)
- try {
- byte[] buf = new byte[10];
- oos.writeBytes("HelloWorld");
- oos.close();
- ois = new ObjectInputStream(loadStream());
- ois.readFully(buf);
- ois.close();
- assertEquals("Wrote incorrect bytes value", "HelloWorld", new String(buf, 0, 10)
- );
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_12_writeChar() {
- // Test for method void java.io.ObjectOutputStream.writeChar(int)
- try {
- oos.writeChar('T');
- oos.close();
- ois = new ObjectInputStream(loadStream());
- assertEquals("Wrote incorrect char value", 'T', ois.readChar());
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_13_writeChars() {
- // Test for method void
- // java.io.ObjectOutputStream.writeChars(java.lang.String)
- try {
- int avail = 0;
- char[] buf = new char[10];
- oos.writeChars("HelloWorld");
- oos.close();
- ois = new ObjectInputStream(loadStream());
- // Number of prim data bytes in stream / 2 to give char index
- avail = ois.available() / 2;
- for (int i = 0; i < avail; ++i)
- buf[i] = ois.readChar();
- ois.close();
- assertEquals("Wrote incorrect chars", "HelloWorld", new String(buf, 0, 10)
- );
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_14_writeDouble() {
- // Test for method void java.io.ObjectOutputStream.writeDouble(double)
- try {
- oos.writeDouble(Double.MAX_VALUE);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- assertTrue("Wrote incorrect double value",
- ois.readDouble() == Double.MAX_VALUE);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_15_writeFloat() {
- // Test for method void java.io.ObjectOutputStream.writeFloat(float)
- try {
- oos.writeFloat(Float.MAX_VALUE);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- assertTrue("Wrote incorrect double value",
- ois.readFloat() == Float.MAX_VALUE);
- ois.close();
- ois = null;
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_16_writeInt() {
- // Test for method void java.io.ObjectOutputStream.writeInt(int)
- try {
- oos.writeInt(Integer.MAX_VALUE);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- assertTrue("Wrote incorrect double value",
- ois.readInt() == Integer.MAX_VALUE);
- ois.close();
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_17_writeLong() {
- // Test for method void java.io.ObjectOutputStream.writeLong(long)
- try {
- oos.writeLong(Long.MAX_VALUE);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- assertTrue("Wrote incorrect double value",
- ois.readLong() == Long.MAX_VALUE);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_19_writeShort() {
- // Test for method void java.io.ObjectOutputStream.writeShort(int)
- try {
- oos.writeShort(127);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- assertEquals("Wrote incorrect short value", 127, ois.readShort());
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_20_writeUTF() {
- // Test for method void
- // java.io.ObjectOutputStream.writeUTF(java.lang.String)
- try {
- oos.writeUTF("HelloWorld");
- oos.close();
- ois = new ObjectInputStream(loadStream());
- assertEquals("Wrote incorrect UTF value",
- "HelloWorld", ois.readUTF());
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_25_available() {
- try {
- oos.writeObject(FOO);
- oos.writeObject(FOO);
- oos.flush();
- int available1 = 0;
- int available2 = 0;
- Object obj1 = null;
- Object obj2 = null;
- ObjectInputStream ois = new ObjectInputStream(loadStream());
- available1 = ois.available();
- obj1 = ois.readObject();
- available2 = ois.available();
- obj2 = ois.readObject();
-
- assertEquals("available returned incorrect value", 0, available1);
- assertEquals("available returned incorrect value", 0, available2);
-
- assertTrue("available caused incorrect reading", FOO.equals(obj1));
- assertTrue("available returned incorrect value", FOO.equals(obj2));
-
- } catch (IOException e) {
- fail("IOException serializing object : " + e.getMessage());
- } catch (ClassNotFoundException e) {
- fail("Unable to read Object type : " + e.toString());
- } catch (Error err) {
- System.out.println("Error " + err);
- throw err;
- }
-
- }
-
- protected void t_MixPrimitivesAndObjects() throws IOException,
- ClassNotFoundException {
- int i = 7;
- String s1 = "string 1";
- String s2 = "string 2";
- byte[] bytes = { 1, 2, 3 };
-
- oos.writeInt(i);
- oos.writeObject(s1);
- oos.writeUTF(s2);
- oos.writeObject(bytes);
- oos.close();
- try {
- ois = new ObjectInputStream(loadStream());
-
- int j = ois.readInt();
- assertTrue("Wrong int :" + j, i == j);
-
- String l1 = (String) ois.readObject();
- assertTrue("Wrong obj String :" + l1, s1.equals(l1));
-
- String l2 = (String) ois.readUTF();
- assertTrue("Wrong UTF String :" + l2, s2.equals(l2));
-
- byte[] bytes2 = (byte[]) ois.readObject();
- assertTrue("Wrong byte[]", Arrays.equals(bytes, bytes2));
-
- } finally {
- ois.close();
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_resolveClass() {
- try {
- oos.writeObject(new Object[] { Integer.class, new Integer(1) });
- oos.close();
-
- ois = new ObjectInputStreamSubclass(loadStream());
- ois.readObject();
- ois.close();
- } catch (IOException e1) {
- fail("IOException : " + e1.getMessage());
- } catch (ClassNotFoundException e2) {
- fail("ClassNotFoundException : " + e2.getMessage());
- }
-
- Class[] resolvedClasses = ((ObjectInputStreamSubclass) ois)
- .resolvedClasses();
- assertEquals("missing resolved", 3, resolvedClasses.length);
- assertTrue("resolved class 1", resolvedClasses[0] == Object[].class);
- assertTrue("resolved class 2", resolvedClasses[1] == Integer.class);
- assertTrue("resolved class 3", resolvedClasses[2] == Number.class);
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_reset() {
- try {
- oos.reset();
- oos.writeObject("R");
- oos.reset();
- oos.writeByte(24);
- oos.close();
-
- DataInputStream dis = new DataInputStream(loadStream());
- byte[] input = new byte[dis.available()];
- dis.readFully(input);
- byte[] result = new byte[] { (byte) 0xac, (byte) 0xed, (byte) 0,
- (byte) 5, (byte) 0x79, (byte) 0x74, (byte) 0, (byte) 1,
- (byte) 'R', (byte) 0x79, (byte) 0x77, (byte) 1, (byte) 24 };
- assertTrue("incorrect output", Arrays.equals(input, result));
-
- ois = new ObjectInputStreamSubclass(loadStream());
- assertEquals("Wrong result from readObject()", "R", ois.readObject()
- );
- assertEquals("Wrong result from readByte()", 24, ois.readByte());
- ois.close();
- } catch (IOException e1) {
- fail("IOException : " + e1.getMessage());
- } catch (ClassNotFoundException e2) {
- fail("ClassNotFoundException : " + e2.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_serialVersionUID(Class clazz, long svUID) {
- final String idWrong = "serialVersionUID is wrong for: ";
- long reflectedSvUID = 0L;
- try {
- reflectedSvUID = clazz.getField("serialVersionUID").getLong(null);
- } catch (Exception e) {
- fail("Unable to determine serialVersionUID of " + clazz);
- }
- assertTrue(idWrong + clazz + ": " + reflectedSvUID + " does not equal "
- + svUID, reflectedSvUID == svUID);
- }
-
- private static class ResolveObjectTest implements Serializable {
- Object field1, field2;
- }
-
- private static class ResolveObjectInputStream extends ObjectInputStream {
- ResolveObjectInputStream(InputStream in)
- throws StreamCorruptedException, IOException {
- super(in);
- }
-
- public void enableResolve() {
- enableResolveObject(true);
- }
-
- public Object resolveObject(Object obj) {
- if (obj instanceof Vector) // test_1_resolveObject()
- return new Hashtable();
- else if ("abc".equals(obj)) // test_2_resolveObject()
- return "ABC";
- else if (obj instanceof String) // test_3_resolveObject()
- return String.valueOf(((String) obj).length());
- else if (obj instanceof int[]) // test_4_resolveObject()
- return new Object[1];
- else if (obj instanceof Object[] && ((Object[]) obj).length == 2) // test_5_resolveObject()
- return new char[1];
- return obj;
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_1_resolveObject() {
- try {
- ResolveObjectTest obj = new ResolveObjectTest();
- obj.field1 = new Vector();
- obj.field2 = obj.field1;
- oos.writeObject(obj);
- oos.close();
- ois = new ResolveObjectInputStream(loadStream());
- ((ResolveObjectInputStream) ois).enableResolve();
- ResolveObjectTest result = null;
- try {
- result = (ResolveObjectTest) ois.readObject();
- } catch (ClassNotFoundException e) {
- fail(e.toString());
- }
- assertTrue("Object not resolved",
- result.field1 instanceof Hashtable);
- assertTrue("Second reference not resolved",
- result.field1 == result.field2);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_2_resolveObject() {
- try {
- ResolveObjectTest obj = new ResolveObjectTest();
- obj.field1 = "abc";
- obj.field2 = obj.field1;
- oos.writeObject(obj);
- oos.close();
- ois = new ResolveObjectInputStream(loadStream());
- ((ResolveObjectInputStream) ois).enableResolve();
- ResolveObjectTest result = null;
- try {
- result = (ResolveObjectTest) ois.readObject();
- } catch (ClassNotFoundException e) {
- fail(e.toString());
- }
- assertEquals("String not resolved", "ABC", result.field1);
- assertTrue("Second reference not resolved",
- result.field1 == result.field2);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_3_resolveObject() {
- try {
- ResolveObjectTest obj = new ResolveObjectTest();
- char[] lchars = new char[70000];
- obj.field1 = new String(lchars);
- obj.field2 = obj.field1;
- oos.writeObject(obj);
- oos.close();
- ois = new ResolveObjectInputStream(loadStream());
- ((ResolveObjectInputStream) ois).enableResolve();
- ResolveObjectTest result = null;
- try {
- result = (ResolveObjectTest) ois.readObject();
- } catch (ClassNotFoundException e) {
- fail(e.toString());
- }
- assertTrue("Long String not resolved", "70000"
- .equals(result.field1));
- assertTrue("Second reference not resolved",
- result.field1 == result.field2);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_4_resolveObject() {
- try {
- ResolveObjectTest obj = new ResolveObjectTest();
- obj.field1 = new int[5];
- obj.field2 = obj.field1;
- oos.writeObject(obj);
- oos.close();
- ois = new ResolveObjectInputStream(loadStream());
- ((ResolveObjectInputStream) ois).enableResolve();
- ResolveObjectTest result = null;
- try {
- result = (ResolveObjectTest) ois.readObject();
- } catch (ClassNotFoundException e) {
- fail(e.toString());
- }
- Class cl = new Object[0].getClass();
- assertTrue("int[] not resolved", result.field1.getClass() == cl);
- assertTrue("Second reference not resolved",
- result.field1 == result.field2);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_5_resolveObject() {
- try {
- ResolveObjectTest obj = new ResolveObjectTest();
- obj.field1 = new Object[2];
- obj.field2 = obj.field1;
- oos.writeObject(obj);
- oos.close();
- ois = new ResolveObjectInputStream(loadStream());
- ((ResolveObjectInputStream) ois).enableResolve();
- ResolveObjectTest result = null;
- try {
- result = (ResolveObjectTest) ois.readObject();
- } catch (ClassNotFoundException e) {
- fail(e.toString());
- }
- Class cl = new char[0].getClass();
- assertTrue("int[] not resolved", result.field1.getClass() == cl);
- assertTrue("Second reference not resolved",
- result.field1 == result.field2);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- }
- }
-
- static class WriteReplaceTestA implements Serializable {
- public Object writeReplace() throws ObjectStreamException {
- return new ReadResolveTestB();
- }
- }
-
- static class WriteReplaceTestB extends WriteReplaceTestA {
- }
-
- static class WriteReplaceTestC extends WriteReplaceTestA {
- public Object writeReplace() throws ObjectStreamException {
- return new ReadResolveTestC();
- }
- }
-
- static class WriteReplaceTestD implements Serializable {
- private Object writeReplace() throws ObjectStreamException {
- return new ReadResolveTestD();
- }
- }
-
- static class WriteReplaceTestE extends WriteReplaceTestD {
- }
-
- static class WriteReplaceTestF implements Serializable {
- int type, readType;
-
- public WriteReplaceTestF(int type, int readType) {
- this.type = type;
- this.readType = readType;
- }
-
- public Object writeReplace() throws ObjectStreamException {
- switch (type) {
- case 0:
- throw new InvalidObjectException("invalid");
- case 1:
- throw new RuntimeException("runtime");
- case 2:
- throw new Error("error");
- default:
- return new ReadResolveTestE(readType);
- }
- }
- }
-
- static class ReadResolveTestA implements Serializable {
- public Object readResolve() throws ObjectStreamException {
- return new ReadResolveTestA();
- }
- }
-
- static class ReadResolveTestB extends ReadResolveTestA {
- }
-
- static class ReadResolveTestC implements Serializable {
- private Object readResolve() throws ObjectStreamException {
- return new ReadResolveTestB();
- }
- }
-
- static class ReadResolveTestD extends ReadResolveTestC {
- }
-
- static class ReadResolveTestE implements Serializable {
- int type;
-
- public ReadResolveTestE(int type) {
- this.type = type;
- }
-
- public Object readResolve() throws ObjectStreamException {
- switch (type) {
- case 0:
- throw new InvalidObjectException("invalid");
- case 1:
- throw new RuntimeException("runtime");
- case 2:
- throw new Error("error");
- case 3:
- return this;
- default:
- return new ReadResolveTestF();
- }
- }
- }
-
- static class ReadResolveTestF implements Serializable {
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_1_writeReplace() {
- try {
- Vector v = new Vector();
- v.addElement(new WriteReplaceTestA());
- v.addElement(new WriteReplaceTestB());
- v.addElement(new WriteReplaceTestB());
- v.addElement(new WriteReplaceTestC());
- v.addElement(new WriteReplaceTestD());
- v.addElement(new WriteReplaceTestE());
- oos.writeObject(v);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- Vector result = (Vector) ois.readObject();
- assertTrue("invalid 0 : " + result.elementAt(0), result
- .elementAt(0).getClass() == ReadResolveTestA.class);
- assertTrue("invalid 1 : " + result.elementAt(1), result
- .elementAt(1).getClass() == ReadResolveTestA.class);
- assertTrue("invalid 2 : " + result.elementAt(2), result
- .elementAt(2).getClass() == ReadResolveTestA.class);
- assertTrue("invalid 3 : " + result.elementAt(3), result
- .elementAt(3).getClass() == ReadResolveTestB.class);
- assertTrue("invalid 4 : " + result.elementAt(4), result
- .elementAt(4).getClass() == ReadResolveTestD.class);
- assertTrue("invalid 5 : " + result.elementAt(5), result
- .elementAt(5).getClass() == WriteReplaceTestE.class);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- } catch (ClassNotFoundException e) {
- fail("ClassNotFoundException serializing data : " + e.getMessage());
- }
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Verifies serialization.",
- method = "!Serialization",
- args = {}
- )
- public void test_2_writeReplace() {
- try {
- boolean exception = false;
- try {
- oos.writeObject(new WriteReplaceTestF(0, -1));
- } catch (ObjectStreamException e) {
- exception = true;
- }
- assertTrue("Should throw ObjectStreamException", exception);
- exception = false;
- try {
- oos.writeObject(new WriteReplaceTestF(1, -1));
- } catch (RuntimeException e) {
- exception = true;
- }
- assertTrue("Should throw RuntimeException", exception);
- exception = false;
- try {
- oos.writeObject(new WriteReplaceTestF(2, -1));
- } catch (Error e) {
- exception = true;
- }
- assertTrue("Should throw Error", exception);
-
- oos.writeObject(new WriteReplaceTestF(3, 0));
- oos.writeObject(new WriteReplaceTestF(3, 1));
- oos.writeObject(new WriteReplaceTestF(3, 2));
- WriteReplaceTestF test = new WriteReplaceTestF(3, 3);
- oos.writeObject(test);
- oos.writeObject(test);
- WriteReplaceTestF test2 = new WriteReplaceTestF(3, 4);
- oos.writeObject(test2);
- oos.writeObject(test2);
- oos.close();
- ois = new ObjectInputStream(loadStream());
- try {
- ois.readObject();
- } catch (WriteAbortedException e) {
- }
-
- exception = false;
- try {
- ois.readObject();
- } catch (ObjectStreamException e) {
- exception = true;
- }
- assertTrue("Expected ObjectStreamException", exception);
- exception = false;
- try {
- ois.readObject();
- } catch (RuntimeException e) {
- exception = true;
- }
- assertTrue("Expected RuntimeException", exception);
- exception = false;
- try {
- ois.readObject();
- } catch (Error e) {
- exception = true;
- }
- assertTrue("Expected Error", exception);
- Object readE1 = ois.readObject();
- Object readE2 = ois.readObject();
- assertTrue("Replaced objects should be identical", readE1 == readE2);
- Object readF1 = ois.readObject();
- Object readF2 = ois.readObject();
- assertTrue("Replaced resolved objects should be identical: "
- + readF1 + " " + readF2, readF1 == readF2);
- } catch (IOException e) {
- fail("IOException serializing data : " + e.getMessage());
- } catch (ClassNotFoundException e) {
- fail("ClassNotFoundException serializing data : " + e.getMessage());
- }
- }
}
diff --git a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest0.java b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest0.java
new file mode 100644
index 0000000..b9d7eb6
--- /dev/null
+++ b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest0.java
@@ -0,0 +1,1000 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.java.io;
+
+import dalvik.annotation.BrokenTest;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.io.NotActiveException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.io.StreamCorruptedException;
+import java.io.WriteAbortedException;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * Automated Test Suite for class java.io.ObjectOutputStream
+ *
+ */
+@TestTargetClass(Serializable.class)
+public class SerializationStressTest0 extends SerializationStressTest {
+
+ private static class ObjectInputStreamSubclass extends ObjectInputStream {
+ private Vector resolvedClasses = new Vector();
+
+ public ObjectInputStreamSubclass(InputStream in) throws IOException,
+ StreamCorruptedException {
+ super(in);
+ }
+
+ public Class resolveClass(ObjectStreamClass osClass)
+ throws IOException, ClassNotFoundException {
+ Class result = super.resolveClass(osClass);
+ resolvedClasses.addElement(result);
+ return result;
+ }
+
+ public Class[] resolvedClasses() {
+ return (Class[]) resolvedClasses.toArray(new Class[resolvedClasses
+ .size()]);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_1_Constructor() {
+ // Test for method java.io.ObjectOutputStream(java.io.OutputStream)
+
+ try {
+ oos.close();
+ oos = new ObjectOutputStream(new ByteArrayOutputStream());
+ oos.close();
+ } catch (Exception e) {
+ fail("Failed to create ObjectOutputStream : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_2_close() {
+ // Test for method void java.io.ObjectOutputStream.close()
+ try {
+ oos.close();
+ oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+ oos.close();
+ oos.writeChar('T');
+ oos.writeObject(FOO);
+ // Writing to a closed stream does not cause problems. This is
+ // the expected behavior
+ } catch (IOException e) {
+ fail("Operation on closed stream threw IOException : "
+ + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_3_defaultWriteObject() {
+ // Test for method void java.io.ObjectOutputStream.defaultWriteObject()
+
+ try {
+ oos.defaultWriteObject();
+ } catch (NotActiveException e) {
+ // Correct
+ return;
+ } catch (IOException e) {
+ }
+ fail(
+ "Failed to throw NotActiveException when invoked outside readObject");
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_4_flush() {
+ // Test for method void java.io.ObjectOutputStream.flush()
+ try {
+ oos.close();
+ oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+ int size = bao.size();
+ oos.writeByte(127);
+ assertTrue("Data flushed already", bao.size() == size);
+ oos.flush();
+ assertTrue("Failed to flush data", bao.size() > size);
+ // we don't know how many bytes are actually written for 1 byte,
+ // so we test > <before>
+ oos.close();
+ oos = null;
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_5_reset() {
+ // Test for method void java.io.ObjectOutputStream.reset()
+ try {
+ String o = "HelloWorld";
+ oos.writeObject(o);
+ oos.writeObject(o);
+ oos.reset();
+ oos.writeObject(o);
+ ois = new ObjectInputStream(loadStream());
+ ois.close();
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_6_write() {
+ // Test for method void java.io.ObjectOutputStream.write(byte [], int,
+ // int)
+ try {
+ byte[] buf = new byte[255];
+ byte[] output = new byte[255];
+ for (int i = 0; i < output.length; i++)
+ output[i] = (byte) i;
+ oos.write(output, 0, output.length);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ ois.readFully(buf);
+ ois.close();
+ for (int i = 0; i < output.length; i++)
+ if (buf[i] != output[i])
+ fail("Read incorrect byte: " + i);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_6a_write() {
+ // Test for method void java.io.ObjectOutputStream.write(byte [], int,
+ // int)
+ try {
+ byte[] buf = new byte[256];
+ byte[] output = new byte[256];
+ for (int i = 0; i < output.length; i++)
+ output[i] = (byte) (i & 0xff);
+ oos.write(output, 0, output.length);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ ois.readFully(buf);
+ ois.close();
+ for (int i = 0; i < output.length; i++)
+ if (buf[i] != output[i])
+ fail("Read incorrect byte: " + i);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_7_write() {
+ // Test for method void java.io.ObjectOutputStream.write(int)
+ try {
+ byte[] buf = new byte[10];
+ oos.write('T');
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertEquals("Read incorrect byte", 'T', ois.read());
+ ois.close();
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_8_write() {
+ // Test for method void java.io.ObjectOutputStream.write(byte [])
+ try {
+ byte[] buf = new byte[10];
+ oos.write("HelloWorld".getBytes());
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ ois.read(buf, 0, 10);
+ ois.close();
+ assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0, 10)
+ );
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_9_writeBoolean() {
+ // Test for method void java.io.ObjectOutputStream.writeBoolean(boolean)
+ try {
+ oos.writeBoolean(true);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertTrue("Wrote incorrect byte value", ois.readBoolean());
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_10_writeByte() {
+ // Test for method void java.io.ObjectOutputStream.writeByte(int)
+ try {
+ oos.writeByte(127);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertEquals("Wrote incorrect byte value", 127, ois.readByte());
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_11_writeBytes() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeBytes(java.lang.String)
+ try {
+ byte[] buf = new byte[10];
+ oos.writeBytes("HelloWorld");
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ ois.readFully(buf);
+ ois.close();
+ assertEquals("Wrote incorrect bytes value", "HelloWorld", new String(buf, 0, 10)
+ );
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_12_writeChar() {
+ // Test for method void java.io.ObjectOutputStream.writeChar(int)
+ try {
+ oos.writeChar('T');
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertEquals("Wrote incorrect char value", 'T', ois.readChar());
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_13_writeChars() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeChars(java.lang.String)
+ try {
+ int avail = 0;
+ char[] buf = new char[10];
+ oos.writeChars("HelloWorld");
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ // Number of prim data bytes in stream / 2 to give char index
+ avail = ois.available() / 2;
+ for (int i = 0; i < avail; ++i)
+ buf[i] = ois.readChar();
+ ois.close();
+ assertEquals("Wrote incorrect chars", "HelloWorld", new String(buf, 0, 10)
+ );
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_14_writeDouble() {
+ // Test for method void java.io.ObjectOutputStream.writeDouble(double)
+ try {
+ oos.writeDouble(Double.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertTrue("Wrote incorrect double value",
+ ois.readDouble() == Double.MAX_VALUE);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_15_writeFloat() {
+ // Test for method void java.io.ObjectOutputStream.writeFloat(float)
+ try {
+ oos.writeFloat(Float.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertTrue("Wrote incorrect double value",
+ ois.readFloat() == Float.MAX_VALUE);
+ ois.close();
+ ois = null;
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_16_writeInt() {
+ // Test for method void java.io.ObjectOutputStream.writeInt(int)
+ try {
+ oos.writeInt(Integer.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertTrue("Wrote incorrect double value",
+ ois.readInt() == Integer.MAX_VALUE);
+ ois.close();
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_17_writeLong() {
+ // Test for method void java.io.ObjectOutputStream.writeLong(long)
+ try {
+ oos.writeLong(Long.MAX_VALUE);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertTrue("Wrote incorrect double value",
+ ois.readLong() == Long.MAX_VALUE);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_19_writeShort() {
+ // Test for method void java.io.ObjectOutputStream.writeShort(int)
+ try {
+ oos.writeShort(127);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertEquals("Wrote incorrect short value", 127, ois.readShort());
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_20_writeUTF() {
+ // Test for method void
+ // java.io.ObjectOutputStream.writeUTF(java.lang.String)
+ try {
+ oos.writeUTF("HelloWorld");
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ assertEquals("Wrote incorrect UTF value",
+ "HelloWorld", ois.readUTF());
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_25_available() {
+ try {
+ oos.writeObject(FOO);
+ oos.writeObject(FOO);
+ oos.flush();
+ int available1 = 0;
+ int available2 = 0;
+ Object obj1 = null;
+ Object obj2 = null;
+ ObjectInputStream ois = new ObjectInputStream(loadStream());
+ available1 = ois.available();
+ obj1 = ois.readObject();
+ available2 = ois.available();
+ obj2 = ois.readObject();
+
+ assertEquals("available returned incorrect value", 0, available1);
+ assertEquals("available returned incorrect value", 0, available2);
+
+ assertTrue("available caused incorrect reading", FOO.equals(obj1));
+ assertTrue("available returned incorrect value", FOO.equals(obj2));
+
+ } catch (IOException e) {
+ fail("IOException serializing object : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("Unable to read Object type : " + e.toString());
+ } catch (Error err) {
+ System.out.println("Error " + err);
+ throw err;
+ }
+
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_resolveClass() {
+ try {
+ oos.writeObject(new Object[] { Integer.class, new Integer(1) });
+ oos.close();
+
+ ois = new ObjectInputStreamSubclass(loadStream());
+ ois.readObject();
+ ois.close();
+ } catch (IOException e1) {
+ fail("IOException : " + e1.getMessage());
+ } catch (ClassNotFoundException e2) {
+ fail("ClassNotFoundException : " + e2.getMessage());
+ }
+
+ Class[] resolvedClasses = ((ObjectInputStreamSubclass) ois)
+ .resolvedClasses();
+ assertEquals("missing resolved", 3, resolvedClasses.length);
+ assertTrue("resolved class 1", resolvedClasses[0] == Object[].class);
+ assertTrue("resolved class 2", resolvedClasses[1] == Integer.class);
+ assertTrue("resolved class 3", resolvedClasses[2] == Number.class);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_reset() {
+ try {
+ oos.reset();
+ oos.writeObject("R");
+ oos.reset();
+ oos.writeByte(24);
+ oos.close();
+
+ DataInputStream dis = new DataInputStream(loadStream());
+ byte[] input = new byte[dis.available()];
+ dis.readFully(input);
+ byte[] result = new byte[] { (byte) 0xac, (byte) 0xed, (byte) 0,
+ (byte) 5, (byte) 0x79, (byte) 0x74, (byte) 0, (byte) 1,
+ (byte) 'R', (byte) 0x79, (byte) 0x77, (byte) 1, (byte) 24 };
+ assertTrue("incorrect output", Arrays.equals(input, result));
+
+ ois = new ObjectInputStreamSubclass(loadStream());
+ assertEquals("Wrong result from readObject()", "R", ois.readObject()
+ );
+ assertEquals("Wrong result from readByte()", 24, ois.readByte());
+ ois.close();
+ } catch (IOException e1) {
+ fail("IOException : " + e1.getMessage());
+ } catch (ClassNotFoundException e2) {
+ fail("ClassNotFoundException : " + e2.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_serialVersionUID(Class clazz, long svUID) {
+ final String idWrong = "serialVersionUID is wrong for: ";
+ long reflectedSvUID = 0L;
+ try {
+ reflectedSvUID = clazz.getField("serialVersionUID").getLong(null);
+ } catch (Exception e) {
+ fail("Unable to determine serialVersionUID of " + clazz);
+ }
+ assertTrue(idWrong + clazz + ": " + reflectedSvUID + " does not equal "
+ + svUID, reflectedSvUID == svUID);
+ }
+
+ private static class ResolveObjectTest implements Serializable {
+ Object field1, field2;
+ }
+
+ private static class ResolveObjectInputStream extends ObjectInputStream {
+ ResolveObjectInputStream(InputStream in)
+ throws StreamCorruptedException, IOException {
+ super(in);
+ }
+
+ public void enableResolve() {
+ enableResolveObject(true);
+ }
+
+ public Object resolveObject(Object obj) {
+ if (obj instanceof Vector) // test_1_resolveObject()
+ return new Hashtable();
+ else if ("abc".equals(obj)) // test_2_resolveObject()
+ return "ABC";
+ else if (obj instanceof String) // test_3_resolveObject()
+ return String.valueOf(((String) obj).length());
+ else if (obj instanceof int[]) // test_4_resolveObject()
+ return new Object[1];
+ else if (obj instanceof Object[] && ((Object[]) obj).length == 2) // test_5_resolveObject()
+ return new char[1];
+ return obj;
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_1_resolveObject() {
+ try {
+ ResolveObjectTest obj = new ResolveObjectTest();
+ obj.field1 = new Vector();
+ obj.field2 = obj.field1;
+ oos.writeObject(obj);
+ oos.close();
+ ois = new ResolveObjectInputStream(loadStream());
+ ((ResolveObjectInputStream) ois).enableResolve();
+ ResolveObjectTest result = null;
+ try {
+ result = (ResolveObjectTest) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ }
+ assertTrue("Object not resolved",
+ result.field1 instanceof Hashtable);
+ assertTrue("Second reference not resolved",
+ result.field1 == result.field2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_2_resolveObject() {
+ try {
+ ResolveObjectTest obj = new ResolveObjectTest();
+ obj.field1 = "abc";
+ obj.field2 = obj.field1;
+ oos.writeObject(obj);
+ oos.close();
+ ois = new ResolveObjectInputStream(loadStream());
+ ((ResolveObjectInputStream) ois).enableResolve();
+ ResolveObjectTest result = null;
+ try {
+ result = (ResolveObjectTest) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ }
+ assertEquals("String not resolved", "ABC", result.field1);
+ assertTrue("Second reference not resolved",
+ result.field1 == result.field2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_3_resolveObject() {
+ try {
+ ResolveObjectTest obj = new ResolveObjectTest();
+ char[] lchars = new char[70000];
+ obj.field1 = new String(lchars);
+ obj.field2 = obj.field1;
+ oos.writeObject(obj);
+ oos.close();
+ ois = new ResolveObjectInputStream(loadStream());
+ ((ResolveObjectInputStream) ois).enableResolve();
+ ResolveObjectTest result = null;
+ try {
+ result = (ResolveObjectTest) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ }
+ assertTrue("Long String not resolved", "70000"
+ .equals(result.field1));
+ assertTrue("Second reference not resolved",
+ result.field1 == result.field2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_4_resolveObject() {
+ try {
+ ResolveObjectTest obj = new ResolveObjectTest();
+ obj.field1 = new int[5];
+ obj.field2 = obj.field1;
+ oos.writeObject(obj);
+ oos.close();
+ ois = new ResolveObjectInputStream(loadStream());
+ ((ResolveObjectInputStream) ois).enableResolve();
+ ResolveObjectTest result = null;
+ try {
+ result = (ResolveObjectTest) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ }
+ Class cl = new Object[0].getClass();
+ assertTrue("int[] not resolved", result.field1.getClass() == cl);
+ assertTrue("Second reference not resolved",
+ result.field1 == result.field2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_5_resolveObject() {
+ try {
+ ResolveObjectTest obj = new ResolveObjectTest();
+ obj.field1 = new Object[2];
+ obj.field2 = obj.field1;
+ oos.writeObject(obj);
+ oos.close();
+ ois = new ResolveObjectInputStream(loadStream());
+ ((ResolveObjectInputStream) ois).enableResolve();
+ ResolveObjectTest result = null;
+ try {
+ result = (ResolveObjectTest) ois.readObject();
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ }
+ Class cl = new char[0].getClass();
+ assertTrue("int[] not resolved", result.field1.getClass() == cl);
+ assertTrue("Second reference not resolved",
+ result.field1 == result.field2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ }
+ }
+
+ static class WriteReplaceTestA implements Serializable {
+ public Object writeReplace() throws ObjectStreamException {
+ return new ReadResolveTestB();
+ }
+ }
+
+ static class WriteReplaceTestB extends WriteReplaceTestA {
+ }
+
+ static class WriteReplaceTestC extends WriteReplaceTestA {
+ public Object writeReplace() throws ObjectStreamException {
+ return new ReadResolveTestC();
+ }
+ }
+
+ static class WriteReplaceTestD implements Serializable {
+ private Object writeReplace() throws ObjectStreamException {
+ return new ReadResolveTestD();
+ }
+ }
+
+ static class WriteReplaceTestE extends WriteReplaceTestD {
+ }
+
+ static class WriteReplaceTestF implements Serializable {
+ int type, readType;
+
+ public WriteReplaceTestF(int type, int readType) {
+ this.type = type;
+ this.readType = readType;
+ }
+
+ public Object writeReplace() throws ObjectStreamException {
+ switch (type) {
+ case 0:
+ throw new InvalidObjectException("invalid");
+ case 1:
+ throw new RuntimeException("runtime");
+ case 2:
+ throw new Error("error");
+ default:
+ return new ReadResolveTestE(readType);
+ }
+ }
+ }
+
+ static class ReadResolveTestA implements Serializable {
+ public Object readResolve() throws ObjectStreamException {
+ return new ReadResolveTestA();
+ }
+ }
+
+ static class ReadResolveTestB extends ReadResolveTestA {
+ }
+
+ static class ReadResolveTestC implements Serializable {
+ private Object readResolve() throws ObjectStreamException {
+ return new ReadResolveTestB();
+ }
+ }
+
+ static class ReadResolveTestD extends ReadResolveTestC {
+ }
+
+ static class ReadResolveTestE implements Serializable {
+ int type;
+
+ public ReadResolveTestE(int type) {
+ this.type = type;
+ }
+
+ public Object readResolve() throws ObjectStreamException {
+ switch (type) {
+ case 0:
+ throw new InvalidObjectException("invalid");
+ case 1:
+ throw new RuntimeException("runtime");
+ case 2:
+ throw new Error("error");
+ case 3:
+ return this;
+ default:
+ return new ReadResolveTestF();
+ }
+ }
+ }
+
+ static class ReadResolveTestF implements Serializable {
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ public void test_1_writeReplace() {
+ try {
+ Vector v = new Vector();
+ v.addElement(new WriteReplaceTestA());
+ v.addElement(new WriteReplaceTestB());
+ v.addElement(new WriteReplaceTestB());
+ v.addElement(new WriteReplaceTestC());
+ v.addElement(new WriteReplaceTestD());
+ v.addElement(new WriteReplaceTestE());
+ oos.writeObject(v);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ Vector result = (Vector) ois.readObject();
+ assertTrue("invalid 0 : " + result.elementAt(0), result
+ .elementAt(0).getClass() == ReadResolveTestA.class);
+ assertTrue("invalid 1 : " + result.elementAt(1), result
+ .elementAt(1).getClass() == ReadResolveTestA.class);
+ assertTrue("invalid 2 : " + result.elementAt(2), result
+ .elementAt(2).getClass() == ReadResolveTestA.class);
+ assertTrue("invalid 3 : " + result.elementAt(3), result
+ .elementAt(3).getClass() == ReadResolveTestB.class);
+ assertTrue("invalid 4 : " + result.elementAt(4), result
+ .elementAt(4).getClass() == ReadResolveTestD.class);
+ assertTrue("invalid 5 : " + result.elementAt(5), result
+ .elementAt(5).getClass() == WriteReplaceTestE.class);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException serializing data : " + e.getMessage());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization.",
+ method = "!Serialization",
+ args = {}
+ )
+ @BrokenTest("Needs investigation. succeeds on android, fails on RI")
+ public void test_2_writeReplace() {
+ try {
+ boolean exception = false;
+ try {
+ oos.writeObject(new WriteReplaceTestF(0, -1));
+ } catch (ObjectStreamException e) {
+ exception = true;
+ }
+ assertTrue("Should throw ObjectStreamException", exception);
+ exception = false;
+ try {
+ oos.writeObject(new WriteReplaceTestF(1, -1));
+ } catch (RuntimeException e) {
+ exception = true;
+ }
+ assertTrue("Should throw RuntimeException", exception);
+ exception = false;
+ try {
+ oos.writeObject(new WriteReplaceTestF(2, -1));
+ } catch (Error e) {
+ exception = true;
+ }
+ assertTrue("Should throw Error", exception);
+
+ oos.writeObject(new WriteReplaceTestF(3, 0));
+ oos.writeObject(new WriteReplaceTestF(3, 1));
+ oos.writeObject(new WriteReplaceTestF(3, 2));
+ WriteReplaceTestF test = new WriteReplaceTestF(3, 3);
+ oos.writeObject(test);
+ oos.writeObject(test);
+ WriteReplaceTestF test2 = new WriteReplaceTestF(3, 4);
+ oos.writeObject(test2);
+ oos.writeObject(test2);
+ oos.close();
+ ois = new ObjectInputStream(loadStream());
+ try {
+ ois.readObject();
+ } catch (WriteAbortedException e) {
+ }
+
+ exception = false;
+ try {
+ ois.readObject();
+ } catch (ObjectStreamException e) {
+ exception = true;
+ }
+ assertTrue("Expected ObjectStreamException", exception);
+ exception = false;
+ try {
+ ois.readObject();
+ } catch (RuntimeException e) {
+ exception = true;
+ }
+ assertTrue("Expected RuntimeException", exception);
+ exception = false;
+ try {
+ ois.readObject();
+ } catch (Error e) {
+ exception = true;
+ }
+ assertTrue("Expected Error", exception);
+
+ Object readE1 = ois.readObject();
+ Object readE2 = ois.readObject();
+ assertTrue("Replaced objects should be identical", readE1 == readE2);
+ Object readF1 = ois.readObject();
+ Object readF2 = ois.readObject();
+ assertTrue("Replaced resolved objects should be identical: "
+ + readF1 + " " + readF2, readF1 == readF2);
+ } catch (IOException e) {
+ fail("IOException serializing data : " + e.getMessage());
+ } catch (ClassNotFoundException e) {
+ fail("ClassNotFoundException serializing data : " + e.getMessage());
+ }
+ }
+}
diff --git a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java
index 8327660..d097d67 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java
@@ -16,7 +16,7 @@
*/
package tests.api.java.io;
-import dalvik.annotation.TestTargets;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -358,10 +358,6 @@
}
}
- public SerializationStressTest1(String name) {
- super(name);
- }
-
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Verifies serialization.",
@@ -816,7 +812,8 @@
method = "!Serialization",
args = {}
)
- public void _test_18_14_writeObject() {
+ @BrokenTest("throws IllegalAccessException on Android and InvalidClassException on RI")
+ public void test_18_14_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -861,7 +858,8 @@
method = "!Serialization",
args = {}
)
- public void _test_18_15_writeObject() {
+ @BrokenTest("throws IllegalAccessException on Android and InvalidClassException on RI")
+ public void test_18_15_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1349,6 +1347,7 @@
method = "!Serialization",
args = {}
)
+ @BrokenTest("Needs investigation. fails on RI, succeeds on Android. Maybe a bug in the RI.")
public void test_18_28_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1616,6 +1615,7 @@
method = "!Serialization",
args = {}
)
+ @BrokenTest("succeeds on Android, but fails on RI with MyException being thrown.")
public void test_18_33_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
diff --git a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java
index ba998d8..899cd8f 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java
@@ -17,7 +17,7 @@
package tests.api.java.io;
-import dalvik.annotation.TestTargets;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -804,10 +804,6 @@
}
}
- public SerializationStressTest2(String name) {
- super(name);
- }
-
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Verifies serialization.",
@@ -1423,7 +1419,8 @@
method = "!Serialization",
args = {}
)
- public void _test_18_57_writeObject() {
+ @KnownFailure("Executed replacement when it should not: class java.lang.String")
+ public void test_18_57_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1461,7 +1458,8 @@
method = "!Serialization",
args = {}
)
- public void _test_18_58_writeObject() {
+ @KnownFailure("Executed replacement when it should not: class java.lang.String")
+ public void test_18_58_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1902,7 +1900,8 @@
method = "!Serialization",
args = {}
)
- public void _test_DeepNestingWithWriteObject() {
+ @KnownFailure("Maybe the stack gets too deep for android. Change the test?")
+ public void test_DeepNestingWithWriteObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
diff --git a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java
index 0b8c38d..3674418 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java
@@ -16,6 +16,8 @@
*/
package tests.api.java.io;
+import dalvik.annotation.BrokenTest;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -358,10 +360,6 @@
}
}
- public SerializationStressTest3(String name) {
- super(name);
- }
-
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Verifies serialization.",
@@ -514,7 +512,8 @@
method = "!Serialization",
args = {}
)
- public void _test_18_85_writeObject() {
+ @BrokenTest("Needs investigation.Fails on Android with IlegalAccessException and RI with IOException: no valid constructor")
+ public void test_18_85_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1347,7 +1346,7 @@
method = "!Serialization",
args = {}
)
- public void _test_18_109_writeObject() {
+ public void test_18_109_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1381,7 +1380,7 @@
method = "!Serialization",
args = {}
)
- public void _test_18_110_writeObject() {
+ public void test_18_110_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1416,7 +1415,7 @@
method = "!Serialization",
args = {}
)
- public void _test_18_111_writeObject() {
+ public void test_18_111_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1451,7 +1450,7 @@
method = "!Serialization",
args = {}
)
- public void _test_18_112_writeObject() {
+ public void test_18_112_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1486,7 +1485,8 @@
method = "!Serialization",
args = {}
)
- public void _test_18_113_writeObject() {
+ @KnownFailure("Serialization of SimpleDateFormat object fails")
+ public void test_18_113_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1554,7 +1554,8 @@
method = "!Serialization",
args = {}
)
- public void _test_18_115_writeObject() {
+ @KnownFailure("Serialization of NumberFormat object fails")
+ public void test_18_115_writeObject() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.lang.Object)
diff --git a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java
index b06a457..6cd919a 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java
@@ -17,7 +17,8 @@
package tests.api.java.io;
-import dalvik.annotation.TestTargets;
+import dalvik.annotation.BrokenTest;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -65,10 +66,6 @@
}
}
- public SerializationStressTest4(String name) {
- super(name);
- }
-
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Verifies serialization.",
@@ -721,7 +718,7 @@
method = "!Serialization",
args = {}
)
- public void _test_writeObject_Calendar() {
+ public void test_writeObject_Calendar() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.util.Calendar)
@@ -1202,7 +1199,8 @@
method = "!Serialization",
args = {}
)
- public void _test_writeObject_Collections_UnmodifiableMap_UnmodifiableEntrySet() {
+ @BrokenTest("Needs investigation. Fails on RI and on Android with the same IOException.")
+ public void test_writeObject_Collections_UnmodifiableMap_UnmodifiableEntrySet() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.util.Collections.UnmodifiableMap.UnmodifiableEntrySet)
@@ -2681,7 +2679,7 @@
method = "!Serialization",
args = {}
)
- public void _test_writeObject_Proxy() {
+ public void test_writeObject_Proxy() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.security.GuardedObject)
@@ -2885,6 +2883,7 @@
method = "!Serialization",
args = {}
)
+ @KnownFailure("deserialization of a date fomat field seems to fail")
public void test_writeObject_DateFormat_Field() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.text.DateFormat.Field)
@@ -2929,6 +2928,7 @@
method = "!Serialization",
args = {}
)
+ @KnownFailure("deserialization of a number fomat field seems to fail")
public void test_writeObject_NumberFormat_Field() {
// Test for method void
// java.io.ObjectOutputStream.writeObject(java.text.NumberFormat.Field)
diff --git a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest5.java b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest5.java
index 0f139a3..7b515d9 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest5.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/SerializationStressTest5.java
@@ -59,10 +59,6 @@
{ new Integer(5), new Boolean(false), new Boolean(false),
new Integer(5), new Integer(5) }, {} };
- public SerializationStressTest5(String name) {
- super(name);
- }
-
@TestTargetNew(
level = TestLevel.ADDITIONAL,
notes = "",
diff --git a/libcore/luni/src/test/java/tests/api/java/io/StringBufferInputStreamTest.java b/libcore/luni/src/test/java/tests/api/java/io/StringBufferInputStreamTest.java
index 219d445..bf6b11a 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/StringBufferInputStreamTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/StringBufferInputStreamTest.java
@@ -66,7 +66,7 @@
* @tests java.io.StringBufferInputStream#read()
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "read",
args = {byte[].class, int.class, int.class}
@@ -80,6 +80,38 @@
}
/**
+ * @tests java.io.StringBufferInputStream#read()
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "read",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void test_read$BII_Exception() {
+ // Test for method int java.io.StringBufferInputStream.read()
+ byte[] buf = new byte[10];
+ try {
+ sbis.read(buf, 0, -1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ sbis.read(buf, -1, 1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ sbis.read(buf, 10, 1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ }
+
+ /**
* @tests java.io.StringBufferInputStream#read(byte[], int, int)
*/
@TestTargetNew(
diff --git a/libcore/luni/src/test/java/tests/api/java/io/StringReaderTest.java b/libcore/luni/src/test/java/tests/api/java/io/StringReaderTest.java
index 9cd9293..b0fa469 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/StringReaderTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/StringReaderTest.java
@@ -147,7 +147,7 @@
method = "read",
args = {char[].class, int.class, int.class}
)
- public void test_read$CII() {
+ public void test_read$CII() throws Exception {
// Test for method int java.io.StringReader.read(char [], int, int)
try {
sr = new StringReader(testString);
@@ -159,6 +159,27 @@
} catch (Exception e) {
fail("Exception during read test : " + e.getMessage());
}
+
+ char[] buf = new char[testString.length()];
+ sr = new StringReader(testString);
+ try {
+ sr.read(buf, 0, -1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ sr.read(buf, -1, 1);
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+ try {
+ sr.read(buf, 1, testString.length());
+ fail("IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
}
/**
diff --git a/libcore/luni/src/test/java/tests/api/java/io/StringWriterTest.java b/libcore/luni/src/test/java/tests/api/java/io/StringWriterTest.java
index 980526d..1436b1e 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/StringWriterTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/StringWriterTest.java
@@ -150,58 +150,27 @@
method = "write",
args = {char[].class, int.class, int.class}
)
- public void test_write$CII_2() {
- StringWriter obj = null;
+ public void test_write$CII_Exception() {
+ StringWriter obj = new StringWriter();
try {
- obj = new StringWriter();
- obj.write(new char[0], (int) 0, (int) -1);
+ obj.write(new char[10], 0, -1);
fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException t) {
- assertEquals(
- "IndexOutOfBoundsException rather than a subclass expected",
- IndexOutOfBoundsException.class, t.getClass());
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
- }
- /**
- * @tests java.io.StringWriter#write(char[], int, int)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
- method = "write",
- args = {char[].class, int.class, int.class}
- )
- public void test_write$CII_3() {
- StringWriter obj = null;
try {
- obj = new StringWriter();
- obj.write(new char[0], (int) -1, (int) 0);
+ obj.write(new char[10], -1, 1);
fail("IndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException t) {
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException t) {
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
- }
- /**
- * @tests java.io.StringWriter#write(char[], int, int)
- */
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
- method = "write",
- args = {char[].class, int.class, int.class}
- )
- public void test_write$CII_4() {
- StringWriter obj = null;
try {
- obj = new StringWriter();
- obj.write(new char[0], (int) -1, (int) -1);
+ obj.write(new char[10], 2, 9);
fail("IndexOutOfBoundsException expected");
- } catch (ArrayIndexOutOfBoundsException t) {
- fail("IndexOutOfBoundsException expected");
- } catch (IndexOutOfBoundsException t) {
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
}
}
diff --git a/libcore/luni/src/test/java/tests/api/java/io/WriterTest.java b/libcore/luni/src/test/java/tests/api/java/io/WriterTest.java
index 4c6f98f..2a15c67 100644
--- a/libcore/luni/src/test/java/tests/api/java/io/WriterTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/io/WriterTest.java
@@ -87,10 +87,10 @@
* @tests java.io.Writer#append(CharSequence, int, int)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "append",
- args = {java.lang.CharSequence.class, int.class, int.class}
+ args = {CharSequence.class, int.class, int.class}
)
public void test_appendCharSequenceIntInt() throws IOException {
String testString = "My Test String";
@@ -123,6 +123,38 @@
}
}
+ /**
+ * @tests java.io.Writer#append(CharSequence, int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "append",
+ args = {CharSequence.class, int.class, int.class}
+ )
+ public void test_appendCharSequenceIntInt_Exception() throws IOException {
+ String testString = "My Test String";
+ Writer tobj = new Support_ASimpleWriter(21);
+ try {
+ tobj.append(testString, 30, 31);
+ fail("IndexOutOfBoundsException not thrown!");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ tobj.append(testString, -1, 1);
+ fail("IndexOutOfBoundsException not thrown!");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ tobj.append(testString, 0, -1);
+ fail("IndexOutOfBoundsException not thrown!");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
@@ -193,10 +225,10 @@
* @tests java.io.PrintWriter#write(java.lang.String, int, int)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "write",
- args = {java.lang.String.class, int.class, int.class}
+ args = {String.class, int.class, int.class}
)
public void test_writeLjava_lang_StringII() throws IOException {
String testString;
@@ -222,7 +254,38 @@
// expected
}
}
-
+
+ /**
+ * @tests java.io.Writer#append(CharSequence, int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "write",
+ args = {String.class, int.class, int.class}
+ )
+ public void test_writeLjava_lang_StringII_Exception() throws IOException {
+ String testString = "My Test String";
+ Writer tobj = new Support_ASimpleWriter(21);
+ try {
+ tobj.write(testString, 30, 31);
+ fail("IndexOutOfBoundsException not thrown!");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ tobj.write(testString, -1, 1);
+ fail("IndexOutOfBoundsException not thrown!");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ try {
+ tobj.write(testString, 0, -1);
+ fail("IndexOutOfBoundsException not thrown!");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
class MockWriter extends Writer {
private char[] contents;
diff --git a/libcore/luni/src/test/java/tests/api/java/lang/ProcessManagerTest.java b/libcore/luni/src/test/java/tests/api/java/lang/ProcessManagerTest.java
index e1a2cfc..7129cdc 100644
--- a/libcore/luni/src/test/java/tests/api/java/lang/ProcessManagerTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/lang/ProcessManagerTest.java
@@ -210,6 +210,13 @@
InputStream in;
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ notes = "Check non standard fd behavior",
+ clazz = Runtime.class,
+ method = "exec",
+ args = {String[].class, String[].class, java.io.File.class}
+ )
public void testCloseNonStandardFds()
throws IOException, InterruptedException {
String[] commands = { "ls", "/proc/self/fd" };
@@ -245,11 +252,18 @@
return count;
}
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ notes = "Check non standard fd behavior",
+ clazz = Runtime.class,
+ method = "exec",
+ args = {String[].class, String[].class, java.io.File.class}
+ )
public void testInvalidCommand()
throws IOException, InterruptedException {
try {
String[] commands = { "doesnotexist" };
Runtime.getRuntime().exec(commands, null, null);
} catch (IOException e) { /* expected */ }
- }
-}
\ No newline at end of file
+ }
+}
diff --git a/libcore/luni/src/test/java/tests/api/java/lang/ref/ReferenceQueueTest.java b/libcore/luni/src/test/java/tests/api/java/lang/ref/ReferenceQueueTest.java
index 03375a5..0a32139 100644
--- a/libcore/luni/src/test/java/tests/api/java/lang/ref/ReferenceQueueTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/lang/ref/ReferenceQueueTest.java
@@ -247,11 +247,11 @@
try {
rq.remove(-1);
- fail("IllegalArgumentException was not thrown.");
+ fail("IllegalArgumentException expected.");
} catch(IllegalArgumentException iae) {
//expected
} catch (InterruptedException e) {
- fail("InterruptedException was not thrown.");
+ fail("Unexpected InterruptedException.");
}
}
diff --git a/libcore/luni/src/test/java/tests/api/java/lang/ref/ReferenceTest.java b/libcore/luni/src/test/java/tests/api/java/lang/ref/ReferenceTest.java
index f571b63..68284ef 100644
--- a/libcore/luni/src/test/java/tests/api/java/lang/ref/ReferenceTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/lang/ref/ReferenceTest.java
@@ -252,13 +252,17 @@
@TestTargets({
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
- notes = "Makes sure that overridden versions of clear() and enqueue() get called, and that clear/enqueue/finalize happen in the right order for WeakReferences.",
+ notes = "Makes sure that overridden versions of clear() and enqueue() " +
+ "get called, and that clear/enqueue/finalize happen in the " +
+ "right order for WeakReferences.",
method = "clear",
args = {}
),
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
- notes = "Makes sure that overridden versions of clear() and enqueue() get called, and that clear/enqueue/finalize happen in the right order for WeakReferences.",
+ notes = "Makes sure that overridden versions of clear() and enqueue() " +
+ "get called, and that clear/enqueue/finalize happen in the " +
+ "right order for WeakReferences.",
method = "enqueue",
args = {}
)
@@ -388,7 +392,10 @@
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
- notes = "Contrives a situation where the only reference to a string is a WeakReference from an object that is being finalized. Checks to make sure that the referent of the WeakReference is still pointing to a valid object.",
+ notes = "Contrives a situation where the only reference to a string " +
+ "is a WeakReference from an object that is being finalized. " +
+ "Checks to make sure that the referent of the WeakReference " +
+ "is still pointing to a valid object.",
method = "get",
args = {}
)
@@ -434,7 +441,7 @@
t.join();
System.gc();
System.runFinalization();
-
+ Thread.sleep(1000);
if (error != null) {
throw error;
}
diff --git a/libcore/luni/src/test/java/tests/api/java/lang/reflect/AccessibleObjectTest.java b/libcore/luni/src/test/java/tests/api/java/lang/reflect/AccessibleObjectTest.java
index 0fd60b0..f1c7026 100644
--- a/libcore/luni/src/test/java/tests/api/java/lang/reflect/AccessibleObjectTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/lang/reflect/AccessibleObjectTest.java
@@ -17,7 +17,6 @@
package tests.api.java.lang.reflect;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -168,7 +167,6 @@
method = "getAnnotation",
args = {java.lang.Class.class}
)
- @KnownFailure("Does not throw NPE if argument is null. Fixed in ToT")
public void test_getAnnotation() throws Exception{
AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
//test error case
@@ -238,7 +236,6 @@
method = "isAnnotationPresent",
args = {java.lang.Class.class}
)
- @KnownFailure("Does not throw NPE if argument is null. Fixed in ToT")
public void test_isAnnotationPresent() throws Exception {
AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
assertTrue("Missing @AnnotationRuntime0",
diff --git a/libcore/luni/src/test/java/tests/api/java/lang/reflect/ConstructorTest.java b/libcore/luni/src/test/java/tests/api/java/lang/reflect/ConstructorTest.java
index 9d6d39c..6bdb55a 100644
--- a/libcore/luni/src/test/java/tests/api/java/lang/reflect/ConstructorTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/lang/reflect/ConstructorTest.java
@@ -17,7 +17,6 @@
package tests.api.java.lang.reflect;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -217,7 +216,6 @@
method = "toGenericString",
args = {}
)
- @KnownFailure("Generic string does not contain declared exception types. Fixed in ToT.")
public void test_toGenericString() throws Exception {
Constructor<GenericConstructorTestHelper> genericCtor = GenericConstructorTestHelper.class
.getConstructor(Object.class, Object.class);
@@ -471,7 +469,6 @@
args = {}
)
@SuppressWarnings("unchecked")
- @KnownFailure("Does not return any declared exception types. Fixed in ToT.")
public void test_getGenericExceptionTypes() {
Type[] types = null;
diff --git a/libcore/luni/src/test/java/tests/api/java/lang/reflect/FieldTest.java b/libcore/luni/src/test/java/tests/api/java/lang/reflect/FieldTest.java
index 8e693cf..460cf66 100644
--- a/libcore/luni/src/test/java/tests/api/java/lang/reflect/FieldTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/lang/reflect/FieldTest.java
@@ -17,7 +17,6 @@
package tests.api.java.lang.reflect;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -2130,7 +2129,6 @@
method = "hashCode",
args = {}
)
- @KnownFailure("Spec and code is not conform with other well-established implementation. Fixed in ToT.")
public void test_hashCode() throws Exception {
Field field = TestClass.class.getDeclaredField("annotatedField");
assertEquals("Wrong hashCode returned", field.getName().hashCode()
diff --git a/libcore/luni/src/test/java/tests/api/java/lang/reflect/GenericSignatureFormatErrorTest.java b/libcore/luni/src/test/java/tests/api/java/lang/reflect/GenericSignatureFormatErrorTest.java
index f61cd29..eb5cead 100644
--- a/libcore/luni/src/test/java/tests/api/java/lang/reflect/GenericSignatureFormatErrorTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/lang/reflect/GenericSignatureFormatErrorTest.java
@@ -1,5 +1,6 @@
package tests.api.java.lang.reflect;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -36,7 +37,9 @@
)
public void test_readResource() throws Exception {
File tf = File.createTempFile("classes", ".dex");
- System.out.println("GenericSignatureFormatErrorTest:"+tf.getAbsolutePath()+", canRead: "+tf.canRead()+", canWrite: "+tf.canWrite());
+ // System.out.println("GenericSignatureFormatErrorTest:"
+ // +tf.getAbsolutePath()+", canRead: "+tf.canRead()
+ // +", canWrite: "+tf.canWrite());
InputStream is = this.getClass().getResourceAsStream("dex1.bytes");
assertNotNull(is);
}
@@ -48,6 +51,8 @@
method = "GenericSignatureFormatError",
args = {}
)
+ @AndroidOnly("Uses Android specific class dalvik.system.DexFile " +
+ "for loading classes.")
public void test_signatureFormatError() throws Exception {
/*
* dex1.bytes is a jar file with a classes.dex in it.
@@ -66,7 +71,9 @@
*/
File tf = File.createTempFile("classes", ".dex");
- System.out.println("GenericSignatureFormatErrorTest:"+tf.getAbsolutePath()+", canRead: "+tf.canRead()+", canWrite: "+tf.canWrite());
+ // System.out.println("GenericSignatureFormatErrorTest:" +
+ // tf.getAbsolutePath() + ", canRead: " + tf.canRead() +
+ // ", canWrite: "+tf.canWrite());
InputStream is = this.getClass().getResourceAsStream("dex1.bytes");
assertNotNull(is);
OutputStream fos = new FileOutputStream(tf);
@@ -81,9 +88,9 @@
Class clazz = df.loadClass("demo/HelloWorld", this.getClass().getClassLoader());
TypeVariable[] tvs = clazz.getTypeParameters();
fail("expecting a GenericSignatureFormatError");
- for (TypeVariable tv : tvs) {
- System.out.println("tv:"+tv.toString());
- }
+ // for (TypeVariable tv : tvs) {
+ // System.out.println("tv:"+tv.toString());
+ // }
} catch (GenericSignatureFormatError gsfe) {
// expected
}
diff --git a/libcore/luni/src/test/java/tests/api/java/lang/reflect/ProxyTest.java b/libcore/luni/src/test/java/tests/api/java/lang/reflect/ProxyTest.java
index 2dd4ccf..051d5b2 100644
--- a/libcore/luni/src/test/java/tests/api/java/lang/reflect/ProxyTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/lang/reflect/ProxyTest.java
@@ -163,7 +163,6 @@
method = "newProxyInstance",
args = {java.lang.ClassLoader.class, java.lang.Class[].class, java.lang.reflect.InvocationHandler.class}
)
- @KnownFailure("Fixed in ToT")
public void test_newProxyInstanceLjava_lang_ClassLoader$Ljava_lang_ClassLjava_lang_reflect_InvocationHandler() {
Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
.getClassLoader(), new Class[] { Support_Proxy_I1.class,
@@ -295,7 +294,6 @@
method = "getInvocationHandler",
args = {java.lang.Object.class}
)
- @KnownFailure("Fixed in ToT")
public void test_getInvocationHandlerLjava_lang_Object() {
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
@@ -341,7 +339,6 @@
method = "newProxyInstance",
args = {java.lang.ClassLoader.class, java.lang.Class[].class, java.lang.reflect.InvocationHandler.class}
)
- @KnownFailure("Fixed in ToT")
public void test_newProxyInstance_withNonCompatibleReturnTypes() {
try {
Proxy.newProxyInstance(this.getClass().getClassLoader(),
diff --git a/libcore/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java b/libcore/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java
index 3d43205..256c5ba 100644
--- a/libcore/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java
@@ -23,7 +23,6 @@
import dalvik.annotation.TestTargetNew;
import java.io.IOException;
-import java.io.InputStream;
import java.net.CookieHandler;
import java.net.MalformedURLException;
import java.net.NetPermission;
diff --git a/libcore/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java b/libcore/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java
index 1930f53..b422761 100644
--- a/libcore/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/net/DatagramSocketTest.java
@@ -19,7 +19,6 @@
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -38,7 +37,6 @@
import java.net.PortUnreachableException;
import java.net.SocketAddress;
import java.net.SocketException;
-import java.net.SocketPermission;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.channels.DatagramChannel;
@@ -300,7 +298,6 @@
method = "connect",
args = {java.net.InetAddress.class, int.class}
)
- @KnownFailure("An unexpected Exception was thrown in the last part of the test")
public void test_connectLjava_net_InetAddressI() {
try {
ds = new java.net.DatagramSocket();
diff --git a/libcore/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java b/libcore/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
index 46c7e98..f6957e2 100644
--- a/libcore/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
@@ -19,14 +19,12 @@
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import java.io.IOException;
import java.net.BindException;
import java.net.DatagramPacket;
-import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -273,13 +271,13 @@
groupPort = Support_PortManager.getNextPortForUDP();
mss = new MulticastSocket(groupPort);
mss.setNetworkInterface(networkInterface1);
- assertTrue(
+ InetAddress addr = mss.getInterface();
+ NetworkInterface if1 = NetworkInterface.getByInetAddress(addr);
+ assertEquals(
"getInterface did not return interface set by " +
- "setNeworkInterface Expected: "
- + firstAddress + "Got:"
- + mss.getInterface(), NetworkInterface
- .getByInetAddress(mss.getInterface())
- .equals(networkInterface1));
+ "setNeworkInterface Expected: " + firstAddress
+ + "Got:" + mss.getInterface(),
+ networkInterface1, if1);
}
mss.close();
try {
diff --git a/libcore/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java b/libcore/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java
index 449fbba..c64fd82 100644
--- a/libcore/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java
@@ -22,13 +22,8 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.CacheRequest;
import java.net.CacheResponse;
@@ -40,7 +35,6 @@
import java.net.URL;
import java.net.URLConnection;
import java.security.Permission;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -168,7 +162,8 @@
method = "get",
args = {java.net.URI.class, java.lang.String.class, java.util.Map.class}
)
- @BrokenTest("cache seems not to be used")
+ @BrokenTest("This test fails on both RI and android. Also only getting " +
+ "from the cache is tested. The put method is not tested.")
public void test_get_put() throws Exception {
URL url = new URL("http://" +
diff --git a/libcore/luni/src/test/java/tests/api/java/net/ServerSocketTest.java b/libcore/luni/src/test/java/tests/api/java/net/ServerSocketTest.java
index 36e092d..ecdfd01 100644
--- a/libcore/luni/src/test/java/tests/api/java/net/ServerSocketTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/net/ServerSocketTest.java
@@ -46,15 +46,7 @@
import tests.support.Support_Configuration;
import tests.support.Support_PortManager;
-@TestTargetClass(value = ServerSocket.class,
- untestedMethods = {
- @TestTargetNew(
- level = TestLevel.NOT_NECESSARY,
- notes = "Protected constructor.",
- method = "ServerSocket",
- args = {SocketImpl.class}
- )}
- )
+@TestTargetClass(value = ServerSocket.class)
public class ServerSocketTest extends SocketTestCase {
boolean interrupted;
diff --git a/libcore/luni/src/test/java/tests/api/java/net/SocketPermissionTest.java b/libcore/luni/src/test/java/tests/api/java/net/SocketPermissionTest.java
index fecf50c..f600ef4 100644
--- a/libcore/luni/src/test/java/tests/api/java/net/SocketPermissionTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/net/SocketPermissionTest.java
@@ -17,6 +17,8 @@
package tests.api.java.net;
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -273,6 +275,56 @@
}
/**
+ * @tests serialization/deserialization.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Verifies serialization/deserialization compatibility.",
+ method = "!SerializationSelf",
+ args = {}
+ )
+ public void testSerializationSelf() throws Exception {
+ SocketPermission permission = new SocketPermission("harmony.apache.org", "connect");;
+
+ SerializationTest.verifySelf(permission);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "SocketPermission",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void test_ConstructorLjava_lang_StringLjava_lang_String_subtestIPv6() {
+ String[] goodTestStrings = {
+ "12334.0.0.01", "[fe80::1]",
+ "[FE80:0000:0000:0000:0000:0000:0000:0001]:80",
+ "[::ffff]:80-82", "[ffff::]:80-82", "[fe80::1]:80",
+ "FE80:0000:0000:0000:0000:0000:0000:0001",
+ "FE80:0000:0000:0000:0000:0000:0000:0001:80"
+ };
+ String[] badTestStrings = {"someName:withColonInit:80", "fg80::1", "[ffff:::80-82]",
+ ":[:fff]:80", "FE80:0000:0000:0000:0000:0000:0000:0001:80:82", "FE80::1"
+ };
+
+ for (int i=0; i < goodTestStrings.length; i++) {
+ try {
+ SocketPermission sp = new SocketPermission(goodTestStrings[i], "connect");
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ fail("SocketPermission named: " + goodTestStrings[i] + " failed construction: " + e.getMessage());
+ }
+ }
+
+ for (int i=0; i < badTestStrings.length; i++) {
+ try {
+ SocketPermission sp = new SocketPermission(badTestStrings[i], "connect");
+ fail("SocketPermission named: " + badTestStrings[i] + " should have thrown an IllegalArgumentException on construction");
+ } catch (IllegalArgumentException e) {}
+ }
+ }
+
+ /**
* Sets up the fixture, for example, open a network connection. This method
* is called before a test is executed.
*/
diff --git a/libcore/luni/src/test/java/tests/api/java/net/SocketTest.java b/libcore/luni/src/test/java/tests/api/java/net/SocketTest.java
index b4376c5..94e7d09 100644
--- a/libcore/luni/src/test/java/tests/api/java/net/SocketTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/net/SocketTest.java
@@ -18,7 +18,7 @@
package tests.api.java.net;
import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.KnownFailure;
+//import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -617,8 +617,8 @@
int sport = startServer("SServer getLocAddress");
int portNumber = Support_PortManager.getNextPort();
s = new Socket(InetAddress.getLocalHost(), sport, null, portNumber);
- assertTrue("Returned incorrect InetAddress", s.getLocalAddress()
- .equals(InetAddress.getLocalHost()));
+ assertEquals("Returned incorrect InetAddress",
+ InetAddress.getLocalHost(), s.getLocalAddress());
// now validate thet behaviour when the any address is returned
String preferIPv4StackValue = System
@@ -675,7 +675,6 @@
method = "getOutputStream",
args = {}
)
- @KnownFailure("Needs investigation")
public void test_getOutputStream() throws IOException {
// Test for method java.io.OutputStream
// java.net.Socket.getOutputStream()
@@ -1586,7 +1585,7 @@
assertTrue(
"Local address not correct after bind:"
+ theSocket.getLocalSocketAddress().toString()
- + "Expected: "
+ + " Expected: "
+ (new InetSocketAddress(InetAddress.getLocalHost(),
portNumber)).toString(), theSocket
.getLocalSocketAddress().equals(
@@ -1604,7 +1603,7 @@
assertTrue(
"Returned Remote address from server connected to does not match expected local address:"
+ servSock.getRemoteSocketAddress().toString()
- + "Expected: "
+ + " Expected: "
+ (new InetSocketAddress(InetAddress.getLocalHost(),
portNumber)).toString(), servSock
.getRemoteSocketAddress().equals(
diff --git a/libcore/luni/src/test/java/tests/api/java/util/AbstractMapTest.java b/libcore/luni/src/test/java/tests/api/java/util/AbstractMapTest.java
index 70f73f3..c6a612c 100644
--- a/libcore/luni/src/test/java/tests/api/java/util/AbstractMapTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/util/AbstractMapTest.java
@@ -17,9 +17,7 @@
package tests.api.java.util;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -295,7 +293,6 @@
method = "putAll",
args = {java.util.Map.class}
)
- @KnownFailure("ToT fixed.")
public void test_putAllLMap() {
Hashtable ht = new Hashtable();
AMT amt = new AMT();
diff --git a/libcore/luni/src/test/java/tests/api/java/util/CurrencyTest.java b/libcore/luni/src/test/java/tests/api/java/util/CurrencyTest.java
index 04c92ee..d41f719 100644
--- a/libcore/luni/src/test/java/tests/api/java/util/CurrencyTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/util/CurrencyTest.java
@@ -18,13 +18,10 @@
package tests.api.java.util;
import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.AndroidOnly;
-import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Currency;
@@ -58,7 +55,6 @@
method = "getInstance",
args = {java.util.Locale.class}
)
- @KnownFailure("getInstance instead of returning null value for region without currency throws exception which should be thrown only in case of locale does not support country code.")
public void test_getInstanceLjava_util_Locale() {
/*
* the behaviour in all these three cases should be the same since this
@@ -150,30 +146,32 @@
method = "getSymbol",
args = {}
)
- @KnownFailure("getSymbol() returns wrong value for currency symbol")
+ @AndroidOnly("icu and the RI have different data. Because Android"
+ + "only defines a few locales as a must have, it was not possible"
+ + "to find a set of combinations where no differences between"
+ + "the RI and Android exist.")
public void test_getSymbol() {
-
+
Currency currK = Currency.getInstance("KRW");
- Currency currI = Currency.getInstance("INR");
+ Currency currI = Currency.getInstance("IEP");
Currency currUS = Currency.getInstance("USD");
Locale.setDefault(Locale.US);
assertEquals("currK.getSymbol()", "KRW", currK.getSymbol());
- assertEquals("currI.getSymbol()", "INR", currI.getSymbol());
+ assertEquals("currI.getSymbol()", "IR\u00a3", currI.getSymbol());
assertEquals("currUS.getSymbol()", "$", currUS.getSymbol());
- Locale.setDefault(new Locale("ko", "KR"));
- assertEquals("currK.getSymbol()", "\uffe6", currK.getSymbol());
- assertEquals("currI.getSymbol()", "INR", currI.getSymbol());
+ Locale.setDefault(new Locale("en", "IE"));
+ assertEquals("currK.getSymbol()", "KRW", currK.getSymbol());
+ assertEquals("currI.getSymbol()", "\u00a3", currI.getSymbol());
assertEquals("currUS.getSymbol()", "USD", currUS.getSymbol());
// test what happens if this is an invalid locale,
// one with Korean country but an India language
- // this method should return the currency codes in that case
Locale.setDefault(new Locale("kr", "KR"));
assertEquals("currK.getSymbol()", "KRW", currK.getSymbol());
- assertEquals("currI.getSymbol()", "INR", currI.getSymbol());
- assertEquals("currUS.getSymbol()", "USD", currUS.getSymbol());
+ assertEquals("currI.getSymbol()", "IR\u00a3", currI.getSymbol());
+ assertEquals("currUS.getSymbol()", "$", currUS.getSymbol());
}
/**
@@ -220,24 +218,20 @@
new Locale("en", "")};
String[] euro = new String[] {"EUR", "\u20ac"};
- String[] yen = new String[] {"JPY", "\uffe5", "\uffe5JP", "JP\uffe5"};
+ // \u00a5 and \uffe5 are actually the same symbol, just different code points.
+ // But the RI returns the \uffe5 and Android returns those with \u00a5
+ String[] yen = new String[] {"JPY", "\u00a5", "\u00a5JP", "JP\u00a5", "\uffe5", "\uffe5JP", "JP\uffe5"};
String[] dollar = new String[] {"USD", "$", "US$", "$US"};
String[] cDollar = new String[] {"CAD", "$", "Can$", "$Ca"};
- String[] crone = new String[] {"DKK", "kr", "CrD"};
Currency currE = Currency.getInstance("EUR");
Currency currJ = Currency.getInstance("JPY");
Currency currUS = Currency.getInstance("USD");
Currency currCA = Currency.getInstance("CAD");
- Currency currDKK = Currency.getInstance("DKK");
int i, j, k;
boolean flag;
- Locale.setDefault(Locale.US);
- Locale.setDefault(new Locale("ja", "JP"));
- Locale.setDefault(new Locale("da", "DK"));
-
for(k = 0; k < loc1.length; k++) {
Locale.setDefault(loc1[k]);
@@ -249,7 +243,12 @@
break;
}
}
- assertTrue(flag);
+ assertTrue("Default Locale is: " + Locale.getDefault()
+ + ". For locale " + loc1[i]
+ + " the Euro currency returned "
+ + currE.getSymbol(loc1[i])
+ + ". Expected was one of these: "
+ + Arrays.toString(euro), flag);
}
for (i = 0; i < loc1.length; i++) {
@@ -262,7 +261,12 @@
break;
}
}
- assertTrue(flag);
+ assertTrue("Default Locale is: " + Locale.getDefault()
+ + ". For locale " + loc1[i]
+ + " the Yen currency returned "
+ + currJ.getSymbol(loc1[i])
+ + ". Expected was one of these: "
+ + Arrays.toString(yen), flag);
}
for (i = 0; i < loc1.length; i++) {
@@ -273,7 +277,12 @@
break;
}
}
- assertTrue(flag);
+ assertTrue("Default Locale is: " + Locale.getDefault()
+ + ". For locale " + loc1[i]
+ + " the Dollar currency returned "
+ + currUS.getSymbol(loc1[i])
+ + ". Expected was one of these: "
+ + Arrays.toString(dollar), flag);
}
for (i = 0; i < loc1.length; i++) {
@@ -284,18 +293,12 @@
break;
}
}
- assertTrue(flag);
- }
-
- for (i = 0; i < loc1.length; i++) {
- flag = false;
- for (j = 0; j < dollar.length; j++) {
- if (currCA.getSymbol(loc1[i]).equals(cDollar[j])) {
- flag = true;
- break;
- }
- }
- assertTrue(flag);
+ assertTrue("Default Locale is: " + Locale.getDefault()
+ + ". For locale " + loc1[i]
+ + " the Canadian Dollar currency returned "
+ + currCA.getSymbol(loc1[i])
+ + ". Expected was one of these: "
+ + Arrays.toString(cDollar), flag);
}
}
}
@@ -309,26 +312,31 @@
method = "getDefaultFractionDigits",
args = {}
)
- @KnownFailure("method return wrong number of digits for pseudo-currency")
public void test_getDefaultFractionDigits() {
- Currency c1 = Currency.getInstance("EUR");
+
+ Currency c1 = Currency.getInstance("TND");
c1.getDefaultFractionDigits();
assertEquals(" Currency.getInstance(\"" + c1
- + "\") returned incorrect number of digits. ", 2, c1
+ + "\") returned incorrect number of digits. ", 3, c1
.getDefaultFractionDigits());
- Currency c2 = Currency.getInstance("JPY");
+ Currency c2 = Currency.getInstance("EUR");
c2.getDefaultFractionDigits();
assertEquals(" Currency.getInstance(\"" + c2
- + "\") returned incorrect number of digits. ", 0, c2
+ + "\") returned incorrect number of digits. ", 2, c2
.getDefaultFractionDigits());
- Currency c3 = Currency.getInstance("XBD");
+ Currency c3 = Currency.getInstance("JPY");
c3.getDefaultFractionDigits();
assertEquals(" Currency.getInstance(\"" + c3
- + "\") returned incorrect number of digits. ", -1, c3
+ + "\") returned incorrect number of digits. ", 0, c3
.getDefaultFractionDigits());
+ Currency c4 = Currency.getInstance("XXX");
+ c4.getDefaultFractionDigits();
+ assertEquals(" Currency.getInstance(\"" + c4
+ + "\") returned incorrect number of digits. ", -1, c4
+ .getDefaultFractionDigits());
}
/**
diff --git a/libcore/luni/src/test/java/tests/api/java/util/FormatterTest.java b/libcore/luni/src/test/java/tests/api/java/util/FormatterTest.java
index 6e1c86e..06a7797 100644
--- a/libcore/luni/src/test/java/tests/api/java/util/FormatterTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/util/FormatterTest.java
@@ -16,7 +16,6 @@
package tests.api.java.util;
import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.KnownFailure;
@@ -194,6 +193,7 @@
method = "Formatter",
args = {java.lang.Appendable.class}
)
+ @AndroidOnly("the RI trows an exception that makes no sense. See comment.")
public void test_ConstructorLjava_lang_Appendable() {
MockAppendable ma = new MockAppendable();
Formatter f1 = new Formatter(ma);
@@ -267,6 +267,7 @@
method = "Formatter",
args = {java.lang.String.class}
)
+ @KnownFailure("The Exception is not thrown on linux if the user is root")
public void test_ConstructorLjava_lang_String() throws IOException {
Formatter f = null;
try {
@@ -284,7 +285,7 @@
assertEquals(0, fileWithContent.length());
f.close();
- // FIXME This exception will not be thrown out on linux.
+ // FIXME This exception will not be thrown on linux if the user is root.
try {
f = new Formatter(readOnly.getPath());
fail("should throw FileNotFoundException");
@@ -313,6 +314,7 @@
method = "Formatter",
args = {java.lang.String.class, java.lang.String.class}
)
+ @KnownFailure("The Exception is not thrown on linux if the user is root")
public void test_ConstructorLjava_lang_StringLjava_lang_String()
throws IOException {
Formatter f = null;
@@ -345,7 +347,7 @@
assertEquals(0, fileWithContent.length());
f.close();
- // FIXME This exception will not be thrown out on linux.
+ // FIXME This exception will not be thrown on linux if the user is root.
try {
f = new Formatter(readOnly.getPath(), "UTF-16BE");
fail("should throw FileNotFoundException");
@@ -374,6 +376,7 @@
method = "Formatter",
args = {java.lang.String.class, java.lang.String.class, java.util.Locale.class}
)
+ @KnownFailure("The Exception is not thrown on linux if the user is root")
public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_util_Locale()
throws IOException {
Formatter f = null;
@@ -414,6 +417,7 @@
assertEquals(0, fileWithContent.length());
f.close();
+ // FIXME This exception will not be thrown on linux if the user is root.
try {
f = new Formatter(readOnly.getPath(), Charset.defaultCharset()
.name(), Locale.ITALY);
@@ -444,6 +448,7 @@
method = "Formatter",
args = {java.io.File.class}
)
+ @KnownFailure("The Exception is not thrown on linux if the user is root")
public void test_ConstructorLjava_io_File() throws IOException {
Formatter f = null;
try {
@@ -461,7 +466,7 @@
assertEquals(0, fileWithContent.length());
f.close();
- // FIXME This exception will not be thrown out on linux.
+ // FIXME This exception will not be thrown on linux if the user is root.
try {
f = new Formatter(readOnly);
fail("should throw FileNotFoundException");
@@ -490,6 +495,7 @@
method = "Formatter",
args = {java.io.File.class, java.lang.String.class}
)
+ @KnownFailure("The Exception is not thrown on linux if the user is root")
public void test_ConstructorLjava_io_FileLjava_lang_String()
throws IOException {
Formatter f = null;
@@ -508,7 +514,7 @@
assertEquals(0, fileWithContent.length());
f.close();
- // FIXME This exception will not be thrown out on linux.
+ // FIXME This exception will not be thrown on linux if the user is root.
try {
f = new Formatter(readOnly, Charset.defaultCharset().name());
fail("should throw FileNotFoundException");
@@ -563,6 +569,7 @@
method = "Formatter",
args = {java.io.File.class, java.lang.String.class, java.util.Locale.class}
)
+ @KnownFailure("The Exception is not thrown on linux if the user is root")
public void test_ConstructorLjava_io_FileLjava_lang_StringLjava_util_Locale()
throws IOException {
Formatter f = null;
@@ -601,7 +608,7 @@
assertEquals(0, fileWithContent.length());
f.close();
- // FIXME This exception will not be thrown out on linux.
+ // FIXME This exception will not be thrown on linux if the user is root.
try {
f = new Formatter(readOnly.getPath(), Charset.defaultCharset()
.name(), Locale.ITALY);
@@ -2021,7 +2028,7 @@
method = "format",
args = {java.lang.String.class, java.lang.Object[].class}
)
- @KnownFailure("Conversion for japanese locale works improperly")
+ @AndroidOnly("Icu data for Czech locale differs a bit from the RI")
public void test_formatLjava_lang_String$Ljava_lang_Object_DateTimeConversion() {
Formatter f = null;
Date now = new Date(1147327147578L);
@@ -2223,25 +2230,25 @@
};
- final Object[][] lowerCaseJapanTriple = {
- {0L, 'a', "\u6728"}, //$NON-NLS-2$
- {Long.MAX_VALUE, 'a', "\u65e5"}, //$NON-NLS-2$
- {-1000L, 'a', "\u6728"}, //$NON-NLS-2$
- {new Date(1147327147578L), 'a', "\u6728"}, //$NON-NLS-2$
- {paris, 'a', "\u6708"}, //$NON-NLS-2$
- {china, 'a', "\u6708"}, //$NON-NLS-2$
+ final Object[][] lowerCaseCzechTriple = {
+ {0L, 'a', "\u010dt"}, //$NON-NLS-2$
+ {Long.MAX_VALUE, 'a', "ne"}, //$NON-NLS-2$
+ {-1000L, 'a', "\u010dt"}, //$NON-NLS-2$
+ {new Date(1147327147578L), 'a', "\u010dt"}, //$NON-NLS-2$
+ {paris, 'a', "po"}, //$NON-NLS-2$
+ {china, 'a', "po"}, //$NON-NLS-2$
{0L, 'b', "1"}, //$NON-NLS-2$
{Long.MAX_VALUE, 'b', "8"}, //$NON-NLS-2$
{-1000L, 'b', "1"}, //$NON-NLS-2$
{new Date(1147327147578L), 'b', "5"}, //$NON-NLS-2$
{paris, 'b', "5"}, //$NON-NLS-2$
{china, 'b', "5"}, //$NON-NLS-2$
- {0L, 'c', "\u6728 1 01 08:00:00 CST 1970"}, //$NON-NLS-2$
- {Long.MAX_VALUE, 'c', "\u65e5 8 17 15:12:55 CST 292278994"}, //$NON-NLS-2$
- {-1000L, 'c', "\u6728 1 01 07:59:59 CST 1970"}, //$NON-NLS-2$
- {new Date(1147327147578L), 'c', "\u6728 5 11 13:59:07 CST 2006"}, //$NON-NLS-2$
- {paris, 'c', "\u6708 5 08 12:00:00 CEST 2006"}, //$NON-NLS-2$
- {china, 'c', "\u6708 5 08 12:00:00 GMT-08:00 2006"}, //$NON-NLS-2$
+ {0L, 'c', "\u010dt I 01 08:00:00 CST 1970"}, //$NON-NLS-2$
+ {Long.MAX_VALUE, 'c', "ne VIII 17 15:12:55 CST 292278994"}, //$NON-NLS-2$
+ {-1000L, 'c', "\u010dt I 01 07:59:59 CST 1970"}, //$NON-NLS-2$
+ {new Date(1147327147578L), 'c', "\u010dt V 11 13:59:07 CST 2006"}, //$NON-NLS-2$
+ {paris, 'c', "po V 08 12:00:00 CEST 2006"}, //$NON-NLS-2$
+ {china, 'c', "po V 08 12:00:00 GMT-08:00 2006"}, //$NON-NLS-2$
{0L, 'd', "01"}, //$NON-NLS-2$
{Long.MAX_VALUE, 'd', "17"}, //$NON-NLS-2$
{-1000L, 'd', "01"}, //$NON-NLS-2$
@@ -2254,12 +2261,12 @@
{new Date(1147327147578L), 'e', "11"}, //$NON-NLS-2$
{paris, 'e', "8"}, //$NON-NLS-2$
{china, 'e', "8"}, //$NON-NLS-2$
- {0L, 'h', "1"}, //$NON-NLS-2$
- {Long.MAX_VALUE, 'h', "8"}, //$NON-NLS-2$
- {-1000L, 'h', "1"}, //$NON-NLS-2$
- {new Date(1147327147578L), 'h', "5"}, //$NON-NLS-2$
- {paris, 'h', "5"}, //$NON-NLS-2$
- {china, 'h', "5"}, //$NON-NLS-2$
+ {0L, 'h', "I"}, //$NON-NLS-2$
+ {Long.MAX_VALUE, 'h', "VIII"}, //$NON-NLS-2$
+ {-1000L, 'h', "I"}, //$NON-NLS-2$
+ {new Date(1147327147578L), 'h', "V"}, //$NON-NLS-2$
+ {paris, 'h', "V"}, //$NON-NLS-2$
+ {china, 'h', "V"}, //$NON-NLS-2$
{0L, 'j', "001"}, //$NON-NLS-2$
{Long.MAX_VALUE, 'j', "229"}, //$NON-NLS-2$
{-1000L, 'j', "001"}, //$NON-NLS-2$
@@ -2284,18 +2291,18 @@
{new Date(1147327147578L), 'm', "05"}, //$NON-NLS-2$
{paris, 'm', "05"}, //$NON-NLS-2$
{china, 'm', "05"}, //$NON-NLS-2$
- {0L, 'p', "\u5348\u524d"}, //$NON-NLS-2$
- {Long.MAX_VALUE, 'p', "\u5348\u5f8c"}, //$NON-NLS-2$
- {-1000L, 'p', "\u5348\u524d"}, //$NON-NLS-2$
- {new Date(1147327147578L), 'p', "\u5348\u5f8c"}, //$NON-NLS-2$
- {paris, 'p', "\u5348\u5f8c"}, //$NON-NLS-2$
- {china, 'p', "\u5348\u5f8c"}, //$NON-NLS-2$
- {0L, 'r', "08:00:00 \u5348\u524d"}, //$NON-NLS-2$
- {Long.MAX_VALUE, 'r', "03:12:55 \u5348\u5f8c"}, //$NON-NLS-2$
- {-1000L, 'r', "07:59:59 \u5348\u524d"}, //$NON-NLS-2$
- {new Date(1147327147578L), 'r', "01:59:07 \u5348\u5f8c"}, //$NON-NLS-2$
- {paris, 'r', "12:00:00 \u5348\u5f8c"}, //$NON-NLS-2$
- {china, 'r', "12:00:00 \u5348\u5f8c"}, //$NON-NLS-2$
+ {0L, 'p', "dop."}, //$NON-NLS-2$
+ {Long.MAX_VALUE, 'p', "odp."}, //$NON-NLS-2$
+ {-1000L, 'p', "dop."}, //$NON-NLS-2$
+ {new Date(1147327147578L), 'p', "odp."}, //$NON-NLS-2$
+ {paris, 'p', "odp."}, //$NON-NLS-2$
+ {china, 'p', "odp."}, //$NON-NLS-2$
+ {0L, 'r', "08:00:00 DOP."}, //$NON-NLS-2$
+ {Long.MAX_VALUE, 'r', "03:12:55 ODP."}, //$NON-NLS-2$
+ {-1000L, 'r', "07:59:59 DOP."}, //$NON-NLS-2$
+ {new Date(1147327147578L), 'r', "01:59:07 ODP."}, //$NON-NLS-2$
+ {paris, 'r', "12:00:00 ODP."}, //$NON-NLS-2$
+ {china, 'r', "12:00:00 ODP."}, //$NON-NLS-2$
{0L, 's', "0"}, //$NON-NLS-2$
{Long.MAX_VALUE, 's', "9223372036854775"}, //$NON-NLS-2$
{-1000L, 's', "-1"}, //$NON-NLS-2$
@@ -2337,10 +2344,10 @@
lowerCaseFranceTriple[i][output], f.toString());
f = new Formatter(Locale.GERMAN);
- f.format(Locale.JAPAN, formatSpecifier, lowerCaseJapanTriple[i][input]);
+ f.format(new Locale("cs", "CZ"), formatSpecifier, lowerCaseCzechTriple[i][input]);
assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
- + " Argument: " + lowerCaseJapanTriple[i][input], //$NON-NLS-2$
- lowerCaseJapanTriple[i][output], f.toString());
+ + " Argument: " + lowerCaseCzechTriple[i][input], //$NON-NLS-2$
+ lowerCaseCzechTriple[i][output], f.toString());
// test '%T'
f = new Formatter(Locale.GERMAN);
@@ -2358,10 +2365,10 @@
.toUpperCase(Locale.US), f.toString());
f = new Formatter(Locale.GERMAN);
- f.format(Locale.JAPAN, formatSpecifierUpper, lowerCaseJapanTriple[i][input]);
+ f.format(new Locale("cs", "CZ"), formatSpecifierUpper, lowerCaseCzechTriple[i][input]);
assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
- + " Argument: " + lowerCaseJapanTriple[i][input], //$NON-NLS-2$
- ((String)lowerCaseJapanTriple[i][output])
+ + " Argument: " + lowerCaseCzechTriple[i][input], //$NON-NLS-2$
+ ((String)lowerCaseCzechTriple[i][output])
.toUpperCase(Locale.US), f.toString());
}
@@ -2565,19 +2572,19 @@
};
- final Object[][] upperCaseJapanTriple = {
- {0L, 'A', "\u6728\u66dc\u65e5"}, //$NON-NLS-2$
- {Long.MAX_VALUE, 'A', "\u65e5\u66dc\u65e5"}, //$NON-NLS-2$
- {-1000L, 'A', "\u6728\u66dc\u65e5"}, //$NON-NLS-2$
- {new Date(1147327147578L), 'A', "\u6728\u66dc\u65e5"}, //$NON-NLS-2$
- {paris, 'A', "\u6708\u66dc\u65e5"}, //$NON-NLS-2$
- {china, 'A', "\u6708\u66dc\u65e5"}, //$NON-NLS-2$
- {0L, 'B', "1\u6708"}, //$NON-NLS-2$
- {Long.MAX_VALUE, 'B', "8\u6708"}, //$NON-NLS-2$
- {-1000L, 'B', "1\u6708"}, //$NON-NLS-2$
- {new Date(1147327147578L), 'B', "5\u6708"}, //$NON-NLS-2$
- {paris, 'B', "5\u6708"}, //$NON-NLS-2$
- {china, 'B', "5\u6708"}, //$NON-NLS-2$
+ final Object[][] upperCaseCzechTriple = {
+ {0L, 'A', "\u010ctvrtek"}, //$NON-NLS-2$
+ {Long.MAX_VALUE, 'A', "Ned\u011ble"}, //$NON-NLS-2$
+ {-1000L, 'A', "\u010ctvrtek"}, //$NON-NLS-2$
+ {new Date(1147327147578L), 'A', "\u010ctvrtek"}, //$NON-NLS-2$
+ {paris, 'A', "Pond\u011bl\u00ed"}, //$NON-NLS-2$
+ {china, 'A', "Pond\u011bl\u00ed"}, //$NON-NLS-2$
+ {0L, 'B', "leden"}, //$NON-NLS-2$
+ {Long.MAX_VALUE, 'B', "srpen"}, //$NON-NLS-2$
+ {-1000L, 'B', "leden"}, //$NON-NLS-2$
+ {new Date(1147327147578L), 'B', "kv\u011bten"}, //$NON-NLS-2$
+ {paris, 'B', "kv\u011bten"}, //$NON-NLS-2$
+ {china, 'B', "kv\u011bten"}, //$NON-NLS-2$
{0L, 'C', "19"}, //$NON-NLS-2$
{Long.MAX_VALUE, 'C', "2922789"}, //$NON-NLS-2$
{-1000L, 'C', "19"}, //$NON-NLS-2$
@@ -2673,19 +2680,19 @@
continue;
}
// test '%t'
- f = new Formatter(Locale.JAPAN);
- f.format(formatSpecifier, upperCaseJapanTriple[i][input]);
+ f = new Formatter(new Locale("cs", "CZ"));
+ f.format(formatSpecifier, upperCaseCzechTriple[i][input]);
assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
- + " Argument: " + upperCaseJapanTriple[i][input], //$NON-NLS-2$
- upperCaseJapanTriple[i][output], f.toString());
+ + " Argument: " + upperCaseCzechTriple[i][input], //$NON-NLS-2$
+ upperCaseCzechTriple[i][output], f.toString());
- f = new Formatter(Locale.JAPAN);
+ f = new Formatter(new Locale("cs", "CZ"));
f.format(Locale.GERMAN, formatSpecifier, upperCaseGermanTriple[i][input]);
assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+ " Argument: " + upperCaseGermanTriple[i][input], //$NON-NLS-2$
upperCaseGermanTriple[i][output], f.toString());
- f = new Formatter(Locale.JAPAN);
+ f = new Formatter(new Locale("cs", "CZ"));
f.format(Locale.FRANCE, formatSpecifier, upperCaseFranceTriple[i][input]);
assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+ " Argument: " + upperCaseFranceTriple[i][input], //$NON-NLS-2$
@@ -2700,10 +2707,10 @@
.toUpperCase(Locale.US), f.toString());
f = new Formatter(Locale.GERMAN);
- f.format(Locale.JAPAN, formatSpecifierUpper, upperCaseJapanTriple[i][input]);
+ f.format(new Locale("cs", "CZ"), formatSpecifierUpper, upperCaseCzechTriple[i][input]);
assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
- + " Argument: " + upperCaseJapanTriple[i][input], //$NON-NLS-2$
- ((String)upperCaseJapanTriple[i][output])
+ + " Argument: " + upperCaseCzechTriple[i][input], //$NON-NLS-2$
+ ((String)upperCaseCzechTriple[i][output])
.toUpperCase(Locale.US), f.toString());
f = new Formatter(Locale.GERMAN);
@@ -2766,6 +2773,7 @@
method = "format",
args = {java.lang.String.class, java.lang.Object[].class}
)
+ @KnownFailure("flaky! results. differs if debugger is attached.")
public void test_formatLjava_lang_String$LBigInteger() {
final Object[][] tripleD = {
{new BigInteger("123456789012345678901234567890"), "%d", "123456789012345678901234567890"}, //$NON-NLS-2$
diff --git a/libcore/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java b/libcore/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
index 76026bf..6d2ef74 100644
--- a/libcore/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
@@ -17,8 +17,8 @@
package tests.api.java.util;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.KnownFailure;
@@ -208,7 +208,6 @@
method = "GregorianCalendar",
args = {java.util.TimeZone.class, java.util.Locale.class}
)
- @KnownFailure("same objects for different locales are not considered equal")
public void test_ConstructorLjava_util_TimeZoneLjava_util_Locale() {
// Test for method java.util.GregorianCalendar(java.util.TimeZone,
// java.util.Locale)
@@ -248,6 +247,8 @@
method = "add",
args = {int.class, int.class}
)
+ @AndroidOnly("This test fails on the RI with version 1.5 but succeeds"
+ + "on the RI with version 1.6")
public void test_addII() {
// Test for method void java.util.GregorianCalendar.add(int, int)
GregorianCalendar gc1 = new GregorianCalendar(1998, 11, 6);
@@ -763,7 +764,8 @@
method = "getMinimalDaysInFirstWeek",
args = {}
)
- @KnownFailure("Looks like there're some mistakes in timezones and/or locales data")
+ @KnownFailure("Some difference in timezones and/or locales data"
+ + "Who is right, the CLDR or the RI?")
public void test_getMinimalDaysInFirstWeek() {
// Regression for Harmony-1037
GregorianCalendar g = new GregorianCalendar(TimeZone
@@ -772,7 +774,7 @@
assertEquals(4, minimalDaysInFirstWeek);
g = new GregorianCalendar(TimeZone.getTimeZone("Paris/France"),
- new Locale("fr"));
+ new Locale("fr", "FR"));
minimalDaysInFirstWeek = g.getMinimalDaysInFirstWeek();
assertEquals(4, minimalDaysInFirstWeek);
diff --git a/libcore/luni/src/test/java/tests/api/java/util/LinkedHashMapTest.java b/libcore/luni/src/test/java/tests/api/java/util/LinkedHashMapTest.java
index aec90f8..7169aca 100644
--- a/libcore/luni/src/test/java/tests/api/java/util/LinkedHashMapTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/util/LinkedHashMapTest.java
@@ -462,6 +462,38 @@
assertEquals("keySet() was not cloned",
"key2", key2.iterator().next());
}
+
+ /**
+ * @tests java.util.LinkedHashMap#clone()
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "clone",
+ args = {}
+ )
+ public void test_clone_ordered() {
+ // Test for method java.lang.Object java.util.LinkedHashMap.clone()
+ LinkedHashMap<String, String> hm1 = new LinkedHashMap<String, String>(10, 0.75f, true);
+ hm1.put("a", "a");
+ hm1.put("b", "b");
+ hm1.put("c", "c");
+ LinkedHashMap<String, String> hm2 = (LinkedHashMap<String, String>) hm1.clone();
+ hm1.get("a");
+
+ Map.Entry<String, String>[] set = new Map.Entry[3];
+ Iterator<Map.Entry<String,String>> iterator = hm1.entrySet().iterator();
+
+ assertEquals("b", iterator.next().getKey());
+ assertEquals("c", iterator.next().getKey());
+ assertEquals("a", iterator.next().getKey());
+
+ iterator = hm2.entrySet().iterator();
+ assertEquals("a", iterator.next().getKey());
+ assertEquals("b", iterator.next().getKey());
+ assertEquals("c", iterator.next().getKey());
+ }
+
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Regression test.",
diff --git a/libcore/luni/src/test/java/tests/api/java/util/PropertiesTest.java b/libcore/luni/src/test/java/tests/api/java/util/PropertiesTest.java
index f1024f6..ddf9994 100644
--- a/libcore/luni/src/test/java/tests/api/java/util/PropertiesTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/util/PropertiesTest.java
@@ -17,11 +17,10 @@
package tests.api.java.util;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -202,7 +201,6 @@
method = "load",
args = {java.io.InputStream.class}
)
- @KnownFailure("ToT fixed")
public void test_loadLjava_io_InputStream() throws IOException {
Properties prop = new Properties();
InputStream is = new ByteArrayInputStream(writeProperties());
@@ -389,14 +387,14 @@
method = "loadFromXML",
args = {java.io.InputStream.class}
)
- @KnownFailure("ToT fixed")
+ @KnownFailure("Expected Exception is not thrown.")
public void test_loadFromXMLLjava_io_InputStream() throws IOException {
Properties myProps = new Properties();
myProps.put("Property A", " aye\\\f\t\n\r\b");
myProps.put("Property B", "b ee#!=:");
myProps.put("Property C", "see");
-
Properties myProps2 = new Properties();
+
ByteArrayOutputStream out = new ByteArrayOutputStream();
myProps.storeToXML(out, "A Header");
out.close();
diff --git a/libcore/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java b/libcore/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
index d693ca3..480c998 100644
--- a/libcore/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
@@ -17,11 +17,11 @@
package tests.api.java.util;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.KnownFailure;
import java.io.File;
import java.net.MalformedURLException;
@@ -139,7 +139,9 @@
method = "getBundle",
args = {java.lang.String.class, java.util.Locale.class, java.lang.ClassLoader.class}
)
- @KnownFailure("ToT fixed")
+ @KnownFailure("It's not allowed to pass null as parent class loader to"
+ + " a new ClassLoader anymore. Maybe we need to change"
+ + " URLClassLoader to allow this? It's not specified.")
public void test_getBundleLjava_lang_StringLjava_util_LocaleLjava_lang_ClassLoader() {
String classPath = System.getProperty("java.class.path");
StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator);
diff --git a/libcore/luni/src/test/java/tests/api/java/util/StringTokenizerTest.java b/libcore/luni/src/test/java/tests/api/java/util/StringTokenizerTest.java
index a3ece6c..a7ba8da 100644
--- a/libcore/luni/src/test/java/tests/api/java/util/StringTokenizerTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/util/StringTokenizerTest.java
@@ -21,7 +21,6 @@
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.KnownFailure;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
@@ -238,7 +237,6 @@
method = "nextToken",
args = {java.lang.String.class}
)
- @KnownFailure("ToT fixed")
public void test_nextTokenLjava_lang_String() {
// Test for method java.lang.String
// java.util.StringTokenizer.nextToken(java.lang.String)
diff --git a/libcore/luni/src/test/java/tests/api/java/util/TimeZoneTest.java b/libcore/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
index 87a5e87..4637f10 100644
--- a/libcore/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
+++ b/libcore/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
@@ -61,7 +61,7 @@
method = "getDSTSavings",
args = {}
)
- @KnownFailure("method returns wrong time shift")
+ @KnownFailure("Might be a difference in data.")
public void test_getDSTSavings() {
// Test for method int java.util.TimeZone.getDSTSavings()
@@ -136,6 +136,7 @@
method = "getTimeZone",
args = {java.lang.String.class}
)
+ @KnownFailure("Android fails the last test.")
public void test_getTimeZoneLjava_lang_String() {
assertEquals("Must return GMT when given an invalid TimeZone id SMT-8.",
"GMT", TimeZone.getTimeZone("SMT-8").getID());
diff --git a/libcore/luni/src/test/resources/org/apache/harmony/luni/tests/java/lang/illegalClasses.jar b/libcore/luni/src/test/resources/org/apache/harmony/luni/tests/java/lang/illegalClasses.jar
new file mode 100644
index 0000000..4a5f4ef
--- /dev/null
+++ b/libcore/luni/src/test/resources/org/apache/harmony/luni/tests/java/lang/illegalClasses.jar
Binary files differ
diff --git a/libcore/luni/src/test/resources/tests/api/java/net/file1.cache b/libcore/luni/src/test/resources/tests/api/java/net/file1.cache
new file mode 100644
index 0000000..9245960
--- /dev/null
+++ b/libcore/luni/src/test/resources/tests/api/java/net/file1.cache
@@ -0,0 +1 @@
+Cache test
\ No newline at end of file
diff --git a/libcore/math/src/main/java/java/math/BigDecimal.java b/libcore/math/src/main/java/java/math/BigDecimal.java
index 93c095c..6fa1f34 100644
--- a/libcore/math/src/main/java/java/math/BigDecimal.java
+++ b/libcore/math/src/main/java/java/math/BigDecimal.java
@@ -38,7 +38,6 @@
/**
* The constant zero as a {@code BigDecimal}.
*
- * @since 1.2
* @since Android 1.0
*/
public static final BigDecimal ZERO = new BigDecimal(0, 0);
@@ -46,7 +45,6 @@
/**
* The constant one as a {@code BigDecimal}.
*
- * @since 1.2
* @since Android 1.0
*/
public static final BigDecimal ONE = new BigDecimal(1, 0);
@@ -54,7 +52,6 @@
/**
* The constant ten as a {@code BigDecimal}.
*
- * @since 1.5
* @since Android 1.0
*/
public static final BigDecimal TEN = new BigDecimal(10, 0);
diff --git a/libcore/math/src/main/java/java/math/BigInteger.java b/libcore/math/src/main/java/java/math/BigInteger.java
index cfe9818..aece078 100644
--- a/libcore/math/src/main/java/java/math/BigInteger.java
+++ b/libcore/math/src/main/java/java/math/BigInteger.java
@@ -152,7 +152,6 @@
/**
* The {@code BigInteger} constant 0.
*
- * @since 1.2
* @since Android 1.0
*/
public static final BigInteger ZERO = new BigInteger(0, 0);
@@ -160,7 +159,6 @@
/**
* The {@code BigInteger} constant 1.
*
- * @since 1.2
* @since Android 1.0
*/
public static final BigInteger ONE = new BigInteger(1, 1);
@@ -168,7 +166,6 @@
/**
* The {@code BigInteger} constant 10.
*
- * @since 1.5
* @since Android 1.0
*/
public static final BigInteger TEN = new BigInteger(1, 10);
diff --git a/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalArithmeticTest.java b/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalArithmeticTest.java
index b2375f8..3119131 100644
--- a/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalArithmeticTest.java
+++ b/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalArithmeticTest.java
@@ -231,7 +231,6 @@
method = "add",
args = {java.math.BigDecimal.class, java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.inplaceRound")
public void testAddMathContextNonTrivial() {
MathContext mc;
BigDecimal a, b, res;
@@ -432,7 +431,6 @@
method = "subtract",
args = {java.math.BigDecimal.class, java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.inplaceRound")
public void testSubtractMathContextNonTrivial() {
MathContext mc;
BigDecimal a, b, res;
@@ -629,7 +627,6 @@
method = "multiply",
args = {java.math.BigDecimal.class, java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.inplaceRound")
public void testMultiplyMathContextNonTrivial() {
MathContext mc;
BigDecimal a, b, res;
@@ -767,7 +764,6 @@
method = "pow",
args = {int.class, java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.inplaceRound")
public void testPowMathContextNonTrivial() {
MathContext mc;
BigDecimal a, b, res;
@@ -912,7 +908,6 @@
method = "divide",
args = {java.math.BigDecimal.class, int.class}
)
- @KnownFailure("Fix in BigDecimal.inplaceRound")
public void testDivideINonTrivial() {
MathContext mc;
BigDecimal a, b, res;
@@ -1820,7 +1815,9 @@
method = "divide",
args = {java.math.BigDecimal.class, int.class, java.math.RoundingMode.class}
)
- @KnownFailure("Fix in BigDecimal.inplaceRound IS INSUFFICIENT!!!")
+ @KnownFailure("Has a rounding problem. seems like the precision is"
+ + " 1 too small and cuts off the last digit. also this test might"
+ + "not be correct. The name implies that scale should be used.")
public void testDivideScaleRoundingModeNonTrivial() {
MathContext mc;
BigDecimal a, b, res;
@@ -2041,7 +2038,8 @@
method = "divide",
args = {java.math.BigDecimal.class, java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.inplaceRound IS INSUFFICIENT!!!")
+ @KnownFailure("The same test and the same problem like "
+ + "testDivideScaleRoundingModeNonTrivial")
public void testDivideMathContextNonTrivial() {
MathContext mc;
BigDecimal a, b, res;
@@ -2196,7 +2194,6 @@
method = "divideToIntegralValue",
args = {java.math.BigDecimal.class, java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.inplaceRound")
public void testDivideToIntegralValueMathContextNonTrivial() {
MathContext mc;
BigDecimal a, b, res;
@@ -2382,7 +2379,6 @@
method = "divideAndRemainder",
args = {java.math.BigDecimal.class, java.math.MathContext.class}
)
- @KnownFailure("WHY ISN'T THE LAST VALUE ROUNDED?")
public void testDivideAndRemainderMathContextNonTrivial() {
MathContext mc;
BigDecimal a, b, res[];
@@ -2542,7 +2538,6 @@
method = "remainder",
args = {java.math.BigDecimal.class, java.math.MathContext.class}
)
- @KnownFailure("WHY ISN'T THE LAST VALUE ROUNDED?")
public void testRemainderMathContextNonTrivial() {
MathContext mc;
BigDecimal a, b, res;
diff --git a/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalCompareTest.java b/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalCompareTest.java
index a1b3202..97e8a5d 100644
--- a/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalCompareTest.java
+++ b/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalCompareTest.java
@@ -21,7 +21,6 @@
package org.apache.harmony.math.tests.java.math;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -80,7 +79,6 @@
method = "abs",
args = {java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.abs")
public void testAbsMathContextNeg() {
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
BigDecimal aNumber = new BigDecimal(a);
@@ -628,7 +626,6 @@
method = "negate",
args = {java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.negate")
public void testNegateMathContextPositive() {
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
MathContext mc = new MathContext(37, RoundingMode.FLOOR);
@@ -678,7 +675,6 @@
method = "negate",
args = {java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.negate")
public void testNegateMathContextNegative() {
String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
int aScale = 49;
diff --git a/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConstructorsTest.java b/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConstructorsTest.java
index a428c9f..74d0cb0 100644
--- a/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConstructorsTest.java
+++ b/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConstructorsTest.java
@@ -21,7 +21,6 @@
package org.apache.harmony.math.tests.java.math;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -374,7 +373,6 @@
method = "BigDecimal",
args = {java.math.BigInteger.class, int.class, java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.inplaceRound")
public void testConstrBigIntegerScaleMathContext_AndroidFailure() {
MathContext mc;
BigDecimal bd;
@@ -802,7 +800,6 @@
method = "BigDecimal",
args = {double.class, java.math.MathContext.class}
)
- @KnownFailure("Fix in BigDecimal.inplaceRound")
public void testConstrDoubleMathContext_AndroidFailure() {
BigDecimal bd;
MathContext mc;
diff --git a/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalScaleOperationsTest.java b/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalScaleOperationsTest.java
index 3444a27..17c9a26 100644
--- a/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalScaleOperationsTest.java
+++ b/libcore/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalScaleOperationsTest.java
@@ -529,7 +529,7 @@
method = "movePointRight",
args = {int.class}
)
- @KnownFailure("Throws ArrayIndexOutOfBoundsException instead of ArithmeticException!")
+ @KnownFailure("Throws OutOfMemoryError instead of ArithmeticException!")
public void testMovePointRightEx2() {
BigDecimal a = new BigDecimal("123456789012345678901234567890123456789E25");
try {
diff --git a/libcore/math/src/test/java/tests/api/java/math/BigDecimalTest.java b/libcore/math/src/test/java/tests/api/java/math/BigDecimalTest.java
index 32c9e84..47e5b31 100644
--- a/libcore/math/src/test/java/tests/api/java/math/BigDecimalTest.java
+++ b/libcore/math/src/test/java/tests/api/java/math/BigDecimalTest.java
@@ -21,6 +21,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.AndroidOnly;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -1287,10 +1288,11 @@
*/
@TestTargetNew(
level = TestLevel.PARTIAL,
- notes = "SUN JDK fails the Zero Test: has scale 4 for BigDecimal('0.0000')",
+ notes = "The RI fails the Zero Test: has scale 4 for BigDecimal('0.0000')",
method = "stripTrailingZeros",
args = {}
)
+ @AndroidOnly("Stripping trailing zeroes from 0.000 value doesn't work on RI. See below")
public void test_stripTrailingZero() {
BigDecimal sixhundredtest = new BigDecimal("600.0");
assertTrue("stripTrailingZero failed for 600.0",
diff --git a/libcore/nio/src/main/java/java/nio/MappedByteBufferAdapter.java b/libcore/nio/src/main/java/java/nio/MappedByteBufferAdapter.java
index a3f5d7e..83a51c1 100644
--- a/libcore/nio/src/main/java/java/nio/MappedByteBufferAdapter.java
+++ b/libcore/nio/src/main/java/java/nio/MappedByteBufferAdapter.java
@@ -17,6 +17,7 @@
// BEGIN android-note
// updated to a newer version of harmony
+// added some missing updates on position and limit
// END android-note
package java.nio;
@@ -105,32 +106,44 @@
}
public byte get() {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
byte result = this.wrapped.get();
this.position++;
return result;
}
public byte get(int index) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
return this.wrapped.get(index);
}
public char getChar() {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
char result = this.wrapped.getChar();
this.position += CHAR_SIZE;
return result;
}
public char getChar(int index) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
return this.wrapped.getChar(index);
}
public double getDouble() {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
double result = this.wrapped.getDouble();
this.position += DOUBLE_SIZE;
return result;
}
public double getDouble(int index) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
return this.wrapped.getDouble(index);
}
@@ -139,42 +152,58 @@
}
public float getFloat() {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
float result = this.wrapped.getFloat();
this.position += FLOAT_SIZE;
return result;
}
public float getFloat(int index) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
return this.wrapped.getFloat(index);
}
public int getInt() {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
int result = this.wrapped.getInt();
this.position += INTEGER_SIZE;
return result;
}
public int getInt(int index) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
return this.wrapped.getInt(index);
}
public long getLong() {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
long result = this.wrapped.getLong();
this.position += LONG_SIZE;
return result;
}
public long getLong(int index) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
return this.wrapped.getLong(index);
}
public short getShort() {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
short result = this.wrapped.getShort();
this.position += SHORT_SIZE;
return result;
}
public short getShort(int index) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
return this.wrapped.getShort(index);
}
@@ -192,12 +221,15 @@
}
public ByteBuffer put(byte b) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.put(b);
this.position++;
return this;
}
public ByteBuffer put(byte[] src, int off, int len) {
+ this.wrapped.limit(this.limit);
this.wrapped.position(this.position);
this.wrapped.put(src, off, len);
this.position += len;
@@ -205,71 +237,97 @@
}
public ByteBuffer put(int index, byte b) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.put(index, b);
return this;
}
public ByteBuffer putChar(char value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putChar(value);
this.position += CHAR_SIZE;
return this;
}
public ByteBuffer putChar(int index, char value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putChar(index, value);
return this;
}
public ByteBuffer putDouble(double value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putDouble(value);
this.position += DOUBLE_SIZE;
return this;
}
public ByteBuffer putDouble(int index, double value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putDouble(index, value);
return this;
}
public ByteBuffer putFloat(float value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putFloat(value);
this.position += FLOAT_SIZE;
return this;
}
public ByteBuffer putFloat(int index, float value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putFloat(index, value);
return this;
}
public ByteBuffer putInt(int index, int value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putInt(index, value);
return this;
}
public ByteBuffer putInt(int value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putInt(value);
this.position += INTEGER_SIZE;
return this;
}
public ByteBuffer putLong(int index, long value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putLong(index, value);
return this;
}
public ByteBuffer putLong(long value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putLong(value);
this.position += LONG_SIZE;
return this;
}
public ByteBuffer putShort(int index, short value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putShort(index, value);
return this;
}
public ByteBuffer putShort(short value) {
+ this.wrapped.limit(this.limit);
+ this.wrapped.position(this.position);
this.wrapped.putShort(value);
this.position += SHORT_SIZE;
return this;
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AbstractBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AbstractBufferTest.java
index 901a2a6..d0fc537 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AbstractBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AbstractBufferTest.java
@@ -30,7 +30,7 @@
* Tests a java.nio.Buffer instance.
*/
@TestTargetClass(java.nio.Buffer.class)
-public class AbstractBufferTest extends TestCase {
+public abstract class AbstractBufferTest extends TestCase {
protected Buffer baseBuf;
protected int capacity;
@@ -139,9 +139,7 @@
method = "isReadOnly",
args = {}
)
- public void testIsReadOnly() {
- baseBuf.isReadOnly();
- }
+ public abstract void testIsReadOnly();
/*
* Class under test for int limit()
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AllTests.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AllTests.java
index 6528c22..6bf13f1 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AllTests.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AllTests.java
@@ -33,69 +33,61 @@
public static Test suite() {
TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.nio");
//$JUnit-BEGIN$
- suite.addTestSuite(ReadOnlyHeapShortBufferTest.class);
- suite.addTestSuite(ReadOnlyLongBufferTest.class);
suite.addTestSuite(BufferOverflowExceptionTest.class);
- suite.addTestSuite(CharBufferTest.class);
- suite.addTestSuite(DirectShortBufferTest.class);
- suite.addTestSuite(ReadOnlyHeapIntBufferTest.class);
- suite.addTestSuite(HeapIntBufferTest.class);
- suite.addTestSuite(WrappedDoubleBufferTest.class);
- suite.addTestSuite(WrappedCharBufferTest2.class);
- suite.addTestSuite(HeapLongBufferTest.class);
+ suite.addTestSuite(BufferUnderflowExceptionTest.class);
suite.addTestSuite(ByteOrderTest.class);
- suite.addTestSuite(ReadOnlyFloatBufferTest.class);
- suite.addTestSuite(WrappedFloatBufferTest.class);
- suite.addTestSuite(DirectLongBufferTest.class);
- suite.addTestSuite(ReadOnlyWrappedByteBufferTest.class);
- suite.addTestSuite(ReadOnlyWrappedLongBufferTest.class);
- suite.addTestSuite(HeapFloatBufferTest.class);
- suite.addTestSuite(WrappedCharBufferTest1.class);
- suite.addTestSuite(WrappedShortBufferTest.class);
- suite.addTestSuite(ReadOnlyWrappedIntBufferTest.class);
- suite.addTestSuite(AbstractBufferTest.class);
- suite.addTestSuite(ReadOnlyCharBufferTest.class);
- suite.addTestSuite(SliceHeapByteBufferTest.class);
- suite.addTestSuite(LongBufferTest.class);
- suite.addTestSuite(DuplicateWrappedByteBufferTest.class);
- suite.addTestSuite(FloatBufferTest.class);
- suite.addTestSuite(ReadOnlyHeapCharBufferTest.class);
- suite.addTestSuite(WrappedLongBufferTest.class);
- suite.addTestSuite(ReadOnlyWrappedShortBufferTest.class);
- suite.addTestSuite(ByteBufferTest.class);
- suite.addTestSuite(ReadOnlyBufferExceptionTest.class);
- suite.addTestSuite(ReadOnlyDirectByteBufferTest.class);
- suite.addTestSuite(ReadOnlyHeapDoubleBufferTest.class);
- suite.addTestSuite(ReadOnlyShortBufferTest.class);
- suite.addTestSuite(DoubleBufferTest.class);
- suite.addTestSuite(ReadOnlyWrappedFloatBufferTest.class);
- suite.addTestSuite(ShortBufferTest.class);
- suite.addTestSuite(DirectFloatBufferTest.class);
- suite.addTestSuite(SliceWrappedByteBufferTest.class);
+ suite.addTestSuite(DirectByteBufferTest.class);
suite.addTestSuite(DirectCharBufferTest.class);
- suite.addTestSuite(SliceDirectByteBufferTest.class);
- suite.addTestSuite(ReadOnlyHeapLongBufferTest.class);
+ suite.addTestSuite(DirectDoubleBufferTest.class);
+ suite.addTestSuite(DirectFloatBufferTest.class);
suite.addTestSuite(DirectIntBufferTest.class);
- suite.addTestSuite(HeapByteBufferTest.class);
- suite.addTestSuite(ReadOnlyWrappedDoubleBufferTest.class);
+ suite.addTestSuite(DirectLongBufferTest.class);
+ suite.addTestSuite(DirectShortBufferTest.class);
+ suite.addTestSuite(DuplicateDirectByteBufferTest.class);
suite.addTestSuite(DuplicateHeapByteBufferTest.class);
+ suite.addTestSuite(DuplicateWrappedByteBufferTest.class);
+ suite.addTestSuite(HeapByteBufferTest.class);
+ suite.addTestSuite(HeapCharBufferTest.class);
+ suite.addTestSuite(HeapDoubleBufferTest.class);
+ suite.addTestSuite(HeapFloatBufferTest.class);
+ suite.addTestSuite(HeapIntBufferTest.class);
+ suite.addTestSuite(HeapLongBufferTest.class);
suite.addTestSuite(HeapShortBufferTest.class);
suite.addTestSuite(InvalidMarkExceptionTest.class);
- suite.addTestSuite(DirectDoubleBufferTest.class);
- suite.addTestSuite(ReadOnlyHeapByteBufferTest.class);
- suite.addTestSuite(ReadOnlyIntBufferTest.class);
- suite.addTestSuite(HeapDoubleBufferTest.class);
- suite.addTestSuite(DirectByteBufferTest.class);
- suite.addTestSuite(ReadOnlyWrappedCharBufferTest1.class);
- suite.addTestSuite(IntBufferTest.class);
- suite.addTestSuite(ReadOnlyDoubleBufferTest.class);
- suite.addTestSuite(ReadOnlyHeapFloatBufferTest.class);
- suite.addTestSuite(WrappedByteBufferTest.class);
- suite.addTestSuite(BufferUnderflowExceptionTest.class);
- suite.addTestSuite(DuplicateDirectByteBufferTest.class);
- suite.addTestSuite(WrappedIntBufferTest.class);
- suite.addTestSuite(HeapCharBufferTest.class);
suite.addTestSuite(MappedByteBufferTest.class);
+ suite.addTestSuite(ReadOnlyBufferExceptionTest.class);
+ suite.addTestSuite(ReadOnlyCharBufferTest.class);
+ suite.addTestSuite(ReadOnlyDirectByteBufferTest.class);
+ suite.addTestSuite(ReadOnlyDoubleBufferTest.class);
+ suite.addTestSuite(ReadOnlyFloatBufferTest.class);
+ suite.addTestSuite(ReadOnlyHeapByteBufferTest.class);
+ suite.addTestSuite(ReadOnlyHeapCharBufferTest.class);
+ suite.addTestSuite(ReadOnlyHeapDoubleBufferTest.class);
+ suite.addTestSuite(ReadOnlyHeapFloatBufferTest.class);
+ suite.addTestSuite(ReadOnlyHeapIntBufferTest.class);
+ suite.addTestSuite(ReadOnlyHeapLongBufferTest.class);
+ suite.addTestSuite(ReadOnlyHeapShortBufferTest.class);
+ suite.addTestSuite(ReadOnlyIntBufferTest.class);
+ suite.addTestSuite(ReadOnlyLongBufferTest.class);
+ suite.addTestSuite(ReadOnlyShortBufferTest.class);
+ suite.addTestSuite(ReadOnlyWrappedByteBufferTest.class);
+ suite.addTestSuite(ReadOnlyWrappedCharBufferTest1.class);
+ suite.addTestSuite(ReadOnlyWrappedDoubleBufferTest.class);
+ suite.addTestSuite(ReadOnlyWrappedFloatBufferTest.class);
+ suite.addTestSuite(ReadOnlyWrappedIntBufferTest.class);
+ suite.addTestSuite(ReadOnlyWrappedLongBufferTest.class);
+ suite.addTestSuite(ReadOnlyWrappedShortBufferTest.class);
+ suite.addTestSuite(SliceDirectByteBufferTest.class);
+ suite.addTestSuite(SliceHeapByteBufferTest.class);
+ suite.addTestSuite(SliceWrappedByteBufferTest.class);
+ suite.addTestSuite(WrappedByteBufferTest.class);
+ suite.addTestSuite(WrappedCharBufferTest1.class);
+ suite.addTestSuite(WrappedCharBufferTest2.class);
+ suite.addTestSuite(WrappedDoubleBufferTest.class);
+ suite.addTestSuite(WrappedFloatBufferTest.class);
+ suite.addTestSuite(WrappedIntBufferTest.class);
+ suite.addTestSuite(WrappedLongBufferTest.class);
+ suite.addTestSuite(WrappedShortBufferTest.class);
//$JUnit-END$
return suite;
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteBufferTest.java
index 8bf0208..acc2c6e 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteBufferTest.java
@@ -20,6 +20,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.AndroidOnly;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
@@ -40,20 +41,23 @@
*
*/
@TestTargetClass(ByteBuffer.class)
-public class ByteBufferTest extends AbstractBufferTest {
+public abstract class ByteBufferTest extends AbstractBufferTest {
protected static final int SMALL_TEST_LENGTH = 5;
protected static final int BUFFER_LENGTH = 250;
protected ByteBuffer buf;
protected void setUp() throws Exception {
- capacity = 10;
- buf = ByteBuffer.allocate(10);
+ capacity = BUFFER_LENGTH;
+ buf = ByteBuffer.allocate(BUFFER_LENGTH);
+ loadTestData1(buf);
baseBuf = buf;
}
protected void tearDown() throws Exception {
super.tearDown();
+ buf = null;
+ baseBuf = null;
}
/*
@@ -192,6 +196,7 @@
args = {}
)
public void testAsReadOnlyBuffer() {
+ loadTestData1(buf);
buf.clear();
buf.mark();
buf.position(buf.limit());
@@ -221,6 +226,7 @@
method = "compact",
args = {}
)
+ @AndroidOnly("Fails on RI. See comment below")
public void testCompact() {
if (buf.isReadOnly()) {
try {
@@ -242,6 +248,9 @@
assertEquals(buf.capacity(), buf.limit());
assertContentLikeTestData1(buf, 0, (byte) 0, buf.capacity());
try {
+ // Fails on RI. Spec doesn't specify the behavior if
+ // actually nothing to be done by compact(). So RI doesn't reset
+ // mark position
buf.reset();
fail("Should throw Exception"); //$NON-NLS-1$
} catch (InvalidMarkException e) {
@@ -361,6 +370,8 @@
args = {java.lang.Object.class}
)
public void testEquals() {
+ loadTestData1(buf);
+
// equal to self
assertTrue(buf.equals(buf));
ByteBuffer readonly = buf.asReadOnlyBuffer();
@@ -380,6 +391,10 @@
buf.limit(buf.capacity() - 1).position(0);
duplicate.limit(duplicate.capacity()).position(0);
assertFalse(buf.equals(duplicate));
+
+ buf.limit(buf.capacity() - 1).position(0);
+ duplicate.limit(duplicate.capacity()).position(1);
+ assertFalse(buf.equals(duplicate));
}
/*
@@ -392,6 +407,7 @@
args = {}
)
public void testGet() {
+ loadTestData1(buf);
buf.clear();
for (int i = 0; i < buf.capacity(); i++) {
assertEquals(i, buf.position());
@@ -416,6 +432,7 @@
)
public void testGetbyteArray() {
byte array[] = new byte[1];
+ loadTestData1(buf);
buf.clear();
for (int i = 0; i < buf.capacity(); i++) {
assertEquals(i, buf.position());
@@ -451,6 +468,7 @@
args = {byte[].class, int.class, int.class}
)
public void testGetbyteArrayintint() {
+ loadTestData1(buf);
buf.clear();
byte array[] = new byte[buf.capacity()];
@@ -524,6 +542,7 @@
args = {int.class}
)
public void testGetint() {
+ loadTestData1(buf);
buf.clear();
for (int i = 0; i < buf.capacity(); i++) {
assertEquals(i, buf.position());
@@ -545,24 +564,13 @@
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
+ notes = "Verifies hasArray method for wrapped ByteBuffer.",
method = "hasArray",
args = {}
)
public void testHasArray() {
- if (buf.hasArray()) {
- assertNotNull(buf.array());
- } else {
- try {
- buf.array();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- // expected
- // Note:can not tell when to catch
- // UnsupportedOperationException or
- // ReadOnlyBufferException, so catch all.
- }
- }
+ assertTrue(buf.hasArray());
+ assertNotNull(buf.array());
}
@TestTargetNew(
@@ -603,12 +611,22 @@
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
- notes = "Abstract method.",
+ notes = "Verifies isDirect method with not direct buffer.",
method = "isDirect",
args = {}
)
public void testIsDirect() {
- buf.isDirect();
+ assertFalse(buf.isDirect());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "isReadOnly",
+ args = {}
+ )
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
}
@TestTargetNew(
@@ -943,6 +961,7 @@
args = {}
)
public void testSlice() {
+ loadTestData1(buf);
assertTrue(buf.capacity() > SMALL_TEST_LENGTH);
buf.position(1);
buf.limit(buf.capacity() - 1);
@@ -994,6 +1013,7 @@
CharBuffer charBuffer;
byte bytes[] = new byte[2];
char value;
+ loadTestData1(buf);
// test BIG_ENDIAN char buffer, read
buf.clear();
@@ -1056,6 +1076,7 @@
DoubleBuffer doubleBuffer;
byte bytes[] = new byte[8];
double value;
+ loadTestData1(buf);
// test BIG_ENDIAN double buffer, read
buf.clear();
@@ -1092,7 +1113,7 @@
doubleBuffer = buf.asDoubleBuffer();
assertSame(ByteOrder.BIG_ENDIAN, doubleBuffer.order());
while (doubleBuffer.remaining() > 0) {
- value = (double) doubleBuffer.remaining();
+ value = doubleBuffer.remaining();
doubleBuffer.put(value);
buf.get(bytes);
assertTrue(Arrays.equals(bytes, double2bytes(value, buf.order())));
@@ -1104,7 +1125,7 @@
doubleBuffer = buf.asDoubleBuffer();
assertSame(ByteOrder.LITTLE_ENDIAN, doubleBuffer.order());
while (doubleBuffer.remaining() > 0) {
- value = (double) doubleBuffer.remaining();
+ value = doubleBuffer.remaining();
doubleBuffer.put(value);
buf.get(bytes);
assertTrue(Arrays.equals(bytes, double2bytes(value, buf.order())));
@@ -1125,6 +1146,7 @@
FloatBuffer floatBuffer;
byte bytes[] = new byte[4];
float value;
+ loadTestData1(buf);
// test BIG_ENDIAN float buffer, read
buf.clear();
@@ -1161,7 +1183,7 @@
floatBuffer = buf.asFloatBuffer();
assertSame(ByteOrder.BIG_ENDIAN, floatBuffer.order());
while (floatBuffer.remaining() > 0) {
- value = (float) floatBuffer.remaining();
+ value = floatBuffer.remaining();
floatBuffer.put(value);
buf.get(bytes);
assertTrue(Arrays.equals(bytes, float2bytes(value, buf.order())));
@@ -1173,7 +1195,7 @@
floatBuffer = buf.asFloatBuffer();
assertSame(ByteOrder.LITTLE_ENDIAN, floatBuffer.order());
while (floatBuffer.remaining() > 0) {
- value = (float) floatBuffer.remaining();
+ value = floatBuffer.remaining();
floatBuffer.put(value);
buf.get(bytes);
assertTrue(Arrays.equals(bytes, float2bytes(value, buf.order())));
@@ -1194,6 +1216,7 @@
IntBuffer intBuffer;
byte bytes[] = new byte[4];
int value;
+ loadTestData1(buf);
// test BIG_ENDIAN int buffer, read
buf.clear();
@@ -1224,7 +1247,7 @@
intBuffer = buf.asIntBuffer();
assertSame(ByteOrder.BIG_ENDIAN, intBuffer.order());
while (intBuffer.remaining() > 0) {
- value = (int) intBuffer.remaining();
+ value = intBuffer.remaining();
intBuffer.put(value);
buf.get(bytes);
assertTrue(Arrays.equals(bytes, int2bytes(value, buf.order())));
@@ -1236,7 +1259,7 @@
intBuffer = buf.asIntBuffer();
assertSame(ByteOrder.LITTLE_ENDIAN, intBuffer.order());
while (intBuffer.remaining() > 0) {
- value = (int) intBuffer.remaining();
+ value = intBuffer.remaining();
intBuffer.put(value);
buf.get(bytes);
assertTrue(Arrays.equals(bytes, int2bytes(value, buf.order())));
@@ -1257,6 +1280,7 @@
LongBuffer longBuffer;
byte bytes[] = new byte[8];
long value;
+ loadTestData1(buf);
// test BIG_ENDIAN long buffer, read
buf.clear();
@@ -1287,7 +1311,7 @@
longBuffer = buf.asLongBuffer();
assertSame(ByteOrder.BIG_ENDIAN, longBuffer.order());
while (longBuffer.remaining() > 0) {
- value = (long) longBuffer.remaining();
+ value = longBuffer.remaining();
longBuffer.put(value);
buf.get(bytes);
assertTrue(Arrays.equals(bytes, long2bytes(value, buf.order())));
@@ -1299,7 +1323,7 @@
longBuffer = buf.asLongBuffer();
assertSame(ByteOrder.LITTLE_ENDIAN, longBuffer.order());
while (longBuffer.remaining() > 0) {
- value = (long) longBuffer.remaining();
+ value = longBuffer.remaining();
longBuffer.put(value);
buf.get(bytes);
assertTrue(Arrays.equals(bytes, long2bytes(value, buf.order())));
@@ -1320,6 +1344,7 @@
ShortBuffer shortBuffer;
byte bytes[] = new byte[2];
short value;
+ loadTestData1(buf);
// test BIG_ENDIAN short buffer, read
buf.clear();
@@ -1383,6 +1408,8 @@
int nbytes = 2;
byte bytes[] = new byte[nbytes];
char value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; buf.remaining() >= nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -1415,6 +1442,8 @@
int nbytes = 2;
byte bytes[] = new byte[nbytes];
char value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; i <= buf.limit() - nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -1473,7 +1502,8 @@
assertEquals((i + 1) * nbytes, buf.position());
buf.reset();
buf.get(bytes);
- assertTrue(Arrays.equals(char2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(char2bytes(value, buf.order()), bytes));
}
try {
@@ -1522,7 +1552,8 @@
buf.putChar(i, value);
assertEquals(i, buf.position());
buf.get(bytes);
- assertTrue(Arrays.equals(char2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(char2bytes(value, buf.order()), bytes));
}
try {
@@ -1562,6 +1593,8 @@
int nbytes = 8;
byte bytes[] = new byte[nbytes];
double value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; buf.remaining() >= nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -1597,6 +1630,8 @@
int nbytes = 8;
byte bytes[] = new byte[nbytes];
double value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; i <= buf.limit() - nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -1643,7 +1678,7 @@
if (buf.isReadOnly()) {
try {
buf.clear();
- buf.putDouble((double) 1);
+ buf.putDouble(1);
fail("Should throw Exception"); //$NON-NLS-1$
} catch (ReadOnlyBufferException e) {
// expected
@@ -1658,13 +1693,14 @@
for (int i = 0; buf.remaining() >= nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
: ByteOrder.LITTLE_ENDIAN);
- value = (double) i;
+ value = i;
buf.mark();
buf.putDouble(value);
assertEquals((i + 1) * nbytes, buf.position());
buf.reset();
buf.get(bytes);
- assertTrue(Arrays.equals(double2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(double2bytes(value, buf.order()), bytes));
}
try {
@@ -1702,7 +1738,7 @@
public void testPutDoubleint() {
if (buf.isReadOnly()) {
try {
- buf.putDouble(0, (double) 1);
+ buf.putDouble(0, 1);
fail("Should throw Exception"); //$NON-NLS-1$
} catch (ReadOnlyBufferException e) {
// expected
@@ -1717,12 +1753,13 @@
for (int i = 0; i <= buf.limit() - nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
: ByteOrder.LITTLE_ENDIAN);
- value = (double) i;
+ value = i;
buf.position(i);
buf.putDouble(i, value);
assertEquals(i, buf.position());
buf.get(bytes);
- assertTrue(Arrays.equals(double2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(double2bytes(value, buf.order()), bytes));
}
try {
@@ -1762,6 +1799,8 @@
int nbytes = 4;
byte bytes[] = new byte[nbytes];
float value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; buf.remaining() >= nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -1797,6 +1836,8 @@
int nbytes = 4;
byte bytes[] = new byte[nbytes];
float value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; i <= buf.limit() - nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -1837,7 +1878,7 @@
if (buf.isReadOnly()) {
try {
buf.clear();
- buf.putFloat((float) 1);
+ buf.putFloat(1);
fail("Should throw Exception"); //$NON-NLS-1$
} catch (ReadOnlyBufferException e) {
// expected
@@ -1852,13 +1893,14 @@
for (int i = 0; buf.remaining() >= nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
: ByteOrder.LITTLE_ENDIAN);
- value = (float) i;
+ value = i;
buf.mark();
buf.putFloat(value);
assertEquals((i + 1) * nbytes, buf.position());
buf.reset();
buf.get(bytes);
- assertTrue(Arrays.equals(float2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(float2bytes(value, buf.order()), bytes));
}
try {
@@ -1896,7 +1938,7 @@
public void testPutFloatint() {
if (buf.isReadOnly()) {
try {
- buf.putFloat(0, (float) 1);
+ buf.putFloat(0, 1);
fail("Should throw Exception"); //$NON-NLS-1$
} catch (ReadOnlyBufferException e) {
// expected
@@ -1911,12 +1953,13 @@
for (int i = 0; i <= buf.limit() - nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
: ByteOrder.LITTLE_ENDIAN);
- value = (float) i;
+ value = i;
buf.position(i);
buf.putFloat(i, value);
assertEquals(i, buf.position());
buf.get(bytes);
- assertTrue(Arrays.equals(float2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(float2bytes(value, buf.order()), bytes));
}
try {
@@ -1956,6 +1999,8 @@
int nbytes = 4;
byte bytes[] = new byte[nbytes];
int value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; buf.remaining() >= nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -1988,6 +2033,8 @@
int nbytes = 4;
byte bytes[] = new byte[nbytes];
int value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; i <= buf.limit() - nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -2030,7 +2077,7 @@
if (buf.isReadOnly()) {
try {
buf.clear();
- buf.putInt((int) 1);
+ buf.putInt(1);
fail("Should throw Exception"); //$NON-NLS-1$
} catch (ReadOnlyBufferException e) {
// expected
@@ -2045,13 +2092,14 @@
for (int i = 0; buf.remaining() >= nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
: ByteOrder.LITTLE_ENDIAN);
- value = (int) i;
+ value = i;
buf.mark();
buf.putInt(value);
assertEquals((i + 1) * nbytes, buf.position());
buf.reset();
buf.get(bytes);
- assertTrue(Arrays.equals(int2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(int2bytes(value, buf.order()), bytes));
}
try {
@@ -2080,7 +2128,7 @@
public void testPutIntint() {
if (buf.isReadOnly()) {
try {
- buf.putInt(0, (int) 1);
+ buf.putInt(0, 1);
fail("Should throw Exception"); //$NON-NLS-1$
} catch (ReadOnlyBufferException e) {
// expected
@@ -2095,12 +2143,13 @@
for (int i = 0; i <= buf.limit() - nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
: ByteOrder.LITTLE_ENDIAN);
- value = (int) i;
+ value = i;
buf.position(i);
buf.putInt(i, value);
assertEquals(i, buf.position());
buf.get(bytes);
- assertTrue(Arrays.equals(int2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(int2bytes(value, buf.order()), bytes));
}
try {
@@ -2134,6 +2183,8 @@
int nbytes = 8;
byte bytes[] = new byte[nbytes];
long value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; buf.remaining() >= nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -2166,6 +2217,8 @@
int nbytes = 8;
byte bytes[] = new byte[nbytes];
long value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; i <= buf.limit() - nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -2203,7 +2256,7 @@
if (buf.isReadOnly()) {
try {
buf.clear();
- buf.putLong((long) 1);
+ buf.putLong(1);
fail("Should throw Exception"); //$NON-NLS-1$
} catch (ReadOnlyBufferException e) {
// expected
@@ -2218,13 +2271,14 @@
for (int i = 0; buf.remaining() >= nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
: ByteOrder.LITTLE_ENDIAN);
- value = (long) i;
+ value = i;
buf.mark();
buf.putLong(value);
assertEquals((i + 1) * nbytes, buf.position());
buf.reset();
buf.get(bytes);
- assertTrue(Arrays.equals(long2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(long2bytes(value, buf.order()), bytes));
}
try {
@@ -2253,7 +2307,7 @@
public void testPutLongint() {
if (buf.isReadOnly()) {
try {
- buf.putLong(0, (long) 1);
+ buf.putLong(0, 1);
fail("Should throw Exception"); //$NON-NLS-1$
} catch (ReadOnlyBufferException e) {
// expected
@@ -2268,12 +2322,13 @@
for (int i = 0; i <= buf.limit() - nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
: ByteOrder.LITTLE_ENDIAN);
- value = (long) i;
+ value = i;
buf.position(i);
buf.putLong(i, value);
assertEquals(i, buf.position());
buf.get(bytes);
- assertTrue(Arrays.equals(long2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(long2bytes(value, buf.order()), bytes));
}
try {
@@ -2307,6 +2362,8 @@
int nbytes = 2;
byte bytes[] = new byte[nbytes];
short value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; buf.remaining() >= nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -2339,6 +2396,8 @@
int nbytes = 2;
byte bytes[] = new byte[nbytes];
short value;
+ loadTestData1(buf);
+
buf.clear();
for (int i = 0; i <= buf.limit() - nbytes; i++) {
buf.order(i % 2 == 0 ? ByteOrder.BIG_ENDIAN
@@ -2397,7 +2456,8 @@
assertEquals((i + 1) * nbytes, buf.position());
buf.reset();
buf.get(bytes);
- assertTrue(Arrays.equals(short2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(short2bytes(value, buf.order()), bytes));
}
try {
@@ -2446,7 +2506,8 @@
buf.putShort(i, value);
assertEquals(i, buf.position());
buf.get(bytes);
- assertTrue(Arrays.equals(short2bytes(value, buf.order()), bytes));
+ assertTrue("Wrong value at " + i,
+ Arrays.equals(short2bytes(value, buf.order()), bytes));
}
try {
@@ -2569,26 +2630,29 @@
}
}
- private void loadTestData1(byte array[], int offset, int length) {
+ protected void loadTestData1(byte array[], int offset, int length) {
for (int i = 0; i < length; i++) {
array[offset + i] = (byte) i;
}
}
- private void loadTestData2(byte array[], int offset, int length) {
+ protected void loadTestData2(byte array[], int offset, int length) {
for (int i = 0; i < length; i++) {
array[offset + i] = (byte) (length - i);
}
}
- private void loadTestData1(ByteBuffer buf) {
+ protected void loadTestData1(ByteBuffer buf) {
+ if (buf.isReadOnly()) {
+ return;
+ }
buf.clear();
for (int i = 0; i < buf.capacity(); i++) {
buf.put(i, (byte) i);
}
}
- private void loadTestData2(ByteBuffer buf) {
+ protected void loadTestData2(ByteBuffer buf) {
buf.clear();
for (int i = 0; i < buf.capacity(); i++) {
buf.put(i, (byte) (buf.capacity() - i));
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java
index 21d96a5..b3e866c 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/CharBufferTest.java
@@ -21,6 +21,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.AndroidOnly;
import java.io.IOException;
import java.nio.BufferOverflowException;
@@ -35,7 +36,7 @@
*
*/
@TestTargetClass(CharBuffer.class)
-public class CharBufferTest extends AbstractBufferTest {
+public abstract class CharBufferTest extends AbstractBufferTest {
protected static final int SMALL_TEST_LENGTH = 5;
protected static final int BUFFER_LENGTH = 20;
@@ -203,6 +204,7 @@
method = "compact",
args = {}
)
+ @AndroidOnly("fails on RI. See comment below")
public void testCompact() {
// case: buffer is full
buf.clear();
@@ -230,6 +232,8 @@
assertEquals(buf.limit(), buf.capacity());
assertContentLikeTestData1(buf, 0, (char) 0, buf.capacity());
try {
+ // failed on RI. Spec doesn't specify the behavior if
+ // actually nothing to be done by compact()
buf.reset();
fail("Should throw Exception"); //$NON-NLS-1$
} catch (InvalidMarkException e) {
@@ -938,6 +942,7 @@
method = "put",
args = {java.lang.String.class, int.class, int.class}
)
+ @AndroidOnly("Fails on RI. See commend below")
public void testPutStringintint() {
buf.clear();
String str = String.valueOf(new char[buf.capacity()]);
@@ -951,6 +956,11 @@
} catch (BufferOverflowException e) {
// expected
}
+
+ // Fails on RI. On RI put() starts transferring characters even if
+ // there's no free space for whole string
+ assertEquals(0, buf.position());
+
try {
buf.put((String) null, 0, buf.capacity() + 1);
fail("Should throw Exception"); //$NON-NLS-1$
@@ -1004,26 +1014,26 @@
assertSame(ret, buf);
}
- void loadTestData1(char array[], int offset, int length) {
+ protected void loadTestData1(char array[], int offset, int length) {
for (int i = 0; i < length; i++) {
array[offset + i] = (char) i;
}
}
- void loadTestData2(char array[], int offset, int length) {
+ protected void loadTestData2(char array[], int offset, int length) {
for (int i = 0; i < length; i++) {
array[offset + i] = (char) (length - i);
}
}
- void loadTestData1(CharBuffer buf) {
+ protected void loadTestData1(CharBuffer buf) {
buf.clear();
for (int i = 0; i < buf.capacity(); i++) {
buf.put(i, (char) i);
}
}
- void loadTestData2(CharBuffer buf) {
+ protected void loadTestData2(CharBuffer buf) {
buf.clear();
for (int i = 0; i < buf.capacity(); i++) {
buf.put(i, (char) (buf.capacity() - i));
@@ -1344,24 +1354,23 @@
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
+ notes = "Abstract method.",
+ method = "isReadOnly",
+ args = {}
+ )
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that hasArray returns true value.",
method = "hasArray",
args = {}
)
public void testHasArray() {
- if (buf.hasArray()) {
- assertNotNull(buf.array());
- } else {
- try {
- buf.array();
- fail("Should throw Exception"); //$NON-NLS-1$
- } catch (UnsupportedOperationException e) {
- // expected
- // Note:can not tell when to catch
- // UnsupportedOperationException or
- // ReadOnlyBufferException, so catch all.
- }
- }
+ assertTrue(buf.hasArray());
+ assertNotNull(buf.array());
}
@TestTargetNew(
@@ -1374,16 +1383,6 @@
assertEquals(ByteOrder.nativeOrder(), buf.order());
}
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Abstract method.",
- method = "isReadOnly",
- args = {}
- )
- public void testIsReadOnly() {
- assertFalse(buf.isReadOnly());
- }
-
/*
* test for method static CharBuffer wrap(char[] array) test covers
* following usecases: 1. case for check CharBuffer buf2 properties 2. case
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectByteBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectByteBufferTest.java
index 08e4813..e384a3d 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectByteBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectByteBufferTest.java
@@ -25,14 +25,13 @@
public class DirectByteBufferTest extends ByteBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = ByteBuffer.allocateDirect(BUFFER_LENGTH);
+ loadTestData1(buf);
baseBuf = buf;
}
protected void tearDown() throws Exception {
- super.tearDown();
buf = null;
baseBuf = null;
}
@@ -111,14 +110,4 @@
// expected
}
}
-
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Verifies isReadOnly method for direct ByteBuffer.",
- method = "isReadOnly",
- args = {}
- )
- public void testIsReadOnly() {
- assertFalse(buf.isReadOnly());
- }
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectCharBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectCharBufferTest.java
index fb55e1d..e910f92 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectCharBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectCharBufferTest.java
@@ -25,14 +25,14 @@
@TestTargetClass(java.nio.CharBuffer.class)
public class DirectCharBufferTest extends CharBufferTest {
- public void setUp(){
+ protected void setUp(){
capacity = BUFFER_LENGTH;
- buf = ByteBuffer.allocateDirect(BUFFER_LENGTH*2).asCharBuffer();
- super.loadTestData1(buf);
+ buf = ByteBuffer.allocateDirect(BUFFER_LENGTH * 2).asCharBuffer();
+ loadTestData1(buf);
baseBuf = buf;
}
- public void tearDown(){
+ protected void tearDown(){
buf = null;
baseBuf = null;
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectIntBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectIntBufferTest.java
index 4e72a43..489d265 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectIntBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectIntBufferTest.java
@@ -19,6 +19,7 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -94,4 +95,47 @@
public void testOrder() {
assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
}
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Regression test for IntToByteBufferAdapter",
+ clazz = ByteBuffer.class,
+ method = "asIntBuffer",
+ args = {}
+ )
+ public void testRangeChecks() {
+ int[] myInts = new int[BUFFER_LENGTH];
+
+ for (int i = 0; i < BUFFER_LENGTH; i++) {
+ myInts[i] = 1000 + i;
+ }
+
+ buf.position(0);
+ buf.put(myInts, 0, BUFFER_LENGTH);
+ buf.position(0);
+ buf.put(myInts, 0, BUFFER_LENGTH);
+
+ try {
+ buf.put(myInts, 0, 1); // should fail
+ fail("BufferOverflowException expected but not thrown");
+ } catch (BufferOverflowException boe) {
+ // expected
+ }
+
+ try {
+ buf.position(0);
+ buf.put(myInts, 0, BUFFER_LENGTH + 1); // should fail
+ fail("BufferOverflowException expected but not thrown");
+ } catch (IndexOutOfBoundsException ioobe) {
+ // expected
+ }
+
+ try {
+ buf.position(BUFFER_LENGTH - 1);
+ buf.put(myInts, 0, 2); // should fail
+ fail("BufferOverflowException expected but not thrown");
+ } catch (BufferOverflowException boe) {
+ // expected
+ }
+ }
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectShortBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectShortBufferTest.java
index a76701f..a6e922b 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectShortBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DirectShortBufferTest.java
@@ -19,8 +19,10 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.nio.ShortBuffer;
@TestTargetClass(java.nio.ShortBuffer.class)
public class DirectShortBufferTest extends ShortBufferTest {
@@ -94,4 +96,47 @@
public void testOrder() {
assertEquals(ByteOrder.BIG_ENDIAN, buf.order());
}
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Regression test for ShortToByteBufferAdapter",
+ clazz = ByteBuffer.class,
+ method = "asShortBuffer",
+ args = {}
+ )
+ public void testRangeChecks() {
+ short[] myShorts = new short[BUFFER_LENGTH];
+
+ for (short i = 0; i < BUFFER_LENGTH; i++) {
+ myShorts[i] = (short) (1000 + i);
+ }
+
+ buf.position(0);
+ buf.put(myShorts, 0, BUFFER_LENGTH);
+ buf.position(0);
+ buf.put(myShorts, 0, BUFFER_LENGTH);
+
+ try {
+ buf.put(myShorts, 0, 1); // should fail
+ fail("BufferOverflowException expected but not thrown");
+ } catch (BufferOverflowException boe) {
+ // expected
+ }
+
+ try {
+ buf.position(0);
+ buf.put(myShorts, 0, BUFFER_LENGTH + 1); // should fail
+ fail("BufferOverflowException expected but not thrown");
+ } catch (IndexOutOfBoundsException ioobe) {
+ // expected
+ }
+
+ try {
+ buf.position(BUFFER_LENGTH - 1);
+ buf.put(myShorts, 0, 2); // should fail
+ fail("BufferOverflowException expected but not thrown");
+ } catch (BufferOverflowException boe) {
+ // expected
+ }
+ }
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java
index 44f0ae7..033c289 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/DoubleBufferTest.java
@@ -20,6 +20,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.AndroidOnly;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
@@ -32,7 +33,7 @@
* Tests java.nio.DoubleBuffer
*/
@TestTargetClass(java.nio.DoubleBuffer.class)
-public class DoubleBufferTest extends AbstractBufferTest {
+public abstract class DoubleBufferTest extends AbstractBufferTest {
protected static final int SMALL_TEST_LENGTH = 5;
@@ -216,6 +217,7 @@
method = "compact",
args = {}
)
+ @AndroidOnly("Fails on RI. See comment below")
public void testCompact() {
// case: buffer is full
buf.clear();
@@ -243,6 +245,9 @@
assertEquals(buf.limit(), buf.capacity());
assertContentLikeTestData1(buf, 0, 0.0, buf.capacity());
try {
+ // Fails on RI. Spec doesn't specify the behavior if
+ // actually nothing to be done by compact(). So RI doesn't reset
+ // mark position
buf.reset();
fail("Should throw Exception"); //$NON-NLS-1$
} catch (InvalidMarkException e) {
@@ -569,6 +574,16 @@
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Abstract method.",
+ method = "isReadOnly",
+ args = {}
+ )
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "order",
args = {}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java
index f140dd2..f0a629a 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/FloatBufferTest.java
@@ -20,6 +20,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.AndroidOnly;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
@@ -33,7 +34,7 @@
*
*/
@TestTargetClass(java.nio.FloatBuffer.class)
-public class FloatBufferTest extends AbstractBufferTest {
+public abstract class FloatBufferTest extends AbstractBufferTest {
protected static final int SMALL_TEST_LENGTH = 5;
@@ -198,6 +199,7 @@
method = "compact",
args = {}
)
+ @AndroidOnly("Fails on RI. See comment below")
public void testCompact() {
// case: buffer is full
@@ -226,6 +228,9 @@
assertEquals(buf.limit(), buf.capacity());
assertContentLikeTestData1(buf, 0, 0.0f, buf.capacity());
try {
+ // Fails on RI. Spec doesn't specify the behavior if
+ // actually nothing to be done by compact(). So RI doesn't reset
+ // mark position
buf.reset();
fail("Should throw Exception"); //$NON-NLS-1$
} catch (InvalidMarkException e) {
@@ -578,6 +583,16 @@
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Abstract method.",
+ method = "isReadOnly",
+ args = {}
+ )
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "order",
args = {}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapByteBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapByteBufferTest.java
index 046350f..e7235ca 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapByteBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapByteBufferTest.java
@@ -26,15 +26,10 @@
protected void setUp() throws Exception {
super.setUp();
- capacity = BUFFER_LENGTH;
- buf = ByteBuffer.allocate(BUFFER_LENGTH);
- baseBuf = buf;
}
protected void tearDown() throws Exception {
super.tearDown();
- buf = null;
- baseBuf = null;
}
/**
@@ -55,35 +50,4 @@
// expected
}
}
-
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Verifies isDirect method with not direct buffer.",
- method = "isDirect",
- args = {}
- )
- public void testIsDirect() {
- assertFalse(buf.isDirect());
- }
-
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Verifies that hasArray returns true value.",
- method = "hasArray",
- args = {}
- )
- public void testHasArray() {
- assertTrue(buf.hasArray());
- assertNotNull(buf.array());
- }
-
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Verifies isReadOnly method with non read only buffer.",
- method = "isReadOnly",
- args = {}
- )
- public void testIsReadOnly() {
- assertFalse(buf.isReadOnly());
- }
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapCharBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapCharBufferTest.java
index 5c370a2..2ece6de 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapCharBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapCharBufferTest.java
@@ -29,8 +29,6 @@
protected void tearDown() throws Exception {
super.tearDown();
- buf = null;
- baseBuf = null;
}
@TestTargetNew(
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapDoubleBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapDoubleBufferTest.java
index ddef05f..c56f6a1 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapDoubleBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapDoubleBufferTest.java
@@ -29,8 +29,6 @@
protected void tearDown() throws Exception {
super.tearDown();
- buf = null;
- baseBuf = null;
}
@TestTargetNew(
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapFloatBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapFloatBufferTest.java
index 2a323c5..3a9fddc 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapFloatBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapFloatBufferTest.java
@@ -29,8 +29,6 @@
protected void tearDown() throws Exception {
super.tearDown();
- buf = null;
- baseBuf = null;
}
@TestTargetNew(
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapIntBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapIntBufferTest.java
index b92f7c6..203a743 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapIntBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapIntBufferTest.java
@@ -29,8 +29,6 @@
protected void tearDown() throws Exception {
super.tearDown();
- buf = null;
- baseBuf = null;
}
@TestTargetNew(
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapLongBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapLongBufferTest.java
index 7beedbb..667c7ed 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapLongBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapLongBufferTest.java
@@ -29,8 +29,6 @@
protected void tearDown() throws Exception {
super.tearDown();
- buf = null;
- baseBuf = null;
}
@TestTargetNew(
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapShortBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapShortBufferTest.java
index 4de5229..679b0bd 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapShortBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/HeapShortBufferTest.java
@@ -29,8 +29,6 @@
protected void tearDown() throws Exception {
super.tearDown();
- buf = null;
- baseBuf = null;
}
@TestTargetNew(
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/IntBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/IntBufferTest.java
index 1f26d5e..2313190 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/IntBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/IntBufferTest.java
@@ -20,9 +20,11 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.AndroidOnly;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.InvalidMarkException;
@@ -32,7 +34,7 @@
*
*/
@TestTargetClass(java.nio.IntBuffer.class)
-public class IntBufferTest extends AbstractBufferTest {
+public abstract class IntBufferTest extends AbstractBufferTest {
protected static final int SMALL_TEST_LENGTH = 5;
@@ -172,6 +174,7 @@
method = "compact",
args = {}
)
+ @AndroidOnly("Fails on RI. See comment below")
public void testCompact() {
// case: buffer is full
buf.clear();
@@ -199,6 +202,9 @@
assertEquals(buf.limit(), buf.capacity());
assertContentLikeTestData1(buf, 0, 0, buf.capacity());
try {
+ // Fails on RI. Spec doesn't specify the behavior if
+ // actually nothing to be done by compact(). So RI doesn't reset
+ // mark position
buf.reset();
fail("Should throw Exception"); //$NON-NLS-1$
} catch (InvalidMarkException e) {
@@ -530,6 +536,16 @@
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Abstract method.",
+ method = "isReadOnly",
+ args = {}
+ )
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "order",
args = {}
@@ -668,6 +684,29 @@
assertContentEquals(buf, array, 0, array.length);
assertSame(ret, buf);
}
+
+ /*
+ * Class under test for java.nio.IntBuffer put(int[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Regression Test",
+ method = "put",
+ args = {int[].class, int.class, int.class}
+ )
+ public void testPutintArrayintint2() {
+ // Regression test
+ ByteBuffer buf = ByteBuffer.allocateDirect(20);
+ IntBuffer intBuf = buf.asIntBuffer();
+ int[] src = new int[5];
+ intBuf.put(src);
+ intBuf.clear();
+ try {
+ intBuf.put(src);
+ } catch (BufferOverflowException e) {
+ fail("should not throw a BufferOverflowException");
+ }
+ }
/*
* Class under test for java.nio.IntBuffer put(java.nio.IntBuffer)
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/LongBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/LongBufferTest.java
index c608f70..d6d8ed1 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/LongBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/LongBufferTest.java
@@ -20,6 +20,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.AndroidOnly;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
@@ -32,7 +33,7 @@
*
*/
@TestTargetClass(java.nio.LongBuffer.class)
-public class LongBufferTest extends AbstractBufferTest {
+public abstract class LongBufferTest extends AbstractBufferTest {
protected static final int SMALL_TEST_LENGTH = 5;
@@ -172,6 +173,7 @@
method = "compact",
args = {}
)
+ @AndroidOnly("Fails on RI. See comment below")
public void testCompact() {
// case: buffer is full
buf.clear();
@@ -199,6 +201,9 @@
assertEquals(buf.limit(), buf.capacity());
assertContentLikeTestData1(buf, 0, 0, buf.capacity());
try {
+ // Fails on RI. Spec doesn't specify the behavior if
+ // actually nothing to be done by compact(). So RI doesn't reset
+ // mark position
buf.reset();
fail("Should throw Exception"); //$NON-NLS-1$
} catch (InvalidMarkException e) {
@@ -530,6 +535,16 @@
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Abstract method.",
+ method = "isReadOnly",
+ args = {}
+ )
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "order",
args = {}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/MappedByteBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/MappedByteBufferTest.java
index d9eefaf..3161fe1 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/MappedByteBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/MappedByteBufferTest.java
@@ -36,8 +36,6 @@
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
-import junit.framework.TestCase;
-
@TestTargetClass(
value = MappedByteBuffer.class,
untestedMethods = {
@@ -48,9 +46,10 @@
)
}
)
-public class MappedByteBufferTest extends TestCase {
+public class MappedByteBufferTest extends DirectByteBufferTest {
File tmpFile;
+ FileChannel fc;
/**
* A regression test for failing to correctly set capacity of underlying
@@ -62,28 +61,23 @@
method = "asIntBuffer",
args = {}
)
- public void test_asIntBuffer() throws IOException {
- // Map file
- FileInputStream fis = new FileInputStream(tmpFile);
- FileChannel fc = fis.getChannel();
- MappedByteBuffer mmb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc
- .size());
- int len = mmb.capacity();
- assertEquals("Got wrong number of bytes", 46, len); //$NON-NLS-1$
+ public void test_asIntBuffer() {
+ int len = buf.capacity();
+ assertEquals("Got wrong number of bytes", BUFFER_LENGTH, len); //$NON-NLS-1$
// Read in our 26 bytes
- for (int i = 0; i < 26; i++) {
- byte b = mmb.get();
- assertEquals("Got wrong byte value", (byte) 'A' + i, b); //$NON-NLS-1$
+ for (int i = 0; i < BUFFER_LENGTH - 20; i++) {
+ byte b = buf.get();
+ assertEquals("Got wrong byte value", (byte) i, b); //$NON-NLS-1$
}
// Now convert to an IntBuffer to read our ints
- IntBuffer ibuffer = mmb.asIntBuffer();
- for (int i = 0; i < 5; i++) {
+ IntBuffer ibuffer = buf.asIntBuffer();
+ for (int i = BUFFER_LENGTH - 20; i < BUFFER_LENGTH; i+=4) {
int val = ibuffer.get();
- assertEquals("Got wrong int value", i + 1, val); //$NON-NLS-1$
+ int res = i * 16777216 + (i + 1) * 65536 + (i + 2) * 256 + (i + 3);
+ assertEquals("Got wrong int value", res, val); //$NON-NLS-1$
}
- fc.close();
}
/**
@@ -167,20 +161,33 @@
protected void setUp() throws IOException {
// Create temp file with 26 bytes and 5 ints
- tmpFile = new File(System.getProperty("ctsdir"), "MappedByteBufferTest"); //$NON-NLS-1$//$NON-NLS-2$
+ tmpFile = File.createTempFile("MappedByteBufferTest", ".tmp"); //$NON-NLS-1$//$NON-NLS-2$
tmpFile.createNewFile();
tmpFile.deleteOnExit();
+
+ fillTempFile();
+
+ // Map file
+ RandomAccessFile raf = new RandomAccessFile(tmpFile, "rw");
+ fc = raf.getChannel();
+ capacity = (int) fc.size();
+ buf = fc.map(FileChannel.MapMode.READ_WRITE, 0, capacity);
+ baseBuf = buf;
+ }
+
+ protected void tearDown() throws IOException {
+ fc.close();
+ }
+
+ private void fillTempFile() throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(tmpFile);
FileChannel fileChannel = fileOutputStream.getChannel();
- ByteBuffer byteBuffer = ByteBuffer.allocateDirect(26 + 20);
- for (int i = 0; i < 26; i++) {
- byteBuffer.put((byte) ('A' + i));
- }
- for (int i = 0; i < 5; i++) {
- byteBuffer.putInt(i + 1);
- }
- byteBuffer.rewind();
+ ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER_LENGTH);
+
+ loadTestData1(byteBuffer);
+ byteBuffer.clear();
fileChannel.write(byteBuffer);
+
fileChannel.close();
fileOutputStream.close();
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyCharBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyCharBufferTest.java
index e5d3573..97fd2c6 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyCharBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyCharBufferTest.java
@@ -32,8 +32,6 @@
}
protected void tearDown() throws Exception {
- buf = null;
- baseBuf = null;
super.tearDown();
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java
index 259e3d9..456a212 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedCharBufferTest1.java
@@ -24,15 +24,15 @@
public class ReadOnlyWrappedCharBufferTest1 extends ReadOnlyCharBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = CharBuffer.wrap(new char[BUFFER_LENGTH]);
- super.loadTestData1(buf);
+ loadTestData1(buf);
buf = buf.asReadOnlyBuffer();
baseBuf = buf;
}
protected void tearDown() throws Exception {
- super.tearDown();
+ buf = null;
+ baseBuf = null;
}
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java
index 21951cf..43a0733 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedDoubleBufferTest.java
@@ -23,15 +23,15 @@
public class ReadOnlyWrappedDoubleBufferTest extends ReadOnlyDoubleBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = DoubleBuffer.wrap(new double[BUFFER_LENGTH]);
- super.loadTestData1(buf);
+ loadTestData1(buf);
buf = buf.asReadOnlyBuffer();
baseBuf = buf;
}
protected void tearDown() throws Exception {
- super.tearDown();
+ buf =null;
+ baseBuf = null;
}
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java
index cfbca11..62ab26a 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedFloatBufferTest.java
@@ -23,15 +23,15 @@
public class ReadOnlyWrappedFloatBufferTest extends ReadOnlyFloatBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = FloatBuffer.wrap(new float[BUFFER_LENGTH]);
- super.loadTestData1(buf);
+ loadTestData1(buf);
buf = buf.asReadOnlyBuffer();
baseBuf = buf;
}
protected void tearDown() throws Exception {
- super.tearDown();
+ buf = null;
+ baseBuf = null;
}
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedIntBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedIntBufferTest.java
index a9210d2..842b553 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedIntBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedIntBufferTest.java
@@ -23,7 +23,6 @@
public class ReadOnlyWrappedIntBufferTest extends ReadOnlyIntBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = IntBuffer.wrap(new int[BUFFER_LENGTH]);
loadTestData1(buf);
@@ -32,6 +31,7 @@
}
protected void tearDown() throws Exception {
- super.tearDown();
+ buf = null;
+ baseBuf = null;
}
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedLongBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedLongBufferTest.java
index 392d9c5..6d04d6f 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedLongBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedLongBufferTest.java
@@ -23,7 +23,6 @@
public class ReadOnlyWrappedLongBufferTest extends ReadOnlyLongBufferTest{
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = LongBuffer.wrap(new long[BUFFER_LENGTH]);
loadTestData1(buf);
@@ -32,6 +31,7 @@
}
protected void tearDown() throws Exception {
- super.tearDown();
+ buf = null;
+ baseBuf = null;
}
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedShortBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedShortBufferTest.java
index 32e5c29..eb604ab 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedShortBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ReadOnlyWrappedShortBufferTest.java
@@ -23,7 +23,6 @@
public class ReadOnlyWrappedShortBufferTest extends ReadOnlyShortBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = ShortBuffer.wrap(new short[BUFFER_LENGTH]);
loadTestData1(buf);
@@ -32,6 +31,7 @@
}
protected void tearDown() throws Exception {
- super.tearDown();
+ buf = null;
+ baseBuf = null;
}
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ShortBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ShortBufferTest.java
index 13af578..8985d31 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ShortBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ShortBufferTest.java
@@ -20,9 +20,11 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.AndroidOnly;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.InvalidMarkException;
import java.nio.ShortBuffer;
@@ -32,7 +34,7 @@
*
*/
@TestTargetClass(java.nio.ShortBuffer.class)
-public class ShortBufferTest extends AbstractBufferTest {
+public abstract class ShortBufferTest extends AbstractBufferTest {
protected static final int SMALL_TEST_LENGTH = 5;
@@ -171,6 +173,7 @@
method = "compact",
args = {}
)
+ @AndroidOnly("Fails on RI. See comment below")
public void testCompact() {
// case: buffer is full
buf.clear();
@@ -198,6 +201,9 @@
assertEquals(buf.limit(), buf.capacity());
assertContentLikeTestData1(buf, 0, (short) 0, buf.capacity());
try {
+ // Fails on RI. Spec doesn't specify the behavior if
+ // actually nothing to be done by compact(). So RI doesn't reset
+ // mark position
buf.reset();
fail("Should throw Exception"); //$NON-NLS-1$
} catch (InvalidMarkException e) {
@@ -523,6 +529,16 @@
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Abstract method.",
+ method = "isReadOnly",
+ args = {}
+ )
+ public void testIsReadOnly() {
+ assertFalse(buf.isReadOnly());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "",
method = "order",
args = {}
@@ -661,6 +677,29 @@
assertContentEquals(buf, array, 0, array.length);
assertSame(ret, buf);
}
+
+ /*
+ * Class under test for java.nio.IntBuffer put(int[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Regression test",
+ method = "put",
+ args = {short[].class, int.class, int.class}
+ )
+ public void testPutshortArrayintint2() {
+ // Regression test
+ ByteBuffer buf = ByteBuffer.allocateDirect(10);
+ ShortBuffer shortBuf = buf.asShortBuffer();
+ short[] src = new short[5];
+ shortBuf.put(src);
+ shortBuf.clear();
+ try {
+ shortBuf.put(src);
+ } catch (BufferOverflowException e) {
+ fail("should not throw a BufferOverflowException");
+ }
+ }
/*
* Class under test for java.nio.ShortBuffer put(java.nio.ShortBuffer)
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceDirectByteBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceDirectByteBufferTest.java
index 8b94e3e..022739c 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceDirectByteBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceDirectByteBufferTest.java
@@ -24,7 +24,7 @@
protected void setUp() throws Exception {
super.setUp();
capacity = BUFFER_LENGTH - 2;
- buf.position(1).limit(BUFFER_LENGTH-1);
+ buf.position(1).limit(BUFFER_LENGTH - 1);
buf = buf.slice();
baseBuf = buf;
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceHeapByteBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceHeapByteBufferTest.java
index aafe47f..2325da0 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceHeapByteBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceHeapByteBufferTest.java
@@ -24,7 +24,7 @@
protected void setUp() throws Exception {
super.setUp();
capacity = BUFFER_LENGTH - 2;
- buf.position(1).limit(BUFFER_LENGTH-1);
+ buf.position(1).limit(BUFFER_LENGTH - 1);
buf = buf.slice();
baseBuf = buf;
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceWrappedByteBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceWrappedByteBufferTest.java
index d348916..0bfd339 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceWrappedByteBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/SliceWrappedByteBufferTest.java
@@ -24,7 +24,7 @@
protected void setUp() throws Exception {
super.setUp();
capacity = BUFFER_LENGTH - 2;
- buf.position(1).limit(BUFFER_LENGTH-1);
+ buf.position(1).limit(BUFFER_LENGTH - 1);
buf = buf.slice();
baseBuf = buf;
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedByteBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedByteBufferTest.java
index 94c8418..ec01f03 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedByteBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedByteBufferTest.java
@@ -26,14 +26,13 @@
public class WrappedByteBufferTest extends ByteBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = ByteBuffer.wrap(new byte[BUFFER_LENGTH]);
+ loadTestData1(buf);
baseBuf = buf;
}
protected void tearDown() throws Exception {
- super.tearDown();
buf = null;
baseBuf = null;
}
@@ -94,35 +93,4 @@
}
}
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Verifies isDirect method for non direct ByteBuffer.",
- method = "isDirect",
- args = {}
- )
- public void testIsDirect() {
- assertFalse(buf.isDirect());
- }
-
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Verifies hasArray method for wrapped ByteBuffer.",
- method = "hasArray",
- args = {}
- )
- public void testHasArray() {
- assertTrue(buf.hasArray());
- assertNotNull(buf.array());
- }
-
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
- method = "isReadOnly",
- args = {}
- )
- public void testIsReadOnly() {
- assertFalse(buf.isReadOnly());
- }
-
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest1.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest1.java
index ff48762..2398cdb 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest1.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest1.java
@@ -26,7 +26,6 @@
public class WrappedCharBufferTest1 extends CharBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = CharBuffer.wrap(new char[BUFFER_LENGTH]);
loadTestData1(buf);
@@ -34,7 +33,6 @@
}
protected void tearDown() throws Exception {
- super.tearDown();
baseBuf = null;
buf = null;
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest2.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest2.java
index e3a51c8..8365c1c 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest2.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedCharBufferTest2.java
@@ -19,6 +19,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.AndroidOnly;
import java.nio.BufferOverflowException;
import java.nio.CharBuffer;
@@ -170,4 +171,15 @@
// expected
}
}
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "slice",
+ args = {}
+ )
+ @AndroidOnly("Fails on RI")
+ public void testSlice() {
+ super.testSlice();
+ }
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedDoubleBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedDoubleBufferTest.java
index 4ea5c84..d47ed75 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedDoubleBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedDoubleBufferTest.java
@@ -24,7 +24,6 @@
@TestTargetClass(java.nio.DoubleBuffer.class)
public class WrappedDoubleBufferTest extends DoubleBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = DoubleBuffer.wrap(new double[BUFFER_LENGTH]);
loadTestData1(buf);
@@ -32,9 +31,8 @@
}
protected void tearDown() throws Exception {
- super.tearDown();
- baseBuf = null;
buf = null;
+ baseBuf = null;
}
/**
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedFloatBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedFloatBufferTest.java
index 71f84a9..ee5095d 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedFloatBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedFloatBufferTest.java
@@ -24,7 +24,6 @@
@TestTargetClass(java.nio.FloatBuffer.class)
public class WrappedFloatBufferTest extends FloatBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = FloatBuffer.wrap(new float[BUFFER_LENGTH]);
loadTestData1(buf);
@@ -32,7 +31,6 @@
}
protected void tearDown() throws Exception {
- super.tearDown();
baseBuf = null;
buf = null;
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedIntBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedIntBufferTest.java
index 3041de7..b22258b 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedIntBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedIntBufferTest.java
@@ -24,7 +24,6 @@
@TestTargetClass(java.nio.IntBuffer.class)
public class WrappedIntBufferTest extends IntBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = IntBuffer.wrap(new int[BUFFER_LENGTH]);
loadTestData1(buf);
@@ -32,7 +31,6 @@
}
protected void tearDown() throws Exception {
- super.tearDown();
baseBuf = null;
buf = null;
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedLongBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedLongBufferTest.java
index 552a1e3..3faec21 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedLongBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedLongBufferTest.java
@@ -24,7 +24,6 @@
@TestTargetClass(java.nio.LongBuffer.class)
public class WrappedLongBufferTest extends LongBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = LongBuffer.wrap(new long[BUFFER_LENGTH]);
loadTestData1(buf);
@@ -32,7 +31,6 @@
}
protected void tearDown() throws Exception {
- super.tearDown();
baseBuf = null;
buf = null;
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedShortBufferTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedShortBufferTest.java
index 9917ae0..aa3c76e 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedShortBufferTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/WrappedShortBufferTest.java
@@ -24,7 +24,6 @@
@TestTargetClass(java.nio.ShortBuffer.class)
public class WrappedShortBufferTest extends ShortBufferTest {
protected void setUp() throws Exception {
- super.setUp();
capacity = BUFFER_LENGTH;
buf = ShortBuffer.wrap(new short[BUFFER_LENGTH]);
loadTestData1(buf);
@@ -32,7 +31,6 @@
}
protected void tearDown() throws Exception {
- super.tearDown();
baseBuf = null;
buf = null;
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java
index 9a1a956..91d6d06 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileChannelTest.java
@@ -2439,6 +2439,7 @@
method = "position",
args = {}
)
+ @AndroidOnly("Fails on RI. See comment below")
public void test_position_append() throws Exception {
// Regression test for Harmony-508
File tmpfile = File.createTempFile("FileOutputStream", "tmp");
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java
index 6dc127e..6148b6f 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/FileLockTest.java
@@ -260,4 +260,19 @@
FileLock fileLock = fileChannel.lock();
assertTrue(fileLock.toString().length() > 0);
}
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Regression test",
+ method = "release",
+ args = {}
+ )
+ public void testFileLock() throws Exception {
+ String fileName = File.createTempFile("test", "tmp").getAbsolutePath();
+ RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
+ FileLock lock = raf.getChannel().tryLock();
+ raf.write("file lock test".getBytes());
+ lock.release();
+ raf.close();
+ }
}
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java
index 883ca28..de69f9f 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SelectorTest.java
@@ -16,7 +16,6 @@
package org.apache.harmony.nio.tests.java.nio.channels;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -340,7 +339,6 @@
method = "select",
args = {long.class}
)
- @KnownFailure("fixed in ToT")
public void test_selectJ_Empty_Keys() throws IOException {
// regression test, see HARMONY-3888.
// make sure select(long) does wait for specified amount of
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ServerSocketChannelTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ServerSocketChannelTest.java
index 988cef6..ad1e78f 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ServerSocketChannelTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/ServerSocketChannelTest.java
@@ -17,11 +17,11 @@
package org.apache.harmony.nio.tests.java.nio.channels;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.AndroidOnly;
import java.io.IOException;
import java.io.InputStream;
@@ -719,6 +719,7 @@
method = "accept",
args = {}
)
+ @AndroidOnly("seems to run on newer RI versions")
public void test_accept_Security() throws IOException {
this.clientChannel.configureBlocking(true);
this.serverChannel.configureBlocking(true);
@@ -868,7 +869,6 @@
method = "socket",
args = {}
)
- @KnownFailure("Fixed in ToT")
public void test_socket_getLocalPort() throws IOException {
// regression test for Harmony-4961
serverChannel.socket().bind(localAddr1);
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SinkChannelTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SinkChannelTest.java
index 849ef12..04f0e6c 100644
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SinkChannelTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SinkChannelTest.java
@@ -20,6 +20,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
+import dalvik.annotation.AndroidOnly;
import java.io.IOException;
import java.net.InetAddress;
@@ -270,6 +271,7 @@
method = "write",
args = {java.nio.ByteBuffer[].class}
)
+ @AndroidOnly("seems to run on newer RI versions")
public void test_write_LByteBuffer_SourceClosed() throws IOException {
source.close();
int written = sink.write(buffer);
@@ -384,6 +386,7 @@
method = "write",
args = {java.nio.ByteBuffer[].class}
)
+ @AndroidOnly("seems to run on newer RI versions")
public void test_write_$LByteBuffer_SourceClosed() throws IOException {
ByteBuffer[] bufArray = { buffer };
source.close();
@@ -553,6 +556,7 @@
method = "write",
args = {java.nio.ByteBuffer[].class, int.class, int.class}
)
+ @AndroidOnly("seems to run on newer RI versions")
public void test_write_$LByteBufferII_SourceClosed() throws IOException {
ByteBuffer[] bufArray = { buffer };
source.close();
diff --git a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java
index d31cd0a..69f245d 100755
--- a/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java
+++ b/libcore/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/SocketChannelTest.java
@@ -22,6 +22,7 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestLevel;
+import dalvik.annotation.AndroidOnly;
import java.io.IOException;
import java.io.InputStream;
@@ -517,9 +518,12 @@
method = "socket",
args = {}
)
+ @AndroidOnly("Fails on RI. See comment below")
public void testSocket_BasicStatusBeforeConnect() throws IOException {
assertFalse(this.channel1.isConnected());// not connected
Socket s1 = this.channel1.socket();
+ // RI fails here. RI returns 0 while spec says getLocalPort()
+ // shall return -1 for unbound socket
assertSocketBeforeConnect(s1);
Socket s2 = this.channel1.socket();
// same
@@ -551,6 +555,7 @@
method = "socket",
args = {}
)
+ @AndroidOnly("Fails on RI. See comment below")
public void testSocket_NonBlock_BasicStatusAfterConnect() throws Exception {
assertFalse(this.channel1.isConnected());// not connected
this.channel1.configureBlocking(false);
@@ -559,6 +564,8 @@
assertTrue(this.channel1.isConnectionPending());
Socket s1 = this.channel1.socket();
// status of not connected
+ // RI fails here. RI returns 0 while spec says getLocalPort()
+ // shall return -1 for unbound socket
assertSocketBeforeConnect(s1);
Socket s2 = this.channel1.socket();
// same
@@ -2666,7 +2673,7 @@
method = "write",
args = {java.nio.ByteBuffer.class}
)
- @KnownFailure("Fxed on ToT")
+ @KnownFailure("Fixed on ToT")
public void test_writeLjava_nio_ByteBuffer_Nonblocking_HugeData() throws IOException {
// initialize write content
ByteBuffer writeContent = ByteBuffer.allocate(CAPACITY_HUGE);
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/ASCCharsetTest.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/ASCCharsetTest.java
index eceb1a0..a354d65 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/ASCCharsetTest.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/ASCCharsetTest.java
@@ -31,8 +31,8 @@
* Constructor.
*
*/
- public ASCCharsetTest(String arg0) {
- super(arg0, "US-ASCII", new String[] { "ISO646-US", "ASCII", "cp367",
+ public ASCCharsetTest() {
+ super("US-ASCII", new String[] { "ISO646-US", "ASCII", "cp367",
"ascii7", "ANSI_X3.4-1986", "iso-ir-6", "us", "646",
"iso_646.irv:1983", "csASCII", "ANSI_X3.4-1968",
"ISO_646.irv:1991" }, true, true); // "ibm-367"
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java
index 4c69759..88cbbdb 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/AbstractCharsetTestCase.java
@@ -1,15 +1,13 @@
package tests.api.java.nio.charset;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import junit.framework.TestCase;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
@TestTargetClass(Charset.class)
@@ -54,9 +52,8 @@
* Constructor for ConcreteCharsetTest.
*
*/
- public AbstractCharsetTestCase(String arg0, String canonicalName,
+ public AbstractCharsetTestCase(String canonicalName,
String[] aliases, boolean canEncode, boolean isRegistered) {
- super(arg0);
this.canonicalName = canonicalName;
this.canEncode = canEncode;
this.isRegistered = isRegistered;
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java
index a0db954..535f068 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java
@@ -15,11 +15,11 @@
*/
package tests.api.java.nio.charset;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
+import dalvik.annotation.AndroidOnly;
import junit.framework.TestCase;
@@ -131,7 +131,8 @@
method = "charsetForName",
args = {String.class}
)
- @KnownFailure("Fixed in ToT")
+ @AndroidOnly("Looks like RI doesn't use current thread's context class "+
+ "loader to lookup charset providers")
public void testIsSupported_And_ForName_NormalProvider() throws Exception {
try {
assertFalse(Charset.isSupported("mockCharset10"));
@@ -231,7 +232,8 @@
method = "charsetForName",
args = {String.class}
)
- @KnownFailure("Fixed in ToT")
+ @AndroidOnly("Looks like RI doesn't use current thread's context class "+
+ "loader to lookup charset providers")
public void testIsSupported_NotCharsetProviderClass() throws Exception {
try {
StringBuffer sb = new StringBuffer();
@@ -359,7 +361,8 @@
method = "charsetForName",
args = {String.class}
)
- @KnownFailure("Fixed in ToT")
+ @AndroidOnly("Looks like RI doesn't use current thread's context class "+
+ "loader to lookup charset providers")
public void testForName_NonExistingClass() throws Exception {
try {
StringBuffer sb = new StringBuffer();
@@ -385,7 +388,8 @@
method = "charsetForName",
args = {String.class}
)
- @KnownFailure("Fixed in ToT")
+ @AndroidOnly("Looks like RI doesn't use current thread's context class "+
+ "loader to lookup charset providers")
public void testForName_NotCharsetProviderClass() throws Exception {
try {
StringBuffer sb = new StringBuffer();
@@ -411,7 +415,8 @@
method = "charsets",
args = {}
)
- @KnownFailure("Fixed in ToT")
+ @AndroidOnly("Looks like RI doesn't use current thread's context class "+
+ "loader to lookup charset providers")
public void testAvailableCharsets_NormalProvider() throws Exception {
try {
assertFalse(Charset.availableCharsets()
@@ -506,7 +511,8 @@
method = "charsets",
args = {}
)
- @KnownFailure("Fixed in ToT")
+ @AndroidOnly("Looks like RI doesn't use current thread's context class "+
+ "loader to lookup charset providers")
public void testAvailableCharsets_NotCharsetProviderClass()
throws Exception {
try {
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_AbstractTest.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_AbstractTest.java
index d4447a6..10d6caf 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_AbstractTest.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_AbstractTest.java
@@ -91,6 +91,7 @@
args = {}
)
public void test_dumpEncodableChars () {
+ if (testChars == null) return;
if (testChars.length > 0) return;
System.out.format("\ntest_dumpEncodableChars() for name %s => %s (class = %s)\n",
charsetName, charset.name(), getClass().getName());
@@ -121,6 +122,7 @@
args = {}
)
public void test_dumpEncoded () throws CharacterCodingException {
+ if (testChars == null) return;
if (testChars.length == 0) return;
if (testBytes.length > 0) return;
System.out.format("\ntest_dumpEncoded() for name %s => %s (class = %s)\n",
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_GSM0338.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_GSM0338.java
index 10be214..24a6acb 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_GSM0338.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_GSM0338.java
@@ -16,7 +16,9 @@
package tests.api.java.nio.charset;
import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
import java.nio.charset.CharacterCodingException;
@@ -54,6 +56,12 @@
super.setUp();
}
+ @TestTargetNew(
+ level = TestLevel.SUFFICIENT,
+ notes = "Not applicable to this charset.",
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@Override
public void test_CodecDynamic () throws CharacterCodingException {
}
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_Big5.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_Big5.java
index e409a71..59bfcbc 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_Big5.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_Big5.java
@@ -29,8 +29,10 @@
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
-// SEE correspondig_Android test class:
-//@TestTargetClass(targets.Charsets.Big5.class)
+@TestTargetClass(targets.Charsets.Big5.class)
+/** @hide
+ * SEE correspondig_Android test class:
+ */
public class Charset_MultiByte_Big5 extends Charset_AbstractTest {
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_Big5_Android.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_Big5_Android.java
index 9619154..1416d2a 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_Big5_Android.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_Big5_Android.java
@@ -15,21 +15,11 @@
*/
package tests.api.java.nio.charset;
-import dalvik.annotation.TestLevel;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
-import junit.framework.TestCase;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CodingErrorAction;
@TestTargetClass(targets.Charsets.Big5.class)
+@AndroidOnly("icu different from RI")
public class Charset_MultiByte_Big5_Android extends Charset_AbstractTest {
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_EUC_JP.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_EUC_JP.java
index 995f757..69a9663 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_EUC_JP.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_EUC_JP.java
@@ -29,8 +29,10 @@
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
-// SEE correspondig_Android test class:
-//@TestTargetClass(targets.Charsets.EUC_JP.class)
+@TestTargetClass(targets.Charsets.EUC_JP.class)
+/** @hide
+ * SEE correspondig_Android test class:
+ */
public class Charset_MultiByte_EUC_JP extends Charset_AbstractTest {
@@ -509,6 +511,12 @@
super.setUp();
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Duplicate Characters.",
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@Override
public void test_CodecDynamic () throws CharacterCodingException {
encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_EUC_JP_Android.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_EUC_JP_Android.java
index a3701e9..2ebff21 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_EUC_JP_Android.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_EUC_JP_Android.java
@@ -15,21 +15,18 @@
*/
package tests.api.java.nio.charset;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
-import junit.framework.TestCase;
-
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
@TestTargetClass(targets.Charsets.EUC_JP.class)
+@AndroidOnly("icu different from RI")
public class Charset_MultiByte_EUC_JP_Android extends Charset_AbstractTest {
@@ -508,6 +505,12 @@
super.setUp();
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Duplicate Characters.",
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@Override
public void test_CodecDynamic () throws CharacterCodingException {
encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GB2312.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GB2312.java
index c4cd724..b9f9bc6 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GB2312.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GB2312.java
@@ -16,7 +16,9 @@
package tests.api.java.nio.charset;
import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
import java.nio.charset.CharacterCodingException;
@@ -175,24 +177,43 @@
super.setUp();
}
- @KnownFailure("This Characterset is not properly supported in Android!")
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@Override
public void test_CodecDynamic() throws CharacterCodingException {
super.test_CodecDynamic();
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@KnownFailure("This Characterset is not properly supported in Android!")
@Override
public void test_Decode() throws CharacterCodingException {
super.test_Decode();
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@KnownFailure("This Characterset is not properly supported in Android!")
@Override
public void test_Encode() throws CharacterCodingException {
super.test_Encode();
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@KnownFailure("This Characterset is mapped to GBK Android!")
@Override
public void test_nameMatch() {
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GBK.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GBK.java
index 6b919ef..2546e58 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GBK.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GBK.java
@@ -29,8 +29,10 @@
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
-// SEE correspondig_Android test class:
-//@TestTargetClass(targets.Charsets.GBK.class)
+@TestTargetClass(targets.Charsets.GBK.class)
+/** @hide
+ * SEE correspondig_Android test class:
+ */
public class Charset_MultiByte_GBK extends Charset_AbstractTest {
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GBK_Android.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GBK_Android.java
index 0e80bd0..e036607 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GBK_Android.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GBK_Android.java
@@ -15,21 +15,11 @@
*/
package tests.api.java.nio.charset;
-import dalvik.annotation.TestLevel;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
-import junit.framework.TestCase;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CodingErrorAction;
@TestTargetClass(targets.Charsets.GBK.class)
+@AndroidOnly("icu different from RI")
public class Charset_MultiByte_GBK_Android extends Charset_AbstractTest {
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_ISO_2022_JP.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_ISO_2022_JP.java
index 54fd399..3f1afb5 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_ISO_2022_JP.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_ISO_2022_JP.java
@@ -16,7 +16,9 @@
package tests.api.java.nio.charset;
import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
import java.nio.charset.CharacterCodingException;
@@ -368,18 +370,32 @@
super.setUp();
}
- @KnownFailure("This Characterset is not properly supported in Android!")
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@Override
public void test_CodecDynamic() throws CharacterCodingException {
super.test_CodecDynamic();
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@KnownFailure("This Characterset is not properly supported in Android!")
@Override
public void test_Decode() throws CharacterCodingException {
super.test_Decode();
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@KnownFailure("This Characterset is not properly supported in Android!")
@Override
public void test_Encode() throws CharacterCodingException {
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_UTF_16.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_UTF_16.java
index 1d93f54..6b71385 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_UTF_16.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_UTF_16.java
@@ -29,8 +29,10 @@
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
-// SEE correspondig_Android test class:
-//@TestTargetClass(targets.Charsets.UTF_16.class)
+@TestTargetClass(targets.Charsets.UTF_16.class)
+/** @hide
+ * SEE correspondig_Android test class:
+ */
public class Charset_MultiByte_UTF_16 extends Charset_AbstractTest {
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_UTF_16_Android.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_UTF_16_Android.java
index ac351d1..787deca 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_UTF_16_Android.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_UTF_16_Android.java
@@ -15,21 +15,11 @@
*/
package tests.api.java.nio.charset;
-import dalvik.annotation.TestLevel;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
-import junit.framework.TestCase;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CodingErrorAction;
@TestTargetClass(targets.Charsets.UTF_16.class)
+@AndroidOnly("icu different from RI")
public class Charset_MultiByte_UTF_16_Android extends Charset_AbstractTest {
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_x_windows_950.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_x_windows_950.java
index ea8fd6b..5a1faa2 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_x_windows_950.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_x_windows_950.java
@@ -16,7 +16,9 @@
package tests.api.java.nio.charset;
import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
import java.nio.charset.CharacterCodingException;
@@ -224,24 +226,43 @@
super.setUp();
}
- @KnownFailure("This Characterset is not properly supported in Android!")
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@Override
public void test_CodecDynamic() throws CharacterCodingException {
super.test_CodecDynamic();
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@KnownFailure("This Characterset is not properly supported in Android!")
@Override
public void test_Decode() throws CharacterCodingException {
super.test_Decode();
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@KnownFailure("This Characterset is not properly supported in Android!")
@Override
public void test_Encode() throws CharacterCodingException {
super.test_Encode();
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
@KnownFailure("This Characterset is mapped to Big5 Android!")
@Override
public void test_nameMatch() {
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_IBM864.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_IBM864.java
index 45a3a39..02b6a3b 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_IBM864.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_IBM864.java
@@ -15,21 +15,15 @@
*/
package tests.api.java.nio.charset;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
-import junit.framework.TestCase;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CodingErrorAction;
@TestTargetClass(targets.Charsets.IBM864.class)
+@AndroidOnly("icu different from RI")
public class Charset_SingleByte_IBM864 extends Charset_SingleByteAbstractTest {
@@ -75,12 +69,17 @@
super.setUp();
}
- public static void _test_Bytes_DifferentOnes_RI() throws CharacterCodingException {
- decodeReplace(
- theseBytes(new int[]{26, 28, 37, 127, 159, 215, 216, 241}),
- new char[] {26, 28, 1642, 127, 65533, 65217, 65221, 1617} );
- }
+// public static void _test_Bytes_DifferentOnes_RI() throws CharacterCodingException {
+// decodeReplace(
+// theseBytes(new int[]{26, 28, 37, 127, 159, 215, 216, 241}),
+// new char[] {26, 28, 1642, 127, 65533, 65217, 65221, 1617} );
+// }
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
public static void test_Bytes_DifferentOnes_Android() throws CharacterCodingException {
// Android:
decodeReplace(
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_ISO_8859_3.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_ISO_8859_3.java
index 272e517..8da07d5 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_ISO_8859_3.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_ISO_8859_3.java
@@ -55,6 +55,11 @@
super.setUp();
}
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
public static void test_Bytes_166() throws CharacterCodingException {
decodeReplace(
new byte[] {(byte)166},
@@ -70,18 +75,33 @@
// outputCB.array());
}
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
public static void test_Bytes_195() throws CharacterCodingException {
decodeReplace(
new byte[] {(byte)195},
new char[] {65533} );
}
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
public static void test_Bytes_165() throws CharacterCodingException {
decodeReplace(
new byte[] {(byte)165},
new char[] {65533} );
}
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
public static void test_Bytes_165_any() throws CharacterCodingException {
decodeReplace(
new byte[] {(byte)165, 32},
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_x_IBM874.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_x_IBM874.java
index 12ffff2..e538206 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_x_IBM874.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/Charset_SingleByte_x_IBM874.java
@@ -15,21 +15,15 @@
*/
package tests.api.java.nio.charset;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
-import junit.framework.TestCase;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CodingErrorAction;
@TestTargetClass(targets.Charsets.x_IBM874.class)
+@AndroidOnly("icu different from RI")
public class Charset_SingleByte_x_IBM874 extends Charset_SingleByteAbstractTest {
@@ -58,12 +52,17 @@
super.setUp();
}
- public static void _test_Bytes_DifferentOnes_RI() throws CharacterCodingException {
- decodeReplace(
- theseBytes(new int[]{26, 28, 127, 128}),
- new char[] {26, 28, 127, 8364} );
- }
+// public static void _test_Bytes_DifferentOnes_RI() throws CharacterCodingException {
+// decodeReplace(
+// theseBytes(new int[]{26, 28, 127, 128}),
+// new char[] {26, 28, 127, 8364} );
+// }
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "functionalCoDec_REPR",
+ args = {}
+ )
public static void test_Bytes_DifferentOnes_Android() throws CharacterCodingException {
// Android:
decodeReplace(
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/ISOCharsetTest.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/ISOCharsetTest.java
index e001292..41e2d3b 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/ISOCharsetTest.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/ISOCharsetTest.java
@@ -31,8 +31,8 @@
/**
* Constructor.
*/
- public ISOCharsetTest(String arg0) {
- super(arg0, "ISO-8859-1", new String[] { "iso-ir-100", "8859_1",
+ public ISOCharsetTest() {
+ super("ISO-8859-1", new String[] { "iso-ir-100", "8859_1",
"ISO_8859-1", "ISO8859_1", "819", "csISOLatin1", "IBM-819",
"ISO_8859-1:1987", "latin1", "cp819", "ISO8859-1", "IBM819",
"ISO_8859_1", "l1" }, true, true);
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16BECharsetTest.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16BECharsetTest.java
index d7f4866..0ca8bd3 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16BECharsetTest.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16BECharsetTest.java
@@ -31,8 +31,8 @@
/**
* Constructor.
*/
- public UTF16BECharsetTest(String arg0) {
- super(arg0, "UTF-16BE", new String[] { "X-UTF-16BE", "UTF_16BE" },
+ public UTF16BECharsetTest() {
+ super("UTF-16BE", new String[] { "X-UTF-16BE", "UTF_16BE" },
true, true); // "ISO-10646-UCS-2"
}
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16CharsetTest.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16CharsetTest.java
index 4972abe..a0026a1 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16CharsetTest.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16CharsetTest.java
@@ -31,8 +31,8 @@
/**
* Constructor.
*/
- public UTF16CharsetTest(String arg0) {
- super(arg0, "UTF-16", new String[] { "UTF_16" }, true, true);
+ public UTF16CharsetTest() {
+ super("UTF-16", new String[] { "UTF_16" }, true, true);
}
/*
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16LECharsetTest.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16LECharsetTest.java
index 3189a15..3df7536 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16LECharsetTest.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF16LECharsetTest.java
@@ -31,8 +31,8 @@
/**
* Constructor.
*/
- public UTF16LECharsetTest(String arg0) {
- super(arg0, "UTF-16LE", new String[] { "UTF_16LE", "X-UTF-16LE" },
+ public UTF16LECharsetTest() {
+ super("UTF-16LE", new String[] { "UTF_16LE", "X-UTF-16LE" },
true, true);
}
diff --git a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF8CharsetTest.java b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF8CharsetTest.java
index 1df2def..b9ebbb8 100644
--- a/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF8CharsetTest.java
+++ b/libcore/nio_char/src/test/java/tests/api/java/nio/charset/UTF8CharsetTest.java
@@ -32,8 +32,8 @@
* Constructor for UTF8CharsetTest.
*
*/
- public UTF8CharsetTest(String arg0) {
- super(arg0, "UTF-8", new String[] { "UTF8" }, true, true);
+ public UTF8CharsetTest() {
+ super("UTF-8", new String[] { "UTF8" }, true, true);
}
/*
diff --git a/libcore/openssl/src/main/native/BNInterface.c b/libcore/openssl/src/main/native/BNInterface.c
index 6026d55..4132e4f 100644
--- a/libcore/openssl/src/main/native/BNInterface.c
+++ b/libcore/openssl/src/main/native/BNInterface.c
@@ -421,10 +421,10 @@
// FIXME: Currently ignoring array passed in to:
returnJBytes = (*env)->NewByteArray(env, byteCnt);
// FIXME: is it neccessary to check for returnJBytes != NULL?
- tmpBytes = (unsigned char *)((*env)->GetPrimitiveArrayCritical(env, returnJBytes, 0));
+ tmpBytes = (unsigned char *)((*env)->GetPrimitiveArrayCritical(env, returnJBytes, NULL));
if (tmpBytes != NULL) {
len = BN_bn2bin(a, tmpBytes);
- (*env)->ReleasePrimitiveArrayCritical(env, returnJBytes, tmpBytes, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, returnJBytes, tmpBytes, 0);
return returnJBytes;
}
else return NULL;
@@ -443,10 +443,10 @@
// FIXME: Currently ignoring array passed in to:
returnJInts = (*env)->NewIntArray(env, len);
// FIXME: is it neccessary to check for returnJBytes != NULL?
- BN_ULONG* tmpInts = (BN_ULONG*)((*env)->GetPrimitiveArrayCritical(env, returnJInts, 0));
+ BN_ULONG* tmpInts = (BN_ULONG*)((*env)->GetPrimitiveArrayCritical(env, returnJInts, NULL));
if (tmpInts != NULL) {
int i = len; do { i--; tmpInts[i] = a->d[i]; } while (i > 0);
- (*env)->ReleasePrimitiveArrayCritical(env, returnJInts, tmpInts, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, returnJInts, tmpInts, 0);
return returnJInts;
}
else return NULL;
@@ -468,10 +468,10 @@
// FIXME: Currently ignoring array passed in to:
returnJBytes = (*env)->NewByteArray(env, byteCnt);
// FIXME: is it neccessary to check for returnJBytes != NULL?
- tmpBytes = (unsigned char *)((*env)->GetPrimitiveArrayCritical(env, returnJBytes, 0));
+ tmpBytes = (unsigned char *)((*env)->GetPrimitiveArrayCritical(env, returnJBytes, NULL));
if (tmpBytes != NULL) {
len = BN_bn2bin(a, tmpBytes);
- (*env)->ReleasePrimitiveArrayCritical(env, returnJBytes, tmpBytes, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, returnJBytes, tmpBytes, 0);
return returnJBytes;
}
else return NULL;
diff --git a/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AbstractPreferencesTest.java b/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AbstractPreferencesTest.java
index f53a579..80f663c 100644
--- a/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AbstractPreferencesTest.java
+++ b/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AbstractPreferencesTest.java
@@ -49,24 +49,18 @@
protected void setUp() throws Exception {
super.setUp();
+ Preferences.systemRoot().clear();
+ Preferences.userRoot().clear();
+
parent = (AbstractPreferences) Preferences.userNodeForPackage(this.getClass());
-/*
- String str[] = parent.childrenNames();
- for (int i = 0; i < str.length; i++) {
- System.out.print(str[i] + " ");
- }
- System.out.println();
-/**/
+
pref = (AbstractPreferences) parent.node(nodeName);
}
protected void tearDown() throws Exception {
-/* String str[] = parent.childrenNames();
- for (int i = 0; i < str.length; i++) {
- System.out.print(str[i] + " ");
- }
- System.out.println();/**/
parent.removeNode();
+ Preferences.systemRoot().clear();
+ Preferences.userRoot().clear();
super.tearDown();
}
diff --git a/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java b/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java
index 7f7c296..3e1a377 100644
--- a/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java
+++ b/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java
@@ -16,16 +16,14 @@
package org.apache.harmony.prefs.tests.java.util.prefs;
-import dalvik.annotation.BrokenTest;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import java.io.FilePermission;
-import java.io.IOException;
import java.security.Permission;
-import java.util.prefs.AbstractPreferences;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
@@ -34,28 +32,15 @@
@TestTargetClass(java.util.prefs.Preferences.class)
public class FilePreferencesImplTest extends TestCase {
- private String prevFactory;
- private Preferences uroot;
- private Preferences sroot;
-
public FilePreferencesImplTest() {
super();
}
- protected void setUp() throws Exception {
- // prevFactory = System.getProperty("java.util.prefs.PreferencesFactory");
- // System.setProperty("java.util.prefs.PreferencesFactory", "java.util.prefs.FilePreferencesFactoryImpl");
-
- // uroot = (AbstractPreferences) Preferences.userRoot();
- uroot = Preferences.userRoot();
- sroot = Preferences.systemRoot();
+ @Override
+ protected void setUp(){
}
-
- protected void tearDown() throws Exception {
- // if (prevFactory != null)
- // System.setProperty("java.util.prefs.PreferencesFactory", prevFactory);
- uroot = null;
- sroot = null;
+ @Override
+ protected void tearDown(){
}
@TestTargets({
@@ -78,7 +63,8 @@
args = {}
)
})
- public void testPutGet() throws IOException, BackingStoreException {
+ public void testUserPutGet() throws BackingStoreException {
+ Preferences uroot = Preferences.userRoot().node("test");
uroot.put("ukey1", "value1");
assertEquals("value1", uroot.get("ukey1", null));
String[] names = uroot.keys();
@@ -94,7 +80,30 @@
uroot.clear();
names = uroot.keys();
assertEquals(0, names.length);
+ }
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed, but method is abstract, probably it is OK",
+ method = "put",
+ args = {java.lang.String.class, java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed, but method is abstract, probably it is OK",
+ method = "get",
+ args = {java.lang.String.class, java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed, but method is abstract, probably it is OK",
+ method = "keys",
+ args = {}
+ )
+ })
+ public void testSystemPutGet() throws BackingStoreException {
+ Preferences sroot = Preferences.systemRoot().node("test");
sroot.put("skey1", "value1");
assertEquals("value1", sroot.get("skey1", null));
sroot.put("\u4e2d key1", "\u4e2d value1");
@@ -107,65 +116,74 @@
method = "childrenNames",
args = {}
)
- @BrokenTest("Checking of childNames.length is not valid because of " +
- "it depends on .userPrefs")
- public void testChildNodes() throws Exception {
-
+ public void testUserChildNodes() throws Exception {
+ Preferences uroot = Preferences.userRoot().node("test");
+
Preferences child1 = uroot.node("child1");
Preferences child2 = uroot.node("\u4e2d child2");
Preferences grandchild = child1.node("grand");
assertNotNull(grandchild);
String[] childNames = uroot.childrenNames();
- for (int i = 0; i < childNames.length; i++) {
- System.out.println("test:" + childNames[i]);
- }
- assertEquals(4, childNames.length);
+ assertContains(childNames, "child1");
+ assertContains(childNames, "\u4e2d child2");
+ assertNotContains(childNames, "grand");
childNames = child1.childrenNames();
- assertEquals(1, childNames.length);
- for (int i = 0; i < childNames.length; i++) {
- System.out.println(childNames[i]);
- }
+ assertContains(childNames, "grand");
childNames = child2.childrenNames();
assertEquals(0, childNames.length);
- for (int i = 0; i < childNames.length; i++) {
- System.out.println(childNames[i]);
- }
child1.removeNode();
childNames = uroot.childrenNames();
- assertEquals(3, childNames.length);
- for (int i = 0; i < childNames.length; i++) {
- System.out.println(childNames[i]);
- }
- // child2.removeNode();
- // childNames = uroot.childrenNames();
- // assertEquals(0, childNames.length);
+ assertNotContains(childNames, "child1");
+ assertContains(childNames, "\u4e2d child2");
+ assertNotContains(childNames, "grand");
- child1 = sroot.node("child1");
- child2 = sroot.node("child2");
- grandchild = child1.node("grand");
+ child2.removeNode();
+ childNames = uroot.childrenNames();
+ assertNotContains(childNames, "child1");
+ assertNotContains(childNames, "\u4e2d child2");
+ assertNotContains(childNames, "grand");
+ }
- childNames = sroot.childrenNames();
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed, but method is abstract, probably it is OK",
+ method = "childrenNames",
+ args = {}
+ )
+ @AndroidOnly("It seems like the RI can't remove nodes created in the system root.")
+ public void testSystemChildNodes() throws Exception {
+ Preferences sroot = Preferences.systemRoot().node("test");
- for (int i = 0; i < childNames.length; i++) {
- System.out.println(childNames[i]);
- }
- // assertEquals(2, childNames.length);
+ Preferences child1 = sroot.node("child1");
+ Preferences child2 = sroot.node("child2");
+ Preferences grandchild = child1.node("grand");
+
+ String[] childNames = sroot.childrenNames();
+ assertContains(childNames, "child1");
+ assertContains(childNames, "child2");
+ assertNotContains(childNames, "grand");
childNames = child1.childrenNames();
assertEquals(1, childNames.length);
- for (int i = 0; i < childNames.length; i++) {
- System.out.println(childNames[i]);
- }
childNames = child2.childrenNames();
assertEquals(0, childNames.length);
- for (int i = 0; i < childNames.length; i++) {
- System.out.println(childNames[i]);
- }
+
+ child1.removeNode();
+ childNames = sroot.childrenNames();
+ assertNotContains(childNames, "child1");
+ assertContains(childNames, "child2");
+ assertNotContains(childNames, "grand");
+
+ child2.removeNode();
+ childNames = sroot.childrenNames();
+ assertNotContains(childNames, "child1");
+ assertNotContains(childNames, "child2");
+ assertNotContains(childNames, "grand");
}
@TestTargets({
@@ -201,6 +219,8 @@
)
})
public void testSecurityException() throws BackingStoreException {
+ Preferences uroot = Preferences.userRoot().node("test");
+
Preferences child1 = uroot.node("child1");
MockFileSecurityManager manager = new MockFileSecurityManager();
manager.install();
@@ -243,6 +263,23 @@
}
}
+ private void assertContains(String[] childNames, String name) {
+ for (String childName : childNames) {
+ if (childName == name) {
+ return;
+ }
+ }
+ fail("No child with name " + name + " was found. It was expected to exist.");
+ }
+
+ private void assertNotContains(String[] childNames, String name) {
+ for (String childName : childNames) {
+ if (childName == name) {
+ fail("Child with name " + name + " was found. This was unexpected.");
+ }
+ }
+ }
+
static class MockFileSecurityManager extends SecurityManager {
SecurityManager dflt;
diff --git a/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java b/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
index 2221cc5..9d526d6 100644
--- a/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
+++ b/libcore/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
@@ -45,6 +45,9 @@
@TestTargetClass(Preferences.class)
public class PreferencesTest extends TestCase {
+ private String oldJavaHome;
+ private String oldUserHome;
+
MockSecurityManager manager = new MockSecurityManager();
MockInputStream stream = null;
@@ -77,18 +80,10 @@
"<!DOCTYPE preferences SYSTEM \"http://java.sun.com/dtd/preferences.dtd\"><preferences><root type=\"user\"><map></map></root></preferences>"
.getBytes("UTF-8"));
stream = new MockInputStream(in);
-
- String userHome = System.getProperty("user.home");
- if (userHome != null) {
- File userHomeDir = new File(userHome);
- if (!userHomeDir.isDirectory() || !userHomeDir.canWrite()) {
- userHome = null;
- }
- }
- if (userHome == null) {
- System.setProperty("user.home", System.getProperty("java.io.tmpdir"));
- }
-
+
+ Preferences.systemRoot().clear();
+ Preferences.userRoot().clear();
+
Preferences p = Preferences.userNodeForPackage(Preferences.class);
p.clear();
try {
@@ -109,6 +104,9 @@
p.removeNode();
} catch (BackingStoreException e) {
}
+
+ Preferences.systemRoot().clear();
+ Preferences.userRoot().clear();
}
@TestTargetNew(
@@ -146,7 +144,7 @@
}
try {
- p = Preferences.userNodeForPackage(null);
+ p = Preferences.systemNodeForPackage(null);
fail("NullPointerException has not been thrown");
} catch (NullPointerException e) {
// expected
diff --git a/libcore/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java b/libcore/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
index 21672b7..f70f9f1 100644
--- a/libcore/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
+++ b/libcore/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
@@ -86,16 +86,6 @@
final static int DEFAULT_FLAGS = 0;
- /**
- * Constructor for PatternTest.
- *
- * @param name
- */
- public PatternTest(String name) {
- super(name);
- }
-
-
@TestTargetNew(
level = TestLevel.ADDITIONAL,
notes = "TODO empty test",
diff --git a/libcore/run-core-tests b/libcore/run-core-tests
index 3656e2d..25e53ee 100755
--- a/libcore/run-core-tests
+++ b/libcore/run-core-tests
@@ -26,6 +26,5 @@
chmod 777 $tmp
exec dalvikvm -Duser.language=en -Duser.region=US -Djava.io.tmpdir=$tmp \
- -Xbootclasspath:$BOOTCLASSPATH \
- -classpath /system/framework/core-tests.jar \
+ -Xbootclasspath:$BOOTCLASSPATH:/system/framework/core-tests.jar \
com.google.coretests.Main "$@"
diff --git a/libcore/security/src/main/java/java/security/Security.java b/libcore/security/src/main/java/java/security/Security.java
index 78abdb7..d5c77dc 100644
--- a/libcore/security/src/main/java/java/security/Security.java
+++ b/libcore/security/src/main/java/java/security/Security.java
@@ -181,7 +181,9 @@
if (algName == null || propName == null) {
return null;
}
- String prop = propName + "." + algName; //$NON-NLS-1$
+ // BEGIN android-changed
+ String prop = "Alg." + propName + "." + algName; //$NON-NLS-1$
+ // END android-changed
Provider[] providers = getProviders();
for (int i = 0; i < providers.length; i++) {
for (Enumeration e = providers[i].propertyNames(); e
diff --git a/libcore/security/src/main/java/org/apache/harmony/security/fortress/Services.java b/libcore/security/src/main/java/org/apache/harmony/security/fortress/Services.java
index 2e92d82..300854a 100644
--- a/libcore/security/src/main/java/org/apache/harmony/security/fortress/Services.java
+++ b/libcore/security/src/main/java/org/apache/harmony/security/fortress/Services.java
@@ -44,7 +44,11 @@
// The HashMap that contains information about preferred implementations for
// all serviceName.algName in the registered providers
- private static final Map<String, Provider.Service> services = new HashMap<String, Provider.Service>(512);
+ // BEGIN android-changed
+ // set the initial size to 600 so we don't grow to 1024 by default because
+ // initialization adds a few entries more than the growth threshold.
+ private static final Map<String, Provider.Service> services = new HashMap<String, Provider.Service>(600);
+ // END android-changed
// Need refresh flag
private static boolean needRefresh; // = false;
diff --git a/libcore/security/src/main/java/org/apache/harmony/security/internal/nls/messages.properties b/libcore/security/src/main/java/org/apache/harmony/security/internal/nls/messages.properties
index 9a73b51..7fb0b4b 100644
--- a/libcore/security/src/main/java/org/apache/harmony/security/internal/nls/messages.properties
+++ b/libcore/security/src/main/java/org/apache/harmony/security/internal/nls/messages.properties
@@ -133,6 +133,7 @@
security.15B3=Bad Certificate encoding.
security.15B4=Bad CRL encoding.
security.15C=Signature was not verified.
+security.15C1=key is not instanceof RSAPublicKey
security.15D=One of provided certificates is not X509 certificate
security.15E=Incorrect encoded form: {0}
security.15F=Unsupported encoding.
diff --git a/libcore/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertImpl.java b/libcore/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertImpl.java
index 20e73bd..3face61 100644
--- a/libcore/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertImpl.java
+++ b/libcore/security/src/main/java/org/apache/harmony/security/provider/cert/X509CertImpl.java
@@ -567,8 +567,13 @@
* @param key The RSA public key to use
*
* @throws SignatureException If the verification fails.
+ * @throws InvalidKeyException
*/
- private void fastVerify(PublicKey key) throws SignatureException {
+ private void fastVerify(PublicKey key) throws SignatureException,
+ InvalidKeyException {
+ if (!(key instanceof RSAPublicKey)) {
+ throw new InvalidKeyException(Messages.getString("security.15C1"));
+ }
RSAPublicKey rsaKey = (RSAPublicKey) key;
String algorithm = getSigAlgName();
diff --git a/libcore/security/src/main/java/org/bouncycastle/asn1/x509/X509NameTokenizer.java b/libcore/security/src/main/java/org/bouncycastle/asn1/x509/X509NameTokenizer.java
index 035e924..8f0d08b 100644
--- a/libcore/security/src/main/java/org/bouncycastle/asn1/x509/X509NameTokenizer.java
+++ b/libcore/security/src/main/java/org/bouncycastle/asn1/x509/X509NameTokenizer.java
@@ -66,6 +66,17 @@
{
if (escaped || quoted)
{
+ // BEGIN android-added
+ // copied from a newer version of BouncyCastle
+ if (c == '#' && buf.charAt(buf.length() - 1) == '=')
+ {
+ buf.append('\\');
+ }
+ else if (c == '+' && seperator != '+')
+ {
+ buf.append('\\');
+ }
+ // END android-added
buf.append(c);
escaped = false;
}
@@ -88,4 +99,4 @@
index = end;
return buf.toString().trim();
}
-}
+}
\ No newline at end of file
diff --git a/libcore/security/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java b/libcore/security/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java
index 12000aa..aaa6015 100644
--- a/libcore/security/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java
+++ b/libcore/security/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java
@@ -121,7 +121,8 @@
public static byte[] PKCS12PasswordToBytes(
char[] password)
{
- if (password.length > 0)
+ // BEGIN android-changed
+ if (password != null && password.length > 0)
{
// +1 for extra 2 pad bytes.
byte[] bytes = new byte[(password.length + 1) * 2];
@@ -138,5 +139,6 @@
{
return new byte[0];
}
+ // END android-changed
}
}
diff --git a/libcore/security/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/libcore/security/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
index d802228..d9f4727 100644
--- a/libcore/security/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
+++ b/libcore/security/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
@@ -112,7 +112,10 @@
// END android-removed
put("AlgorithmParameters.IES", "org.bouncycastle.jce.provider.JDKAlgorithmParameters$IES");
put("AlgorithmParameters.PKCS12PBE", "org.bouncycastle.jce.provider.JDKAlgorithmParameters$PKCS12PBE");
- put("AlgorithmParameters.1.2.840.113549.3.7", "org.bouncycastle.jce.provider.JDKAlgorithmParameters$IVAlgorithmParameters");
+ // BEGIN android-removed
+ // double entry
+ // put("AlgorithmParameters.1.2.840.113549.3.7", "org.bouncycastle.jce.provider.JDKAlgorithmParameters$IVAlgorithmParameters");
+ // END android-removed
// BEGIN android-removed
// put("AlgorithmParameters.IDEA", "org.bouncycastle.jce.provider.JDKAlgorithmParameters$IDEAAlgorithmParameters");
// put("AlgorithmParameters.1.3.6.1.4.1.188.7.1.1.2", "org.bouncycastle.jce.provider.JDKAlgorithmParameters$IDEAAlgorithmParameters");
@@ -171,12 +174,14 @@
put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND192BITAES-CBC-BC","PKCS12PBE");
put("Alg.Alias.AlgorithmParameters.PBEWITHSHA-256AND256BITAES-CBC-BC","PKCS12PBE");
- put("AlgorithmParameters.SHA1WITHECDSA", "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters");
- put("AlgorithmParameters.SHA224WITHECDSA", "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters");
- put("AlgorithmParameters.SHA256WITHECDSA", "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters");
- put("AlgorithmParameters.SHA384WITHECDSA", "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters");
- put("AlgorithmParameters.SHA512WITHECDSA", "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters");
-
+ // BEGIN android-removed
+ // put("AlgorithmParameters.SHA1WITHECDSA", "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters");
+ // put("AlgorithmParameters.SHA224WITHECDSA", "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters");
+ // put("AlgorithmParameters.SHA256WITHECDSA", "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters");
+ // put("AlgorithmParameters.SHA384WITHECDSA", "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters");
+ // put("AlgorithmParameters.SHA512WITHECDSA", "org.bouncycastle.jce.provider.JDKECDSAAlgParameters$SigAlgParameters");
+ // END android-removed
+
//
// key agreement
//
@@ -491,9 +496,10 @@
put("Alg.Alias.KeyFactory.1.2.840.113549.1.1.1", "RSA");
put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
- put("Alg.Alias.KeyFactory." + X9ObjectIdentifiers.id_ecPublicKey, "EC");
+ // BEGIN android-removed
+ // put("Alg.Alias.KeyFactory." + X9ObjectIdentifiers.id_ecPublicKey, "EC");
- // END android-removed
+
// put("KeyFactory.GOST3410", "org.bouncycastle.jce.provider.JDKKeyFactory$GOST3410");
// put("Alg.Alias.KeyFactory.GOST-3410", "GOST3410");
// put("Alg.Alias.KeyFactory.GOST-3410-94", "GOST3410");
@@ -732,16 +738,18 @@
//
private void addMessageDigestAlgorithms()
{
- put("MessageDigest.SHA-1", "org.bouncycastle.jce.provider.JDKMessageDigest$SHA1");
- put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
- put("Alg.Alias.MessageDigest.SHA", "SHA-1");
- put("Alg.Alias.MessageDigest." + OIWObjectIdentifiers.idSHA1, "SHA-1");
- put("MessageDigest.SHA-224", "org.bouncycastle.jce.provider.JDKMessageDigest$SHA224");
- put("Alg.Alias.MessageDigest.SHA224", "SHA-224");
- put("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha224, "SHA-224");
- put("MessageDigest.SHA-256", "org.bouncycastle.jce.provider.JDKMessageDigest$SHA256");
- put("Alg.Alias.MessageDigest.SHA256", "SHA-256");
- put("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha256, "SHA-256");
+ // BEGIN android-removed
+ // put("MessageDigest.SHA-1", "org.bouncycastle.jce.provider.JDKMessageDigest$SHA1");
+ // put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
+ // put("Alg.Alias.MessageDigest.SHA", "SHA-1");
+ // put("Alg.Alias.MessageDigest." + OIWObjectIdentifiers.idSHA1, "SHA-1");
+ // put("MessageDigest.SHA-224", "org.bouncycastle.jce.provider.JDKMessageDigest$SHA224");
+ // put("Alg.Alias.MessageDigest.SHA224", "SHA-224");
+ // put("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha224, "SHA-224");
+ // put("MessageDigest.SHA-256", "org.bouncycastle.jce.provider.JDKMessageDigest$SHA256");
+ // put("Alg.Alias.MessageDigest.SHA256", "SHA-256");
+ // put("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha256, "SHA-256");
+ // END android-removed
put("MessageDigest.SHA-384", "org.bouncycastle.jce.provider.JDKMessageDigest$SHA384");
put("Alg.Alias.MessageDigest.SHA384", "SHA-384");
put("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha384, "SHA-384");
@@ -754,10 +762,8 @@
// put("Alg.Alias.MessageDigest." + PKCSObjectIdentifiers.md2, "MD2");
// put("MessageDigest.MD4", "org.bouncycastle.jce.provider.JDKMessageDigest$MD4");
// put("Alg.Alias.MessageDigest." + PKCSObjectIdentifiers.md4, "MD4");
- // END android-removed
- put("MessageDigest.MD5", "org.bouncycastle.jce.provider.JDKMessageDigest$MD5");
- put("Alg.Alias.MessageDigest." + PKCSObjectIdentifiers.md5, "MD5");
- // BEGIN android-removed
+ // put("MessageDigest.MD5", "org.bouncycastle.jce.provider.JDKMessageDigest$MD5");
+ // put("Alg.Alias.MessageDigest." + PKCSObjectIdentifiers.md5, "MD5");
// put("MessageDigest.RIPEMD128", "org.bouncycastle.jce.provider.JDKMessageDigest$RIPEMD128");
// put("Alg.Alias.MessageDigest." + TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128");
// put("MessageDigest.RIPEMD160", "org.bouncycastle.jce.provider.JDKMessageDigest$RIPEMD160");
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator1Test.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator1Test.java
index 85d6c71..1ff236a 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator1Test.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator1Test.java
@@ -49,14 +49,6 @@
*/
public class AlgorithmParameterGenerator1Test extends TestCase {
- /**
- * Constructor for AlgorithmParameterGeneratorTests.
- *
- * @param arg0
- */
- public AlgorithmParameterGenerator1Test(String arg0) {
- super(arg0);
- }
private static String[] invalidValues = SpiEngUtils.invalidValues;
private static String validAlgName = "DSA";
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator2Test.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator2Test.java
index efa8e04..c67822a 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator2Test.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator2Test.java
@@ -82,15 +82,6 @@
Security.removeProvider(mProv.getName());
}
- /**
- * Constructor for SecurityManagerFactoryTest2.
- *
- * @param arg0
- */
- public AlgorithmParameterGenerator2Test(String arg0) {
- super(arg0);
- }
-
private void checkResult(AlgorithmParameterGenerator algParGen)
throws InvalidAlgorithmParameterException {
AlgorithmParameters param = algParGen.generateParameters();
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersSpiTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersSpiTest.java
index 100c077..5ec3d96 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersSpiTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersSpiTest.java
@@ -35,14 +35,6 @@
@TestTargetClass(AlgorithmParametersSpi.class)
public class AlgorithmParametersSpiTest extends TestCase {
- /**
- * Constructor for AlgorithmParametersSpiTest.
- *
- * @param name
- */
- public AlgorithmParametersSpiTest(String name) {
- super(name);
- }
/**
* Test for <code>AlgorithmParametersSpi</code> constructor
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSignerTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSignerTest.java
index d02f2c7..e29d9ac 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSignerTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSignerTest.java
@@ -180,7 +180,7 @@
assertTrue(new CodeSigner(cpath, null).toString().contains(""));
assertTrue(new CodeSigner(cpath, ts).toString().contains(""));
- assertTrue(new CodeSigner(cpath, null).toString().contains("CodeSigner"));
+ assertTrue(new CodeSigner(cpath, null).toString().contains("Signer"));
assertTrue(new CodeSigner(cpath, ts).toString().contains(ts.toString()));
}
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSourceTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSourceTest.java
index ad59b99..276dfd7 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSourceTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSourceTest.java
@@ -83,45 +83,52 @@
private static URL urlFileDirStar;
private static URL urlRef1, urlRef2;
+
+ private boolean init = false;
- static {
- try {
- String siteName = "www.intel.com";
- InetAddress addr = InetAddress.getByName(siteName);
- String siteIP = addr.getHostAddress();
-
- urlSite = new URL("http://"+siteName+"");
- urlDir = new URL("http://"+siteName+"/drl_test");
- urlDirOtherSite = new URL("http://www.any-other-site-which-is-not-siteName.com/drl_test");
-
- urlDir_port80 = new URL("http://"+siteName+":80/drl_test");
- urlDir_port81 = new URL("http://"+siteName+":81/drl_test");
- urlDirWithSlash = new URL(urlDir + "/");
-
- //urlDirFtp = new URL("ftp://www.intel.com/drl_test");
- urlDir_FileProtocol = new URL("file://"+siteName+"/drl_test");
-
- urlDirIP = new URL("http://"+siteIP+"/drl_test");
-
- urlFile = new URL("http://"+siteName+"/drl_test/empty.jar");
- urlFileWithAdditionalDirs = new URL(
- "http://"+siteName+"/drl_test/what/ever/here/empty.jar");
-
- urlFileDirMinus = new URL("http://"+siteName+"/drl_test/-");
- urlFileDirStar = new URL("http://"+siteName+"/drl_test/*");
- urlFileDirOtherDir = new URL("http://"+siteName+"/_test_drl_/*");
-
- urlRef1 = new URL("http://"+siteName+"/drl_test/index.html#ref1");
- urlRef2 = new URL("http://"+siteName+"/drl_test/index.html#ref2");
- } catch (MalformedURLException ex) {
- throw new Error(ex);
- } catch (UnknownHostException ex) {
- throw new Error(ex);
+ private void init() {
+ if (!init) {
+ try {
+ String siteName = "www.intel.com";
+ InetAddress addr = InetAddress.getByName(siteName);
+ String siteIP = addr.getHostAddress();
+
+ urlSite = new URL("http://"+siteName+"");
+ urlDir = new URL("http://"+siteName+"/drl_test");
+ urlDirOtherSite = new URL("http://www.any-other-site-which-is-not-siteName.com/drl_test");
+
+ urlDir_port80 = new URL("http://"+siteName+":80/drl_test");
+ urlDir_port81 = new URL("http://"+siteName+":81/drl_test");
+ urlDirWithSlash = new URL(urlDir + "/");
+
+ //urlDirFtp = new URL("ftp://www.intel.com/drl_test");
+ urlDir_FileProtocol = new URL("file://"+siteName+"/drl_test");
+
+ urlDirIP = new URL("http://"+siteIP+"/drl_test");
+
+ urlFile = new URL("http://"+siteName+"/drl_test/empty.jar");
+ urlFileWithAdditionalDirs = new URL(
+ "http://"+siteName+"/drl_test/what/ever/here/empty.jar");
+
+ urlFileDirMinus = new URL("http://"+siteName+"/drl_test/-");
+ urlFileDirStar = new URL("http://"+siteName+"/drl_test/*");
+ urlFileDirOtherDir = new URL("http://"+siteName+"/_test_drl_/*");
+
+ urlRef1 = new URL("http://"+siteName+"/drl_test/index.html#ref1");
+ urlRef2 = new URL("http://"+siteName+"/drl_test/index.html#ref2");
+ } catch (MalformedURLException ex) {
+ throw new Error(ex);
+ } catch (UnknownHostException ex) {
+ throw new Error(ex);
+ } finally {
+ init = true;
+ }
}
}
protected void setUp() throws Exception {
super.setUp();
+ init();
chain = TestCertUtils.getCertChain();
}
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestExceptionTest.java
index f13cc92..b6f0fe2 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestExceptionTest.java
@@ -37,18 +37,6 @@
*/
public class DigestExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for DigestExceptionTests.
- *
- * @param arg0
- */
- public DigestExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestInputStreamTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestInputStreamTest.java
index 44f697b..0eed898 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestInputStreamTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestInputStreamTest.java
@@ -70,14 +70,6 @@
*/
private static final int MY_MESSAGE_LEN = myMessage.length;
- /**
- * Constructor for DigestInputStreamTest.
- * @param name
- */
- public DigestInputStreamTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestOutputStreamTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestOutputStreamTest.java
index 794a10b..8309c87 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestOutputStreamTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/DigestOutputStreamTest.java
@@ -75,14 +75,6 @@
*/
private static final int MY_MESSAGE_LEN = myMessage.length;
- /**
- * Constructor for DigestInputStreamTest.
- * @param name
- */
- public DigestOutputStreamTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/GeneralSecurityExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/GeneralSecurityExceptionTest.java
index 7cc9d37..5bdd450 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/GeneralSecurityExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/GeneralSecurityExceptionTest.java
@@ -38,18 +38,6 @@
*/
public class GeneralSecurityExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for GeneralSecurityExceptionTests.
- *
- * @param arg0
- */
- public GeneralSecurityExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
index 962a775..55e2fd2 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
@@ -32,7 +32,7 @@
import org.apache.harmony.security.tests.java.security.IdentityScope2Test.IdentityScopeSubclass;
-import dalvik.annotation.KnownFailure;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -244,7 +244,8 @@
args = {java.lang.String.class, java.security.IdentityScope.class}
)
public void test_ConstructorLjava_lang_StringLjava_security_IdentityScope() {
- String[] str = {"test", "", "!@#$%^&*()", "identity name", null};
+ String nameNull = null;
+ String[] str = {"test", "", "!@#$%^&*()", "identity name"};
IdentityScopeSubclass iss = new IdentityScopeSubclass("name");
IdentitySubclass is;
@@ -254,11 +255,19 @@
assertNotNull(is);
assertTrue(is instanceof Identity);
} catch (Exception e) {
+ System.out.println(e);
fail("Unexpected exception for parameter " + str[i]);
}
}
try {
+ is = new IdentitySubclass(nameNull, new IdentityScopeSubclass());
+ } catch (NullPointerException npe) {
+ } catch (Exception e) {
+ fail("Incorrect exception " + e + " was thrown");
+ }
+
+ try {
is = new IdentitySubclass("test", iss);
is = new IdentitySubclass("test", iss);
fail("KeyManagementException was not thrown");
@@ -373,7 +382,8 @@
args = {java.security.Certificate.class}
)
})
- @KnownFailure("Test 3 disabled because the exception is never thrown.")
+ @AndroidOnly("Spec says: Removing unknown certificates throw an exception. "
+ + "The RI ignores unknown certificates.")
public void test_removeCertificateLjava_security_Certificate() throws Exception {
IdentitySubclass sub = new IdentitySubclass("test",
new IdentityScopeSubclass());
@@ -384,21 +394,26 @@
CertificateImpl certImpl = new CertificateImpl(cert[0]);
sub.addCertificate(certImpl);
- sub.removeCertificate(null);
- assertEquals("Test 1: Certificate should not have been removed.",
+ try {
+ sub.removeCertificate(null);
+ fail("Test 1: KeyManagementException expected.");
+ } catch (KeyManagementException e) {
+ // Expected.
+ }
+ assertEquals("Test 2: Certificate should not have been removed.",
1, sub.certificates().length);
sub.removeCertificate(certImpl);
- assertEquals("Test 2: Certificate has not been removed.",
+ assertEquals("Test 3: Certificate has not been removed.",
0, sub.certificates().length);
// Removing the same certificate a second time should fail.
-// try {
-// sub.removeCertificate(certImpl);
-// fail("Test 3: KeyManagementException expected.");
-// } catch (KeyManagementException e) {
-// // Expected.
-// }
+ try {
+ sub.removeCertificate(certImpl);
+ fail("Test 4: KeyManagementException expected.");
+ } catch (KeyManagementException e) {
+ // Expected.
+ }
}
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScope2Test.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScope2Test.java
index c97a7f3..3fca2fa 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScope2Test.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScope2Test.java
@@ -166,7 +166,8 @@
args = {java.lang.String.class, java.security.IdentityScope.class}
)
public void test_ConstructorLjava_lang_StringLjava_security_IdentityScope() {
- String[] str = {"test", "", "!@#$%^&*()", "identity name", null};
+ String nameNull = null;
+ String[] str = {"test", "", "!@#$%^&*()", "identity name"};
IdentityScope is;
IdentityScope iss = new IdentityScopeSubclass("test scope");
@@ -181,6 +182,13 @@
}
try {
+ is = new IdentityScopeSubclass(nameNull, new IdentityScopeSubclass());
+ } catch (NullPointerException npe) {
+ } catch (Exception e) {
+ fail("Incorrect exception " + e + " was thrown");
+ }
+
+ try {
is = new IdentityScopeSubclass("test", iss);
is = new IdentityScopeSubclass("test", iss);
fail("KeyManagementException was not thrown");
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScopeTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScopeTest.java
index 109c776..5b1ea7f 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScopeTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScopeTest.java
@@ -58,14 +58,6 @@
IdentityScope is;
/**
- * Constructor for IdentityScopeTest.
- * @param arg0
- */
- public IdentityScopeTest(String arg0) {
- super(arg0);
- }
-
- /**
* Class under test for String toString()
*/
@TestTargetNew(
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidAlgorithmParameterExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidAlgorithmParameterExceptionTest.java
index a4848fd..849f29c 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidAlgorithmParameterExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidAlgorithmParameterExceptionTest.java
@@ -38,18 +38,6 @@
*/
public class InvalidAlgorithmParameterExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for InvalidAlgorithmParameterExceptionTests.
- *
- * @param arg0
- */
- public InvalidAlgorithmParameterExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidKeyExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidKeyExceptionTest.java
index fb08d32..5f5f7da 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidKeyExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidKeyExceptionTest.java
@@ -37,18 +37,6 @@
*/
public class InvalidKeyExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for InvalidKeyExceptionTests.
- *
- * @param arg0
- */
- public InvalidKeyExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidParameterExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidParameterExceptionTest.java
index c6442d8..c22b903 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidParameterExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/InvalidParameterExceptionTest.java
@@ -38,18 +38,6 @@
*/
public class InvalidParameterExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for InvalidParameterExceptionTests.
- *
- * @param arg0
- */
- public InvalidParameterExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSCallbackHandlerProtectionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSCallbackHandlerProtectionTest.java
index 8c64110..056d7eb 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSCallbackHandlerProtectionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSCallbackHandlerProtectionTest.java
@@ -46,14 +46,6 @@
public class KSCallbackHandlerProtectionTest extends TestCase {
/**
- * Constructor for KSCallbackHandlerProtectionTest.
- * @param arg0
- */
- public KSCallbackHandlerProtectionTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>KeyStore.CallbackHandlerProtection(CallbackHandler handler)</code>
* constructor
* Assertion: throws NullPointerException when handler is null
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPasswordProtectionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPasswordProtectionTest.java
index 5bbe687..0c8ec0a 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPasswordProtectionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPasswordProtectionTest.java
@@ -41,14 +41,6 @@
public class KSPasswordProtectionTest extends TestCase {
/**
- * Constructor for KSPasswordProtectionTest.
- * @param arg0
- */
- public KSPasswordProtectionTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>KeyStore.PasswordProtection(char[] password)</code> constructor
* and the following methods
* <code>getPassword()<code>
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPrivateKeyEntryTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPrivateKeyEntryTest.java
index 4be5d18..dc7880f 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPrivateKeyEntryTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPrivateKeyEntryTest.java
@@ -46,13 +46,6 @@
public class KSPrivateKeyEntryTest extends TestCase {
- /**
- * Constructor for KSPrivateKeyEntryTest.
- * @param arg0
- */
- public KSPrivateKeyEntryTest(String arg0) {
- super(arg0);
- }
private PrivateKey testPrivateKey;
private Certificate [] testChain;
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSSecretKeyEntryTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSSecretKeyEntryTest.java
index 58d7d0a..f4c995d 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSSecretKeyEntryTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KSSecretKeyEntryTest.java
@@ -41,13 +41,6 @@
public class KSSecretKeyEntryTest extends TestCase {
/**
- * Constructor for KSSecretKeyTest.
- * @param arg0
- */
- public KSSecretKeyEntryTest(String arg0) {
- super(arg0);
- }
- /**
* Test for <code>SecretKeyEntry(SecretKey secretKey)</code> constructor
* Assertion: throws NullPointerException when secretKey is null
*/
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyExceptionTest.java
index b75ee68..af46c54 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyExceptionTest.java
@@ -37,18 +37,6 @@
*/
public class KeyExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for KeyExceptionTests.
- *
- * @param arg0
- */
- public KeyExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyFactorySpiTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyFactorySpiTest.java
index b8e0c85..c0f548c 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyFactorySpiTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyFactorySpiTest.java
@@ -39,15 +39,6 @@
public class KeyFactorySpiTest extends TestCase {
/**
- * Constructor for KeyFactorySpiTest.
- *
- * @param name
- */
- public KeyFactorySpiTest(String name) {
- super(name);
- }
-
- /**
* Test for <code>KeyFactorySpi</code> constructor
* Assertion: constructs KeyFactorySpi
*/
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyManagementExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyManagementExceptionTest.java
index b0548e4..67c2284 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyManagementExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyManagementExceptionTest.java
@@ -38,18 +38,6 @@
*/
public class KeyManagementExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for KeyManagementExceptionTests.
- *
- * @param arg0
- */
- public KeyManagementExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator1Test.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator1Test.java
index 4a61cb7..742cc13 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator1Test.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator1Test.java
@@ -51,15 +51,6 @@
public class KeyPairGenerator1Test extends TestCase {
- /**
- * Constructor for KayPairGeneratorTest.
- *
- * @param arg0
- */
- public KeyPairGenerator1Test(String arg0) {
- super(arg0);
- }
-
private static String[] invalidValues = SpiEngUtils.invalidValues;
public static final String srvKeyPairGenerator = "KeyPairGenerator";
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator2Test.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator2Test.java
index a3b1d54..9a8c5c5 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator2Test.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator2Test.java
@@ -91,15 +91,6 @@
Security.insertProviderAt(mProv, 1);
}
- /**
- * Constructor for SecurityManagerFactoryTest2.
- *
- * @param arg0
- */
- public KeyPairGenerator2Test(String arg0) {
- super(arg0);
- }
-
private void checkResult(KeyPairGenerator keyPairGen, int mode)
throws InvalidAlgorithmParameterException {
AlgorithmParameterSpec pp = null;
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator3Test.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator3Test.java
index a3aa4ee..69ec7a7 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator3Test.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator3Test.java
@@ -49,15 +49,6 @@
public class KeyPairGenerator3Test extends TestCase {
- /**
- * Constructor for KeyPairGenerator3Test.
- *
- * @param arg0
- */
- public KeyPairGenerator3Test(String arg0) {
- super(arg0);
- }
-
private static String validProviderName = null;
public static Provider validProvider = null;
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGeneratorSpiTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGeneratorSpiTest.java
index fb67c6f..8d75921 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGeneratorSpiTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGeneratorSpiTest.java
@@ -46,15 +46,6 @@
public class KeyPairGeneratorSpiTest extends TestCase {
/**
- * Constructor for KeyPairGeneratorSpiTest.
- *
- * @param arg0
- */
- public KeyPairGeneratorSpiTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>KeyPairGeneratorSpi</code> constructor
* Assertion: constructs KeyPairGeneratorSpi
*/
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairTest.java
index 1f54198..a428334 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairTest.java
@@ -69,13 +69,6 @@
}
}
- /**
- * Constructor for KeyPairTest.
- * @param name
- */
- public KeyPairTest(String name) {
- super(name);
- }
/**
* Test #1 for <code>KeyPair(PublicKey, PrivateKey)</code> constructor<br>
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore2Test.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore2Test.java
index 92ad60f..817de35 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore2Test.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore2Test.java
@@ -18,7 +18,6 @@
package org.apache.harmony.security.tests.java.security;
import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -562,7 +561,6 @@
method = "load",
args = {java.io.InputStream.class, char[].class}
)
- @KnownFailure("null parameter for password is not checked and results in a NullPointerException")
public void test_loadLjava_io_InputStream$C() throws Exception {
// Test for method void java.security.KeyStore.load(java.io.InputStream,
// char [])
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore4Test.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore4Test.java
index 2889a7b..bf5b136 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore4Test.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore4Test.java
@@ -695,7 +695,7 @@
)
public void testGetProvider() {
assertNotNull(keyStore.getProvider());
- assertSame(provider, keyStore.getProvider());
+ assertEquals("not equal", provider, keyStore.getProvider());
}
}
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreExceptionTest.java
index 27f6b60..ac62d58 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreExceptionTest.java
@@ -37,18 +37,6 @@
*/
public class KeyStoreExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for KeyStoreExceptionTests.
- *
- * @param arg0
- */
- public KeyStoreExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java
index f0b2f3e..2ccca0e 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java
@@ -161,15 +161,6 @@
public class KeyStoreSpiTest extends TestCase {
- /**
- * Constructor for KeyStoreSpi.
- *
- * @param arg0
- */
- public KeyStoreSpiTest(String arg0) {
- super(arg0);
- }
-
@SuppressWarnings("cast")
@TestTargetNew(
level = TestLevel.COMPLETE,
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java
index e49611c..d7ae43f 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreTest.java
@@ -22,7 +22,6 @@
package org.apache.harmony.security.tests.java.security;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -267,7 +266,6 @@
method = "getPassword",
args = {}
)
- @KnownFailure("the password char[] is not cloned in the constructor of PasswordProtection")
public void testKeyStorePPGetPassword() {
// Regression for HARMONY-1539
// no exception expected
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyTest.java
index 2fa48ab..ddbddc4 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyTest.java
@@ -39,15 +39,6 @@
public class KeyTest extends TestCase {
/**
- * Constructor for KeyTest.
- *
- * @param arg0
- */
- public KeyTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>serialVersionUID</code> field
*/
@TestTargetNew(
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchAlgorithmExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchAlgorithmExceptionTest.java
index 8074591..9a6b457 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchAlgorithmExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchAlgorithmExceptionTest.java
@@ -38,18 +38,6 @@
*/
public class NoSuchAlgorithmExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for NoSuchAlgorithmExceptionTests.
- *
- * @param arg0
- */
- public NoSuchAlgorithmExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchProviderExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchProviderExceptionTest.java
index a67fdc0..7cb1558 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchProviderExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/NoSuchProviderExceptionTest.java
@@ -38,18 +38,6 @@
*/
public class NoSuchProviderExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for NoSuchProviderExceptionTests.
- *
- * @param arg0
- */
- public NoSuchProviderExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionCollectionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionCollectionTest.java
index f1369b4..82815eb 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionCollectionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionCollectionTest.java
@@ -27,7 +27,6 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
-import java.security.AllPermission;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.*;
@@ -41,32 +40,26 @@
public class PermissionCollectionTest extends TestCase {
- public static void main(String[] args) {
- junit.textui.TestRunner.run(PermissionCollectionTest.class);
- }
-
- /**
- * Constructor for PermissionCollectionTest.
- * @param arg0
- */
- public PermissionCollectionTest(String arg0) {
- super(arg0);
- }
-
// Bare extension to instantiate abstract PermissionCollection class
private static final class RealPermissionCollection extends PermissionCollection
{
- final private Collection col;
- public RealPermissionCollection(Collection col)
+ final private Set <Permission> setCol = new HashSet<Permission>();
+ public RealPermissionCollection(Set <Permission> col)
{
- this.col = col;
+ if (col != null) {
+ setCol.addAll(col);
+ }
}
-
- public void add(Permission permission) {}
+
+ public void add(Permission permission) {
+ if (!setCol.add(permission)) {
+ throw new IllegalArgumentException("permission is not added");
+ }
+ }
public Enumeration elements()
{
- return col == null ? null : Collections.enumeration(col);
+ return setCol == null ? null : Collections.enumeration(setCol);
}
public boolean implies(Permission permission)
@@ -107,12 +100,37 @@
args = {}
)
public void testToString() {
- PermissionCollection pc = new RealPermissionCollection(null);
+ Set<Permission> perm = new HashSet<Permission>();
+ Permission p = new RealPermission("TestPermission");
+ perm.add(p);
+ PermissionCollection pc = new RealPermissionCollection(perm);
try {
String str = pc.toString();
assertNotNull("toString return null", str);
} catch (Exception e) {
- fail("Unexpected exception");
+ fail("Unexpected exception " + e);
}
}
}
+
+class RealPermission extends Permission {
+
+ public RealPermission(String name) {
+ super(name);
+ }
+
+ public boolean equals(Object obj) {
+ return false;
+ }
+
+ public String getActions() {
+ return null;
+ }
+ public int hashCode() {
+ return 0;
+ }
+
+ public boolean implies(Permission permission) {
+ return false;
+ }
+}
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionTest.java
index 5707ef2..85d4851 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionTest.java
@@ -44,15 +44,6 @@
junit.textui.TestRunner.run(PermissionTest.class);
}
- /**
- * Constructor for PermissionTest.
- *
- * @param arg0
- */
- public PermissionTest(String arg0) {
- super(arg0);
- }
-
// Bare extension to instantiate abstract Permission class
static final class RealPermission extends Permission {
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PrivateKeyTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PrivateKeyTest.java
index fbb4fea..b968a03 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PrivateKeyTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PrivateKeyTest.java
@@ -38,15 +38,6 @@
public class PrivateKeyTest extends TestCase {
/**
- * Constructor for PrivateKeyTest.
- *
- * @param arg0
- */
- public PrivateKeyTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>serialVersionUID</code> field
*/
@TestTargetNew(
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderExceptionTest.java
index 0aba8e4..2350679 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderExceptionTest.java
@@ -37,18 +37,6 @@
*/
public class ProviderExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for ProviderExceptionTests.
- *
- * @param arg0
- */
- public ProviderExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java
index 9e87833..197ce79 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java
@@ -111,20 +111,14 @@
args = {}
)
@KnownFailure("AccessController/AccessControlContext grants Permissions by default")
- public final void testClear_SecurityException() {
+ public final void testClear_SecurityManager() {
TestSecurityManager sm = new TestSecurityManager("clearProviderProperties.MyProvider");
- try {
- System.setSecurityManager(sm);
- p.clear();
- fail("expected SecurityException");
- } catch (SecurityException e) {
- // ok
- assertTrue("Provider.clear must call checkPermission with "
- + "SecurityPermission clearProviderProperties.NAME",
- sm.called);
- } finally {
- System.setSecurityManager(null);
- }
+ System.setSecurityManager(sm);
+ p.clear();
+ assertTrue("Provider.clear must call checkPermission with "
+ + "SecurityPermission clearProviderProperties.NAME",
+ sm.called);
+ System.setSecurityManager(null);
}
/*
@@ -382,21 +376,15 @@
args = {java.lang.Object.class, java.lang.Object.class}
)
@KnownFailure("AccessController/AccessControlContext grants Permissions by default")
- public final void testPutObjectObject_SecurityException() {
+ public final void testPutObjectObject_SecurityManager() {
TestSecurityManager sm = new TestSecurityManager("putProviderProperty.MyProvider");
Provider p = new MyProvider();
- try {
- System.setSecurityManager(sm);
- p.put(new Object(), new Object());
- fail("expected SecurityPermission");
- } catch (SecurityException e) {
- // ok
- assertTrue("Provider put must call checkPermission "
- + "SecurityPermission putProviderProperty.Name", sm.called);
- } finally {
- System.setSecurityManager(null);
- }
+ System.setSecurityManager(sm);
+ p.put(new Object(), new Object());
+ assertTrue("Provider put must call checkPermission "
+ + "SecurityPermission putProviderProperty.Name", sm.called);
+ System.setSecurityManager(null);
}
/*
@@ -408,7 +396,6 @@
method = "remove",
args = {java.lang.Object.class}
)
- @KnownFailure("AccessController/AccessControlContext grants Permissions by default")
public final void testRemoveObject() {
Object o = p.remove("MessageDigest.SHA-1");
if (!"SomeClassName".equals(o)) {
@@ -439,21 +426,15 @@
args = {java.lang.Object.class}
)
@KnownFailure("AccessController/AccessControlContext grants Permissions by default")
- public final void testRemoveObject_SecurityException() {
+ public final void testRemoveObject_SecurityManager() {
TestSecurityManager sm = new TestSecurityManager(
"removeProviderProperty.MyProvider");
- try {
- System.setSecurityManager(sm);
- p.remove(new Object());
- fail("expected SecurityException");
- } catch (SecurityException e) {
- // ok
- assertTrue("Provider.remove must check permission "
- + "SecurityPermission removeProviderProperty.NAME",
- sm.called);
- } finally {
- System.setSecurityManager(null);
- }
+ System.setSecurityManager(sm);
+ p.remove(new Object());
+ assertTrue("Provider.remove must check permission "
+ + "SecurityPermission removeProviderProperty.NAME",
+ sm.called);
+ System.setSecurityManager(null);
}
@TestTargetNew(
@@ -802,7 +783,6 @@
if (permission instanceof SecurityPermission) {
if (permissionName.equals(permission.getName())) {
called = true;
- super.checkPermission(permission);
}
}
}
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PublicKeyTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PublicKeyTest.java
index 8697880..f9efe56 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PublicKeyTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/PublicKeyTest.java
@@ -22,14 +22,12 @@
package org.apache.harmony.security.tests.java.security;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
import java.security.PublicKey;
import junit.framework.TestCase;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
@TestTargetClass(PublicKey.class)
/**
* Tests for <code>PublicKey</code> class field
@@ -38,16 +36,6 @@
public class PublicKeyTest extends TestCase {
-
- /**
- * Constructor for PublicKeyTest.
- *
- * @param arg0
- */
- public PublicKeyTest(String arg0) {
- super(arg0);
- }
-
/**
* Test for <code>serialVersionUID</code> field
*/
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecureRandomSpiTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecureRandomSpiTest.java
index f569684..8ca84b9 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecureRandomSpiTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecureRandomSpiTest.java
@@ -35,15 +35,6 @@
public class SecureRandomSpiTest extends TestCase {
/**
- * Constructor for SecureRandomSpiTest.
- *
- * @param name
- */
- public SecureRandomSpiTest(String name) {
- super(name);
- }
-
- /**
* Test for <code>SecureRandomSpi</code> constructor
* Assertion: constructs SecureRandomSpi
*/
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityPermissionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityPermissionTest.java
index 211f666..2531c81 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityPermissionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityPermissionTest.java
@@ -42,14 +42,6 @@
}
/**
- * Constructor for SecurityPermissionTest.
- * @param arg0
- */
- public SecurityPermissionTest(String arg0) {
- super(arg0);
- }
-
- /**
* Check all constructors: an object is created with the specified valid name.
* If name equal null then NPE should be thrown.
* If name is empty then IAE should be thrown.
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityTest.java
index 0a01541..d2edfd0 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityTest.java
@@ -22,7 +22,6 @@
package org.apache.harmony.security.tests.java.security;
-import dalvik.annotation.BrokenTest;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -30,18 +29,13 @@
import dalvik.annotation.TestLevel;
import java.security.InvalidParameterException;
-import java.security.KeyFactory;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
-import java.security.Signature;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import org.apache.harmony.security.tests.support.TestKeyPair;
import junit.framework.TestCase;
@@ -51,35 +45,6 @@
*/
public class SecurityTest extends TestCase {
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- notes = "Methods from java.security.Security class are not tested",
- method = "!",
- args = {}
- )
- @BrokenTest("empty test")
- public final void testMixed() {
-
- TestKeyPair tkp = null;
- try {
- tkp = new TestKeyPair("DSA");
- } catch (NoSuchAlgorithmException e1) {
- e1.printStackTrace();
- return;
- }
-
- try {
- MessageDigest.getInstance("SHA-1");
- KeyFactory.getInstance("DSA");
- Signature ss = Signature.getInstance("DSA");
- ss.initSign(tkp.getPrivate());
- Signature.getInstance("aaaaaaaaaaaa");
- } catch (Exception e) {
- // ignore
- }
-
- }
-
/**
* @tests java.security.Security#insertProviderAt(Provider, int)
*/
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureExceptionTest.java
index 959b452..5e2bfe3 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureExceptionTest.java
@@ -37,18 +37,6 @@
*/
public class SignatureExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for SignatureExceptionTests.
- *
- * @param arg0
- */
- public SignatureExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureTest.java
index 0a08069..3bfc664 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignatureTest.java
@@ -512,20 +512,27 @@
assertTrue("update() failed", s.runEngineUpdate2);
try {
- s.update(b, 3, 0);
- } catch (SignatureException e) {
- fail("unexpected: " + e);
+ s.update(null, 0, 3);
+ fail("NullPointerException wasn't thrown");
+ } catch (NullPointerException npe) {
}
try {
- s.update(b, 2, 4);
+ s.update(b, 3, 0);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// ok
}
try {
- s.update(null, 0, 5);
+ s.update(b, 0, b.length + 1);
+ fail("expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // ok
+ }
+
+ try {
+ s.update(b, -1, b.length);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// ok
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignerTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignerTest.java
index 7eda819..898ab17 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignerTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/SignerTest.java
@@ -63,14 +63,6 @@
}
/**
- * Constructor for SignerTest.
- * @param arg0
- */
- public SignerTest(String arg0) {
- super(arg0);
- }
-
- /**
* @tests java.security.Signer#toString()
*/
@TestTargetNew(
@@ -86,7 +78,8 @@
Signer s2 = new SignerStub("testToString2", IdentityScope.getSystemScope());
s2.toString();
- KeyPair kp = new KeyPair(new PublicKeyStub("public", "SignerTest.testToString", null), new PrivateKeyStub("private", "SignerTest.testToString", null));
+ KeyPair kp = new KeyPair(new PublicKeyStub("public", "SignerTest.testToString", null),
+ new PrivateKeyStub("private", "SignerTest.testToString", null));
s1.setKeyPair(kp);
s1.toString();
@@ -198,15 +191,17 @@
System.setSecurityManager(sm);
try {
Signer s = new SignerStub("sss6");
- s.setKeyPair(new KeyPair(new PublicKeyStub("public", "fff", null), new PrivateKeyStub("private", "fff", null)));
+ s.setKeyPair(new KeyPair(new PublicKeyStub("public", "fff", null), new PrivateKeyStub(
+ "private", "fff", null)));
try {
s.getPrivateKey();
fail("SecurityException should be thrown");
- } catch (SecurityException ok) {}
+ } catch (SecurityException ok) {
+ }
} finally {
System.setSecurityManager(null);
}
-
+
}
/**
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableEntryExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableEntryExceptionTest.java
index c985ef8..96b0847 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableEntryExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableEntryExceptionTest.java
@@ -38,15 +38,6 @@
public class UnrecoverableEntryExceptionTest extends TestCase {
- /**
- * Constructor for UnrecoverableEntryExceptionTest.
- *
- * @param arg0
- */
- public UnrecoverableEntryExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableKeyExceptionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableKeyExceptionTest.java
index d1dd78b..dda3231 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableKeyExceptionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnrecoverableKeyExceptionTest.java
@@ -38,18 +38,6 @@
*/
public class UnrecoverableKeyExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for UnrecoverableKeyExceptionTests.
- *
- * @param arg0
- */
- public UnrecoverableKeyExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.java b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.java
index 3453e10..ce02e9d 100644
--- a/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.java
+++ b/libcore/security/src/test/java/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.java
@@ -19,7 +19,6 @@
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import java.io.Serializable;
@@ -138,11 +137,11 @@
@TestTargetNew(
level = TestLevel.COMPLETE,
- notes = "missing serialization golden file",
+ notes = "",
method = "!SerializationGolden",
args = {}
)
- public void _testSerialization_Compatibility() throws Exception {
+ public void testSerialization_Compatibility() throws Exception {
UnresolvedPermission up = new UnresolvedPermission(
"java.security.SecurityPermission", "a.b.c", "actions", null);
assertEquals("java.security.SecurityPermission", up.getUnresolvedType());
@@ -156,8 +155,10 @@
assertEquals("java.security.SecurityPermission", deserializedUp
.getUnresolvedType());
assertEquals("a.b.c", deserializedUp.getUnresolvedName());
- assertEquals("actions", deserializedUp.getUnresolvedActions());
- assertNull(deserializedUp.getUnresolvedCerts());
+ assertEquals("action", deserializedUp.getUnresolvedActions());
+ Certificate[] certs = deserializedUp.getUnresolvedCerts();
+ assertNotNull(certs);
+ assertEquals(1, certs.length);
}
});
}
diff --git a/libcore/security/src/test/java/tests/api/java/security/AccessControlContextTest.java b/libcore/security/src/test/java/tests/api/java/security/AccessControlContextTest.java
index c77647c..9831472 100644
--- a/libcore/security/src/test/java/tests/api/java/security/AccessControlContextTest.java
+++ b/libcore/security/src/test/java/tests/api/java/security/AccessControlContextTest.java
@@ -17,7 +17,6 @@
package tests.api.java.security;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -251,7 +250,6 @@
method = "equals",
args = {java.lang.Object.class}
)
- @KnownFailure("AccessControlContext.equals() doesn't compare the DomainCombiner")
public void test_equals() {
final Permission perm1 = new PropertyPermission("java.class.path",
"read");
diff --git a/libcore/security/src/test/java/tests/api/java/security/PermissionCollectionTest.java b/libcore/security/src/test/java/tests/api/java/security/PermissionCollectionTest.java
index 4d367ef..c63fe50 100644
--- a/libcore/security/src/test/java/tests/api/java/security/PermissionCollectionTest.java
+++ b/libcore/security/src/test/java/tests/api/java/security/PermissionCollectionTest.java
@@ -19,7 +19,6 @@
import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -66,8 +65,8 @@
method = "implies",
args = {java.security.Permission.class}
)
- @BrokenTest("Method implies is not called in this test")
- public void _test_impliesLjava_security_Permission() throws Exception{
+ @BrokenTest("Android doesn't support protection domains. NPE at first Line")
+ public void test_impliesLjava_security_Permission() throws Exception{
// Look for the tests classpath
URL classURL = this.getClass().getProtectionDomain().getCodeSource()
diff --git a/libcore/security/src/test/java/tests/api/javax/security/auth/PrivateCredentialPermissionTest.java b/libcore/security/src/test/java/tests/api/javax/security/auth/PrivateCredentialPermissionTest.java
index 27402f2..8e45657 100644
--- a/libcore/security/src/test/java/tests/api/javax/security/auth/PrivateCredentialPermissionTest.java
+++ b/libcore/security/src/test/java/tests/api/javax/security/auth/PrivateCredentialPermissionTest.java
@@ -239,7 +239,7 @@
}
- PrivateCredentialPermission p3 = new PrivateCredentialPermission(name2, "read");
+ PrivateCredentialPermission p3 = new PrivateCredentialPermission(name4, "read");
assertFalse("hashCode() must not be the same for non-equal PrivateCredentialPermission objects", p1.hashCode() == p3.hashCode());
}
diff --git a/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateEncodingExceptionTest.java b/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateEncodingExceptionTest.java
index a14a46c..1bec4ce 100644
--- a/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateEncodingExceptionTest.java
+++ b/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateEncodingExceptionTest.java
@@ -38,18 +38,6 @@
@TestTargetClass(CertificateEncodingException.class)
public class CertificateEncodingExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertificateEncodingExceptionTests.
- *
- * @param arg0
- */
- public CertificateEncodingExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateExceptionTest.java b/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateExceptionTest.java
index 896b6bd..6641097 100644
--- a/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateExceptionTest.java
+++ b/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateExceptionTest.java
@@ -39,18 +39,6 @@
@TestTargetClass(CertificateException.class)
public class CertificateExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertificateExceptionTests.
- *
- * @param arg0
- */
- public CertificateExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateExpiredExceptionTest.java b/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateExpiredExceptionTest.java
index 7578dee..83af35c 100644
--- a/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateExpiredExceptionTest.java
+++ b/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateExpiredExceptionTest.java
@@ -39,18 +39,6 @@
@TestTargetClass(CertificateExpiredException.class)
public class CertificateExpiredExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertificateExpiredExceptionTests.
- *
- * @param arg0
- */
- public CertificateExpiredExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateNotYetValidExceptionTest.java b/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateNotYetValidExceptionTest.java
index 8a212e6..09fb186 100644
--- a/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateNotYetValidExceptionTest.java
+++ b/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateNotYetValidExceptionTest.java
@@ -39,18 +39,6 @@
@TestTargetClass(CertificateNotYetValidException.class)
public class CertificateNotYetValidExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertificateNotYetValidExceptionTests.
- *
- * @param arg0
- */
- public CertificateNotYetValidExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateParsingExceptionTest.java b/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateParsingExceptionTest.java
index d8bef51..c00d0dd 100644
--- a/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateParsingExceptionTest.java
+++ b/libcore/security/src/test/java/tests/api/javax/security/cert/CertificateParsingExceptionTest.java
@@ -39,17 +39,6 @@
@TestTargetClass(CertificateParsingException.class)
public class CertificateParsingExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertificateParsingExceptionTests.
- *
- * @param arg0
- */
- public CertificateParsingExceptionTest(String arg0) {
- super(arg0);
- }
static String[] msgs = {
"",
diff --git a/libcore/security/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java b/libcore/security/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
index 8f521f9..ba8998d 100644
--- a/libcore/security/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
+++ b/libcore/security/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
@@ -22,7 +22,7 @@
package tests.api.javax.security.cert;
-import dalvik.annotation.KnownFailure;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -170,26 +170,9 @@
method = "X509Certificate",
args = {}
)
- public void testConstructor() throws CertificateEncodingException {
- //Direct constructor
+ public void testConstructor() {
+ //Direct constructor, check if it throws an exception
X509Certificate cert = new MyCertificate();
- assertNotNull(cert);
- assertNull("Principal should be null", cert.getIssuerDN());
- assertEquals("Wrong end date", new Date(), cert.getNotAfter());
- assertEquals("Wrong start date", new Date(), cert.getNotBefore());
- assertNull("Public key should be null", cert.getPublicKey());
- assertEquals("Serial number should be 0", BigInteger.valueOf(0), cert.getSerialNumber());
- assertEquals("Wrong algorithm name", "algName", cert.getSigAlgName());
- assertEquals("Wrong algorithm OID", "algOID", cert.getSigAlgOID());
- assertNull("Signature algorithm parameters should be null", cert.getSigAlgParams());
- assertNull("Subject should be null", cert.getSubjectDN());
- assertEquals("Version should be 0", 0, cert.getVersion());
-
- try {
- X509Certificate.getInstance(new byte[]{(byte) 1 });
- } catch (CertificateException e) {
- //ok
- }
}
/**
@@ -264,6 +247,12 @@
assertNotNull(c);
assertTrue(Arrays.equals(c.getEncoded(),cert.getEncoded() ));
}
+
+ try {
+ X509Certificate.getInstance(new byte[]{(byte) 1 });
+ } catch (CertificateException e) {
+ //ok
+ }
// Regression for HARMONY-756
try {
@@ -583,27 +572,27 @@
@Override
public Date getNotAfter() {
- return new Date();
+ return null;
}
@Override
public Date getNotBefore() {
- return new Date();
+ return null;
}
@Override
public BigInteger getSerialNumber() {
- return BigInteger.valueOf(0);
+ return null;
}
@Override
public String getSigAlgName() {
- return "algName";
+ return null;
}
@Override
public String getSigAlgOID() {
- return "algOID";
+ return null;
}
@Override
@@ -623,8 +612,7 @@
@Override
public byte[] getEncoded() throws CertificateEncodingException {
- return new byte[] { (byte) 1, (byte) 2,
- (byte) 3, (byte) 4, (byte) 5 };
+ return null;
}
@Override
@@ -634,7 +622,7 @@
@Override
public String toString() {
- return "certificate";
+ return null;
}
@Override
@@ -764,13 +752,12 @@
@TestTargetNew(
level = TestLevel.SUFFICIENT,
notes = " CertificateException not supported."+
- "NoSuchAlgorithmException, NoSuchProviderException can be "+
- "implemented only with working Cert. Verification fails (see failing) "+
- "precondition assertions",
+ "NoSuchAlgorithmException, NoSuchProviderException can be "+
+ "implemented only with working Cert. Verification fails (see failing) "+
+ "precondition assertions",
method = "verify",
args = {java.security.PublicKey.class}
)
- @KnownFailure("there is an error with the self signed certificate")
public void testVerifyPublicKey() throws InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException,
SignatureException, CertificateException {
@@ -779,9 +766,9 @@
assertNotNull(javaxCert.getPublicKey());
assertNotNull(javaxSSCert.getPublicKey());
//precondition for self signed certificates
- assertEquals(((X509Certificate) javaxSSCert).getIssuerDN().getName(),
- ((X509Certificate) javaxSSCert).getSubjectDN());
-
+ /*assertEquals(((X509Certificate) javaxSSCert).getIssuerDN().getName(),
+ ((X509Certificate) javaxSSCert).getSubjectDN());*/
+
// must always evaluate true for self signed
// here not self signed:
try {
@@ -816,37 +803,31 @@
// ok
}
- MyModifiablePublicKey changedAlgo = new MyModifiablePublicKey(k);
- changedAlgo.setAlgorithm("MD5withBla");
-
- try {
- javaxCert.verify(changedAlgo);
- fail("Exception expected");
- } catch (SignatureException e) {
- // ok
- }
-
-
- /*
+ // following test doesn't work because the algorithm is derived from
+ // somewhere else.
- Security.removeProvider(mySSProvider.getName());
+ // MyModifiablePublicKey changedAlgo = new MyModifiablePublicKey(k);
+ // changedAlgo.setAlgorithm("MD5withBla");
- try {
- javaxSSCert.verify(javaxSSCert.getPublicKey());
- } catch (NoSuchProviderException e) {
- // ok
- }
+ // try {
+ // javaxCert.verify(changedAlgo);
+ // fail("Exception expected");
+ // } catch (SignatureException e) {
+ // // ok
+ // }
+
+ // Security.removeProvider(mySSProvider.getName());
- Security.addProvider(mySSProvider);
-
- //Test NoSuchAlgorithmException
-
-
+ // try {
+ // javaxSSCert.verify(javaxSSCert.getPublicKey());
+ // } catch (NoSuchProviderException e) {
+ // // ok
+ // }
+
+ // Security.addProvider(mySSProvider);
// must always evaluate true for self signed
- javaxSSCert.verify(javaxSSCert.getPublicKey());
-
- */
+ // javaxSSCert.verify(javaxSSCert.getPublicKey());
}
/**
@@ -866,7 +847,7 @@
method = "verify",
args = {java.security.PublicKey.class, java.lang.String.class}
)
- @KnownFailure("there is an error with the self signed certificate")
+ @BrokenTest("there is an error with the self signed certificate")
public void testVerifyPublicKeyString() throws InvalidKeyException,
java.security.cert.CertificateException, NoSuchAlgorithmException,
NoSuchProviderException, SignatureException, IOException,
diff --git a/libcore/security/src/test/java/tests/java/security/AlgorithmParameterGeneratorSpiTest.java b/libcore/security/src/test/java/tests/java/security/AlgorithmParameterGeneratorSpiTest.java
index 590e0b5..976a9cb 100644
--- a/libcore/security/src/test/java/tests/java/security/AlgorithmParameterGeneratorSpiTest.java
+++ b/libcore/security/src/test/java/tests/java/security/AlgorithmParameterGeneratorSpiTest.java
@@ -45,15 +45,6 @@
public class AlgorithmParameterGeneratorSpiTest extends TestCase {
/**
- * Constructor for CertPathBuilderTests.
- *
- * @param name
- */
- public AlgorithmParameterGeneratorSpiTest(String name) {
- super(name);
- }
-
- /**
* Test for <code>AlgorithmParameterGeneratorSpi</code> constructor
* Assertion: constructs AlgorithmParameterGeneratorSpi
*/
diff --git a/libcore/security/src/test/java/tests/java/security/AllPermissionTest.java b/libcore/security/src/test/java/tests/java/security/AllPermissionTest.java
index fa1d24d..e9668ad 100644
--- a/libcore/security/src/test/java/tests/java/security/AllPermissionTest.java
+++ b/libcore/security/src/test/java/tests/java/security/AllPermissionTest.java
@@ -45,14 +45,6 @@
}
/**
- * Constructor for AllPermissionsTest.
- * @param arg0
- */
- public AllPermissionTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test all constructors: an object is created, name and actions are ignored
*/
@TestTargets({
diff --git a/libcore/security/src/test/java/tests/java/security/BasicPermissionTest.java b/libcore/security/src/test/java/tests/java/security/BasicPermissionTest.java
index 735871b..4987ab4 100644
--- a/libcore/security/src/test/java/tests/java/security/BasicPermissionTest.java
+++ b/libcore/security/src/test/java/tests/java/security/BasicPermissionTest.java
@@ -44,14 +44,6 @@
}
/**
- * Constructor for BasicPermissionTest.
- * @param arg0
- */
- public BasicPermissionTest(String arg0) {
- super(arg0);
- }
-
- /**
* Check all constructors: an object is created with the specified valid name.
* If name equal null then NPE should be thrown.
* If name is empty then IAE should be thrown.
diff --git a/libcore/security/src/test/java/tests/java/security/IdentityTest.java b/libcore/security/src/test/java/tests/java/security/IdentityTest.java
index 24ad095..3566ecf 100644
--- a/libcore/security/src/test/java/tests/java/security/IdentityTest.java
+++ b/libcore/security/src/test/java/tests/java/security/IdentityTest.java
@@ -60,14 +60,6 @@
junit.textui.TestRunner.run(IdentityTest.class);
}
- /**
- * Constructor for IdentityTest.
- * @param name
- */
- public IdentityTest(String name) {
- super(name);
- }
-
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Method's returned variable is not checked",
diff --git a/libcore/security/src/test/java/tests/java/security/SecureClassLoaderTest.java b/libcore/security/src/test/java/tests/java/security/SecureClassLoaderTest.java
index 7a6353c..1dfaae6 100644
--- a/libcore/security/src/test/java/tests/java/security/SecureClassLoaderTest.java
+++ b/libcore/security/src/test/java/tests/java/security/SecureClassLoaderTest.java
@@ -22,6 +22,7 @@
package tests.java.security;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -247,6 +248,7 @@
method = "SecureClassLoader",
args = {java.lang.ClassLoader.class}
)
+ @KnownFailure("Android doesn't allow null parent.")
public void testSecureClassLoaderClassLoader() throws Exception {
URL[] urls = new URL[] { new URL("http://localhost") };
URLClassLoader ucl = URLClassLoader.newInstance(urls);
@@ -307,36 +309,36 @@
ldr.getPerms(cs);
}
- /**
- * Tests defineClass(String, byte[], int, int, CodeSource)
- */
- @TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- notes = "ClassFormatError, IndexOutOfBoundsException, SecurityException checking missed",
- method = "defineClass",
- args = {java.lang.String.class, byte[].class, int.class, int.class, java.security.CodeSource.class}
- )
- public void _testDefineClassStringbyteArrayintintCodeSource() {
- MyClassLoader ldr = new MyClassLoader();
- Class klass = ldr.define(null, klassData, 0, klassData.length, null);
- assertEquals(klass.getName(), klassName);
- }
-
- /**
- * Tests defineClass(String, ByteBuffer, CodeSource)
- */
- @TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- notes = "ClassFormatError, SecurityException checking missed",
- method = "defineClass",
- args = {java.lang.String.class, java.nio.ByteBuffer.class, java.security.CodeSource.class}
- )
- public void _testDefineClassStringByteBufferCodeSource() {
- MyClassLoader ldr = new MyClassLoader();
- ByteBuffer bbuf = ByteBuffer.wrap(klassData);
- Class klass = ldr.define(null, bbuf, null);
- assertEquals(klass.getName(), klassName);
- }
+// /**
+// * Tests defineClass(String, byte[], int, int, CodeSource)
+// */
+// @TestTargetNew(
+// level = TestLevel.NOT_FEASIBLE,
+// notes = "ClassFormatError, IndexOutOfBoundsException, SecurityException checking missed",
+// method = "defineClass",
+// args = {java.lang.String.class, byte[].class, int.class, int.class, java.security.CodeSource.class}
+// )
+// public void _testDefineClassStringbyteArrayintintCodeSource() {
+// MyClassLoader ldr = new MyClassLoader();
+// Class klass = ldr.define(null, klassData, 0, klassData.length, null);
+// assertEquals(klass.getName(), klassName);
+// }
+//
+// /**
+// * Tests defineClass(String, ByteBuffer, CodeSource)
+// */
+// @TestTargetNew(
+// level = TestLevel.NOT_FEASIBLE,
+// notes = "ClassFormatError, SecurityException checking missed",
+// method = "defineClass",
+// args = {java.lang.String.class, java.nio.ByteBuffer.class, java.security.CodeSource.class}
+// )
+// public void _testDefineClassStringByteBufferCodeSource() {
+// MyClassLoader ldr = new MyClassLoader();
+// ByteBuffer bbuf = ByteBuffer.wrap(klassData);
+// Class klass = ldr.define(null, bbuf, null);
+// assertEquals(klass.getName(), klassName);
+// }
class MyClassLoader extends SecureClassLoader {
diff --git a/libcore/security/src/test/java/tests/security/AllTests.java b/libcore/security/src/test/java/tests/security/AllTests.java
index 19d87a1..2ce2db0 100644
--- a/libcore/security/src/test/java/tests/security/AllTests.java
+++ b/libcore/security/src/test/java/tests/security/AllTests.java
@@ -40,7 +40,7 @@
suite.addTest(tests.security.interfaces.AllTests.suite());
suite.addTest(tests.security.spec.AllTests.suite());
- suite.addTestSuite(tests.security.SecurityPermissionsTest.class);
+ suite.addTest(tests.security.SecurityPermissionsTest.suite());
suite.addTest(tests.api.javax.security.cert.AllTests.suite());
diff --git a/libcore/security/src/test/java/tests/security/acl/IAclEntryTest.java b/libcore/security/src/test/java/tests/security/acl/IAclEntryTest.java
index 98c0a87..94ddf14 100644
--- a/libcore/security/src/test/java/tests/security/acl/IAclEntryTest.java
+++ b/libcore/security/src/test/java/tests/security/acl/IAclEntryTest.java
@@ -35,16 +35,6 @@
@TestTargetClass(AclEntry.class)
public class IAclEntryTest extends TestCase {
- /**
- * Constructor for IAclEntryTest.
- *
- * @param arg0
- */
- public IAclEntryTest(String arg0) {
- super(arg0);
- }
-
-
class MyAclEntry extends AclEntryImpl {
public MyAclEntry() {
super();
diff --git a/libcore/security/src/test/java/tests/security/acl/IAclTest.java b/libcore/security/src/test/java/tests/security/acl/IAclTest.java
index 3cebcfa..65cb971 100644
--- a/libcore/security/src/test/java/tests/security/acl/IAclTest.java
+++ b/libcore/security/src/test/java/tests/security/acl/IAclTest.java
@@ -37,15 +37,6 @@
@TestTargetClass(Acl.class)
public class IAclTest extends TestCase {
- /**
- * Constructor for IAclEntryTest.
- *
- * @param arg0
- */
- public IAclTest(String arg0) {
- super(arg0);
- }
-
class MyAcl extends AclImpl {
public MyAcl(Principal principal, String str) {
super(principal, str);
diff --git a/libcore/security/src/test/java/tests/security/acl/IGroupTest.java b/libcore/security/src/test/java/tests/security/acl/IGroupTest.java
index 7efec28..47eac93 100644
--- a/libcore/security/src/test/java/tests/security/acl/IGroupTest.java
+++ b/libcore/security/src/test/java/tests/security/acl/IGroupTest.java
@@ -33,15 +33,6 @@
@TestTargetClass(Group.class)
public class IGroupTest extends TestCase {
- /**
- * Constructor for IOwnerTest.
- *
- * @param arg0
- */
- public IGroupTest(String arg0) {
- super(arg0);
- }
-
class MyGroup extends GroupImpl {
public MyGroup(String str) {
super(str);
diff --git a/libcore/security/src/test/java/tests/security/acl/IOwnerTest.java b/libcore/security/src/test/java/tests/security/acl/IOwnerTest.java
index 5324d4d..3cb222d 100644
--- a/libcore/security/src/test/java/tests/security/acl/IOwnerTest.java
+++ b/libcore/security/src/test/java/tests/security/acl/IOwnerTest.java
@@ -34,15 +34,6 @@
@TestTargetClass(Owner.class)
public class IOwnerTest extends TestCase {
- /**
- * Constructor for IOwnerTest.
- *
- * @param arg0
- */
- public IOwnerTest(String arg0) {
- super(arg0);
- }
-
class MyOwner extends OwnerImpl {
public MyOwner(Principal pr) {
super(pr);
diff --git a/libcore/security/src/test/java/tests/security/acl/IPermissionTest.java b/libcore/security/src/test/java/tests/security/acl/IPermissionTest.java
index 19f18ea..17cd7a9 100644
--- a/libcore/security/src/test/java/tests/security/acl/IPermissionTest.java
+++ b/libcore/security/src/test/java/tests/security/acl/IPermissionTest.java
@@ -31,15 +31,6 @@
@TestTargetClass(Permission.class)
public class IPermissionTest extends TestCase {
- /**
- * Constructor for IPermissionTest.
- *
- * @param arg0
- */
- public IPermissionTest(String arg0) {
- super(arg0);
- }
-
class MyPermission extends PermissionImpl {
public MyPermission(String str) {
super(str);
diff --git a/libcore/security/src/test/java/tests/security/cert/CRLExceptionTest.java b/libcore/security/src/test/java/tests/security/cert/CRLExceptionTest.java
index c43ef36..3fc37c0 100644
--- a/libcore/security/src/test/java/tests/security/cert/CRLExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CRLExceptionTest.java
@@ -38,18 +38,6 @@
@TestTargetClass(CRLException.class)
public class CRLExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CRLExceptionTests.
- *
- * @param arg0
- */
- public CRLExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/cert/CRLTest.java b/libcore/security/src/test/java/tests/security/cert/CRLTest.java
index e46a033..8e5693e 100644
--- a/libcore/security/src/test/java/tests/security/cert/CRLTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CRLTest.java
@@ -45,14 +45,6 @@
private final static String[] invalidValues = SpiEngUtils.invalidValues;
- /**
- * Constructor for CRLTest.
- * @param name
- */
- public CRLTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathBuilder1Test.java b/libcore/security/src/test/java/tests/security/cert/CertPathBuilder1Test.java
index 7f5674d..5af75c2 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathBuilder1Test.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathBuilder1Test.java
@@ -53,13 +53,6 @@
@TestTargetClass(CertPathBuilder.class)
public class CertPathBuilder1Test extends TestCase {
- /**
- * Constructor for CertPathBuilderTests.
- * @param name
- */
- public CertPathBuilder1Test(String name) {
- super(name);
- }
public static final String srvCertPathBuilder = "CertPathBuilder";
public static final String defaultType = "PKIX";
@@ -398,6 +391,7 @@
method="build",
args={CertPathParameters.class}
)
+ // Test passed on RI
public void testBuild() throws Exception {
TestUtils.initCertPathSSCertChain();
CertPathParameters params = TestUtils.getCertPathParameters();
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathBuilder2Test.java b/libcore/security/src/test/java/tests/security/cert/CertPathBuilder2Test.java
index 3d4f4cf..fcf235e 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathBuilder2Test.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathBuilder2Test.java
@@ -82,15 +82,6 @@
Security.removeProvider(mProv.getName());
}
- /**
- * Constructor for CertPathBuilder2Test.
- *
- * @param arg0
- */
- public CertPathBuilder2Test(String arg0) {
- super(arg0);
- }
-
private void checkResult(CertPathBuilder certBuild)
throws InvalidAlgorithmParameterException,
CertPathBuilderException {
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathBuilderExceptionTest.java b/libcore/security/src/test/java/tests/security/cert/CertPathBuilderExceptionTest.java
index f8aeb08..efd575a 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathBuilderExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathBuilderExceptionTest.java
@@ -40,18 +40,6 @@
@TestTargetClass(CertPathBuilderException.class)
public class CertPathBuilderExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertPathBuilderExceptionTests.
- *
- * @param arg0
- */
- public CertPathBuilderExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathBuilderSpiTest.java b/libcore/security/src/test/java/tests/security/cert/CertPathBuilderSpiTest.java
index 338060d..751f0c6 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathBuilderSpiTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathBuilderSpiTest.java
@@ -45,15 +45,6 @@
public class CertPathBuilderSpiTest extends TestCase {
/**
- * Constructor for CertPathBuilderSpiTest.
- *
- * @param arg0
- */
- public CertPathBuilderSpiTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>CertPathBuilderSpi</code> constructor Assertion:
* constructs CertPathBuilderSpi
*/
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathCertPathRepTest.java b/libcore/security/src/test/java/tests/security/cert/CertPathCertPathRepTest.java
index 0e607c5..6ca848e 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathCertPathRepTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathCertPathRepTest.java
@@ -51,8 +51,8 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
- notes = "ObjectStreamException checking missed",
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks ObjectStreamException",
method = "CertPath.CertPathRep.readResolve",
args = {}
)
@@ -62,9 +62,9 @@
try {
Object obj = rep.readResolve();
- assertTrue(obj instanceof CertPath);
+ fail("ObjectStreamException was not thrown.");
} catch (ObjectStreamException e) {
- fail("unexpected exception: " + e);
+ //expected
}
rep = cp.new MyCertPathRep("MyEncoding", new byte[] {(byte) 1, (byte) 2, (byte) 3 });
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathTest.java b/libcore/security/src/test/java/tests/security/cert/CertPathTest.java
index 10095ec..5edb3f5 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathTest.java
@@ -341,6 +341,7 @@
args = {}
)
})
+ // Test passed on RI
public void testSerializationSelf() throws Exception {
TestUtils.initCertPathSSCertChain();
CertPath certPath = TestUtils.buildCertPathSSCertChain();
@@ -371,6 +372,7 @@
args = {}
)
})
+ // Test passed on RI
public void testSerializationCompatibility() throws Exception {
TestUtils.initCertPathSSCertChain();
CertPath certPath = TestUtils.buildCertPathSSCertChain();
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathValidator1Test.java b/libcore/security/src/test/java/tests/security/cert/CertPathValidator1Test.java
index 54e210a..a76af78 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathValidator1Test.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathValidator1Test.java
@@ -52,13 +52,6 @@
@TestTargetClass(CertPathValidator.class)
public class CertPathValidator1Test extends TestCase {
- /**
- * Constructor for CertPathValidatorTests.
- * @param name
- */
- public CertPathValidator1Test(String name) {
- super(name);
- }
public static final String srvCertPathValidator = "CertPathValidator";
private static final String defaultType = "PKIX";
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathValidator2Test.java b/libcore/security/src/test/java/tests/security/cert/CertPathValidator2Test.java
index a7e922d..3f513cc 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathValidator2Test.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathValidator2Test.java
@@ -16,9 +16,9 @@
*/
/**
-* @author Vera Y. Petrashkova
-* @version $Revision$
-*/
+ * @author Vera Y. Petrashkova
+ * @version $Revision$
+ */
package tests.security.cert;
@@ -42,14 +42,14 @@
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.PKIXParameters;
+
/**
* Tests for CertPathValidator class constructors and methods
- *
*/
@TestTargetClass(CertPathValidator.class)
public class CertPathValidator2Test extends TestCase {
private static final String defaultAlg = "CertPB";
-
+
public static final String CertPathValidatorProviderClass = "org.apache.harmony.security.tests.support.cert.MyCertPathValidatorSpi";
private static final String[] invalidValues = SpiEngUtils.invalidValues;
@@ -69,9 +69,8 @@
protected void setUp() throws Exception {
super.setUp();
mProv = (new SpiEngUtils()).new MyProvider("MyCertPathValidatorProvider",
- "Provider for testing", CertPathValidator1Test.srvCertPathValidator
- .concat(".").concat(defaultAlg),
- CertPathValidatorProviderClass);
+ "Provider for testing", CertPathValidator1Test.srvCertPathValidator.concat(".")
+ .concat(defaultAlg), CertPathValidatorProviderClass);
Security.insertProviderAt(mProv, 1);
}
@@ -83,51 +82,37 @@
Security.removeProvider(mProv.getName());
}
- /**
- * Constructor for CertPathValidator2Test.
- *
- * @param arg0
- */
- public CertPathValidator2Test(String arg0) {
- super(arg0);
- }
-
- private void checkResult(CertPathValidator certV)
- throws CertPathValidatorException,
+ private void checkResult(CertPathValidator certV) throws CertPathValidatorException,
InvalidAlgorithmParameterException {
String dt = CertPathValidator.getDefaultType();
String propName = "certpathvalidator.type";
- for (int i = 0; i <invalidValues.length; i++) {
+ for (int i = 0; i < invalidValues.length; i++) {
Security.setProperty(propName, invalidValues[i]);
assertEquals("Incorrect default type", CertPathValidator.getDefaultType(),
invalidValues[i]);
}
Security.setProperty(propName, dt);
- assertEquals("Incorrect default type", CertPathValidator.getDefaultType(),
- dt); certV.validate(null, null);
- try {
- certV.validate(null, null);
- } catch (CertPathValidatorException e) {
- }
- try {
- certV.validate(null, null);
- } catch (InvalidAlgorithmParameterException e) {
- }
+ assertEquals("Incorrect default type", CertPathValidator.getDefaultType(), dt);
+ certV.validate(null, null);
+ try {
+ certV.validate(null, null);
+ } catch (CertPathValidatorException e) {
+ }
+ try {
+ certV.validate(null, null);
+ } catch (InvalidAlgorithmParameterException e) {
+ }
}
/**
- * Test for <code>getInstance(String algorithm)</code> method
- * Assertions:
- * throws NullPointerException when algorithm is null
- * throws NoSuchAlgorithmException when algorithm is not available
- * returns CertPathValidator object
+ * Test for <code>getInstance(String algorithm)</code> method Assertions:
+ * throws NullPointerException when algorithm is null throws
+ * NoSuchAlgorithmException when algorithm is not available returns
+ * CertPathValidator object
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getInstance",
- args = {java.lang.String.class}
- )
+ @TestTargetNew(level = TestLevel.COMPLETE, notes = "", method = "getInstance", args = {
+ java.lang.String.class
+ })
public void testGetInstance01() throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException, CertPathValidatorException {
try {
@@ -139,8 +124,8 @@
for (int i = 0; i < invalidValues.length; i++) {
try {
CertPathValidator.getInstance(invalidValues[i]);
- fail("NoSuchAlgorithmException must be thrown (type: ".concat(
- invalidValues[i]).concat(")"));
+ fail("NoSuchAlgorithmException must be thrown (type: ".concat(invalidValues[i])
+ .concat(")"));
} catch (NoSuchAlgorithmException e) {
}
}
@@ -154,23 +139,19 @@
}
/**
- * Test for <code>getInstance(String algorithm, String provider)</code> method
- * Assertions:
- * throws NullPointerException when algorithm is null
- * throws NoSuchAlgorithmException when algorithm is not available
- * throws IllegalArgumentException when provider is null or empty;
- * throws NoSuchProviderException when provider is available;
- * returns CertPathValidator object
+ * Test for <code>getInstance(String algorithm, String provider)</code>
+ * method Assertions: throws NullPointerException when algorithm is null
+ * throws NoSuchAlgorithmException when algorithm is not available throws
+ * IllegalArgumentException when provider is null or empty; throws
+ * NoSuchProviderException when provider is available; returns
+ * CertPathValidator object
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getInstance",
- args = {java.lang.String.class, java.lang.String.class}
- )
- public void testGetInstance02() throws NoSuchAlgorithmException,
- NoSuchProviderException, IllegalArgumentException,
- InvalidAlgorithmParameterException, CertPathValidatorException {
+ @TestTargetNew(level = TestLevel.COMPLETE, notes = "", method = "getInstance", args = {
+ java.lang.String.class, java.lang.String.class
+ })
+ public void testGetInstance02() throws NoSuchAlgorithmException, NoSuchProviderException,
+ IllegalArgumentException, InvalidAlgorithmParameterException,
+ CertPathValidatorException {
try {
CertPathValidator.getInstance(null, mProv.getName());
fail("NullPointerException or NoSuchAlgorithmException must be thrown when algorithm is null");
@@ -179,10 +160,9 @@
}
for (int i = 0; i < invalidValues.length; i++) {
try {
- CertPathValidator.getInstance(invalidValues[i], mProv
- .getName());
- fail("NoSuchAlgorithmException must be thrown (type: ".concat(
- invalidValues[i]).concat(")"));
+ CertPathValidator.getInstance(invalidValues[i], mProv.getName());
+ fail("NoSuchAlgorithmException must be thrown (type: ".concat(invalidValues[i])
+ .concat(")"));
} catch (NoSuchAlgorithmException e) {
}
}
@@ -204,43 +184,33 @@
for (int i = 0; i < validValues.length; i++) {
for (int j = 1; j < invalidValues.length; j++) {
try {
- CertPathValidator.getInstance(validValues[i],
- invalidValues[j]);
- fail("NoSuchProviderException must be thrown (type: "
- .concat(validValues[i]).concat(" provider: ")
- .concat(invalidValues[j]).concat(")"));
+ CertPathValidator.getInstance(validValues[i], invalidValues[j]);
+ fail("NoSuchProviderException must be thrown (type: ".concat(validValues[i])
+ .concat(" provider: ").concat(invalidValues[j]).concat(")"));
} catch (NoSuchProviderException e) {
}
}
}
CertPathValidator cerPV;
for (int i = 0; i < validValues.length; i++) {
- cerPV = CertPathValidator.getInstance(validValues[i], mProv
- .getName());
+ cerPV = CertPathValidator.getInstance(validValues[i], mProv.getName());
assertEquals("Incorrect type", cerPV.getAlgorithm(), validValues[i]);
- assertEquals("Incorrect provider", cerPV.getProvider().getName(),
- mProv.getName());
+ assertEquals("Incorrect provider", cerPV.getProvider().getName(), mProv.getName());
checkResult(cerPV);
}
}
/**
* Test for <code>getInstance(String algorithm, Provider provider)</code>
- * method
- * Assertions:
- * throws NullPointerException when algorithm is null
- * throws NoSuchAlgorithmException when algorithm is not available
- * throws IllegalArgumentException when provider is null;
- * returns CertPathValidator object
+ * method Assertions: throws NullPointerException when algorithm is null
+ * throws NoSuchAlgorithmException when algorithm is not available throws
+ * IllegalArgumentException when provider is null; returns CertPathValidator
+ * object
*/
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getInstance",
- args = {java.lang.String.class, java.security.Provider.class}
- )
- public void testGetInstance03() throws NoSuchAlgorithmException,
- IllegalArgumentException,
+ @TestTargetNew(level = TestLevel.COMPLETE, notes = "", method = "getInstance", args = {
+ java.lang.String.class, java.security.Provider.class
+ })
+ public void testGetInstance03() throws NoSuchAlgorithmException, IllegalArgumentException,
InvalidAlgorithmParameterException, CertPathValidatorException {
try {
CertPathValidator.getInstance(null, mProv);
@@ -251,8 +221,8 @@
for (int i = 0; i < invalidValues.length; i++) {
try {
CertPathValidator.getInstance(invalidValues[i], mProv);
- fail("NoSuchAlgorithmException must be thrown (type: ".concat(
- invalidValues[i]).concat(")"));
+ fail("NoSuchAlgorithmException must be thrown (type: ".concat(invalidValues[i])
+ .concat(")"));
} catch (NoSuchAlgorithmException e) {
}
}
@@ -273,35 +243,33 @@
checkResult(cerPV);
}
}
-
- @TestTargetNew(
- level=TestLevel.PARTIAL_COMPLETE,
- method="validate",
- args={CertPath.class,CertPathParameters.class}
- )
+
+ @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "validate", args = {
+ CertPath.class, CertPathParameters.class
+ })
public void testValidate() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
MyCertPath mCP = new MyCertPath(new byte[0]);
- CertPathParameters params = new PKIXParameters(TestUtils.getTrustAnchorSet());
+ CertPathParameters params = new PKIXParameters(TestUtils.getTrustAnchorSet());
CertPathValidator certPV = CertPathValidator.getInstance(defaultAlg);
try {
certPV.validate(mCP, params);
} catch (InvalidAlgorithmParameterException e) {
- fail("unexpected exception: " + e);
+ fail("unexpected exception: " + e);
} catch (CertPathValidatorException e) {
fail("unexpected exception: " + e);
}
try {
certPV.validate(null, params);
fail("NullPointerException must be thrown");
- } catch(InvalidAlgorithmParameterException e) {
+ } catch (InvalidAlgorithmParameterException e) {
fail("unexpected exception: " + e);
} catch (CertPathValidatorException e) {
// ok
- }
+ }
try {
certPV.validate(mCP, null);
fail("InvalidAlgorithmParameterException must be thrown");
- } catch(InvalidAlgorithmParameterException e) {
+ } catch (InvalidAlgorithmParameterException e) {
// ok
} catch (CertPathValidatorException e) {
fail("unexpected exception");
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathValidator3Test.java b/libcore/security/src/test/java/tests/security/cert/CertPathValidator3Test.java
index a590635..b624b25 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathValidator3Test.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathValidator3Test.java
@@ -50,13 +50,6 @@
@TestTargetClass(CertPathValidator.class)
public class CertPathValidator3Test extends TestCase {
- /**
- * Constructor for CertPathValidatorTests.
- * @param name
- */
- public CertPathValidator3Test(String name) {
- super(name);
- }
private static final String defaultType = CertPathBuilder1Test.defaultType;
private static boolean PKIXSupport = false;
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathValidatorExceptionTest.java b/libcore/security/src/test/java/tests/security/cert/CertPathValidatorExceptionTest.java
index 57f5e71..c28a761 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathValidatorExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathValidatorExceptionTest.java
@@ -46,18 +46,6 @@
@TestTargetClass(CertPathValidatorException.class)
public class CertPathValidatorExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertPathValidatorExceptionTests.
- *
- * @param arg0
- */
- public CertPathValidatorExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/cert/CertPathValidatorSpiTest.java b/libcore/security/src/test/java/tests/security/cert/CertPathValidatorSpiTest.java
index dbb1466..080a112 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertPathValidatorSpiTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertPathValidatorSpiTest.java
@@ -45,15 +45,6 @@
public class CertPathValidatorSpiTest extends TestCase {
/**
- * Constructor for CertPathValidatorSpiTest.
- *
- * @param arg0
- */
- public CertPathValidatorSpiTest(String arg0) {
- super(arg0);
- }
-
- /**
* Test for <code>CertPathValidatorSpi</code> constructor Assertion:
* constructs CertPathValidatorSpi
*/
diff --git a/libcore/security/src/test/java/tests/security/cert/CertStore1Test.java b/libcore/security/src/test/java/tests/security/cert/CertStore1Test.java
index 6f67aeb..48c40c9 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertStore1Test.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertStore1Test.java
@@ -54,13 +54,6 @@
@TestTargetClass(CertStore.class)
public class CertStore1Test extends TestCase {
- /**
- * Constructor for CertStoreTests.
- * @param arg0
- */
- public CertStore1Test(String arg0) {
- super(arg0);
- }
public static final String srvCertStore = "CertStore";
private static final String defaultType = "LDAP";
diff --git a/libcore/security/src/test/java/tests/security/cert/CertStoreExceptionTest.java b/libcore/security/src/test/java/tests/security/cert/CertStoreExceptionTest.java
index d18fb78..9eddf86 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertStoreExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertStoreExceptionTest.java
@@ -38,18 +38,6 @@
@TestTargetClass(CertStoreException.class)
public class CertStoreExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertStoreExceptionTests.
- *
- * @param arg0
- */
- public CertStoreExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/cert/CertStoreSpiTest.java b/libcore/security/src/test/java/tests/security/cert/CertStoreSpiTest.java
index 8223f4c..3cac01f 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertStoreSpiTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertStoreSpiTest.java
@@ -50,14 +50,6 @@
@TestTargetClass(CertStoreSpi.class)
public class CertStoreSpiTest extends TestCase {
- /**
- * Constructor for CertStoreSpiTest.
- *
- * @param arg0
- */
- public CertStoreSpiTest(String arg0) {
- super(arg0);
- }
/**
* Test for <code>CertStoreSpi</code> constructor Assertion: constructs
diff --git a/libcore/security/src/test/java/tests/security/cert/CertificateEncodingExceptionTest.java b/libcore/security/src/test/java/tests/security/cert/CertificateEncodingExceptionTest.java
index 38a857f..1792abe 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertificateEncodingExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertificateEncodingExceptionTest.java
@@ -40,18 +40,6 @@
@TestTargetClass(CertificateEncodingException.class)
public class CertificateEncodingExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertificateEncodingExceptionTests.
- *
- * @param arg0
- */
- public CertificateEncodingExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/cert/CertificateExceptionTest.java b/libcore/security/src/test/java/tests/security/cert/CertificateExceptionTest.java
index e1d6645..fbd777c 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertificateExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertificateExceptionTest.java
@@ -39,18 +39,6 @@
@TestTargetClass(CertificateException.class)
public class CertificateExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertificateExceptionTests.
- *
- * @param arg0
- */
- public CertificateExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/cert/CertificateExpiredExceptionTest.java b/libcore/security/src/test/java/tests/security/cert/CertificateExpiredExceptionTest.java
index 647345f..9a7ce5a 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertificateExpiredExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertificateExpiredExceptionTest.java
@@ -39,18 +39,6 @@
@TestTargetClass(CertificateExpiredException.class)
public class CertificateExpiredExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertificateExpiredExceptionTests.
- *
- * @param arg0
- */
- public CertificateExpiredExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/cert/CertificateFactory1Test.java b/libcore/security/src/test/java/tests/security/cert/CertificateFactory1Test.java
index 7237871..42677eb 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertificateFactory1Test.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertificateFactory1Test.java
@@ -59,15 +59,6 @@
@TestTargetClass(CertificateFactory.class)
public class CertificateFactory1Test extends TestCase {
- /**
- * Constructor for CertificateFactoryTests.
- *
- * @param arg0
- */
- public CertificateFactory1Test(String arg0) {
- super(arg0);
- }
-
public static final String srvCertificateFactory = "CertificateFactory";
private static String defaultProviderName = null;
@@ -675,6 +666,7 @@
args = {java.io.InputStream.class, java.lang.String.class}
)
})
+ // Test passed on RI
public void testCertificateFactory13() throws IOException {
if (!X509Support) {
fail(NotSupportMsg);
diff --git a/libcore/security/src/test/java/tests/security/cert/CertificateFactory2Test.java b/libcore/security/src/test/java/tests/security/cert/CertificateFactory2Test.java
index 12c7ec1..4350db0 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertificateFactory2Test.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertificateFactory2Test.java
@@ -86,15 +86,6 @@
Security.removeProvider(mProv.getName());
}
- /**
- * Constructor for CertificateFactory2Test.
- *
- * @param arg0
- */
- public CertificateFactory2Test(String arg0) {
- super(arg0);
- }
-
private void checkResult(CertificateFactory certFactory, boolean mode)
throws CertificateException, CRLException {
MyCertificateFactorySpi.putMode(mode);
diff --git a/libcore/security/src/test/java/tests/security/cert/CertificateFactorySpiTest.java b/libcore/security/src/test/java/tests/security/cert/CertificateFactorySpiTest.java
index 09090f6..fbb2372 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertificateFactorySpiTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertificateFactorySpiTest.java
@@ -51,16 +51,8 @@
*/
@TestTargetClass(CertificateFactorySpi.class)
public class CertificateFactorySpiTest extends TestCase {
- /**
- * Constructor for CertStoreSpiTest.
- *
- * @param arg0
- */
- public CertificateFactorySpiTest(String arg0) {
- super(arg0);
- }
- /**
+ /**
* Test for <code>CertificateFactorySpi</code> constructor
* Assertion: constructs CertificateFactorySpi
*/
diff --git a/libcore/security/src/test/java/tests/security/cert/CertificateNotYetValidExceptionTest.java b/libcore/security/src/test/java/tests/security/cert/CertificateNotYetValidExceptionTest.java
index 2ed6b05..b386387 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertificateNotYetValidExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertificateNotYetValidExceptionTest.java
@@ -39,18 +39,6 @@
@TestTargetClass(CertificateNotYetValidException.class)
public class CertificateNotYetValidExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertificateNotYetValidExceptionTests.
- *
- * @param arg0
- */
- public CertificateNotYetValidExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/cert/CertificateParsingExceptionTest.java b/libcore/security/src/test/java/tests/security/cert/CertificateParsingExceptionTest.java
index c079f6c..c690b5b 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertificateParsingExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertificateParsingExceptionTest.java
@@ -40,18 +40,6 @@
@TestTargetClass(CertificateParsingException.class)
public class CertificateParsingExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for CertificateParsingExceptionTests.
- *
- * @param arg0
- */
- public CertificateParsingExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/cert/CertificateTest.java b/libcore/security/src/test/java/tests/security/cert/CertificateTest.java
index 28fab31..2d0f7e8 100644
--- a/libcore/security/src/test/java/tests/security/cert/CertificateTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CertificateTest.java
@@ -24,7 +24,7 @@
-import dalvik.annotation.BrokenTest;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -34,7 +34,9 @@
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.ObjectStreamException;
+import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
@@ -42,12 +44,10 @@
import java.security.PublicKey;
import java.security.Security;
import java.security.SignatureException;
-import java.security.cert.CertPath;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
import java.util.Arrays;
import org.apache.harmony.security.tests.support.cert.MyCertificate;
@@ -55,9 +55,6 @@
import org.apache.harmony.security.tests.support.cert.TestUtils;
import org.apache.harmony.testframework.serialization.SerializationTest;
-import tests.api.javax.security.cert.X509CertificateTest.MyModifiablePublicKey;
-
-
/**
* Tests for <code>Certificate</code> fields and methods
*
@@ -70,14 +67,6 @@
private static final byte[] testEncoding = new byte[] { (byte) 1, (byte) 2,
(byte) 3, (byte) 4, (byte) 5 };
- /**
- * Constructor for CertificateTest.
- * @param name
- */
- public CertificateTest(String name) {
- super(name);
- }
-
//
// Tests
//
@@ -91,6 +80,8 @@
method = "Certificate",
args = {java.lang.String.class}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testCertificate() {
try {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
@@ -117,6 +108,8 @@
method = "hashCode",
args = {}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testHashCode() throws CertificateEncodingException {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
Certificate c2 = new MyCertificate("TEST_TYPE", testEncoding);
@@ -138,6 +131,8 @@
method = "hashCode",
args = {}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testHashCodeEqualsObject() {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
Certificate c2 = new MyCertificate("TEST_TYPE", testEncoding);
@@ -157,6 +152,8 @@
method = "getType",
args = {}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testGetType() {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
assertEquals("TEST_TYPE", c1.getType());
@@ -172,6 +169,8 @@
method = "equals",
args = {java.lang.Object.class}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testEqualsObject01() {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
assertTrue(c1.equals(c1));
@@ -188,6 +187,8 @@
method = "equals",
args = {java.lang.Object.class}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testEqualsObject02() {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
Certificate c2 = new MyCertificate("TEST_TYPE", testEncoding);
@@ -204,6 +205,8 @@
method = "equals",
args = {java.lang.Object.class}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testEqualsObject03() {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
assertFalse(c1.equals(null));
@@ -220,6 +223,8 @@
method = "equals",
args = {java.lang.Object.class}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testEqualsObject04() {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
assertFalse(c1.equals("TEST_TYPE"));
@@ -241,6 +246,8 @@
method = "getEncoded",
args = {}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
@KnownFailure("Assertion does not evaluate to true... Works in javax.Certificate")
public final void testGetEncoded() throws CertificateException {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
@@ -248,7 +255,7 @@
assertTrue(Arrays.equals(TestUtils.rootCert.getBytes(),cert.getEncoded()));
- byte[] b = rootCert.getBytes();
+ byte[] b = TestUtils.rootCert.getBytes();
b[4] = (byte) 200;
@@ -276,6 +283,8 @@
method = "verify",
args = {java.security.PublicKey.class}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testVerifyPublicKey()
throws InvalidKeyException,
CertificateException,
@@ -301,6 +310,8 @@
method = "verify",
args = {java.security.PublicKey.class, java.lang.String.class}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testVerifyPublicKeyString()
throws InvalidKeyException,
CertificateException,
@@ -320,6 +331,8 @@
method = "toString",
args = {}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testToString() {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
c1.toString();
@@ -334,6 +347,8 @@
method = "getPublicKey",
args = {}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testGetPublicKey() {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
c1.getPublicKey();
@@ -348,6 +363,8 @@
method = "writeReplace",
args = {}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testWriteReplace() {
MyCertificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
@@ -360,72 +377,6 @@
}
}
- /**
- * Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 0 (0x0)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=AN, ST=Android, O=Android, OU=Android, CN=Android/emailAddress=android
- Validity
- Not Before: Dec 9 16:35:30 2008 GMT
- Not After : Dec 9 16:35:30 2011 GMT
- Subject: C=AN, ST=Android, O=Android, OU=Android, CN=Android/emailAddress=android
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:c5:fb:5e:68:37:82:1d:58:ed:cb:31:8c:08:7f:
- 51:31:4c:68:40:8c:4d:07:a1:0e:18:36:02:6b:89:
- 92:c1:cf:88:1e:cf:00:22:00:8c:37:e8:6a:76:94:
- 71:53:81:78:e1:48:94:fa:16:61:93:eb:a0:ee:62:
- 9d:6a:d2:2c:b8:77:9d:c9:36:d5:d9:1c:eb:26:3c:
- 43:66:4d:7b:1c:1d:c7:a1:37:66:e2:84:54:d3:ed:
- 21:dd:01:1c:ec:9b:0c:1e:35:e9:37:15:9d:2b:78:
- a8:3b:11:3a:ee:c2:de:55:44:4c:bd:40:8d:e5:52:
- b0:fc:53:33:73:4a:e5:d0:df
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 4B:E3:22:14:AD:0A:14:46:B7:52:31:8B:AB:9E:5A:62:F3:98:37:80
- X509v3 Authority Key Identifier:
- keyid:4B:E3:22:14:AD:0A:14:46:B7:52:31:8B:AB:9E:5A:62:F3:98:37:80
- DirName:/C=AN/ST=Android/O=Android/OU=Android/CN=Android/emailAddress=android
- serial:00
-
- X509v3 Basic Constraints:
- CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- 72:4f:12:8a:4e:61:b2:9a:ba:58:17:0b:55:96:f5:66:1c:a8:
- ba:d1:0f:8b:9b:2d:ab:a8:00:ac:7f:99:7d:f6:0f:d7:85:eb:
- 75:4b:e5:42:37:71:46:b1:4a:b0:1b:17:e4:f9:7c:9f:bd:20:
- 75:35:9f:27:8e:07:95:e8:34:bd:ab:e4:10:5f:a3:7b:4c:56:
- 69:d4:d0:f1:e9:74:15:2d:7f:77:f0:38:77:eb:8a:99:f3:a9:
- 88:f0:63:58:07:b9:5a:61:f8:ff:11:e7:06:a1:d1:f8:85:fb:
- 99:1c:f5:cb:77:86:36:cd:43:37:99:09:c2:9a:d8:f2:28:05:
- 06:0c
-
- */
- public static final String rootCert = "-----BEGIN CERTIFICATE-----\n" +
- "MIIDGzCCAoSgAwIBAgIBADANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJBTjEQ\n" +
- "MA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5k\n" +
- "cm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEWMBQGCSqGSIb3DQEJARYHYW5kcm9pZDAe\n" +
- "Fw0wODEyMDkxNjM1MzBaFw0xMTEyMDkxNjM1MzBaMG0xCzAJBgNVBAYTAkFOMRAw\n" +
- "DgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQKEwdBbmRyb2lkMRAwDgYDVQQLEwdBbmRy\n" +
- "b2lkMRAwDgYDVQQDEwdBbmRyb2lkMRYwFAYJKoZIhvcNAQkBFgdhbmRyb2lkMIGf\n" +
- "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDF+15oN4IdWO3LMYwIf1ExTGhAjE0H\n" +
- "oQ4YNgJriZLBz4gezwAiAIw36Gp2lHFTgXjhSJT6FmGT66DuYp1q0iy4d53JNtXZ\n" +
- "HOsmPENmTXscHcehN2bihFTT7SHdARzsmwweNek3FZ0reKg7ETruwt5VREy9QI3l\n" +
- "UrD8UzNzSuXQ3wIDAQABo4HKMIHHMB0GA1UdDgQWBBRL4yIUrQoURrdSMYurnlpi\n" +
- "85g3gDCBlwYDVR0jBIGPMIGMgBRL4yIUrQoURrdSMYurnlpi85g3gKFxpG8wbTEL\n" +
- "MAkGA1UEBhMCQU4xEDAOBgNVBAgTB0FuZHJvaWQxEDAOBgNVBAoTB0FuZHJvaWQx\n" +
- "EDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWQxFjAUBgkqhkiG9w0B\n" +
- "CQEWB2FuZHJvaWSCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBy\n" +
- "TxKKTmGymrpYFwtVlvVmHKi60Q+Lmy2rqACsf5l99g/Xhet1S+VCN3FGsUqwGxfk\n" +
- "+XyfvSB1NZ8njgeV6DS9q+QQX6N7TFZp1NDx6XQVLX938Dh364qZ86mI8GNYB7la\n" +
- "Yfj/EecGodH4hfuZHPXLd4Y2zUM3mQnCmtjyKAUGDA==\n" +
- "-----END CERTIFICATE-----";
-
public class MyModifiablePublicKey implements PublicKey {
private PublicKey key;
@@ -517,7 +468,8 @@
method = "verify",
args = {java.security.PublicKey.class, java.lang.String.class}
)
- @BrokenTest("Test fails: ClassCastException when SignatureException is expected")
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testVerifyPublicKeyString2() throws InvalidKeyException,
CertificateException, NoSuchAlgorithmException,
NoSuchProviderException, SignatureException {
@@ -533,15 +485,21 @@
// ok
}
- Security.removeProvider(wrongProvider.getName());
+ // This test has side effects affecting all other tests running later
+ // on in the same vm instance. Maybe a better way would be to first add
+ // a new provider, test if it works, then remove it and test if the
+ // exception is thrown.
+ //
+ // Security.removeProvider(wrongProvider.getName());
+ //
+ // try {
+ // cert.verify(cert.getPublicKey(), wrongProvider.getName());
+ // } catch (NoSuchAlgorithmException e) {
+ // // ok
+ // }
+ //
+ // Security.insertProviderAt(wrongProvider, oldPosition);
- try {
- cert.verify(cert.getPublicKey(), wrongProvider.getName());
- } catch (NoSuchAlgorithmException e) {
- // ok
- }
-
- Security.addProvider(wrongProvider);
/*
PublicKey k = cert.getPublicKey();
MyModifiablePublicKey tamperedKey = new MyModifiablePublicKey(k);
@@ -569,18 +527,20 @@
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws SignatureException
+ * @throws IOException
+ * @throws InvalidAlgorithmParameterException
*/
@TestTargetNew(
level = TestLevel.SUFFICIENT,
- notes = "Test fails: ClassCastException when InvalidKeyException is expected." +
- "",
+ notes = "Can't test exception for cases where the algorithm is unknown",
method = "verify",
args = {java.security.PublicKey.class}
)
- @BrokenTest("ClassCastException")
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testVerifyPublicKey2() throws InvalidKeyException,
CertificateException, NoSuchAlgorithmException,
- NoSuchProviderException, SignatureException {
+ NoSuchProviderException, SignatureException, InvalidAlgorithmParameterException, IOException {
Certificate c1 = new MyCertificate("TEST_TYPE", testEncoding);
c1.verify(null);
@@ -605,18 +565,7 @@
fail("Exception expected");
} catch (Exception e) {
// ok
- }
-
- MyModifiablePublicKey changedAlgo = new MyModifiablePublicKey(k);
- changedAlgo.setAlgorithm("MD5withBla");
-
- try {
- cert.verify(changedAlgo);
- fail("Exception expected");
- } catch (SignatureException e) {
- // ok
- }
-
+ }
}
/**
@@ -628,6 +577,8 @@
method = "writeReplace",
args = {}
)
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public final void testWriteReplace2() {
MyCertificate c1 = new MyFailingCertificate("TEST_TYPE", testEncoding);
@@ -661,6 +612,8 @@
args = {}
)
})
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public void testSerializationSelf() throws Exception {
TestUtils.initCertPathSSCertChain();
@@ -690,6 +643,8 @@
args = {}
)
})
+ @AndroidOnly("Gets security providers with specific signature algorithm: " +
+ "Security.getProviders(\"Signature.sha1WithRSAEncryption\")")
public void testSerializationCompatibility() throws Exception {
//create test file (once)
// SerializationTest.createGoldenFile("device/dalvik/libcore/security/src/test/resources/serialization", this, TestUtils.rootCertificateSS);
diff --git a/libcore/security/src/test/java/tests/security/cert/CollectionCertStoreParametersTest.java b/libcore/security/src/test/java/tests/security/cert/CollectionCertStoreParametersTest.java
index f4fb0ec..551fda6 100644
--- a/libcore/security/src/test/java/tests/security/cert/CollectionCertStoreParametersTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/CollectionCertStoreParametersTest.java
@@ -43,14 +43,6 @@
@TestTargetClass(CollectionCertStoreParameters.class)
public class CollectionCertStoreParametersTest extends TestCase {
- /**
- * Constructor for CollectionCertStoreParametersTest.
- * @param name
- */
- public CollectionCertStoreParametersTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/cert/LDAPCertStoreParametersTest.java b/libcore/security/src/test/java/tests/security/cert/LDAPCertStoreParametersTest.java
index e699f91..66d5ad4 100644
--- a/libcore/security/src/test/java/tests/security/cert/LDAPCertStoreParametersTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/LDAPCertStoreParametersTest.java
@@ -40,14 +40,6 @@
@TestTargetClass(LDAPCertStoreParameters.class)
public class LDAPCertStoreParametersTest extends TestCase {
- /**
- * Constructor for LDAPCertStoreParametersTest.
- * @param name
- */
- public LDAPCertStoreParametersTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/cert/PKIXBuilderParametersTest.java b/libcore/security/src/test/java/tests/security/cert/PKIXBuilderParametersTest.java
index 789fb6b..b3ebcb6 100644
--- a/libcore/security/src/test/java/tests/security/cert/PKIXBuilderParametersTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/PKIXBuilderParametersTest.java
@@ -84,14 +84,6 @@
+ "-----END CERTIFICATE-----\n";
/**
- * Constructor for PKIXBuilderParametersTest.
- * @param name
- */
- public PKIXBuilderParametersTest(String name) {
- super(name);
- }
-
- /**
* Test #1 for <code>PKIXBuilderParameters(Set, CertSelector)</code>
* constructor<br>
* Assertion: creates an instance of <code>PKIXBuilderParameters</code>
diff --git a/libcore/security/src/test/java/tests/security/cert/PKIXCertPathBuilderResultTest.java b/libcore/security/src/test/java/tests/security/cert/PKIXCertPathBuilderResultTest.java
index a7a5e74..57f7882 100644
--- a/libcore/security/src/test/java/tests/security/cert/PKIXCertPathBuilderResultTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/PKIXCertPathBuilderResultTest.java
@@ -70,14 +70,6 @@
};
- /**
- * Constructor for PKIXCertPathBuilderResultTest.
- * @param name
- */
- public PKIXCertPathBuilderResultTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/cert/PKIXCertPathCheckerTest.java b/libcore/security/src/test/java/tests/security/cert/PKIXCertPathCheckerTest.java
index 01db618..6153d5c 100644
--- a/libcore/security/src/test/java/tests/security/cert/PKIXCertPathCheckerTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/PKIXCertPathCheckerTest.java
@@ -46,14 +46,6 @@
@TestTargetClass(PKIXCertPathChecker.class)
public class PKIXCertPathCheckerTest extends TestCase {
- /**
- * Constructor for PKIXCertPathCheckerTest.
- * @param name
- */
- public PKIXCertPathCheckerTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/cert/PKIXCertPathValidatorResultTest.java b/libcore/security/src/test/java/tests/security/cert/PKIXCertPathValidatorResultTest.java
index 610bdc4..e3970ac 100644
--- a/libcore/security/src/test/java/tests/security/cert/PKIXCertPathValidatorResultTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/PKIXCertPathValidatorResultTest.java
@@ -60,14 +60,6 @@
}
};
- /**
- * Constructor for PKIXCertPathValidatorResultTest.
- * @param name
- */
- public PKIXCertPathValidatorResultTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/cert/PKIXParametersTest.java b/libcore/security/src/test/java/tests/security/cert/PKIXParametersTest.java
index 79f489e..394e08e 100644
--- a/libcore/security/src/test/java/tests/security/cert/PKIXParametersTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/PKIXParametersTest.java
@@ -22,8 +22,7 @@
package tests.security.cert;
-import dalvik.annotation.BrokenTest;
-import dalvik.annotation.KnownFailure;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -69,15 +68,6 @@
private final static String testIssuer =
"CN=VM,OU=DRL Security,O=Intel,L=Novosibirsk,ST=NSO,C=RU";
- /**
- * Constructor for PKIXParametersTest.
- *
- * @param name
- */
- public PKIXParametersTest(String name) {
- super(name);
- }
-
//
// Tests
//
@@ -1423,9 +1413,8 @@
method = "setDate",
args = {java.util.Date.class}
)
- @KnownFailure("p.setDate(null) does not reset to current"+
- " time. RI fails at last assertion (time reset to 2007). Our" +
- " fails at assertNotNull(p.getDate)")
+ @AndroidOnly("On the RI p.setDate(null) does not reset the date to null "
+ + "as specified.")
public final void test_setDateLjava_util_Date() throws Exception {
Set<TrustAnchor> taSet = TestUtils.getTrustAnchorSet();
assertNotNull("could not create test TrustAnchor set", taSet);
@@ -1453,8 +1442,7 @@
p = new PKIXParameters(taSet);
p.setDate(new Date(555L));
p.setDate(null); // reset 'date' back to current time
- assertNotNull(p.getDate());
- assertEquals(Calendar.getInstance().getTime(), p.getDate());
+ assertNull(p.getDate());
}
/**
@@ -1567,7 +1555,12 @@
* Test #3 for <code>setInitialPolicies(Set)</code> method<br>
* Assertion: <code>Set</code> may be empty
*/
- @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, notes = "Doesn't verify ClassCastException.", method = "setInitialPolicies", args = {java.util.Set.class})
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Doesn't verify ClassCastException.",
+ method = "setInitialPolicies",
+ args = {java.util.Set.class}
+ )
public final void testSetInitialPolicies03() throws Exception {
Set<TrustAnchor> taSet = TestUtils.getTrustAnchorSet();
if (taSet == null) {
@@ -1585,7 +1578,12 @@
* Assertion: <code>Set</code> is copied to protect against subsequent
* modifications
*/
- @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, notes = "Verifies that Set is copied to protect against subsequent modifications.", method = "setInitialPolicies", args = {java.util.Set.class})
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies that Set is copied to protect against subsequent modifications.",
+ method = "setInitialPolicies",
+ args = {java.util.Set.class}
+ )
public final void testSetInitialPolicies04() throws Exception {
Set<TrustAnchor> taSet = TestUtils.getTrustAnchorSet();
if (taSet == null) {
@@ -1612,7 +1610,12 @@
*
* @throws InvalidAlgorithmParameterException
*/
- @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, notes = "Verifies ClassCastException.", method = "setInitialPolicies", args = {java.util.Set.class})
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Verifies ClassCastException.",
+ method = "setInitialPolicies",
+ args = {java.util.Set.class}
+ )
@SuppressWarnings("unchecked")
public final void testSetInitialPolicies05() throws Exception {
Set<TrustAnchor> taSet = TestUtils.getTrustAnchorSet();
@@ -1870,8 +1873,5 @@
PKIXParameters p = new PKIXParameters(keystore);
-
-
-
}
}
diff --git a/libcore/security/src/test/java/tests/security/cert/PolicyNodeTest.java b/libcore/security/src/test/java/tests/security/cert/PolicyNodeTest.java
index 95d9629..6c075f9 100644
--- a/libcore/security/src/test/java/tests/security/cert/PolicyNodeTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/PolicyNodeTest.java
@@ -98,14 +98,6 @@
}
- /**
- * Constructor for CRLTest.
- * @param name
- */
- public PolicyNodeTest(String name) {
- super(name);
- }
-
class MyPolicyNode extends PolicyNodeImpl {
MyPolicyNode(PolicyNodeImpl policynode, String s, Set set,
boolean flag, Set set1, boolean flag1) {
diff --git a/libcore/security/src/test/java/tests/security/cert/PolicyQualifierInfoTest.java b/libcore/security/src/test/java/tests/security/cert/PolicyQualifierInfoTest.java
index d794f06..be86083 100644
--- a/libcore/security/src/test/java/tests/security/cert/PolicyQualifierInfoTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/PolicyQualifierInfoTest.java
@@ -39,13 +39,6 @@
@TestTargetClass(PolicyQualifierInfo.class)
public class PolicyQualifierInfoTest extends TestCase {
- /**
- * Constructor for PolicyQualifierInfoTest.
- * @param name
- */
- public PolicyQualifierInfoTest(String name) {
- super(name);
- }
/**
* Test #1 for <code>PolicyQualifierInfo</code> constructor<br>
diff --git a/libcore/security/src/test/java/tests/security/cert/X509CRLSelector2Test.java b/libcore/security/src/test/java/tests/security/cert/X509CRLSelector2Test.java
index e3bf819..4dafb52 100644
--- a/libcore/security/src/test/java/tests/security/cert/X509CRLSelector2Test.java
+++ b/libcore/security/src/test/java/tests/security/cert/X509CRLSelector2Test.java
@@ -1,5 +1,6 @@
package tests.security.cert;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -289,6 +290,8 @@
method = "setMinCRLNumber",
args = {java.math.BigInteger.class}
)
+ @AndroidOnly("Uses specific class: " +
+ "org.apache.harmony.security.asn1.ASN1OctetString.")
public void testSetMinCRLNumberLjava_math_BigInteger() {
X509CRLSelector selector = new X509CRLSelector();
BigInteger minCRL = new BigInteger("10000");
@@ -317,6 +320,8 @@
method = "setMaxCRLNumber",
args = {java.math.BigInteger.class}
)
+ @AndroidOnly("Uses specific class: " +
+ "org.apache.harmony.security.asn1.ASN1OctetString.")
public void testSetMaxCRLNumberLjava_math_BigInteger() {
X509CRLSelector selector = new X509CRLSelector();
BigInteger maxCRL = new BigInteger("10000");
@@ -573,6 +578,9 @@
method = "clone",
args = {}
)
+ @AndroidOnly("Uses specific classes: " +
+ "org.apache.harmony.security.asn1.ASN1OctetString, " +
+ "org.apache.harmony.security.asn1.ASN1Integer.")
public void testClone() {
X509CRLSelector selector = new X509CRLSelector();
X500Principal iss1 = new X500Principal("O=First Org.");
diff --git a/libcore/security/src/test/java/tests/security/cert/X509CRLTest.java b/libcore/security/src/test/java/tests/security/cert/X509CRLTest.java
index bd80dac..c10494e 100644
--- a/libcore/security/src/test/java/tests/security/cert/X509CRLTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/X509CRLTest.java
@@ -22,6 +22,7 @@
package tests.security.cert;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -172,6 +173,10 @@
public X509CRLTest() {
+
+ }
+
+ public void setUp() {
tbt_crl = new TBTCRL() {
public byte[] getEncoded() {
return new byte[] {1, 2, 3};
@@ -300,6 +305,8 @@
method = "getRevokedCertificate",
args = {java.security.cert.X509Certificate.class}
)
+ @AndroidOnly("Test filed on RI: getRevokedCertificate throws " +
+ "RuntimeException.")
public void testGetRevokedCertificate() {
try {
tbt_crl.getRevokedCertificate((X509Certificate) null);
diff --git a/libcore/security/src/test/java/tests/security/cert/X509CertSelectorTest.java b/libcore/security/src/test/java/tests/security/cert/X509CertSelectorTest.java
index a3c1d24..3199ffa 100644
--- a/libcore/security/src/test/java/tests/security/cert/X509CertSelectorTest.java
+++ b/libcore/security/src/test/java/tests/security/cert/X509CertSelectorTest.java
@@ -17,8 +17,6 @@
package tests.security.cert;
-import dalvik.annotation.BrokenTest;
-
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -38,18 +36,15 @@
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderException;
-import java.security.cert.CertStore;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.CertificateParsingException;
-import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXCertPathBuilderResult;
import java.security.cert.TrustAnchor;
-import java.security.cert.X509CRL;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
@@ -66,7 +61,6 @@
import javax.security.auth.x500.X500Principal;
-import org.apache.harmony.security.provider.cert.X509CertImpl;
import org.apache.harmony.security.tests.support.cert.MyCRL;
import org.apache.harmony.security.tests.support.cert.TestUtils;
import org.apache.harmony.security.tests.support.TestKeyPair;
@@ -80,8 +74,6 @@
import org.apache.harmony.security.x509.CertificatePolicies;
import org.apache.harmony.security.x509.GeneralName;
import org.apache.harmony.security.x509.GeneralNames;
-import org.apache.harmony.security.x509.GeneralSubtree;
-import org.apache.harmony.security.x509.GeneralSubtrees;
import org.apache.harmony.security.x509.NameConstraints;
import org.apache.harmony.security.x509.ORAddress;
import org.apache.harmony.security.x509.OtherName;
@@ -93,6 +85,47 @@
*/
@TestTargetClass(X509CertSelector.class)
public class X509CertSelectorTest extends TestCase {
+
+ byte[][] constraintBytes = new byte[][] {
+ {
+ 48, 34, -96, 15, 48, 13, -127, 8, 56, 50, 50, 46, 78,
+ 97, 109, 101, -128, 1, 0, -95, 15, 48, 13, -127, 8, 56,
+ 50, 50, 46, 78, 97, 109, 101, -128, 1, 0},
+ {
+ 48, 42, -96, 19, 48, 17, -127, 12, 114, 102, 99, 64,
+ 56, 50, 50, 46, 78, 97, 109, 101, -128, 1, 0, -95, 19,
+ 48, 17, -127, 12, 114, 102, 99, 64, 56, 50, 50, 46, 78,
+ 97, 109, 101, -128, 1, 0},
+ {
+ 48, 34, -96, 15, 48, 13, -126, 8, 78, 97, 109, 101, 46,
+ 111, 114, 103, -128, 1, 0, -95, 15, 48, 13, -126, 8,
+ 78, 97, 109, 101, 46, 111, 114, 103, -128, 1, 0},
+ {
+ 48, 42, -96, 19, 48, 17, -126, 12, 100, 78, 83, 46, 78,
+ 97, 109, 101, 46, 111, 114, 103, -128, 1, 0, -95, 19,
+ 48, 17, -126, 12, 100, 78, 83, 46, 78, 97, 109, 101,
+ 46, 111, 114, 103, -128, 1, 0},
+ {
+ 48, 54, -96, 25, 48, 23, -122, 18, 104, 116, 116, 112,
+ 58, 47, 47, 82, 101, 115, 111, 117, 114, 99, 101, 46,
+ 73, 100, -128, 1, 0, -95, 25, 48, 23, -122, 18, 104,
+ 116, 116, 112, 58, 47, 47, 82, 101, 115, 111, 117, 114,
+ 99, 101, 46, 73, 100, -128, 1, 0},
+ {
+ 48, 70, -96, 33, 48, 31, -122, 26, 104, 116, 116, 112,
+ 58, 47, 47, 117, 110, 105, 102, 111, 114, 109, 46, 82,
+ 101, 115, 111, 117, 114, 99, 101, 46, 73, 100, -128, 1,
+ 0, -95, 33, 48, 31, -122, 26, 104, 116, 116, 112, 58,
+ 47, 47, 117, 110, 105, 102, 111, 114, 109, 46, 82, 101,
+ 115, 111, 117, 114, 99, 101, 46, 73, 100, -128, 1, 0},
+ {
+ 48, 26, -96, 11, 48, 9, -121, 4, 1, 1, 1, 1, -128, 1,
+ 0, -95, 11, 48, 9, -121, 4, 1, 1, 1, 1, -128, 1, 0},
+ {
+ 48, 50, -96, 23, 48, 21, -121, 16, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, -128, 1, 0, -95, 23, 48, 21,
+ -121, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, -128, 1, 0}};
/**
* @tests java.security.cert.X509CertSelector#addSubjectAlternativeName(int, byte[])
@@ -542,29 +575,38 @@
args = {}
)
public void test_getNameConstraints() throws IOException {
- GeneralName[] name_constraints = new GeneralName[] {
- new GeneralName(1, "822.Name"),
- new GeneralName(1, "rfc@822.Name"),
- new GeneralName(2, "Name.org"),
- new GeneralName(2, "dNS.Name.org"),
- new GeneralName(6, "http://Resource.Id"),
- new GeneralName(6, "http://uniform.Resource.Id"),
- new GeneralName(7, "1.1.1.1"),
-
- new GeneralName(new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1 }), };
+// Used to generate following byte array
+// GeneralName[] name_constraints = new GeneralName[] {
+// new GeneralName(1, "822.Name"),
+// new GeneralName(1, "rfc@822.Name"),
+// new GeneralName(2, "Name.org"),
+// new GeneralName(2, "dNS.Name.org"),
+//
+// new GeneralName(6, "http://Resource.Id"),
+// new GeneralName(6, "http://uniform.Resource.Id"),
+// new GeneralName(7, "1.1.1.1"),
+//
+// new GeneralName(new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+// 1, 1, 1, 1, 1 }), };
+//
+// constraintBytes = new byte[name_constraints.length][];
+//
+// for (int i = 0; i < name_constraints.length; i++) {
+// GeneralSubtree subtree = new GeneralSubtree(name_constraints[i]);
+// GeneralSubtrees subtrees = new GeneralSubtrees();
+// subtrees.addSubtree(subtree);
+// NameConstraints constraints = new NameConstraints(subtrees,
+// subtrees);
+// constraintBytes[i] = constraints.getEncoded();
+// }
+// System.out.println("XXX"+Arrays.deepToString(constraintBytes)+"XXX");
X509CertSelector selector = new X509CertSelector();
- for (int i = 0; i < name_constraints.length; i++) {
- GeneralSubtree subtree = new GeneralSubtree(name_constraints[i]);
- GeneralSubtrees subtrees = new GeneralSubtrees();
- subtrees.addSubtree(subtree);
- NameConstraints constraints = new NameConstraints(subtrees,
- subtrees);
- selector.setNameConstraints(constraints.getEncoded());
- assertTrue(Arrays.equals(constraints.getEncoded(), selector
+ for (int i = 0; i < constraintBytes.length; i++) {
+ selector.setNameConstraints(constraintBytes[i]);
+ assertTrue(Arrays.equals(constraintBytes[i], selector
.getNameConstraints()));
}
}
@@ -1353,29 +1395,31 @@
args = {byte[].class}
)
public void test_setNameConstraintsLB$() throws IOException {
- GeneralName[] name_constraints = new GeneralName[] {
- new GeneralName(1, "822.Name"),
- new GeneralName(1, "rfc@822.Name"),
- new GeneralName(2, "Name.org"),
- new GeneralName(2, "dNS.Name.org"),
-
- new GeneralName(6, "http://Resource.Id"),
- new GeneralName(6, "http://uniform.Resource.Id"),
- new GeneralName(7, "1.1.1.1"),
-
- new GeneralName(new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1 }), };
-
+// GeneralName[] name_constraints = new GeneralName[] {
+// new GeneralName(1, "822.Name"),
+// new GeneralName(1, "rfc@822.Name"),
+// new GeneralName(2, "Name.org"),
+// new GeneralName(2, "dNS.Name.org"),
+//
+// new GeneralName(6, "http://Resource.Id"),
+// new GeneralName(6, "http://uniform.Resource.Id"),
+// new GeneralName(7, "1.1.1.1"),
+//
+// new GeneralName(new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+// 1, 1, 1, 1, 1 }), };
+//
+// for (int i = 0; i < name_constraints.length; i++) {
+// GeneralSubtree subtree = new GeneralSubtree(name_constraints[i]);
+// GeneralSubtrees subtrees = new GeneralSubtrees();
+// subtrees.addSubtree(subtree);
+// NameConstraints constraints = new NameConstraints(subtrees,
+// subtrees);
+// }
X509CertSelector selector = new X509CertSelector();
- for (int i = 0; i < name_constraints.length; i++) {
- GeneralSubtree subtree = new GeneralSubtree(name_constraints[i]);
- GeneralSubtrees subtrees = new GeneralSubtrees();
- subtrees.addSubtree(subtree);
- NameConstraints constraints = new NameConstraints(subtrees,
- subtrees);
- selector.setNameConstraints(constraints.getEncoded());
- assertTrue(Arrays.equals(constraints.getEncoded(), selector
+ for (int i = 0; i < constraintBytes.length; i++) {
+ selector.setNameConstraints(constraintBytes[i]);
+ assertTrue(Arrays.equals(constraintBytes[i], selector
.getNameConstraints()));
}
}
@@ -2347,183 +2391,12 @@
private CertPathBuilder builder;
- /**
- * Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 0 (0x0)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=AN, ST=Android, O=Android, OU=Android, CN=Android/emailAddress=android
- Validity
- Not Before: Dec 9 16:35:30 2008 GMT
- Not After : Dec 9 16:35:30 2011 GMT
- Subject: C=AN, ST=Android, O=Android, OU=Android, CN=Android/emailAddress=android
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:c5:fb:5e:68:37:82:1d:58:ed:cb:31:8c:08:7f:
- 51:31:4c:68:40:8c:4d:07:a1:0e:18:36:02:6b:89:
- 92:c1:cf:88:1e:cf:00:22:00:8c:37:e8:6a:76:94:
- 71:53:81:78:e1:48:94:fa:16:61:93:eb:a0:ee:62:
- 9d:6a:d2:2c:b8:77:9d:c9:36:d5:d9:1c:eb:26:3c:
- 43:66:4d:7b:1c:1d:c7:a1:37:66:e2:84:54:d3:ed:
- 21:dd:01:1c:ec:9b:0c:1e:35:e9:37:15:9d:2b:78:
- a8:3b:11:3a:ee:c2:de:55:44:4c:bd:40:8d:e5:52:
- b0:fc:53:33:73:4a:e5:d0:df
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 4B:E3:22:14:AD:0A:14:46:B7:52:31:8B:AB:9E:5A:62:F3:98:37:80
- X509v3 Authority Key Identifier:
- keyid:4B:E3:22:14:AD:0A:14:46:B7:52:31:8B:AB:9E:5A:62:F3:98:37:80
- DirName:/C=AN/ST=Android/O=Android/OU=Android/CN=Android/emailAddress=android
- serial:00
-
- X509v3 Basic Constraints:
- CA:TRUE
- Signature Algorithm: sha1WithRSAEncryption
- 72:4f:12:8a:4e:61:b2:9a:ba:58:17:0b:55:96:f5:66:1c:a8:
- ba:d1:0f:8b:9b:2d:ab:a8:00:ac:7f:99:7d:f6:0f:d7:85:eb:
- 75:4b:e5:42:37:71:46:b1:4a:b0:1b:17:e4:f9:7c:9f:bd:20:
- 75:35:9f:27:8e:07:95:e8:34:bd:ab:e4:10:5f:a3:7b:4c:56:
- 69:d4:d0:f1:e9:74:15:2d:7f:77:f0:38:77:eb:8a:99:f3:a9:
- 88:f0:63:58:07:b9:5a:61:f8:ff:11:e7:06:a1:d1:f8:85:fb:
- 99:1c:f5:cb:77:86:36:cd:43:37:99:09:c2:9a:d8:f2:28:05:
- 06:0c
-
- */
- public static final String rootCert = "-----BEGIN CERTIFICATE-----\n" +
- "MIIDGzCCAoSgAwIBAgIBADANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJBTjEQ\n" +
- "MA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5k\n" +
- "cm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEWMBQGCSqGSIb3DQEJARYHYW5kcm9pZDAe\n" +
- "Fw0wODEyMDkxNjM1MzBaFw0xMTEyMDkxNjM1MzBaMG0xCzAJBgNVBAYTAkFOMRAw\n" +
- "DgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQKEwdBbmRyb2lkMRAwDgYDVQQLEwdBbmRy\n" +
- "b2lkMRAwDgYDVQQDEwdBbmRyb2lkMRYwFAYJKoZIhvcNAQkBFgdhbmRyb2lkMIGf\n" +
- "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDF+15oN4IdWO3LMYwIf1ExTGhAjE0H\n" +
- "oQ4YNgJriZLBz4gezwAiAIw36Gp2lHFTgXjhSJT6FmGT66DuYp1q0iy4d53JNtXZ\n" +
- "HOsmPENmTXscHcehN2bihFTT7SHdARzsmwweNek3FZ0reKg7ETruwt5VREy9QI3l\n" +
- "UrD8UzNzSuXQ3wIDAQABo4HKMIHHMB0GA1UdDgQWBBRL4yIUrQoURrdSMYurnlpi\n" +
- "85g3gDCBlwYDVR0jBIGPMIGMgBRL4yIUrQoURrdSMYurnlpi85g3gKFxpG8wbTEL\n" +
- "MAkGA1UEBhMCQU4xEDAOBgNVBAgTB0FuZHJvaWQxEDAOBgNVBAoTB0FuZHJvaWQx\n" +
- "EDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWQxFjAUBgkqhkiG9w0B\n" +
- "CQEWB2FuZHJvaWSCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBy\n" +
- "TxKKTmGymrpYFwtVlvVmHKi60Q+Lmy2rqACsf5l99g/Xhet1S+VCN3FGsUqwGxfk\n" +
- "+XyfvSB1NZ8njgeV6DS9q+QQX6N7TFZp1NDx6XQVLX938Dh364qZ86mI8GNYB7la\n" +
- "Yfj/EecGodH4hfuZHPXLd4Y2zUM3mQnCmtjyKAUGDA==\n" +
- "-----END CERTIFICATE-----";
-
- public static final String rootPrivateKey =
- "-----BEGIN RSA PRIVATE KEY-----\n" +
- "Proc-Type: 4,ENCRYPTED\n" +
- "DEK-Info: DES-EDE3-CBC,D9682F66FDA316E5\n" +
- "\n" +
- "8lGaQPlUZ/iHhdldB//xfNUrZ3RAkBthzKg+n9HBJsjztXXAZ40NGYZmgvpgnfmr\n" +
- "7ZJxHxYHFc3GAmBBk9v+/dA8E5yWJa71roffWMQUuFNfGzHhGTOxvNC04W7yAajs\n" +
- "CPuyI+xnAAo73F7NVTiqX3NVgu4bB8RVxJyToMe4M289oh93YvxWQ4buVTf0ErJ8\n" +
- "Yc8+0ugpfXjGfRhL36qj6B1CcV7NMdXAVExrGlTf0TWT9wVbiROk4XaoaFuWh17h\n" +
- "11NEDjsKQ8T4M9kRdC+tKfST8sLik1Pq6jRLIKeX8GQd7tV1IWVZ3KcQBJwu9zLq\n" +
- "Hi0GTSF7IWCdwXjDyniMQiSbkmHNP+OnVyhaqew5Ooh0uOEQq/KWFewXg7B3VMr0\n" +
- "l6U8sBX9ODGeW0wVdNopvl17udCkV0xm3S+MRZDnZiTlAXwKx/a/gyf5R5XYp3S0\n" +
- "0eqrfy2o6Ax4hRkwcNJ2KMeLQNIiYYWKABQj5/i4TYZV6npCIXOnQEkXa9DmqyUE\n" +
- "qB7eFj5FcXeqQ8ERmsLveWArsLDn2NNPdv5EaKIs2lrvwoKYeYF7hrKNpifq+QqS\n" +
- "u1kN+KHjibcF42EAUozNVmkHsW8VqlywAs4MsMwxU0D57cVGWycuSedraKhc0D6j\n" +
- "a4pQOWWY3ZMLoAA1ZmHG9cjDPqcJt0rqk5AhSBRmGVUccfkP7dk9KyJQizro87LI\n" +
- "u7zWwMIqTfmlhyfAP0AWjrt/bMN9heGByVA55xkyCdSEVaC5gsIfmGpNy4u+wbZ9\n" +
- "rSWVuTfAbjW0n0FW+CDS1LgdjXNkeAP2Uvc1QgVRCPdA23WniLFFJQ==\n" +
- "-----END RSA PRIVATE KEY-----";
-
- /**
- * Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 1 (0x1)
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=AN, ST=Android, O=Android, OU=Android, CN=Android/emailAddress=android
- Validity
- Not Before: Dec 9 16:40:35 2008 GMT
- Not After : Dec 9 16:40:35 2009 GMT
- Subject: C=AN, ST=Android, L=Android, O=Android, OU=Android, CN=Android Certificate/emailAddress=android
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- RSA Public Key: (1024 bit)
- Modulus (1024 bit):
- 00:b8:e3:de:c7:a9:40:47:2c:2a:6f:f5:2a:f4:cd:
- f2:2d:40:fa:15:3f:1c:37:66:73:a5:67:4d:5b:a0:
- b6:b1:dd:dc:bf:01:c7:e2:c1:48:1a:8f:1c:ce:ec:
- b0:a2:55:29:9a:1b:3a:6e:cc:7b:d7:65:ae:0b:05:
- 34:03:8a:af:db:f0:dc:01:80:92:03:b4:13:e5:d6:
- fd:79:66:7f:c3:1a:62:d5:5e:3d:c0:19:a4:42:15:
- 47:19:e6:f0:c8:b7:e2:7b:82:a2:c7:3d:df:ac:8c:
- d5:bc:39:b8:e5:93:ac:3f:af:30:b7:cc:00:a8:00:
- f3:38:23:b0:97:0e:92:b1:1b
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
- X509v3 Subject Key Identifier:
- 88:4D:EC:16:26:A7:76:F5:26:43:BC:34:99:DF:D5:EA:7B:F8:5F:DE
- X509v3 Authority Key Identifier:
- keyid:4B:E3:22:14:AD:0A:14:46:B7:52:31:8B:AB:9E:5A:62:F3:98:37:80
-
- Signature Algorithm: sha1WithRSAEncryption
- 55:73:95:e6:4c:40:fc:fd:52:8a:5f:83:15:49:73:ca:f3:d8:
- 5f:bb:d6:f5:2e:90:e6:7f:c3:7d:4d:27:d3:45:c6:53:9b:aa:
- e3:32:99:40:b3:a9:d3:14:7d:d5:e6:a7:70:95:30:6e:dc:8c:
- 7b:48:e1:98:d1:65:7a:eb:bf:b0:5c:cd:c2:eb:31:5e:b6:e9:
- df:56:95:bc:eb:79:74:27:5b:6d:c8:55:63:09:d3:f9:e2:40:
- ba:b4:a2:c7:2c:cb:b1:3a:c2:d8:0c:21:31:ee:68:7e:97:ce:
- 98:22:2e:c6:cf:f0:1a:11:04:ca:9a:06:de:98:48:85:ac:6c:
- 6f:98
- */
- public static final String endCert =
- "-----BEGIN CERTIFICATE-----\n" +
- "MIIC6jCCAlOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJBTjEQ\n" +
- "MA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5k\n" +
- "cm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEWMBQGCSqGSIb3DQEJARYHYW5kcm9pZDAe\n" +
- "Fw0wODEyMDkxNjQwMzVaFw0wOTEyMDkxNjQwMzVaMIGLMQswCQYDVQQGEwJBTjEQ\n" +
- "MA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEBxMHQW5kcm9pZDEQMA4GA1UEChMHQW5k\n" +
- "cm9pZDEQMA4GA1UECxMHQW5kcm9pZDEcMBoGA1UEAxMTQW5kcm9pZCBDZXJ0aWZp\n" +
- "Y2F0ZTEWMBQGCSqGSIb3DQEJARYHYW5kcm9pZDCBnzANBgkqhkiG9w0BAQEFAAOB\n" +
- "jQAwgYkCgYEAuOPex6lARywqb/Uq9M3yLUD6FT8cN2ZzpWdNW6C2sd3cvwHH4sFI\n" +
- "Go8czuywolUpmhs6bsx712WuCwU0A4qv2/DcAYCSA7QT5db9eWZ/wxpi1V49wBmk\n" +
- "QhVHGebwyLfie4Kixz3frIzVvDm45ZOsP68wt8wAqADzOCOwlw6SsRsCAwEAAaN7\n" +
- "MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQg\n" +
- "Q2VydGlmaWNhdGUwHQYDVR0OBBYEFIhN7BYmp3b1JkO8NJnf1ep7+F/eMB8GA1Ud\n" +
- "IwQYMBaAFEvjIhStChRGt1Ixi6ueWmLzmDeAMA0GCSqGSIb3DQEBBQUAA4GBAFVz\n" +
- "leZMQPz9UopfgxVJc8rz2F+71vUukOZ/w31NJ9NFxlObquMymUCzqdMUfdXmp3CV\n" +
- "MG7cjHtI4ZjRZXrrv7BczcLrMV626d9WlbzreXQnW23IVWMJ0/niQLq0oscsy7E6\n" +
- "wtgMITHuaH6XzpgiLsbP8BoRBMqaBt6YSIWsbG+Y\n" +
- "-----END CERTIFICATE-----";
-
- public static final String endPrivateKey =
- "-----BEGIN RSA PRIVATE KEY-----\n" +
- "Proc-Type: 4,ENCRYPTED\n" +
- "DEK-Info: DES-EDE3-CBC,E20AAB000D1D90B1\n" +
- "\n" +
- "cWrCb6eHuwb6/gnbX12Va47qSpFW0j99Lq2eEj0fqLdlwA6+KvD3/U+Nj4ldaAQ4\n" +
- "rYryQv0MJu/kT9z/mJbBI4NwunX/9vXttyuh8s07sv8AqdHCylYR9miz61Q0LkLR\n" +
- "9H9D8NWMgMnuVhlj+NUXlkF+Jfriu5xkIqeYDhN8c3/AMawQoNdW/pWmgz0BfFIP\n" +
- "DUxszfXHx5mfSMoRdC2YZGlFdsONSO7s14Ayz8+pKD0PzSARXtTEJ5+mELCnhFsw\n" +
- "R7zYYwD+9WjL702bjYQxwRS5Sk1Z/VAxLFfjdtlUFSi6VLGIG+jUnM1RF91KtJY1\n" +
- "bJOQrlHw9/wyH75y9sXUrVpil4qH9shILHgu4A0VaL7IpIFjWS9vPY7SvwqRlbk7\n" +
- "QPhxoIpiNzjzjEa7PG6nSqy8mRzJP0OLWzRUoMWJn6ntf+oj7CzaaIgFrrwRGOCQ\n" +
- "BYibTTMZ/paxKDvZ9Lcl8a6uRvi2II2/F63bPcTcILsKDsBdQp93Evanw1QKXdGi\n" +
- "jb4b0Y1LYZM0jl7z2TSBZ27HyHKp4jMQP9q9mujEKInjzSB+gsRGfP6++OilrR2U\n" +
- "Y7kN2o/ufnPHltel0pUWOHr45IyK8zowgXWtKVl9U+VRwr2thGbdqkRGk55KjJK4\n" +
- "Q+OfwvIKHgvn/4cN/BGIA/52eyY//bTFk6ePGY2vlQK4mvB7MeSxtxoCGxdCYQru\n" +
- "wI28rOHyQ1cdx141yxlKVSIcxBVZHm8sfh9PHeKMKuaOgc8kfx+Qh8IghFHyJ+yg\n" +
- "PboNF9/PiM/glaaBzY2OKTYQKY6LiTetZiI6RdLE7Y+SFwG7Wwo5dg==\n" +
- "-----END RSA PRIVATE KEY-----";
-
private void setupEnvironment() throws Exception {
// create certificates and CRLs
CertificateFactory cf = CertificateFactory.getInstance("X.509");
- ByteArrayInputStream bi = new ByteArrayInputStream(rootCert.getBytes());
+ ByteArrayInputStream bi = new ByteArrayInputStream(TestUtils.rootCert.getBytes());
rootCertificate = (X509Certificate) cf.generateCertificate(bi);
- bi = new ByteArrayInputStream(endCert.getBytes());
+ bi = new ByteArrayInputStream(TestUtils.endCert.getBytes());
endCertificate = (X509Certificate) cf.generateCertificate(bi);
BigInteger revokedSerialNumber = BigInteger.valueOf(1);
@@ -2542,10 +2415,10 @@
// list);
// CertStore store = CertStore.getInstance("Collection", params);
//
-// theCertSelector = new X509CertSelector();
-// theCertSelector.setCertificate(endCertificate);
-// theCertSelector.setIssuer(endCertificate.getIssuerX500Principal()
-// .getEncoded());
+ theCertSelector = new X509CertSelector();
+ theCertSelector.setCertificate(endCertificate);
+ theCertSelector.setIssuer(endCertificate.getIssuerX500Principal()
+ .getEncoded());
// build the path
builder = CertPathBuilder.getInstance("PKIX");
@@ -2575,26 +2448,29 @@
method = "addPathToName",
args = {int.class, byte[].class}
)
- @BrokenTest("cannot find a valid name for whitch a match is found (assertNotNull(p);): check "+
- "test_addSubjectAlternativeNameLintLjava_lang_array2() for a possbile approach.")
public void test_addPathToNameLintLbyte_array2() throws Exception {
TestUtils.initCertPathSSCertChain();
-
- GeneralName name = new GeneralName(1, "822.Name");
- assertNotNull(name.getEncoded());
- byte[] b = new byte[name.getEncoded().length];
- b = name.getEncoded();
- b[name.getEncoded().length-3] = (byte) 200;
+ setupEnvironment();
+ byte[] bytes, bytesName;
+ // GeneralName name = new GeneralName(1, "822.Name");
+ // bytes = name.getEncoded();
+ // bytesName = name.getEncodedName();
+ bytes = new byte[] {-127, 8, 56, 50, 50, 46, 78, 97, 109, 101};
+ bytesName = new byte[] {-127, 8, 56, 50, 50, 46, 78, 97, 109, 101};
+ assertNotNull(bytes);
+ byte[] b = new byte[bytes.length];
+ b = bytes;
+ b[bytes.length-3] = (byte) 200;
try {
- theCertSelector.addPathToName(1, b);
+ theCertSelector.addPathToName(1, b);
} catch (IOException e) {
// ok
}
theCertSelector.setPathToNames(null);
- theCertSelector.addPathToName(1, name.getEncodedName());
+ theCertSelector.addPathToName(1, bytesName);
assertNotNull(theCertSelector.getPathToNames());
CertPath p = buildCertPath();
assertNull(p);
@@ -2618,16 +2494,18 @@
method = "addPathToName",
args = {int.class, java.lang.String.class}
)
- @BrokenTest("cannot find a valid name for whitch a match is found: check "+
- " for a possbile approach.")
public void test_addPathToNameLintLjava_lang_String2() throws Exception {
setupEnvironment();
-
- GeneralName name = new GeneralName(1, "822.Name");
- assertNotNull(name.getEncoded());
- byte[] b = new byte[name.getEncoded().length];
- b = name.getEncoded();
- b[name.getEncoded().length-3] = (byte) 200;
+ byte[] bytes, bytesName;
+ // GeneralName name = new GeneralName(1, "822.Name");
+ // bytes = name.getEncoded();
+ // bytesName = name.getEncodedName();
+ bytes = new byte[] {-127, 8, 56, 50, 50, 46, 78, 97, 109, 101};
+ bytesName = new byte[] {22, 8, 56, 50, 50, 46, 78, 97, 109, 101};
+ assertNotNull(bytes);
+ byte[] b = new byte[bytes.length];
+ b = bytes;
+ b[bytes.length-3] = (byte) 200;
try {
theCertSelector.addPathToName(1, new String(b));
@@ -2637,17 +2515,17 @@
theCertSelector.setPathToNames(null);
- theCertSelector.addPathToName(1, new String(name.getEncodedName()));
+ theCertSelector.addPathToName(1, new String(bytesName));
assertNotNull(theCertSelector.getPathToNames());
+
CertPath p = buildCertPath();
assertNull(p);
theCertSelector.setPathToNames(null);
-
- theCertSelector.addPathToName(0, rootCertificate.getIssuerX500Principal().getName());
+ theCertSelector.addPathToName(1, rootCertificate.getIssuerX500Principal().getName());
assertNotNull(theCertSelector.getPathToNames());
- p = buildCertPath();
- assertNotNull(p);
+ //p = buildCertPath();
+ //assertNotNull(p);
}
/**
@@ -2661,6 +2539,8 @@
)
public void test_addSubjectAlternativeNameLintLbyte_array2()
throws Exception {
+
+
GeneralName san0 = new GeneralName(new OtherName("1.2.3.4.5",
new byte[] {1, 2, 0, 1}));
GeneralName san1 = new GeneralName(1, "rfc@822.Name");
diff --git a/libcore/security/src/test/java/tests/security/cert/X509Certificate2Test.java b/libcore/security/src/test/java/tests/security/cert/X509Certificate2Test.java
index 54f2836..f60ca80 100644
--- a/libcore/security/src/test/java/tests/security/cert/X509Certificate2Test.java
+++ b/libcore/security/src/test/java/tests/security/cert/X509Certificate2Test.java
@@ -504,7 +504,7 @@
assertNull(new MyX509Certificate().getSubjectAlternativeNames());
Collection<List<?>> coll = cert.getSubjectAlternativeNames();
-
+ //getSubjectAlternativeNames method is not supported
assertNotNull(coll);
try {
@@ -540,7 +540,7 @@
assertNull(new MyX509Certificate().getIssuerAlternativeNames());
Collection<List<?>> coll = cert.getIssuerAlternativeNames();
-
+ // getIssuerAlternativeNames returns null.
assertNotNull(coll);
try {
diff --git a/libcore/security/src/test/java/tests/security/interfaces/AllTests.java b/libcore/security/src/test/java/tests/security/interfaces/AllTests.java
index 884dadf..e665119 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/AllTests.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/AllTests.java
@@ -39,9 +39,6 @@
suite.addTestSuite(RSAMultiPrimePrivateCrtKeyTest.class);
suite.addTestSuite(DSAPrivateKeyTest.class);
suite.addTestSuite(DSAPublicKeyTest.class);
- suite.addTestSuite(ECKeyTest.class);
- suite.addTestSuite(ECPrivateKeyTest.class);
- suite.addTestSuite(ECPublicKeyTest.class);
suite.addTestSuite(RSAKeyTest.class);
suite.addTestSuite(RSAPrivateCrtKeyTest.class);
suite.addTestSuite(RSAPrivateKeyTest.class);
diff --git a/libcore/security/src/test/java/tests/security/interfaces/DSAKeyPairGeneratorTest.java b/libcore/security/src/test/java/tests/security/interfaces/DSAKeyPairGeneratorTest.java
index 8c257d9..0de893d 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/DSAKeyPairGeneratorTest.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/DSAKeyPairGeneratorTest.java
@@ -16,7 +16,6 @@
package tests.security.interfaces;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
diff --git a/libcore/security/src/test/java/tests/security/interfaces/DSAKeyTest.java b/libcore/security/src/test/java/tests/security/interfaces/DSAKeyTest.java
index cb43b08..2a65b64 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/DSAKeyTest.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/DSAKeyTest.java
@@ -15,7 +15,6 @@
*/
package tests.security.interfaces;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -46,7 +45,7 @@
public void test_getParams() throws Exception {
DSAParams param = new DSAParameterSpec(Util.P, Util.Q, Util.G);
- KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA", Util.prov);
+ KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
gen.initialize((DSAParameterSpec) param);
DSAKey key = null;
diff --git a/libcore/security/src/test/java/tests/security/interfaces/DSAParamsTest.java b/libcore/security/src/test/java/tests/security/interfaces/DSAParamsTest.java
index f01462e..4a19512 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/DSAParamsTest.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/DSAParamsTest.java
@@ -14,7 +14,6 @@
* limitations under the License.
*/
package tests.security.interfaces;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
diff --git a/libcore/security/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java b/libcore/security/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java
index 504f8d7..ee09915 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/DSAPrivateKeyTest.java
@@ -17,7 +17,7 @@
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.KnownFailure;
+import dalvik.annotation.BrokenTest;
import junit.framework.TestCase;
@@ -39,12 +39,11 @@
method = "getX",
args = {}
)
- @SuppressWarnings("serial")
- @KnownFailure("Incorrect value was returned for method " +
+ @BrokenTest("Incorrect value was returned for method " +
"java.security.interfaces.DSAPrivateKey.getX(). "+
- "This test is passed for RI.")
+ "This test does not pass on the RI.")
public void test_getX() throws Exception {
- KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", Util.prov);
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(new DSAParameterSpec(Util.P, Util.Q, Util.G),
new SecureRandom(new MySecureRandomSpi(), null) {
});
diff --git a/libcore/security/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java b/libcore/security/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java
index 2341447..42f2966 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/DSAPublicKeyTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package tests.security.interfaces;
-import dalvik.annotation.KnownFailure;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -45,10 +45,9 @@
method = "getY",
args = {}
)
- @SuppressWarnings("serial")
- @KnownFailure("Incorrect value was returned for method " +
+ @BrokenTest("Incorrect value was returned for method " +
"java.security.interfaces.DSAPublicKey.getY(). "+
- "This test is passed for RI.")
+ "This test does not pass on the RI.")
public void test_getY() throws Exception {
KeyPairGenerator keyGen = null;
KeyPair keys = null;
@@ -56,7 +55,7 @@
DSAPublicKey publ = null;
// Case 1: check with predefined p, q, g, x
- keyGen = KeyPairGenerator.getInstance("DSA", Util.prov);
+ keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(new DSAParameterSpec(Util.P, Util.Q, Util.G),
new SecureRandom(new MySecureRandomSpi(), null) {
});
@@ -68,7 +67,7 @@
// Case 2: check with random p, q, g, x. It takes some time (up to
// minute)
- keyGen = KeyPairGenerator.getInstance("DSA", Util.prov);
+ keyGen = KeyPairGenerator.getInstance("DSA");
keys = keyGen.generateKeyPair();
priv = (DSAPrivateKey) keys.getPrivate();
publ = (DSAPublicKey) keys.getPublic();
diff --git a/libcore/security/src/test/java/tests/security/interfaces/ECKeyTest.java b/libcore/security/src/test/java/tests/security/interfaces/ECKeyTest.java
deleted file mode 100644
index cee4a6f..0000000
--- a/libcore/security/src/test/java/tests/security/interfaces/ECKeyTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.security.interfaces;
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
-import java.security.KeyPairGenerator;
-import java.security.interfaces.ECKey;
-import java.security.spec.ECParameterSpec;
-
-@TestTargetClass(ECKey.class)
-public class ECKeyTest extends TestCase {
-
- /**
- * @tests java.security.interfaces.ECKey
- * #getParams()
- * test covers following use cases
- * Case 1: check private key
- * Case 2: check public key
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getParams",
- args = {}
- )
- @AndroidOnly("EC is not supported for android. " +
- "EC is not define in RI.")
- public void test_getParams() throws Exception {
- KeyPairGenerator gen = KeyPairGenerator.getInstance("EC", Util.prov);
- gen.initialize(Util.ecParam);
- ECKey key = null;
-
- // Case 1: check private key
- key = (ECKey) gen.generateKeyPair().getPrivate();
- assertECParameterSpecEquals(Util.ecParam, key.getParams());
-
- // Case 2: check public key
- key = (ECKey) gen.generateKeyPair().getPublic();
- assertECParameterSpecEquals(Util.ecParam, key.getParams());
- }
-
- private void assertECParameterSpecEquals(ECParameterSpec expected, ECParameterSpec actual) {
- assertEquals("cofactors don't match", expected.getCofactor(), actual.getCofactor());
- assertEquals("curves don't match", expected.getCurve(), actual.getCurve());
- assertEquals("generator don't match", expected.getGenerator(), actual.getGenerator());
- assertEquals("order don't match", expected.getOrder(), actual.getOrder());
-
- }
-}
diff --git a/libcore/security/src/test/java/tests/security/interfaces/ECPrivateKeyTest.java b/libcore/security/src/test/java/tests/security/interfaces/ECPrivateKeyTest.java
deleted file mode 100644
index 79acdb7..0000000
--- a/libcore/security/src/test/java/tests/security/interfaces/ECPrivateKeyTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.security.interfaces;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.AndroidOnly;
-
-import junit.framework.TestCase;
-
-import java.security.KeyPairGenerator;
-import java.security.SecureRandom;
-import java.security.interfaces.ECPrivateKey;
-
-@TestTargetClass(ECPrivateKey.class)
-public class ECPrivateKeyTest extends TestCase {
-
- /**
- * @tests java.security.interfaces.ECPrivateKey
- * #getS()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getS",
- args = {}
- )
- @SuppressWarnings("serial")
- @AndroidOnly("EC is not supported for android. " +
- "EC is not define in RI.")
- public void test_getS() throws Exception {
- KeyPairGenerator gen = KeyPairGenerator.getInstance("EC", Util.prov);
- gen.initialize(Util.ecParam, new SecureRandom(new MySecureRandomSpi(),
- null) {
- });
- ECPrivateKey key = (ECPrivateKey) gen.generateKeyPair().getPrivate();
- assertEquals("Invalid S", Util.RND_RET, key.getS());
- }
-
-}
diff --git a/libcore/security/src/test/java/tests/security/interfaces/ECPublicKeyTest.java b/libcore/security/src/test/java/tests/security/interfaces/ECPublicKeyTest.java
deleted file mode 100644
index 0c497ec..0000000
--- a/libcore/security/src/test/java/tests/security/interfaces/ECPublicKeyTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package tests.security.interfaces;
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
-import java.math.BigInteger;
-import java.security.KeyPairGenerator;
-import java.security.SecureRandom;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECPoint;
-
-@TestTargetClass(ECPublicKey.class)
-public class ECPublicKeyTest extends TestCase {
-
- /**
- * @tests java.security.interfaces.ECPublicKey
- * #getW()
- */
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "getW",
- args = {}
- )
- @SuppressWarnings("serial")
- @AndroidOnly("EC is not supported for android. " +
- "EC is not define in RI.")
- public void test_getW() throws Exception {
- KeyPairGenerator gen = KeyPairGenerator.getInstance("EC", Util.prov);
- gen.initialize(Util.ecParam, new SecureRandom(new MySecureRandomSpi(),
- null) {
- });
- ECPublicKey key = (ECPublicKey) gen.generateKeyPair().getPublic();
- assertECPointEquals(new ECPoint(BigInteger.valueOf(4),
- BigInteger.valueOf(15)), key.getW());
- }
-
- private void assertECPointEquals(ECPoint expected, ECPoint actual) {
- assertEquals("X coordiates are different", expected.getAffineX(),
- actual.getAffineX());
- assertEquals("Y coordiates are different", expected.getAffineY(),
- actual.getAffineY());
- }
-}
diff --git a/libcore/security/src/test/java/tests/security/interfaces/RSAKeyTest.java b/libcore/security/src/test/java/tests/security/interfaces/RSAKeyTest.java
index 87804b0..dad13db 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/RSAKeyTest.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/RSAKeyTest.java
@@ -14,7 +14,6 @@
* limitations under the License.
*/
package tests.security.interfaces;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -44,7 +43,7 @@
args = {}
)
public void test_getModulus() throws Exception {
- KeyFactory gen = KeyFactory.getInstance("RSA", Util.prov);
+ KeyFactory gen = KeyFactory.getInstance("RSA");
final BigInteger n = BigInteger.valueOf(3233);
final BigInteger d = BigInteger.valueOf(2753);
final BigInteger e = BigInteger.valueOf(17);
diff --git a/libcore/security/src/test/java/tests/security/interfaces/RSAPrivateCrtKeyTest.java b/libcore/security/src/test/java/tests/security/interfaces/RSAPrivateCrtKeyTest.java
index 7549852..fb79721 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/RSAPrivateCrtKeyTest.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/RSAPrivateCrtKeyTest.java
@@ -14,7 +14,6 @@
* limitations under the License.
*/
package tests.security.interfaces;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -31,7 +30,7 @@
protected void setUp() throws Exception {
super.setUp();
- KeyFactory gen = KeyFactory.getInstance("RSA", Util.prov);
+ KeyFactory gen = KeyFactory.getInstance("RSA");
key = (RSAPrivateCrtKey) gen.generatePrivate(Util.rsaCrtParam);
}
diff --git a/libcore/security/src/test/java/tests/security/interfaces/RSAPrivateKeyTest.java b/libcore/security/src/test/java/tests/security/interfaces/RSAPrivateKeyTest.java
index e911be7..4e7d616 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/RSAPrivateKeyTest.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/RSAPrivateKeyTest.java
@@ -14,7 +14,6 @@
* limitations under the License.
*/
package tests.security.interfaces;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -40,7 +39,7 @@
args = {}
)
public void test_getPrivateExponent() throws Exception {
- KeyFactory gen = KeyFactory.getInstance("RSA", Util.prov);
+ KeyFactory gen = KeyFactory.getInstance("RSA");
final BigInteger n = BigInteger.valueOf(3233);
final BigInteger d = BigInteger.valueOf(2753);
RSAPrivateKey key = (RSAPrivateKey) gen.generatePrivate(new RSAPrivateKeySpec(
diff --git a/libcore/security/src/test/java/tests/security/interfaces/RSAPublicKeyTest.java b/libcore/security/src/test/java/tests/security/interfaces/RSAPublicKeyTest.java
index c7018a6..83fbeb2 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/RSAPublicKeyTest.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/RSAPublicKeyTest.java
@@ -14,7 +14,6 @@
* limitations under the License.
*/
package tests.security.interfaces;
-import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
@@ -40,7 +39,7 @@
args = {}
)
public void test_getPublicExponent() throws Exception {
- KeyFactory gen = KeyFactory.getInstance("RSA", Util.prov);
+ KeyFactory gen = KeyFactory.getInstance("RSA");
final BigInteger n = BigInteger.valueOf(3233);
final BigInteger e = BigInteger.valueOf(17);
RSAPublicKey key = (RSAPublicKey) gen.generatePublic(new RSAPublicKeySpec(
diff --git a/libcore/security/src/test/java/tests/security/interfaces/Util.java b/libcore/security/src/test/java/tests/security/interfaces/Util.java
index c1f3bb7..61143a0 100644
--- a/libcore/security/src/test/java/tests/security/interfaces/Util.java
+++ b/libcore/security/src/test/java/tests/security/interfaces/Util.java
@@ -15,7 +15,6 @@
*/
package tests.security.interfaces;
import java.math.BigInteger;
-import java.security.Provider;
import java.security.SecureRandomSpi;
import java.security.spec.ECFieldFp;
import java.security.spec.ECParameterSpec;
@@ -29,11 +28,6 @@
class Util {
/**
- * BouncyCastle provider
- */
- static final Provider prov = new org.bouncycastle.jce.provider.BouncyCastleProvider();
-
- /**
* Valid P for DSA tests
*/
static final BigInteger P = new BigInteger(
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaIoFileInputStreamTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaIoFileInputStreamTest.java
index 2aa63e2..36ad29e 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaIoFileInputStreamTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaIoFileInputStreamTest.java
@@ -27,6 +27,7 @@
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
+import java.security.Permission;
/*
* This class tests the security permissions which are documented in
@@ -91,6 +92,10 @@
this.file = file;
super.checkRead(file);
}
+ @Override
+ public void checkPermission(Permission p) {
+
+ }
}
long id = new java.util.Date().getTime();
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaIoFileOutputStreamTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaIoFileOutputStreamTest.java
index 0974ef5..78f248d 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaIoFileOutputStreamTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaIoFileOutputStreamTest.java
@@ -27,6 +27,7 @@
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.security.Permission;
/*
* This class tests the security permissions which are documented in
@@ -103,6 +104,10 @@
this.file = file;
super.checkWrite(file);
}
+ @Override
+ public void checkPermission(Permission p) {
+
+ }
}
long id = new java.util.Date().getTime();
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaIoObjectInputStreamTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaIoObjectInputStreamTest.java
index 27ef0c1..1fb873f 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaIoObjectInputStreamTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaIoObjectInputStreamTest.java
@@ -85,7 +85,6 @@
called = true;
this.permission = permission;
}
- super.checkPermission(permission);
}
}
@@ -145,7 +144,6 @@
called = true;
this.permission = permission;
}
- super.checkPermission(permission);
}
}
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaIoObjectOutputStreamTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaIoObjectOutputStreamTest.java
index 5e98b59..0de39df 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaIoObjectOutputStreamTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaIoObjectOutputStreamTest.java
@@ -72,7 +72,6 @@
called = true;
this.permission = permission;
}
- super.checkPermission(permission);
}
}
@@ -124,7 +123,6 @@
called = true;
this.permission = permission;
}
- super.checkPermission(permission);
}
}
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaIoRandomAccessFileTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaIoRandomAccessFileTest.java
index 7cb875f..8201e32 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaIoRandomAccessFileTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaIoRandomAccessFileTest.java
@@ -26,6 +26,7 @@
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
+import java.security.Permission;
/*
* This class tests the security permissions which are documented in
* http://java.sun.com/j2se/1.5.0/docs/guide/security/permissions.html#PermsAndMethods
@@ -76,6 +77,10 @@
this.file = file;
super.checkRead(file);
}
+ @Override
+ public void checkPermission(Permission p) {
+
+ }
}
long id = new java.util.Date().getTime();
@@ -130,6 +135,10 @@
this.checkWriteFile = file;
super.checkWrite(file);
}
+ @Override
+ public void checkPermission(Permission p) {
+
+ }
}
long id = new java.util.Date().getTime();
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaLangClassLoaderTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaLangClassLoaderTest.java
index 12016e8..cd8640b 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaLangClassLoaderTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaLangClassLoaderTest.java
@@ -16,7 +16,7 @@
package tests.security.permissions;
-import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -71,7 +71,10 @@
@Override
public void checkCreateClassLoader(){
called = true;
- super.checkCreateClassLoader();
+ }
+ @Override
+ public void checkPermission(Permission p) {
+
}
}
@@ -102,12 +105,12 @@
),
@TestTargetNew(
level = TestLevel.PARTIAL,
- notes = "Verifies that ClassLoader.getSystemClassLoader() calls checkPermission on security manager.",
+ notes = "Verifies that ClassLoader.getParent() calls checkPermission on security manager.",
method = "getParent",
args = {}
)
})
- @AndroidOnly("test must be executed with a new PathClassLoader")
+ @BrokenTest("RI and Android don't pass this test. Also this test must be executed with a new PathClassLoader")
public void test_getSystemClassLoader () {
class TestSecurityManager extends SecurityManager {
boolean called;
@@ -119,7 +122,6 @@
if(permission instanceof RuntimePermission && "getClassLoader".equals(permission.getName())){
called = true;
}
- super.checkPermission(permission);
}
}
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaLangClassTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaLangClassTest.java
index 18277a0..f666d44 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaLangClassTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaLangClassTest.java
@@ -19,8 +19,6 @@
import java.security.Permission;
import junit.framework.TestCase;
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -54,8 +52,6 @@
method = "getProtectionDomain",
args = {}
)
- @KnownFailure("Fails because the default security manager allows " +
- "everything. Remove this when it is more restrictive.")
public void test_getProtectionDomain () {
class TestSecurityManager extends SecurityManager {
boolean called;
@@ -66,7 +62,6 @@
public void checkPermission(Permission permission){
if(permission instanceof RuntimePermission && "getProtectionDomain".equals(permission.getName())){
called = true;
- super.checkPermission(permission);
}
}
}
@@ -78,12 +73,7 @@
System.setSecurityManager(s);
s.reset();
- try {
- c.getProtectionDomain();
- fail("Test 1: SecurityException expected.");
- } catch (SecurityException e) {
- // Expected.
- }
+ c.getProtectionDomain();
assertTrue("Test 2: Class.getProtectionDomain() must check " +
"RuntimePermission(\"getProtectionDomain\") on " +
"security manager", s.called);
@@ -95,11 +85,6 @@
method = "forName",
args = {String.class, boolean.class, ClassLoader.class}
)
- @AndroidOnly("")
- // TODO it is not clear under which conditions the security manager is inspected
- // Should only be checked if the calling class loader is not null.
- @KnownFailure("Fails because the default security manager allows " +
- "everything. Remove this when it is more restrictive.")
public void test_forName() throws ClassNotFoundException {
class TestSecurityManager extends SecurityManager {
boolean called;
@@ -110,7 +95,6 @@
public void checkPermission(Permission permission){
if (permission instanceof RuntimePermission && "getClassLoader".equals(permission.getName())){
called = true;
- super.checkPermission(permission);
}
}
}
@@ -119,27 +103,9 @@
System.setSecurityManager(s);
s.reset();
- try {
- Class.forName("java.lang.String", true, null);
- fail("Test 1: Security exception expected.");
- } catch (SecurityException e) {
- // Expected.
- }
+ Class.forName("java.lang.String", true, null);
assertTrue("Test 2: Class.forName(String,boolean,Classloader) must " +
"check RuntimePermission(getClassLoader) on security manager",
s.called);
}
-
- /*
- @TestTargetNew(
- level = TestLevel.TODO,
- notes = "this test is only here as otherwise all tests in this class " +
- "would be underscored which would give an error upon" +
- "invokation of the tests.",
- method = "forName",
- args = {String.class, boolean.class, ClassLoader.class}
- )
- public void test_dummy() throws ClassNotFoundException {}
- */
-
}
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaLangReflectAccessibleObjectTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaLangReflectAccessibleObjectTest.java
index 6831467..a618546 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaLangReflectAccessibleObjectTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaLangReflectAccessibleObjectTest.java
@@ -55,7 +55,6 @@
&& "suppressAccessChecks".equals(permission.getName())) {
called = true;
}
- super.checkPermission(permission);
}
}
@@ -87,9 +86,7 @@
&& "suppressAccessChecks".equals(permission.getName())) {
called = true;
}
- super.checkPermission(permission);
}
-
}
TestSecurityManager s = new TestSecurityManager();
System.setSecurityManager(s);
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaLangRuntimeTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaLangRuntimeTest.java
index 519660a..c78f6cc 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaLangRuntimeTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaLangRuntimeTest.java
@@ -16,7 +16,6 @@
package tests.security.permissions;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -78,17 +77,18 @@
class TestSecurityManager extends SecurityManager {
boolean called;
String cmd;
-
void reset(){
called = false;
cmd = null;
}
-
@Override
public void checkExec(String cmd) {
called = true;
this.cmd = cmd;
- super.checkExec(cmd);
+ }
+ @Override
+ public void checkPermission(Permission p) {
+
}
}
@@ -133,7 +133,6 @@
args = {java.lang.Thread.class}
)
})
- @KnownFailure("ToT fixed.")
public void test_shutdownHook() {
class TestSecurityManager extends SecurityManager {
boolean called;
@@ -148,7 +147,6 @@
called = true;
this.permission = permission;
}
- super.checkPermission(permission);
}
}
@@ -189,6 +187,10 @@
this.status = status;
throw new ExitNotAllowedException(); // prevent that the system is shut down
}
+ @Override
+ public void checkPermission(Permission p) {
+
+ }
}
TestSecurityManager s = new TestSecurityManager();
@@ -212,7 +214,6 @@
method = "runFinalizersOnExit",
args = {boolean.class}
)
- @KnownFailure("ToT fixed.")
public void test_runFinalizersOnExit() {
class TestSecurityManager extends SecurityManager {
boolean called;
@@ -225,7 +226,10 @@
public void checkExit(int status){
this.called = true;
this.status = status;
- super.checkExit(status);
+ }
+ @Override
+ public void checkPermission(Permission p) {
+
}
}
@@ -268,7 +272,10 @@
if(library.equals(lib)){
throw new CheckLinkCalledException();
}
- super.checkLink(lib);
+ }
+ @Override
+ public void checkPermission(Permission p) {
+
}
}
@@ -299,6 +306,3 @@
}
}
-
-
-
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaLangSystemTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaLangSystemTest.java
index 02f1031..d1bf7c2 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaLangSystemTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaLangSystemTest.java
@@ -16,7 +16,6 @@
package tests.security.permissions;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -76,7 +75,11 @@
@Override
public void checkPropertiesAccess() {
called = true;
- super.checkPropertiesAccess();
+ }
+
+ @Override
+ public void checkPermission(Permission p) {
+ // nothing to do
}
}
@@ -120,7 +123,11 @@
public void checkPropertyAccess(String key) {
called = true;
this.key = key;
- super.checkPropertyAccess(key);
+ }
+
+ @Override
+ public void checkPermission(Permission p) {
+ // nothing to do
}
}
@@ -158,7 +165,6 @@
public void checkPermission(Permission p) {
called = true;
this.p = p;
- super.checkPermission(p);
}
}
@@ -185,7 +191,6 @@
if(permission instanceof RuntimePermission && "setSecurityManager".equals(permission.getName())){
called = true;
}
- super.checkPermission(permission);
}
}
@@ -220,7 +225,6 @@
args = {java.io.PrintStream.class}
)
})
- @KnownFailure("ToT fixed.")
public void test_setInOutErr() {
class TestSecurityManager extends SecurityManager {
boolean called;
@@ -235,7 +239,6 @@
public void checkPermission(Permission p) {
called = true;
this.p = p;
- super.checkPermission(p);
}
}
@@ -282,6 +285,11 @@
this.status = status;
throw new ExitNotAllowedException(); // prevent that the system is shut down
}
+
+ @Override
+ public void checkPermission(Permission p) {
+ // nothing to do
+ }
}
TestSecurityManager s = new TestSecurityManager();
@@ -305,7 +313,6 @@
method = "runFinalizersOnExit",
args = {boolean.class}
)
- @KnownFailure("ToT fixed.")
public void test_runFinalizersOnExit() {
class TestSecurityManager extends SecurityManager {
boolean called;
@@ -318,7 +325,11 @@
public void checkExit(int status){
this.called = true;
this.status = status;
- super.checkExit(status);
+ }
+
+ @Override
+ public void checkPermission(Permission p) {
+ // nothing to do
}
}
@@ -339,18 +350,17 @@
@TestTargets({
@TestTargetNew(
level = TestLevel.PARTIAL,
- notes = "Verifies that methods load and loadLibrary call checkLink on security manager., loadlibrary needs to be fixed, see ticket #58",
+ notes = "Verifies that methods load and loadLibrary call checkLink on security manager.",
method = "load",
args = {java.lang.String.class}
),
@TestTargetNew(
level = TestLevel.PARTIAL,
- notes = "Verifies that methods load and loadLibrary call checkLink on security manager., loadlibrary needs to be fixed, see ticket #58",
+ notes = "Verifies that methods load and loadLibrary call checkLink on security manager.",
method = "loadLibrary",
args = {java.lang.String.class}
)
})
- @KnownFailure("ToT fixed.")
public void test_load() {
final String library = "library";
@@ -364,6 +374,11 @@
}
super.checkLink(lib);
}
+
+ @Override
+ public void checkPermission(Permission p) {
+ // nothing to do
+ }
}
TestSecurityManager s = new TestSecurityManager();
@@ -371,26 +386,25 @@
try {
System.load(library);
- fail("System.load must call checkLink on security manager with argument "+library);
+ fail("System.load must call checkLink on security manager with argument \"" + library + "\"");
}
catch(CheckLinkCalledException e){
// ok
}
catch(Throwable t){
- fail("System.load must call checkLink on security manager with argument "+library);
+ fail("System.load must call checkLink on security manager with argument \"" + library + "\"");
}
try {
System.loadLibrary(library);
- fail("System.load must call checkLink on security manager with argument "+library);
+ fail("System.loadLibrary must call checkLink on security manager with argument \"" + library + "\"");
}
catch(CheckLinkCalledException e){
// ok
}
catch(Throwable t){
- fail("System.load must call checkLink on security manager with argument "+library);
+ fail("System.loadLibrary must call checkLink on security manager with argument \"" + library + "\"");
}
}
}
-
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaLangThreadTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaLangThreadTest.java
index 1dd2e13..2c9af67 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaLangThreadTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaLangThreadTest.java
@@ -16,7 +16,7 @@
package tests.security.permissions;
-import dalvik.annotation.KnownFailure;
+import dalvik.annotation.AndroidOnly;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -67,7 +67,6 @@
public void checkPermission(Permission p) {
called = true;
this.p = p;
- super.checkPermission(p);
}
}
@@ -94,6 +93,7 @@
method = "enumerate",
args = {java.lang.Thread[].class}
)
+ @AndroidOnly("RI impl differs from RI spec, Android impl does not.")
public void test_enumerate() {
class TestSecurityManager extends SecurityManager {
boolean called;
@@ -108,7 +108,11 @@
public void checkAccess(Thread t) {
called = true;
this.t = t;
- super.checkAccess(t);
+ }
+
+ @Override
+ public void checkPermission(Permission p) {
+
}
}
@@ -132,14 +136,12 @@
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Verifies that getContextClassLoader calls checkPermission " +
- "on security manager.Needs fixes in methods " +
- "Thread.getContextClassLoader and ClassLoader.isAncestorOf, " +
- "see ticket #101",
+ "on security manager.",
method = "getContextClassLoader",
args = {}
)
- @KnownFailure("ToT fixed.")
- public void testGetContextClassLoader() {
+ @AndroidOnly("RI impl differs from RI spec, Android impl does not.")
+ public void test_getContextClassLoader() {
class TestSecurityManager extends SecurityManager {
boolean called;
@@ -153,7 +155,6 @@
&& "getClassLoader".equals(p.getName())) {
called = true;
}
- super.checkPermission(p);
}
}
TestSecurityManager sm = new TestSecurityManager();
@@ -210,5 +211,4 @@
"caller's class loader is parent of requested class loader",
sm.called);
}
-
}
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaNetDatagramSocketTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaNetDatagramSocketTest.java
index 29726c9..714c523 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaNetDatagramSocketTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaNetDatagramSocketTest.java
@@ -30,8 +30,7 @@
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.net.SocketTimeoutException;
+import java.security.Permission;
/*
* This class tests the security permissions which are documented in
@@ -78,18 +77,19 @@
public void test_ctor() throws IOException {
class TestSecurityManager extends SecurityManager {
boolean called = false;
- String host = null;
int port = 0;
void reset(){
called = false;
- host = null;
port = 0;
}
@Override
public void checkListen(int port) {
called = true;
this.port = port;
- super.checkListen(port);
+ }
+ @Override
+ public void checkPermission(Permission p) {
+
}
}
@@ -131,20 +131,18 @@
public void test_receive() throws IOException {
class TestSecurityManager extends SecurityManager {
boolean called = false;
- String host = null;
- int port = 0;
void reset(){
called = false;
- host = null;
- port = 0;
}
@Override
public void checkAccept(String host, int port) {
- this.host = host;
- this.port = port;
this.called = true;
super.checkAccept(host, port);
}
+ @Override
+ public void checkPermission(Permission p) {
+
+ }
}
final int port = Support_PortManager.getNextPortForUDP();
@@ -177,12 +175,10 @@
System.setSecurityManager(s);
s.reset();
- assert(s1.getInetAddress()==null);
assertTrue(s1.getInetAddress()==null);
try {
s1.receive(p);
- }
- catch(Exception e){
+ } catch(Exception e) {
fail("unexpected exception " + e);
}
sender.interrupt();
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaNetMulticastSocketTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaNetMulticastSocketTest.java
index f970345..f48e5d3 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaNetMulticastSocketTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaNetMulticastSocketTest.java
@@ -29,6 +29,7 @@
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.SocketAddress;
+import java.security.Permission;
/*
* This class tests the secrity permissions which are documented in
@@ -86,6 +87,10 @@
this.port = port;
super.checkListen(port);
}
+ @Override
+ public void checkPermission(Permission permission) {
+
+ }
}
TestSecurityManager s = new TestSecurityManager();
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaNetServerSocketTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaNetServerSocketTest.java
index ff439bd..f26becc 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaNetServerSocketTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaNetServerSocketTest.java
@@ -27,7 +27,7 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
-import java.net.SocketAddress;
+import java.security.Permission;
/*
* This class tests the security permissions which are documented in
* http://java.sun.com/j2se/1.5.0/docs/guide/security/permissions.html#PermsAndMethods
@@ -88,7 +88,10 @@
public void checkListen(int port) {
called = true;
this.port = port;
- super.checkListen(port);
+ }
+ @Override
+ public void checkPermission(Permission permission) {
+
}
}
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaNetSocketTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaNetSocketTest.java
index fac1206..3933064 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaNetSocketTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaNetSocketTest.java
@@ -16,6 +16,7 @@
package tests.security.permissions;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -26,6 +27,8 @@
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.Permission;
/*
* This class tests the security permissions which are documented in
* http://java.sun.com/j2se/1.5.0/docs/guide/security/permissions.html#PermsAndMethods
@@ -101,12 +104,16 @@
this.called = true;
this.port = port;
this.host = host;
- super.checkConnect(host, port);
+ }
+ @Override
+ public void checkPermission(Permission permission) {
+
}
}
String host = "www.google.ch";
int port = 80;
+ String hostAddress = InetAddress.getByName(host).getHostAddress();
TestSecurityManager s = new TestSecurityManager();
System.setSecurityManager(s);
@@ -114,40 +121,80 @@
s.reset();
new Socket(host, port);
assertTrue("java.net.ServerSocket ctor must call checkConnect on security permissions", s.called);
- assertEquals("Argument of checkConnect is not correct", host, s.host);
+ assertEquals("Argument of checkConnect is not correct", hostAddress, s.host);
assertEquals("Argument of checkConnect is not correct", port, s.port);
s.reset();
new Socket(host, port, true);
assertTrue("java.net.ServerSocket ctor must call checkConnect on security permissions", s.called);
- assertEquals("Argument of checkConnect is not correct", host, s.host);
+ assertEquals("Argument of checkConnect is not correct", hostAddress, s.host);
assertEquals("Argument of checkConnect is not correct", port, s.port);
-// TODO returns error message "the socket level is invalid", see ticket 66
-// s.reset();
-// new Socket(host, port, InetAddress.getLocalHost(), 0);
-// assertTrue("java.net.ServerSocket ctor must call checkConnect on security permissions", s.called);
-// assertEquals("Argument of checkConnect is not correct", host, s.host);
-// assertEquals("Argument of checkConnect is not correct", port, s.port);
+ s.reset();
+ new Socket(host, port, InetAddress.getByAddress(new byte[] {0,0,0,0}), 0);
+ assertTrue("java.net.ServerSocket ctor must call checkConnect on security permissions", s.called);
+ assertEquals("Argument of checkConnect is not correct", hostAddress, s.host);
+ assertEquals("Argument of checkConnect is not correct", port, s.port);
s.reset();
new Socket(InetAddress.getByName(host), port);
assertTrue("java.net.ServerSocket ctor must call checkConnect on security permissions", s.called);
- assertEquals("Argument of checkConnect is not correct", host, s.host);
+ assertEquals("Argument of checkConnect is not correct", hostAddress, s.host);
assertEquals("Argument of checkConnect is not correct", port, s.port);
s.reset();
new Socket(InetAddress.getByName(host), port, true);
assertTrue("java.net.ServerSocket ctor must call checkConnect on security permissions", s.called);
- assertEquals("Argument of checkConnect is not correct", host, s.host);
+ assertEquals("Argument of checkConnect is not correct", hostAddress, s.host);
assertEquals("Argument of checkConnect is not correct", port, s.port);
-// TODO returns error message "the socket level is invalid", see ticket 66
-// s.reset();
-// new Socket(InetAddress.getByName(host), port, InetAddress.getLocalHost(), 0);
-// assertTrue("java.net.ServerSocket ctor must call checkConnect on security permissions", s.called);
-// assertEquals("Argument of checkConnect is not correct", host, s.host);
-// assertEquals("Argument of checkConnect is not correct", port, s.port);
+ s.reset();
+ new Socket(InetAddress.getByName(host), port, InetAddress.getByAddress(new byte[] {0,0,0,0}), 0);
+ assertTrue("java.net.ServerSocket ctor must call checkConnect on security permissions", s.called);
+ assertEquals("Argument of checkConnect is not correct", hostAddress, s.host);
+ assertEquals("Argument of checkConnect is not correct", port, s.port);
}
-
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "",
+ method = "Socket",
+ args = {java.net.InetAddress.class, int.class, java.net.InetAddress.class, int.class}
+ )
+ @KnownFailure("throws SocketException with message: the socket level is invalid. Works on the RI")
+ public void test_ctor2() throws IOException {
+ class TestSecurityManager extends SecurityManager {
+ boolean called = false;
+ String host = null;
+ int port = -1;
+ void reset(){
+ called = false;
+ host = null;
+ port = -1;
+ }
+ @Override
+ public void checkConnect(String host, int port) {
+ this.called = true;
+ this.port = port;
+ this.host = host;
+ }
+ @Override
+ public void checkPermission(Permission permission) {
+
+ }
+ }
+
+ String host = "www.google.ch";
+ int port = 80;
+ String hostAddress = InetAddress.getByName(host).getHostAddress();
+
+ TestSecurityManager s = new TestSecurityManager();
+ System.setSecurityManager(s);
+
+ s.reset();
+ new Socket(InetAddress.getByName(host), port, InetAddress.getLocalHost(), 0);
+ assertTrue("java.net.ServerSocket ctor must call checkConnect on security permissions", s.called);
+ assertEquals("Argument of checkConnect is not correct", hostAddress, s.host);
+ assertEquals("Argument of checkConnect is not correct", port, s.port);
+ }
}
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaSecurityPolicyTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaSecurityPolicyTest.java
index c779b2e..c07940e 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaSecurityPolicyTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaSecurityPolicyTest.java
@@ -65,7 +65,6 @@
if(permission instanceof SecurityPermission && "getPolicy".equals(permission.getName())){
called = true;
}
- super.checkPermission(permission);
}
}
TestSecurityManager s = new TestSecurityManager();
@@ -93,7 +92,6 @@
if(permission instanceof SecurityPermission && "setPolicy".equals(permission.getName())){
called = true;
}
- super.checkPermission(permission);
}
}
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaSecuritySecurityTest.java b/libcore/security/src/test/java/tests/security/permissions/JavaSecuritySecurityTest.java
index 8b2d713..e84c976 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaSecuritySecurityTest.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaSecuritySecurityTest.java
@@ -16,7 +16,6 @@
package tests.security.permissions;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -73,9 +72,7 @@
target = permission.getName();
if (target.equals("getProperty.key")) {
called = true;
- return;
}
- super.checkPermission(permission);
}
}
@@ -89,46 +86,6 @@
assertEquals("Argument of checkSecurityAccess is not correct", "getProperty.key", s.target);
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
- method = "getProperty",
- args = {String.class}
- ),
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "",
- method = "setProperty",
- args = {String.class, String.class}
- )
- })
- @KnownFailure("As long as ProtectionDomains are not implemeneted the default implementation of SecurityManager will allow everything.")
- public void test_getProperty_setProperty_SecurityException() {
- System.setSecurityManager(new SecurityManager() {
- @Override
- public void checkPermission(Permission permission) {
- if (permission instanceof SecurityPermission) {
- super.checkPermission(permission);
- }
- }
- });
-
- try {
- Security.getProperty("anotherKey");
- fail("expected SecurityException");
- } catch (SecurityException e) {
- // ok
- }
-
- try {
- Security.setProperty("anotherKey", "anotherValue");
- fail("expected SecurityException");
- } catch (SecurityException e) {
- // ok
- }
- }
-
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
notes = "Verifies that setProperty() method calls checkSecurityAccess on security manager.",
@@ -150,9 +107,7 @@
target = permission.getName();
if (target.equals("setProperty.key")) {
called = true;
- return;
}
- super.checkPermission(permission);
}
}
}
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaUtilZipZipFile.java b/libcore/security/src/test/java/tests/security/permissions/JavaUtilZipZipFile.java
index 36b30ff..f8cb026 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaUtilZipZipFile.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaUtilZipZipFile.java
@@ -24,6 +24,7 @@
import junit.framework.TestCase;
import java.io.IOException;
+import java.io.File;
import java.util.zip.ZipFile;
/*
* This class tests the security permissions which are documented in
@@ -70,7 +71,8 @@
}
}
- String filename = "foo.zip";
+ File file = File.createTempFile("foo", "zip");
+ String filename = file.getAbsolutePath();
TestSecurityManager s = new TestSecurityManager();
System.setSecurityManager(s);
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaxSecurityAuthSubject.java b/libcore/security/src/test/java/tests/security/permissions/JavaxSecurityAuthSubject.java
index 289df0f..46f52c6 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaxSecurityAuthSubject.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaxSecurityAuthSubject.java
@@ -23,7 +23,7 @@
import junit.framework.TestCase;
-import org.apache.harmony.security.tests.support.acl.PrincipalImpl;
+//import org.apache.harmony.security.tests.support.acl.PrincipalImpl;
import java.security.AccessControlContext;
import java.security.KeyFactory;
@@ -95,7 +95,6 @@
&& "getSubject".equals(permission.getName())) {
called = true;
}
- super.checkPermission(permission);
}
}
@@ -140,7 +139,6 @@
&& "setReadOnly".equals(permission.getName())) {
called = true;
}
- super.checkPermission(permission);
}
}
@@ -186,7 +184,6 @@
&& "doAs".equals(permission.getName())) {
called = true;
}
- super.checkPermission(permission);
}
}
@@ -223,13 +220,13 @@
@TestTargets({
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "Exception checking missing",
method = "doAs",
args = {javax.security.auth.Subject.class, java.security.PrivilegedAction.class}
),
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "Exception checking missing",
method = "doAs",
args = {javax.security.auth.Subject.class, java.security.PrivilegedExceptionAction.class}
@@ -267,7 +264,6 @@
&& "doAsPrivileged".equals(permission.getName())) {
called = true;
}
- super.checkPermission(permission);
}
}
@@ -304,13 +300,13 @@
@TestTargets({
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "doAsPrivileged",
args = {javax.security.auth.Subject.class, java.security.PrivilegedAction.class, java.security.AccessControlContext.class}
),
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "doAsPrivileged",
args = {javax.security.auth.Subject.class, java.security.PrivilegedExceptionAction.class, java.security.AccessControlContext.class}
@@ -322,13 +318,13 @@
@TestTargets({
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "isReadOnly",
args = {}
),
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "setReadOnly",
args = {}
@@ -339,7 +335,7 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "getPrincipals",
args = {}
@@ -349,7 +345,7 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "getPrincipals",
args = {java.lang.Class.class}
@@ -359,7 +355,7 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "getPrivateCredentials",
args = {}
@@ -369,7 +365,7 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "getPrivateCredentials",
args = {java.lang.Class.class}
@@ -379,7 +375,7 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "getPublicCredentials",
args = {}
@@ -389,7 +385,7 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "getPublicCredentials",
args = {java.lang.Class.class}
@@ -399,7 +395,7 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "getSubject",
args = {java.security.AccessControlContext.class}
@@ -409,7 +405,7 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "hashCode",
args = {}
@@ -419,7 +415,7 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "",
method = "equals",
args = {java.lang.Object.class}
@@ -442,7 +438,7 @@
}
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.TODO,
notes = "test only started please continue. Throws exception InvalidKeySpecException line 455",
method = "Subject",
args = {boolean.class, java.util.Set.class, java.util.Set.class, java.util.Set.class}
diff --git a/libcore/security/src/test/java/tests/security/permissions/JavaxSecurityAuthSubjectDomainCombiner.java b/libcore/security/src/test/java/tests/security/permissions/JavaxSecurityAuthSubjectDomainCombiner.java
index f1f5bb0..8204aa2 100644
--- a/libcore/security/src/test/java/tests/security/permissions/JavaxSecurityAuthSubjectDomainCombiner.java
+++ b/libcore/security/src/test/java/tests/security/permissions/JavaxSecurityAuthSubjectDomainCombiner.java
@@ -72,7 +72,6 @@
&& "getSubjectFromDomainCombiner".equals(permission.getName())) {
called = true;
}
- super.checkPermission(permission);
}
}
diff --git a/libcore/security/src/test/java/tests/security/spec/DSAParameterSpecTest.java b/libcore/security/src/test/java/tests/security/spec/DSAParameterSpecTest.java
index 6a5e43e..42fce7b 100644
--- a/libcore/security/src/test/java/tests/security/spec/DSAParameterSpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/DSAParameterSpecTest.java
@@ -41,14 +41,6 @@
public class DSAParameterSpecTest extends TestCase {
/**
- * Constructor for DSAParameterSpecTest.
- * @param name
- */
- public DSAParameterSpecTest(String name) {
- super(name);
- }
-
- /**
* Ctor test
*/
@TestTargetNew(
diff --git a/libcore/security/src/test/java/tests/security/spec/DSAPrivateKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/DSAPrivateKeySpecTest.java
index b372b9d..f01e957 100644
--- a/libcore/security/src/test/java/tests/security/spec/DSAPrivateKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/DSAPrivateKeySpecTest.java
@@ -41,14 +41,6 @@
public class DSAPrivateKeySpecTest extends TestCase {
/**
- * Constructor for DSAPrivateKeySpecTest.
- * @param name
- */
- public DSAPrivateKeySpecTest(String name) {
- super(name);
- }
-
- /**
* Test for constructor
*/
@TestTargetNew(
diff --git a/libcore/security/src/test/java/tests/security/spec/DSAPublicKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/DSAPublicKeySpecTest.java
index 872568b..6133836 100644
--- a/libcore/security/src/test/java/tests/security/spec/DSAPublicKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/DSAPublicKeySpecTest.java
@@ -41,14 +41,6 @@
public class DSAPublicKeySpecTest extends TestCase {
/**
- * Constructor for DSAPublicKeySpecTest.
- * @param name
- */
- public DSAPublicKeySpecTest(String name) {
- super(name);
- }
-
- /**
* Test for <code>DSAPublicKeySpec</code> ctor
*/
@TestTargetNew(
diff --git a/libcore/security/src/test/java/tests/security/spec/ECFieldF2mTest.java b/libcore/security/src/test/java/tests/security/spec/ECFieldF2mTest.java
index 5681286..f731eaa 100644
--- a/libcore/security/src/test/java/tests/security/spec/ECFieldF2mTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/ECFieldF2mTest.java
@@ -104,14 +104,6 @@
}
}
- /**
- * Constructor for ECFieldF2mTest.
- * @param name
- */
- public ECFieldF2mTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/spec/ECFieldFpTest.java b/libcore/security/src/test/java/tests/security/spec/ECFieldFpTest.java
index 8d2c083..82db1c1 100644
--- a/libcore/security/src/test/java/tests/security/spec/ECFieldFpTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/ECFieldFpTest.java
@@ -39,14 +39,6 @@
@TestTargetClass(ECFieldFp.class)
public class ECFieldFpTest extends TestCase {
- /**
- * Constructor for ECFieldFpTest.
- * @param name
- */
- public ECFieldFpTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/spec/ECGenParameterSpecTest.java b/libcore/security/src/test/java/tests/security/spec/ECGenParameterSpecTest.java
index a3c2e6f..77747c3 100644
--- a/libcore/security/src/test/java/tests/security/spec/ECGenParameterSpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/ECGenParameterSpecTest.java
@@ -38,14 +38,6 @@
@TestTargetClass(ECGenParameterSpec.class)
public class ECGenParameterSpecTest extends TestCase {
- /**
- * Constructor for ECGenParameterSpecTest.
- * @param name
- */
- public ECGenParameterSpecTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/spec/ECParameterSpecTest.java b/libcore/security/src/test/java/tests/security/spec/ECParameterSpecTest.java
index 55ac4d0..d970f67 100644
--- a/libcore/security/src/test/java/tests/security/spec/ECParameterSpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/ECParameterSpecTest.java
@@ -38,15 +38,6 @@
ECParameterSpec ecps;
- /**
- * Constructor for ECParameterSpecTest.
- *
- * @param name
- */
- public ECParameterSpecTest(String name) {
- super(name);
- }
-
protected void setUp() throws Exception {
super.setUp();
curve = new EllipticCurve(new ECFieldF2m(2), BigInteger.valueOf(1),
diff --git a/libcore/security/src/test/java/tests/security/spec/ECPointTest.java b/libcore/security/src/test/java/tests/security/spec/ECPointTest.java
index 383592b..17856ae 100644
--- a/libcore/security/src/test/java/tests/security/spec/ECPointTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/ECPointTest.java
@@ -39,14 +39,6 @@
@TestTargetClass(ECPoint.class)
public class ECPointTest extends TestCase {
- /**
- * Constructor for ECPointTest.
- * @param name
- */
- public ECPointTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/spec/ECPrivateKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/ECPrivateKeySpecTest.java
index 6311f83..e13f7ee 100644
--- a/libcore/security/src/test/java/tests/security/spec/ECPrivateKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/ECPrivateKeySpecTest.java
@@ -39,15 +39,6 @@
ECPrivateKeySpec ecpks;
- /**
- * Constructor for ECPrivateKeySpecTest
- *
- * @param name
- */
- public ECPrivateKeySpecTest(String name) {
- super(name);
- }
-
protected void setUp() throws Exception {
super.setUp();
diff --git a/libcore/security/src/test/java/tests/security/spec/ECPublicKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/ECPublicKeySpecTest.java
index b763cd9..c74939e 100644
--- a/libcore/security/src/test/java/tests/security/spec/ECPublicKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/ECPublicKeySpecTest.java
@@ -38,15 +38,6 @@
ECPublicKeySpec ecpks;
- /**
- * Constructor for ECPublicKeySpec
- *
- * @param name
- */
- public ECPublicKeySpecTest(String name) {
- super(name);
- }
-
protected void setUp() throws Exception {
super.setUp();
ECPoint ecpoint = new ECPoint(BigInteger.valueOf(1), BigInteger
diff --git a/libcore/security/src/test/java/tests/security/spec/EncodedKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/EncodedKeySpecTest.java
index 76605df..16208e4 100644
--- a/libcore/security/src/test/java/tests/security/spec/EncodedKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/EncodedKeySpecTest.java
@@ -41,15 +41,6 @@
public class EncodedKeySpecTest extends TestCase {
/**
- * Constructor for EncodedKeySpecTest.
- *
- * @param name
- */
- public EncodedKeySpecTest(String name) {
- super(name);
- }
-
- /**
* Tests for constructor <code>EncodedKeySpec(byte[])</code><br>
*/
@TestTargetNew(
diff --git a/libcore/security/src/test/java/tests/security/spec/InvalidKeySpecExceptionTest.java b/libcore/security/src/test/java/tests/security/spec/InvalidKeySpecExceptionTest.java
index 4b500c6..ba3bb49 100644
--- a/libcore/security/src/test/java/tests/security/spec/InvalidKeySpecExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/InvalidKeySpecExceptionTest.java
@@ -39,18 +39,6 @@
@TestTargetClass(InvalidKeySpecException.class)
public class InvalidKeySpecExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for InvalidKeySpecExceptionTests.
- *
- * @param arg0
- */
- public InvalidKeySpecExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/spec/InvalidParameterSpecExceptionTest.java b/libcore/security/src/test/java/tests/security/spec/InvalidParameterSpecExceptionTest.java
index 104c8f5..b797525 100644
--- a/libcore/security/src/test/java/tests/security/spec/InvalidParameterSpecExceptionTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/InvalidParameterSpecExceptionTest.java
@@ -39,18 +39,6 @@
@TestTargetClass(InvalidParameterSpecException.class)
public class InvalidParameterSpecExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for InvalidParameterSpecExceptionTests.
- *
- * @param arg0
- */
- public InvalidParameterSpecExceptionTest(String arg0) {
- super(arg0);
- }
-
static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/security/src/test/java/tests/security/spec/MGF1ParameterSpecTest.java b/libcore/security/src/test/java/tests/security/spec/MGF1ParameterSpecTest.java
index 2480b6f..2af3be4 100644
--- a/libcore/security/src/test/java/tests/security/spec/MGF1ParameterSpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/MGF1ParameterSpecTest.java
@@ -43,14 +43,6 @@
*/
private static final String testAlgName = "TEST";
- /**
- * Constructor for MGF1ParameterSpecTest.
- * @param arg0
- */
- public MGF1ParameterSpecTest(String arg0) {
- super(arg0);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/spec/PKCS8EncodedKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/PKCS8EncodedKeySpecTest.java
index 4b50e6e..1820d4e 100644
--- a/libcore/security/src/test/java/tests/security/spec/PKCS8EncodedKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/PKCS8EncodedKeySpecTest.java
@@ -40,14 +40,6 @@
@TestTargetClass(PKCS8EncodedKeySpec.class)
public class PKCS8EncodedKeySpecTest extends TestCase {
- /**
- * Constructor for PKCS8EncodedKeySpecTest.
- * @param name
- */
- public PKCS8EncodedKeySpecTest(String name) {
- super(name);
- }
-
//
// Tests
//
diff --git a/libcore/security/src/test/java/tests/security/spec/PSSParameterSpecTest.java b/libcore/security/src/test/java/tests/security/spec/PSSParameterSpecTest.java
index 9082558..4525816 100644
--- a/libcore/security/src/test/java/tests/security/spec/PSSParameterSpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/PSSParameterSpecTest.java
@@ -41,15 +41,6 @@
public class PSSParameterSpecTest extends TestCase {
/**
- * Constructor for PSSParameterSpecTest.
- *
- * @param name
- */
- public PSSParameterSpecTest(String name) {
- super(name);
- }
-
- /**
* Test #1 for <code>PSSParameterSpec(int)</code> ctor<br>
* Assertion: constructs using valid parameter
* <code>PSSParameterSpec<code> object
diff --git a/libcore/security/src/test/java/tests/security/spec/RSAKeyGenParameterSpecTest.java b/libcore/security/src/test/java/tests/security/spec/RSAKeyGenParameterSpecTest.java
index 3d4f1d2..4752d39 100644
--- a/libcore/security/src/test/java/tests/security/spec/RSAKeyGenParameterSpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/RSAKeyGenParameterSpecTest.java
@@ -41,14 +41,6 @@
public class RSAKeyGenParameterSpecTest extends TestCase {
/**
- * Constructor for RSAKeyGenParameterSpecTest.
- * @param name
- */
- public RSAKeyGenParameterSpecTest(String name) {
- super(name);
- }
-
- /**
* Test for <code>RSAKeyGenParameterSpec(int,BigInteger)</code> ctor
* Assertion: constructs <code>RSAKeyGenParameterSpec</code>
* object using valid parameters
diff --git a/libcore/security/src/test/java/tests/security/spec/RSAMultiPrimePrivateCrtKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/RSAMultiPrimePrivateCrtKeySpecTest.java
index ae79695..2963458 100644
--- a/libcore/security/src/test/java/tests/security/spec/RSAMultiPrimePrivateCrtKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/RSAMultiPrimePrivateCrtKeySpecTest.java
@@ -50,14 +50,6 @@
new RSAOtherPrimeInfo(BigInteger.ONE, BigInteger.ONE, BigInteger.ONE)
};
- /**
- * Constructor for RSAMultiPrimePrivateCrtKeySpecTest.
- * @param name
- */
- public RSAMultiPrimePrivateCrtKeySpecTest(String name) {
- super(name);
- }
-
// Test-cases:
/**
diff --git a/libcore/security/src/test/java/tests/security/spec/RSAOtherPrimeInfoTest.java b/libcore/security/src/test/java/tests/security/spec/RSAOtherPrimeInfoTest.java
index 9344c97..8179e75 100644
--- a/libcore/security/src/test/java/tests/security/spec/RSAOtherPrimeInfoTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/RSAOtherPrimeInfoTest.java
@@ -40,14 +40,6 @@
public class RSAOtherPrimeInfoTest extends TestCase {
/**
- * Constructor for RSAOtherPrimeInfoTest.
- * @param name
- */
- public RSAOtherPrimeInfoTest(String name) {
- super(name);
- }
-
- /**
* Test #1 for <code>RSAOtherPrimeInfo(BigInteger,BigInteger,BigInteger)</code> ctor
* Assertion: constructs <code>RSAOtherPrimeInfo</code>
* object using valid parameter
diff --git a/libcore/security/src/test/java/tests/security/spec/RSAPrivateCrtKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/RSAPrivateCrtKeySpecTest.java
index 13c4f22..5f4b6c4 100644
--- a/libcore/security/src/test/java/tests/security/spec/RSAPrivateCrtKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/RSAPrivateCrtKeySpecTest.java
@@ -42,14 +42,6 @@
public class RSAPrivateCrtKeySpecTest extends TestCase {
/**
- * Constructor for RSAPrivateCrtKeySpecTest.
- * @param name
- */
- public RSAPrivateCrtKeySpecTest(String name) {
- super(name);
- }
-
- /**
* Test #1 for <code>RSAPrivateCrtKeySpec</code> constructor
* Assertion: Constructs <code>RSAPrivateCrtKeySpec</code>
* object using valid parameters
diff --git a/libcore/security/src/test/java/tests/security/spec/RSAPrivateKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/RSAPrivateKeySpecTest.java
index 8940003..207c173 100644
--- a/libcore/security/src/test/java/tests/security/spec/RSAPrivateKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/RSAPrivateKeySpecTest.java
@@ -41,14 +41,6 @@
public class RSAPrivateKeySpecTest extends TestCase {
/**
- * Constructor for RSAPrivateKeySpecTest.
- * @param name
- */
- public RSAPrivateKeySpecTest(String name) {
- super(name);
- }
-
- /**
* Test for <code>RSAPrivateKeySpec(BigInteger,BigInteger)</code> ctor
* Assertion: constructs <code>RSAPrivateKeySpec</code>
* object using valid parameters
diff --git a/libcore/security/src/test/java/tests/security/spec/RSAPublicKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/RSAPublicKeySpecTest.java
index 47b9ca6..08f852c 100644
--- a/libcore/security/src/test/java/tests/security/spec/RSAPublicKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/RSAPublicKeySpecTest.java
@@ -41,15 +41,6 @@
public class RSAPublicKeySpecTest extends TestCase {
/**
- * Constructor for RSAPublicKeySpecTest.
- * @param name
- */
- public RSAPublicKeySpecTest(String name) {
- super(name);
- }
-
-
- /**
* Test #1 for <code>RSAPublicKeySpec</code> constructor
* Assertion: Constructs <code>RSAPublicKeySpec</code>
* object using valid parameters
diff --git a/libcore/security/src/test/java/tests/security/spec/X509EncodedKeySpecTest.java b/libcore/security/src/test/java/tests/security/spec/X509EncodedKeySpecTest.java
index 26c0b5e..8942b89 100644
--- a/libcore/security/src/test/java/tests/security/spec/X509EncodedKeySpecTest.java
+++ b/libcore/security/src/test/java/tests/security/spec/X509EncodedKeySpecTest.java
@@ -41,14 +41,6 @@
@TestTargetClass(X509EncodedKeySpec.class)
public class X509EncodedKeySpecTest extends TestCase {
- /**
- * Constructor for X509EncodedKeySpecTest.
- * @param name
- */
- public X509EncodedKeySpecTest(String name) {
- super(name);
- }
-
//
// Test cases
//
diff --git a/libcore/security/src/test/java/tests/targets/security/AlgorithmParameterGeneratorTest.java b/libcore/security/src/test/java/tests/targets/security/AlgorithmParameterGeneratorTest.java
index 0c362fa..7c76430 100644
--- a/libcore/security/src/test/java/tests/targets/security/AlgorithmParameterGeneratorTest.java
+++ b/libcore/security/src/test/java/tests/targets/security/AlgorithmParameterGeneratorTest.java
@@ -1,7 +1,6 @@
package tests.targets.security;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
@@ -11,7 +10,6 @@
import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
-@TestTargetClass(targets.AlgorithmParameterGenerators.Internal.class)
public abstract class AlgorithmParameterGeneratorTest extends TestCase {
private final String algorithmName;
@@ -32,6 +30,11 @@
level=TestLevel.ADDITIONAL,
method="init",
args={int.class}
+ ),
+ @TestTargetNew(
+ level=TestLevel.COMPLETE,
+ method="method",
+ args={}
)
})
public void testAlgorithmParameterGenerator() {
diff --git a/libcore/security/src/test/java/tests/targets/security/AlgorithmParametersTest.java b/libcore/security/src/test/java/tests/targets/security/AlgorithmParametersTest.java
index 3b45d40..49ac2de 100644
--- a/libcore/security/src/test/java/tests/targets/security/AlgorithmParametersTest.java
+++ b/libcore/security/src/test/java/tests/targets/security/AlgorithmParametersTest.java
@@ -1,7 +1,6 @@
package tests.targets.security;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
@@ -12,7 +11,6 @@
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
-@TestTargetClass(targets.AlgorithmParameters.Internal.class)
public class AlgorithmParametersTest extends TestCase {
private final String algorithmName;
@@ -40,6 +38,11 @@
level=TestLevel.ADDITIONAL,
method="init",
args={byte[].class}
+ ),
+ @TestTargetNew(
+ level=TestLevel.COMPLETE,
+ method="method",
+ args={}
)
})
public void testAlgorithmParameters() {
diff --git a/libcore/security/src/test/java/tests/targets/security/AllTests.java b/libcore/security/src/test/java/tests/targets/security/AllTests.java
index 4235b71..c4d85b5 100644
--- a/libcore/security/src/test/java/tests/targets/security/AllTests.java
+++ b/libcore/security/src/test/java/tests/targets/security/AllTests.java
@@ -35,6 +35,7 @@
suite.addTestSuite(MessageDigestTestMD5.class);
suite.addTestSuite(MessageDigestTestSHA1.class);
+ suite.addTestSuite(MessageDigestTestSHA224.class);
suite.addTestSuite(MessageDigestTestSHA256.class);
suite.addTestSuite(MessageDigestTestSHA384.class);
suite.addTestSuite(MessageDigestTestSHA512.class);
@@ -49,8 +50,10 @@
suite.addTestSuite(SignatureTestMD2withRSA.class);
suite.addTestSuite(SignatureTestMD5withRSA.class);
+ suite.addTestSuite(SignatureTestNONEwithDSA.class);
suite.addTestSuite(SignatureTestSHA1withDSA.class);
suite.addTestSuite(SignatureTestSHA1withRSA.class);
+ suite.addTestSuite(SignatureTestSHA224withRSA.class);
suite.addTestSuite(SignatureTestSHA256withRSA.class);
suite.addTestSuite(SignatureTestSHA384withRSA.class);
suite.addTestSuite(SignatureTestSHA512withRSA.class);
@@ -67,6 +70,8 @@
suite.addTestSuite(AlgorithmParametersTestDH.class);
suite.addTestSuite(KeyStoreTestPKCS12.class);
+
+ suite.addTestSuite(SecureRandomTestSHA1PRNG.class);
// $JUnit-END$
return suite;
diff --git a/libcore/security/src/test/java/tests/targets/security/DHTest.java b/libcore/security/src/test/java/tests/targets/security/DHTest.java
index 9ccc616..16b6d62 100644
--- a/libcore/security/src/test/java/tests/targets/security/DHTest.java
+++ b/libcore/security/src/test/java/tests/targets/security/DHTest.java
@@ -22,10 +22,9 @@
@TestTargetNew(
level = TestLevel.ADDITIONAL,
- method = "!",
+ method = "method",
args = {}
)
- @BrokenTest("please cleanup test and annotations")
public void testDHGen() throws Exception
{
KeyPairGenerator gen = null;
@@ -33,8 +32,6 @@
gen = KeyPairGenerator.getInstance("DH");
} catch (NoSuchAlgorithmException e) {
fail(e.getMessage());
-// } catch (NoSuchProviderException e) {
-// fail(e.getMessage());
}
AlgorithmParameterGenerator algorithmparametergenerator = AlgorithmParameterGenerator.getInstance("DH");
diff --git a/libcore/security/src/test/java/tests/targets/security/KeyFactoryTest.java b/libcore/security/src/test/java/tests/targets/security/KeyFactoryTest.java
index 9b5008a..ddfef9f 100644
--- a/libcore/security/src/test/java/tests/targets/security/KeyFactoryTest.java
+++ b/libcore/security/src/test/java/tests/targets/security/KeyFactoryTest.java
@@ -1,7 +1,6 @@
package tests.targets.security;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
@@ -15,7 +14,6 @@
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
-@TestTargetClass(targets.KeyFactories.Internal.class)
public abstract class KeyFactoryTest<PublicKeySpec extends KeySpec, PrivateKeySpec extends KeySpec>
extends TestCase {
@@ -65,6 +63,11 @@
level = TestLevel.ADDITIONAL,
method = "generatePublic",
args = {KeySpec.class}
+ ),
+ @TestTargetNew(
+ level=TestLevel.COMPLETE,
+ method="method",
+ args={}
)
})
public void testKeyFactory() {
diff --git a/libcore/security/src/test/java/tests/targets/security/KeyPairGeneratorTest.java b/libcore/security/src/test/java/tests/targets/security/KeyPairGeneratorTest.java
index 86f1c78..64fb079 100644
--- a/libcore/security/src/test/java/tests/targets/security/KeyPairGeneratorTest.java
+++ b/libcore/security/src/test/java/tests/targets/security/KeyPairGeneratorTest.java
@@ -27,7 +27,6 @@
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
-@TestTargetClass(targets.KeyPairGenerators.Internal.class)
public abstract class KeyPairGeneratorTest extends TestCase {
private final String algorithmName;
@@ -67,6 +66,11 @@
level = TestLevel.ADDITIONAL,
method = "generateKeyPair",
args = {}
+ ),
+ @TestTargetNew(
+ level=TestLevel.COMPLETE,
+ method="method",
+ args={}
)
})
public void testKeyPairGenerator() {
diff --git a/libcore/security/src/test/java/tests/targets/security/KeyStoreTest.java b/libcore/security/src/test/java/tests/targets/security/KeyStoreTest.java
index 57dad92..3f29387 100644
--- a/libcore/security/src/test/java/tests/targets/security/KeyStoreTest.java
+++ b/libcore/security/src/test/java/tests/targets/security/KeyStoreTest.java
@@ -1,7 +1,6 @@
package tests.targets.security;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
@@ -26,7 +25,6 @@
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-@TestTargetClass(targets.KeyStores.Internal.class)
public class KeyStoreTest extends TestCase {
private final String algorithmName;
@@ -50,6 +48,11 @@
level=TestLevel.ADDITIONAL,
method="load",
args={InputStream.class,char[].class}
+ ),
+ @TestTargetNew(
+ level=TestLevel.PARTIAL_COMPLETE,
+ method="method",
+ args={}
)
})
public void testKeyStoreLoad() {
@@ -94,6 +97,11 @@
level=TestLevel.ADDITIONAL,
method="setEntry",
args={String.class,Entry.class,ProtectionParameter.class}
+ ),
+ @TestTargetNew(
+ level=TestLevel.PARTIAL_COMPLETE,
+ method="method",
+ args={}
)
})
public void testKeyStoreCreate() {
diff --git a/libcore/security/src/test/java/tests/targets/security/KeyStoreTestPKCS12.java b/libcore/security/src/test/java/tests/targets/security/KeyStoreTestPKCS12.java
index 81f57d9..487e315 100644
--- a/libcore/security/src/test/java/tests/targets/security/KeyStoreTestPKCS12.java
+++ b/libcore/security/src/test/java/tests/targets/security/KeyStoreTestPKCS12.java
@@ -1,9 +1,6 @@
package tests.targets.security;
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
@TestTargetClass(targets.KeyStores.PKCS12.class)
public class KeyStoreTestPKCS12 extends KeyStoreTest {
@@ -12,26 +9,6 @@
super("PKCS12", keyStoreData, keyStorePassword);
}
- @Override
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "!"
- )
- @KnownFailure("Missing SecretKeyFactory 1.2.840.113549.1.12.1.3")
- public void testKeyStoreCreate() {
- super.testKeyStoreCreate();
- }
-
- @Override
- @TestTargetNew(
- level = TestLevel.ADDITIONAL,
- method = "!"
- )
- @KnownFailure("Missing SecretKeyFactory 1.2.840.113549.1.12.1.3")
- public void testKeyStoreLoad() {
- super.testKeyStoreLoad();
- }
-
public static final String keyStorePassword = "the keystore password";
public static final byte[] keyStoreData = new byte[] {
diff --git a/libcore/security/src/test/java/tests/targets/security/MessageDigestTest.java b/libcore/security/src/test/java/tests/targets/security/MessageDigestTest.java
index d2d3b5d..20dc238 100644
--- a/libcore/security/src/test/java/tests/targets/security/MessageDigestTest.java
+++ b/libcore/security/src/test/java/tests/targets/security/MessageDigestTest.java
@@ -1,7 +1,6 @@
package tests.targets.security;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
@@ -11,7 +10,6 @@
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-@TestTargetClass(targets.MessageDigests.Internal.class)
public abstract class MessageDigestTest extends TestCase {
private String digestAlgorithmName;
@@ -78,9 +76,14 @@
level = TestLevel.ADDITIONAL,
method = "digest",
args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "method",
+ args = {}
)
})
- public void testMessageDigest()
+ public void testMessageDigest1()
{
byte[] buf = new byte[128];
int read = 0;
@@ -104,4 +107,168 @@
}
}
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "update",
+ args = {byte.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "digest",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "method",
+ args = {}
+ )
+ })
+ public void testMessageDigest2()
+ {
+ int val;
+ try {
+ while ((val = sourceData.read()) != -1)
+ {
+ digest.update((byte)val);
+ }
+ } catch (IOException e) {
+ fail("failed to read digest data");
+ }
+
+ byte[] computedDigest = digest.digest();
+
+ assertNotNull("computed digest is is null", computedDigest);
+ assertEquals("digest length mismatch", checkDigest.length, computedDigest.length);
+ StringBuilder sb1, sb2;
+ sb1 = new StringBuilder();
+ sb2 = new StringBuilder();
+ for (int i = 0; i < checkDigest.length; i++)
+ {
+ assertEquals("byte " + i + " of computed and check digest differ", checkDigest[i], computedDigest[i]);
+ }
+
+ }
+
+
+ /**
+ * Official FIPS180-2 testcases
+ */
+
+ protected String source1, source2, source3;
+ protected String expected1, expected2, expected3;
+
+ String getLongMessage(int length) {
+ StringBuilder sourceBuilder = new StringBuilder(length);
+ for (int i = 0; i < length / 10; i++) {
+ sourceBuilder.append("aaaaaaaaaa");
+ }
+ return sourceBuilder.toString();
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "update",
+ args = {byte.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "digest",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "method",
+ args = {}
+ )
+ })
+ public void testfips180_2_singleblock() {
+
+ digest.update(source1.getBytes(), 0, source1.length());
+
+ byte[] computedDigest = digest.digest();
+
+ assertNotNull("computed digest is null", computedDigest);
+
+ StringBuilder sb = new StringBuilder();
+ String res;
+ for (int i = 0; i < computedDigest.length; i++)
+ {
+ res = Integer.toHexString(computedDigest[i] & 0xFF);
+ sb.append((res.length() == 1 ? "0" : "") + res);
+ }
+ assertEquals("computed and check digest differ", expected1, sb.toString());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "update",
+ args = {byte.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "digest",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "method",
+ args = {}
+ )
+ })
+ public void testfips180_2_multiblock() {
+
+ digest.update(source2.getBytes(), 0, source2.length());
+
+ byte[] computedDigest = digest.digest();
+
+ assertNotNull("computed digest is null", computedDigest);
+
+ StringBuilder sb = new StringBuilder();
+ String res;
+ for (int i = 0; i < computedDigest.length; i++)
+ {
+ res = Integer.toHexString(computedDigest[i] & 0xFF);
+ sb.append((res.length() == 1 ? "0" : "") + res);
+ }
+ assertEquals("computed and check digest differ", expected2, sb.toString());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "update",
+ args = {byte.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.ADDITIONAL,
+ method = "digest",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "method",
+ args = {}
+ )
+ })
+ public void testfips180_2_longMessage() {
+
+ digest.update(source3.getBytes(), 0, source3.length());
+
+ byte[] computedDigest = digest.digest();
+
+ assertNotNull("computed digest is null", computedDigest);
+
+ StringBuilder sb = new StringBuilder();
+ String res;
+ for (int i = 0; i < computedDigest.length; i++)
+ {
+ res = Integer.toHexString(computedDigest[i] & 0xFF);
+ sb.append((res.length() == 1 ? "0" : "") + res);
+ }
+ assertEquals("computed and check digest differ", expected3, sb.toString());
+ }
}
diff --git a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestMD5.java b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestMD5.java
index a6663d8..c651695 100644
--- a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestMD5.java
+++ b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestMD5.java
@@ -8,8 +8,16 @@
public MessageDigestTestMD5() {
super("MD5");
+ super.source1 = "abc";
+ super.source2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
+ super.source3 = getLongMessage(1000000);
+ super.expected1 = singleblock;
+ super.expected2 = multiblock;
+ super.expected3 = longmessage;
}
-
+ String singleblock = "900150983cd24fb0d6963f7d28e17f72";
+ String multiblock = "03dd8807a93175fb062dfb55dc7d359c";
+ String longmessage = "7707d6ae4e027c70eea2a935c2296f21";
}
diff --git a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA1.java b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA1.java
index 79ba6a0..0d9fe5c 100644
--- a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA1.java
+++ b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA1.java
@@ -8,8 +8,17 @@
public MessageDigestTestSHA1() {
super("SHA-1");
+ super.source1 = "abc";
+ super.source2 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+ super.source3 = getLongMessage(1000000);
+ super.expected1 = singleblock;
+ super.expected2 = multiblock;
+ super.expected3 = longmessage;
}
-
+ // results from fips180-2
+ String singleblock = "a9993e364706816aba3e25717850c26c9cd0d89d";
+ String multiblock = "84983e441c3bd26ebaae4aa1f95129e5e54670f1";
+ String longmessage = "34aa973cd4c4daa4f61eeb2bdbad27316534016f";
}
diff --git a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA224.java b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA224.java
new file mode 100644
index 0000000..71b8a5a
--- /dev/null
+++ b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA224.java
@@ -0,0 +1,20 @@
+package tests.targets.security;
+
+public class MessageDigestTestSHA224 extends MessageDigestTest {
+
+ public MessageDigestTestSHA224() {
+ super("SHA-224");
+ super.source1 = "abc";
+ super.source2 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+ super.source3 = getLongMessage(1000000);
+ super.expected1 = singleblock;
+ super.expected2 = multiblock;
+ super.expected3 = longmessage;
+ }
+
+ // results from fips180-2
+ String singleblock = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7";
+ String multiblock = "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525";
+ String longmessage = "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67";
+
+}
diff --git a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA256.java b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA256.java
index aac55bf..b238a47 100644
--- a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA256.java
+++ b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA256.java
@@ -8,8 +8,17 @@
public MessageDigestTestSHA256() {
super("SHA-256");
+ super.source1 = "abc";
+ super.source2 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+ super.source3 = getLongMessage(1000000);
+ super.expected1 = singleblock;
+ super.expected2 = multiblock;
+ super.expected3 = longmessage;
}
-
+ // results from fips180-2
+ String singleblock = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
+ String multiblock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
+ String longmessage = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0";
}
diff --git a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA384.java b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA384.java
index eacc675..acfebd0 100644
--- a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA384.java
+++ b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA384.java
@@ -8,8 +8,17 @@
public MessageDigestTestSHA384() {
super("SHA-384");
+ super.source1 = "abc";
+ super.source2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
+ super.source3 = getLongMessage(1000000);
+ super.expected1 = singleblock;
+ super.expected2 = multiblock;
+ super.expected3 = longmessage;
}
-
+ // results from fips180-2
+ String singleblock = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";
+ String multiblock = "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039";
+ String longmessage = "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985";
}
diff --git a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA512.java b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA512.java
index eb254cf..826fd56 100644
--- a/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA512.java
+++ b/libcore/security/src/test/java/tests/targets/security/MessageDigestTestSHA512.java
@@ -8,8 +8,17 @@
public MessageDigestTestSHA512() {
super("SHA-512");
+ super.source1 = "abc";
+ super.source2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
+ super.source3 = getLongMessage(1000000);
+ super.expected1 = singleblock;
+ super.expected2 = multiblock;
+ super.expected3 = longmessage;
}
-
+ // results from fips180-2
+ String singleblock = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
+ String multiblock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909";
+ String longmessage = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b";
}
diff --git a/libcore/security/src/test/java/tests/targets/security/SecureRandomTest.java b/libcore/security/src/test/java/tests/targets/security/SecureRandomTest.java
index fa60150..3314cd1 100644
--- a/libcore/security/src/test/java/tests/targets/security/SecureRandomTest.java
+++ b/libcore/security/src/test/java/tests/targets/security/SecureRandomTest.java
@@ -1,7 +1,6 @@
package tests.targets.security;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
@@ -10,7 +9,6 @@
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
-@TestTargetClass(targets.SecureRandoms.Internal.class)
public abstract class SecureRandomTest extends TestCase {
@@ -41,6 +39,11 @@
level=TestLevel.ADDITIONAL,
method="nextBytes",
args={byte[].class}
+ ),
+ @TestTargetNew(
+ level=TestLevel.COMPLETE,
+ method="method",
+ args={}
)
})
public void testSecureRandom() {
diff --git a/libcore/security/src/test/java/tests/targets/security/SignatureTest.java b/libcore/security/src/test/java/tests/targets/security/SignatureTest.java
index 65098b0..b6ac758 100644
--- a/libcore/security/src/test/java/tests/targets/security/SignatureTest.java
+++ b/libcore/security/src/test/java/tests/targets/security/SignatureTest.java
@@ -1,7 +1,6 @@
package tests.targets.security;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
@@ -15,7 +14,6 @@
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
-@TestTargetClass(targets.Signatures.Internal.class)
public abstract class SignatureTest extends TestCase {
private final String algorithmName;
@@ -78,6 +76,11 @@
level = TestLevel.ADDITIONAL,
method = "verify",
args = {byte[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "method",
+ args = {}
)
})
public void testSignature() {
diff --git a/libcore/security/src/test/java/tests/targets/security/SignatureTestSHA224withRSA.java b/libcore/security/src/test/java/tests/targets/security/SignatureTestSHA224withRSA.java
new file mode 100644
index 0000000..20945bd
--- /dev/null
+++ b/libcore/security/src/test/java/tests/targets/security/SignatureTestSHA224withRSA.java
@@ -0,0 +1,11 @@
+package tests.targets.security;
+
+import dalvik.annotation.TestTargetClass;
+
+@TestTargetClass(targets.Signatures.SHA224withRSA.class)
+public class SignatureTestSHA224withRSA extends SignatureTest {
+
+ public SignatureTestSHA224withRSA() {
+ super("SHA224withRSA", "RSA");
+ }
+}
diff --git a/libcore/security/src/test/java/tests/targets/security/cert/CertPathBuilderTest.java b/libcore/security/src/test/java/tests/targets/security/cert/CertPathBuilderTest.java
index f95f10c..2dcacc2 100644
--- a/libcore/security/src/test/java/tests/targets/security/cert/CertPathBuilderTest.java
+++ b/libcore/security/src/test/java/tests/targets/security/cert/CertPathBuilderTest.java
@@ -1,7 +1,6 @@
package tests.targets.security.cert;
import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
@@ -14,7 +13,6 @@
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertPathBuilderResult;
import java.security.cert.CertPathParameters;
-@TestTargetClass(targets.CertPathBuilders.Internal.class)
public abstract class CertPathBuilderTest extends TestCase {
private final String algorithmName;
@@ -49,6 +47,11 @@
clazz=CertPathBuilderResult.class,
method="getCertPath",
args={}
+ ),
+ @TestTargetNew(
+ level=TestLevel.COMPLETE,
+ method="method",
+ args={}
)
})
public void testCertPathBuilder() {
diff --git a/libcore/security/src/test/resources/serialization/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.golden.ser b/libcore/security/src/test/resources/serialization/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.golden.ser
new file mode 100755
index 0000000..2937f2f
--- /dev/null
+++ b/libcore/security/src/test/resources/serialization/org/apache/harmony/security/tests/java/security/UnresolvedPermissionTest.golden.ser
Binary files differ
diff --git a/libcore/security/src/test/resources/hyts_badpem.cer b/libcore/security/src/test/resources/tests/resources/hyts_badpem.cer
similarity index 100%
rename from libcore/security/src/test/resources/hyts_badpem.cer
rename to libcore/security/src/test/resources/tests/resources/hyts_badpem.cer
diff --git a/libcore/security/src/test/resources/java/security/cert/CertPath.PkiPath b/libcore/security/src/test/resources/tests/resources/java/security/cert/CertPath.PkiPath
similarity index 100%
rename from libcore/security/src/test/resources/java/security/cert/CertPath.PkiPath
rename to libcore/security/src/test/resources/tests/resources/java/security/cert/CertPath.PkiPath
Binary files differ
diff --git a/libcore/security/src/test/resources/tests/targets/security/SHA-224.check b/libcore/security/src/test/resources/tests/targets/security/SHA-224.check
new file mode 100644
index 0000000..a7aaf15
--- /dev/null
+++ b/libcore/security/src/test/resources/tests/targets/security/SHA-224.check
@@ -0,0 +1 @@
+äì¸:ž˽>à|=¦Úûż¾¼0]•âGQ¢í
\ No newline at end of file
diff --git a/libcore/security/src/test/resources/tests/targets/security/SHA-224.data b/libcore/security/src/test/resources/tests/targets/security/SHA-224.data
new file mode 100644
index 0000000..39be11d
--- /dev/null
+++ b/libcore/security/src/test/resources/tests/targets/security/SHA-224.data
@@ -0,0 +1 @@
+hallo welt!
\ No newline at end of file
diff --git a/libcore/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java b/libcore/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java
index d459a63..a4b12ab 100644
--- a/libcore/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java
+++ b/libcore/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java
@@ -82,12 +82,11 @@
* @throws SQLException
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "SQLException checking missed: not feasible. test fails, Disabled due to potential implementation error ticket #60.",
+ level = TestLevel.SUFFICIENT,
+ notes = "SQLException checking missed: not feasible.",
method = "deregisterDriver",
args = {java.sql.Driver.class}
)
- @BrokenTest("Error creating Test Helper in test setup")
public void testDeregisterDriver() throws Exception {
// First get one of the drivers loaded by the test
Driver aDriver;
diff --git a/libcore/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/TestHelper_DriverManager.java b/libcore/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/TestHelper_DriverManager.java
index f82271e..773684e 100644
--- a/libcore/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/TestHelper_DriverManager.java
+++ b/libcore/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/TestHelper_DriverManager.java
@@ -22,6 +22,7 @@
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
+import java.util.logging.Logger;
import junit.framework.TestCase;
@@ -49,7 +50,7 @@
public static void setDriver(Driver theDriver) {
testDriver = theDriver;
- // System.out.println("TestHelper_DriverManager: Test Driver set!");
+ // Logger.global.info("TestHelper_DriverManager: Test Driver set!");
theHelper.checkDeregister();
} // end method setDriver( Driver )
@@ -58,19 +59,16 @@
String baseURL = "jdbc:mikes1";
- // System.out.println("Calling checkDeregister in
- // TestHelper_DriverManager....");
+ // Logger.global.info("Calling checkDeregister in TestHelper_DriverManager....");
Driver aDriver;
- // System.out.println("checkDeregister classloader: " +
- // this.getClass().getClassLoader() );
+ // Logger.global.info("checkDeregister classloader: this.getClass().getClassLoader()");
// Try to get a driver from the general pool... this should fail
try {
aDriver = DriverManager.getDriver(baseURL);
- fail(
- "testDeregisterDriver: Didn't get exception when getting valid driver from other classloader.");
+ fail("testDeregisterDriver: Didn't get exception when getting valid driver from other classloader.");
} catch (SQLException e) {
// e.printStackTrace();
assertTrue(
@@ -92,15 +90,13 @@
// prevent subsequent tests from failing due to inability to get to
// this driver...
DriverManager.registerDriver(aDriver);
- fail(
- "checkDeregisterDriver: Didn't get Security Exception deregistering invalid driver.");
+ fail("checkDeregisterDriver: Didn't get Security Exception deregistering invalid driver.");
} catch (SecurityException s) {
// This is the exception we should get...
// System.out.println("checkDeregisterDriver: got expected Security
// Exception");
} catch (Exception e) {
- fail(
- "checkDeregisterDriver: Got wrong exception type when deregistering invalid driver.");
+ fail("checkDeregisterDriver: Got wrong exception type when deregistering invalid driver.");
} // end try
} // end method testDeRegister
diff --git a/libcore/sql/src/test/java/tests/SQLite/AbstractSqlTest.java b/libcore/sql/src/test/java/tests/SQLite/AbstractSqlTest.java
index f580f70..0c7fa61 100644
--- a/libcore/sql/src/test/java/tests/SQLite/AbstractSqlTest.java
+++ b/libcore/sql/src/test/java/tests/SQLite/AbstractSqlTest.java
@@ -76,8 +76,8 @@
private final String[] ones_updated;
/** Creates a new instance of this class */
- public AbstractSqlTest(String testName) {
- super(testName);
+ public AbstractSqlTest() {
+ super();
ones_updated = new String[ones.length];
for (int i = 0; i < ones.length; i++) {
ones_updated[i] = ones[i] + twos[i];
diff --git a/libcore/sql/src/test/java/tests/SQLite/AllTests.java b/libcore/sql/src/test/java/tests/SQLite/AllTests.java
index bb41f58..2cf0f61 100644
--- a/libcore/sql/src/test/java/tests/SQLite/AllTests.java
+++ b/libcore/sql/src/test/java/tests/SQLite/AllTests.java
@@ -31,6 +31,8 @@
suite.addTestSuite(ConstantsTest.class);
suite.addTestSuite(BlobTest.class);
suite.addTestSuite(StmtTest.class);
+ suite.addTestSuite(ExceptionTest.class);
+ suite.addTestSuite(FunctionContextTest.class);
//$JUnit-END$
return suite;
}
diff --git a/libcore/sql/src/test/java/tests/SQLite/BlobTest.java b/libcore/sql/src/test/java/tests/SQLite/BlobTest.java
index 25c1274..71f2005 100644
--- a/libcore/sql/src/test/java/tests/SQLite/BlobTest.java
+++ b/libcore/sql/src/test/java/tests/SQLite/BlobTest.java
@@ -17,33 +17,61 @@
package tests.SQLite;
import SQLite.Blob;
+import SQLite.Database;
+import SQLite.Exception;
+import SQLite.Stmt;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
import junit.framework.TestCase;
+import tests.support.DatabaseCreator;
+import tests.support.Support_SQL;
+
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@TestTargetClass(Blob.class)
-public class BlobTest extends TestCase {
+public class BlobTest extends SQLiteTest {
private static Blob testBlob = null;
private byte[] blobInput= null;
private static InputStream file = null;
-
- public BlobTest(String name) {
- super(name);
+ private static Database db = null;
+
+ private static Stmt st = null;
+
+ public class MockBlob extends Blob {
+ public void finalize() {
+ try {
+ super.finalize();
+ } catch (Throwable exception) {
+ fail("Test activity faild!");
+ }
+ }
}
- protected void setUp() throws java.lang.Exception {
+ public void setUp() throws java.lang.Exception {
super.setUp();
testBlob = new Blob();
+ super.setUp();
+ Support_SQL.loadDriver();
+ db = new Database();
+ db.open(dbFile.getPath(), 0);
+
+ db.exec("create table B(id integer primary key, val blob)",null);
+ db.exec("insert into B values(1, zeroblob(128))", null);
+ db.exec("insert into B values(2, zeroblob(128))", null);
+ db.exec("insert into B values(3, zeroblob(128))", null);
+
// can not fill Blob with data at this point...
/*
File resources = Support_Resources.createTempFolder();
@@ -69,23 +97,58 @@
*/
}
- protected void tearDown() throws java.lang.Exception {
- super.tearDown();
+ public void tearDown() {
+
testBlob.close();
+ super.tearDown();
}
+
/**
+ * @throws Exception
+ * @throws IOException
* @tests Blob#Blob()
*/
+ @TestTargets ( {
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "constructor test",
+ level = TestLevel.NOT_FEASIBLE,
+ notes = "db.open_blob is not supported also for Stmt, therefore cannot test Blobs",
method = "Blob",
args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.NOT_FEASIBLE,
+ notes = "functional test",
+ method = "getOutputStream",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.NOT_FEASIBLE,
+ notes = "functional test",
+ method = "getInputStream",
+ args = {}
)
- public void _testBlob() {
- Blob b = new Blob();
- assertNotNull(b);
- //assertEquals(0, b.size);
+ })
+ @KnownFailure("db.open_blob is not supported.")
+ public void testBlob() throws Exception, IOException {
+ byte[] b = new byte[4];
+ byte[] b128 = new byte[128];
+ for (int i = 0; i < b128.length; i++) {
+ b128[i] = (byte) i;
+ }
+ Blob blob = db.open_blob(dbFile.getPath(), "B", "val", 1, true);
+ try {
+
+ OutputStream os = blob.getOutputStream();
+ os.write(b128);
+ os.close();
+
+ InputStream is = blob.getInputStream();
+ is.skip(96);
+ assertEquals(4,is.read(b));
+ is.close();
+ } finally {
+ blob.close();
+ }
}
/**
@@ -93,53 +156,32 @@
*/
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
- notes = "method test",
+ notes = "Can not be checked. Should be tested in DX test package.",
method = "finalize",
args = {}
)
- public void _testFinalize() {
- fail("Not yet implemented");
+ public void testFinalize() {
+
}
/**
* @tests Blob.getInputStream()
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "method test",
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Exception test",
method = "getInputStream",
args = {}
)
public void testGetInputStream() {
InputStream in = testBlob.getInputStream();
- assertNotNull(in);
+
try {
in.read();
- fail("Read operation unsupported");
+ fail("Exception not thrown for invalid Blob.");
} catch (Throwable e) {
//ok
- }
-
- /*
- byte[] defaultByteArray = null;
- BufferedReader actual = new BufferedReader(new InputStreamReader(
- testBlob.getInputStream()));
- byte[] b1;
- byte[] b2;
- try {
- BufferedReader shouldBe = new BufferedReader(new InputStreamReader(
- this.file));
- while (((b1 = actual.readLine().getBytes()) != null)
- && ((b2 = shouldBe.readLine().getBytes()) != null)) {
- assertEquals(b2, b1);
- }
- assertEquals("both finished", shouldBe.readLine(), actual
- .readLine());
- } catch (IOException e) {
- fail("Error in test setup: " + e.toString());
- e.printStackTrace();
- }
- */
+ }
}
/**
@@ -147,13 +189,13 @@
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
- notes = "method test",
+ notes = "Exception test",
method = "getOutputStream",
args = {}
)
public void testGetOutputStream() {
OutputStream out = testBlob.getOutputStream();
- assertNotNull(out);
+
try {
out.write(null);
fail("Write operation unsupported");
@@ -166,58 +208,28 @@
* @tests Blob#close()
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "method test",
+ level = TestLevel.SUFFICIENT,
+ notes = "not clear from spec what should happen when Blob is closed.",
method = "close",
args = {}
)
- public void _testClose() {
- try {
- testBlob.close();
- testBlob.close();
- testBlob.getInputStream();
- //assertEquals(0, testBlob.size);
- } catch (Throwable e) {
- fail("Tests failed");
- }
+ @KnownFailure("Blob does not clean up inputStream.")
+ public void testClose() {
+ assertNotNull(testBlob);
+
+ testBlob.close();
+ // inputStream eithter null or some error occurs
+ try {
+ assertNull(testBlob.getInputStream());
+ } catch (Throwable e) {
+ //ok
}
-
- // these tests show that read and write are unsupported -> blob is unsupported
-// /**
-// * @tests Blob#write(byte[], int, int, int)
-// */
-// @TestTargetNew(
-// level = TestLevel.COMPLETE,
-// notes = "method test",
-// method = "write",
-// args = {byte[].class, int.class, int.class, int.class}
-// )
-// public void testWrite() {
-// try {
-// testBlob.write(null, 0, 0, 0);
-// fail("Write operation unsupported");
-// } catch (Throwable e) {
-// //ok
-// }
-// }
-//
-// /**
-// * @tests Blob#read()
-// */
-// @TestTargetNew(
-// level = TestLevel.COMPLETE,
-// notes = "method test",
-// method = "read",
-// args = {}
-// )
-// public void testRead() {
-// Blob b = new Blob();
-// try {
-// testBlob.read(null, 0, 0, 0);
-// fail("Read operation unsupported");
-// } catch (Throwable e) {
-// //ok
-// }
-// }
+ try {
+ assertNull(testBlob.getOutputStream());
+ } catch (Throwable e) {
+ //ok
+ }
+
+ }
}
diff --git a/libcore/sql/src/test/java/tests/SQLite/DatabaseTest.java b/libcore/sql/src/test/java/tests/SQLite/DatabaseTest.java
index 6cb2b4e..50eb6cc 100644
--- a/libcore/sql/src/test/java/tests/SQLite/DatabaseTest.java
+++ b/libcore/sql/src/test/java/tests/SQLite/DatabaseTest.java
@@ -16,6 +16,7 @@
package tests.SQLite;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -52,7 +53,9 @@
import SQLite.Vm;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.logging.Logger;
@TestTargetClass(Database.class)
public class DatabaseTest extends SQLiteTest {
@@ -62,7 +65,7 @@
*/
// protected final File dbFile = new File("sqliteTest.db");
//
-// private final String connectionURL = "jdbc:sqlite:/" + dbFile.getName();
+// private final String connectionURL = "jdbc:sqlite:/" + dbFile.getPath();
//
// private final String classname = "SQLite.JDBCDriver";
//
@@ -78,34 +81,37 @@
private static final int numOfRecords = 30;
- protected void setUp() throws java.lang.Exception {
+ public void setUp() throws java.lang.Exception {
try {
super.setUp();
-// Class.forName(classname).newInstance();
-// conn = DriverManager.getConnection(connectionURL);
-// tracker = new ErrorTracker();
-//
-// statement = conn.createStatement();
+ assertNotNull("Could not establish DB connection",conn);
+ tracker = new ErrorTracker();
+
+ statement = conn.createStatement();
//Cleanup tables if necessary
+
DatabaseMetaData meta = conn.getMetaData();
+ assertNotNull(meta);
+ if (meta != null) {
ResultSet userTab = meta.getTables(null, null, null, null);
while (userTab.next()) {
String tableName = userTab.getString("TABLE_NAME");
this.statement.execute("drop table "+tableName);
}
-
+ }
// Create default test table
- statement = conn.createStatement();
+// statement = conn.createStatement();
statement.execute(DatabaseCreator.CREATE_TABLE_SIMPLE1);
+ statement.close();
try {
db = new Database();
- db.open(dbFile.getName(), 0);
+ db.open(dbFile.getPath(), 0);
db.busy_handler(null);
} catch (Exception e) {
- System.out.println("2: Error opening File: Dir "+dbFile.getPath()+" Name: "+dbFile.getName());
+ System.out.println("2: Error opening File: Dir "+dbFile.getPath()+" Name: "+dbFile.getPath());
} catch (java.lang.Exception e) {
System.err.println("Non SQLException "+e.getMessage());
}
@@ -117,17 +123,18 @@
}
public void tearDown() {
- super.tearDown();
+
try {
db.close();
}catch (Exception e) {
if (! (e.getMessage().equals("database already closed"))) {
- System.err.println("Error closing DB "+dbFile.getName());
+ System.err.println("Error closing DB "+dbFile.getPath());
}
}
// conn.close();
// dbFile.delete();
tracker.reset();
+ super.tearDown();
}
/**
@@ -145,16 +152,16 @@
try {
db.close();
db2 = new Database();
- db2.open(dbFile.getName(), 0);
+ db2.open(dbFile.getPath(), 0);
db2.close();
- db.open(dbFile.getName(), 0);
+ db.open(dbFile.getPath(), 0);
} catch (Exception e) {
fail("Database object could not be created "+e.getMessage());
e.printStackTrace();
}
//db is open
try {
- db2.open(dbFile.getName(), 0);
+ db2.open(dbFile.getPath(), 0);
db2.close();
} catch (Exception e) {
fail("Second Database object could not be created "+e.getMessage());
@@ -171,8 +178,7 @@
method = "finalize",
args = {}
)
- public void _testFinalize() {
- fail("Not yet implemented");
+ public void testFinalize() {
}
/**
@@ -187,7 +193,7 @@
public void testOpen() {
try {
db.close();
- db.open(dbFile.getName(), 0);
+ db.open(dbFile.getPath(), 0);
} catch (Exception e) {
fail("Database object could not be opened: " + e.getMessage());
e.printStackTrace();
@@ -195,8 +201,8 @@
// open second db while db1 still open
Database db2 = new Database();
try {
- db2.open(dbFile.getName(), 0);
- db2.open(dbFile.getName(), 0);
+ db2.open(dbFile.getPath(), 0);
+ db2.open(dbFile.getPath(), 0);
db2.close();
} catch (Exception e) {
fail("Database object could not be opened: " + e.getMessage());
@@ -223,7 +229,7 @@
* @tests Database#open_aux_file(String)
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.SUFFICIENT,
notes = "not supported",
method = "open_aux_file",
args = {java.lang.String.class}
@@ -253,7 +259,7 @@
e.printStackTrace();
}
try {
- db.open(dbFile.getName(),0);
+ db.open(dbFile.getPath(),0);
db.exec("select * from AUX_TABLE", null);
fail("Statement should fail");
} catch (Exception e) {
@@ -281,7 +287,7 @@
} catch (Exception e) {
assertTrue(e.getMessage().equals("database already closed"));
try {
- db.open(dbFile.getName(), 0);
+ db.open(dbFile.getPath(), 0);
} catch (Exception e1) {
fail("Database object could not be reopened after 'close': "
+ e.getMessage());
@@ -295,7 +301,7 @@
} catch (Exception e) {
assertTrue(e.getMessage().equals("database already closed"));
try {
- db.open(dbFile.getName(), 0);
+ db.open(dbFile.getPath(), 0);
} catch (Exception e1) {
fail("Database object could not be reopened after 'close': "
+ e.getMessage());
@@ -398,17 +404,20 @@
}
/**
+ * @throws Exception
* @tests {@link Database#interrupt()}
*/
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- notes = "How should this be tested?",
+ level = TestLevel.COMPLETE,
+ notes = "",
method = "interrupt",
args = {}
)
- public void _testInterrupt() {
+ @KnownFailure("Reason for failure unknown: Database should be locked. " +
+ "Specification of interrupt is scarce.")
+ public void testInterrupt() throws Exception {
ThreadPool threadPool = new ThreadPool(numThreads);
-
+
// initialization
ResultSet userTabs;
try {
@@ -428,41 +437,39 @@
fail("Error initializing test " + e.getMessage());
e.printStackTrace();
}
-
+
int id1 = numOfRecords - 3;
- threadPool.runTask(createTask1(id1, dbFile.getName(), tracker));
+ threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
+ // should not be able to do any other insertions since task 1 holds lock
int id2 = numOfRecords + 3;
- threadPool.runTask(createTask2Interrupt(id2, dbFile.getName(), tracker));
+ threadPool
+ .runTask(createTask2Interrupt(id2, dbFile.getPath(), tracker));
threadPool.join();
List<String> errors = tracker.getErrors();
- System.out.println("Last error: "+db.error_message());
+ System.out.println("Last error: " + db.error_message());
if (errors.size() > 0) {
-// assertEquals(errors.get(0),
-// db.error_string(Constants.SQLITE_LOCKED));
- for (String s: errors) {
- System.out.println("INTERRUPT Error: "+s);
-
- }
- fail("Should not have any errors with interrupt");
+ assertEquals(errors.get(0), db
+ .error_string(Constants.SQLITE_LOCKED));
+ for (String s : errors) {
+ Logger.global.info("INTERRUPT Error: " + s);
+ }
+
} else {
- System.out.println("INTERRUPT: No error happened");
+ fail("Should have one exception: database should be locked.");
}
-
+
// reset
- try {
- db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
- null);
- db.exec("delete from " + DatabaseCreator.TEST_TABLE3 + " where 1",
- null);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
-
+ db
+ .exec(
+ "delete from " + DatabaseCreator.TEST_TABLE1
+ + " where 1", null);
+ db
+ .exec(
+ "delete from " + DatabaseCreator.TEST_TABLE3
+ + " where 1", null);
}
@@ -475,23 +482,24 @@
method = "changes",
args = {}
)
- public void _testChanges() {
+ @KnownFailure("Returns wrong number for updates: returns value > 1 for select.")
+ public void testChanges() {
TableResult res = new TableResult();
try {
assertTrue(db.changes() == 0);
db.exec("INSERT INTO " + DatabaseCreator.SIMPLE_TABLE1
- + " VALUES(2, 5, 7)", null);
+ + " VALUES(2, 5, 7);", null);
int rows = (int) db.changes();
assertEquals(1,db.changes());
db.exec("update " + DatabaseCreator.SIMPLE_TABLE1
- + " set speed = 7, size= 5 where id = 2", null);
+ + " set speed = 7, size= 5 where id = 2;", null);
assertEquals(1,db.changes());
db.exec("select * from " + DatabaseCreator.SIMPLE_TABLE1, res);
assertEquals(0,db.changes());
db.exec("INSERT INTO " + DatabaseCreator.SIMPLE_TABLE1
- + " VALUES(8, 5, 7)", null);
- db.exec("drop table "+DatabaseCreator.SIMPLE_TABLE1, null);
- assertTrue(db.changes() > 1);
+ + " VALUES(8, 5, 7);", null);
+ db.exec("Update "+DatabaseCreator.SIMPLE_TABLE1+" set speed = 10;",null);
+ assertTrue(db.changes() > 2);
} catch (Exception e) {
fail("Could not get changes: " + e.getMessage());
e.printStackTrace();
@@ -499,24 +507,28 @@
}
/**
+ * @throws SQLException
+ * @throws Exception
* @tests {@link Database#busy_handler(BusyHandler)}
*/
@TestTargets({
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
- notes = "method test fails. Cannot be sure that exception is thrown wvery time.",
+ notes = "method test fails once in a while. Cannot be sure that exception is thrown every time.",
method = "busy_handler",
args = {BusyHandler.class}
),
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
- notes = "method test fails. Cannot be sure that exception is thrown every time.",
+ notes = "method test fails once in a while. Cannot be sure that exception is thrown every time.",
method = "busy",
clazz = BusyHandler.class,
args = {java.lang.String.class, int.class}
)
})
- public void _testBusy_handler() {
+ @KnownFailure("method test fails once in a while. "+
+ "Cannot be sure that exception is thrown in every test execution.")
+ public void testBusy_handler() throws SQLException, Exception {
TestBusyHandler bh = new TestBusyHandler();
db.busy_handler(bh);
int counter = 0;
@@ -542,19 +554,21 @@
e.printStackTrace();
}
-
+
// try {
// DatabaseCreator.fillTestTable1(conn, numOfRecords);
// set to fail immediately if table is locked.
// db.busy_handler(bh);
// db.busy_timeout(0);
+ try {
+ conn.setAutoCommit(false);
int id1 = numOfRecords - 3;
- threadPool.runTask(createTask1(id1, dbFile.getName(), tracker));
+ threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
int id2 = numOfRecords + 3;
- threadPool.runTask(createTask2(id2, dbFile.getName(), tracker));
+ threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
int oldID = 5;
int newID = 100;
- threadPool.runTask(createTask3(oldID, dbFile.getName(), newID,
+ threadPool.runTask(createTask3(oldID, dbFile.getPath(), newID,
tracker));
threadPool.join();
@@ -567,12 +581,11 @@
System.out.println("Round 2 Error: "+s);
}
} else {
- System.out.println("BUSY: No error happened");
+ fail("No error happened");
}
// reset
- try{
db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
null);
@@ -586,8 +599,8 @@
// threadPool = new ThreadPool(numThreads);
//
-// threadPool.runTask(createTask1(id1, dbFile.getName(), tracker));
-// threadPool.runTask(createTask2(id2, dbFile.getName(), tracker));
+// threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
+// threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
//
// threadPool.join();
//
@@ -622,31 +635,29 @@
// } catch (Exception e1) {
// e2.printStackTrace();
// }
- }
-
- try {
+ } finally {
+ conn.setAutoCommit(true);
db.exec(DatabaseCreator.DROP_TABLE1, null);
db.exec(DatabaseCreator.DROP_TABLE3, null);
- } catch (Exception e) {
- fail("Error in test cleanup" + e.getMessage());
- e.printStackTrace();
}
-
}
/**
+ * @throws Exception
+ * @throws SQLException
* @tests {@link Database#busy_timeout(int)}
*/
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
- notes = "method test fails. Cannot be sure that exception is thrown wvery time.",
+ notes = "test fails. Cannot be sure that exception is thrown every time.",
method = "busy_timeout",
args = {int.class}
)
- public void _testBusy_timeout() {
+ @KnownFailure("Database does not lock values")
+ public void testBusy_timeout() throws Exception, SQLException {
int counter = 0;
ThreadPool threadPool = new ThreadPool(numThreads);
-
+
// initialization
ResultSet userTabs;
try {
@@ -666,33 +677,35 @@
fail("Error initializing test " + e.getMessage());
e.printStackTrace();
}
-
-
+
+
+ // test run
try {
+ conn.setAutoCommit(false);
+
// DatabaseCreator.fillTestTable1(conn, numOfRecords);
// set to fail immediately if table is locked.
db.busy_handler(null);
db.busy_timeout(0);
int id1 = numOfRecords - 3;
- threadPool.runTask(createTask1(id1, dbFile.getName(), tracker));
+
+ threadPool.runTask(createTask2(id1, dbFile.getPath(), tracker));
int id2 = numOfRecords + 3;
- threadPool.runTask(createTask2(id2, dbFile.getName(), tracker));
+ threadPool.runTask(createTask1(id2, dbFile.getPath(), tracker));
int oldID = 5;
int newID = 100;
- threadPool.runTask(createTask3(oldID, dbFile.getName(), newID,
+ threadPool.runTask(createTask3(oldID, dbFile.getPath(), newID,
tracker));
threadPool.join();
-
- List<String> errors = tracker.getErrors();
- if (errors.size() > 0) {
-// assertEquals(errors.get(0),
-// db.error_string(Constants.SQLITE_LOCKED));
- assertEquals(errors.get(0), "database is locked");
- } else {
- fail("Error in test setup");
- }
+ List<String> errors = tracker.getErrors();
+ assertTrue("No error occurred on DB but should have",errors.size() > 0);
+
+ assertEquals(errors.get(0),
+ db.error_string(Constants.SQLITE_LOCKED));
+ assertEquals(errors.get(0), "database is locked");
+
// reset
db.exec("delete from " + DatabaseCreator.TEST_TABLE1 + " where 1",
@@ -706,22 +719,19 @@
tracker.reset();
threadPool = new ThreadPool(numThreads);
- threadPool.runTask(createTask1(id1, dbFile.getName(), tracker));
- threadPool.runTask(createTask2(id2, dbFile.getName(), tracker));
+ threadPool.runTask(createTask1(id1, dbFile.getPath(), tracker));
+ threadPool.runTask(createTask2(id2, dbFile.getPath(), tracker));
threadPool.join();
errors = tracker.getErrors();
if (errors.size() > 0) {
- // assertEquals(errors.get(0),
- // db.error_string(Constants.SQLITE_LOCKED));
fail("busy timeout should prevent from lock exception!");
for (String s: errors) {
System.out.println("Round 2 Error"+s);
}
} else {
// ok
- System.out.println("No Error!");
}
@@ -735,24 +745,12 @@
e1.printStackTrace();
}
e.printStackTrace();
-// } catch (SQLException e2) {
-// System.out.println("Error in test setup "+e2.toString());
-// try {
-// db.get_table("select * from "+DatabaseCreator.TEST_TABLE1,null).
-// toString();
-// } catch (Exception e1) {
-// e2.printStackTrace();
-// }
- }
-
- try {
+ } finally {
+ conn.setAutoCommit(true);
+ // cleanup
db.exec(DatabaseCreator.DROP_TABLE1, null);
db.exec(DatabaseCreator.DROP_TABLE3, null);
- } catch (Exception e) {
- fail("Error in test cleanup" + e.getMessage());
- e.printStackTrace();
}
-
}
/**
@@ -837,33 +835,33 @@
* @tests {@link Database#get_table(String, String[], TableResult)}
*/
@TestTargets({
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "method test",
- method = "get_table",
- args = {java.lang.String.class, java.lang.String[].class, TableResult.class}
- ),
- @TestTargetNew(
+ @TestTargetNew(
level = TestLevel.COMPLETE,
notes = "method test",
- method = "toString",
- clazz = TableResult.class,
- args = {}
+ method = "get_table",
+ args = {java.lang.String.class, java.lang.String[].class, TableResult.class}
),
- @TestTargetNew(
+ @TestTargetNew(
level = TestLevel.COMPLETE,
notes = "method test",
- method = "types",
+ method = "toString",
clazz = TableResult.class,
- args = {String[].class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "method test",
- method = "TableResult",
- clazz = TableResult.class,
- args = {}
- ),
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "method test",
+ method = "types",
+ clazz = TableResult.class,
+ args = {String[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "method test",
+ method = "TableResult",
+ clazz = TableResult.class,
+ args = {}
+ ),
@TestTargetNew(
level = TestLevel.NOT_NECESSARY,
notes = "method test",
@@ -871,20 +869,20 @@
clazz = TableResult.class,
args = {String[].class}
),
- @TestTargetNew(
- level = TestLevel.NOT_NECESSARY,
- notes = "method test",
- method = "newrow",
- clazz = TableResult.class,
- args = {String[].class}
- ),
- @TestTargetNew(
- level = TestLevel.NOT_NECESSARY,
- notes = "method test",
- method = "clear",
- clazz = TableResult.class,
- args = {}
- )
+ @TestTargetNew(
+ level = TestLevel.NOT_NECESSARY,
+ notes = "method test",
+ method = "newrow",
+ clazz = TableResult.class,
+ args = {String[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.NOT_NECESSARY,
+ notes = "method test",
+ method = "clear",
+ clazz = TableResult.class,
+ args = {}
+ )
})
public void testGet_tableStringStringArrayTableResult() {
@@ -960,15 +958,16 @@
args = {}
)
public void testDbversion() {
+ String verNo = "";
try {
- String verNo = db.dbversion();
+ verNo = db.dbversion();
db.close();
assertEquals(db.dbversion(),"unknown");
- db.open(dbFile.getName(), 0);
+ db.open(dbFile.getPath(), 0);
assertEquals(verNo,db.dbversion());
} catch (Exception e) {
try {
- db.open(dbFile.getName(), 0);
+ db.open(dbFile.getPath(), 0);
} catch (Exception e1) {
fail("error in db setup "+e.getMessage());
e.printStackTrace();
@@ -977,6 +976,8 @@
e.printStackTrace();
}
+ assertTrue(Integer.parseInt(verNo.substring(0, 1))>= 3 );
+
}
/**
@@ -990,10 +991,10 @@
args = {java.lang.String.class, int.class, Function.class}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "method test",
- method = "create_function",
- args = {java.lang.String.class, int.class, Function.class}
+ level = TestLevel.COMPLETE,
+ notes = "method test",
+ method = "create_function",
+ args = {java.lang.String.class, int.class, Function.class}
)
})
public void testCreate_function() {
@@ -1031,37 +1032,32 @@
args = {java.lang.String.class, int.class, Function.class}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "method test",
- method = "trace",
- clazz = Trace.class,
- args = {String.class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "method test",
- method = "step",
- clazz = Function.class,
- args = {FunctionContext.class, String[].class}
+ level = TestLevel.COMPLETE,
+ notes = "method test",
+ method = "step",
+ clazz = Function.class,
+ args = {FunctionContext.class, String[].class}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "method test",
- method = "last_step",
- clazz = Function.class,
- args = {FunctionContext.class}
+ level = TestLevel.COMPLETE,
+ notes = "method test",
+ method = "last_step",
+ clazz = Function.class,
+ args = {FunctionContext.class}
),
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "method test",
- method = "function",
- clazz = Function.class,
- args = {FunctionContext.class, String[].class}
+ level = TestLevel.COMPLETE,
+ notes = "method test",
+ method = "function",
+ clazz = Function.class,
+ args = {FunctionContext.class, String[].class}
)
})
public void testCreate_aggregate() {
TestTrace t = new TestTrace();
+
MockFunction aggFunction = new MockFunction();
+
try {
db
.exec(
@@ -1073,7 +1069,15 @@
db.create_aggregate("myaggfunc", 1, aggFunction);
db.function_type("myaggfunc", Constants.SQLITE_TEXT);
db.exec("PRAGMA show_datatypes = on", null);
+
+ assertFalse(aggFunction.functionCalled);
+ assertFalse(aggFunction.stepCalled);
+ assertFalse(aggFunction.lastStepCalled);
db.exec("select myaggfunc(TEST.firstname) from TEST", t);
+ assertTrue(aggFunction.stepCalled);
+ assertTrue(aggFunction.lastStepCalled);
+ assertTrue(aggFunction.functionCalled);
+
assertEquals("James Fiona ",aggFunction.getAggValue());
db.exec("drop table TEST", null);
} catch (Exception e) {
@@ -1097,54 +1101,52 @@
}
/**
+ * @throws Exception
* @tests {@link Database#function_type(String, int)}
* This method does not make sense
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
- notes = "method test fails.",
+ notes = "Method does not make sense: for functions, return type is already set.",
method = "function_type",
args = {java.lang.String.class, int.class}
)
- public void _testFunction_type() {
+ public void testFunction_type() throws Exception {
double input = 1.0;
TableResult res = new TableResult();
Function sinFunc = (Function) new SinFunc();
- try {
- db.exec("PRAGMA show_datatypes = on", null);
- db.exec("create table TEST (res double)", null);
- db.exec("insert into TEST values (" + Double.toString(input) + ")",
- null);
-
- db.create_function("sin", 1, sinFunc);
- db.function_type("sin", Constants.SQLITE2_TEXT);
- res = db.get_table("select sin(res) from TEST WHERE res = "
- + Double.toString(input));
- for(String s: res.types) {
- System.out.println("DatabaseTest.testFunction_type()"+s);
- }
- db.function_type("sin", Constants.SQLITE2_TEXT);
- Stmt s = db.prepare("select sin(res) from TEST WHERE res = "
- + Double.toString(input));
- s.step();
-
-// fail("Return type is not Text");
+ db.exec("PRAGMA show_datatypes = on", null);
+ db.exec("create table TEST (res double)", null);
+ db.exec("insert into TEST values (" + Double.toString(input) + ")",
+ null);
+
+ db.create_function("sin", 1, sinFunc);
+ db.function_type("sin", Constants.SQLITE_NUMERIC);
+ res = db.get_table("select sin(res) from TEST WHERE res = "
+ + Double.toString(input));
+
+ String row[] = (String[]) res.rows.elementAt(0);
+ String val = row[0];
+ assertTrue("double".equalsIgnoreCase(res.types[0]));
+ assertSame(Math.round(Math.sin(input)), Math.round(Double.parseDouble(val)));
+
+ // function determines return type: test that Double type is returned.
+ db.function_type("sin", Constants.SQLITE_BLOB);
+ Stmt s = db.prepare("select sin(res) from TEST WHERE res = ?");
+ s.bind(1,input);
+ s.step();
+
+ res = db.get_table("select sin(res) from TEST WHERE res = "
+ + Double.toString(input));
+ assertTrue("double".equalsIgnoreCase(res.types[0]));
+ row = (String[]) res.rows.elementAt(0);
+ val = row[0];
+ assertSame(Math.round(Math.sin(input)), Math.round(Double.parseDouble(val)));
+
-
- // System.out.println(res.toString());
- // String row[] = (String[]) res.rows.elementAt(0);
- // String val = row[0];
- // System.out.println(db.get_table("select sin(1) from TEST"));
- // } catch (SQLException e) {
- // fail("Error happened creating function:"
- // + e.getMessage());
- // e.printStackTrace();
- } catch (Exception e) {
- fail("Error happened creating function:" + e.getMessage());
- e.printStackTrace();
- }
+
}
@@ -1174,17 +1176,19 @@
* @tests {@link Database#set_last_error(int)}
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "method test",
+ level = TestLevel.SUFFICIENT,
+ notes = "don't now which other errors may occur from black-box approach.",
method = "set_last_error",
args = {int.class}
)
- public void _testSet_last_error() {
+ public void testSet_last_error() {
assertEquals(db.last_error(), Constants.SQLITE_OK);
- //db.set_last_error(Constants.SQLITE_MISMATCH);
- //assertEquals(db.last_error(),Constants.SQLITE_MISMATCH);
- //db.set_last_error(Constants.SQLITE3_TEXT);
- //assertEquals(db.last_error(),Constants.SQLITE3_TEXT);
+
+ try {
+ db.exec("sel from test;", null);
+ } catch (Exception e) {
+ assertEquals(Constants.SQLITE_ERROR,db.last_error());
+ }
}
/**
@@ -1237,6 +1241,7 @@
}
/**
+ * @throws UnsupportedEncodingException
* @tests {@link Database#set_encoding(String)}
* Method unsupported? -> tests fail
*/
@@ -1246,7 +1251,9 @@
method = "set_encoding",
args = {java.lang.String.class}
)
- public void _testSet_encoding() {
+ @KnownFailure("ASCII encoding does not work: a UTF encoded val is returned. Spec is not sufficient. "
+ + "Might be that test impl is wrong or String constructor for the ASCII encoding.")
+ public void testSet_encoding() throws UnsupportedEncodingException {
String input = "\u00bfMa\u00f1ana\u003f"; // ?Manana?
TableResult res = new TableResult();
String refOutput = null;
@@ -1271,46 +1278,15 @@
e1.printStackTrace();
}
- // Default tests
- try {
- db.set_encoding("");
- fail("invalid input should fail");
- } catch (Exception e) {
- //ok
- }
-
- // Default tests
- try {
- db.set_encoding("UTF-16");
- db.exec("select * from encodingTest;", res);
- String[] encOutput1 = (String[]) res.rows.elementAt(0);
-
- db.set_encoding("US-ASCII");
- db.exec("select * from encodingTest;", res);
- String[] encOutput2 = (String[]) res.rows.elementAt(0);
-
- assertFalse(encOutput1[0].equals(encOutput2[0]));
- } catch (Exception e) {
- fail("Error setting the encoding." + e.getMessage());
- e.printStackTrace();
- }
-
- // tests for different encoding schemes
- // String[] charsetNames = { "ISO-8859-1","US-ASCII", "UTF-8",
- // "UTF-16","UTF-16BE", "UTF-16LE"
+ // tests for different encoding schemes
String[] charsetNames = {"UTF-8", "UTF-16", "UTF-16BE", "UTF-16LE"};
for (int i = 0; i < charsetNames.length; i++) {
try {
byte[] encInput = input.getBytes(charsetNames[i]);
db.set_encoding(charsetNames[i]);
- // stat.reset();
- // stat.bind(1, encInput);
- // stat.step();
db.exec("select * from encodingTest;", res);
String[] encOutput = (String[]) res.rows.elementAt(0);
- String inputAsString = new String(encInput);
- System.out.println(charsetNames[i] + " input: " + inputAsString
- + " output: " + encOutput[0]);
+ String inputAsString = new String(encInput,charsetNames[i]);
assertEquals(inputAsString, encOutput[0]);
} catch (Exception e4) {
fail("Error setting the encoding." + e4.getMessage());
@@ -1320,15 +1296,41 @@
e2.printStackTrace();
}
}
+
+ // Default tests
+ try {
+ db.set_encoding("UTF-16");
+ db.exec("select * from encodingTest;", res);
+ String[] encOutput1 = (String[]) res.rows.elementAt(0);
+ assertEquals("Got "+encOutput1[0]+" as UTF-16",input,encOutput1[0]);
+
+ db.set_encoding("US-ASCII");
+ db.exec("select * from encodingTest;", res);
+ String[] encOutput2 = (String[]) res.rows.elementAt(0);
+ assertEquals(new String(input.getBytes(),"US-ASCII"),encOutput2[0]);
+ } catch (Exception e) {
+ fail("Error setting the encoding." + e.getMessage());
+ e.printStackTrace();
+ }
+
+
// DB teardown
try {
stat.close();
- db.exec("delete from encodingTest where 1", null);
+ db.exec("delete from encodingTest", null);
// reset encoding
} catch (Exception e3) {
fail("Error in teardown of encoding environment");
e3.printStackTrace();
}
+
+ // Default tests
+ try {
+ db.set_encoding("");
+ fail("invalid input should fail");
+ } catch (Exception e) {
+ //ok
+ }
}
@@ -1351,7 +1353,9 @@
args = {int.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
)
})
- public void _testSet_authorizer() {
+ @KnownFailure("Callback never made for authorization. "+
+ "Results of private table are returned withouth furhter checks.")
+ public void testSet_authorizer() {
TableResult resPriv = null;
TableResult resPub = null;
@@ -1372,22 +1376,22 @@
// db.exec("delete from public_table where 1", null);
// TableResult emptyPubTable = db.exec("select * from public");
- // set Authorizer (positive case)
+ // set Authorizer (positive case): denies private table
AuthorizerCallback cb = new AuthorizerCallback();
db.set_authorizer(cb);
- System.out.println("Auth set.");
//select
db.exec("select * from private_table", cb);
- fail("authorization failed");
-
-// TableResult res = db.get_table("select * from private_table");
-// assertEquals(emptyTable.toString(),res.toString());
-// assertFalse(emptyTable.equals(resPriv));
-//
-// res = db.get_table("select * from public_table");
-// assertEquals(resPub,res);
+ assertTrue(cb.wasCalled());
+ /*
+ TableResult res = db.get_table("select * from private_table");
+ assertEquals(emptyTable.toString(),res.toString());
+ assertFalse(emptyTable.equals(resPriv));
+
+ res = db.get_table("select * from public_table");
+ assertEquals(resPub,res);
+ */
} catch (Exception e) {
fail("Error testing authorization: "+e.getMessage());
}
@@ -1420,10 +1424,12 @@
public void testTrace() {
String stmt = "create table TEST (res double);";
TestTrace t = new TestTrace();
+ assertFalse(t.traceCalled);
assertEquals(db.last_error(),Constants.SQLITE_OK);
try {
db.trace((Trace) t);
db.exec(stmt,t);
+ assertTrue(t.traceCalled);
assertEquals(t.getTrace(),stmt);
} catch (Exception e) {
fail("Error testing traces: "+e.getMessage());
@@ -1558,82 +1564,76 @@
}
/**
+ * @throws Exception
+ * @throws java.lang.Exception
* @tests {@link Database#open_blob(String, String, String, long, boolean)}
* unsupported
*/
- @TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
- notes = "",
+ notes = "not supported",
method = "open_blob",
args = {java.lang.String.class, java.lang.String.class, java.lang.String.class, long.class, boolean.class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "",
- method = "Exception",
- clazz = Exception.class,
- args = {java.lang.String.class}
- )
- })
- public void _testOpen_blob() {
+ )
+ @KnownFailure("not supported")
+ public void testOpen_blob() throws Exception, java.lang.Exception {
Stmt statement2;
Blob blobInput = new Blob();
// Create test input Blob
- //File resources = Support_Resources.createTempFolder();
InputStream inStream = null;
- byte[] in = new byte[20];
- try {
- db.exec("create table TEST (res blob)",null);
- inStream = Class.forName(this.getClass().getName()).getResourceAsStream("/blob.c");
- assertNotNull(inStream);
- inStream.read(in);
- inStream.close();
- } catch (NullPointerException e) {
- fail("Error reading file"+e.getMessage());
- } catch (java.lang.Exception e2) {
- fail("Error reading from input "+e2.getMessage());
- }
+ byte[] in = {(byte) 1, (byte) 2, (byte) 3, (byte) 4};
+
+ // setup test input
+ db.exec("create table TEST (res blob)",null);
+ inStream = Class.forName(this.getClass().getName()).getResourceAsStream("/blob.c");
+ assertNotNull(inStream);
+
// insert byte array in db
try {
- statement2 = db.prepare("insert into TEST(res) values (?)");
- statement2.bind(1,in);
- statement2.step();
- statement2.close();
+ statement2 = db.prepare("insert into TEST(res) values (?)");
+ statement2.bind(1, in);
+ statement2.step();
+ statement2.close();
} catch (Exception e) {
- fail("Error happened inserting blob"+e.getMessage());
+ fail("Error happened inserting blob" + e.getMessage());
e.printStackTrace();
}
- byte[] output = new byte[20];
+
+ // read from db
+ byte[] output = null;
Blob blob;
- try {
- blob = db.open_blob(dbFile.getName(), "TEST", "res", 1, true);
+
+ blob = db.open_blob(dbFile.getPath(), "TEST", "res", 1, true);
if (blob == null) {
fail("Blob could not be retrieved");
}
- OutputStream os = blob.getOutputStream();
- os.write(output);
- os.close();
- blob.close();
//read from blob and compare values (positive case)
InputStream is = blob.getInputStream();
- assertEquals(in,is);
- //read from blob and compare values (negative case)
+
+ int i = 0;
+ int outByte = 0;
+ byte[] out = new byte[4];
+ while ((outByte = is.read()) > -1) {
+ out[i] = (byte) outByte;
+ i++;
+ }
+ is.close();
+
+ blob.close();
+
+ assertTrue(Arrays.equals(in, out));
+
+ //read from blob and compare values (default blob)
db.exec("insert into TEST values(zeroblob(128))", null);
- Blob blob2 = db.open_blob(dbFile.getName(), "TEST", "res", 2, true);
- /*if (blob2 != null) {
- assertEquals(0, blob2.size);
- }*/
- } catch (Exception e) {
- assertEquals("Method opend_blob unsupported (sqlite 3)","unsupported", e.getMessage());
- } catch (IOException e2) {
- fail("error in setup: "+e2.getMessage());
- e2.printStackTrace();
- }
-
+ Blob blob2 = db.open_blob(dbFile.getPath(), "TEST", "res", 2, true);
+ is = blob2.getInputStream();
+ for (i = 0; i < 128; i++) {
+ assertEquals(0, is.read());
+ }
+ is.close();
}
/**
@@ -1750,11 +1750,14 @@
private StringBuffer buf = new StringBuffer();
+ public boolean traceCalled = false;
+
public String getTrace() {
return buf.toString();
}
public void trace(String stmt) {
+ traceCalled = true;
buf.append(stmt);
}
@@ -1784,9 +1787,9 @@
public int authorize(int action, String arg1, String arg2, String arg3,
String arg4) {
- System.out.println("Authorize "+action+" "+arg1+" "+arg2+" "+arg3+" "+arg4+" ");
+ Logger.global.info("DB authorization callback "+action+" "+arg1+" "+arg2+" "+arg3+" "+arg4+" ");
this.isAuthorizing = true;
- if (action != Constants.SQLITE_SELECT || arg1 == "private_table" ) {
+ if (action != Constants.SQLITE_SELECT || arg1.contains("private_table")) {
return Constants.SQLITE_DENY;
} else {
return Constants.SQLITE_OK;
@@ -1933,14 +1936,12 @@
+ ", '" + value + "', " + id + ", " + id + ")";
db.exec(insertQuery, null);
} catch (Exception e) {
- // errorTracker.registerException(this, e);
- db.interrupt();
-
+ errorTracker.registerException(this, e);
try {
+ db.interrupt();
db.exec("DELETE FROM " + DatabaseCreator.SIMPLE_TABLE1
+ " WHERE id=" + id, null);
} catch (Exception e1) {
- errorTracker.reset();
errorTracker.registerException(this, e1);
}
}
diff --git a/libcore/sql/src/test/java/tests/SQLite/ExceptionTest.java b/libcore/sql/src/test/java/tests/SQLite/ExceptionTest.java
index cc37c2a..fe86e8f 100644
--- a/libcore/sql/src/test/java/tests/SQLite/ExceptionTest.java
+++ b/libcore/sql/src/test/java/tests/SQLite/ExceptionTest.java
@@ -16,24 +16,26 @@
package tests.SQLite;
+import SQLite.Database;
import SQLite.Exception;
+import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import junit.framework.TestCase;
-public class ExceptionTest extends TestCase {
+@TestTargetClass(SQLite.Exception.class)
+public class ExceptionTest extends SQLiteTest {
+
+ private Database db = null;
- public ExceptionTest(String name) {
- super(name);
- }
-
- protected void setUp() throws java.lang.Exception {
+ public void setUp() throws java.lang.Exception {
super.setUp();
+ db = new Database();
}
-
- protected void tearDown() throws java.lang.Exception {
+
+ public void tearDown() {
super.tearDown();
}
@@ -41,13 +43,18 @@
* @tests {@link Exception#Exception(String)}
*/
@TestTargetNew(
- level = TestLevel.TODO,
+ level = TestLevel.COMPLETE,
notes = "constructor test",
method = "Exception",
args = {java.lang.String.class}
)
public void testException() {
- fail("not yet implemented");
+ try {
+ db.open(dbFile.getName(), 0);
+ } catch (Exception e) {
+ assertNotNull(e);
+ assertNotNull(e.getMessage());
+ }
}
}
diff --git a/libcore/sql/src/test/java/tests/SQLite/FunctionContextTest.java b/libcore/sql/src/test/java/tests/SQLite/FunctionContextTest.java
index e07d7ca..1bb5cf5 100644
--- a/libcore/sql/src/test/java/tests/SQLite/FunctionContextTest.java
+++ b/libcore/sql/src/test/java/tests/SQLite/FunctionContextTest.java
@@ -16,7 +16,14 @@
package tests.SQLite;
+import SQLite.Database;
+import SQLite.Exception;
+import SQLite.Function;
import SQLite.FunctionContext;
+import SQLite.Stmt;
+import SQLite.TableResult;
+import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -24,133 +31,422 @@
import junit.framework.TestCase;
-@TestTargetClass(FunctionContext.class)
-public class FunctionContextTest extends TestCase {
-
- /**
- * @param name
- */
- public FunctionContextTest(String name) {
- super(name);
- }
+import java.io.UnsupportedEncodingException;
+import java.sql.SQLException;
+import java.sql.Statement;
- /* (non-Javadoc)
- * @see junit.framework.TestCase#setUp()
- */
- protected void setUp() throws java.lang.Exception {
- super.setUp();
-
- }
+import tests.support.DatabaseCreator;
+
+@TestTargetClass(FunctionContext.class)
+public class FunctionContextTest extends SQLiteTest {
- /**
- * Test method for {@link SQLite.FunctionContext#FunctionContext()}.
- */
- @TestTargetNew(
- level = TestLevel.TODO,
- notes = "constructor test",
- method = "FunctionContext",
- args = {}
- )
- public void testFunctionContext() {
- fail("Not yet implemented");
+ private Database db = null;
+
+ public void setUp() throws java.lang.Exception {
+ Statement st = null;
+ super.setUp();
+ db = new Database();
+ db.open(dbFile.getPath(), 0);
+ st = conn.createStatement();
+ st.execute(DatabaseCreator.CREATE_TABLE2);
+ st.execute(DatabaseCreator.CREATE_TABLE_SIMPLE1);
+ st.close();
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
- protected void tearDown() throws java.lang.Exception {
+ public void tearDown() {
super.tearDown();
}
/**
* Test method for {@link SQLite.FunctionContext#set_result(java.lang.String)}.
+ * @throws Exception
*/
@TestTargetNew(
- level = TestLevel.TODO,
- notes = "method test",
+ level = TestLevel.SUFFICIENT,
+ notes = "indirectly tested invoking function",
method = "set_result",
args = {java.lang.String.class}
)
- public void testSet_resultString() {
- fail("Not yet implemented");
+ public void testSet_resultString() throws Exception {
+ TestFCString testString = new TestFCString();
+ db.exec("insert into " + DatabaseCreator.TEST_TABLE2
+ + " (ftext) values ('TestInput')", null);
+ db.create_function("test", 1, testString);
+ TableResult res = db.get_table("select test(ftext) from "
+ + DatabaseCreator.TEST_TABLE2);
+ String row[] = (String[]) res.rows.elementAt(0);
+ String val = row[0];
+
+ assertEquals("TestInput", val);
}
/**
* Test method for {@link SQLite.FunctionContext#set_result(int)}.
+ * @throws Exception
*/
@TestTargetNew(
- level = TestLevel.TODO,
+ level = TestLevel.SUFFICIENT,
notes = "method test",
method = "set_result",
args = {int.class}
)
- public void testSet_resultInt() {
- fail("Not yet implemented");
+ public void testSet_resultInt() throws Exception {
+ TestFCInt testInt = new TestFCInt();
+ db.exec("insert into " + DatabaseCreator.SIMPLE_TABLE1
+ + " values (1,'" + testInt.intVal + "',3)", null);
+ db.create_function("testInt", 1, testInt);
+ TableResult res = db.get_table("select testInt(speed) from "
+ + DatabaseCreator.SIMPLE_TABLE1);
+ String row[] = (String[]) res.rows.elementAt(0);
+ String val = row[0];
+
+ assertEquals(testInt.intVal, Integer.parseInt(val));
}
/**
* Test method for {@link SQLite.FunctionContext#set_result(double)}.
+ * @throws Exception
*/
@TestTargetNew(
- level = TestLevel.TODO,
- notes = "method test",
+ level = TestLevel.SUFFICIENT,
+ notes = "indirectly tested",
method = "set_result",
args = {double.class}
)
- public void testSet_resultDouble() {
- fail("Not yet implemented");
+ public void testSet_resultDouble() throws Exception {
+ SinFunc testD = new SinFunc();
+ db.exec("insert into " + DatabaseCreator.TEST_TABLE2
+ + " (fdouble) values (" + testD.testDouble + ")", null);
+ db.create_function("testDouble", 1, testD);
+ TableResult res = db.get_table("select testDouble(fdouble) from "
+ + DatabaseCreator.TEST_TABLE2);
+ String row[] = (String[]) res.rows.elementAt(0);
+ String val = row[0];
+
+ assertEquals(testD.testDouble, Double.parseDouble(val));
+
+ assertTrue(testD.functionCalled);
}
/**
* Test method for {@link SQLite.FunctionContext#set_error(java.lang.String)}.
+ * @throws Exception
*/
@TestTargetNew(
- level = TestLevel.TODO,
+ level = TestLevel.COMPLETE,
notes = "method test",
method = "set_error",
args = {java.lang.String.class}
)
- public void testSet_error() {
- fail("Not yet implemented");
+ public void testSet_error() throws Exception {
+ TestFCError testError = new TestFCError();
+ SinFunc testD = new SinFunc();
+ db.exec("insert into " + DatabaseCreator.TEST_TABLE2
+ + " (fdouble) values (" + testD.testDouble + ")", null);
+ db.create_function("testError", 1, testError);
+
+ try {
+ TableResult res = db.get_table("select testError(fdouble) from "
+ + DatabaseCreator.TEST_TABLE2);
+ fail("Should get Exception");
+ } catch (Exception e) {
+ assertEquals("error in step", e.getMessage());
+ }
+
+ assertFalse(testD.functionCalled);
}
/**
* Test method for {@link SQLite.FunctionContext#set_result(byte[])}.
+ * @throws Exception
+ * @throws UnsupportedEncodingException
*/
@TestTargetNew(
- level = TestLevel.TODO,
+ level = TestLevel.COMPLETE,
notes = "method test",
method = "set_result",
args = {byte[].class}
)
- public void testSet_resultByteArray() {
- fail("Not yet implemented");
+ public void testSet_resultByteArray() throws Exception, UnsupportedEncodingException {
+ Stmt st = null;
+ TestFCByteArray testBinArrayFnc = new TestFCByteArray();
+ String expected = "";
+ expected = "X'" + getHexString(testBinArrayFnc.byteVal) + "'";
+
+ // setup
+ db.exec("create table testBinaryData (binVal BINARY) ;", null);
+
+ try {
+ st = db.prepare("insert into testBinaryData values (?)");
+ st.bind(1, testBinArrayFnc.byteVal);
+ st.step();
+
+
+ db.create_function("testBinArray", 1, testBinArrayFnc);
+ TableResult res = db
+ .get_table("select testBinArray(binVal) from testBinaryData");
+
+ String row[] = (String[]) res.rows.elementAt(0);
+ String val = row[0];
+
+ assertTrue(expected.equalsIgnoreCase(val));
+
+ assertTrue(testBinArrayFnc.functionCalled);
+
+ } finally {
+ //teardown
+ db.exec("drop table testBinaryData;", null);
+ }
}
/**
* Test method for {@link SQLite.FunctionContext#set_result_zeroblob(int)}.
+ * @throws Exception
+ * @throws UnsupportedEncodingException
*/
@TestTargetNew(
- level = TestLevel.TODO,
+ level = TestLevel.COMPLETE,
notes = "method test",
method = "set_result_zeroblob",
args = {int.class}
)
- public void testSet_result_zeroblob() {
- fail("Not yet implemented");
+ public void testSet_result_zeroblob() throws Exception,
+ UnsupportedEncodingException {
+ Stmt st = null;
+ TestFCZeroBlob testZeroBlobFnc = new TestFCZeroBlob();
+ byte[] byteVal = {(byte) 1, (byte) 2, (byte) 3};
+
+
+ // setup
+ db.exec("create table testBinaryData (binVal BINARY) ;", null);
+
+ try {
+ st = db.prepare("insert into testBinaryData values (?)");
+ st.bind(1, byteVal);
+ st.step();
+
+
+ db.create_function("testZeroBlob", 0, testZeroBlobFnc);
+ TableResult res = db
+ .get_table("select testZeroBlob() from testBinaryData");
+ TableResult res2 = db.get_table("select zeroblob("
+ + testZeroBlobFnc.numBytes + ") from testBinaryData");
+
+ String row[] = (String[]) res.rows.elementAt(0);
+ String val = row[0];
+
+ assertNotNull(val);
+
+ assertEquals(((String[]) res2.rows.elementAt(0))[0], val);
+ assertTrue(testZeroBlobFnc.functionCalled);
+
+ } finally {
+ // teardown
+ db.exec("drop table if exists testBinaryData;", null);
+ }
}
/**
* Test method for {@link SQLite.FunctionContext#count()}.
+ * @throws SQLException
+ * @throws Exception
*/
@TestTargetNew(
- level = TestLevel.TODO,
+ level = TestLevel.COMPLETE,
notes = "method test",
method = "count",
args = {}
)
- public void testCount() {
- fail("Not yet implemented");
+ @AndroidOnly("Test Method results in a segmentation fault.")
+ public void testCount() throws SQLException, Exception {
+ TestFCCount countTest = new TestFCCount();
+ int inputCount = 10;
+
+ assertFalse(countTest.functionCalled);
+
+ DatabaseCreator.fillTestTable2(conn, inputCount);
+ db.create_function("testCount", 0, countTest);
+ // the invokation of testCount leads to a Segmentation fault
+ /*
+ TableResult res = db
+ .get_table("select testCount() from "+DatabaseCreator.TEST_TABLE2);
+
+ String row[] = (String[]) res.rows.elementAt(0);
+ String val = row[0];
+
+ assertTrue(countTest.functionCalled);
+ assertEquals(inputCount,Integer.parseInt(val));
+ */
+
+ }
+
+ class TestFCError implements Function {
+ public boolean functionCalled = false;
+ public String errorMsg = "FunctionError";
+
+ public void function(FunctionContext fc, String args[]) {
+ functionCalled = true;
+ fc.set_error(errorMsg);
+ }
+
+ public void last_step(FunctionContext fc) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void step(FunctionContext fc, String[] args) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ class TestFCCount implements Function {
+ public boolean functionCalled = false;
+ public int noOfRows = 0;
+
+ public void function(FunctionContext fc, String args[]) {
+ functionCalled = true;
+ noOfRows = fc.count();
+ fc.set_result(noOfRows);
+ }
+
+ public void last_step(FunctionContext fc) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void step(FunctionContext fc, String[] args) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ class TestFCZeroBlob implements Function {
+ public int numBytes = 16;
+ public boolean functionCalled = false;
+
+ public void function(FunctionContext fc, String args[]) {
+ functionCalled = true;
+ fc.set_result_zeroblob(numBytes);
+ }
+
+ public void last_step(FunctionContext fc) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void step(FunctionContext fc, String[] args) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ class TestFCString implements Function {
+ public String testString = "TestString";
+ public boolean functionCalled;
+
+ public void function(FunctionContext fc, String args[]) {
+ assertNotNull(args);
+ functionCalled = true;
+ fc.set_result(args[0]);
+ }
+
+ public void last_step(FunctionContext fc) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void step(FunctionContext fc, String[] args) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ class TestFCInt implements Function {
+ public int intVal = Integer.MAX_VALUE;
+ public boolean functionCalled;
+
+ public void function(FunctionContext fc, String args[]) {
+ assertNotNull(args);
+ functionCalled = true;
+ fc.set_result(Integer.parseInt(args[0]));
+ }
+
+ public void last_step(FunctionContext fc) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void step(FunctionContext fc, String[] args) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ class TestFCByteArray implements Function {
+ public byte[] byteVal = {(byte) 1, (byte) 2, (byte) 3};
+ public boolean functionCalled;
+
+ public void function(FunctionContext fc, String args[]) {
+ assertNotNull(args);
+ functionCalled = true;
+ fc.set_result(args[0].getBytes());
+ }
+
+ public void last_step(FunctionContext fc) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void step(FunctionContext fc, String[] args) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ class SinFunc implements Function {
+
+ public Double testDouble = 3.0;
+ public boolean functionCalled = false;
+
+ public void function(FunctionContext fc, String args[]) {
+ Double d = new Double(args[0]);
+ functionCalled = true;
+ fc.set_result(d.doubleValue());
+ }
+
+ public void last_step(FunctionContext fc) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void step(FunctionContext fc, String[] args) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ static final byte[] HEX_CHAR_TABLE = {
+ (byte)'0', (byte)'1', (byte)'2', (byte)'3',
+ (byte)'4', (byte)'5', (byte)'6', (byte)'7',
+ (byte)'8', (byte)'9', (byte)'a', (byte)'b',
+ (byte)'c', (byte)'d', (byte)'e', (byte)'f'
+ };
+
+ public static String getHexString(byte[] raw)
+ throws UnsupportedEncodingException {
+ byte[] hex = new byte[2 * raw.length];
+ int index = 0;
+
+ for (byte b : raw) {
+ int v = b & 0xFF;
+ hex[index++] = HEX_CHAR_TABLE[v >>> 4];
+ hex[index++] = HEX_CHAR_TABLE[v & 0xF];
+ }
+ return new String(hex, "ASCII");
}
}
diff --git a/libcore/sql/src/test/java/tests/SQLite/JDBCDriverFunctionalTest.java b/libcore/sql/src/test/java/tests/SQLite/JDBCDriverFunctionalTest.java
index e872182..ed2c0b3 100644
--- a/libcore/sql/src/test/java/tests/SQLite/JDBCDriverFunctionalTest.java
+++ b/libcore/sql/src/test/java/tests/SQLite/JDBCDriverFunctionalTest.java
@@ -1,117 +1,110 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.SQLite;
-
-import SQLite.Exception;
-import SQLite.JDBCDriver;
-import dalvik.annotation.TestTargetClass;
-
-import java.io.File;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-
-/**
- * Tests the SQLite.JDBCDriver.
- */
-@TestTargetClass(JDBCDriver.class)
-public class JDBCDriverFunctionalTest extends AbstractSqlTest {
-
-
-
- /**
- * The SQLite db file.
- */
- private File dbFile = null;
-
- private String connectionURL = "empty";
-
- /**
- * Creates a new instance of this class.
- */
- public JDBCDriverFunctionalTest(String testName) {
- super(testName);
- }
-
- /**
- * Sets up an unit test by loading the SQLite.JDBCDriver, getting two
- * connections and calling the setUp method of the super class.
- * @throws Exception
- * @throws IllegalAccessException
- * @throws InstantiationException
- * @throws Exception
- * @throws Exception
- * @throws Exception
- * @throws Exception
- * @throws Exception
- */
- @Override
- protected void setUp() throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException, Exception { // the Exception class needs to be fully
- // qualified since there is an Exception
- // class in the SQLite package.
-
- super.setUp();
- }
-
- /**
- * Tears down an unit test by calling the tearDown method of the super class
- * and deleting the SQLite test db file.
- */
- @Override
- protected void tearDown() throws SQLException {
- super.tearDown();
- dbFile.delete();
- }
-
-
- @Override
- protected String getConnectionURL() {
- if (connectionURL.equals("empty")) {
- String tmp = System.getProperty("java.io.tmpdir");
- File tmpDir = new File(tmp);
- if (tmpDir.isDirectory()) {
- try {
- dbFile = File.createTempFile("JDBCDriverFunctionalTest",
- ".db", tmpDir);
- } catch (IOException e) {
- System.err.println("error creating temporary DB file.");
- }
- dbFile.deleteOnExit();
- } else {
- System.err.println("ctsdir does not exist");
- }
-
- connectionURL = "jdbc:sqlite:/" + dbFile.getPath();
-
- }
-
- return connectionURL;
- }
-
- @Override
- protected String getDriverClassName() {
- return "SQLite.JDBCDriver";
- }
-
- @Override
- protected int getTransactionIsolation() {
- return Connection.TRANSACTION_SERIALIZABLE;
- }
-
-
-}
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.SQLite;
+
+import SQLite.Exception;
+import SQLite.JDBCDriver;
+import dalvik.annotation.TestTargetClass;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+
+/**
+ * Tests the SQLite.JDBCDriver.
+ */
+@TestTargetClass(JDBCDriver.class)
+public class JDBCDriverFunctionalTest extends AbstractSqlTest {
+
+
+
+ /**
+ * The SQLite db file.
+ */
+ private File dbFile = null;
+
+ private String connectionURL = "empty";
+
+ /**
+ * Sets up an unit test by loading the SQLite.JDBCDriver, getting two
+ * connections and calling the setUp method of the super class.
+ * @throws Exception
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ * @throws Exception
+ * @throws Exception
+ * @throws Exception
+ * @throws Exception
+ * @throws Exception
+ */
+ @Override
+ public void setUp() throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException, Exception { // the Exception class needs to be fully
+ // qualified since there is an Exception
+ // class in the SQLite package.
+
+ super.setUp();
+ }
+
+ /**
+ * Tears down an unit test by calling the tearDown method of the super class
+ * and deleting the SQLite test db file.
+ */
+ @Override
+ protected void tearDown() throws SQLException {
+ super.tearDown();
+ dbFile.delete();
+ }
+
+
+ @Override
+ protected String getConnectionURL() {
+ if (connectionURL.equals("empty")) {
+ String tmp = System.getProperty("java.io.tmpdir");
+ File tmpDir = new File(tmp);
+ if (tmpDir.isDirectory()) {
+ try {
+ dbFile = File.createTempFile("JDBCDriverFunctionalTest",
+ ".db", tmpDir);
+ } catch (IOException e) {
+ System.err.println("error creating temporary DB file.");
+ }
+ dbFile.deleteOnExit();
+ } else {
+ System.err.println("java.io.tmpdir does not exist");
+ }
+
+ connectionURL = "jdbc:sqlite:/" + dbFile.getPath();
+
+ }
+
+ return connectionURL;
+ }
+
+ @Override
+ protected String getDriverClassName() {
+ return "SQLite.JDBCDriver";
+ }
+
+ @Override
+ protected int getTransactionIsolation() {
+ return Connection.TRANSACTION_SERIALIZABLE;
+ }
+
+
+}
diff --git a/libcore/sql/src/test/java/tests/SQLite/JDBCDriverTest.java b/libcore/sql/src/test/java/tests/SQLite/JDBCDriverTest.java
index a252cd4..c6fd677 100644
--- a/libcore/sql/src/test/java/tests/SQLite/JDBCDriverTest.java
+++ b/libcore/sql/src/test/java/tests/SQLite/JDBCDriverTest.java
@@ -33,17 +33,9 @@
@TestTargetClass(JDBCDriver.class)
public class JDBCDriverTest extends JDBCDriverFunctionalTest {
- public JDBCDriverTest(String testName) {
- super(testName);
- }
-
/**
* The SQLite db file.
*/
-// private final File dbFile = new File("sqliteTest.db");
-//
-// private final String connectionURL = "jdbc:sqlite:/" + dbFile.getName();
-
private JDBCDriver jDriver;
private Driver returnedDriver;
diff --git a/libcore/sql/src/test/java/tests/SQLite/SQLiteTest.java b/libcore/sql/src/test/java/tests/SQLite/SQLiteTest.java
index 195b013..0463dcb 100644
--- a/libcore/sql/src/test/java/tests/SQLite/SQLiteTest.java
+++ b/libcore/sql/src/test/java/tests/SQLite/SQLiteTest.java
@@ -23,13 +23,14 @@
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
+import java.util.logging.Logger;
public class SQLiteTest extends TestCase {
public static Connection conn;
public static File dbFile = null;
- public void setup() {
- String tmp = System.getProperty("ctsdir");
+ public void setUp() throws Exception {
+ String tmp = System.getProperty("java.io.tmpdir");
File tmpDir = new File(tmp);
try {
if (tmpDir.isDirectory()) {
@@ -41,16 +42,13 @@
Class.forName("SQLite.JDBCDriver").newInstance();
- if (dbFile.exists()) {
- System.out.println("SQLTest.getSQLiteConnection()File:"
- + dbFile.getName());
- }
- System.out.println("DB File created and Driver instantiated");
- System.out.println("Path "+ dbFile.getPath());
+ if (!dbFile.exists()) {
+ Logger.global.severe("DB file could not be created. Tests can not be executed.");
+ } else {
conn = DriverManager.getConnection("jdbc:sqlite:/"
+ dbFile.getPath());
- assertNotNull("Connection created ",conn);
-
+ }
+ assertNotNull("Error creating connection",conn);
} catch (IOException e) {
System.out.println("Problem creating test file in " + tmp);
} catch (SQLException e) {
diff --git a/libcore/sql/src/test/java/tests/SQLite/StmtTest.java b/libcore/sql/src/test/java/tests/SQLite/StmtTest.java
index fc611db..b60fe2b 100644
--- a/libcore/sql/src/test/java/tests/SQLite/StmtTest.java
+++ b/libcore/sql/src/test/java/tests/SQLite/StmtTest.java
@@ -16,21 +16,21 @@
package tests.SQLite;
+import SQLite.Constants;
import SQLite.Database;
import SQLite.Exception;
import SQLite.Stmt;
import SQLite.TableResult;
-import dalvik.annotation.TestTargets;
+import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
-import junit.framework.TestCase;
import tests.support.DatabaseCreator;
import tests.support.Support_SQL;
-import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
@@ -41,21 +41,71 @@
private static Stmt st = null;
-// private final File dbFile = new File("sqliteTest.db");
+ private static final String createAllTypes =
+ "create table type (" +
- protected void setUp() throws java.lang.Exception {
+ " BoolVal BOOLEAN," + " IntVal INT," + " LongVal LONG,"
+ + " Bint BIGINT," + " Tint TINYINT," + " Sint SMALLINT,"
+ + " Mint MEDIUMINT, " +
+
+ " IntegerVal INTEGER, " + " RealVal REAL, "
+ + " DoubleVal DOUBLE, " + " FloatVal FLOAT, "
+ + " DecVal DECIMAL, " +
+
+ " NumVal NUMERIC, " + " charStr CHAR(20), "
+ + " dateVal DATE, " + " timeVal TIME, " + " TS TIMESTAMP, "
+ +
+
+ " DT DATETIME, " + " TBlob TINYBLOB, " + " BlobVal BLOB, "
+ + " MBlob MEDIUMBLOB, " + " LBlob LONGBLOB, " +
+
+ " TText TINYTEXT, " + " TextVal TEXT, "
+ + " MText MEDIUMTEXT, " + " LText LONGTEXT, " +
+
+ " MaxLongVal BIGINT, MinLongVal BIGINT, "+
+
+ " validURL URL, invalidURL URL "+
+
+ ");";
+
+ static final String insertAllTypes =
+ "insert into type (BoolVal, IntVal, LongVal, Bint, Tint, Sint, Mint,"
+ + "IntegerVal, RealVal, DoubleVal, FloatVal, DecVal,"
+ + "NumVal, charStr, dateVal, timeVal, TS,"
+ + "DT, TBlob, BlobVal, MBlob, LBlob,"
+ + "TText, TextVal, MText, LText, MaxLongVal, MinLongVal,"
+ + " validURL, invalidURL"
+ + ") "
+ + "values (1, -1, 22, 2, 33,"
+ + "3, 1, 2, 3.9, 23.2, 33.3, 44,"
+ + "5, 'test string', '1799-05-26', '12:35:45', '2007-10-09 14:28:02.0',"
+ + "'1221-09-22 10:11:55', 1, 2, 3, 4,"
+ + "'Test text message tiny', 'Test text',"
+ + " 'Test text message medium', 'Test text message long', "
+ + Long.MAX_VALUE+", "+Long.MIN_VALUE+", "
+ + "null, null "+
+ ");";
+
+ static final String allTypesTable = "type";
+
+ public void setUp() throws java.lang.Exception {
super.setUp();
Support_SQL.loadDriver();
db = new Database();
- db.open(dbFile.getName(), 0);
+ db.open(dbFile.getPath(), 0);
db.exec(DatabaseCreator.CREATE_TABLE_SIMPLE1, null);
- DatabaseCreator.fillSimpleTable1(Support_SQL.getConnection());
-
- st = new Stmt();
+ DatabaseCreator.fillSimpleTable1(conn);
+
}
public void tearDown() {
- super.tearDown();
+ if (st != null) {
+ try {
+ st.close();
+ } catch (Exception e) {
+
+ }
+ }
try {
db.close();
Connection con = Support_SQL.getConnection();
@@ -66,7 +116,7 @@
} catch (SQLException e) {
fail("SQLException in tearDown: "+e.getMessage());
}
-
+ super.tearDown();
}
/**
@@ -78,7 +128,7 @@
method = "Stmt",
args = {}
)
- public void _testStmt() {
+ public void testStmt() {
Stmt st = new Stmt();
assertNotNull(st);
try {
@@ -107,8 +157,8 @@
method = "finalize",
args = {}
)
- public void _testFinalize() {
- fail("Not yet implemented");
+ public void testFinalize() {
+
}
/**
@@ -215,16 +265,40 @@
}
/**
+ * @throws Exception
* @tests {@link Stmt#reset()}
*/
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
+ level = TestLevel.COMPLETE,
notes = "method test",
method = "reset",
args = {}
)
- public void _testReset() {
- fail("Not yet implemented");
+ @BrokenTest("Tableresult is not cleared when resetting statement: "+
+ "Either complete spec or change implementation accordingly.")
+ public void testReset() throws Exception {
+ db.exec("create table TEST (res integer not null)", null);
+
+ st = db.prepare("insert into TEST values (:one);");
+ st.bind(1, 1);
+ st.step();
+
+ // verify that parameter is still bound
+ st.reset();
+ assertEquals(1,st.bind_parameter_count());
+ st.step();
+
+ TableResult count = db.get_table("select count(*) from TEST where res=1", null);
+
+ String[] row0 = (String[]) count.rows.elementAt(0);
+ assertEquals(2, Integer.parseInt(row0[0]));
+
+ //Verify that rest (tableResult) is cleared
+ st = db.prepare("select * from TEST;");
+ st.step();
+ assertEquals(1, st.column_count());
+ st.reset();
+ assertEquals(0,st.column_count());
}
/**
@@ -578,7 +652,7 @@
* @tests {@link Stmt#bind_zeroblob(int, int)}
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.NOT_FEASIBLE,
notes = "not supported",
method = "bind_zeroblob",
args = {int.class, int.class}
@@ -720,16 +794,47 @@
}
/**
+ * @throws Exception
* @tests {@link Stmt#column_int(int)}
*/
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
+ level = TestLevel.COMPLETE,
notes = "method test",
method = "column_int",
args = {int.class}
)
- public void _testColumn_int() {
- fail("Not yet implemented");
+ public void testColumn_int() throws Exception {
+ db.exec(createAllTypes, null);
+ db.exec(insertAllTypes, null);
+
+ int columnObjectCastFromLong;
+ Object columnObject = null;
+ int intColumn = 0;
+ String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
+
+ st = db.prepare(selectStmt);
+ st.step();
+ // select 'speed' value
+ columnObject = st.column(1);
+ intColumn = st.column_int(1);
+ assertNotNull(intColumn);
+
+ assertTrue("Integer".equalsIgnoreCase(st.column_decltype(1)));
+ int stSpeed = Integer.parseInt(columnObject.toString());
+ assertNotNull(stSpeed);
+ assertEquals( intColumn, stSpeed);
+ assertEquals(10,stSpeed);
+
+ selectStmt = "select TextVal from "+allTypesTable;
+
+ st = db.prepare(selectStmt);
+ st.step();
+ // select double value
+ try {
+ st.column_int(0);
+ } catch (Exception e) {
+ //ok
+ }
}
/**
@@ -747,7 +852,6 @@
long longColumn = 0;
try {
String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
- TableResult res = db.get_table(selectStmt);
st = db.prepare(selectStmt);
st.step();
columnObject = st.column(1);
@@ -779,75 +883,219 @@
}
/**
+ * @throws Exception
* @tests {@link Stmt#column_double(int)}
*/
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
+ level = TestLevel.COMPLETE,
notes = "method test",
method = "column_double",
args = {int.class}
)
- public void _testColumn_double() {
- fail("Not yet implemented");
+ public void testColumn_double() throws Exception {
+ db.exec(createAllTypes, null);
+ db.exec(insertAllTypes, null);
+
+ Object columnObject = null;
+ double doubleColumn = 0;
+ double actualVal = 23.2;
+ String selectStmt = "select DoubleVal from "+allTypesTable;
+
+ st = db.prepare(selectStmt);
+ st.step();
+ // select double value
+ doubleColumn = st.column_double(0);
+ assertNotNull(doubleColumn);
+
+ assertTrue("DOUBLE".equalsIgnoreCase(st.column_decltype(0)));
+ assertNotNull(doubleColumn);
+ assertEquals( actualVal, doubleColumn);
+
+ // Exception test
+ selectStmt = "select dateVal from "+allTypesTable;
+
+ st = db.prepare(selectStmt);
+ st.step();
+ // select double value
+ try {
+ st.column_double(0);
+ } catch (Exception e) {
+ //ok
+ }
+
+
}
/**
+ * @throws Exception
* @tests {@link Stmt#column_bytes(int)}
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.NOT_FEASIBLE,
notes = "not supported",
method = "column_bytes",
args = {int.class}
)
- public void testColumn_bytes() {
+ public void testColumn_bytes() throws Exception {
+
+ db.exec("create table B(id integer primary key, val blob)",null);
+ db.exec("insert into B values(1, zeroblob(128))", null);
+ st = db.prepare("select val from B where id = 1");
+ assertTrue(st.step());
try {
- st.column_bytes(1);
+ st.column_bytes(0);
} catch (Exception e) {
assertEquals("unsupported", e.getMessage());
}
}
/**
+ * @throws Exception
* @tests {@link Stmt#column_string(int)}
*/
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
+ level = TestLevel.COMPLETE,
notes = "method test",
method = "column_string",
args = {int.class}
)
- public void _testColumn_string() {
- fail("Not yet implemented");
+ public void testColumn_string() throws Exception {
+ db.exec(createAllTypes, null);
+ db.exec(insertAllTypes, null);
+
+ Object columnObject = null;
+ String stringColumn = "";
+ String actualVal = "test string";
+ String selectStmt = "select charStr from "+allTypesTable;
+
+ st = db.prepare(selectStmt);
+ st.step();
+ // select string value
+ stringColumn = st.column_string(0);
+ assertNotNull(stringColumn);
+
+ assertTrue("CHAR(20)".equalsIgnoreCase(st.column_decltype(0)));
+ assertNotNull(stringColumn);
+ assertEquals( actualVal, stringColumn);
+
+ // Exception test
+ selectStmt = "select DoubleVal from "+allTypesTable;
+
+ st = db.prepare(selectStmt);
+ st.step();
+ // select double value
+ try {
+ st.column_string(0);
+ } catch (Exception e) {
+ //ok
+ }
}
/**
+ * @throws Exception
* @tests {@link Stmt#column_type(int)}
*/
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
+ level = TestLevel.SUFFICIENT,
notes = "method test",
method = "column_type",
args = {int.class}
)
- public void _testColumn_type() {
- fail("Not yet implemented");
+ @AndroidOnly("For numeric, float and blob wrong type is returned")
+ public void testColumn_type() throws Exception {
+ db.exec(createAllTypes, null);
+ db.exec(insertAllTypes, null);
+ st = db.prepare("select * from " + allTypesTable);
+ st.step();
+
+ // Exception test
+ try {
+ st.column_type(100);
+ } catch (Exception e) {
+ // ok
+ }
+
+ /*
+ Dictionary
+
+ public static final int SQLITE_INTEGER = 1;
+ public static final int SQLITE_FLOAT = 2;
+ public static final int SQLITE_BLOB = 4;
+ public static final int SQLITE_NULL = 5;
+ public static final int SQLITE3_TEXT = 3;
+ public static final int SQLITE_NUMERIC = -1;
+ */
+
+ assertEquals(Constants.SQLITE3_TEXT, st.column_type(23)); // ok TEXT
+ assertEquals(Constants.SQLITE3_TEXT, st.column_type(13)); // CHAR(20)
+
+ assertEquals(Constants.SQLITE_FLOAT, st.column_type(8));
+ assertEquals(Constants.SQLITE_FLOAT, st.column_type(9));
+ assertEquals(Constants.SQLITE_FLOAT, st.column_type(10)); // FLOAT
+
+ for (int i = 0; i < 8; i++) {
+ assertEquals("Expected Integer at position " + i,
+ Constants.SQLITE_INTEGER, st.column_type(i));
+ }
+
+ assertEquals(Constants.SQLITE_NULL, st.column_type(28));
+ assertEquals(Constants.SQLITE_NULL, st.column_type(29));
+
+ // Failing tests
+ assertTrue("NUMERIC".equalsIgnoreCase(st.column_decltype(12)));
+ assertEquals(Constants.SQLITE_NUMERIC, st.column_type(12)); // NUMERIC
+ // -> got
+ // INTEGER
+
+ assertTrue("FLOAT".equalsIgnoreCase(st.column_decltype(11)));
+ assertEquals(Constants.SQLITE_FLOAT, st.column_type(11)); // FLOAT ->
+ // got INTEGER
+ assertTrue("BLOB".equalsIgnoreCase(st.column_decltype(19)));
+ assertEquals(Constants.SQLITE_BLOB, st.column_type(19)); // Blob got
+ // INTEGER
+
}
/**
+ * @throws Exception
* @tests {@link Stmt#column_count() )}
*/
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
+ level = TestLevel.COMPLETE,
notes = "method test",
method = "column_count",
args = {}
)
- public void _testColumn_count() {
- fail("Not yet implemented");
+ @AndroidOnly("Wrong value is returned in case of a prepared statment to "+
+ "which a '*' bound ")
+ public void testColumn_count() throws Exception {
+
+ String selectStmt = "select * from "+DatabaseCreator.SIMPLE_TABLE1;
+ st = db.prepare(selectStmt);
+
+ assertEquals(3, st.column_count());
+
+ st.step();
+ int columnCount = st.column_count();
+ assertNotNull(columnCount);
+ assertEquals( 3, columnCount);
+
+ // actual prepared statement
+ selectStmt = "select ? from "+DatabaseCreator.SIMPLE_TABLE1;
+ st = db.prepare(selectStmt);
+
+ assertEquals(3, st.column_count());
+
+ st.bind(1, "*");
+ st.step();
+ columnCount = st.column_count();
+ assertNotNull(columnCount);
+ assertEquals( 3, columnCount);
+
}
/**
+ * @throws Exception
* @tests {@link Stmt#column(int) )}
*/
@TestTargetNew(
@@ -856,7 +1104,7 @@
method = "column",
args = {int.class}
)
- public void testColumn() {
+ public void testColumn() throws Exception {
Object columnObject = null;
int columnObjectCastFromLong;
int intColumn = 0;
@@ -905,19 +1153,25 @@
*/
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
- notes = "method test",
+ notes = "not supported",
method = "column_table_name",
args = {int.class}
)
- public void _testColumn_table_name() {
- fail("Not yet implemented");
+ public void testColumn_table_name() {
+ try {
+ st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1);
+ String name = st.column_table_name(1);
+ fail("Function is now supported.");
+ } catch (Exception e) {
+ assertEquals("unsupported", e.getMessage());
+ }
}
/**
* @tests {@link Stmt#column_database_name(int)}
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.NOT_FEASIBLE,
notes = "not supported",
method = "column_database_name",
args = {int.class}
@@ -927,7 +1181,7 @@
st = db.prepare("insert into " + DatabaseCreator.SIMPLE_TABLE1
+ " values (:one,:two,:three)");
String name = st.column_database_name(1);
- fail("test fails");
+ fail("Function is now supported.");
} catch (Exception e) {
assertEquals("unsupported", e.getMessage());
}
@@ -935,16 +1189,66 @@
}
/**
+ * @throws Exception
* @tests {@link Stmt#column_decltype(int)}
*/
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
+ level = TestLevel.SUFFICIENT,
notes = "method test",
method = "column_decltype",
args = {int.class}
)
- public void _testColumn_decltype() {
- fail("Not yet implemented");
+ public void testColumn_decltype() throws Exception {
+ db.exec(createAllTypes, null);
+ db.exec(insertAllTypes, null);
+ st = db.prepare("select * from " + allTypesTable);
+ st.step();
+
+ // Exception test
+ try {
+ st.column_decltype(100);
+ } catch (Exception e) {
+ // ok
+ }
+
+ assertTrue(st.column_decltype(0), "BOOLEAN".equalsIgnoreCase(st
+ .column_decltype(0)));
+ assertTrue(st.column_decltype(1), "INT".equalsIgnoreCase(st
+ .column_decltype(1)));
+ assertTrue(st.column_decltype(2), "LONG".equalsIgnoreCase(st
+ .column_decltype(2)));
+ assertTrue(st.column_decltype(3), "BIGINT".equalsIgnoreCase(st
+ .column_decltype(3)));
+ assertTrue(st.column_decltype(4), "TINYINT".equalsIgnoreCase(st
+ .column_decltype(4)));
+ assertTrue(st.column_decltype(5), "SMALLINT".equalsIgnoreCase(st
+ .column_decltype(5)));
+ assertTrue(st.column_decltype(6), "MEDIUMINT".equalsIgnoreCase(st
+ .column_decltype(6)));
+ assertTrue(st.column_decltype(7), "INTEGER".equalsIgnoreCase(st
+ .column_decltype(7)));
+ assertTrue(st.column_decltype(8), "REAL".equalsIgnoreCase(st
+ .column_decltype(8)));
+ assertTrue(st.column_decltype(9), "DOUBLE".equalsIgnoreCase(st
+ .column_decltype(9)));
+ assertTrue(st.column_decltype(10), "FLOAT".equalsIgnoreCase(st
+ .column_decltype(10)));
+ assertTrue(st.column_decltype(11), "DECIMAL".equalsIgnoreCase(st
+ .column_decltype(11)));
+ assertTrue(st.column_decltype(12), "NUMERIC".equalsIgnoreCase(st
+ .column_decltype(12)));
+ assertTrue(st.column_decltype(13), "CHAR(20)".equalsIgnoreCase(st
+ .column_decltype(13)));
+
+ assertTrue(st.column_decltype(19), "BLOB".equalsIgnoreCase(st
+ .column_decltype(19)));
+
+ assertTrue(st.column_decltype(23), "TEXT".equalsIgnoreCase(st
+ .column_decltype(23)));
+ assertTrue(st.column_decltype(28), "URL".equalsIgnoreCase(st
+ .column_decltype(28)));
+ assertTrue(st.column_decltype(29), "URL".equalsIgnoreCase(st
+ .column_decltype(29)));
}
/**
@@ -952,11 +1256,17 @@
*/
@TestTargetNew(
level = TestLevel.NOT_FEASIBLE,
- notes = "method test",
+ notes = "not supported",
method = "column_origin_name",
args = {int.class}
)
- public void _testColumn_origin_name() {
- fail("Not yet implemented");
+ public void testColumn_origin_name() {
+ try {
+ st = db.prepare("select * from " + DatabaseCreator.SIMPLE_TABLE1);
+ String name = st.column_origin_name(1);
+ fail("Function is now supported.");
+ } catch (Exception e) {
+ assertEquals("unsupported", e.getMessage());
+ }
}
}
diff --git a/libcore/sql/src/test/java/tests/java/sql/DatabaseMetaDataTest.java b/libcore/sql/src/test/java/tests/java/sql/DatabaseMetaDataTest.java
index 8476915..fe7b227 100755
--- a/libcore/sql/src/test/java/tests/java/sql/DatabaseMetaDataTest.java
+++ b/libcore/sql/src/test/java/tests/java/sql/DatabaseMetaDataTest.java
@@ -15,7 +15,6 @@
*/
package tests.java.sql;
-import dalvik.annotation.BrokenTest;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -933,12 +932,12 @@
* @tests java.sql.DatabaseMetaData#getNumericFunctions()
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.SUFFICIENT,
notes = "Test fails. Not implemented correctly. SQLException checking test fails",
method = "getNumericFunctions",
args = {}
)
- @BrokenTest("Not supported feature, Ticket 98. Broken because "+
+ @KnownFailure("Not supported feature, Ticket 98. Broken because "+
"NUMERIC_FUNCTIONS not complete. When fixed change to @KnownFailure")
public void test_getNumericFunctions() throws SQLException {
escapedFunctions(NUMERIC_FUNCTIONS, meta.getNumericFunctions());
@@ -1172,8 +1171,7 @@
method = "getStringFunctions",
args = {}
)
- @BrokenTest("not supported, complete STRING_FUNCTIONS"+
- " to complete test, Ticket 98")
+ @KnownFailure("not supported")
public void test_getStringFunctions() throws SQLException {
escapedFunctions(STRING_FUNCTIONS, meta.getStringFunctions());
@@ -1201,8 +1199,7 @@
method = "getSystemFunctions",
args = {}
)
- @BrokenTest("not supported, complete SYSTEM_FUNCTIONS"+
- " to complete test, Ticket 98")
+ @KnownFailure("not supported")
public void test_getSystemFunctions() throws SQLException {
escapedFunctions(SYSTEM_FUNCTIONS, meta.getSystemFunctions());
@@ -1345,8 +1342,7 @@
method = "getTimeDateFunctions",
args = {}
)
- @BrokenTest("not supported, complete TIMEDATE_FUNCTIONS"+
- " to complete test, Ticket 98.")
+ @KnownFailure("not supported")
public void test_getTimeDateFunctions() throws SQLException {
escapedFunctions(TIMEDATE_FUNCTIONS, meta.getTimeDateFunctions());
diff --git a/libcore/sql/src/test/java/tests/java/sql/SelectFunctionalityTest.java b/libcore/sql/src/test/java/tests/java/sql/SelectFunctionalityTest.java
index 53e6243..5c8f189 100755
--- a/libcore/sql/src/test/java/tests/java/sql/SelectFunctionalityTest.java
+++ b/libcore/sql/src/test/java/tests/java/sql/SelectFunctionalityTest.java
@@ -16,6 +16,7 @@
package tests.java.sql;
+import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
@@ -144,7 +145,7 @@
* from the table
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects all records from the table",
method = "executeQuery",
args = {java.lang.String.class}
@@ -193,7 +194,7 @@
* from the table using parametric query
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects all records from the table using parametric query",
method = "executeQuery",
args = {java.lang.String.class}
@@ -261,7 +262,7 @@
* table using subselect
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects records from the table using subselect",
method = "executeQuery",
args = {java.lang.String.class}
@@ -296,7 +297,7 @@
* from a few tables
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects records from a few tables",
method = "executeQuery",
args = {java.lang.String.class}
@@ -340,7 +341,7 @@
* from a table using union
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects records from a table using union",
method = "executeQuery",
args = {java.lang.String.class}
@@ -374,7 +375,7 @@
* records from a table using left join
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects records from a table using left join",
method = "executeQuery",
args = {java.lang.String.class}
@@ -411,7 +412,14 @@
*
* TODO RIGHT and FULL OUTER JOINs are not supported
*/
-/* public void test_SelectRightOuterJoin() throws SQLException {
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "tests right outer joins. RIGHT and FULL OUTER JOINs are not supported",
+ method = "executeQuery",
+ args = {java.lang.String.class}
+ )
+ @KnownFailure("not supported")
+ public void test_SelectRightOuterJoin() throws SQLException {
String sql = "SELECT distinct s.snum as ssnum, c.snum as ccnum FROM "
+ DatabaseCreator.CUSTOMERS_TABLE + " c right outer join "
+ DatabaseCreator.SALESPEOPLE_TABLE + " s on s.snum=c.snum";
@@ -437,13 +445,13 @@
value.isEmpty());
result.close();
}
-*/
+
/**
* @tests SelectFunctionalityTest#test_SelectGroupBy(). Selects records from
* a table using group by
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects records from a table using group by",
method = "executeQuery",
args = {java.lang.String.class}
@@ -476,7 +484,7 @@
* a table using order by
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects records from a table using order by",
method = "executeQuery",
args = {java.lang.String.class}
@@ -515,7 +523,7 @@
* from a table using distinct
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects records from a table using distinct",
method = "executeQuery",
args = {java.lang.String.class}
@@ -545,7 +553,7 @@
* records from a table using agregate functions
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects records from a table using agregate functions",
method = "executeQuery",
args = {java.lang.String.class}
@@ -570,11 +578,21 @@
}
private void func(String name, String query, int expected) {
+ int res = 0;
+ double resDouble = 0.0;
try {
ResultSet result = statement.executeQuery(query);
while (result.next()) {
- assertEquals("wrong value of " + name + " field", expected,
- result.getInt(name));
+ res = result.getInt(name);
+ if (res != 0 ) {
+ assertEquals(expected,res);
+ break;
+ }
+ // for Double: getInt not supported yet
+ resDouble = Double.parseDouble(result.getString(name));
+ res = (int) Math.rint(resDouble);
+ assertEquals(expected,res);
+
}
assertFalse("wrong size of result set", result.next());
result.close();
@@ -588,7 +606,7 @@
* a table using having
*/
@TestTargetNew(
- level = TestLevel.PARTIAL,
+ level = TestLevel.PARTIAL_COMPLETE,
notes = "Functionality test: Selects records from a table using having",
method = "executeQuery",
args = {java.lang.String.class}
diff --git a/libcore/sql/src/test/java/tests/sql/PreparedStatementTest.java b/libcore/sql/src/test/java/tests/sql/PreparedStatementTest.java
index e2d9909..68d5117 100755
--- a/libcore/sql/src/test/java/tests/sql/PreparedStatementTest.java
+++ b/libcore/sql/src/test/java/tests/sql/PreparedStatementTest.java
@@ -43,6 +43,7 @@
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
+import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
@@ -87,7 +88,8 @@
+ "'1221-09-22 10:11:55', 1, 2, 3, 4,"
+ "'Test text message tiny', 'Test text message', 'Test text message medium', 'Test text message long');" };
- public void createTables() {
+ public void setUp() {
+ super.setUp();
Statement st = null;
try {
st = conn.createStatement();
@@ -104,7 +106,7 @@
}
}
- public void clearTables() {
+ public void tearDown() {
Statement st = null;
try {
st = conn.createStatement();
@@ -117,6 +119,7 @@
} catch (SQLException ee) {
}
}
+ super.tearDown();
}
/**
@@ -157,7 +160,7 @@
}
}
} catch (SQLException e) {
- fail("SQLException is thrown");
+ fail("SQLException is thrown "+e.getMessage());
} finally {
try {
ps.close();
@@ -201,25 +204,29 @@
notes = "",
method = "execute",
args = {}
- )
+ )
+ @KnownFailure("preparedStatement.execute() does not return false on update.")
public void testExecute() {
Statement st = null;
PreparedStatement ps = null;
try {
+ //update
String query = "insert into zoo(id, family, name) values(?, ?, 'unknown animal')";
ps = conn.prepareStatement(query);
ps.setInt(1, 3);
ps.setString(2, "No name");
+ assertFalse(ps.execute());
+ assertEquals(1,ps.getUpdateCount());
+
+ // select
+ ps = conn.prepareStatement("select * from zoo");
assertTrue(ps.execute());
- st = conn.createStatement();
- st.execute("select * from zoo");
- assertEquals(3, getCount(st.getResultSet()));
+ assertEquals(3, getCount(ps.getResultSet()));
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
ps.close();
- st.close();
} catch (Exception ee) {
}
}
@@ -229,7 +236,7 @@
ps = conn.prepareStatement(query);
ps.setString(1, "cat");
ps.setInt(2, 2);
- assertTrue(ps.execute());
+ assertFalse(ps.execute());
assertEquals(1, ps.getUpdateCount());
st = conn.createStatement();
st.execute("select family from zoo where id=2");
@@ -250,7 +257,8 @@
conn.createStatement().execute("drop table if exists hutch");
String query = "create table hutch (id integer not null, animal_id integer, address char(20), primary key (id));";
ps = conn.prepareStatement(query);
- assertTrue(ps.execute());
+ assertFalse(ps.execute());
+ assertTrue(ps.getUpdateCount() > 0);
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
@@ -286,6 +294,21 @@
} catch (Exception ee) {
}
}
+ //Exception test
+ try {
+ String query = "update zoo set name='Masha', family=? where id=?;";
+ ps = conn.prepareStatement(query);
+ ps.setString(1, "cat");
+ ps.setInt(2, 2);
+ assertTrue(ps.execute("update zoo set name='Masha', family='cat' where id=2;"));
+ } catch (SQLException e) {
+ // ok Should not provide string argument for a prepared Statement
+ } finally {
+ try {
+ ps.close();
+ } catch (Exception ee) {
+ }
+ }
}
@@ -421,7 +444,8 @@
args = {}
)
@KnownFailure("it is not possible to invoke the method getMetaData on a " +
- "PreparedStatement object before it is executed")
+ "PreparedStatement object before it is executed: got NullPointerException."+
+ "Test passes on RI.")
public void testGetMetaData() {
PreparedStatement ps = null;
@@ -472,6 +496,7 @@
}
/**
+ * @throws SQLException
* @test java.sql.PreparedStatement#getParameterMetaData()
*/
@TestTargetNew(
@@ -481,11 +506,12 @@
args = {}
)
@KnownFailure("not supported")
- public void testGetParameterMetaData() {
+ public void testGetParameterMetaData() throws SQLException {
PreparedStatement ps = null;
+ String query = "select * from zoo where id = ?";
+ ps = conn.prepareStatement(query);
+
try {
- String query = "select * from zoo where id = ?";
- ps = conn.prepareStatement(query);
ParameterMetaData rsmd = ps.getParameterMetaData();
} catch (SQLException e) {
assertEquals("not supported",e.getMessage());
@@ -496,7 +522,8 @@
}
}
- // ps closed
+ ps.close();
+
try {
ps.getParameterMetaData();
fail("SQLException expected");
@@ -525,6 +552,7 @@
ps.clearParameters();
try {
ps.execute();
+ fail("SQLException is not thrown during execute method after calling clearParameters()");
} catch (SQLException sql) {
}
@@ -574,7 +602,7 @@
args = {int.class, int.class}
)
public void testSetInt() throws SQLException {
- createTables();
+
PreparedStatement ps = null;
Statement st = null;
try {
@@ -592,11 +620,12 @@
fail("SQLException is thrown: " + sqle.getMessage());
} finally {
try {
+ ps.close();
st.close();
} catch (Exception ee) {
}
}
-
+ ps = conn.prepareStatement(query);
try {
ps.setInt(1, Integer.MIN_VALUE);
ps.execute();
@@ -609,29 +638,25 @@
fail("SQLException is thrown: " + sqle.getMessage());
} finally {
try {
+ ps.close();
st.close();
} catch (SQLException ee) {
}
}
-
+ ps = conn.prepareStatement(query);
+ ps.close();
try {
- ps.setInt(2, Integer.MIN_VALUE);
+ ps.setInt(1, Integer.MIN_VALUE);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
}
- try {
- ps.setInt(-2, 0);
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- }
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (SQLException ee) {
}
@@ -648,7 +673,7 @@
args = {int.class, long.class}
)
public void testSetLong() {
- createTables();
+
PreparedStatement ps = null;
try {
String query = "insert into type (LongVal) values (?);";
@@ -689,25 +714,20 @@
} catch (SQLException ee) {
}
}
-
+
+ ps.close();
try {
- ps.setLong(2, Long.MIN_VALUE);
+ ps.setLong(1, Long.MIN_VALUE);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
}
- try {
- ps.setLong(-2, 0);
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- }
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (SQLException ee) {
}
@@ -716,6 +736,7 @@
}
/**
+ * @throws SQLException
* @test java.sql.PreparedStatement#setFloat(int parameterIndex, float x)
*/
@TestTargetNew(
@@ -724,14 +745,16 @@
method = "setFloat",
args = {int.class, float.class}
)
- public void testSetFloat() {
+ public void testSetFloat() throws SQLException {
float value1 = 12345678.12345689f;
float value2 = -12345678.12345689f;
- createTables();
+
PreparedStatement ps = null;
+ String query = "insert into type (FloatVal) values (?);";
+ ps = conn.prepareStatement(query);
+
try {
- String query = "insert into type (FloatVal) values (?);";
- ps = conn.prepareStatement(query);
+
Statement st = null;
try {
ps.setFloat(1, value1);
@@ -765,27 +788,19 @@
}
}
-
+ ps.close();
try {
- ps.setFloat(2, Float.MIN_VALUE);
+ ps.setFloat(1, Float.MIN_VALUE);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
- assertEquals("bad parameter index", sqle.getMessage());
}
- try {
- ps.setFloat(-2, 0);
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- assertEquals("bad parameter index", sqle.getMessage());
- }
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (SQLException ee) {
}
@@ -793,6 +808,7 @@
}
/**
+ * @throws SQLException
* @test java.sql.PreparedStatement#setDouble(int parameterIndex, double x)
*/
@TestTargetNew(
@@ -801,12 +817,14 @@
method = "setDouble",
args = {int.class, double.class}
)
- public void testSetDouble() {
- createTables();
+ public void testSetDouble() throws SQLException {
+
PreparedStatement ps = null;
+ String query = "insert into type (DoubleVal) values (?);";
+ ps = conn.prepareStatement(query);
+
try {
- String query = "insert into type (DoubleVal) values (?);";
- ps = conn.prepareStatement(query);
+
Statement st = null;
try {
ps.setDouble(1, Double.MAX_VALUE);
@@ -841,27 +859,20 @@
} catch (SQLException ee) {
}
}
-
+
+ ps.close();
try {
- ps.setDouble(2, 2.0);
+ ps.setDouble(1, 2.0);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
- assertEquals("bad parameter index", sqle.getMessage());
}
- try {
- ps.setDouble(-2, 2.0);
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- assertEquals("bad parameter index", sqle.getMessage());
- }
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (SQLException ee) {
}
@@ -879,12 +890,14 @@
args = {int.class, java.lang.String.class}
)
public void testSetString_charField() {
- createTables();
+
PreparedStatement ps = null;
+
try {
- String str = "test^text$test%";
String query = "insert into type (charStr) values (?);";
ps = conn.prepareStatement(query);
+
+ String str = "test^text$test%";
Statement st = null;
try {
ps.setString(1, str);
@@ -934,23 +947,7 @@
} catch (SQLException ee) {
}
}
-
- try {
- ps.setString(2, "test text");
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- assertEquals("bad parameter index", sqle.getMessage());
- }
-
- try {
- ps.setString(-2, "test text");
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- assertEquals("bad parameter index", sqle.getMessage());
- }
-
+
try {
ps.setString(1, " test & text * test % text * test ^ text ");
ps.execute();
@@ -964,11 +961,21 @@
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
}
+
+ ps.close();
+
+ try {
+ ps.setString(1, "test text");
+ fail("SQLException is not thrown");
+ } catch (SQLException sqle) {
+ // expected
+ }
+
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (SQLException ee) {
}
@@ -984,8 +991,9 @@
method = "setString",
args = {int.class, java.lang.String.class}
)
+ @KnownFailure("statment.close() does not wrap up")
public void testSetString_tinyTextField() {
- createTables();
+
PreparedStatement ps = null;
try {
String str = "test^text$test%test(text)test@text5test~test^text$test%test(text)test@text5test/test^text$test%test(text)test@text5test~test^text$test%test(text)test@text5test";
@@ -1040,21 +1048,7 @@
} catch (SQLException ee) {
}
}
-
- try {
- ps.setString(2, "test text");
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- }
-
- try {
- ps.setString(-2, "test text");
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- }
-
+
try {
ps.setString(
1,
@@ -1070,11 +1064,22 @@
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
}
+
+ ps.close();
+
+ try {
+ ps.setString(1, "test text");
+ fail("SQLException is not thrown");
+ } catch (SQLException sqle) {
+ // expected
+ }
+
+
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (SQLException ee) {
}
@@ -1091,7 +1096,7 @@
args = {int.class, java.lang.String.class}
)
public void testSetString_textField() {
- createTables();
+
PreparedStatement ps = null;
try {
String str = "test^text$test%test(text)test@text5test~test^text$test%test(text)test@text5test/test^text$test%test(text)test@text5test~test^text$test%test(text)test@text5test";
@@ -1147,19 +1152,6 @@
}
}
- try {
- ps.setString(2, "test text");
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- }
-
- try {
- ps.setString(-2, "test text");
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- }
try {
String longString = " test^text$test%test(text)test@text5test~test^text$test%test(text)test@text5test/";
@@ -1179,11 +1171,20 @@
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
}
+
+ ps.close();
+
+ try {
+ ps.setString(2, "test text");
+ fail("SQLException is not thrown");
+ } catch (SQLException sqle) {
+ // expected
+ }
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (SQLException ee) {
}
@@ -1200,7 +1201,7 @@
args = {int.class, java.lang.String.class}
)
public void testSetString_mediumTextField() {
- createTables();
+
PreparedStatement ps = null;
try {
String str = "test^text$test%test(text)test@text5test~test^text$test%test(text)test@text5test/test^text$test%test(text)test@text5test~test^text$test%test(text)test@text5test";
@@ -1255,6 +1256,15 @@
} catch (Exception ee) {
}
}
+
+ try {
+ ps.setString(1, null);
+ ps.execute();
+ } catch (SQLException sqle) {
+ fail("SQLException is thrown: " + sqle.getMessage());
+ }
+
+ ps.close();
try {
ps.setString(2, "test text");
@@ -1263,24 +1273,13 @@
// expected
}
- try {
- ps.setString(-2, "test text");
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- }
- try {
- ps.setString(1, null);
- ps.execute();
- } catch (SQLException sqle) {
- fail("SQLException is thrown: " + sqle.getMessage());
- }
+
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (Exception ee) {
}
@@ -1297,7 +1296,7 @@
args = {int.class, java.lang.String.class}
)
public void testSetString_longTextField() {
- createTables();
+
PreparedStatement ps = null;
try {
String str = "test^text$test%test(text)test@text5test~test^text$test%test(text)test@text5test/test^text$test%test(text)test@text5test~test^text$test%test(text)test@text5test";
@@ -1352,32 +1351,29 @@
} catch (Exception ee) {
}
}
-
- try {
- ps.setString(2, "test text");
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- }
-
- try {
- ps.setString(-2, "test text");
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- }
-
+
try {
ps.setString(1, null);
ps.execute();
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
}
+
+ ps.close();
+
+ try {
+ ps.setString(1, "test text");
+ fail("SQLException is not thrown");
+ } catch (SQLException sqle) {
+ // expected
+ }
+
+
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (Exception ee) {
}
@@ -1394,7 +1390,7 @@
args = {int.class, short.class}
)
public void testSetShort() {
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
PreparedStatement ps2 = null;
@@ -1433,28 +1429,22 @@
} catch (Exception ee) {
}
}
+
+ ps.close();
try {
- ps.setShort(2, Short.MAX_VALUE);
+ ps.setShort(1, Short.MIN_VALUE);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
}
- try {
- ps.setShort(-2, Short.MIN_VALUE);
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- }
-
- String query1 = "insert type(Tint) values (?);";
+ String query1 = "insert into type (Tint) values (?);";
ps1 = conn.prepareStatement(query1);
try {
ps1.setShort(1, Short.MAX_VALUE);
- fail("SQLException is not thrown");
} catch (SQLException sqle) {
- // expected
+ fail("SQLException is thrown: "+sqle.getMessage());
}
String query2 = "insert into type (IntVal) values (?);";
@@ -1475,7 +1465,7 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
ps1.close();
ps2.close();
@@ -1495,7 +1485,7 @@
args = {int.class, boolean.class}
)
public void testSetBoolean() {
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
try {
@@ -1533,22 +1523,16 @@
} catch (Exception ee) {
}
}
+
+ ps.close();
try {
- ps.setBoolean(2, true);
+ ps.setBoolean(1, false);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
}
- try {
- ps.setBoolean(-2, false);
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
- assertEquals("bad parameter index", sqle.getMessage());
- }
-
String query1 = "insert into type (Tint) values (?);";
ps1 = conn.prepareStatement(query1);
try {
@@ -1562,7 +1546,7 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
ps1.close();
} catch (Exception ee) {
@@ -1580,7 +1564,7 @@
args = {int.class, byte.class}
)
public void testSetByte() {
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
try {
@@ -1622,17 +1606,17 @@
try {
ps.setByte(2, Byte.MAX_VALUE);
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
+ } catch (Exception sqle) {
// expected
- assertEquals("bad parameter index", sqle.getMessage());
}
+
+ ps.close();
try {
- ps.setByte(-2, Byte.MIN_VALUE);
+ ps.setByte(1, Byte.MIN_VALUE);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
- assertEquals("bad parameter index", sqle.getMessage());
}
String query1 = "insert into type (IntVal) values (?);";
@@ -1648,7 +1632,7 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
ps1.close();
} catch (Exception ee) {
@@ -1661,67 +1645,62 @@
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
- notes = "ps.execute() should be removed in exception part (for exception testing)",
+ notes = "",
method = "setBytes",
args = {int.class, byte[].class}
)
+ @KnownFailure("preparedStatement.execute() does not return false on update.")
public void testSetBytes() {
byte[] bytesArray = {1, 0};
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
try {
String query = "insert into type (LBlob) values (?);";
ps = conn.prepareStatement(query);
- Statement st = null;
+
try {
ps.setBytes(1, bytesArray);
- ps.execute();
+ assertFalse(ps.execute());
+ assertTrue(ps.getUpdateCount() > 0);
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
- } finally {
- try {
- st.close();
- } catch (Exception ee) {
- }
- }
+ }
try {
ps.setBytes(2, bytesArray);
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
+ } catch (Exception sqle) {
+ // expected RuntimeException or SQLException
}
+
+ ps.close();
try {
- ps.setBytes(-2, bytesArray);
+ ps.setBytes(1, bytesArray);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
- assertEquals("bad parameter index", sqle.getMessage());
}
String query1 = "insert into type (TBlob) values (?);";
ps1 = conn.prepareStatement(query1);
try {
ps.setBytes(1, bytesArray);
- ps.execute();
+ assertFalse(ps.execute());
+ assertTrue(ps.getUpdateCount() > 0);
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
- } finally {
- try {
- st.close();
- } catch (Exception ee) {
- }
- }
+ }
+
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
- ps.close();
- ps1.close();
+
+ if (ps != null) ps.close();
+ if (ps1 != null) ps1.close();
} catch (Exception ee) {
}
}
@@ -1737,10 +1716,11 @@
method = "setBigDecimal",
args = {int.class, java.math.BigDecimal.class}
)
+ @KnownFailure("preparedStatement.execute() does not return false on update.")
public void testSetBigDecimal() {
BigDecimal bd = new BigDecimal("50");
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
try {
@@ -1749,19 +1729,12 @@
Statement st = null;
try {
ps.setBigDecimal(1, bd);
- ps.execute();
- st = conn.createStatement();
- st.execute("select * from type where DecVal=" + bd);
- ResultSet rs = st.getResultSet();
- assertEquals(1, getCount(rs));
+ assertFalse(ps.execute());
+ assertTrue(ps.getUpdateCount() > 0);
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
- } finally {
- try {
- st.close();
- } catch (SQLException ee) {
- }
- }
+ }
+
try {
ps.setBigDecimal(2, bd);
@@ -1790,9 +1763,9 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
- ps.close();
- ps1.close();
+
+ if (ps != null) ps.close();
+ if (ps1 != null) ps1.close();
} catch (SQLException ee) {
}
}
@@ -1808,14 +1781,16 @@
method = "setDate",
args = {int.class, java.sql.Date.class}
)
- @KnownFailure("Setting a data for a declared INTEGER should throw Exception")
+ @KnownFailure("preparedStatement.execute() does not return false on update. "+
+ "Setting a data for a declared INTEGER should throw Exception")
public void testSetDate_int_Date() {
- Calendar cal = new GregorianCalendar(1799,5,26);
+ Calendar cal = new GregorianCalendar(1799, 5, 26);
- Date[] dates = { new Date(cal.getTimeInMillis()), new Date(Integer.MAX_VALUE),
- new Date(123456789) };
+ Date[] dates = {
+ new Date(cal.getTimeInMillis()), new Date(Integer.MAX_VALUE),
+ new Date(123456789)};
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
try {
@@ -1823,58 +1798,49 @@
ps = conn.prepareStatement(query);
for (int i = 0; i < dates.length; i++) {
- Statement st = null;
try {
ps.setDate(1, dates[i]);
- ps.execute();
- st = conn.createStatement();
- st.execute("select * from type where dateVal='"
- + dates[i].toString() + "'");
- ResultSet rs = st.getResultSet();
- assertEquals(1, getCount(rs));
+ assertFalse(ps.execute());
+ assertTrue(ps.getUpdateCount() > 0);
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
- } finally {
- try {
- st.close();
- } catch (SQLException ee) {
- }
}
}
try {
ps.setDate(2, dates[0]);
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
+ } catch (Exception sqle) {
// expected
- assertEquals("bad parameter index", sqle.getMessage());
}
+ ps.close();
+
try {
- ps.setDate(-2, dates[0]);
+ ps.setDate(1, dates[0]);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
- assertEquals("bad parameter index", sqle.getMessage());
}
-
- String query1 = "insert type(Tint) values (?);";
+
+ String query1 = "insert into type (Tint) values (?);";
ps1 = conn.prepareStatement(query1);
-
+
try {
ps1.setDate(1, dates[0]);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
- assertEquals("SQLite.Exception: error in prepare", sqle.getMessage());
+ assertEquals("SQLite.Exception: error in prepare", sqle
+ .getMessage());
}
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
- ps.close();
- ps1.close();
+
+ if (ps != null) ps.close();
+ if (ps1 != null) ps1.close();
} catch (SQLException ee) {
}
}
@@ -1890,6 +1856,7 @@
method = "setDate",
args = {int.class, java.sql.Date.class, java.util.Calendar.class}
)
+ @KnownFailure("preparedStatement.execute() does not return false on update.")
public void testSetDate_int_Date_Calendar() {
Calendar[] cals = { Calendar.getInstance(),
@@ -1900,7 +1867,7 @@
Date[] dates = { new Date(cal.getTimeInMillis()), new Date(Integer.MAX_VALUE),
new Date(123456789) };
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
try {
@@ -1908,22 +1875,13 @@
ps = conn.prepareStatement(query);
for (int i = 0; i < dates.length; i++) {
- Statement st = null;
+
try {
ps.setDate(1, dates[i], cals[i]);
- ps.execute();
- st = conn.createStatement();
- st.execute("select * from type where dateVal='"
- + dates[i].toString() + "'");
- ResultSet rs = st.getResultSet();
- assertEquals(1, getCount(rs));
+ assertFalse(ps.execute());
+ assertTrue(ps.getUpdateCount() > 0);
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
- } finally {
- try {
- st.close();
- } catch (SQLException ee) {
- }
}
}
@@ -1931,17 +1889,17 @@
ps.setDate(2, dates[0], cals[0]);
ps.execute();
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
+ } catch (Exception sqle) {
// expected
- assertEquals("bad parameter index", sqle.getMessage());
}
-
+
+ ps.close();
+
try {
- ps.setDate(-2, dates[0], cals[1]);
+ ps.setDate(1, dates[0], cals[1]);
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
+ } catch (Exception sqle) {
// expected
- assertEquals("bad parameter index", sqle.getMessage());
}
String query1 = "insert into type (Tint) values (?);";
ps1 = conn.prepareStatement(query1);
@@ -1957,9 +1915,9 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
- ps.close();
- ps1.close();
+
+ if (ps != null) ps.close();
+ if (ps1 != null) ps1.close();
} catch (SQLException ee) {
}
}
@@ -1977,7 +1935,7 @@
args = {int.class, int.class}
)
public void testSetNull_int_int() {
- createTables();
+
PreparedStatement ps = null;
try {
String query = "insert into type (BoolVal, IntVal) values ('true', ?);";
@@ -1990,23 +1948,22 @@
fail("SQLException is thrown: " + sqle.getMessage());
} finally {
try {
- st.close();
+ ps.close();
} catch (Exception ee) {
}
}
- query = "insert into type (BoolVal, LongVal) values (true, ?);";
+ query = "insert into type (BoolVal, LongVal) values ('true', ?);";
ps = conn.prepareStatement(query);
try {
ps.setNull(1, Types.BIGINT);
- fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- //expected
- assertEquals("SQLite.Exception: error in prepare", sqle.getMessage());
+ ps.execute();
+ } catch (SQLException sqle) {
+ fail("SQLException is thrown: " + sqle.getMessage());
} finally {
try {
- st.close();
+ ps.close();
} catch (Exception ee) {
}
}
@@ -2021,62 +1978,55 @@
fail("SQLException is thrown: " + sqle.getMessage());
} finally {
try {
- st.close();
+ ps.close();
} catch (Exception ee) {
}
}
- query = "insert into type (BoolVal, dateVal) values (true, ?);";
+ query = "insert into type (BoolVal, dateVal) values ('true', ?);";
ps = conn.prepareStatement(query);
try {
ps.setNull(1, Types.DATE);
- fail("SQLException is not thrown");
+ ps.execute();
} catch (SQLException sqle) {
- //expected
+ fail("SQLException is thrown: " + sqle.getMessage());
} finally {
try {
- st.close();
+ ps.close();
} catch (Exception ee) {
}
}
- query = "insert into type (BoolVal, BlobVal) values (true, ?);";
+ query = "insert into type (BoolVal, BlobVal) values ('true', ?);";
ps = conn.prepareStatement(query);
try {
ps.setNull(1, Types.BLOB);
- fail("SQLException is not thrown");
+ ps.execute();
} catch (SQLException sqle) {
- //expected
- assertEquals("SQLite.Exception: error in prepare", sqle.getMessage());
+ fail("SQLException is thrown: " + sqle.getMessage());
} finally {
try {
- st.close();
+ ps.close();
} catch (Exception ee) {
}
}
- query = "insert into type (BoolVal, TextVal) values (true, ?);";
+ query = "insert into type (BoolVal, TextVal) values ('true', ?);";
ps = conn.prepareStatement(query);
try {
ps.setNull(1, Types.CHAR);
- fail("SQLException is not thrown");
+ ps.execute();
} catch (SQLException sqle) {
- //expected
- assertEquals("SQLite.Exception: error in prepare", sqle.getMessage());
- } finally {
- try {
- st.close();
- } catch (Exception ee) {
- }
+ fail("SQLException is thrown: " + sqle.getMessage());
}
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (Exception ee) {
}
@@ -2123,7 +2073,7 @@
} catch (SQLException e) {
// UDTs or Ref types not supported
- assertEquals("SQLite.Exception: error in prepare/compile",e.getMessage());
+ // ok
} finally {
try {
st.execute("drop table if exists person");
@@ -2212,7 +2162,7 @@
args = {int.class, java.lang.Object.class}
)
public void testSetObject_int_Object() {
- createTables();
+
PreparedStatement ps = null;
try {
String query = "insert into type (IntVal) values (?);";
@@ -2266,13 +2216,14 @@
query = "insert into type (dateVal) values (?);";
ps = conn.prepareStatement(query);
+ Date d = new Date(123456789);
try {
- ps.setObject(1, new Date(123456789));
+ ps.setObject(1, d);
ps.execute();
st = conn.createStatement();
st.execute("select * from type where dateVal='"
- + new Date(123456789) + "';");
+ + d.getTime() + "';");
ResultSet rs = st.getResultSet();
assertEquals(1, getCount(rs));
} catch (SQLException sqle) {
@@ -2304,7 +2255,7 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (Exception ee) {
}
@@ -2331,10 +2282,10 @@
args = {int.class, java.lang.Object.class, int.class}
)
public void testSetObject_int_Object_int() {
- createTables();
+
PreparedStatement ps = null;
try {
- String query = "insert into type(IntVal) values (?);";
+ String query = "insert into type (IntVal) values (?);";
ps = conn.prepareStatement(query);
Statement st = null;
try {
@@ -2385,13 +2336,15 @@
query = "insert into type (dateVal) values (?);";
ps = conn.prepareStatement(query);
+ Date d = new Date(123456789);
+
try {
- ps.setObject(1, new Date(123456789), Types.DATE);
+ ps.setObject(1, d, Types.DATE);
ps.execute();
st = conn.createStatement();
st.execute("select * from type where dateVal='"
- + new Date(123456789) + "';");
+ + d.getTime() + "';");
ResultSet rs = st.getResultSet();
assertEquals(1, getCount(rs));
} catch (SQLException sqle) {
@@ -2423,7 +2376,7 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (Exception ee) {
}
@@ -2451,7 +2404,7 @@
args = {int.class, java.lang.Object.class, int.class, int.class}
)
public void testSetObject_int_Object_int_int() {
- createTables();
+
PreparedStatement ps = null;
try {
String query = "insert into type (IntVal) values (?);";
@@ -2507,13 +2460,13 @@
query = "insert into type (dateVal) values (?);";
ps = conn.prepareStatement(query);
-
+ Date d = new Date(123456789);
try {
- ps.setObject(1, new Date(123456789), Types.DATE, -1);
+ ps.setObject(1, d , Types.DATE, -1);
ps.execute();
st = conn.createStatement();
st.execute("select * from type where dateVal='"
- + new Date(123456789) + "';");
+ + d.getTime() + "';");
ResultSet rs = st.getResultSet();
assertEquals(1, getCount(rs));
} catch (SQLException sqle) {
@@ -2545,7 +2498,7 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
} catch (Exception ee) {
}
@@ -2568,12 +2521,13 @@
method = "setTime",
args = {int.class, java.sql.Time.class}
)
+ @KnownFailure("statment.close() does not wrap up")
public void testSetTimeint_Time() {
Time[] times = { new Time(24, 25, 26), new Time(Integer.MAX_VALUE),
new Time(123456789) };
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
try {
@@ -2586,7 +2540,7 @@
ps.execute();
st = conn.createStatement();
st.execute("select * from type where timeVal='"
- + times[i].toString() + "'");
+ + times[i].getTime() + "'");
ResultSet rs = st.getResultSet();
assertEquals(1, getCount(rs));
} catch (SQLException sqle) {
@@ -2602,12 +2556,14 @@
try {
ps.setTime(2, times[0]);
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
- // expected
+ } catch (Exception sqle) {
+ // expected index out of bounds
}
-
+
+ ps.close();
+
try {
- ps.setTime(-2, times[0]);
+ ps.setTime(1, times[0]);
fail("SQLException is not thrown");
} catch (SQLException sqle) {
// expected
@@ -2626,7 +2582,7 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
ps1.close();
} catch (Exception ee) {
@@ -2644,6 +2600,7 @@
method = "setTime",
args = {int.class, java.sql.Time.class, java.util.Calendar.class}
)
+ @KnownFailure("preparedStatement.execute() does not return False on update.")
public void testSetTime_int_Time_Calendar() {
Calendar[] cals = { Calendar.getInstance(),
@@ -2653,7 +2610,7 @@
Time[] times = { new Time(24, 25, 26), new Time(Integer.MAX_VALUE),
new Time(123456789) };
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
try {
@@ -2663,12 +2620,8 @@
for (int i = 0; i < times.length; i++) {
try {
ps.setTime(1, times[i], cals[i]);
- ps.execute();
- st = conn.createStatement();
- st.execute("select * from type where timeVal='"
- + times[i].toString() + "'");
- ResultSet rs = st.getResultSet();
- assertEquals(1, getCount(rs));
+ assertFalse(ps.execute());
+ assertTrue(ps.getUpdateCount() > 0);
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
} finally {
@@ -2682,14 +2635,16 @@
try {
ps.setTime(2, times[0], cals[0]);
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
+ } catch (Exception sqle) {
// expected
}
+
+ ps.close();
try {
ps.setTime(-2, times[0], cals[1]);
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
+ } catch (Exception sqle) {
// expected
}
String query1 = "insert into type (Tint) values (?);";
@@ -2706,7 +2661,7 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
ps1.close();
} catch (Exception ee) {
@@ -2724,48 +2679,40 @@
method = "setTimestamp",
args = {int.class, java.sql.Timestamp.class}
)
+ @KnownFailure("preparedStatement.execute() does not return false on update.")
public void testSetTimestamp_int_Timestamp() {
Timestamp[] timestamps = { new Timestamp(2007, 10, 17, 19, 06, 50, 23),
new Timestamp(123) };
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
try {
String query = "insert into type (TS) values (?);";
ps = conn.prepareStatement(query);
- Statement st = null;
+
for (int i = 0; i < timestamps.length; i++) {
try {
ps.setTimestamp(1, timestamps[i]);
- ps.execute();
- st = conn.createStatement();
- st.execute("select * from type where TS='"
- + timestamps[i].toString() + "'");
- ResultSet rs = st.getResultSet();
- assertEquals(1, getCount(rs));
+ assertFalse(ps.execute());
+ assertTrue(ps.getUpdateCount() > 0);
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
- } finally {
- try {
- st.close();
- } catch (SQLException ee) {
- }
}
}
try {
ps.setTimestamp(2, timestamps[0]);
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
+ } catch (Exception sqle) {
// expected
}
try {
ps.setTimestamp(-2, timestamps[0]);
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
+ } catch (Exception sqle) {
// expected
}
String query1 = "insert into type (Tint) values (?);";
@@ -2782,7 +2729,7 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
ps1.close();
} catch (Exception ee) {
@@ -2807,8 +2754,9 @@
String neverExecutedQuery = "select TBlob from type;";
ps = conn.prepareStatement(neverExecutedQuery);
ps.setBlob(1,mock);
+ fail("Exception expected not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ //ok
}
}
@@ -2829,8 +2777,9 @@
String neverExecutedQuery = "select TBlob from type;";
ps = conn.prepareStatement(neverExecutedQuery);
ps.setClob(1,mock);
+ fail("Exception expected not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ //ok
}
}
@@ -2844,6 +2793,7 @@
method = "setTimestamp",
args = {int.class, java.sql.Timestamp.class, java.util.Calendar.class}
)
+ @KnownFailure("preparedStatement.execute() does not return false on update.")
public void testSetTimestampIntTimestampCalendar() {
Calendar[] cals = { Calendar.getInstance(),
Calendar.getInstance(Locale.GERMANY),
@@ -2852,7 +2802,7 @@
Timestamp[] timestamps = { new Timestamp(2007, 10, 17, 19, 06, 50, 23),
new Timestamp(123) };
- createTables();
+
PreparedStatement ps = null;
PreparedStatement ps1 = null;
try {
@@ -2862,12 +2812,8 @@
for (int i = 0; i < timestamps.length; i++) {
try {
ps.setTimestamp(1, timestamps[i], cals[i]);
- ps.execute();
- st = conn.createStatement();
- st.execute("select * from type where timeVal='"
- + timestamps[i].toString() + "'");
- ResultSet rs = st.getResultSet();
- assertEquals(1, getCount(rs));
+ assertFalse(ps.execute());
+ assertTrue(ps.getUpdateCount() > 0);
} catch (SQLException sqle) {
fail("SQLException is thrown: " + sqle.getMessage());
} finally {
@@ -2882,12 +2828,12 @@
ps.setTimestamp(2, timestamps[0], cals[0]);
ps.execute();
fail("SQLException is not thrown");
- } catch (SQLException sqle) {
+ } catch (Exception sqle) {
// expected
}
-
+ ps.close();
try {
- ps.setTimestamp(-2, timestamps[0], cals[1]);
+ ps.setTimestamp(1, timestamps[0], cals[1]);
ps.execute();
fail("SQLException is not thrown");
} catch (SQLException sqle) {
@@ -2907,7 +2853,7 @@
fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
- clearTables();
+
ps.close();
ps1.close();
} catch (Exception ee) {
@@ -2932,8 +2878,9 @@
String query = "insert into type (TText) values (?);";
ps = conn.prepareStatement(query);
ps.setURL(1, new URL("http://www.android.com"));
+ fail("Exception expected not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ //ok
} catch (Exception e) {
fail("Error in test setup "+e.getMessage());
e.printStackTrace();
@@ -2959,8 +2906,9 @@
String query = "insert into type (TText) values (?);";
ps = conn.prepareStatement(query);
ps.setArray(1, new MockArray());
+ fail("Exception expected not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ //ok
} catch (Exception e) {
fail("Error in test setup "+e.getMessage());
e.printStackTrace();
@@ -2986,8 +2934,9 @@
String neverExecutedQuery = "select TBlob from type;";
ps = conn.prepareStatement(neverExecutedQuery);
ps.setRef(1,mock);
+ fail("Exception expected not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ //ok
}
}
@@ -3011,8 +2960,9 @@
InputStream file = Class.forName(this.getClass().getName())
.getResourceAsStream("/blob.c");
ps.setUnicodeStream(0, file, 100);
+ fail("Exception expected not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ //ok
} catch (Exception e) {
fail("Error in test setup "+e.getMessage());
e.printStackTrace();
@@ -3037,10 +2987,12 @@
ps = conn.prepareStatement(query);
InputStream file = Class.forName(this.getClass().getName())
.getResourceAsStream("/blob.c");
+ assertNotNull("Error in test setup: file not found",file);
Reader reader = new InputStreamReader(file);
ps.setCharacterStream(1, reader, 100);
+ fail("Exception expected not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ // ok
} catch (Exception e) {
fail("Error in test setup "+e.getMessage());
e.printStackTrace();
@@ -3066,8 +3018,9 @@
InputStream file = Class.forName(this.getClass().getName())
.getResourceAsStream("/blob.c");
ps.setAsciiStream(0, file, 100);
+ fail("Exception expected not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ // ok
} catch (Exception e) {
fail("Error in test setup "+e.getMessage());
e.printStackTrace();
@@ -3085,6 +3038,7 @@
args = {int.class, java.io.InputStream.class, int.class}
)
public void testSetBinaryStream() {
+
ResultSet res = null;
PreparedStatement ps = null;
try {
@@ -3093,8 +3047,9 @@
InputStream file = Class.forName(this.getClass().getName())
.getResourceAsStream("/blob.c");
ps.setBinaryStream(0, file, 100);
+ fail("Exception expected not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ // ok
} catch (Exception e) {
fail("Error in test setup "+e.getMessage());
e.printStackTrace();
diff --git a/libcore/sql/src/test/java/tests/sql/ResultSetGetterTests.java b/libcore/sql/src/test/java/tests/sql/ResultSetGetterTests.java
index 3bd8859..302dbee 100644
--- a/libcore/sql/src/test/java/tests/sql/ResultSetGetterTests.java
+++ b/libcore/sql/src/test/java/tests/sql/ResultSetGetterTests.java
@@ -23,11 +23,12 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
-import java.io.UnsupportedEncodingException;
+
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.DatabaseMetaData;
import java.sql.Date;
+import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
@@ -125,7 +126,7 @@
static Class[] typeMap = new Class[]{
java.lang.String.class, //
java.lang.Integer.class,//Types.INTEGER,
- java.lang.String.class, //Types.LONG, not a JDBC 1.0 type
+ java.lang.Integer.class, //Types.LONG, not a JDBC 1.0 type
java.lang.Long.class, // Types.BIGINT,
java.lang.Byte.class, // Types.TINYINT,
java.lang.Short.class, // Types.SMALLINT,
@@ -263,7 +264,7 @@
)
public void testGetBytesInt() {
int i = 1;
- /*
+
// null value
try {
@@ -284,93 +285,229 @@
} catch (SQLException e) {
//ok
}
- */
+
}
/**
* Test method for {@link java.sql.ResultSet#getBytes(int)}.
+ * @throws SQLException
*/
@TestTargetNew(
level = TestLevel.PARTIAL_COMPLETE,
- notes = "Integer, test fails",
+ notes = "VARBINARY value",
method = "getBytes",
args = {int.class}
)
- @KnownFailure("res.close() does not wrap up")
- public void testGetBytesIntInteger() {
+ @KnownFailure("last assertion fails: invalid conversion. Test passes on RI")
+ public void testGetBytesIntVarbinary() throws SQLException {
+
+ Statement st = null;
+ Statement stQuery = null;
+ PreparedStatement stPrep = null;
+ ResultSet res = null;
+
+ // setup
try {
+ String testString = "HelloWorld";
+ st = conn.createStatement();
+ st.executeUpdate("create table testBinary (VARBINARY value);");
+ stPrep = conn
+ .prepareStatement("insert into testBinary values (?);");
+ stPrep.setBytes(1, testString.getBytes());
+ stPrep.execute();
- Integer input = -1;
- String output = "";
-
- Byte inputB = Byte.valueOf(input.toString());
- String hexInput = Integer.toHexString(inputB);
- // byte[] inputBytes =
- byte[] outputBytes = res.getBytes(2);
- for (byte b : outputBytes) {
- output += Integer.toHexString(b);
+ stQuery = conn.createStatement();
+ res = stQuery.executeQuery("select * from testBinary");
+ try {
+ assertTrue(res.next());
+ byte[] output = res.getBytes(1);
+ String helloTest = new String(output);
+ assertNotNull(helloTest);
+ assertEquals(testString, helloTest);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
}
-
- assertEquals(1, outputBytes.length);
- assertEquals(hexInput, output);
-
-
-
- } catch (SQLException e) {
- fail("Unexpected exception: " + e.getMessage());
+ } finally {
+ if (res != null) res.close();
+ if (stPrep != null) stPrep.close();
+ if (st != null) st.close();
+ if (stQuery != null) stQuery.close();
}
- // null value
+ }
+
+ /**
+ * Test method for {@link java.sql.ResultSet#getBytes(int)}.
+ * @throws SQLException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "BINARY value",
+ method = "getBytes",
+ args = {int.class}
+ )
+ @KnownFailure("last assertion fails: invalid conversion. Test passes on RI")
+ public void testGetBytesIntBinary() throws SQLException {
+
+ Statement st = null;
+ Statement stQuery = null;
+ PreparedStatement stPrep = null;
+ ResultSet res = null;
+
+
+ // setup
+
+ String testString = "HelloWorld";
+ st = conn.createStatement();
+ st.executeUpdate("create table testBinary (BINARY value);");
+ stPrep = conn.prepareStatement("insert into testBinary values (?);");
+ stPrep.setBytes(1, testString.getBytes());
+ stPrep.execute();
try {
- assertTrue(res.next());
- byte[] b = res.getBytes(2);
- assertNull(b);
+ stQuery = conn.createStatement();
+ res = stQuery.executeQuery("select * from testBinary");
+ try {
+ assertTrue(res.next());
+ byte[] output = res.getBytes(1);
+ String helloTest = new String(output);
+ assertNotNull(helloTest);
+ assertEquals(testString, helloTest);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
+ }
+ } finally {
+ if (res != null) res.close();
+ if (stPrep != null) stPrep.close();
+ if (st != null) st.close();
+ if (stQuery != null) stQuery.close();
+ }
+ }
+
+ /**
+ * Test method for {@link java.sql.ResultSet#getBytes(String)}.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Exception testing",
+ method = "getBytes",
+ args = {String.class}
+ )
+ public void testGetBytesString() {
+ int i = 1;
+
+ // null value
+ try {
+
+ res.next();
+ for (String t : colNames) {
+ assertNull(res.getBytes(t));
+ }
} catch (SQLException e) {
fail("Unexpected exception: " + e.getMessage());
}
try {
res.close();
- res.getBytes(2);
+ res.getBytes(colNames.get(24));
fail("Should get Exception");
} catch (SQLException e) {
//ok
}
}
-
-
+
/**
- * Test method for {@link java.sql.ResultSet#getBytes(java.lang.String)}.
+ * Test method for {@link java.sql.ResultSet#getBytes(int)}.
+ * @throws SQLException
*/
@TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- notes = "no BINARY type supported",
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "VARBINARY value",
method = "getBytes",
- args = {java.lang.String.class}
+ args = {String.class}
)
- public void testGetBytesString() {
- /*
-
-
- // null value
+ @KnownFailure("last assertion fails: invalid conversion. Test passes on RI")
+ public void testGetBytesStringVarbinary() throws SQLException {
+
+ Statement st = null;
+ Statement stQuery = null;
+ PreparedStatement stPrep = null;
+ ResultSet res = null;
+
+ // setup
try {
- res.next();
-
- for (String name: colNames) {
- assertNull(res.getBytes(name));
+ String testString = "HelloWorld";
+ st = conn.createStatement();
+ st.executeUpdate("create table testBinary (VARBINARY value);");
+ stPrep = conn
+ .prepareStatement("insert into testBinary values (?);");
+ stPrep.setBytes(1, testString.getBytes());
+ stPrep.execute();
+
+ stQuery = conn.createStatement();
+ res = stQuery.executeQuery("select value from testBinary");
+ try {
+ assertTrue(res.next());
+ byte[] output = res.getBytes("value");
+ String helloTest = new String(output);
+ assertNotNull(helloTest);
+ assertEquals(testString, helloTest);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
}
- } catch (SQLException e) {
- fail("Unexpected exception: " + e.getMessage());
+ } finally {
+ if (res != null) res.close();
+ if (stPrep != null) stPrep.close();
+ if (st != null) st.close();
+ if (stQuery != null) stQuery.close();
}
+ }
+
+ /**
+ * Test method for {@link java.sql.ResultSet#getBytes(int)}.
+ * @throws SQLException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "BINARY value",
+ method = "getBytes",
+ args = {String.class}
+ )
+ @KnownFailure("last assertion fails: invalid conversion. Test passes on RI")
+ public void testGetBytesStringBinary() throws SQLException {
+
+ Statement st = null;
+ Statement stQuery = null;
+ PreparedStatement stPrep = null;
+ ResultSet res = null;
+
+
+ // setup
+
+ String testString = "HelloWorld";
+ st = conn.createStatement();
+ st.executeUpdate("create table testBinary (BINARY value);");
+ stPrep = conn.prepareStatement("insert into testBinary values (?);");
+ stPrep.setBytes(1, testString.getBytes());
+ stPrep.execute();
try {
- res.close();
- res.getBytes("TextVal");
- fail("Should get Exception");
- } catch (SQLException e) {
- //ok
+ stQuery = conn.createStatement();
+ res = stQuery.executeQuery("select value from testBinary");
+ try {
+ assertTrue(res.next());
+ byte[] output = res.getBytes("value");
+ String helloTest = new String(output);
+ assertNotNull(helloTest);
+ assertEquals(testString, helloTest);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
+ }
+ } finally {
+ if (res != null) res.close();
+ if (stPrep != null) stPrep.close();
+ if (st != null) st.close();
+ if (stQuery != null) stQuery.close();
}
- */
}
/**
@@ -378,7 +515,7 @@
*/
@TestTargetNew(
level = TestLevel.SUFFICIENT,
- notes = "PARTIAL_OKly supported: CONCUR_UPDATABLE not supported",
+ notes = "Not fully supported: CONCUR_UPDATABLE not supported",
method = "getConcurrency",
args = {}
)
@@ -924,7 +1061,7 @@
* "LONGBLOB", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "BIGINT",
* "BIGINT","URL","URL");
*/
- List<String> types = Arrays.asList("VARCHAR", "INTEGER", "VARCHAR",
+ List<String> types = Arrays.asList("VARCHAR", "INTEGER", "INTEGER",
"BIGINT", "SMALLINT", "SHORT", "INTEGER", "INTEGER", "FLOAT",
"DOUBLE", "DOUBLE", "DECIMAL", "NUMERIC", "VARCHAR", "DATE",
"TIME", "TIMESTAMP", "DATETIME", "BLOB", "BLOB", "BLOB",
@@ -1298,8 +1435,8 @@
method = "getTime",
args = {int.class}
)
+ @KnownFailure("getTime should return Time value for a TIMESTAMP type but returns null")
public void testGetTimeInt() {
- List<Time> times = new LinkedList<Time>();
// values "12:35:45", "2007-10-09 14:28:02.0", "1221-09-22 10:11:55"
Calendar cal = new GregorianCalendar();
@@ -1312,7 +1449,19 @@
long millis = cal.getTime().getTime();
Time t1 = new java.sql.Time(millis);
assertNotNull("t1", t1);
- times.add(t1);
+
+
+ Calendar cal2 = new GregorianCalendar();
+ cal2.set(Calendar.YEAR, 2007);
+ cal2.set(Calendar.MONTH, Calendar.OCTOBER);
+ cal2.set(Calendar.DATE, 9);
+ cal2.set(Calendar.HOUR_OF_DAY, 14);
+ cal2.set(Calendar.MINUTE, 28);
+ cal2.set(Calendar.SECOND, 02);
+ cal2.set(Calendar.MILLISECOND, 0);
+
+ long millis2 = cal2.getTime().getTime();
+ Time t2 = new java.sql.Time(millis2);
int i = 16;
@@ -1325,6 +1474,18 @@
} catch (SQLException e) {
fail("Unexpected exception: " + e.getMessage());
}
+ // Compatibility Test: TIMESTAMP value
+ i = 17;
+
+ try {
+ Time resTime = res.getTime(i);
+ assertNotNull("Pos " + i + " null", resTime);
+ assertEquals(t2.toString(), resTime.toString());
+ assertEquals(t2.getTime(), resTime.getTime());
+ assertEquals(t2, resTime);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
+ }
try {
i = 16;
@@ -1351,6 +1512,7 @@
method = "getTime",
args = {int.class, java.util.Calendar.class}
)
+ @KnownFailure("getTime on TIMESTAMP value fails: returns null")
public void testGetTimeIntCalendar() {
List<Time> times = new LinkedList<Time>();
List<Calendar> cals = new LinkedList<Calendar>();
@@ -1366,6 +1528,20 @@
long millis = cal1.getTime().getTime();
Time t1 = new java.sql.Time(millis);
+
+ Calendar cal2 = new GregorianCalendar();
+ cal2.set(Calendar.YEAR, 2007);
+ cal2.set(Calendar.MONTH, Calendar.OCTOBER);
+ cal2.set(Calendar.DATE, 9);
+ cal2.set(Calendar.HOUR_OF_DAY, 14);
+ cal2.set(Calendar.MINUTE, 28);
+ cal2.set(Calendar.SECOND, 02);
+ cal2.set(Calendar.MILLISECOND, 0);
+
+ long millis2 = cal2.getTime().getTime();
+ Time t2 = new java.sql.Time(millis2);
+
+ // TIME value
int i = 16;
@@ -1379,6 +1555,19 @@
fail("Unexpected exception: " + e.getMessage());
}
+ // TIMESTAMP value
+ i = 17;
+
+ try {
+ Time timeRes = res.getTime(i,new GregorianCalendar());
+ assertNotNull(timeRes);
+ assertEquals(t2.toString(), timeRes.toString());
+ assertEquals(t2.getTime(), timeRes.getTime());
+ assertEquals(t2, timeRes);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
+ }
+
try {
res.next();
@@ -1407,7 +1596,7 @@
method = "getTime",
args = {java.lang.String.class}
)
-// @KnownFailure("Type Time not supported. test fails")
+ @KnownFailure("getTime should return a Time value for a TIMESTAMP type but returns null")
public void testGetTimeString() {
List<Time> times = new LinkedList<Time>();
@@ -1438,6 +1627,31 @@
} catch (SQLException e) {
fail("Unexpected exception: " + e.getMessage());
}
+
+ Calendar cal2 = new GregorianCalendar();
+ cal2.set(Calendar.YEAR, 2007);
+ cal2.set(Calendar.MONTH, Calendar.OCTOBER);
+ cal2.set(Calendar.DATE, 9);
+ cal2.set(Calendar.HOUR_OF_DAY, 14);
+ cal2.set(Calendar.MINUTE, 28);
+ cal2.set(Calendar.SECOND, 02);
+ cal2.set(Calendar.MILLISECOND, 0);
+
+ long millis2 = cal.getTime().getTime();
+ Time t2 = new java.sql.Time(millis2);
+
+ col = it.next();
+
+ try {
+ Time timeRes = res.getTime(col);
+ assertNotNull(timeRes);
+ assertEquals(t2.toString(), timeRes.toString());
+ assertEquals(t2.getTime(), timeRes.getTime());
+ assertEquals(t2, timeRes);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
+ }
+
try {
res.next();
@@ -1460,11 +1674,11 @@
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
- notes = "type Time not supported. Test fails",
+ notes = "Testing getTime with TIME, TIMESTAMP value",
method = "getTime",
args = {java.lang.String.class, java.util.Calendar.class}
)
-// @KnownFailure("type Time not supported. Test fails")
+ @KnownFailure("getTime on TIMESTAMP value fails: returns null")
public void testGetTimeStringCalendar() {
List<Time> times = new LinkedList<Time>();
@@ -1497,7 +1711,7 @@
long millis2 = cal2.getTime().getTime();
Time t2 = new java.sql.Time(millis2);
-// ListIterator<Calendar> calIt = cals.listIterator();
+ // TIME value
String col = it.next();
try {
@@ -1509,9 +1723,8 @@
} catch (SQLException e) {
fail("Unexpected exception: " + e.getMessage());
}
-
+ //TIMESTAMP value
col = it.next();
- System.out.println("ResultSetGetterTests.testGetTimeStringCalendar() "+col);
try {
Time timeRes = res.getTime(col, new GregorianCalendar());
@@ -1568,7 +1781,7 @@
long millis = cal2.getTime().getTime();
Timestamp t2 = new Timestamp(millis);
times.add(t2);
- //
+
Calendar cal3 = new GregorianCalendar();
cal3.set(Calendar.YEAR, 1221);
cal3.set(Calendar.MONTH, Calendar.SEPTEMBER);
@@ -1581,26 +1794,27 @@
millis = cal3.getTime().getTime();
Timestamp t3 = new Timestamp(millis);
times.add(t3);
-
-// cals.add(cal1);
- cals.add(cal2);
- cals.add(cal3);
-
- // ListIterator<Calendar> calIt = cals.listIterator();
-
+ // TIMESTAMP value
int i = 17;
-
+
try {
- // String col = it.next();
Timestamp timeRes = res.getTimestamp(i);
assertEquals(t2.toString(), timeRes.toString());
assertEquals(t2.getTime(), timeRes.getTime());
- // assertEquals(t, res.getTime(col));
+ assertEquals(t2, timeRes);
} catch (SQLException e) {
fail("Unexpected exception: " + e.getMessage());
}
-
- // calIt = cals.listIterator();
+ // DATE value
+ i = 18;
+ try {
+ Timestamp timeRes = res.getTimestamp(i);
+ assertEquals(t3.toString(), timeRes.toString());
+ assertEquals(t3.getTime(), timeRes.getTime());
+ assertEquals(t3, timeRes);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
+ }
try {
res.next();
@@ -1668,18 +1882,22 @@
int i = 17;
try {
- // String col = it.next();
- Timestamp timeRes = res.getTimestamp(i,cal2);
+ Timestamp timeRes = res.getTimestamp(i,new GregorianCalendar());
assertEquals(t2.toString(), timeRes.toString());
- timeRes = res.getTimestamp(i+1,cal3);
- assertEquals(t3.toString(), timeRes.toString());
- assertEquals(t3.getTime(), timeRes.getTime());
- // assertEquals(t, res.getTime(col));
+ assertEquals(t2, timeRes);
} catch (SQLException e) {
fail("Unexpected exception: " + e.getMessage());
}
-
- // calIt = cals.listIterator();
+
+ i = 18;
+
+ try {
+ Timestamp timeRes = res.getTimestamp(i,new GregorianCalendar());
+ assertEquals(t3.toString(), timeRes.toString());
+ assertEquals(t3, timeRes);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
+ }
try {
res.next();
@@ -1739,24 +1957,29 @@
Timestamp t3 = new Timestamp(millis);
times.add(t3);
-// cals.add(cal1);
-// cals.add(cal2);
-// cals.add(cal3);
-//
-// ListIterator<Calendar> calIt = cals.listIterator();
+ String col = it.next();
try {
- Timestamp timeRes = res.getTimestamp(stringTimes.get(0));
+ Timestamp timeRes = res.getTimestamp(col);
assertEquals(t2.toString(), timeRes.toString());
- timeRes = res.getTimestamp(stringTimes.get(1));
- assertEquals(t3.toString(), timeRes.toString());
- assertEquals(t3.getTime(), timeRes.getTime());
- // assertEquals(t, res.getTime(col));
+ assertEquals(t2.toString(), timeRes.toString());
+ assertEquals(t2.getTime(), timeRes.getTime());
+ assertEquals(t2, timeRes);
} catch (SQLException e) {
fail("Unexpected exception: " + e.getMessage());
}
-
- // calIt = cals.listIterator();
+ // DATE value
+ col = it.next();
+
+ try {
+ Timestamp timeRes = res.getTimestamp(col);
+ assertEquals(t3.toString(), timeRes.toString());
+ assertEquals(t3.toString(), timeRes.toString());
+ assertEquals(t3.getTime(), timeRes.getTime());
+ assertEquals(t3, timeRes);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
+ }
try {
res.next();
@@ -1818,10 +2041,17 @@
try {
Timestamp timeRes = res.getTimestamp(stringTimes.get(0),cal2);
assertEquals(t2.toString(), timeRes.toString());
- timeRes = res.getTimestamp(stringTimes.get(1),cal3);
+ assertEquals(t2.getTime(), timeRes.getTime());
+ assertEquals(t2, timeRes);
+ } catch (SQLException e) {
+ fail("Unexpected exception: " + e.getMessage());
+ }
+ // DATE value
+ try {
+ Timestamp timeRes = res.getTimestamp(stringTimes.get(1),cal3);
assertEquals(t3.toString(), timeRes.toString());
assertEquals(t3.getTime(), timeRes.getTime());
- // assertEquals(t, res.getTime(col));
+ assertEquals(t3, timeRes);
} catch (SQLException e) {
fail("Unexpected exception: " + e.getMessage());
}
diff --git a/libcore/sql/src/test/java/tests/sql/SQLTest.java b/libcore/sql/src/test/java/tests/sql/SQLTest.java
index 806a873..9d9051d 100755
--- a/libcore/sql/src/test/java/tests/sql/SQLTest.java
+++ b/libcore/sql/src/test/java/tests/sql/SQLTest.java
@@ -42,13 +42,13 @@
protected void getSQLiteConnection() {
String tmp = System.getProperty("java.io.tmpdir");
assertEquals(tmp,System.getProperty("java.io.tmpdir"));
- File ctsDir = new File(tmp);
+ File tmpDir = new File(tmp);
try {
- if (ctsDir.isDirectory()) {
- dbFile = File.createTempFile("sqliteTest", ".db", ctsDir);
+ if (tmpDir.isDirectory()) {
+ dbFile = File.createTempFile("sqliteTest", ".db", tmpDir);
dbFile.deleteOnExit();
} else {
- System.err.println("ctsdir does not exist");
+ System.err.println("java.io.tmpdir does not exist");
}
Class.forName("SQLite.JDBCDriver").newInstance();
diff --git a/libcore/sql/src/test/java/tests/sql/StatementTest.java b/libcore/sql/src/test/java/tests/sql/StatementTest.java
index 7568ac8..21560c2 100755
--- a/libcore/sql/src/test/java/tests/sql/StatementTest.java
+++ b/libcore/sql/src/test/java/tests/sql/StatementTest.java
@@ -281,6 +281,7 @@
method = "execute",
args = {java.lang.String.class}
)
+ @KnownFailure("Return value wrong for queries below.")
public void testExecute() throws SQLException {
String[] queries = {
@@ -292,15 +293,15 @@
"select animal_id, address from hutch where animal_id=1;",
"create view address as select address from hutch where animal_id=2",
"drop view address;", "drop table hutch;" };
- boolean[] results = {true, true, true, true, true, true, true,
- true, true};
+ boolean[] results = {false, false, false, false, false, true, false,
+ false, false};
for (int i = 0; i < queries.length; i++) {
Statement st = null;
try {
st = conn.createStatement();
boolean res = st.execute(queries[i]);
- assertEquals(results[i], res);
+ assertEquals("different result for statement no. "+i, results[i], res);
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
@@ -361,11 +362,14 @@
try {
st = conn.createStatement();
st.execute(queries[i], Statement.NO_GENERATED_KEYS);
+ fail("Exception expected: Not supported");
+ /*
ResultSet rs = st.getGeneratedKeys();
fail("Revise test implemenation for feature impl. has changed");
assertFalse(rs.next());
+ */
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ // ok
} finally {
try {
st.close();
@@ -379,11 +383,14 @@
try {
st = conn.createStatement();
st.execute(queries[i], Statement.RETURN_GENERATED_KEYS);
+ fail("Exception expected: Not supported");
+ /*
ResultSet rs = st.getGeneratedKeys();
fail("Revise test implemenation for feature impl. has changed");
assertFalse(rs.next());
+ */
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ //ok
} finally {
try {
st.close();
@@ -418,7 +425,7 @@
}
try {
- conn.close();
+ st.close();
st.getConnection();
fail("Exception expected");
} catch (SQLException e) {
@@ -432,8 +439,8 @@
* @test java.sql.Statement#getFetchDirection()
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "SQLException test fails",
+ level = TestLevel.SUFFICIENT,
+ notes = "SQLException test fails. Not all Fetch directions supported.",
method = "getFetchDirection",
args = {}
)
@@ -444,7 +451,21 @@
st = conn.createStatement();
assertEquals(ResultSet.FETCH_UNKNOWN, st.getFetchDirection());
} catch (SQLException e) {
- fail("SQLException is thrown" + e.getMessage());
+ fail("SQLException is thrown " + e.getMessage());
+ } finally {
+ try {
+ st.close();
+ } catch (SQLException ee) {
+ }
+ }
+
+ try {
+ st = conn.createStatement();
+ st.setFetchDirection(ResultSet.FETCH_FORWARD);
+ assertEquals(ResultSet.FETCH_FORWARD, st.getFetchDirection());
+ fail("Exception expected: not supported");
+ } catch (SQLException e) {
+ // ok
} finally {
try {
st.close();
@@ -475,11 +496,12 @@
try {
st = conn.createStatement();
st.setFetchDirection(ResultSet.FETCH_FORWARD);
+ st.executeQuery("select * from zoo;");
fail("Revise test implemenation for feature impl. has changed");
// assertEquals(ResultSet.FETCH_FORWARD, st.getFetchDirection());
} catch (SQLException e) {
// fail("SQLException is thrown: " + e.getMessage());
- assertEquals("not supported", e.getMessage());
+ //ok
} finally {
try {
st.close();
@@ -531,6 +553,7 @@
Statement st = null;
try {
st = conn.createStatement();
+ st.execute("select * from zoo;");
assertEquals(1, st.getFetchSize());
} catch (SQLException e) {
fail("SQLException is thrown");
@@ -542,6 +565,7 @@
}
try {
+ st.close();
st.getFetchSize();
fail("Exception expected");
} catch (SQLException e) {
@@ -568,7 +592,7 @@
try {
st.setFetchSize(i);
assertEquals(i, st.getFetchSize());
- fail("Revise test implemenation for feature impl. has changed");
+ fail("Revise: test implemenation for feature impl. has changed");
} catch (SQLException sqle) {
// fail("SQLException is thrown: " + sqle.toString());
assertEquals("not supported", sqle.getMessage());
@@ -653,7 +677,6 @@
for (int i = 200; i < 500; i += 50) {
try {
st.setMaxFieldSize(i);
- assertEquals(i, st.getMaxFieldSize());
fail("Revise test implemenation for feature impl. has changed");
} catch (SQLException sqle) {
assertEquals("not supported", sqle.getMessage());
@@ -685,6 +708,7 @@
Statement st = null;
try {
st = conn.createStatement();
+ st.execute("select * from zoo;");
for (int i = 0; i < 300; i += 50) {
try {
st.setMaxRows(i);
@@ -825,13 +849,16 @@
st = conn.createStatement();
for (int i = 0; i < queries.length; i++) {
st.execute(queries[i], (int[]) array.elementAt(i));
+ fail("SQLException expected: not supported");
}
+ /*
fail("Revise test implemenation for feature impl. has changed");
assertNotNull(st.getResultSet());
st.close();
assertNull(st.getResultSet());
+ */
} catch (SQLException e) {
- assertEquals("not supported",e.getMessage());
+ // ok: not supported
// fail("SQLException is thrown: " + e.getMessage());
} finally {
try {
@@ -867,15 +894,14 @@
st = conn.createStatement();
for (int i = 0; i < queries.length; i++) {
st.execute(queries[i], (String[]) array.elementAt(i));
+ fail("Exception expected: not supported");
}
fail("Revise test implemenation for feature impl. has changed");
assertNotNull(st.getResultSet());
st.close();
assertNull(st.getResultSet());
} catch (SQLException e) {
- assertEquals("not supported",e.getMessage());
-// fail("SQLException is thrown: " + e.getMessage());
- } finally {
+ // ok: not supported
try {
st.close();
} catch (SQLException ee) {
@@ -910,7 +936,7 @@
"create view address as select address from hutch where animal_id=2;",
"drop view address;", "drop table hutch;" };
- int[] result = { 1, 1, 1, 1, 1, 1, 1, 2 };
+ int[] result = { 1, 1, 1, 1, 1, 1, 1, 1 };
Statement st = null;
//Exception test
@@ -954,8 +980,9 @@
st = conn.createStatement();
st.addBatch("select * from zoo");
st.executeBatch();
+ fail("Exception expected");
} catch (BatchUpdateException bue) {
- fail("BatchUpdateException is thrown: " + bue.toString());
+ // ok select returns a resultSet
} catch (SQLException sqle) {
fail("Unknown SQLException is thrown: " + sqle.getMessage());
} finally {
@@ -966,6 +993,7 @@
}
//Exception test
try {
+ st.close();
st.executeBatch();
fail("SQLException not thrown");
} catch (SQLException e) {
@@ -1043,6 +1071,7 @@
}
/**
+ * @throws SQLException
* @test java.sql.Statement#executeUpdate(String sql)
*/
@TestTargetNew(
@@ -1051,8 +1080,10 @@
method = "executeUpdate",
args = {java.lang.String.class}
)
- @KnownFailure("Returns wrong value for updates")
- public void testExecuteUpdate_String() {
+ @KnownFailure("Spec is not precise enough: should be: number of rows affected."+
+ " eg. to be consistent for deletes: 'delete from s1;' should be different from "+
+ "'delete from s1 where c1 = 1;' ")
+ public void testExecuteUpdate_String() throws SQLException {
String[] queries1 = {
"update zoo set name='Masha', family='cat' where id=2;",
@@ -1060,12 +1091,11 @@
"create table hutch (id integer not null, animal_id integer, address char(20), primary key (id));",
"insert into hutch (id, animal_id, address) values (1, 2, 'Birds-house, 1');",
"insert into hutch (id, animal_id, address) values (2, 1, 'Horse-house, 5');",
- "create view address as select address from hutch where animal_id=2",
- "drop view address;", "drop table hutch;" };
+ "create view address as select address from hutch where animal_id=2;",
+ "drop view address;", "drop table hutch;"};
- String[] queries2 = { "select * from zoo",
- "select name, family from zoo where id = 1" };
-
+ String queries2 = "select * from zoo;";
+
Statement st = null;
try {
st = conn.createStatement();
@@ -1078,16 +1108,12 @@
}
}
- for (int i = 0; i < queries2.length; i++) {
- try {
- int count = st.executeUpdate(queries2[i]);
- assertEquals(0, count);
- // according to spec should return 0 for 0 manipulated rows
- } catch (SQLException e) {
- // expected
- fail("SQLException is thrown: " + e.getMessage());
- }
+ try {
+ assertEquals(0, st.executeUpdate(queries2));
+ } catch (SQLException e) {
+ fail("SQLException is thrown: " + e.getMessage());
}
+
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
} finally {
@@ -1095,7 +1121,36 @@
st.close();
} catch (Exception ee) {
}
- }
+ }
+
+ // test return value for specific numbers
+
+ Statement stat = conn.createStatement();
+
+ // there are 0 rows created therefore 0 should be returned.
+ assertEquals(0 ,stat.executeUpdate("create table s1 (c1);"));
+
+ assertEquals(1, stat.executeUpdate("insert into s1 values (0);"));
+ assertEquals(1, stat.executeUpdate("insert into s1 values (1);"));
+ assertEquals(1, stat.executeUpdate("insert into s1 values (2);"));
+ assertEquals(1,stat.executeUpdate("delete from s1 where c1 = 1;"));
+ assertEquals(2, stat.executeUpdate("update s1 set c1 = 5;"));
+
+ // analogous to statemente before, delete all should return 2
+ assertEquals(2,stat.executeUpdate("delete from s1;"));
+
+ // there are no rows in table: 0 should be returned
+ assertEquals(0, stat.executeUpdate("drop table s1;"));
+
+ stat.executeUpdate("create table s1 (c1);");
+ stat.executeUpdate("insert into s1 values (0);");
+ stat.executeUpdate("insert into s1 values (1);");
+ stat.executeUpdate("insert into s1 values (2);");
+
+ // there are 3 rows in table: 3 should be returned
+ assertEquals(3, stat.executeUpdate("drop table s1;"));
+
+ stat.close();
}
/**
@@ -1134,8 +1189,8 @@
st = conn.createStatement();
for (int i = 0; i < queries1.length; i++) {
st.executeUpdate(queries1[i], (int[]) array.elementAt(i));
+ fail("Exception expected");
}
- fail("Revise test implemenation for feature impl. has changed");
} catch (SQLException e) {
assertEquals("not supported",e.getMessage());
// fail("SQLException is thrown: " + e.getMessage());
@@ -1153,7 +1208,7 @@
* TODO executeUpdate(String sql, int autoGeneratedKeys) is not supported
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.SUFFICIENT,
notes = "not supported",
method = "executeUpdate",
args = {java.lang.String.class, int.class}
@@ -1169,26 +1224,39 @@
"create view address as select address from hutch where animal_id=2",
"drop view address;", "drop table hutch;" };
- for (int i = 0; i < queries.length; i++) {
Statement st = null;
ResultSet rs = null;
try {
st = conn.createStatement();
- st.executeUpdate(queries[i], Statement.NO_GENERATED_KEYS);
+ st.executeUpdate(queries[1], Statement.NO_GENERATED_KEYS);
rs = st.getGeneratedKeys();
- fail("Revise test implemenation for feature impl. has changed");
assertFalse(rs.next());
+ fail("Exception expected: not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
-// fail("SQLException is thrown: " + e.getMessage());
+ //ok
} finally {
try {
rs.close();
st.close();
} catch (Exception ee) {
}
- }
- }
+ }
+
+ try {
+ st = conn.createStatement();
+ st.executeUpdate(queries[1], Statement.RETURN_GENERATED_KEYS);
+ rs = st.getGeneratedKeys();
+ assertTrue(rs.next());
+ fail("Exception expected: not supported");
+ } catch (SQLException e) {
+ //ok
+ } finally {
+ try {
+ rs.close();
+ st.close();
+ } catch (Exception ee) {
+ }
+ }
}
/**
@@ -1230,8 +1298,8 @@
st = conn.createStatement();
for (int i = 0; i < queries.length; i++) {
st.executeUpdate(queries[i], (String[]) array.elementAt(i));
+ fail("Revise test implemenation for feature impl. has changed");
}
- fail("Revise test implemenation for feature impl. has changed");
} catch (SQLException e) {
assertEquals("not supported", e.getMessage());
// fail("SQLException is thrown: " + e.getMessage());
@@ -1258,7 +1326,6 @@
try {
String query = "update zoo set name='Masha', family='cat' where id=2;";
st = conn.createStatement();
- assertEquals(0, st.getUpdateCount());
st.executeUpdate(query);
assertEquals(1, st.getUpdateCount());
query = "update zoo set name='Masha', family='cat' where id=5;";
@@ -1287,7 +1354,7 @@
* TODO getGeneratedKeys() is not supported
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.SUFFICIENT,
notes = "not supported",
method = "getGeneratedKeys",
args = {}
@@ -1310,7 +1377,7 @@
* TODO setCursorName() is not supported
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.SUFFICIENT,
notes = "not supported",
method = "setCursorName",
args = {java.lang.String.class}
@@ -1333,7 +1400,7 @@
* TODO setExcapeProcessing() is not supported
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.SUFFICIENT,
notes = "not supported",
method = "setEscapeProcessing",
args = {boolean.class}
@@ -1449,19 +1516,19 @@
*
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.SUFFICIENT,
notes = "not supported",
method = "getResultSetHoldability",
args = {}
)
+ @KnownFailure("Test for default value fails")
public void testGetResultSetHoldability() {
// test default value
Statement st = null;
try {
st = conn.createStatement();
- st.getResultSetHoldability();
- assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, st
+ assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, st
.getResultSetHoldability());
} catch (SQLException e) {
assertEquals("not supported", e.getMessage());
@@ -1472,22 +1539,28 @@
st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
+ fail("Exception expected: not supported");
+ /*
st.getResultSetHoldability();
assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, st
.getResultSetHoldability());
+ */
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ // ok: not supported
}
try {
st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY,
ResultSet.CLOSE_CURSORS_AT_COMMIT);
+ fail("Exception expected: not supported");
+ /*
st.getResultSetHoldability();
assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, st
.getResultSetHoldability());
+ */
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ // ok: not supported
}
}
@@ -1496,12 +1569,12 @@
*
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
+ level = TestLevel.SUFFICIENT,
notes = "Tests fail. returns only ResultSet.TYPE_SCROLL_INSENSITIVE. Either should throw an unsupported exception or behave according to spec.",
method = "getResultSetConcurrency",
args = {}
)
- @KnownFailure("Not fully supported")
+ @KnownFailure("Not supported")
public void testGetResultSetConcurrency() {
Statement st = null;
@@ -1514,16 +1587,7 @@
} catch (SQLException e) {
assertEquals("not supported", e.getMessage());
}
-
-
- try {
- st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
- ResultSet.CONCUR_READ_ONLY);
- st.getResultSetConcurrency();
- assertEquals(ResultSet.CONCUR_READ_ONLY, st.getResultSetConcurrency());
- } catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
- }
+
// failing tests
try {
@@ -1531,10 +1595,21 @@
ResultSet.CONCUR_UPDATABLE);
st.getResultSetConcurrency();
assertEquals(ResultSet.CONCUR_UPDATABLE, st.getResultSetConcurrency());
+ fail("Exception expected: not supported");
} catch (SQLException e) {
- assertEquals("not supported", e.getMessage());
+ //ok
}
+
+ try {
+ st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.CONCUR_READ_ONLY);
+ st.getResultSetConcurrency();
+ assertEquals(ResultSet.CONCUR_READ_ONLY, st.getResultSetConcurrency());
+ fail("Exception expected: not supported");
+ } catch (SQLException e) {
+ //ok;
+ }
}
/**
@@ -1547,7 +1622,7 @@
method = "getResultSet",
args = {}
)
- @KnownFailure("Does not return null on update count > 0")
+ @KnownFailure("Does not return null on update count > 0 (not a select statement) ")
public void testGetResultSet() {
Statement st = null;
ResultSet res = null;
@@ -1555,39 +1630,35 @@
try {
st = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY,
- ResultSet.HOLD_CURSORS_OVER_COMMIT);
+ ResultSet.CLOSE_CURSORS_AT_COMMIT);
+ st.execute("create table test (c1);");
res = st.getResultSet();
assertNull(res);
} catch (SQLException e) {
- fail("SQLException is thrown");
+ fail("Unexpected Exception "+e);
}
try {
- assertNull(st.getResultSet());
- } catch (SQLException e) {
- fail("SQLException is thrown");
- }
-
- try {
+ st = conn.createStatement();
String select = "select * from zoo where id == 4;";
String insert = "insert into zoo (id, name, family) values (4, 'Vorobuy', 'bear');";
st.execute(insert);
st.execute(select);
+ assertEquals(-1, st.getUpdateCount());
res = st.getResultSet();
assertNotNull(res);
res.next();
assertEquals(4,res.getInt(1));
assertEquals("Vorobuy",res.getString(2));
assertEquals("bear",res.getString(3));
-// assertEquals(0, st.getUpdateCount());
-
+// assertEquals(0, st.getUpdateCount()); not supported
assertFalse(res.next());
} catch (SQLException e) {
fail("SQLException is thrown:"+e.getMessage());
}
try {
- assertEquals(0, st.getUpdateCount());
+ st = conn.createStatement();
String insert = "insert into zoo (id, name, family) values (3, 'Vorobey', 'sparrow');";
st
.execute(insert);
@@ -1651,21 +1722,13 @@
* @test {@link java.sql.Statement#getMoreResults()}
*
*/
- @TestTargets({
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Test fails. It can never be that getMoreResults == true and updateCounts > 0, according to spec (see spec of getResultSet).Error seems to be related with malfunction of SQLite.Database.changes",
+ level = TestLevel.SUFFICIENT,
+ notes = "not fully supported",
method = "getMoreResults",
args = {}
- ),
- @TestTargetNew(
- level = TestLevel.PARTIAL_COMPLETE,
- notes = "Test fails. It can never be that getMoreResults == true and updateCounts > 0, according to spec (see spec of getResultSet).Error seems to be related with malfunction of SQLite.Database.changes",
- method = "getUpdateCount",
- args = {}
- )
- })
- @KnownFailure("Precondition fails. dependendancy with getUpdateCount")
+ )
+ @KnownFailure("not supported")
public void testGetMoreResults() {
Statement st = null;
ResultSet res1 = null;
@@ -1673,46 +1736,18 @@
String[] queries = {
"insert into zoo values (3,'John','bird');",
"update zoo set name='Masha', family='cat' where id=3;",
- "update zoo set name='Masha', family='bear' where id=3;",
- "select * from zoo;"};
-
- int[] updates = {1, 1, 1, 0};
- try {
+ "update zoo set name='Masha', family='bear' where id=3;"};
+
+ try {
st = conn.createStatement();
- for (int i = 0; i < queries.length; i++) {
- st.addBatch(queries[i]);
- }
- int[] updateCounts = st.executeBatch();
- //Precondition
- assertTrue(java.util.Arrays.equals(updateCounts, updates));
-
- assertTrue((st.getMoreResults() == false)
- && (st.getUpdateCount() == 1));
- res1 = st.getResultSet();
- assertNull(res1);
-
- assertTrue((st.getMoreResults() == false)
- && (st.getUpdateCount() == 1));
- res2 = st.getResultSet();
- assertNull(res2);
-
- assertTrue((st.getMoreResults() == false)
- && (st.getUpdateCount() == 1));
- res1 = st.getResultSet();
- assertNull(res1);
-
- assertTrue((st.getMoreResults() == true)
- && (st.getUpdateCount() == 0));
- res1 = st.getResultSet();
- assertNotNull(res1);
-
- assertTrue((st.getMoreResults() == false)
- && (st.getUpdateCount() == -1));
+ st.execute(queries[0]);
+ assertFalse(st.getMoreResults());
+
try {
st.getResultSet();
+ fail("Exception expected");
} catch (SQLException e) {
- //error expected
- assertEquals("statement already closed", e.getMessage());
+ //ok
}
} catch (SQLException e) {
fail("SQLException is thrown: " + e.getMessage());
@@ -1736,75 +1771,15 @@
*
*/
@TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "not supported",
+ level = TestLevel.NOT_FEASIBLE,
+ notes = "Callable Statements are not supported",
method = "getMoreResults",
args = {int.class}
)
public void testGetMoreResultsInt() {
- Statement st = null;
- ResultSet res1 = null;
- ResultSet res2 = null;
- ResultSet notClosedResult = null;
- ResultSet notClosedResult2 = null;
- String[] queries = {
- "insert into zoo values (3,'John','bird');",
- "update zoo set name='Masha', family='cat' where id=3;",
- "select * from zoo;",
- "insert into zoo values (6,'Tweety','bird');",
- "select * from zoo;"};
-
- try {
- st = conn.createStatement();
- for (int i = 0; i < queries.length; i++) {
- st.addBatch(queries[i]);
- }
- int[] updateCounts = st.executeBatch();
-
- //insert
- assertTrue((st.getMoreResults(Statement.CLOSE_CURRENT_RESULT) == false)
- && (st.getUpdateCount() == 1));
- res1 = st.getResultSet();
- assertNull(res1);
-
-
- //update
- assertTrue((st.getMoreResults(Statement.CLOSE_CURRENT_RESULT) == false)
- && (st.getUpdateCount() == 1));
- res2 = st.getResultSet();
- assertNull(res2);
-
- //select
- assertTrue((st.getMoreResults(Statement.KEEP_CURRENT_RESULT) == true)
-// && (st.getUpdateCount() == 0)
- );
- notClosedResult = st.getResultSet();
- assertNotNull(notClosedResult);
-
- //insert
- assertTrue((st.getMoreResults(Statement.CLOSE_CURRENT_RESULT) == false)
- && (st.getUpdateCount() == 1));
- res1 = st.getResultSet();
- assertNotNull(res1);
-
- //select
- assertTrue((st.getMoreResults(Statement.KEEP_CURRENT_RESULT) == true)
-// && (st.getUpdateCount() == 0)
- );
- notClosedResult2 = st.getResultSet();
- assertNotNull(notClosedResult2);
- assertFalse(notClosedResult.equals(notClosedResult2));
-
- // end
- assertTrue((st.getMoreResults() == false)
- && (st.getUpdateCount() == -1));
- try {
- st.getResultSet();
- } catch (SQLException e) {
- //error expected
- assertEquals("statement already closed", e.getMessage());
- }
-
+ /*
+ } catch (BatchUpdateException e) {
+ fail("Unexpected Exception "+e.getMessage());
} catch (SQLException e) {
assertEquals("not supported",e.getMessage());
} finally {
@@ -1815,11 +1790,12 @@
}
try {
- st.getMoreResults(Statement.CLOSE_CURRENT_RESULT);
+ st.getMoreResults(Integer.MAX_VALUE);
fail("Exception expected");
} catch (SQLException e) {
//ok
}
+ */
}
/**
diff --git a/libcore/sql/src/test/java/tests/support/MockFunction.java b/libcore/sql/src/test/java/tests/support/MockFunction.java
index 8f78895..de4e9f5 100644
--- a/libcore/sql/src/test/java/tests/support/MockFunction.java
+++ b/libcore/sql/src/test/java/tests/support/MockFunction.java
@@ -22,18 +22,25 @@
public class MockFunction implements SQLite.Function{
private StringBuffer acc = new StringBuffer();
+ public static boolean getAggValueCalled = false;
+ public static boolean functionCalled = false;
+ public static boolean stepCalled = false;
+ public static boolean lastStepCalled = false;
public String getAggValue() {
+ getAggValueCalled = true;
return acc.toString();
}
public void function(FunctionContext fc, String args[]) {
+ functionCalled = true;
if (args.length > 0) {
fc.set_result(args[0].toLowerCase());
}
}
public void step(FunctionContext fc, String args[]) {
+ stepCalled = true;
for (int i = 0; i < args.length; i++) {
acc.append(args[i]);
acc.append(" ");
@@ -41,6 +48,7 @@
}
public void last_step(FunctionContext fc) {
+ lastStepCalled = true;
fc.set_result(acc.toString());
}
}
\ No newline at end of file
diff --git a/libcore/sql/src/test/java/tests/support/Support_SQL.java b/libcore/sql/src/test/java/tests/support/Support_SQL.java
index 71dccc0..1f63f15 100644
--- a/libcore/sql/src/test/java/tests/support/Support_SQL.java
+++ b/libcore/sql/src/test/java/tests/support/Support_SQL.java
@@ -52,12 +52,12 @@
.getResourceAsStream("/connection.properties"));
String tmp = System.getProperty("java.io.tmpdir");
- File ctsDir = new File(tmp);
- if (ctsDir.isDirectory()) {
- dbFile = File.createTempFile("sqliteTest", ".db", ctsDir);
+ File tmpDir = new File(tmp);
+ if (tmpDir.isDirectory()) {
+ dbFile = File.createTempFile("sqliteTest", ".db", tmpDir);
dbFile.deleteOnExit();
} else {
- System.err.println("ctsdir does not exist");
+ System.err.println("java.io.tmpdir does not exist");
}
Class.forName("SQLite.JDBCDriver").newInstance();
diff --git a/libcore/sql/src/test/java/tests/support/ThreadPool.java b/libcore/sql/src/test/java/tests/support/ThreadPool.java
index 37e87f7..6e82f25 100644
--- a/libcore/sql/src/test/java/tests/support/ThreadPool.java
+++ b/libcore/sql/src/test/java/tests/support/ThreadPool.java
@@ -104,7 +104,6 @@
}
if (task == null) {
- Logger.global.info("Task is null");
return;
}
diff --git a/libcore/support/src/test/java/org/apache/harmony/security/tests/support/MySignature1.java b/libcore/support/src/test/java/org/apache/harmony/security/tests/support/MySignature1.java
index 48c3d31..2703b0f 100644
--- a/libcore/support/src/test/java/org/apache/harmony/security/tests/support/MySignature1.java
+++ b/libcore/support/src/test/java/org/apache/harmony/security/tests/support/MySignature1.java
@@ -79,6 +79,13 @@
protected void engineUpdate(byte[] b, int off, int len)
throws SignatureException {
+ if (b == null) throw new NullPointerException();
+ if (off < 0 || off > b.length || off > len) {
+ throw new IllegalArgumentException("incorrect parameter off");
+ }
+ if (len < 0 || len > b.length) {
+ throw new IllegalArgumentException("incorrect parameter len");
+ }
runEngineUpdate2 = true;
}
diff --git a/libcore/support/src/test/java/org/apache/harmony/security/tests/support/cert/TestUtils.java b/libcore/support/src/test/java/org/apache/harmony/security/tests/support/cert/TestUtils.java
index 5d9a6bd..6f9cbd2 100644
--- a/libcore/support/src/test/java/org/apache/harmony/security/tests/support/cert/TestUtils.java
+++ b/libcore/support/src/test/java/org/apache/harmony/security/tests/support/cert/TestUtils.java
@@ -545,6 +545,7 @@
// Second example
/**
* Certificate:
+ * <pre>
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
@@ -588,6 +589,7 @@
99:1c:f5:cb:77:86:36:cd:43:37:99:09:c2:9a:d8:f2:28:05:
06:0c
+ * </pre>
*/
public static final String rootCert = "-----BEGIN CERTIFICATE-----\n" +
"MIIDGzCCAoSgAwIBAgIBADANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJBTjEQ\n" +
@@ -631,6 +633,7 @@
/**
* Certificate:
+ * <pre>
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
@@ -673,6 +676,7 @@
ba:b4:a2:c7:2c:cb:b1:3a:c2:d8:0c:21:31:ee:68:7e:97:ce:
98:22:2e:c6:cf:f0:1a:11:04:ca:9a:06:de:98:48:85:ac:6c:
6f:98
+ * </pre>
*/
public static final String endCert =
"-----BEGIN CERTIFICATE-----\n" +
diff --git a/libcore/support/src/test/java/org/apache/harmony/testframework/serialization/SerializationTest.java b/libcore/support/src/test/java/org/apache/harmony/testframework/serialization/SerializationTest.java
index 9db5382..34b5f0d 100644
--- a/libcore/support/src/test/java/org/apache/harmony/testframework/serialization/SerializationTest.java
+++ b/libcore/support/src/test/java/org/apache/harmony/testframework/serialization/SerializationTest.java
@@ -534,13 +534,13 @@
private static Serializable getObject(TestCase test, String toAppend)
throws Exception {
- StringBuilder path = new StringBuilder("serialization");
+ StringBuilder path = new StringBuilder("/serialization");
path.append(File.separatorChar);
path.append(test.getClass().getName().replace('.', File.separatorChar));
path.append(toAppend);
- InputStream in = ClassLoader.getSystemClassLoader()
+ InputStream in = SerializationTest.class
.getResourceAsStream(path.toString());
Assert.assertNotNull("Failed to load serialization resource file: "
diff --git a/libcore/support/src/test/java/targets/KeyAgreement.java b/libcore/support/src/test/java/targets/KeyAgreement.java
new file mode 100644
index 0000000..48bd7d9
--- /dev/null
+++ b/libcore/support/src/test/java/targets/KeyAgreement.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package targets;
+
+import dalvik.annotation.VirtualTestTarget;
+
+/**
+ * @hide
+ */
+public interface KeyAgreement {
+ /**
+ * @hide
+ */
+ abstract class Internal {
+ protected Internal() {
+ }
+ }
+
+ @VirtualTestTarget
+ static abstract class DH extends Internal {
+ protected abstract void method();
+ }
+}
diff --git a/libcore/support/src/test/java/targets/Mac.java b/libcore/support/src/test/java/targets/Mac.java
new file mode 100644
index 0000000..d1ec21a
--- /dev/null
+++ b/libcore/support/src/test/java/targets/Mac.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package targets;
+
+import dalvik.annotation.VirtualTestTarget;
+
+/**
+ * @hide
+ */
+public interface Mac {
+ /**
+ * @hide
+ */
+ abstract class Internal {
+ protected Internal() {
+ }
+ }
+
+ @VirtualTestTarget
+ static abstract class HMACMD5 extends Internal {
+ protected abstract void method();
+ }
+
+ @VirtualTestTarget
+ static abstract class HMACSHA1 extends Internal {
+ protected abstract void method();
+ }
+
+ @VirtualTestTarget
+ static abstract class HMACSHA256 extends Internal {
+ protected abstract void method();
+ }
+
+ @VirtualTestTarget
+ static abstract class HMACSHA384 extends Internal {
+ protected abstract void method();
+ }
+
+ @VirtualTestTarget
+ static abstract class HMACSHA512 extends Internal {
+ protected abstract void method();
+ }
+}
diff --git a/libcore/support/src/test/java/targets/SecretKeyFactory.java b/libcore/support/src/test/java/targets/SecretKeyFactory.java
new file mode 100644
index 0000000..133b3e3
--- /dev/null
+++ b/libcore/support/src/test/java/targets/SecretKeyFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package targets;
+
+import dalvik.annotation.VirtualTestTarget;
+
+/**
+ * @hide
+ */
+public interface SecretKeyFactory {
+ /**
+ * @hide
+ */
+ abstract class Internal {
+ protected Internal() {
+ }
+ }
+
+ @VirtualTestTarget
+ static abstract class DES extends Internal {
+ protected abstract void method();
+ }
+
+ @VirtualTestTarget
+ static abstract class DESede extends Internal {
+ protected abstract void method();
+ }
+
+ @VirtualTestTarget
+ static abstract class PBEWITHMD5ANDDES extends Internal {
+ protected abstract void method();
+ }
+}
diff --git a/libcore/support/src/test/java/targets/Signatures.java b/libcore/support/src/test/java/targets/Signatures.java
index 3296df6..0d69d9b 100644
--- a/libcore/support/src/test/java/targets/Signatures.java
+++ b/libcore/support/src/test/java/targets/Signatures.java
@@ -23,27 +23,22 @@
}
@VirtualTestTarget
- static abstract class SHA256withRSA extends Internal {
- protected abstract void method();
- }
-
- @VirtualTestTarget
- static abstract class NONEwithDSA extends Internal {
- protected abstract void method();
- }
-
- @VirtualTestTarget
- static abstract class SHA1withRSA extends Internal {
- protected abstract void method();
- }
-
- @VirtualTestTarget
static abstract class SHA384withRSA extends Internal {
protected abstract void method();
}
@VirtualTestTarget
- static abstract class SHA1withDSA extends Internal {
+ static abstract class SHA256withRSA extends Internal {
+ protected abstract void method();
+ }
+
+ @VirtualTestTarget
+ static abstract class SHA224withRSA extends Internal {
+ protected abstract void method();
+ }
+
+ @VirtualTestTarget
+ static abstract class SHA1withRSA extends Internal {
protected abstract void method();
}
@@ -56,4 +51,14 @@
static abstract class MD2withRSA extends Internal {
protected abstract void method();
}
+
+ @VirtualTestTarget
+ static abstract class SHA1withDSA extends Internal {
+ protected abstract void method();
+ }
+
+ @VirtualTestTarget
+ static abstract class NONEwithDSA extends Internal {
+ protected abstract void method();
+ }
}
diff --git a/libcore/support/src/test/java/tests/resources/Package/hyts_all_attributes_dex.jar b/libcore/support/src/test/java/tests/resources/Package/hyts_all_attributes_dex.jar
new file mode 100644
index 0000000..b9da43f
--- /dev/null
+++ b/libcore/support/src/test/java/tests/resources/Package/hyts_all_attributes_dex.jar
Binary files differ
diff --git a/libcore/support/src/test/java/tests/resources/Package/hyts_c_dex.jar b/libcore/support/src/test/java/tests/resources/Package/hyts_c_dex.jar
new file mode 100644
index 0000000..cc2ba1b
--- /dev/null
+++ b/libcore/support/src/test/java/tests/resources/Package/hyts_c_dex.jar
Binary files differ
diff --git a/libcore/support/src/test/java/tests/resources/Package/hyts_no_attributes_dex.jar b/libcore/support/src/test/java/tests/resources/Package/hyts_no_attributes_dex.jar
new file mode 100644
index 0000000..b3c61ef
--- /dev/null
+++ b/libcore/support/src/test/java/tests/resources/Package/hyts_no_attributes_dex.jar
Binary files differ
diff --git a/libcore/support/src/test/java/tests/resources/Package/hyts_no_entry_dex.jar b/libcore/support/src/test/java/tests/resources/Package/hyts_no_entry_dex.jar
new file mode 100644
index 0000000..76777f6
--- /dev/null
+++ b/libcore/support/src/test/java/tests/resources/Package/hyts_no_entry_dex.jar
Binary files differ
diff --git a/libcore/support/src/test/java/tests/resources/Package/hyts_package_dex.jar b/libcore/support/src/test/java/tests/resources/Package/hyts_package_dex.jar
new file mode 100644
index 0000000..837ad0d
--- /dev/null
+++ b/libcore/support/src/test/java/tests/resources/Package/hyts_package_dex.jar
Binary files differ
diff --git a/libcore/support/src/test/java/tests/resources/Package/hyts_pq_dex.jar b/libcore/support/src/test/java/tests/resources/Package/hyts_pq_dex.jar
new file mode 100644
index 0000000..cc45dc9
--- /dev/null
+++ b/libcore/support/src/test/java/tests/resources/Package/hyts_pq_dex.jar
Binary files differ
diff --git a/libcore/support/src/test/java/tests/resources/Package/hyts_some_attributes_dex.jar b/libcore/support/src/test/java/tests/resources/Package/hyts_some_attributes_dex.jar
new file mode 100644
index 0000000..46ab8b9
--- /dev/null
+++ b/libcore/support/src/test/java/tests/resources/Package/hyts_some_attributes_dex.jar
Binary files differ
diff --git a/libcore/support/src/test/java/tests/resources/cts_dalvikExecTest.jar b/libcore/support/src/test/java/tests/resources/cts_dalvikExecTest.jar
new file mode 100644
index 0000000..b6af791
--- /dev/null
+++ b/libcore/support/src/test/java/tests/resources/cts_dalvikExecTest.jar
Binary files differ
diff --git a/libcore/support/src/test/java/tests/resources/cts_dalvikExecTest_classes.dex b/libcore/support/src/test/java/tests/resources/cts_dalvikExecTest_classes.dex
new file mode 100644
index 0000000..415c50a
--- /dev/null
+++ b/libcore/support/src/test/java/tests/resources/cts_dalvikExecTest_classes.dex
Binary files differ
diff --git a/libcore/support/src/test/java/tests/resources/hyts_signed_inc.jar b/libcore/support/src/test/java/tests/resources/hyts_signed_inc.jar
new file mode 100644
index 0000000..d75ce08
--- /dev/null
+++ b/libcore/support/src/test/java/tests/resources/hyts_signed_inc.jar
Binary files differ
diff --git a/libcore/support/src/test/java/tests/support/Support_Exec.java b/libcore/support/src/test/java/tests/support/Support_Exec.java
index cec7934..eb55d67 100644
--- a/libcore/support/src/test/java/tests/support/Support_Exec.java
+++ b/libcore/support/src/test/java/tests/support/Support_Exec.java
@@ -29,6 +29,12 @@
public class Support_Exec extends TestCase {
+ static final boolean againstDalvik;
+ static {
+ String platform = System.getProperty("java.vendor");
+ againstDalvik = (platform.contains("Android"));
+ }
+
/**
* This function returns the output of the process as a string
*/
@@ -51,7 +57,7 @@
return getProcessOutput(arr, displayOutput);
}
- private static String getProcessOutput(Object[] arr, boolean displayOutput)
+ public static String getProcessOutput(Object[] arr, boolean displayOutput)
throws IOException, InterruptedException {
Process proc = (Process) arr[0];
StringBuilder output = new StringBuilder();
@@ -109,7 +115,11 @@
executable += File.separator;
}
executable += "bin" + File.separator;
- execArgs.add(executable + "dalvikvm");
+ if (againstDalvik) {
+ execArgs.add(executable + "dalvikvm");
+ } else {
+ execArgs.add(executable + "java");
+ }
// add classpath string
if (classpath != null) {
@@ -156,9 +166,24 @@
}
// execute java process
- final Process proc = Runtime.getRuntime().exec(
- execArgs.toArray(new String[execArgs.size()]), envp);
+ return execAndDigestOutput(execArgs.toArray(new String[execArgs.size()]), envp);
+ }
+
+ //
+ // mc: This looks like functionaly worth publicity:
+ //
+ public static Object[] execAndDigestOutput (String[] cmdLine, String[] envp)
+ throws IOException, InterruptedException {
+
+// System.out.println("Commandline BEGIN");
+// for (int i = 0; i < cmdLine.length; i++) {
+// System.out.println(cmdLine[i]);
+// }
+// System.out.println("END");
+
+ final Process proc = Runtime.getRuntime().exec(cmdLine, envp);
final StringBuilder errBuf = new StringBuilder();
+
Thread errThread = new Thread(new Runnable() {
public void run() {
synchronized (errBuf) {
diff --git a/libcore/support/src/test/java/tests/support/Support_SimpleDateFormat.java b/libcore/support/src/test/java/tests/support/Support_SimpleDateFormat.java
index 93257da..a90a4d0 100644
--- a/libcore/support/src/test/java/tests/support/Support_SimpleDateFormat.java
+++ b/libcore/support/src/test/java/tests/support/Support_SimpleDateFormat.java
@@ -96,10 +96,10 @@
// test with simple example
format.applyPattern("h:m z");
- super.text = "5:19 EDT";
+ super.text = "5:19 GMT-05:00";
t_FormatWithField(21, format, date, null, Field.HOUR1, 0, 1);
t_FormatWithField(22, format, date, null, Field.MINUTE, 2, 4);
- t_FormatWithField(23, format, date, null, Field.TIME_ZONE, 5, 8);
+ t_FormatWithField(23, format, date, null, Field.TIME_ZONE, 5, 14);
// test fields that are not included in the formatted text
@@ -125,14 +125,14 @@
// test with simple example with pattern char Z
format.applyPattern("h:m Z z");
- super.text = "5:19 -0400 EDT";
+ super.text = "5:19 -0400 GMT-05:00";
t_FormatWithField(40, format, date, null, Field.HOUR1, 0, 1);
t_FormatWithField(41, format, date, null, Field.MINUTE, 2, 4);
t_FormatWithField(42, format, date, null, Field.TIME_ZONE, 5, 10);
}
public void t_formatToCharacterIterator() {
- TimeZone tz = TimeZone.getTimeZone("EST");
+ TimeZone tz = TimeZone.getTimeZone("GMT-05:00");
Calendar cal = new GregorianCalendar(tz);
cal.set(1999, Calendar.SEPTEMBER, 13, 17, 19, 01);
cal.set(Calendar.MILLISECOND, 0);
@@ -184,11 +184,11 @@
}
private Vector<FieldContainer> getDateVector3() {
- // "5:19 EDT"
+ // "5:19 GMT-05:00"
Vector<FieldContainer> v = new Vector<FieldContainer>();
v.add(new FieldContainer(0, 1, Field.HOUR1));
v.add(new FieldContainer(2, 4, Field.MINUTE));
- v.add(new FieldContainer(5, 8, Field.TIME_ZONE));
+ v.add(new FieldContainer(5, 14, Field.TIME_ZONE));
return v;
}
@@ -208,7 +208,7 @@
// 05
// 005 19 019 1 01 001 0 00 000 Mon Monday 256 256 256 2 02 38 038 3 003
// PM
- // PM 5 005 EDT Eastern Daylight Time -0400 -0400"
+ // PM 5 005 GMT-05:00 GMT-05:00 -0500 -0500"
v.add(new FieldContainer(0, 2, Field.ERA));
v.add(new FieldContainer(3, 5, Field.ERA));
v.add(new FieldContainer(6, 8, Field.YEAR));
@@ -253,10 +253,10 @@
v.add(new FieldContainer(145, 147, Field.AM_PM));
v.add(new FieldContainer(149, 150, Field.HOUR0));
v.add(new FieldContainer(151, 154, Field.HOUR0));
- v.add(new FieldContainer(155, 158, Field.TIME_ZONE));
- v.add(new FieldContainer(159, 180, Field.TIME_ZONE));
+ v.add(new FieldContainer(155, 164, Field.TIME_ZONE));
+ v.add(new FieldContainer(165, 174, Field.TIME_ZONE));
+ v.add(new FieldContainer(175, 180, Field.TIME_ZONE));
v.add(new FieldContainer(181, 186, Field.TIME_ZONE));
- v.add(new FieldContainer(187, 192, Field.TIME_ZONE));
return v;
}
diff --git a/libcore/support/src/test/java/tests/support/resource/Support_Resources.java b/libcore/support/src/test/java/tests/support/resource/Support_Resources.java
index b1e63f6..f15f618 100644
--- a/libcore/support/src/test/java/tests/support/resource/Support_Resources.java
+++ b/libcore/support/src/test/java/tests/support/resource/Support_Resources.java
@@ -17,17 +17,18 @@
package tests.support.resource;
+import tests.support.Support_Configuration;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
-import tests.support.Support_Configuration;
-
public class Support_Resources {
public static final String RESOURCE_PACKAGE = "/tests/resources/";
@@ -78,7 +79,7 @@
return folder;
}
- public static void copyFile(File root, String folder, String file) {
+ public static File copyFile(File root, String folder, String file) {
File f;
if (folder != null) {
f = new File(root.toString() + "/" + folder);
@@ -103,6 +104,8 @@
// TODO Auto-generated catch block
e.printStackTrace();
}
+
+ return dest;
}
public static File createTempFile(String suffix) throws IOException {
@@ -144,17 +147,51 @@
* @return - resource input stream
*/
public static InputStream getResourceStream(String name) {
-
- InputStream is = ClassLoader.getSystemClassLoader()
- .getResourceAsStream(name);
+//ATTENTION:
+// Against class.getResourceStream(name) the name can start with a "/".
+// Against classLoader.getResourceStream NOT!
+
+ InputStream is;
+// is = Support_Resources.class.getClassLoader().getResourceAsStream(name); This would work without leading "/"
+ is = Support_Resources.class.getResourceAsStream(name);
+// is = ClassLoader.getSystemClassLoader().getResourceAsStream(name); This would work without leading "/"
if (is == null) {
- throw new RuntimeException("Failed to load resource: " + name);
+ name = "/tests/resources/" + name;
+ is = Support_Resources.class.getResourceAsStream(name);
+ if (is == null) {
+ throw new RuntimeException("Failed to load resource: " + name);
+ }
}
return is;
}
-
+
+ /**
+ * Util method to write resource files directly to an OutputStream.
+ *
+ * @param name - name of resource file.
+ * @param out - OutputStream to write to.
+ * @return - number of bytes written to out.
+ */
+ public static int writeResourceToStream(String name, OutputStream out) {
+ InputStream input = getResourceStream(name);
+ byte[] buffer = new byte[512];
+ int total = 0;
+ int count;
+ try {
+ count = input.read(buffer);
+ while (count != -1) {
+ out.write(buffer, 0, count);
+ total = total + count;
+ count = input.read(buffer);
+ }
+ return total;
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to write to passed stream.", e);
+ }
+ }
+
/**
* Util method to get absolute path to resource file
*
diff --git a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/AttributedCharacterIteratorAttributeTest.java b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/AttributedCharacterIteratorAttributeTest.java
index 14eb17e..ad4c9ca 100644
--- a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/AttributedCharacterIteratorAttributeTest.java
+++ b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/AttributedCharacterIteratorAttributeTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.harmony.text.tests.java.text;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
@@ -145,8 +144,6 @@
method = "hashCode",
args = {}
)
- @KnownFailure("hashCode method returns equal hash code values for " +
- "non equal objects. This test passes on RI.")
public void test_hashCode() {
try {
MockAttributedCharacterIteratorAttribute mac1 = new MockAttributedCharacterIteratorAttribute(
diff --git a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/AttributedStringTest.java b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/AttributedStringTest.java
index 232f356..86deba5 100644
--- a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/AttributedStringTest.java
+++ b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/AttributedStringTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.harmony.text.tests.java.text;
-import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -148,7 +147,6 @@
method = "AttributedString",
args = {java.text.AttributedCharacterIterator.class, int.class, int.class, java.text.AttributedCharacterIterator.Attribute[].class}
)
- @KnownFailure("ToT FIXED Wrong behaviour if null Attribute Array is passed to AttributedString constructor.")
public void test_ConstructorLAttributedCharacterIterator_3() {
String testString = "Test string";
AttributedString attrString = new AttributedString(testString);
diff --git a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/BidiTest.java b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/BidiTest.java
index 70169d7..e3ea9dc 100644
--- a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/BidiTest.java
+++ b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/BidiTest.java
@@ -1728,7 +1728,7 @@
)
public void testCreateLineBidiInvalid() {
// regression for HARMONY-1050
- Bidi bidi = new Bidi("str", 1);
+ Bidi bidi = new Bidi("str", Bidi.DIRECTION_RIGHT_TO_LEFT);
try {
bidi.createLineBidi(-1, 1);
fail("Expected IAE");
@@ -1775,7 +1775,7 @@
)
@KnownFailure("Is this a failure or just a different behaviour of ICU?")
public void testCreateLineBidi_AndroidFailure() {
- Bidi bidi = new Bidi("str", 1);
+ Bidi bidi = new Bidi("str", Bidi.DIRECTION_RIGHT_TO_LEFT);
bidi.createLineBidi(2, 2);
}
@@ -2035,7 +2035,6 @@
String RTL = "\u05DC\u05DD";
String newLine = "\n";
String defText = LTR + newLine + RTL + LTR + RTL;
- System.out.println(defText);
int[][] expectedRuns = { { 0, 3 }, { 3, 5 }, { 5, 7 }, { 7, 9 }, };
diff --git a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/CollatorTest.java b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/CollatorTest.java
index 2371fd9..161a2c5 100644
--- a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/CollatorTest.java
+++ b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/CollatorTest.java
@@ -225,7 +225,6 @@
method = "getAvailableLocales",
args = {}
)
- @KnownFailure("Already fixed?")
public void test_getAvailableLocales() {
Locale[] locales = Collator.getAvailableLocales();
assertTrue("No locales", locales.length > 0);
@@ -277,7 +276,6 @@
method = "getDecomposition",
args = {}
)
- @KnownFailure("Already fixed?")
public void test_getDecomposition() {
RuleBasedCollator collator;
try {
@@ -355,14 +353,14 @@
method = "setDecomposition",
args = {int.class}
)
- @KnownFailure("Already fixed?")
+ @KnownFailure("uses decomposition even if set to NO_DECOMPOSITION")
public void test_setDecompositionI() {
Collator c = Collator.getInstance(Locale.FRENCH);
c.setStrength(Collator.IDENTICAL);
c.setDecomposition(Collator.NO_DECOMPOSITION);
- assertTrue("Collator should not be using decomposition", !c.equals(
+ assertFalse("Collator should not be using decomposition", c.equals(
"\u212B", "\u00C5")); // "ANGSTROM SIGN" and "LATIN CAPITAL
- // LETTER A WITH RING ABOVE"
+ // LETTER A WITH RING ABOVE"
c.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
assertTrue("Collator should be using decomposition", c.equals("\u212B",
"\u00C5")); // "ANGSTROM SIGN" and "LATIN CAPITAL LETTER A WITH
diff --git a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java
index 2998eb6..1b2d8bb 100644
--- a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java
+++ b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java
@@ -18,7 +18,6 @@
package org.apache.harmony.text.tests.java.text;
import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.BrokenTest;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -152,7 +151,6 @@
assertTrue("Returned incorrect currency",
dfsUS.getCurrency() == currency);
- // BEGIN android-changed
// use cs_CZ instead
//Currency currK = Currency.getInstance("KRW");
Currency currC = Currency.getInstance("CZK");
@@ -186,7 +184,6 @@
dfs1.getInternationalCurrencySymbol());
dfs1 = new DecimalFormatSymbols(new Locale("de", "AT"));
- // END android-changed
assertTrue("Test4: Returned incorrect currency",
dfs1.getCurrency() == currE);
assertEquals("Test4: Returned incorrect currencySymbol", "\u20ac", dfs1
@@ -417,10 +414,8 @@
assertTrue("Hash codes of equal object are equal", dfs2
.hashCode() == dfs1.hashCode());
dfs1.setInfinity("infinity_infinity");
- // BEGIN android-changed
assertTrue("Hash codes of non-equal objects are equal", dfs2
.hashCode() != dfs1.hashCode());
- // END android-changed
} catch (Exception e) {
fail("Unexpected exception " + e.toString());
}
@@ -545,7 +540,7 @@
method = "setInternationalCurrencySymbol",
args = {java.lang.String.class}
)
- @KnownFailure("getCurrency() doesn't return null. Test passes on RI.")
+ @KnownFailure("getCurrency() doesn't return null for bogus currency code.")
public void test_setInternationalCurrencySymbolLjava_lang_String() {
Locale locale = Locale.CANADA;
DecimalFormatSymbols dfs = ((DecimalFormat) NumberFormat
@@ -734,7 +729,7 @@
method = "!SerializationGolden",
args = {}
)
- @BrokenTest("Deserialized object is not equal to the original object." +
+ @KnownFailure("Deserialized object is not equal to the original object." +
"Test passes on RI.")
public void test_RIHarmony_compatible() throws Exception {
ObjectInputStream i = null;
diff --git a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
index e9a237d..a5ff158 100644
--- a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
+++ b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
@@ -61,6 +61,82 @@
.isEmpty());
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "formatToCharacterIterator",
+ args = {java.lang.Object.class}
+ )
+ @KnownFailure("formatting numbers with more than ~300 digits doesn't work."
+ + " Also the third test doesn't round the string like the RI does")
+ public void test_formatToCharacterIterator() throws Exception {
+ AttributedCharacterIterator iterator;
+ int[] runStarts;
+ int[] runLimits;
+ String result;
+ char current;
+
+ iterator = new DecimalFormat()
+ .formatToCharacterIterator(new BigDecimal("1.23456789E1234"));
+ runStarts = new int[] {0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11, 11, 11, 14};
+ runLimits = new int[] {2, 2, 3, 6, 6, 6, 7, 10, 10, 10, 11, 14, 14, 14, 15};
+ result = "12,345,678,900,"; // 000,000,000,000....
+ current = iterator.current();
+ for (int i = 0; i < runStarts.length; i++) {
+ assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
+ assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+ assertEquals(0, iterator.getBeginIndex());
+ assertEquals(1646, iterator.getEndIndex());
+
+ iterator = new DecimalFormat()
+ .formatToCharacterIterator(new BigDecimal("1.23456789E301"));
+ runStarts = new int[] {0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11, 11, 11, 14};
+ runLimits = new int[] {2, 2, 3, 6, 6, 6, 7, 10, 10, 10, 11, 14, 14, 14, 15};
+ result = "12,345,678,900,"; // 000,000,000,000....
+ current = iterator.current();
+ for (int i = 0; i < runStarts.length; i++) {
+ assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
+ assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+ assertEquals(0, iterator.getBeginIndex());
+ assertEquals(402, iterator.getEndIndex());
+
+ iterator = new DecimalFormat()
+ .formatToCharacterIterator(new BigDecimal("1.2345678E4"));
+ runStarts = new int[] {0, 0, 2, 3, 3, 3, 6, 7, 7, 7};
+ runLimits = new int[] {2, 2, 3, 6, 6, 6, 7, 10, 10, 10};
+ result = "12,345.678";
+ current = iterator.current();
+ for (int i = 0; i < runStarts.length; i++) {
+ assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
+ assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+ assertEquals(0, iterator.getBeginIndex());
+ assertEquals(10, iterator.getEndIndex());
+
+ iterator = new DecimalFormat()
+ .formatToCharacterIterator(new BigInteger("123456789"));
+ runStarts = new int[] {0, 0, 0, 3, 4, 4, 4, 7, 8, 8, 8};
+ runLimits = new int[] {3, 3, 3, 4, 7, 7, 7, 8, 11, 11, 11};
+ result = "123,456,789";
+ current = iterator.current();
+ for (int i = 0; i < runStarts.length; i++) {
+ assertEquals("wrong start @" + i, runStarts[i], iterator.getRunStart());
+ assertEquals("wrong limit @" + i, runLimits[i], iterator.getRunLimit());
+ assertEquals("wrong char @" + i, result.charAt(i), current);
+ current = iterator.next();
+ }
+ assertEquals(0, iterator.getBeginIndex());
+ assertEquals(11, iterator.getEndIndex());
+ }
+
/*
* Test the getter and setter of parseBigDecimal and parseIntegerOnly and
* test the default value of them.
@@ -586,10 +662,11 @@
method = "getMinimumIntegerDigits",
args = {}
)
- @KnownFailure("Something seems wrong with Android implementation, here!")
- public void test_getMaximumIntegerDigits_AndroidFailure() {
+ @AndroidOnly("second 0 needs to be quoted in icu." +
+ "(quoting special characters in prefix and suffix necessary)")
+ public void test_getMaximumIntegerDigits2() {
// regression test for HARMONY-878
- assertTrue(new DecimalFormat("0\t0").getMaximumIntegerDigits() > 0);
+ assertTrue(new DecimalFormat("0\t'0'").getMaximumIntegerDigits() > 0);
}
@TestTargetNew(
@@ -673,12 +750,12 @@
} catch (IllegalArgumentException e) {
// expected
}
-
+
FieldPosition pos;
StringBuffer out;
DecimalFormat format = (DecimalFormat) NumberFormat
.getInstance(Locale.US);
-
+
// format maxLong
pos = new FieldPosition(0);
out = format.format(new Long(Long.MAX_VALUE), new StringBuffer(), pos);
@@ -1336,23 +1413,28 @@
method = "applyPattern",
args = {java.lang.String.class}
)
- @KnownFailure("Something seems wrong with Android implementation, here!")
- public void test_applyPatternLjava_lang_String_AndroidFailure() {
+ @AndroidOnly("icu supports 2 grouping sizes.")
+ public void test_applyPatternLjava_lang_String2() {
DecimalFormat decFormat = new DecimalFormat("#.#");
String [] patterns = {"####.##", "######.######", "000000.000000",
"######.000000", "000000.######", " ###.###", "$#####.######",
"$$####.######", "%#,##,###,####", "#,##0.00;(#,##0.00)",
"##.##-E"};
- String [] expResult = {"#0.##", "#0.######", "#000000.000000",
+ String [] expResult = {"#0.##", "#0.######", "#000000.000000",
"#.000000", "#000000.######", " #0.###", "$#0.######",
- "$$#0.######", "%#,####", "#,##0.00;(#,##0.00)",
- "#0.##-E"};
+ "$$#0.######",
+ "%#,###,####", // icu only. icu supports two grouping sizes
+ "#,##0.00;(#,##0.00)",
+ "#0.##-'E'"}; // icu only. E in the suffix does not need to be
+ // quoted. This is done automatically.
for (int i = 0; i < patterns.length; i++) {
decFormat.applyPattern(patterns[i]);
- assertEquals("Failed to apply following pattern: " + patterns[i],
- expResult[i], decFormat.toPattern());
+ String result = decFormat.toPattern();
+ assertEquals("Failed to apply following pattern: " + patterns[i] +
+ " expected: " + expResult[i] + " returned: " + result,
+ expResult[i], result);
}
}
@@ -1745,33 +1827,34 @@
method = "format",
args = {double.class}
)
- @BrokenTest("This test should take into account (inexact) double representation. Fails on Both RI and Android at different places.")
+ @KnownFailure("This test should take into account (inexact) double " +
+ "representation. Fails on Both RI and Android at different places." +
+ "There is ticket for this failure because of parseDouble method " +
+ "returns different values on Android and RI.")
public void test_formatD() {
DecimalFormat format = (DecimalFormat) NumberFormat
.getInstance(Locale.ENGLISH);
format.setGroupingUsed(false);
format.setMaximumFractionDigits(400);
-// Funny! This one fails against RI, but succeeds with us:
-//
-// for (int i = 0; i < 309; i++) {
-// String tval = "1";
-// for (int j = 0; j < i; j++)
-// tval += "0";
-// double d = Double.parseDouble(tval);
-// String result = format.format(d);
-// assertEquals(i + ") e:" + tval + " r:" + result, tval, result);
-// }
+ for (int i = 0; i < 309; i++) {
+ String tval = "1";
+ for (int j = 0; j < i; j++)
+ tval += "0";
+ double d = Double.parseDouble(tval);
+ String result = format.format(d);
+ assertEquals(i + ") e:" + tval + " r:" + result, tval, result);
+ }
-// for (int i = 0; i < 322; i++) {
-// String tval = "0.";
-// for (int j = 0; j < i; j++)
-// tval += "0";
-// tval += "1";
-// double d = Double.parseDouble(tval);
-// String result = format.format(d);
-// assertEquals(i + ") e:" + tval + " r:" + result, tval, result);
-// }
+ for (int i = 0; i < 322; i++) {
+ String tval = "0.";
+ for (int j = 0; j < i; j++)
+ tval += "0";
+ tval += "1";
+ double d = Double.parseDouble(tval);
+ String result = format.format(d);
+ assertEquals(i + ") e:" + tval + " r:" + result, tval, result);
+ }
assertEquals("123456789012345", format.format(123456789012345.));
assertEquals("1", "12345678901234.5", format.format(12345678901234.5));
assertEquals("2", "1234567890123.25", format.format(1234567890123.25));
@@ -2351,6 +2434,7 @@
method = "!SerializationGolden",
args = {}
)
+ @KnownFailure("a regression. This didn't fail before")
public void test_serializationHarmonyRICompatible() {
NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
diff --git a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java
index 7cdd164..3c864a5 100644
--- a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java
+++ b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java
@@ -18,7 +18,6 @@
package org.apache.harmony.text.tests.java.text;
import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.BrokenTest;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -151,7 +150,6 @@
method = "equals",
args = {java.lang.Object.class}
)
- @KnownFailure("Succeeds against RI.")
public void testEqualsObject() throws ParseException {
String rule = "< a < b < c < d < e";
RuleBasedCollator coll = new RuleBasedCollator(rule);
@@ -282,17 +280,17 @@
method = "getCollationElementIterator",
args = {java.text.CharacterIterator.class}
)
- @KnownFailure("Succeeds against RI.")
+ @KnownFailure("ICU seems to miss collation data")
public void testGetCollationElementIteratorCharacterIterator() throws Exception {
{
- Locale locale = new Locale("es", "", "TRADITIONAL");
+ Locale locale = new Locale("cs", "CZ", "");
RuleBasedCollator coll = (RuleBasedCollator) Collator
.getInstance(locale);
String text = "cha";
StringCharacterIterator source = new StringCharacterIterator(text);
CollationElementIterator iterator = coll
.getCollationElementIterator(source);
- int[] e_offset = { 0, 1, 2 };
+ int[] e_offset = { 0, 2 };
int offset = iterator.getOffset();
int i = 0;
assertEquals(e_offset[i++], offset);
@@ -407,7 +405,6 @@
method = "getAvailableLocales",
args = {}
)
- @KnownFailure("Succeeds against RI.")
public void testGetAvaiableLocales() {
Locale[] locales = Collator.getAvailableLocales();
boolean isUS = false;
diff --git a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/SimpleDateFormatTest.java b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/SimpleDateFormatTest.java
index 821808f..286f080 100644
--- a/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/SimpleDateFormatTest.java
+++ b/libcore/text/src/test/java/org/apache/harmony/text/tests/java/text/SimpleDateFormatTest.java
@@ -17,7 +17,6 @@
package org.apache.harmony.text.tests.java.text;
import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.BrokenTest;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -470,7 +469,8 @@
)
@KnownFailure("SimpleDateFormat.format(Date date, " +
"StringBuffer toAppendTo, FieldPosition pos) " +
- "return incorrect week number for \" W\" pattern. ")
+ "return incorrect week number for \" W\" pattern. " +
+ "Also Android doesn't support formatting of PST, EST, ...")
public void test_formatLjava_util_DateLjava_lang_StringBufferLjava_text_FieldPosition() {
// Test for method java.lang.StringBuffer
// java.text.SimpleDateFormat.format(java.util.Date,
@@ -607,20 +607,6 @@
" 0", DateFormat.HOUR0_FIELD);
test.test(" KK", cal, " 03", DateFormat.HOUR0_FIELD);
test.test(" KKKK", cal, " 0003", DateFormat.HOUR0_FIELD);
-
-// Android doesn't support EST/EDT time zones
-// format.setTimeZone(TimeZone.getTimeZone("EST"));
-// test.test(" z", cal, " EDT", DateFormat.TIMEZONE_FIELD);
-// Calendar temp2 = new GregorianCalendar(1999, Calendar.JANUARY, 12);
-// test.test(" z", temp2, " EST", DateFormat.TIMEZONE_FIELD);
-// test.test(" zz", cal, " EDT", DateFormat.TIMEZONE_FIELD);
-// test.test(" zzz", cal, " EDT", DateFormat.TIMEZONE_FIELD);
-// test.test(" zzzz", cal, " Eastern Daylight Time",
-// DateFormat.TIMEZONE_FIELD);
-// test.test(" zzzz", temp2, " Eastern Standard Time",
-// DateFormat.TIMEZONE_FIELD);
-// test.test(" zzzzz", cal, " Eastern Daylight Time",
-// DateFormat.TIMEZONE_FIELD);
format.setTimeZone(new SimpleTimeZone(60000, "ONE MINUTE"));
test.test(" z", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
@@ -647,6 +633,19 @@
} catch (Throwable ex) {
fail("Expected test to throw NPE, not " + ex.getClass().getName());
}
+
+ format.setTimeZone(TimeZone.getTimeZone("EST"));
+ test.test(" z", cal, " EDT", DateFormat.TIMEZONE_FIELD);
+ Calendar temp2 = new GregorianCalendar(1999, Calendar.JANUARY, 12);
+ test.test(" z", temp2, " EST", DateFormat.TIMEZONE_FIELD);
+ test.test(" zz", cal, " EDT", DateFormat.TIMEZONE_FIELD);
+ test.test(" zzz", cal, " EDT", DateFormat.TIMEZONE_FIELD);
+ test.test(" zzzz", cal, " Eastern Daylight Time",
+ DateFormat.TIMEZONE_FIELD);
+ test.test(" zzzz", temp2, " Eastern Standard Time",
+ DateFormat.TIMEZONE_FIELD);
+ test.test(" zzzzz", cal, " Eastern Daylight Time",
+ DateFormat.TIMEZONE_FIELD);
}
/**
@@ -672,6 +671,7 @@
args = {java.lang.String.class}
)
})
+ @KnownFailure("Android doesn't support formatting of PST, EST, ...")
public void test_timeZoneFormatting() {
// tests specific to formatting of timezones
Date summerDate = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3,
@@ -681,33 +681,32 @@
TestFormat test = new TestFormat(
"test_formatLjava_util_DateLjava_lang_StringBufferLjava_text_FieldPosition");
-// Android doesn't support this time zone
-// test.verifyFormatTimezone("PST", "PDT, Pacific Daylight Time",
-// "-0700, -0700", summerDate);
-// test.verifyFormatTimezone("PST", "PST, Pacific Standard Time",
-// "-0800, -0800", winterDate);
-
test.verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00",
"-0700, -0700", summerDate);
test.verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00",
"-0700, -0700", winterDate);
- // Pacific/Kiritimati is one of the timezones supported only in mJava
+ // Pacific/Kiritimati is one of the timezones supported only in Java
// Android doesn't support this time zone
// test.verifyFormatTimezone("Pacific/Kiritimati", "LINT, Line Is. Time",
// "+1400, +1400", summerDate);
// test.verifyFormatTimezone("Pacific/Kiritimati", "LINT, Line Is. Time",
// "+1400, +1400", winterDate);
-// test.verifyFormatTimezone("EDT", "EDT, Eastern Daylight Time",
-// "-0400, -0400", summerDate);
-// test.verifyFormatTimezone("EST", "EST, Eastern Standard Time",
-// "-0500, -0500", winterDate);
-
test.verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00",
"+1400, +1400", summerDate);
test.verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00",
"+1400, +1400", winterDate);
+
+ test.verifyFormatTimezone("PST", "PDT, Pacific Daylight Time",
+ "-0700, -0700", summerDate);
+ test.verifyFormatTimezone("PST", "PST, Pacific Standard Time",
+ "-0800, -0800", winterDate);
+
+ test.verifyFormatTimezone("EDT", "EDT, Eastern Daylight Time",
+ "-0400, -0400", summerDate);
+ test.verifyFormatTimezone("EST", "EST, Eastern Standard Time",
+ "-0500, -0500", winterDate);
}
/**
diff --git a/libcore/x-net/src/main/java/javax/net/ssl/DefaultHostnameVerifier.java b/libcore/x-net/src/main/java/javax/net/ssl/DefaultHostnameVerifier.java
index 6469c93..6adca42 100644
--- a/libcore/x-net/src/main/java/javax/net/ssl/DefaultHostnameVerifier.java
+++ b/libcore/x-net/src/main/java/javax/net/ssl/DefaultHostnameVerifier.java
@@ -15,22 +15,352 @@
* limitations under the License.
*/
+// BEGIN android-added
+// Copied and condensed code taken from the Apache HttpClient. Also slightly
+// modified, so it matches the package/class structure of the core libraries.
+// This HostnameVerifier does checking similar to what the RI and popular
+// browsers do.
+// END android-added
+
package javax.net.ssl;
+import org.apache.harmony.luni.util.Inet6Util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
/**
- * Default implementation of javax.net.ssl.HostnameVerifier
+ * A HostnameVerifier that works the same way as Curl and Firefox.
+ * <p/>
+ * The hostname must match either the first CN, or any of the subject-alts.
+ * A wildcard can occur in the CN, and in any of the subject-alts.
+ * <p/>
+ * The only difference between BROWSER_COMPATIBLE and STRICT is that a wildcard
+ * (such as "*.foo.com") with BROWSER_COMPATIBLE matches all subdomains,
+ * including "a.b.foo.com".
*
- * @since Android 1.0
+ * @author Julius Davies
*/
class DefaultHostnameVerifier implements HostnameVerifier {
/**
- * DefaultHostnameVerifier assumes the connection should not be permitted.
- *
- * @param hostname
- * @param session
+ * This contains a list of 2nd-level domains that aren't allowed to
+ * have wildcards when combined with country-codes.
+ * For example: [*.co.uk].
+ * <p/>
+ * The [*.co.uk] problem is an interesting one. Should we just hope
+ * that CA's would never foolishly allow such a certificate to happen?
+ * Looks like we're the only implementation guarding against this.
+ * Firefox, Curl, Sun Java 1.4, 5, 6 don't bother with this check.
*/
- public boolean verify(String hostname, SSLSession session) {
- return false;
+ private final static String[] BAD_COUNTRY_2LDS =
+ { "ac", "co", "com", "ed", "edu", "go", "gouv", "gov", "info",
+ "lg", "ne", "net", "or", "org" };
+
+ static {
+ // Just in case developer forgot to manually sort the array. :-)
+ Arrays.sort(BAD_COUNTRY_2LDS);
}
+
+ public DefaultHostnameVerifier() {
+ super();
+ }
+
+ public final void verify(String host, SSLSocket ssl)
+ throws IOException {
+ if(host == null) {
+ throw new NullPointerException("host to verify is null");
+ }
+
+ ssl.startHandshake();
+ SSLSession session = ssl.getSession();
+ if(session == null) {
+ // In our experience this only happens under IBM 1.4.x when
+ // spurious (unrelated) certificates show up in the server'
+ // chain. Hopefully this will unearth the real problem:
+ InputStream in = ssl.getInputStream();
+ in.available();
+ /*
+ If you're looking at the 2 lines of code above because
+ you're running into a problem, you probably have two
+ options:
+
+ #1. Clean up the certificate chain that your server
+ is presenting (e.g. edit "/etc/apache2/server.crt"
+ or wherever it is your server's certificate chain
+ is defined).
+
+ OR
+
+ #2. Upgrade to an IBM 1.5.x or greater JVM, or switch
+ to a non-IBM JVM.
+ */
+
+ // If ssl.getInputStream().available() didn't cause an
+ // exception, maybe at least now the session is available?
+ session = ssl.getSession();
+ if(session == null) {
+ // If it's still null, probably a startHandshake() will
+ // unearth the real problem.
+ ssl.startHandshake();
+
+ // Okay, if we still haven't managed to cause an exception,
+ // might as well go for the NPE. Or maybe we're okay now?
+ session = ssl.getSession();
+ }
+ }
+
+ Certificate[] certs = session.getPeerCertificates();
+ X509Certificate x509 = (X509Certificate) certs[0];
+ verify(host, x509);
+ }
+
+ public final boolean verify(String host, SSLSession session) {
+ try {
+ Certificate[] certs = session.getPeerCertificates();
+ X509Certificate x509 = (X509Certificate) certs[0];
+ verify(host, x509);
+ return true;
+ }
+ catch(SSLException e) {
+ return false;
+ }
+ }
+
+ public final void verify(String host, X509Certificate cert)
+ throws SSLException {
+ String[] cns = getCNs(cert);
+ String[] subjectAlts = getDNSSubjectAlts(cert);
+ verify(host, cns, subjectAlts);
+ }
+
+ public final void verify(final String host, final String[] cns,
+ final String[] subjectAlts,
+ final boolean strictWithSubDomains)
+ throws SSLException {
+
+ // Build the list of names we're going to check. Our DEFAULT and
+ // STRICT implementations of the HostnameVerifier only use the
+ // first CN provided. All other CNs are ignored.
+ // (Firefox, wget, curl, Sun Java 1.4, 5, 6 all work this way).
+ LinkedList<String> names = new LinkedList<String>();
+ if(cns != null && cns.length > 0 && cns[0] != null) {
+ names.add(cns[0]);
+ }
+ if(subjectAlts != null) {
+ for (String subjectAlt : subjectAlts) {
+ if (subjectAlt != null) {
+ names.add(subjectAlt);
+ }
+ }
+ }
+
+ if(names.isEmpty()) {
+ String msg = "Certificate for <" + host +
+ "> doesn't contain CN or DNS subjectAlt";
+ throw new SSLException(msg);
+ }
+
+ // StringBuffer for building the error message.
+ StringBuffer buf = new StringBuffer();
+
+ // We're can be case-insensitive when comparing the host we used to
+ // establish the socket to the hostname in the certificate.
+ String hostName = host.trim().toLowerCase(Locale.ENGLISH);
+ boolean match = false;
+ for(Iterator<String> it = names.iterator(); it.hasNext();) {
+ // Don't trim the CN, though!
+ String cn = it.next();
+ cn = cn.toLowerCase(Locale.ENGLISH);
+ // Store CN in StringBuffer in case we need to report an error.
+ buf.append(" <");
+ buf.append(cn);
+ buf.append('>');
+ if(it.hasNext()) {
+ buf.append(" OR");
+ }
+
+ // The CN better have at least two dots if it wants wildcard
+ // action. It also can't be [*.co.uk] or [*.co.jp] or
+ // [*.org.uk], etc...
+ boolean doWildcard = cn.startsWith("*.") &&
+ cn.lastIndexOf('.') >= 0 &&
+ acceptableCountryWildcard(cn) &&
+ !Inet6Util.isValidIPV4Address(host);
+
+ if(doWildcard) {
+ match = hostName.endsWith(cn.substring(1));
+ if(match && strictWithSubDomains) {
+ // If we're in strict mode, then [*.foo.com] is not
+ // allowed to match [a.b.foo.com]
+ match = countDots(hostName) == countDots(cn);
+ }
+ } else {
+ match = hostName.equals(cn);
+ }
+ if(match) {
+ break;
+ }
+ }
+ if(!match) {
+ throw new SSLException("hostname in certificate didn't match: <" +
+ host + "> !=" + buf);
+ }
+ }
+
+ public static boolean acceptableCountryWildcard(String cn) {
+ int cnLen = cn.length();
+ if(cnLen >= 7 && cnLen <= 9) {
+ // Look for the '.' in the 3rd-last position:
+ if(cn.charAt(cnLen - 3) == '.') {
+ // Trim off the [*.] and the [.XX].
+ String s = cn.substring(2, cnLen - 3);
+ // And test against the sorted array of bad 2lds:
+ int x = Arrays.binarySearch(BAD_COUNTRY_2LDS, s);
+ return x < 0;
+ }
+ }
+ return true;
+ }
+
+ public static String[] getCNs(X509Certificate cert) {
+ LinkedList<String> cnList = new LinkedList<String>();
+ /*
+ Sebastian Hauer's original StrictSSLProtocolSocketFactory used
+ getName() and had the following comment:
+
+ Parses a X.500 distinguished name for the value of the
+ "Common Name" field. This is done a bit sloppy right
+ now and should probably be done a bit more according to
+ <code>RFC 2253</code>.
+
+ I've noticed that toString() seems to do a better job than
+ getName() on these X500Principal objects, so I'm hoping that
+ addresses Sebastian's concern.
+
+ For example, getName() gives me this:
+ 1.2.840.113549.1.9.1=#16166a756c6975736461766965734063756362632e636f6d
+
+ whereas toString() gives me this:
+ EMAILADDRESS=juliusdavies@cucbc.com
+
+ Looks like toString() even works with non-ascii domain names!
+ I tested it with "花子.co.jp" and it worked fine.
+ */
+ String subjectPrincipal = cert.getSubjectX500Principal().toString();
+ StringTokenizer st = new StringTokenizer(subjectPrincipal, ",");
+ while(st.hasMoreTokens()) {
+ String tok = st.nextToken();
+ int x = tok.indexOf("CN=");
+ if(x >= 0) {
+ cnList.add(tok.substring(x + 3));
+ }
+ }
+ if(!cnList.isEmpty()) {
+ String[] cns = new String[cnList.size()];
+ cnList.toArray(cns);
+ return cns;
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * Extracts the array of SubjectAlt DNS names from an X509Certificate.
+ * Returns null if there aren't any.
+ * <p/>
+ * Note: Java doesn't appear able to extract international characters
+ * from the SubjectAlts. It can only extract international characters
+ * from the CN field.
+ * <p/>
+ * (Or maybe the version of OpenSSL I'm using to test isn't storing the
+ * international characters correctly in the SubjectAlts?).
+ *
+ * @param cert X509Certificate
+ * @return Array of SubjectALT DNS names stored in the certificate.
+ */
+ public static String[] getDNSSubjectAlts(X509Certificate cert) {
+ LinkedList<String> subjectAltList = new LinkedList<String>();
+ Collection<List<?>> c = null;
+ try {
+ c = cert.getSubjectAlternativeNames();
+ }
+ catch(CertificateParsingException cpe) {
+ Logger.getLogger(DefaultHostnameVerifier.class.getName())
+ .log(Level.FINE, "Error parsing certificate.", cpe);
+ }
+ if(c != null) {
+ for (List<?> aC : c) {
+ List<?> list = aC;
+ int type = ((Integer) list.get(0)).intValue();
+ // If type is 2, then we've got a dNSName
+ if (type == 2) {
+ String s = (String) list.get(1);
+ subjectAltList.add(s);
+ }
+ }
+ }
+ if(!subjectAltList.isEmpty()) {
+ String[] subjectAlts = new String[subjectAltList.size()];
+ subjectAltList.toArray(subjectAlts);
+ return subjectAlts;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Counts the number of dots "." in a string.
+ * @param s string to count dots from
+ * @return number of dots
+ */
+ public static int countDots(final String s) {
+ int count = 0;
+ for(int i = 0; i < s.length(); i++) {
+ if(s.charAt(i) == '.') {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Checks to see if the supplied hostname matches any of the supplied CNs
+ * or "DNS" Subject-Alts. Most implementations only look at the first CN,
+ * and ignore any additional CNs. Most implementations do look at all of
+ * the "DNS" Subject-Alts. The CNs or Subject-Alts may contain wildcards
+ * according to RFC 2818.
+ *
+ * @param cns CN fields, in order, as extracted from the X.509
+ * certificate.
+ * @param subjectAlts Subject-Alt fields of type 2 ("DNS"), as extracted
+ * from the X.509 certificate.
+ * @param host The hostname to verify.
+ * @throws SSLException If verification failed.
+ */
+ public final void verify(
+ final String host,
+ final String[] cns,
+ final String[] subjectAlts) throws SSLException {
+ verify(host, cns, subjectAlts, false);
+ }
+
}
diff --git a/libcore/x-net/src/main/java/javax/net/ssl/SSLSocketFactory.java b/libcore/x-net/src/main/java/javax/net/ssl/SSLSocketFactory.java
index cb821c2..2b7c03e 100644
--- a/libcore/x-net/src/main/java/javax/net/ssl/SSLSocketFactory.java
+++ b/libcore/x-net/src/main/java/javax/net/ssl/SSLSocketFactory.java
@@ -24,6 +24,7 @@
// BEGIN android-added
import java.lang.reflect.Method;
import java.net.UnknownHostException;
+import java.util.logging.Logger;
// END android-added
import javax.net.SocketFactory;
@@ -57,60 +58,56 @@
* @since Android 1.0
*/
public static SocketFactory getDefault() {
- if (defaultSocketFactory != null) {
+ synchronized (SSLSocketFactory.class) {
+ if (defaultSocketFactory != null) {
+ // BEGIN android-added
+ log("SSLSocketFactory", "Using factory " + defaultSocketFactory);
+ // END android-added
+ return defaultSocketFactory;
+ }
+ if (defaultName == null) {
+ AccessController.doPrivileged(new java.security.PrivilegedAction(){
+ public Object run() {
+ defaultName = Security.getProperty("ssl.SocketFactory.provider");
+ if (defaultName != null) {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if (cl == null) {
+ cl = ClassLoader.getSystemClassLoader();
+ }
+ try {
+ defaultSocketFactory = (SocketFactory) Class.forName(
+ defaultName, true, cl).newInstance();
+ } catch (Exception e) {
+ return e;
+ }
+ }
+ return null;
+ }
+ });
+ }
+
+ if (defaultSocketFactory == null) {
+ // Try to find in providers
+ SSLContext context = DefaultSSLContext.getContext();
+ if (context != null) {
+ defaultSocketFactory = context.getSocketFactory();
+ }
+ }
+ if (defaultSocketFactory == null) {
+ // Use internal implementation
+ defaultSocketFactory = new DefaultSSLSocketFactory("No SSLSocketFactory installed");
+ }
// BEGIN android-added
log("SSLSocketFactory", "Using factory " + defaultSocketFactory);
// END android-added
return defaultSocketFactory;
}
- if (defaultName == null) {
- AccessController.doPrivileged(new java.security.PrivilegedAction(){
- public Object run() {
- defaultName = Security.getProperty("ssl.SocketFactory.provider");
- if (defaultName != null) {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- if (cl == null) {
- cl = ClassLoader.getSystemClassLoader();
- }
- try {
- defaultSocketFactory = (SocketFactory) Class.forName(
- defaultName, true, cl).newInstance();
- } catch (Exception e) {
- return e;
- }
- }
- return null;
- }
- });
- }
-
- if (defaultSocketFactory == null) {
- // Try to find in providers
- SSLContext context = DefaultSSLContext.getContext();
- if (context != null) {
- defaultSocketFactory = context.getSocketFactory();
- }
- }
- if (defaultSocketFactory == null) {
- // Use internal implementation
- defaultSocketFactory = new DefaultSSLSocketFactory("No SSLSocketFactory installed");
- }
- // BEGIN android-added
- log("SSLSocketFactory", "Using factory " + defaultSocketFactory);
- // END android-added
- return defaultSocketFactory;
}
// BEGIN android-added
@SuppressWarnings("unchecked")
private static void log(String tag, String msg) {
- try {
- Class clazz = Class.forName("android.util.Log");
- Method method = clazz.getMethod("d", new Class[] { String.class, String.class });
- method.invoke(null, new Object[] { tag, msg });
- } catch (Exception ex) {
- // Silently ignore.
- }
+ Logger.getLogger(tag).info(msg);
}
// END android-added
diff --git a/libcore/x-net/src/main/java/javax/net/ssl/X509KeyManager.java b/libcore/x-net/src/main/java/javax/net/ssl/X509KeyManager.java
index 09e559d..f65ae4e 100644
--- a/libcore/x-net/src/main/java/javax/net/ssl/X509KeyManager.java
+++ b/libcore/x-net/src/main/java/javax/net/ssl/X509KeyManager.java
@@ -72,7 +72,8 @@
*
* @param alias
* the alias to get the certificate chain for.
- * @return the certificate chain for the specified alias.
+ * @return the certificate chain for the specified alias, or {@code null} if
+ * the alias cannot be found.
* @since Android 1.0
*/
public X509Certificate[] getCertificateChain(String alias);
@@ -84,7 +85,7 @@
* @param keyType
* the public key algorithm type name.
* @param issuers
- * the list of certificate issuers, or {@code null} is any issuer
+ * the list of certificate issuers, or {@code null} if any issuer
* will do.
* @return the client aliases for the specified public key type, or
* {@code null} if there are no matching aliases.
@@ -99,7 +100,7 @@
* @param keyType
* the public key algorithm type name.
* @param issuers
- * the list of certificate issuers, or {@code null} is any issuer
+ * the list of certificate issuers, or {@code null} if any issuer
* will do.
* @return the client aliases for the specified public key type, or
* {@code null} if there are no matching aliases.
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java
new file mode 100644
index 0000000..a95d38f
--- /dev/null
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import java.util.*;
+import java.util.logging.Level;
+import java.io.*;
+
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+import javax.security.cert.X509Certificate;
+import javax.security.cert.CertificateEncodingException;
+import javax.security.cert.CertificateException;
+
+/**
+ * Supports SSL session caches.
+ */
+abstract class AbstractSessionContext implements SSLSessionContext {
+
+ volatile int maximumSize;
+ volatile int timeout;
+
+ final SSLParameters parameters;
+
+ /** Identifies OpenSSL sessions. */
+ static final int OPEN_SSL = 1;
+
+ /**
+ * Constructs a new session context.
+ *
+ * @param parameters
+ * @param maximumSize of cache
+ * @param timeout for cache entries
+ */
+ AbstractSessionContext(SSLParameters parameters, int maximumSize,
+ int timeout) {
+ this.parameters = parameters;
+ this.maximumSize = maximumSize;
+ this.timeout = timeout;
+ }
+
+ /**
+ * Returns the collection of sessions ordered by least-recently-used first.
+ */
+ abstract Iterator<SSLSession> sessionIterator();
+
+ public final Enumeration getIds() {
+ final Iterator<SSLSession> iterator = sessionIterator();
+ return new Enumeration<byte[]>() {
+ public boolean hasMoreElements() {
+ return iterator.hasNext();
+ }
+ public byte[] nextElement() {
+ return iterator.next().getId();
+ }
+ };
+ }
+
+ public final int getSessionCacheSize() {
+ return maximumSize;
+ }
+
+ public final int getSessionTimeout() {
+ return timeout;
+ }
+
+ /**
+ * Makes sure cache size is < maximumSize.
+ */
+ abstract void trimToSize();
+
+ public final void setSessionCacheSize(int size)
+ throws IllegalArgumentException {
+ if (size < 0) {
+ throw new IllegalArgumentException("size < 0");
+ }
+
+ int oldMaximum = maximumSize;
+ maximumSize = size;
+
+ // Trim cache to size if necessary.
+ if (size < oldMaximum) {
+ trimToSize();
+ }
+ }
+
+ /**
+ * Converts the given session to bytes.
+ *
+ * @return session data as bytes or null if the session can't be converted
+ */
+ byte[] toBytes(SSLSession session) {
+ // TODO: Support SSLSessionImpl, too.
+ if (!(session instanceof OpenSSLSessionImpl)) {
+ return null;
+ }
+
+ OpenSSLSessionImpl sslSession = (OpenSSLSessionImpl) session;
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DataOutputStream daos = new DataOutputStream(baos);
+
+ daos.writeInt(OPEN_SSL); // session type ID
+
+ // Session data.
+ byte[] data = sslSession.getEncoded();
+ daos.writeInt(data.length);
+ daos.write(data);
+
+ // Certificates.
+ X509Certificate[] certs = session.getPeerCertificateChain();
+ daos.writeInt(certs.length);
+
+ // TODO: Call nativegetpeercertificates()
+ for (X509Certificate cert : certs) {
+ data = cert.getEncoded();
+ daos.writeInt(data.length);
+ daos.write(data);
+ }
+
+ return baos.toByteArray();
+ } catch (IOException e) {
+ log(e);
+ return null;
+ } catch (CertificateEncodingException e) {
+ log(e);
+ return null;
+ }
+ }
+
+ /**
+ * Creates a session from the given bytes.
+ *
+ * @return a session or null if the session can't be converted
+ */
+ SSLSession toSession(byte[] data, String host, int port) {
+ ByteArrayInputStream bais = new ByteArrayInputStream(data);
+ DataInputStream dais = new DataInputStream(bais);
+ try {
+ int type = dais.readInt();
+ if (type != OPEN_SSL) {
+ log(new AssertionError("Unexpected type ID: " + type));
+ return null;
+ }
+
+ int length = dais.readInt();
+ byte[] sessionData = new byte[length];
+ dais.readFully(sessionData);
+
+ int count = dais.readInt();
+ X509Certificate[] certs = new X509Certificate[count];
+ for (int i = 0; i < count; i++) {
+ length = dais.readInt();
+ byte[] certData = new byte[length];
+ dais.readFully(certData);
+ certs[i] = X509Certificate.getInstance(certData);
+ }
+
+ return new OpenSSLSessionImpl(sessionData, parameters, host, port,
+ certs, this);
+ } catch (IOException e) {
+ log(e);
+ return null;
+ } catch (CertificateException e) {
+ log(e);
+ return null;
+ }
+ }
+
+ static void log(Throwable t) {
+ java.util.logging.Logger.global.log(Level.WARNING,
+ "Error converting session.", t);
+ }
+
+ /**
+ * Byte array wrapper. Implements equals() and hashCode().
+ */
+ static class ByteArray {
+
+ private final byte[] bytes;
+
+ ByteArray(byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(bytes);
+ }
+
+ @Override
+ @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
+ public boolean equals(Object o) {
+ ByteArray other = (ByteArray) o;
+ return Arrays.equals(bytes, other.bytes);
+ }
+ }
+}
\ No newline at end of file
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java
index 8419096..55a06f5 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java
@@ -613,22 +613,18 @@
host = engineOwner.getPeerHost();
port = engineOwner.getPeerPort();
}
- // END android-changed
if (host == null || port == -1) {
return null; // starts new session
}
- byte[] id;
- SSLSession ses;
- SSLSessionContext context = parameters.getClientSessionContext();
- for (Enumeration en = context.getIds(); en.hasMoreElements();) {
- id = (byte[])en.nextElement();
- ses = context.getSession(id);
- if (host.equals(ses.getPeerHost()) && port == ses.getPeerPort()) {
- return (SSLSessionImpl)((SSLSessionImpl)ses).clone(); // resume
- }
+ ClientSessionContext context = parameters.getClientSessionContext();
+ SSLSessionImpl session
+ = (SSLSessionImpl) context.getSession(host, port);
+ if (session != null) {
+ session = (SSLSessionImpl) session.clone();
}
- return null; // starts new session
+ return session;
+ // END android-changed
}
}
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java
new file mode 100644
index 0000000..2c8738f
--- /dev/null
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.net.ssl.SSLSession;
+
+/**
+ * Caches client sessions. Indexes by host and port. Users are typically
+ * looking to reuse any session for a given host and port. Users of the
+ * standard API are forced to iterate over the sessions semi-linearly as
+ * opposed to in constant time.
+ */
+public class ClientSessionContext extends AbstractSessionContext {
+
+ /*
+ * We don't care about timeouts in the client implementation. Trying
+ * to reuse an expired session and having to start a new one requires no
+ * more effort than starting a new one, so you might as well try to reuse
+ * one on the off chance it's still valid.
+ */
+
+ /** Sessions indexed by host and port in access order. */
+ final Map<HostAndPort, SSLSession> sessions
+ = new LinkedHashMap<HostAndPort, SSLSession>() {
+ @Override
+ protected boolean removeEldestEntry(
+ Map.Entry<HostAndPort, SSLSession> eldest) {
+ // Called while lock is held on sessions.
+ boolean remove = maximumSize > 0 && size() > maximumSize;
+ if (remove) {
+ removeById(eldest.getValue());
+ }
+ return remove;
+ }
+ };
+
+ /**
+ * Sessions indexed by ID. Initialized on demand. Protected from concurrent
+ * access by holding a lock on sessions.
+ */
+ Map<ByteArray, SSLSession> sessionsById;
+
+ final SSLClientSessionCache persistentCache;
+
+ public ClientSessionContext(SSLParameters parameters,
+ SSLClientSessionCache persistentCache) {
+ super(parameters, 10, 0);
+ this.persistentCache = persistentCache;
+ }
+
+ public final void setSessionTimeout(int seconds)
+ throws IllegalArgumentException {
+ if (seconds < 0) {
+ throw new IllegalArgumentException("seconds < 0");
+ }
+ timeout = seconds;
+ }
+
+ Iterator<SSLSession> sessionIterator() {
+ synchronized (sessions) {
+ SSLSession[] array = sessions.values().toArray(
+ new SSLSession[sessions.size()]);
+ return Arrays.asList(array).iterator();
+ }
+ }
+
+ void trimToSize() {
+ synchronized (sessions) {
+ int size = sessions.size();
+ if (size > maximumSize) {
+ int removals = size - maximumSize;
+ Iterator<SSLSession> i = sessions.values().iterator();
+ do {
+ removeById(i.next());
+ i.remove();
+ } while (--removals > 0);
+ }
+ }
+ }
+
+ void removeById(SSLSession session) {
+ if (sessionsById != null) {
+ sessionsById.remove(new ByteArray(session.getId()));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see #getSession(String, int) for an implementation-specific but more
+ * efficient approach
+ */
+ public SSLSession getSession(byte[] sessionId) {
+ /*
+ * This method is typically used in conjunction with getIds() to
+ * iterate over the sessions linearly, so it doesn't make sense for
+ * it to impact access order.
+ *
+ * It also doesn't load sessions from the persistent cache as doing
+ * so would likely force every session to load.
+ */
+
+ ByteArray id = new ByteArray(sessionId);
+ synchronized (sessions) {
+ indexById();
+ return sessionsById.get(id);
+ }
+ }
+
+ /**
+ * Ensures that the ID-based index is initialized.
+ */
+ private void indexById() {
+ if (sessionsById == null) {
+ sessionsById = new HashMap<ByteArray, SSLSession>();
+ for (SSLSession session : sessions.values()) {
+ sessionsById.put(new ByteArray(session.getId()), session);
+ }
+ }
+ }
+
+ /**
+ * Adds the given session to the ID-based index if the index has already
+ * been initialized.
+ */
+ private void indexById(SSLSession session) {
+ if (sessionsById != null) {
+ sessionsById.put(new ByteArray(session.getId()), session);
+ }
+ }
+
+ /**
+ * Finds a cached session for the given host name and port.
+ *
+ * @param host of server
+ * @param port of server
+ * @return cached session or null if none found
+ */
+ public SSLSession getSession(String host, int port) {
+ synchronized (sessions) {
+ SSLSession session = sessions.get(new HostAndPort(host, port));
+ if (session != null) {
+ return session;
+ }
+ }
+
+ // Look in persistent cache.
+ if (persistentCache != null) {
+ byte[] data = persistentCache.getSessionData(host, port);
+ if (data != null) {
+ SSLSession session = toSession(data, host, port);
+ if (session != null) {
+ synchronized (sessions) {
+ sessions.put(new HostAndPort(host, port), session);
+ indexById(session);
+ }
+ return session;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ void putSession(SSLSession session) {
+ HostAndPort key = new HostAndPort(session.getPeerHost(),
+ session.getPeerPort());
+ synchronized (sessions) {
+ sessions.put(key, session);
+ indexById(session);
+ }
+
+ // TODO: This in a background thread.
+ if (persistentCache != null) {
+ byte[] data = toBytes(session);
+ if (data != null) {
+ persistentCache.putSessionData(session, data);
+ }
+ }
+ }
+
+ static class HostAndPort {
+ final String host;
+ final int port;
+
+ HostAndPort(String host, int port) {
+ this.host = host;
+ this.port = port;
+ }
+
+ @Override
+ public int hashCode() {
+ return host.hashCode() * 31 + port;
+ }
+
+ @Override
+ @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
+ public boolean equals(Object o) {
+ HostAndPort other = (HostAndPort) o;
+ return host.equals(other.host) && port == other.port;
+ }
+ }
+}
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/FileClientSessionCache.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/FileClientSessionCache.java
new file mode 100644
index 0000000..ab097e4
--- /dev/null
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/FileClientSessionCache.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import javax.net.ssl.SSLSession;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.Iterator;
+import java.util.Arrays;
+import java.util.logging.Level;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * File-based cache implementation. Only one process should access the
+ * underlying directory at a time.
+ */
+public class FileClientSessionCache {
+
+ static final int MAX_SIZE = 20;
+
+ static final java.util.logging.Logger logger
+ = java.util.logging.Logger.getLogger(
+ FileClientSessionCache.class.getName());
+
+ private FileClientSessionCache() {}
+
+ /**
+ * This cache creates one file per SSL session using "host.port" for
+ * the file name. Files are created or replaced when session data is put
+ * in the cache (see {@link #putSessionData}). Files are read on
+ * cache hits, but not on cache misses.
+ *
+ * <p>When the number of session files exceeds MAX_SIZE, we delete the
+ * least-recently-used file. We don't current persist the last access time,
+ * so the ordering actually ends up being least-recently-modified in some
+ * cases and even just "not accessed in this process" if the filesystem
+ * doesn't track last modified times.
+ */
+ static class Impl implements SSLClientSessionCache {
+
+ /** Directory to store session files in. */
+ final File directory;
+
+ /**
+ * Map of name -> File. Keeps track of the order files were accessed in.
+ */
+ Map<String, File> accessOrder = newAccessOrder();
+
+ /** The number of files on disk. */
+ int size;
+
+ /**
+ * The initial set of files. We use this to defer adding information
+ * about all files to accessOrder until necessary.
+ */
+ String[] initialFiles;
+
+ /**
+ * Constructs a new cache backed by the given directory.
+ */
+ Impl(File directory) throws IOException {
+ boolean exists = directory.exists();
+ if (exists && !directory.isDirectory()) {
+ throw new IOException(directory
+ + " exists but is not a directory.");
+ }
+
+ if (exists) {
+ // Read and sort initial list of files. We defer adding
+ // information about these files to accessOrder until necessary
+ // (see indexFiles()). Sorting the list enables us to detect
+ // cache misses in getSessionData().
+ // Note: Sorting an array here was faster than creating a
+ // HashSet on Dalvik.
+ initialFiles = directory.list();
+ Arrays.sort(initialFiles);
+ size = initialFiles.length;
+ } else {
+ // Create directory.
+ if (!directory.mkdirs()) {
+ throw new IOException("Creation of " + directory
+ + " directory failed.");
+ }
+ size = 0;
+ }
+
+ this.directory = directory;
+ }
+
+ /**
+ * Creates a new access-ordered linked hash map.
+ */
+ private static Map<String, File> newAccessOrder() {
+ return new LinkedHashMap<String, File>(
+ MAX_SIZE, 0.75f, true /* access order */);
+ }
+
+ /**
+ * Gets the file name for the given host and port.
+ */
+ private static String fileName(String host, int port) {
+ if (host == null) {
+ throw new NullPointerException("host");
+ }
+ return host + "." + port;
+ }
+
+ public synchronized byte[] getSessionData(String host, int port) {
+ /*
+ * Note: This method is only called when the in-memory cache
+ * in SSLSessionContext misses, so it would be unnecesarily
+ * rendundant for this cache to store data in memory.
+ */
+
+ String name = fileName(host, port);
+ File file = accessOrder.get(name);
+
+ if (file == null) {
+ // File wasn't in access order. Check initialFiles...
+ if (initialFiles == null) {
+ // All files are in accessOrder, so it doesn't exist.
+ return null;
+ }
+
+ // Look in initialFiles.
+ if (Arrays.binarySearch(initialFiles, name) < 0) {
+ // Not found.
+ return null;
+ }
+
+ // The file is on disk but not in accessOrder yet.
+ file = new File(directory, name);
+ accessOrder.put(name, file);
+ }
+
+ FileInputStream in;
+ try {
+ in = new FileInputStream(file);
+ } catch (FileNotFoundException e) {
+ logReadError(host, e);
+ return null;
+ }
+ try {
+ int size = (int) file.length();
+ byte[] data = new byte[size];
+ new DataInputStream(in).readFully(data);
+ logger.log(Level.FINE, "Read session for " + host + ".");
+ return data;
+ } catch (IOException e) {
+ logReadError(host, e);
+ return null;
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) { /* ignore */ }
+ }
+ }
+
+ static void logReadError(String host, Throwable t) {
+ logger.log(Level.INFO, "Error reading session data for " + host
+ + ".", t);
+ }
+
+ public synchronized void putSessionData(SSLSession session,
+ byte[] sessionData) {
+ String host = session.getPeerHost();
+ if (sessionData == null) {
+ throw new NullPointerException("sessionData");
+ }
+
+ String name = fileName(host, session.getPeerPort());
+ File file = new File(directory, name);
+
+ // Used to keep track of whether or not we're expanding the cache.
+ boolean existedBefore = file.exists();
+
+ FileOutputStream out;
+ try {
+ out = new FileOutputStream(file);
+ } catch (FileNotFoundException e) {
+ // We can't write to the file.
+ logWriteError(host, e);
+ return;
+ }
+
+ // If we expanded the cache (by creating a new file)...
+ if (!existedBefore) {
+ size++;
+
+ // Delete an old file if necessary.
+ makeRoom();
+ }
+
+ boolean writeSuccessful = false;
+ try {
+ out.write(sessionData);
+ writeSuccessful = true;
+ } catch (IOException e) {
+ logWriteError(host, e);
+ } finally {
+ boolean closeSuccessful = false;
+ try {
+ out.close();
+ closeSuccessful = true;
+ } catch (IOException e) {
+ logWriteError(host, e);
+ } finally {
+ if (!writeSuccessful || !closeSuccessful) {
+ // Storage failed. Clean up.
+ delete(file);
+ } else {
+ // Success!
+ accessOrder.put(name, file);
+ logger.log(Level.FINE, "Stored session for " + host
+ + ".");
+ }
+ }
+ }
+ }
+
+ /**
+ * Deletes old files if necessary.
+ */
+ private void makeRoom() {
+ if (size <= MAX_SIZE) {
+ return;
+ }
+
+ indexFiles();
+
+ // Delete LRUed files.
+ int removals = size - MAX_SIZE;
+ Iterator<File> i = accessOrder.values().iterator();
+ do {
+ delete(i.next());
+ i.remove();
+ } while (--removals > 0);
+ }
+
+ /**
+ * Lazily updates accessOrder to know about all files as opposed to
+ * just the files accessed since this process started.
+ */
+ private void indexFiles() {
+ String[] initialFiles = this.initialFiles;
+ if (initialFiles != null) {
+ this.initialFiles = null;
+
+ // Files on disk only, sorted by last modified time.
+ // TODO: Use last access time.
+ Set<CacheFile> diskOnly = new TreeSet<CacheFile>();
+ for (String name : initialFiles) {
+ // If the file hasn't been accessed in this process...
+ if (!accessOrder.containsKey(name)) {
+ diskOnly.add(new CacheFile(directory, name));
+ }
+ }
+
+ if (!diskOnly.isEmpty()) {
+ // Add files not accessed in this process to the beginning
+ // of accessOrder.
+ Map<String, File> newOrder = newAccessOrder();
+ for (CacheFile cacheFile : diskOnly) {
+ newOrder.put(cacheFile.name, cacheFile);
+ }
+ newOrder.putAll(accessOrder);
+
+ this.accessOrder = newOrder;
+ }
+ }
+ }
+
+ @SuppressWarnings("ThrowableInstanceNeverThrown")
+ private void delete(File file) {
+ if (!file.delete()) {
+ logger.log(Level.INFO, "Failed to delete " + file + ".",
+ new IOException());
+ }
+ size--;
+ }
+
+ static void logWriteError(String host, Throwable t) {
+ logger.log(Level.INFO, "Error writing session data for "
+ + host + ".", t);
+ }
+ }
+
+ /**
+ * Maps directories to the cache instances that are backed by those
+ * directories. We synchronize access using the cache instance, so it's
+ * important that everyone shares the same instance.
+ */
+ static final Map<File, FileClientSessionCache.Impl> caches
+ = new HashMap<File, FileClientSessionCache.Impl>();
+
+ /**
+ * Returns a cache backed by the given directory. Creates the directory
+ * (including parent directories) if necessary. This cache should have
+ * exclusive access to the given directory.
+ *
+ * @param directory to store files in
+ * @return a cache backed by the given directory
+ * @throws IOException if the file exists and is not a directory or if
+ * creating the directories fails
+ */
+ public static synchronized SSLClientSessionCache usingDirectory(
+ File directory) throws IOException {
+ FileClientSessionCache.Impl cache = caches.get(directory);
+ if (cache == null) {
+ cache = new FileClientSessionCache.Impl(directory);
+ caches.put(directory, cache);
+ }
+ return cache;
+ }
+
+ /** For testing. */
+ static synchronized void reset() {
+ caches.clear();
+ }
+
+ /** A file containing a piece of cached data. */
+ static class CacheFile extends File {
+
+ final String name;
+
+ CacheFile(File dir, String name) {
+ super(dir, name);
+ this.name = name;
+ }
+
+ long lastModified = -1;
+
+ @Override
+ public long lastModified() {
+ long lastModified = this.lastModified;
+ if (lastModified == -1) {
+ lastModified = this.lastModified = super.lastModified();
+ }
+ return lastModified;
+ }
+
+ @Override
+ public int compareTo(File another) {
+ // Sort by last modified time.
+ long result = lastModified() - another.lastModified();
+ if (result == 0) {
+ return super.compareTo(another);
+ }
+ return result < 0 ? -1 : 1;
+ }
+ }
+}
\ No newline at end of file
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
index 25b027e..e65f832 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
@@ -119,6 +119,20 @@
"org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl");
put("TrustManagerFactory.X509",
"org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl");
+ // BEGIN android-added
+ put("MessageDigest.SHA-1", "org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$SHA1");
+ put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
+ put("Alg.Alias.MessageDigest.SHA", "SHA-1");
+ put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA-1");
+ put("MessageDigest.SHA-224", "org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$SHA224");
+ put("Alg.Alias.MessageDigest.SHA224", "SHA-224");
+ put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.4", "SHA-224");
+ put("MessageDigest.SHA-256", "org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$SHA256");
+ put("Alg.Alias.MessageDigest.SHA256", "SHA-256");
+ put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.1", "SHA-256");
+ put("MessageDigest.MD5", "org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$MD5");
+ put("Alg.Alias.MessageDigest.1.2.840.113549.2.5", "MD5");
+ // END android-added
return null;
}
});
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/KeyManagerImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/KeyManagerImpl.java
index 092d92d..b7451d5 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/KeyManagerImpl.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/KeyManagerImpl.java
@@ -122,6 +122,11 @@
* alias)
*/
public X509Certificate[] getCertificateChain(String alias) {
+ // BEGIN android-changed
+ if (alias == null) {
+ return null;
+ }
+ // END android-changed
if (hash.containsKey(alias)) {
Certificate[] certs = ((KeyStore.PrivateKeyEntry) hash.get(alias))
.getCertificateChain();
@@ -157,6 +162,11 @@
* @see javax.net.ssl.X509ExtendedKeyManager#getPrivateKey(String alias)
*/
public PrivateKey getPrivateKey(String alias) {
+ // BEGIN android-changed
+ if (alias == null) {
+ return null;
+ }
+ // END android-changed
if (hash.containsKey(alias)) {
return ((KeyStore.PrivateKeyEntry) hash.get(alias)).getPrivateKey();
}
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java
index b00c5dd..4336214 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java
@@ -63,6 +63,11 @@
}
@Override
+ protected int engineGetDigestLength() {
+ return NativeCrypto.EVP_DigestSize(ctx);
+ }
+
+ @Override
protected void engineUpdate(byte input) {
singleByte[0] = input;
engineUpdate(singleByte, 0, 1);
@@ -79,4 +84,27 @@
NativeCrypto.EVP_free(ctx);
}
+ static public class MD5 extends OpenSSLMessageDigestJDK {
+ public MD5() throws NoSuchAlgorithmException {
+ super("MD5");
+ }
+ }
+
+ static public class SHA1 extends OpenSSLMessageDigestJDK {
+ public SHA1() throws NoSuchAlgorithmException {
+ super("SHA-1");
+ }
+ }
+
+ static public class SHA224 extends OpenSSLMessageDigestJDK {
+ public SHA224() throws NoSuchAlgorithmException {
+ super("SHA-224");
+ }
+ }
+
+ static public class SHA256 extends OpenSSLMessageDigestJDK {
+ public SHA256() throws NoSuchAlgorithmException {
+ super("SHA-256");
+ }
+ }
}
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
index 4fc6e99..e985908 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
@@ -302,7 +302,8 @@
@Override
public Socket accept() throws IOException {
- OpenSSLSocketImpl socket = new OpenSSLSocketImpl(sslParameters, ssl_op_no);
+ OpenSSLSocketImpl socket
+ = new OpenSSLSocketImpl(sslParameters, ssl_op_no);
implAccept(socket);
socket.accept(ssl_ctx, client_mode);
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
index 475d388..ca7d6f8 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
@@ -23,6 +23,7 @@
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Iterator;
+import java.util.UnknownFormatConversionException;
import java.util.Vector;
import javax.net.ssl.SSLPeerUnverifiedException;
@@ -55,21 +56,41 @@
private SSLParameters sslParameters;
private String peerHost;
private int peerPort;
+ private final SSLSessionContext sessionContext;
/**
* Class constructor creates an SSL session context given the appropriate
* SSL parameters.
+ *
+ * @param session the Identifier for SSL session
* @param sslParameters the SSL parameters like ciphers' suites etc.
- * @param ssl the Identifier for SSL session
*/
- protected OpenSSLSessionImpl(int session, SSLParameters sslParameters, String peerHost, int peerPort) {
+ protected OpenSSLSessionImpl(int session, SSLParameters sslParameters,
+ String peerHost, int peerPort, SSLSessionContext sessionContext) {
this.session = session;
this.sslParameters = sslParameters;
this.peerHost = peerHost;
this.peerPort = peerPort;
+ this.sessionContext = sessionContext;
}
/**
+ * Constructs a session from a byte[].
+ */
+ OpenSSLSessionImpl(byte[] derData, SSLParameters sslParameters,
+ String peerHost, int peerPort,
+ javax.security.cert.X509Certificate[] peerCertificateChain,
+ SSLSessionContext sessionContext)
+ throws IOException {
+ this.sslParameters = sslParameters;
+ this.peerHost = peerHost;
+ this.peerPort = peerPort;
+ this.peerCertificateChain = peerCertificateChain;
+ this.sessionContext = sessionContext;
+ initializeNative(derData);
+ }
+
+ /**
* Returns the identifier of the actual OpenSSL session.
*/
private native byte[] nativegetid();
@@ -90,6 +111,40 @@
private native long nativegetcreationtime();
/**
+ * Serialize the native state of the session ( ID, cypher, keys - but
+ * not certs ), using openSSL i2d_SSL_SESSION()
+ *
+ * @return the DER encoding of the session.
+ */
+ private native byte[] nativeserialize();
+
+ /**
+ * Create a SSL_SESSION object using d2i_SSL_SESSION.
+ */
+ private native int nativedeserialize(byte[] data, int size);
+
+ /**
+ * Get the session object in DER format. This allows saving the session
+ * data or sharing it with other processes.
+ */
+ byte[] getEncoded() {
+ return nativeserialize();
+ }
+
+ /**
+ * Init the underlying native object from DER data. This
+ * allows loading the saved session.
+ * @throws IOException
+ */
+ private void initializeNative(byte[] derData) throws IOException {
+ this.session = nativedeserialize(derData, derData.length);
+ if (this.session == 0) {
+ throw new IOException("Invalid session data");
+ }
+ }
+
+
+ /**
* Gets the creation time of the SSL session.
* @return the session's creation time in milli seconds since 12.00 PM,
* January 1st, 1970
@@ -337,7 +392,7 @@
if (sm != null) {
sm.checkPermission(new SSLPermission("getSSLSessionContext"));
}
- return sslParameters.getClientSessionContext();
+ return sessionContext;
}
/**
@@ -347,7 +402,7 @@
* @return true if this session may be resumed.
*/
public boolean isValid() {
- SSLSessionContextImpl context = sslParameters.getClientSessionContext();
+ SSLSessionContext context = sessionContext;
if (isValid
&& context != null
&& context.getSessionTimeout() != 0
@@ -372,7 +427,7 @@
* of security, by the full machinery of the <code>AccessController</code>
* class.
*
- * @param <code>String name</code> the name of the binding to find.
+ * @param name the name of the binding to find.
* @return the value bound to that name, or null if the binding does not
* exist.
* @throws <code>IllegalArgumentException</code> if the argument is null.
@@ -416,9 +471,9 @@
* -data bounds are monitored, as a matter of security, by the full
* machinery of the <code>AccessController</code> class.
*
- * @param <code>String name</code> the name of the link (no null are
+ * @param name the name of the link (no null are
* accepted!)
- * @param <code>Object value</code> data object that shall be bound to
+ * @param value data object that shall be bound to
* name.
* @throws <code>IllegalArgumentException</code> if one or both
* argument(s) is null.
@@ -444,7 +499,7 @@
* monitored, as a matter of security, by the full machinery of the
* <code>AccessController</code> class.
*
- * @param <code>String name</code> the name of the link (no null are
+ * @param name the name of the link (no null are
* accepted!)
* @throws <code>IllegalArgumentException</code> if the argument is null.
*/
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
index 1d38ca9..8779736 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
@@ -21,7 +21,6 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
@@ -31,7 +30,6 @@
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -58,7 +56,7 @@
private int ssl;
private InputStream is;
private OutputStream os;
- private Object handshakeLock = new Object();
+ private final Object handshakeLock = new Object();
private Object readLock = new Object();
private Object writeLock = new Object();
private SSLParameters sslParameters;
@@ -66,7 +64,7 @@
private Socket socket;
private boolean autoClose;
private boolean handshakeStarted = false;
- private ArrayList listeners;
+ private ArrayList<HandshakeCompletedListener> listeners;
private long ssl_op_no = 0x00000000L;
private int timeout = 0;
private InetSocketAddress address;
@@ -137,11 +135,11 @@
/**
* Class constructor with 2 parameters
*
- * @param <code>SSLParameters sslParameters</code> Parameters for the SSL
+ * @param sslParameters Parameters for the SSL
* context
- * @param <code>long ssl_op_no</code> Parameter to set the enabled
+ * @param ssl_op_no Parameter to set the enabled
* protocols
- * @throws <code>IOException</code> if network fails
+ * @throws IOException if network fails
*/
protected OpenSSLSocketImpl(SSLParameters sslParameters, long ssl_op_no) throws IOException {
super();
@@ -153,9 +151,9 @@
/**
* Class constructor with 1 parameter
*
- * @param <code>SSLParameters sslParameters</code> Parameters for the SSL
+ * @param sslParameters Parameters for the SSL
* context
- * @throws <code>IOException</code> if network fails
+ * @throws IOException if network fails
*/
protected OpenSSLSocketImpl(SSLParameters sslParameters) throws IOException {
super();
@@ -167,11 +165,8 @@
/**
* Class constructor with 3 parameters
*
- * @param <code> String host</code>
- * @param <code>int port</code>
- * @param <code>SSLParameters sslParameters</code>
- * @throws <code>IOException</code> if network fails
- * @throws <code>UnknownHostException</code> host not defined
+ * @throws IOException if network fails
+ * @throws java.net.UnknownHostException host not defined
*/
protected OpenSSLSocketImpl(String host, int port,
SSLParameters sslParameters)
@@ -186,11 +181,8 @@
/**
* Class constructor with 3 parameters: 1st is InetAddress
*
- * @param <code>InetAddress address</code>
- * @param <code>int port</code>
- * @param <code>SSLParameters sslParameters</code>
- * @throws <code>IOException</code> if network fails
- * @throws <code>UnknownHostException</code> host not defined
+ * @throws IOException if network fails
+ * @throws java.net.UnknownHostException host not defined
*/
protected OpenSSLSocketImpl(InetAddress address, int port,
SSLParameters sslParameters)
@@ -205,13 +197,8 @@
/**
* Class constructor with 5 parameters: 1st is host
*
- * @param <code>String host</code>
- * @param <code>int port</code>
- * @param <code>InetAddress localHost</code>
- * @param <code>int localPort</code>
- * @param <code>SSLParameters sslParameters</code>
- * @throws <code>IOException</code> if network fails
- * @throws <code>UnknownHostException</code> host not defined
+ * @throws IOException if network fails
+ * @throws java.net.UnknownHostException host not defined
*/
protected OpenSSLSocketImpl(String host, int port, InetAddress clientAddress,
int clientPort, SSLParameters sslParameters)
@@ -225,13 +212,8 @@
/**
* Class constructor with 5 parameters: 1st is InetAddress
*
- * @param <code>InetAddress address</code>
- * @param <code>int port</code>
- * @param <code>InetAddress localAddress</code>
- * @param <code>int localPort</code>
- * @param <code>SSLParameters sslParameters</code>
- * @throws <code>IOException</code> if network fails
- * @throws <code>UnknownHostException</code> host not defined
+ * @throws IOException if network fails
+ * @throws java.net.UnknownHostException host not defined
*/
protected OpenSSLSocketImpl(InetAddress address, int port,
InetAddress clientAddress, int clientPort, SSLParameters sslParameters)
@@ -246,12 +228,7 @@
* Constructor with 5 parameters: 1st is socket. Enhances an existing socket
* with SSL functionality.
*
- * @param <code>Socket socket</code>
- * @param <code>String host</code>
- * @param <code>int port</code>
- * @param <code>boolean autoClose</code>
- * @param <code>SSLParameters sslParameters</code>
- * @throws <code>IOException</code> if network fails
+ * @throws IOException if network fails
*/
protected OpenSSLSocketImpl(Socket socket, String host, int port,
boolean autoClose, SSLParameters sslParameters) throws IOException {
@@ -278,26 +255,26 @@
*
* @return OpenSSLSessionImpl
*/
- private OpenSSLSessionImpl getOpenSSLSessionImpl() {
- try {
- byte[] id;
- SSLSession ses;
- for (Enumeration<byte[]> en = sslParameters.getClientSessionContext().getIds(); en.hasMoreElements();) {
- id = en.nextElement();
- ses = sslParameters.getClientSessionContext().getSession(id);
- if (ses instanceof OpenSSLSessionImpl && ses.isValid() &&
- super.getInetAddress() != null &&
- super.getInetAddress().getHostAddress() != null &&
- super.getInetAddress().getHostName().equals(ses.getPeerHost()) &&
- super.getPort() == ses.getPeerPort()) {
- return (OpenSSLSessionImpl) ses;
- }
- }
- } catch (Exception ex) {
- // It's not clear to me under what circumstances the above code
- // might fail. I also can't reproduce it.
+ private OpenSSLSessionImpl getCachedClientSession() {
+ if (super.getInetAddress() == null ||
+ super.getInetAddress().getHostAddress() == null ||
+ super.getInetAddress().getHostName() == null) {
+ return null;
}
- return null;
+ ClientSessionContext sessionContext
+ = sslParameters.getClientSessionContext();
+ return (OpenSSLSessionImpl) sessionContext.getSession(
+ super.getInetAddress().getHostName(),
+ super.getPort());
+ }
+
+ /**
+ * Ensures that logger is lazily loaded. The outer class seems to load
+ * before logging is ready.
+ */
+ static class LoggerHolder {
+ static final Logger logger = Logger.getLogger(
+ OpenSSLSocketImpl.class.getName());
}
/**
@@ -317,38 +294,60 @@
return;
}
}
-
- {
- // Debug
- int size = 0;
- for (Enumeration<byte[]> en = sslParameters.getClientSessionContext().getIds();
- en.hasMoreElements(); en.nextElement()) { size++; };
- }
- OpenSSLSessionImpl session = getOpenSSLSessionImpl();
+
+ OpenSSLSessionImpl session = getCachedClientSession();
// Check if it's allowed to create a new session (default is true)
- if (!sslParameters.getEnableSessionCreation() && session == null) {
+ if (session == null && !sslParameters.getEnableSessionCreation()) {
throw new SSLHandshakeException("SSL Session may not be created");
} else {
- if (nativeconnect(ssl_ctx, this.socket != null ?
- this.socket : this, sslParameters.getUseClientMode(), session != null ? session.session : 0)) {
+ Socket socket = this.socket != null ? this.socket : this;
+ int sessionId = session != null ? session.session : 0;
+ if (nativeconnect(ssl_ctx, socket, sslParameters.getUseClientMode(),
+ sessionId)) {
+ // nativeconnect shouldn't return true if the session is not
+ // done
session.lastAccessedTime = System.currentTimeMillis();
sslSession = session;
- } else {
- if (address == null) sslSession = new OpenSSLSessionImpl(nativegetsslsession(ssl),
- sslParameters, super.getInetAddress().getHostName(), super.getPort());
- else sslSession = new OpenSSLSessionImpl(nativegetsslsession(ssl),
- sslParameters, address.getHostName(), address.getPort());
- try {
- X509Certificate[] peerCertificates = (X509Certificate[]) sslSession.getPeerCertificates();
- if (peerCertificates == null || peerCertificates.length == 0) {
+ LoggerHolder.logger.fine("Reused cached session for "
+ + getInetAddress().getHostName() + ".");
+ } else {
+ if (session != null) {
+ LoggerHolder.logger.fine("Reuse of cached session for "
+ + getInetAddress().getHostName() + " failed.");
+ } else {
+ LoggerHolder.logger.fine("Created new session for "
+ + getInetAddress().getHostName() + ".");
+ }
+
+ ClientSessionContext sessionContext
+ = sslParameters.getClientSessionContext();
+ if (address == null) {
+ sslSession = new OpenSSLSessionImpl(
+ nativegetsslsession(ssl), sslParameters,
+ super.getInetAddress().getHostName(),
+ super.getPort(), sessionContext);
+ } else {
+ sslSession = new OpenSSLSessionImpl(
+ nativegetsslsession(ssl), sslParameters,
+ address.getHostName(), address.getPort(),
+ sessionContext);
+ }
+
+ try {
+ X509Certificate[] peerCertificates = (X509Certificate[])
+ sslSession.getPeerCertificates();
+
+ if (peerCertificates == null
+ || peerCertificates.length == 0) {
throw new SSLException("Server sends no certificate");
}
- sslParameters.getTrustManager().checkServerTrusted(peerCertificates,
- nativecipherauthenticationmethod());
- sslParameters.getClientSessionContext().putSession(sslSession);
+ sslParameters.getTrustManager().checkServerTrusted(
+ peerCertificates,
+ nativecipherauthenticationmethod());
+ sessionContext.putSession(sslSession);
} catch (CertificateException e) {
throw new SSLException("Not trusted server certificate", e);
}
@@ -360,9 +359,8 @@
HandshakeCompletedEvent event =
new HandshakeCompletedEvent(this, sslSession);
int size = listeners.size();
- for (int i=0; i<size; i++) {
- ((HandshakeCompletedListener)listeners.get(i))
- .handshakeCompleted(event);
+ for (int i = 0; i < size; i++) {
+ listeners.get(i).handshakeCompleted(event);
}
}
}
@@ -381,22 +379,27 @@
nativeaccept(this, m_ctx, client_mode);
+ ServerSessionContext sessionContext
+ = sslParameters.getServerSessionContext();
sslSession = new OpenSSLSessionImpl(nativegetsslsession(ssl),
- sslParameters, super.getInetAddress().getHostName(), super.getPort());
+ sslParameters, super.getInetAddress().getHostName(),
+ super.getPort(), sessionContext);
sslSession.lastAccessedTime = System.currentTimeMillis();
+ sessionContext.putSession(sslSession);
}
/**
* Callback methode for the OpenSSL native certificate verification process.
*
- * @param <code>byte[][] bytes</code> Byte array containing the cert's
+ * @param bytes Byte array containing the cert's
* information.
* @return 0 if the certificate verification fails or 1 if OK
*/
@SuppressWarnings("unused")
private int verify_callback(byte[][] bytes) {
try {
- X509Certificate[] peerCertificateChain = new X509Certificate[bytes.length];
+ X509Certificate[] peerCertificateChain
+ = new X509Certificate[bytes.length];
for(int i = 0; i < bytes.length; i++) {
peerCertificateChain[i] =
new X509CertImpl(javax.security.cert.X509Certificate.getInstance(bytes[i]).getEncoded());
@@ -582,7 +585,6 @@
/**
* Registers a listener to be notified that a SSL handshake
* was successfully completed on this connection.
- * @param <code>HandShakeCompletedListener listener</code>
* @throws <code>IllegalArgumentException</code> if listener is null.
*/
public void addHandshakeCompletedListener(
@@ -598,7 +600,6 @@
/**
* The method removes a registered listener.
- * @param <code>HandShakeCompletedListener listener</code>
* @throws IllegalArgumentException if listener is null or not registered
*/
public void removeHandshakeCompletedListener(
@@ -631,7 +632,7 @@
* SSL sessions. If the flag is set to false, and there are no actual
* sessions to resume, then there will be no successful handshaking.
*
- * @param <code>boolean flag</code> true if session may be created; false
+ * @param flag true if session may be created; false
* if a session already exists and must be resumed.
*/
public void setEnableSessionCreation(boolean flag) {
@@ -683,9 +684,9 @@
* This method enables the cipher suites listed by
* getSupportedCipherSuites().
*
- * @param <code> String[] suites</code> names of all the cipher suites to
+ * @param suites names of all the cipher suites to
* put on use
- * @throws <code>IllegalArgumentException</code> when one or more of the
+ * @throws IllegalArgumentException when one or more of the
* ciphers in array suites are not supported, or when the array
* is null.
*/
@@ -781,9 +782,9 @@
/**
* This method set the actual SSL socket to client mode.
*
- * @param <code>boolean mode</code> true if the socket starts in client
+ * @param mode true if the socket starts in client
* mode
- * @throws <code>IllegalArgumentException</code> if mode changes during
+ * @throws IllegalArgumentException if mode changes during
* handshake.
*/
public synchronized void setUseClientMode(boolean mode) {
@@ -818,7 +819,7 @@
* Sets the SSL socket to use client's authentication. Relevant only for
* server sockets!
*
- * @param <code>boolean need</code> true if client authentication is
+ * @param need true if client authentication is
* desired, false if not.
*/
public void setNeedClientAuth(boolean need) {
@@ -831,7 +832,7 @@
* method will continue the negotiation if the client decide not to send
* authentication credentials.
*
- * @param <code>boolean want</code> true if client authentication is
+ * @param want true if client authentication is
* desired, false if not.
*/
public void setWantClientAuth(boolean want) {
@@ -878,6 +879,9 @@
* socket's closure.
*/
public void close() throws IOException {
+ // TODO: Close SSL sockets using a background thread so they close
+ // gracefully.
+
synchronized (handshakeLock) {
if (!handshakeStarted) {
handshakeStarted = true;
@@ -987,10 +991,11 @@
}
/**
- * Helper class for a thread that knows how to call {@link #close} on behalf
- * of instances being finalized, since that call can take arbitrarily long
- * (e.g., due to a slow network), and an overly long-running finalizer will
- * cause the process to be totally aborted.
+ * Helper class for a thread that knows how to call
+ * {@link OpenSSLSocketImpl#close} on behalf of instances being finalized,
+ * since that call can take arbitrarily long (e.g., due to a slow network),
+ * and an overly long-running finalizer will cause the process to be
+ * totally aborted.
*/
private class Finalizer extends Thread {
public void run() {
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLClientSessionCache.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLClientSessionCache.java
new file mode 100644
index 0000000..8a73fa5
--- /dev/null
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLClientSessionCache.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import javax.net.ssl.SSLSession;
+
+/**
+ * A persistent {@link javax.net.ssl.SSLSession} cache used by
+ * {@link javax.net.ssl.SSLSessionContext} to share client-side SSL sessions
+ * across processes. For example, this cache enables applications to
+ * persist and reuse sessions across restarts.
+ *
+ * <p>The {@code SSLSessionContext} implementation converts
+ * {@code SSLSession}s into raw bytes and vice versa. The exact makeup of the
+ * session data is dependent upon the caller's implementation and is opaque to
+ * the {@code SSLClientSessionCache} implementation.
+ */
+public interface SSLClientSessionCache {
+
+ /**
+ * Gets data from a pre-existing session for a given server host and port.
+ *
+ * @param host from {@link javax.net.ssl.SSLSession#getPeerHost()}
+ * @param port from {@link javax.net.ssl.SSLSession#getPeerPort()}
+ * @return the session data or null if none is cached
+ * @throws NullPointerException if host is null
+ */
+ public byte[] getSessionData(String host, int port);
+
+ /**
+ * Stores session data for the given session.
+ *
+ * @param session to cache data for
+ * @param sessionData to cache
+ * @throws NullPointerException if session, result of
+ * {@code session.getPeerHost()} or data is null
+ */
+ public void putSessionData(SSLSession session, byte[] sessionData);
+}
\ No newline at end of file
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java
index 3f4ab96..2e4de04 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java
@@ -22,9 +22,6 @@
package org.apache.harmony.xnet.provider.jsse;
-// BEGIN android-removed
-// import org.apache.harmony.xnet.provider.jsse.SSLSocketFactoryImpl;
-// END android-removed
import org.apache.harmony.xnet.provider.jsse.SSLEngineImpl;
import org.apache.harmony.xnet.provider.jsse.SSLParameters;
// BEGIN android-removed
@@ -42,19 +39,21 @@
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
+// BEGIN android-note
+// Modified heavily during SSLSessionContext refactoring. Added support for
+// persistent session caches.
+// END android-note
+
/**
* Implementation of SSLContext service provider interface.
*/
public class SSLContextImpl extends SSLContextSpi {
- // client session context contains the set of reusable
- // client-side SSL sessions
- private SSLSessionContextImpl clientSessionContext =
- new SSLSessionContextImpl();
- // server session context contains the set of reusable
- // server-side SSL sessions
- private SSLSessionContextImpl serverSessionContext =
- new SSLSessionContextImpl();
+ /** Client session cache. */
+ private ClientSessionContext clientSessionContext;
+
+ /** Server session cache. */
+ private ServerSessionContext serverSessionContext;
protected SSLParameters sslParameters;
@@ -64,26 +63,44 @@
public void engineInit(KeyManager[] kms, TrustManager[] tms,
SecureRandom sr) throws KeyManagementException {
- sslParameters = new SSLParameters(kms, tms, sr, clientSessionContext,
- serverSessionContext);
+ engineInit(kms, tms, sr, null, null);
+ }
+
+ /**
+ * Initializes this {@code SSLContext} instance. All of the arguments are
+ * optional, and the security providers will be searched for the required
+ * implementations of the needed algorithms.
+ *
+ * @param kms the key sources or {@code null}
+ * @param tms the trust decision sources or {@code null}
+ * @param sr the randomness source or {@code null}
+ * @param clientCache persistent client session cache or {@code null}
+ * @param serverCache persistent server session cache or {@code null}
+ * @throws KeyManagementException if initializing this instance fails
+ *
+ * @since Android 1.1
+ */
+ public void engineInit(KeyManager[] kms, TrustManager[] tms,
+ SecureRandom sr, SSLClientSessionCache clientCache,
+ SSLServerSessionCache serverCache) throws KeyManagementException {
+ sslParameters = new SSLParameters(kms, tms, sr,
+ clientCache, serverCache);
+ clientSessionContext = sslParameters.getClientSessionContext();
+ serverSessionContext = sslParameters.getServerSessionContext();
}
public SSLSocketFactory engineGetSocketFactory() {
if (sslParameters == null) {
throw new IllegalStateException("SSLContext is not initiallized.");
}
- // BEGIN android-changed
return new OpenSSLSocketFactoryImpl(sslParameters);
- // END android-changed
}
public SSLServerSocketFactory engineGetServerSocketFactory() {
if (sslParameters == null) {
throw new IllegalStateException("SSLContext is not initiallized.");
}
- // BEGIN android-changed
return new OpenSSLServerSocketFactoryImpl(sslParameters);
- // END android-changed
}
public SSLEngine engineCreateSSLEngine(String host, int port) {
@@ -101,12 +118,11 @@
return new SSLEngineImpl((SSLParameters) sslParameters.clone());
}
- public SSLSessionContext engineGetServerSessionContext() {
+ public ServerSessionContext engineGetServerSessionContext() {
return serverSessionContext;
}
- public SSLSessionContext engineGetClientSessionContext() {
+ public ClientSessionContext engineGetClientSessionContext() {
return clientSessionContext;
}
-}
-
+}
\ No newline at end of file
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java
index 9a14f46..60a5535 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java
@@ -22,8 +22,6 @@
package org.apache.harmony.xnet.provider.jsse;
-import org.apache.harmony.xnet.provider.jsse.SSLSessionContextImpl;
-
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -45,7 +43,9 @@
* and controls whether new SSL sessions may be established by this
* socket or not.
*/
-public class SSLParameters {
+// BEGIN android-changed
+public class SSLParameters implements Cloneable {
+// END android-changed
// default source of authentication keys
private static X509KeyManager defaultKeyManager;
@@ -58,10 +58,12 @@
// client session context contains the set of reusable
// client-side SSL sessions
- private SSLSessionContextImpl clientSessionContext;
+// BEGIN android-changed
+ private final ClientSessionContext clientSessionContext;
// server session context contains the set of reusable
// server-side SSL sessions
- private SSLSessionContextImpl serverSessionContext;
+ private final ServerSessionContext serverSessionContext;
+// END android-changed
// source of authentication keys
private X509KeyManager keyManager;
// source of authentication trust decisions
@@ -88,16 +90,7 @@
// if the peer with this parameters allowed to cteate new SSL session
private boolean enable_session_creation = true;
- /**
- * Creates an instance of SSLParameters.
- */
- private SSLParameters() {
- // BEGIN android-removed
- // this.enabledCipherSuites = CipherSuite.defaultCipherSuites;
- // END android-removed
- }
-
- // BEGIN android-added
+// BEGIN android-changed
protected CipherSuite[] getEnabledCipherSuitesMember() {
if (enabledCipherSuites == null) this.enabledCipherSuites = CipherSuite.defaultCipherSuites;
return enabledCipherSuites;
@@ -120,23 +113,26 @@
if (ssl_ctx == 0) ssl_ctx = nativeinitsslctx();
return ssl_ctx;
}
- // END android-added
+// END android-changed
/**
* Initializes the parameters. Naturally this constructor is used
* in SSLContextImpl.engineInit method which dirrectly passes its
* parameters. In other words this constructor holds all
* the functionality provided by SSLContext.init method.
- * See {@link javax.net.ssl.SSLContext#init(KeyManager[],TrustManager[],SecureRandom)}
- * for more information
+ * See {@link javax.net.ssl.SSLContext#init(KeyManager[],TrustManager[],
+ * SecureRandom)} for more information
*/
protected SSLParameters(KeyManager[] kms, TrustManager[] tms,
- SecureRandom sr, SSLSessionContextImpl clientSessionContext,
- SSLSessionContextImpl serverSessionContext)
+// BEGIN android-changed
+ SecureRandom sr, SSLClientSessionCache clientCache,
+ SSLServerSessionCache serverCache)
throws KeyManagementException {
- this();
- this.serverSessionContext = serverSessionContext;
- this.clientSessionContext = clientSessionContext;
+ this.serverSessionContext
+ = new ServerSessionContext(this, serverCache);
+ this.clientSessionContext
+ = new ClientSessionContext(this, clientCache);
+// END android-changed
try {
// initialize key manager
boolean initialize_default = false;
@@ -228,8 +224,9 @@
protected static SSLParameters getDefault() throws KeyManagementException {
if (defaultParameters == null) {
- defaultParameters = new SSLParameters(null, null, null,
- new SSLSessionContextImpl(), new SSLSessionContextImpl());
+// BEGIN android-changed
+ defaultParameters = new SSLParameters(null, null, null, null, null);
+// END android-changed
}
return (SSLParameters) defaultParameters.clone();
}
@@ -237,14 +234,18 @@
/**
* @return server session context
*/
- protected SSLSessionContextImpl getServerSessionContext() {
+// BEGIN android-changed
+ protected ServerSessionContext getServerSessionContext() {
+// END android-changed
return serverSessionContext;
}
/**
* @return client session context
*/
- protected SSLSessionContextImpl getClientSessionContext() {
+// BEGIN android-changed
+ protected ClientSessionContext getClientSessionContext() {
+// END android-changed
return clientSessionContext;
}
@@ -335,7 +336,7 @@
/**
* Sets the set of available protocols for use in SSL connection.
- * @param suites: String[]
+ * @param protocols String[]
*/
protected void setEnabledProtocols(String[] protocols) {
if (protocols == null) {
@@ -422,23 +423,13 @@
* @return the clone.
*/
protected Object clone() {
- SSLParameters parameters = new SSLParameters();
-
- parameters.clientSessionContext = clientSessionContext;
- parameters.serverSessionContext = serverSessionContext;
- parameters.keyManager = keyManager;
- parameters.trustManager = trustManager;
- parameters.secureRandom = secureRandom;
-
- parameters.enabledCipherSuites = enabledCipherSuites;
- parameters.enabledProtocols = enabledProtocols;
-
- parameters.client_mode = client_mode;
- parameters.need_client_auth = need_client_auth;
- parameters.want_client_auth = want_client_auth;
- parameters.enable_session_creation = enable_session_creation;
-
- return parameters;
+// BEGIN android-changed
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new AssertionError(e);
+ }
+// END android-changed
}
}
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLServerSessionCache.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLServerSessionCache.java
new file mode 100644
index 0000000..32a0e72
--- /dev/null
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLServerSessionCache.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import javax.net.ssl.SSLSession;
+
+/**
+ * A persistent {@link javax.net.ssl.SSLSession} cache used by
+ * {@link javax.net.ssl.SSLSessionContext} to share server-side SSL sessions
+ * across processes. For example, this cache enables one server to resume
+ * a session started by a different server based on a session ID provided
+ * by the client.
+ *
+ * <p>The {@code SSLSessionContext} implementation converts
+ * {@code SSLSession}s into raw bytes and vice versa. The exact makeup of the
+ * session data is dependent upon the caller's implementation and is opaque to
+ * the {@code SSLServerSessionCache} implementation.
+ */
+public interface SSLServerSessionCache {
+
+ /**
+ * Gets the session data for given session ID.
+ *
+ * @param id from {@link javax.net.ssl.SSLSession#getId()}
+ * @return the session data or null if none is cached
+ * @throws NullPointerException if id is null
+ */
+ public byte[] getSessionData(byte[] id);
+
+ /**
+ * Stores session data for the given session.
+ *
+ * @param session to cache data for
+ * @param sessionData to cache
+ * @throws NullPointerException if session or data is null
+ */
+ public void putSessionData(SSLSession session, byte[] sessionData);
+}
\ No newline at end of file
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionContextImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionContextImpl.java
deleted file mode 100644
index 6882aa1..0000000
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionContextImpl.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Boris Kuznetsov
- * @version $Revision$
- */
-package org.apache.harmony.xnet.provider.jsse;
-
-import java.nio.ByteBuffer;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionContext;
-
-/**
- * SSLSessionContext implementation
- *
- * @see javax.net.ssl.SSLSessionContext
- */
-public class SSLSessionContextImpl implements SSLSessionContext {
-
- private int cacheSize = 20;
- private long timeout = 0;
- private final LinkedHashMap<ByteBuffer, SSLSession> sessions =
- new LinkedHashMap<ByteBuffer, SSLSession>(cacheSize, 0.75f, true) {
- @Override
- public boolean removeEldestEntry(
- Map.Entry<ByteBuffer, SSLSession> eldest) {
- return cacheSize > 0 && this.size() > cacheSize;
- }
- };
- private volatile LinkedHashMap<ByteBuffer, SSLSession> clone =
- new LinkedHashMap<ByteBuffer, SSLSession>();
-
- /**
- * @see javax.net.ssl.SSLSessionContext#getIds()
- */
- public Enumeration<byte[]> getIds() {
- return new Enumeration<byte[]>() {
- Iterator<ByteBuffer> iterator = clone.keySet().iterator();
- public boolean hasMoreElements() {
- return iterator.hasNext();
- }
- public byte[] nextElement() {
- return iterator.next().array();
- }
- };
- }
-
- /**
- * @see javax.net.ssl.SSLSessionContext#getSession(byte[] sessionId)
- */
- public SSLSession getSession(byte[] sessionId) {
- synchronized (sessions) {
- return sessions.get(ByteBuffer.wrap(sessionId));
- }
- }
-
- /**
- * @see javax.net.ssl.SSLSessionContext#getSessionCacheSize()
- */
- public int getSessionCacheSize() {
- synchronized (sessions) {
- return cacheSize;
- }
- }
-
- /**
- * @see javax.net.ssl.SSLSessionContext#getSessionTimeout()
- */
- public int getSessionTimeout() {
- synchronized (sessions) {
- return (int) (timeout/1000);
- }
- }
-
- /**
- * @see javax.net.ssl.SSLSessionContext#setSessionCacheSize(int size)
- */
- public void setSessionCacheSize(int size) throws IllegalArgumentException {
- if (size < 0) {
- throw new IllegalArgumentException("size < 0");
- }
- synchronized (sessions) {
- cacheSize = size;
- if (cacheSize > 0 && cacheSize < sessions.size()) {
- int removals = sessions.size() - cacheSize;
- Iterator<ByteBuffer> iterator = sessions.keySet().iterator();
- while (removals-- > 0) {
- iterator.next();
- iterator.remove();
- }
- clone = (LinkedHashMap<ByteBuffer, SSLSession>)
- sessions.clone();
- }
- }
- }
-
- /**
- * @see javax.net.ssl.SSLSessionContext#setSessionTimeout(int seconds)
- */
- public void setSessionTimeout(int seconds) throws IllegalArgumentException {
- if (seconds < 0) {
- throw new IllegalArgumentException("seconds < 0");
- }
- synchronized (sessions) {
- timeout = seconds*1000;
- // Check timeouts and remove expired sessions
- SSLSession ses;
- Iterator<Map.Entry<ByteBuffer, SSLSession>> iterator =
- sessions.entrySet().iterator();
- while (iterator.hasNext()) {
- SSLSession session = iterator.next().getValue();
- if (!session.isValid()) {
- // safe to remove with this special method since it doesn't
- // make the iterator throw a ConcurrentModificationException
- iterator.remove();
- }
- }
- clone = (LinkedHashMap<ByteBuffer, SSLSession>) sessions.clone();
- }
- }
-
- /**
- * Adds session to the session cache
- * @param ses
- */
- void putSession(SSLSession ses) {
- synchronized (sessions) {
- sessions.put(ByteBuffer.wrap(ses.getId()), ses);
- clone = (LinkedHashMap<ByteBuffer, SSLSession>) sessions.clone();
- }
- }
-}
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionImpl.java
index df46094..4510c96 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionImpl.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionImpl.java
@@ -40,7 +40,6 @@
import javax.net.ssl.SSLSessionContext;
import org.apache.harmony.luni.util.TwoKeyHashMap;
-import org.apache.harmony.xnet.provider.jsse.SSLSessionContextImpl;
/**
*
@@ -83,8 +82,9 @@
/**
* Context of the session
*/
- SSLSessionContextImpl context;
-
+// BEGIN android-changed
+ SSLSessionContext context;
+// END android-changed
/**
* certificates were sent to the peer
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java
index 93dc9c4..f6eef23 100644
--- a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java
@@ -81,7 +81,6 @@
/**
* Start session negotiation
- * @param session
*/
public void start() {
if (session == null) { // initial handshake
@@ -299,7 +298,7 @@
clientFinished = new Finished(io_stream, length);
verifyFinished(clientFinished.getData());
// BEGIN android-added
- session.context = parameters.getClientSessionContext();
+ session.context = parameters.getServerSessionContext();
// END android-added
parameters.getServerSessionContext().putSession(session);
if (!isResuming) {
diff --git a/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java
new file mode 100644
index 0000000..a3c2c6d
--- /dev/null
+++ b/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.net.ssl.SSLSession;
+
+/**
+ * Caches server sessions. Indexes by session ID. Users typically look up
+ * sessions using the ID provided by an SSL client.
+ */
+public class ServerSessionContext extends AbstractSessionContext {
+
+ /*
+ * TODO: Expire timed-out sessions more pro-actively.
+ */
+
+ private final Map<ByteArray, SSLSession> sessions
+ = new LinkedHashMap<ByteArray, SSLSession>() {
+ @Override
+ protected boolean removeEldestEntry(
+ Map.Entry<ByteArray, SSLSession> eldest) {
+ return maximumSize > 0 && size() > maximumSize;
+ }
+ };
+
+ private final SSLServerSessionCache persistentCache;
+
+ public ServerSessionContext(SSLParameters parameters,
+ SSLServerSessionCache persistentCache) {
+ super(parameters, 100, 0);
+ this.persistentCache = persistentCache;
+ }
+
+ Iterator<SSLSession> sessionIterator() {
+ synchronized (sessions) {
+ SSLSession[] array = sessions.values().toArray(
+ new SSLSession[sessions.size()]);
+ return Arrays.asList(array).iterator();
+ }
+ }
+
+ void trimToSize() {
+ synchronized (sessions) {
+ int size = sessions.size();
+ if (size > maximumSize) {
+ int removals = size - maximumSize;
+ Iterator<SSLSession> i = sessions.values().iterator();
+ do {
+ i.next();
+ i.remove();
+ } while (--removals > 0);
+ }
+ }
+ }
+
+ public void setSessionTimeout(int seconds)
+ throws IllegalArgumentException {
+ if (seconds < 0) {
+ throw new IllegalArgumentException("seconds < 0");
+ }
+ timeout = seconds;
+ }
+
+ public SSLSession getSession(byte[] sessionId) {
+ ByteArray key = new ByteArray(sessionId);
+ synchronized (sessions) {
+ SSLSession session = sessions.get(key);
+ if (session != null) {
+ return session;
+ }
+ }
+
+ // Check persistent cache.
+ if (persistentCache != null) {
+ byte[] data = persistentCache.getSessionData(sessionId);
+ if (data != null) {
+ SSLSession session = toSession(data, null, -1);
+ if (session != null) {
+ synchronized (sessions) {
+ sessions.put(key, session);
+ }
+ return session;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ void putSession(SSLSession session) {
+ ByteArray key = new ByteArray(session.getId());
+ synchronized (sessions) {
+ sessions.put(key, session);
+ }
+
+ // TODO: In background thread.
+ if (persistentCache != null) {
+ byte[] data = toBytes(session);
+ if (data != null) {
+ persistentCache.putSessionData(session, data);
+ }
+ }
+ }
+}
diff --git a/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp b/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
index 59859ba..c6d23e7 100644
--- a/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
+++ b/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
@@ -296,7 +296,7 @@
}
/*
- * public static native void EVP_DigestReset(int)
+ * public static native void EVP_DigestSize(int)
*/
static jint NativeCrypto_EVP_DigestSize(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
// LOGI("NativeCrypto_EVP_DigestSize");
@@ -314,7 +314,7 @@
}
/*
- * public static native void EVP_DigestReset(int)
+ * public static native void EVP_DigestBlockSize(int)
*/
static jint NativeCrypto_EVP_DigestBlockSize(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
// LOGI("NativeCrypto_EVP_DigestBlockSize");
diff --git a/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp b/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp
index 42c4e77..feae690 100644
--- a/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp
+++ b/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp
@@ -61,7 +61,7 @@
}
/**
- * Gets the peer certificate in the chain and fills a byte array with the
+ * Gets the peer certificate in the chain and fills a byte array with the
* information therein.
*/
static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeercertificates(JNIEnv* env,
@@ -91,7 +91,62 @@
}
/**
- * Gets and returns in a byte array the ID of the actual SSL session.
+ * Serialize the session.
+ * See apache mod_ssl
+ */
+static jbyteArray org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_serialize(JNIEnv* env, jobject object)
+{
+ SSL_SESSION * ssl_session;
+ jbyteArray bytes = NULL;
+ jbyte *tmp;
+ int size;
+ unsigned char *ucp;
+
+ ssl_session = getSslSessionPointer(env, object);
+ if (ssl_session == NULL) {
+ return NULL;
+ }
+
+ // Compute the size of the DER data
+ size = i2d_SSL_SESSION(ssl_session, NULL);
+ if (size == 0) {
+ return NULL;
+ }
+
+ bytes = env->NewByteArray(size);
+ if (bytes != NULL) {
+ tmp = env->GetByteArrayElements(bytes, NULL);
+ ucp = (unsigned char *) tmp;
+ i2d_SSL_SESSION(ssl_session, &ucp);
+ env->ReleaseByteArrayElements(bytes, tmp, 0);
+ }
+
+ return bytes;
+
+}
+
+/**
+ * Deserialize the session.
+ */
+static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_deserialize(JNIEnv* env, jobject object, jbyteArray bytes, jint size)
+{
+ const unsigned char *ucp;
+ jbyte *tmp;
+ SSL_SESSION *ssl_session;
+
+ if (bytes != NULL) {
+ tmp = env->GetByteArrayElements(bytes, NULL);
+ ucp = (const unsigned char *) tmp;
+ ssl_session = d2i_SSL_SESSION(NULL, &ucp, (long) size);
+ env->ReleaseByteArrayElements(bytes, tmp, 0);
+
+ return (jint) ssl_session;
+ }
+ return 0;
+}
+
+/**
+ * Gets and returns in a byte array the ID of the actual SSL session.
*/
static jbyteArray org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getid(JNIEnv* env, jobject object)
{
@@ -112,8 +167,8 @@
}
/**
- * Gets and returns in a long integer the creation's time of the
- * actual SSL session.
+ * Gets and returns in a long integer the creation's time of the
+ * actual SSL session.
*/
static jlong org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getcreationtime(JNIEnv* env, jobject object)
{
@@ -126,7 +181,7 @@
}
/**
- * Gets and returns in a string the peer's host's name.
+ * Gets and returns in a string the peer's host's name.
*/
static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeerhost(JNIEnv* env, jobject object)
{
@@ -158,7 +213,7 @@
}
/**
- * Gets and returns in a string the peer's port name (https, ftp, etc.).
+ * Gets and returns in a string the peer's port name (https, ftp, etc.).
*/
static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeerport(JNIEnv* env, jobject object)
{
@@ -179,7 +234,7 @@
bio = SSL_get_rbio(ssl);
port = BIO_get_conn_port(bio);
- /* Notice: port name can be NULL */
+ /* Notice: port name can be NULL */
result = env->NewStringUTF(port);
SSL_free(ssl);
@@ -189,7 +244,7 @@
}
/**
- * Gets and returns in a string the version of the SSL protocol. If it
+ * Gets and returns in a string the version of the SSL protocol. If it
* returns the string "unknown" it means that no connection is established.
*/
static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getprotocol(JNIEnv* env, jobject object)
@@ -218,7 +273,7 @@
}
/**
- * Gets and returns in a string the set of ciphers the actual SSL session uses.
+ * Gets and returns in a string the set of ciphers the actual SSL session uses.
*/
static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getciphersuite(JNIEnv* env, jobject object)
{
@@ -238,6 +293,7 @@
SSL_free(ssl);
SSL_CTX_free(ssl_ctx);
+ return result;
}
/**
@@ -261,8 +317,11 @@
{"nativegetpeerhost", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeerhost},
{"nativegetpeerport", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeerport},
{"nativegetprotocol", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getprotocol},
+ {"nativegetciphersuite", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getciphersuite},
{"nativegetpeercertificates", "()[[B", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_getpeercertificates},
- {"nativefree", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_free}
+ {"nativefree", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_free},
+ {"nativeserialize", "()[B", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_serialize},
+ {"nativedeserialize", "([BI)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl_deserialize}
};
/**
diff --git a/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl.cpp b/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl.cpp
index b1ce1bc..250cf83 100644
--- a/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl.cpp
+++ b/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl.cpp
@@ -41,12 +41,6 @@
#include "org_apache_harmony_xnet_provider_jsse_common.h"
/**
- * Global variable used in module org_apache_harmony_xnet_provider_jsse_common.h.
- * It is correctly updated in the function accept().
- */
-int verify_callback_mydata_index = 0;
-
-/**
* Module scope variables initialized during JNI registration.
*/
static jfieldID field_ssl_ctx;
@@ -1273,8 +1267,6 @@
SSL_CTX *ssl_ctx;
mydata_t mydata;
- char name[] = "mydata index";
-
ssl_ctx = (SSL_CTX *)jssl_ctx;
ssl = create_ssl(env, object, ssl_ctx);
@@ -1310,33 +1302,55 @@
SSL_set_bio(ssl, bio, bio);
- /* Call to "register" some new application specific data. It takes three
- * optional function pointers which are called when the parent structure
- * (in this case an RSA structure) is initially created, when it is copied
- * and when it is freed up. If any or all of these function pointer
- * arguments are not used they should be set to NULL. Here we simply
- * register a dummy callback application with the index 0.
+ /*
+ * Fill in the mydata structure needed for the certificate callback and
+ * store this in the SSL application data slot.
*/
- verify_callback_mydata_index = SSL_get_ex_new_index(0, name, NULL, NULL, NULL);
-
- /* Fill in the mydata structure */
mydata.env = env;
mydata.object = object;
- SSL_set_ex_data(ssl, verify_callback_mydata_index, &mydata);
+ SSL_set_app_data(ssl, &mydata);
+ /*
+ * Do the actual SSL_accept(). It is possible this code is insufficient.
+ * Maybe we need to deal with all the special SSL error cases (WANT_*),
+ * just like we do for SSL_connect(). But currently it is looking ok.
+ */
ret = SSL_accept(ssl);
- if (ret < 1) {
+ /*
+ * Clear the SSL application data slot again, so we can safely use it for
+ * our ordinary synchronization structure afterwards. Also, we don't want
+ * sslDestroyAppData() to think that there is something that needs to be
+ * freed right now (in case of an error).
+ */
+ SSL_set_app_data(ssl, NULL);
+
+ if (ret == 0) {
/*
- * Translate the error, and throw if it turns out to be a real
- * problem.
+ * The other side closed the socket before the handshake could be
+ * completed, but everything is within the bounds of the TLS protocol.
+ * We still might want to find out the real reason of the failure.
*/
int sslErrorCode = SSL_get_error(ssl, ret);
- if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
- throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
- "Trouble accepting connection");
- free_ssl(env, object);
- }
+ if (sslErrorCode == SSL_ERROR_NONE ||
+ sslErrorCode == SSL_ERROR_SYSCALL && errno == 0) {
+ throwIOExceptionStr(env, "Connection closed by peer");
+ } else {
+ throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
+ "Trouble accepting connection");
+ }
+ free_ssl(env, object);
+ return;
+ } else if (ret < 0) {
+ /*
+ * Translate the error and throw exception. We are sure it is an error
+ * at this point.
+ */
+ int sslErrorCode = SSL_get_error(ssl, ret);
+ throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
+ "Trouble accepting connection");
+ free_ssl(env, object);
+ return;
}
/*
diff --git a/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_common.h b/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_common.h
index 16ecf9d..9ed75be 100644
--- a/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_common.h
+++ b/libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_common.h
@@ -91,8 +91,6 @@
}
}
-extern int verify_callback_mydata_index;
-
/**
* Verify the X509 certificate.
*/
@@ -107,7 +105,7 @@
/* Get the correct index to the SSLobject stored into X509_STORE_CTX. */
ssl = (SSL*)X509_STORE_CTX_get_ex_data(x509_store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
- mydata = (mydata_t*)SSL_get_ex_data(ssl, verify_callback_mydata_index);
+ mydata = (mydata_t*)SSL_get_app_data(ssl);
cls = mydata->env->GetObjectClass(mydata->object);
diff --git a/libcore/x-net/src/test/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContextTest.java b/libcore/x-net/src/test/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContextTest.java
new file mode 100644
index 0000000..af4490b
--- /dev/null
+++ b/libcore/x-net/src/test/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContextTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import junit.framework.TestCase;
+
+import javax.net.ssl.SSLSession;
+import java.util.Enumeration;
+import java.util.Set;
+import java.util.HashSet;
+
+public class ClientSessionContextTest extends TestCase {
+
+ public void testGetSessionById() {
+ ClientSessionContext context = new ClientSessionContext(null, null);
+
+ SSLSession a = new FakeSession("a");
+ SSLSession b = new FakeSession("b");
+
+ context.putSession(a);
+ context.putSession(b);
+
+ assertSame(a, context.getSession("a".getBytes()));
+ assertSame(b, context.getSession("b".getBytes()));
+
+ assertSame(a, context.getSession("a", 443));
+ assertSame(b, context.getSession("b", 443));
+
+ assertEquals(2, context.sessions.size());
+
+ Set<SSLSession> sessions = new HashSet<SSLSession>();
+ Enumeration ids = context.getIds();
+ while (ids.hasMoreElements()) {
+ sessions.add(context.getSession((byte[]) ids.nextElement()));
+ }
+
+ Set<SSLSession> expected = new HashSet<SSLSession>();
+ expected.add(a);
+ expected.add(b);
+
+ assertEquals(expected, sessions);
+ }
+
+ public void testTrimToSize() {
+ ClientSessionContext context = new ClientSessionContext(null, null);
+
+ FakeSession a = new FakeSession("a");
+ FakeSession b = new FakeSession("b");
+ FakeSession c = new FakeSession("c");
+ FakeSession d = new FakeSession("d");
+
+ context.putSession(a);
+ context.putSession(b);
+ context.putSession(c);
+ context.putSession(d);
+
+ context.setSessionCacheSize(2);
+
+ Set<SSLSession> sessions = new HashSet<SSLSession>();
+ Enumeration ids = context.getIds();
+ while (ids.hasMoreElements()) {
+ sessions.add(context.getSession((byte[]) ids.nextElement()));
+ }
+
+ Set<SSLSession> expected = new HashSet<SSLSession>();
+ expected.add(c);
+ expected.add(d);
+
+ assertEquals(expected, sessions);
+ }
+
+}
diff --git a/libcore/x-net/src/test/java/org/apache/harmony/xnet/provider/jsse/FakeSession.java b/libcore/x-net/src/test/java/org/apache/harmony/xnet/provider/jsse/FakeSession.java
new file mode 100644
index 0000000..4a793dd
--- /dev/null
+++ b/libcore/x-net/src/test/java/org/apache/harmony/xnet/provider/jsse/FakeSession.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+import java.security.cert.Certificate;
+import java.security.Principal;
+
+class FakeSession implements SSLSession {
+ final String host;
+
+ FakeSession(String host) {
+ this.host = host;
+ }
+
+ public int getApplicationBufferSize() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getCipherSuite() {
+ throw new UnsupportedOperationException();
+ }
+
+ public long getCreationTime() {
+ throw new UnsupportedOperationException();
+ }
+
+ public byte[] getId() {
+ return host.getBytes();
+ }
+
+ public long getLastAccessedTime() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Certificate[] getLocalCertificates() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Principal getLocalPrincipal() {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getPacketBufferSize() {
+ throw new UnsupportedOperationException();
+ }
+
+ public javax.security.cert.X509Certificate[] getPeerCertificateChain() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Certificate[] getPeerCertificates() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getPeerHost() {
+ return host;
+ }
+
+ public int getPeerPort() {
+ return 443;
+ }
+
+ public Principal getPeerPrincipal() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getProtocol() {
+ throw new UnsupportedOperationException();
+ }
+
+ public SSLSessionContext getSessionContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getValue(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String[] getValueNames() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void invalidate() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isValid() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void putValue(String name, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void removeValue(String name) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/libcore/x-net/src/test/java/org/apache/harmony/xnet/provider/jsse/FileClientSessionCacheTest.java b/libcore/x-net/src/test/java/org/apache/harmony/xnet/provider/jsse/FileClientSessionCacheTest.java
new file mode 100644
index 0000000..ee50863
--- /dev/null
+++ b/libcore/x-net/src/test/java/org/apache/harmony/xnet/provider/jsse/FileClientSessionCacheTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.IOException;
+
+public class FileClientSessionCacheTest extends TestCase {
+
+ public void testMaxSize() throws IOException, InterruptedException {
+ String tmpDir = System.getProperty("java.io.tmpdir");
+ if (tmpDir == null) {
+ fail("Please set 'java.io.tmpdir' system property.");
+ }
+ File cacheDir = new File(tmpDir
+ + "/" + FileClientSessionCacheTest.class.getName() + "/cache");
+ final SSLClientSessionCache cache
+ = FileClientSessionCache.usingDirectory(cacheDir);
+ Thread[] threads = new Thread[10];
+ final int iterations = FileClientSessionCache.MAX_SIZE * 10;
+ for (int i = 0; i < threads.length; i++) {
+ final int id = i;
+ threads[i] = new Thread() {
+ @Override
+ public void run() {
+ for (int i = 0; i < iterations; i++) {
+ cache.putSessionData(new FakeSession(id + "." + i),
+ new byte[10]);
+ }
+ }
+ };
+ }
+ for (int i = 0; i < threads.length; i++) {
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; i++) {
+ threads[i].join();
+ }
+ assertEquals(FileClientSessionCache.MAX_SIZE, cacheDir.list().length);
+ }
+}
diff --git a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java
index 1b3c9d7..d21215b 100644
--- a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java
+++ b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java
@@ -22,20 +22,32 @@
import dalvik.annotation.TestTargetNew;
import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.security.KeyStore;
import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
import javax.security.cert.X509Certificate;
import junit.framework.TestCase;
+import org.apache.harmony.luni.util.Base64;
import org.apache.harmony.xnet.tests.support.mySSLSession;
import org.apache.harmony.xnet.tests.support.mySSLSocket;
-
/**
* Tests for <code>HandshakeCompletedEvent</code> class constructors and methods.
*
@@ -276,4 +288,404 @@
fail("Unexpected exception: " + e);
}
}
+
+
+ // Regression test for CompletedHandshakeEvent not firing with a custom
+ // TrustManager
+
+
+ SSLSocket socket;
+ SSLSocket serverSocket;
+ MyHandshakeListener listener;
+ int port = 1081;
+ String host = "localhost";
+
+ private String PASSWORD = "android";
+
+ /**
+ * Defines the keystore contents for the server, BKS version. Holds just a
+ * single self-generated key. The subject name is "Test Server".
+ */
+ private static final String SERVER_KEYS_BKS =
+ "AAAAAQAAABQDkebzoP1XwqyWKRCJEpn/t8dqIQAABDkEAAVteWtleQAAARpYl20nAAAAAQAFWC41" +
+ "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU1jANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET" +
+ "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV" +
+ "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMB4XDTA4MDYwNTExNTgxNFoXDTA4MDkw" +
+ "MzExNTgxNFowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U" +
+ "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IFNlcnZl" +
+ "cjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0LIdKaIr9/vsTq8BZlA3R+NFWRaH4lGsTAQy" +
+ "DPMF9ZqEDOaL6DJuu0colSBBBQ85hQTPa9m9nyJoN3pEi1hgamqOvQIWcXBk+SOpUGRZZFXwniJV" +
+ "zDKU5nE9MYgn2B9AoiH3CSuMz6HRqgVaqtppIe1jhukMc/kHVJvlKRNy9XMCAwEAATANBgkqhkiG" +
+ "9w0BAQUFAAOBgQC7yBmJ9O/eWDGtSH9BH0R3dh2NdST3W9hNZ8hIa8U8klhNHbUCSSktZmZkvbPU" +
+ "hse5LI3dh6RyNDuqDrbYwcqzKbFJaq/jX9kCoeb3vgbQElMRX8D2ID1vRjxwlALFISrtaN4VpWzV" +
+ "yeoHPW4xldeZmoVtjn8zXNzQhLuBqX2MmAAAAqwAAAAUvkUScfw9yCSmALruURNmtBai7kQAAAZx" +
+ "4Jmijxs/l8EBaleaUru6EOPioWkUAEVWCxjM/TxbGHOi2VMsQWqRr/DZ3wsDmtQgw3QTrUK666sR" +
+ "MBnbqdnyCyvM1J2V1xxLXPUeRBmR2CXorYGF9Dye7NkgVdfA+9g9L/0Au6Ugn+2Cj5leoIgkgApN" +
+ "vuEcZegFlNOUPVEs3SlBgUF1BY6OBM0UBHTPwGGxFBBcetcuMRbUnu65vyDG0pslT59qpaR0TMVs" +
+ "P+tcheEzhyjbfM32/vwhnL9dBEgM8qMt0sqF6itNOQU/F4WGkK2Cm2v4CYEyKYw325fEhzTXosck" +
+ "MhbqmcyLab8EPceWF3dweoUT76+jEZx8lV2dapR+CmczQI43tV9btsd1xiBbBHAKvymm9Ep9bPzM" +
+ "J0MQi+OtURL9Lxke/70/MRueqbPeUlOaGvANTmXQD2OnW7PISwJ9lpeLfTG0LcqkoqkbtLKQLYHI" +
+ "rQfV5j0j+wmvmpMxzjN3uvNajLa4zQ8l0Eok9SFaRr2RL0gN8Q2JegfOL4pUiHPsh64WWya2NB7f" +
+ "V+1s65eA5ospXYsShRjo046QhGTmymwXXzdzuxu8IlnTEont6P4+J+GsWk6cldGbl20hctuUKzyx" +
+ "OptjEPOKejV60iDCYGmHbCWAzQ8h5MILV82IclzNViZmzAapeeCnexhpXhWTs+xDEYSKEiG/camt" +
+ "bhmZc3BcyVJrW23PktSfpBQ6D8ZxoMfF0L7V2GQMaUg+3r7ucrx82kpqotjv0xHghNIm95aBr1Qw" +
+ "1gaEjsC/0wGmmBDg1dTDH+F1p9TInzr3EFuYD0YiQ7YlAHq3cPuyGoLXJ5dXYuSBfhDXJSeddUkl" +
+ "k1ufZyOOcskeInQge7jzaRfmKg3U94r+spMEvb0AzDQVOKvjjo1ivxMSgFRZaDb/4qw=";
+
+ /**
+ * Defines the keystore contents for the server, JKS version. Holds just a
+ * single self-generated key. The subject name is "Test Server".
+ */
+ private static final String SERVER_KEYS_JKS =
+ "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFfBeAAAArowggK2MA4GCisGAQQBKgIRAQEFAASC" +
+ "AqI2kp5XjnF8YZkhcF92YsJNQkvsmH7zqMM87j23zSoV4DwyE3XeC/gZWq1ToScIhoqZkzlbWcu4" +
+ "T/Zfc/DrfGk/rKbBL1uWKGZ8fMtlZk8KoAhxZk1JSyJvdkyKxqmzUbxk1OFMlN2VJNu97FPVH+du" +
+ "dvjTvmpdoM81INWBW/1fZJeQeDvn4mMbbe0IxgpiLnI9WSevlaDP/sm1X3iO9yEyzHLL+M5Erspo" +
+ "Cwa558fOu5DdsICMXhvDQxjWFKFhPHnKtGe+VvwkG9/bAaDgx3kfhk0w5zvdnkKb+8Ed9ylNRzdk" +
+ "ocAa/mxlMTOsTvDKXjjsBupNPIIj7OP4GNnZaxkJjSs98pEO67op1GX2qhy6FSOPNuq8k/65HzUc" +
+ "PYn6voEeh6vm02U/sjEnzRevQ2+2wXoAdp0EwtQ/DlMe+NvcwPGWKuMgX4A4L93DZGb04N2VmAU3" +
+ "YLOtZwTO0LbuWrcCM/q99G/7LcczkxIVrO2I/rh8RXVczlf9QzcrFObFv4ATuspWJ8xG7DhsMbnk" +
+ "rT94Pq6TogYeoz8o8ZMykesAqN6mt/9+ToIemmXv+e+KU1hI5oLwWMnUG6dXM6hIvrULY6o+QCPH" +
+ "172YQJMa+68HAeS+itBTAF4Clm/bLn6reHCGGU6vNdwU0lYldpiOj9cB3t+u2UuLo6tiFWjLf5Zs" +
+ "EQJETd4g/EK9nHxJn0GAKrWnTw7pEHQJ08elzUuy04C/jEEG+4QXU1InzS4o/kR0Sqz2WTGDoSoq" +
+ "ewuPRU5bzQs/b9daq3mXrnPtRBL6HfSDAdpTK76iHqLCGdqx3avHjVSBm4zFvEuYBCev+3iKOBmg" +
+ "yh7eQRTjz4UOWfy85omMBr7lK8PtfVBDzOXpasxS0uBgdUyBDX4tO6k9jZ8a1kmQRQAAAAEABVgu" +
+ "NTA5AAACSDCCAkQwggGtAgRIR8SKMA0GCSqGSIb3DQEBBAUAMGkxCzAJBgNVBAYTAlVTMRMwEQYD" +
+ "VQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMH" +
+ "QW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBTZXJ2ZXIwHhcNMDgwNjA1MTA0ODQyWhcNMDgwOTAzMTA0" +
+ "ODQyWjBpMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8w" +
+ "DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgU2VydmVyMIGf" +
+ "MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwoC6chqCI84rj1PrXuJgbiit4EV909zR6N0jNlYfg" +
+ "itwB39bP39wH03rFm8T59b3mbSptnGmCIpLZn25KPPFsYD3JJ+wFlmiUdEP9H05flfwtFQJnw9uT" +
+ "3rRIdYVMPcQ3RoZzwAMliGr882I2thIDbA6xjGU/1nRIdvk0LtxH3QIDAQABMA0GCSqGSIb3DQEB" +
+ "BAUAA4GBAJn+6YgUlY18Ie+0+Vt8oEi81DNi/bfPrAUAh63fhhBikx/3R9dl3wh09Z6p7cIdNxjW" +
+ "n2ll+cRW9eqF7z75F0Omm0C7/KAEPjukVbszmzeU5VqzkpSt0j84YWi+TfcHRrfvhLbrlmGITVpY" +
+ "ol5pHLDyqGmDs53pgwipWqsn/nEXEBgj3EoqPeqHbDf7YaP8h/5BSt0=";
+
+ /**
+ * Defines the keystore contents for the client, JKS version. Holds just a
+ * single self-generated key. The subject name is "Test Client".
+ */
+ private static final String CLIENT_KEYS_JKS =
+ "/u3+7QAAAAIAAAABAAAAAQAFbXlrZXkAAAEaWFhyMAAAArkwggK1MA4GCisGAQQBKgIRAQEFAASC" +
+ "AqGVSfXolBStZy4nnRNn4fAr+S7kfU2BS23wwW8uB2Ru3GvtLzlK9q08Gvq/LNqBafjyFTVL5FV5" +
+ "SED/8YomO5a98GpskSeRvytCiTBLJdgGhws5TOGekgIAcBROPGIyOtJPQ0HfOQs+BqgzGDHzHQhw" +
+ "u/8Tm6yQwiP+W/1I9B1QnaEztZA3mhTyMMJsmsFTYroGgAog885D5Cmzd8sYGfxec3R6I+xcmBAY" +
+ "eibR5kGpWwt1R+qMvRrtBqh5r6WSKhCBNax+SJVbtUNRiKyjKccdJg6fGqIWWeivwYTy0OhjA6b4" +
+ "NiZ/ZZs5pxFGWUj/Rlp0RYy8fCF6aw5/5s4Bf4MI6dPSqMG8Hf7sJR91GbcELyzPdM0h5lNavgit" +
+ "QPEzKeuDrGxhY1frJThBsNsS0gxeu+OgfJPEb/H4lpYX5IvuIGbWKcxoO9zq4/fimIZkdA8A+3eY" +
+ "mfDaowvy65NBVQPJSxaOyFhLHfeLqOeCsVENAea02vA7andZHTZehvcrqyKtm+z8ncHGRC2H9H8O" +
+ "jKwKHfxxrYY/jMAKLl00+PBb3kspO+BHI2EcQnQuMw/zr83OR9Meq4TJ0TMuNkApZELAeFckIBbS" +
+ "rBr8NNjAIfjuCTuKHhsTFWiHfk9ZIzigxXagfeDRiyVc6khOuF/bGorj23N2o7Rf3uLoU6PyXWi4" +
+ "uhctR1aL6NzxDoK2PbYCeA9hxbDv8emaVPIzlVwpPK3Ruvv9mkjcOhZ74J8bPK2fQmbplbOljcZi" +
+ "tZijOfzcO/11JrwhuJZRA6wanTqHoujgChV9EukVrmbWGGAcewFnAsSbFXIik7/+QznXaDIt5NgL" +
+ "H/Bcz4Z/fdV7Ae1eUaxKXdPbI//4J+8liVT/d8awjW2tldIaDlmGMR3aoc830+3mAAAAAQAFWC41" +
+ "MDkAAAJIMIICRDCCAa0CBEhHxLgwDQYJKoZIhvcNAQEEBQAwaTELMAkGA1UEBhMCVVMxEzARBgNV" +
+ "BAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01UVjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdB" +
+ "bmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVudDAeFw0wODA2MDUxMDQ5MjhaFw0wODA5MDMxMDQ5" +
+ "MjhaMGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMQwwCgYDVQQHEwNNVFYxDzAN" +
+ "BgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEUMBIGA1UEAxMLVGVzdCBDbGllbnQwgZ8w" +
+ "DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIK3Q+KiFbmCGg422TAo4gggdhMH6FJhiuz8DxRyeMKR" +
+ "UAfP4MK0wtc8N42waZ6OKvxpBFUy0BRfBsX0GD4Ku99yu9/tavSigTraeJtwV3WWRRjIqk7L3wX5" +
+ "cmgS2KSD43Y0rNUKrko26lnt9N4qiYRBSj+tcAN3Lx9+ptqk1LApAgMBAAEwDQYJKoZIhvcNAQEE" +
+ "BQADgYEANb7Q1GVSuy1RPJ0FmiXoMYCCtvlRLkmJphwxovK0cAQK12Vll+yAzBhHiQHy/RA11mng" +
+ "wYudC7u3P8X/tBT8GR1Yk7QW3KgFyPafp3lQBBCraSsfrjKj+dCLig1uBLUr4f68W8VFWZWWTHqp" +
+ "NMGpCX6qmjbkJQLVK/Yfo1ePaUexPSOX0G9m8+DoV3iyNw6at01NRw==";
+
+ /**
+ * Defines the keystore contents for the client, BKS version. Holds just a
+ * single self-generated key. The subject name is "Test Client".
+ */
+ private static final String CLIENT_KEYS_BKS =
+ "AAAAAQAAABT4Rka6fxbFps98Y5k2VilmbibNkQAABfQEAAVteWtleQAAARpYl+POAAAAAQAFWC41" +
+ "MDkAAAJNMIICSTCCAbKgAwIBAgIESEfU9TANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJVUzET" +
+ "MBEGA1UECBMKQ2FsaWZvcm5pYTEMMAoGA1UEBxMDTVRWMQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNV" +
+ "BAsTB0FuZHJvaWQxFDASBgNVBAMTC1Rlc3QgQ2xpZW50MB4XDTA4MDYwNTExNTg0NVoXDTA4MDkw" +
+ "MzExNTg0NVowaTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDDAKBgNVBAcTA01U" +
+ "VjEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRQwEgYDVQQDEwtUZXN0IENsaWVu" +
+ "dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApUvmWsQDHPpbDKK13Yez2/q54tTOmRml/qva" +
+ "2K6dZjkjSTW0iRuk7ztaVEvdJpfVIDv1oBsCI51ttyLHROy1epjF+GoL74mJb7fkcd0VOoSOTjtD" +
+ "+3GgZkHPAm5YmUYxiJXqxKKJJqMCTIW46eJaA2nAep9QIwZ14/NFAs4ObV8CAwEAATANBgkqhkiG" +
+ "9w0BAQUFAAOBgQCJrCr3hZQFDlLIfsSKI1/w+BLvyf4fubOid0pBxfklR8KBNPTiqjSmu7pd/C/F" +
+ "1FR8CdZUDoPflZHCOU+fj5r5KUC1HyigY/tEUvlforBpfB0uCF+tXW4DbUfOWhfMtLV4nCOJOOZg" +
+ "awfZLJWBJouLKOp427vDftxTSB+Ks8YjlgAAAqwAAAAU+NH6TtrzjyDdCXm5B6Vo7xX5G4YAAAZx" +
+ "EAUkcZtmykn7YdaYxC1jRFJ+GEJpC8nZVg83QClVuCSIS8a5f8Hl44Bk4oepOZsPzhtz3RdVzDVi" +
+ "RFfoyZFsrk9F5bDTVJ6sQbb/1nfJkLhZFXokka0vND5AXMSoD5Bj1Fqem3cK7fSUyqKvFoRKC3XD" +
+ "FQvhqoam29F1rbl8FaYdPvhhZo8TfZQYUyUKwW+RbR44M5iHPx+ykieMe/C/4bcM3z8cwIbYI1aO" +
+ "gjQKS2MK9bs17xaDzeAh4sBKrskFGrDe+2dgvrSKdoakJhLTNTBSG6m+rzqMSCeQpafLKMSjTSSz" +
+ "+KoQ9bLyax8cbvViGGju0SlVhquloZmKOfHr8TukIoV64h3uCGFOVFtQjCYDOq6NbfRvMh14UVF5" +
+ "zgDIGczoD9dMoULWxBmniGSntoNgZM+QP6Id7DBasZGKfrHIAw3lHBqcvB5smemSu7F4itRoa3D8" +
+ "N7hhUEKAc+xA+8NKmXfiCBoHfPHTwDvt4IR7gWjeP3Xv5vitcKQ/MAfO5RwfzkYCXQ3FfjfzmsE1" +
+ "1IfLRDiBj+lhQSulhRVStKI88Che3M4JUNGKllrc0nt1pWa1vgzmUhhC4LSdm6trTHgyJnB6OcS9" +
+ "t2furYjK88j1AuB4921oxMxRm8c4Crq8Pyuf+n3YKi8Pl2BzBtw++0gj0ODlgwut8SrVj66/nvIB" +
+ "jN3kLVahR8nZrEFF6vTTmyXi761pzq9yOVqI57wJGx8o3Ygox1p+pWUPl1hQR7rrhUbgK/Q5wno9" +
+ "uJk07h3IZnNxE+/IKgeMTP/H4+jmyT4mhsexJ2BFHeiKF1KT/FMcJdSi+ZK5yoNVcYuY8aZbx0Ef" +
+ "lHorCXAmLFB0W6Cz4KPP01nD9YBB4olxiK1t7m0AU9zscdivNiuUaB5OIEr+JuZ6dNw=";
+
+
+ /**
+ * Implements the actual test case. Launches a server and a client, requires
+ * client authentication and checks the certificates afterwards (not in the
+ * usual sense, we just make sure that we got the expected certificates,
+ * because our self-signed test certificates are not valid.)
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = SSLSocket.class,
+ method = "addHandshakeCompletedListener",
+ args = {HandshakeCompletedListener.class}
+ )
+ public void testClientAuth() {
+ listener = new MyHandshakeListener();
+ try {
+ TestServer server = new TestServer(8088, true, TestServer.CLIENT_AUTH_WANTED);
+ TestClient client = new TestClient(8088, true);
+
+ Thread serverThread = new Thread(server);
+ Thread clientThread = new Thread(client);
+
+ serverThread.start();
+ Thread.currentThread().sleep(3000);
+ clientThread.start();
+
+ serverThread.join();
+ clientThread.join();
+
+ // The server must have completed without an exception.
+ if (server.getException() != null) {
+ throw new RuntimeException(server.getException());
+ }
+
+ // The client must have completed without an exception.
+ if (client.getException() != null) {
+ throw new RuntimeException(client.getException());
+ }
+
+ assertTrue(listener.completeDone);
+
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ /**
+ * Implements a test SSL socket server. It wait for a connection on a given
+ * port, requests client authentication (if specified), and read 256 bytes
+ * from the socket.
+ */
+ class TestServer implements Runnable {
+
+ public static final int CLIENT_AUTH_NONE = 0;
+
+ public static final int CLIENT_AUTH_WANTED = 1;
+
+ public static final int CLIENT_AUTH_NEEDED = 2;
+
+ private TestTrustManager trustManager;
+
+ private Exception exception;
+
+ private int port;
+
+ private int clientAuth;
+
+ private boolean provideKeys;
+
+ public TestServer(int port, boolean provideKeys, int clientAuth) {
+ this.port = port;
+ this.clientAuth = clientAuth;
+ this.provideKeys = provideKeys;
+
+ trustManager = new TestTrustManager();
+ }
+
+ public void run() {
+ try {
+ KeyManager[] keyManagers = provideKeys ? getKeyManagers(SERVER_KEYS_BKS) : null;
+ TrustManager[] trustManagers = new TrustManager[] { trustManager };
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(keyManagers, trustManagers, null);
+
+ SSLServerSocket serverSocket = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket();
+
+ if (clientAuth == CLIENT_AUTH_WANTED) {
+ serverSocket.setWantClientAuth(true);
+ } else if (clientAuth == CLIENT_AUTH_NEEDED) {
+ serverSocket.setNeedClientAuth(true);
+ } else {
+ serverSocket.setWantClientAuth(false);
+ }
+
+ serverSocket.bind(new InetSocketAddress(port));
+
+ SSLSocket clientSocket = (SSLSocket)serverSocket.accept();
+
+ InputStream stream = clientSocket.getInputStream();
+
+ for (int i = 0; i < 256; i++) {
+ int j = stream.read();
+ if (i != j) {
+ throw new RuntimeException("Error reading socket, expected " + i + ", got " + j);
+ }
+ }
+
+ stream.close();
+ clientSocket.close();
+ serverSocket.close();
+
+ } catch (Exception ex) {
+ exception = ex;
+ }
+ }
+
+ public Exception getException() {
+ return exception;
+ }
+
+ public X509Certificate[] getChain() {
+ return trustManager.getChain();
+ }
+
+ }
+
+ /**
+ * Implements a test SSL socket client. It open a connection to localhost on
+ * a given port and writes 256 bytes to the socket.
+ */
+ class TestClient implements Runnable {
+
+ private TestTrustManager trustManager;
+
+ private Exception exception;
+
+ private int port;
+
+ private boolean provideKeys;
+
+ public TestClient(int port, boolean provideKeys) {
+ this.port = port;
+ this.provideKeys = provideKeys;
+
+ trustManager = new TestTrustManager();
+ }
+
+ public void run() {
+ try {
+ KeyManager[] keyManagers = provideKeys ? getKeyManagers(CLIENT_KEYS_BKS) : null;
+ TrustManager[] trustManagers = new TrustManager[] { trustManager };
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(keyManagers, trustManagers, null);
+
+ SSLSocket socket = (SSLSocket)sslContext.getSocketFactory().createSocket();
+
+ socket.connect(new InetSocketAddress(port));
+ socket.addHandshakeCompletedListener(listener);
+ socket.startHandshake();
+
+ OutputStream stream = socket.getOutputStream();
+
+ for (int i = 0; i < 256; i++) {
+ stream.write(i);
+ }
+
+ stream.flush();
+ stream.close();
+ socket.close();
+
+ } catch (Exception ex) {
+ exception = ex;
+ }
+ }
+
+ public Exception getException() {
+ return exception;
+ }
+
+ public X509Certificate[] getChain() {
+ return trustManager.getChain();
+ }
+ }
+
+ /**
+ * Loads a keystore from a base64-encoded String. Returns the KeyManager[]
+ * for the result.
+ */
+ private KeyManager[] getKeyManagers(String keys) throws Exception {
+ byte[] bytes = new Base64().decode(keys.getBytes());
+ InputStream inputStream = new ByteArrayInputStream(bytes);
+
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(inputStream, PASSWORD.toCharArray());
+ inputStream.close();
+
+ String algorithm = KeyManagerFactory.getDefaultAlgorithm();
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(algorithm);
+ keyManagerFactory.init(keyStore, PASSWORD.toCharArray());
+
+ return keyManagerFactory.getKeyManagers();
+ }
+
+
+ /**
+ * Implements basically a dummy TrustManager. It stores the certificate
+ * chain it sees, so it can later be queried.
+ */
+ static class TestTrustManager implements X509TrustManager {
+
+ private X509Certificate[] chain;
+
+ private String authType;
+
+ public void checkClientTrusted(X509Certificate[] chain, String authType) {
+ this.chain = chain;
+ this.authType = authType;
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType) {
+ this.chain = chain;
+ this.authType = authType;
+ }
+
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return new java.security.cert.X509Certificate[0];
+ }
+
+ public X509Certificate[] getChain() {
+ return chain;
+ }
+
+ public String getAuthType() {
+ return authType;
+ }
+
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] chain, String authType)
+ throws CertificateException {
+
+ }
+
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] chain, String authType)
+ throws CertificateException {
+
+ }
+
+ }
+
+ class MyHandshakeListener implements HandshakeCompletedListener {
+
+ public boolean completeDone;
+
+ MyHandshakeListener() {
+ completeDone = false;
+ }
+
+ public void handshakeCompleted(HandshakeCompletedEvent event) {
+ if (event != null) completeDone = true;
+ }
+ }
}
+
diff --git a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLExceptionTest.java b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLExceptionTest.java
index fe0d056..301f510 100644
--- a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLExceptionTest.java
+++ b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLExceptionTest.java
@@ -32,18 +32,6 @@
*/
public class SSLExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for SSLExceptionTests.
- *
- * @param arg0
- */
- public SSLExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLHandshakeExceptionTest.java b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLHandshakeExceptionTest.java
index ffc0105..45bf262 100644
--- a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLHandshakeExceptionTest.java
+++ b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLHandshakeExceptionTest.java
@@ -27,18 +27,6 @@
@TestTargetClass(SSLHandshakeException.class)
public class SSLHandshakeExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for SSLHandshakeExceptionTest.
- *
- * @param arg0
- */
- public SSLHandshakeExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLKeyExceptionTest.java b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLKeyExceptionTest.java
index a890dbd..7d3b48a 100644
--- a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLKeyExceptionTest.java
+++ b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLKeyExceptionTest.java
@@ -27,18 +27,6 @@
@TestTargetClass(SSLKeyException.class)
public class SSLKeyExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for SSLKeyExceptionTest.
- *
- * @param arg0
- */
- public SSLKeyExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLPeerUnverifiedExceptionTest.java b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLPeerUnverifiedExceptionTest.java
index 7fdd0b7..7e4c9be 100644
--- a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLPeerUnverifiedExceptionTest.java
+++ b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLPeerUnverifiedExceptionTest.java
@@ -27,18 +27,6 @@
@TestTargetClass(SSLPeerUnverifiedException.class)
public class SSLPeerUnverifiedExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for SSLPeerUnverifiedExceptionTest.
- *
- * @param arg0
- */
- public SSLPeerUnverifiedExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLProtocolExceptionTest.java b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLProtocolExceptionTest.java
index e73a525..9b8b22c 100644
--- a/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLProtocolExceptionTest.java
+++ b/libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLProtocolExceptionTest.java
@@ -27,18 +27,6 @@
@TestTargetClass(SSLProtocolException.class)
public class SSLProtocolExceptionTest extends TestCase {
- public static void main(String[] args) {
- }
-
- /**
- * Constructor for SSLProtocolExceptionTest.
- *
- * @param arg0
- */
- public SSLProtocolExceptionTest(String arg0) {
- super(arg0);
- }
-
private static String[] msgs = {
"",
"Check new message",
diff --git a/libdex/DexFile.c b/libdex/DexFile.c
index 773d3b1..2639d7b 100644
--- a/libdex/DexFile.c
+++ b/libdex/DexFile.c
@@ -678,7 +678,8 @@
}
/*
- * Parse an optimized or unoptimized .dex file sitting in memory.
+ * Parse an optimized or unoptimized .dex file sitting in memory. This is
+ * called after the byte-ordering and structure alignment has been fixed up.
*
* On success, return a newly-allocated DexFile.
*/
@@ -751,17 +752,14 @@
* byte-swapping and DEX optimization.
*/
if (flags & kDexParseVerifyChecksum) {
- uLong adler = adler32(0L, Z_NULL, 0);
- const int nonSum = sizeof(pHeader->magic) + sizeof(pHeader->checksum);
-
- adler = adler32(adler, data + nonSum, length - nonSum);
-
+ u4 adler = dexComputeChecksum(pHeader);
if (adler != pHeader->checksum) {
- LOGW("WARNING: bad checksum (%08lx vs %08x)\n",
+ LOGE("ERROR: bad checksum (%08x vs %08x)\n",
adler, pHeader->checksum);
- /* keep going */
+ if (!(flags & kDexParseContinueOnError))
+ goto bail;
} else {
- LOGV("+++ adler32 checksum verified\n");
+ LOGV("+++ adler32 checksum (%08x) verified\n", adler);
}
}
@@ -781,23 +779,25 @@
if (memcmp(sha1Digest, pHeader->signature, kSHA1DigestLen) != 0) {
char tmpBuf1[kSHA1DigestOutputLen];
char tmpBuf2[kSHA1DigestOutputLen];
- LOGW("Warning: bad SHA1 digest (%s vs %s)\n",
+ LOGE("ERROR: bad SHA1 digest (%s vs %s)\n",
dexSHA1DigestToStr(sha1Digest, tmpBuf1),
dexSHA1DigestToStr(pHeader->signature, tmpBuf2));
- /* for now, keep going */
+ if (!(flags & kDexParseContinueOnError))
+ goto bail;
} else {
LOGV("+++ sha1 digest verified\n");
}
}
if (pHeader->fileSize != length) {
- LOGW("Warning: embedded file size (%d) != expected (%d)\n",
+ LOGE("ERROR: stored file size (%d) != expected (%d)\n",
(int) pHeader->fileSize, (int) length);
- /* keep going, maybe it'll be okay */
+ if (!(flags & kDexParseContinueOnError))
+ goto bail;
}
if (pHeader->classDefsSize == 0) {
- LOGW("DEX file has no classes in it, failing\n");
+ LOGE("ERROR: DEX file has no classes in it, failing\n");
goto bail;
}
@@ -869,6 +869,20 @@
/*
+ * Compute the DEX file checksum for a memory-mapped DEX file.
+ */
+u4 dexComputeChecksum(const DexHeader* pHeader)
+{
+ const u1* start = (const u1*) pHeader;
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+ const int nonSum = sizeof(pHeader->magic) + sizeof(pHeader->checksum);
+
+ return (u4) adler32(adler, start + nonSum, pHeader->fileSize - nonSum);
+}
+
+
+/*
* ===========================================================================
* Debug info
* ===========================================================================
@@ -1115,8 +1129,14 @@
goto invalid_stream;
}
- localInReg[reg].startAddress = address;
- localInReg[reg].live = true;
+ /*
+ * If the register is live, the "restart" is superfluous,
+ * and we don't want to mess with the existing start address.
+ */
+ if (!localInReg[reg].live) {
+ localInReg[reg].startAddress = address;
+ localInReg[reg].live = true;
+ }
break;
case DBG_SET_PROLOGUE_END:
diff --git a/libdex/DexFile.h b/libdex/DexFile.h
index 8a60f25..d1ea5eb 100644
--- a/libdex/DexFile.h
+++ b/libdex/DexFile.h
@@ -546,6 +546,7 @@
enum {
kDexParseDefault = 0,
kDexParseVerifyChecksum = 1,
+ kDexParseContinueOnError = (1 << 1),
};
/*
@@ -557,6 +558,11 @@
int dexFixByteOrdering(u1* addr, int len);
/*
+ * Compute DEX checksum.
+ */
+u4 dexComputeChecksum(const DexHeader* pHeader);
+
+/*
* Free a DexFile structure, along with any associated structures.
*/
void dexFileFree(DexFile* pDexFile);
diff --git a/libdex/DexSwapVerify.c b/libdex/DexSwapVerify.c
index 6ccd820..5ecda9f 100644
--- a/libdex/DexSwapVerify.c
+++ b/libdex/DexSwapVerify.c
@@ -2753,6 +2753,43 @@
}
if (okay) {
+ int expectedLen = (int) SWAP4(pHeader->fileSize);
+ if (len < expectedLen) {
+ LOGE("ERROR: Bad length: expected %d, got %d\n", expectedLen, len);
+ okay = false;
+ } else if (len != expectedLen) {
+ LOGW("WARNING: Odd length: expected %d, got %d\n", expectedLen,
+ len);
+ // keep going
+ }
+ }
+
+ if (okay) {
+ /*
+ * Compute the adler32 checksum and compare it to what's stored in
+ * the file. This isn't free, but chances are good that we just
+ * unpacked this from a jar file and have all of the pages sitting
+ * in memory, so it's pretty quick.
+ *
+ * This might be a big-endian system, so we need to do this before
+ * we byte-swap the header.
+ */
+ uLong adler = adler32(0L, Z_NULL, 0);
+ const int nonSum = sizeof(pHeader->magic) + sizeof(pHeader->checksum);
+ u4 storedFileSize = SWAP4(pHeader->fileSize);
+ u4 expectedChecksum = SWAP4(pHeader->checksum);
+
+ adler = adler32(adler, ((const u1*) pHeader) + nonSum,
+ storedFileSize - nonSum);
+
+ if (adler != expectedChecksum) {
+ LOGE("ERROR: bad checksum (%08lx, expected %08x)\n",
+ adler, expectedChecksum);
+ okay = false;
+ }
+ }
+
+ if (okay) {
state.fileStart = addr;
state.fileEnd = addr + len;
state.fileLen = len;
@@ -2781,18 +2818,6 @@
}
if (okay) {
- int expectedLen = (int) pHeader->fileSize;
- if (len < expectedLen) {
- LOGE("ERROR: Bad length: expected %d, got %d\n", expectedLen, len);
- okay = false;
- } else if (len != expectedLen) {
- LOGW("WARNING: Odd length: expected %d, got %d\n", expectedLen,
- len);
- // keep going
- }
- }
-
- if (okay) {
/*
* Look for the map. Swap it and then use it to find and swap
* everything else.
diff --git a/libdex/InstrUtils.c b/libdex/InstrUtils.c
index bd0c553..b0718f3 100644
--- a/libdex/InstrUtils.c
+++ b/libdex/InstrUtils.c
@@ -1057,7 +1057,7 @@
pDec->vA = (s1) INST_AA(inst); // sign-extend 8-bit value
break;
case kFmt20t: // op +AAAA
- pDec->vB = (s2) FETCH(1); // sign-extend 16-bit value
+ pDec->vA = (s2) FETCH(1); // sign-extend 16-bit value
break;
case kFmt21c: // op vAA, thing@BBBB
case kFmt22x: // op vAA, vBBBB
@@ -1232,4 +1232,3 @@
}
return width;
}
-
diff --git a/libdex/OpCode.h b/libdex/OpCode.h
index 32aebdd..d389472 100644
--- a/libdex/OpCode.h
+++ b/libdex/OpCode.h
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* Dalvik opcode enumeration.
*/
@@ -36,24 +37,19 @@
* - update the parallel definitions in the class dalvik.bytecode.Opcodes
*
* Interpreter:
- * - implement/update the instruction in C in interp/InterpCore.h
+ * - implement/update the instruction in C in mterp/c/...
* - verify new code by running with "dalvik.vm.execution-mode =
* int:portable" or "-Xint:portable"
- * - propagate the changes to mterp/c/...
- * - verify by configuring "mterp" to use C instead of asm in the
- * mterp config file and running with "dalvik.vm.execution-mode =
- * int:fast" or "-Xint:fast"
* - implement/update the instruction in ARM in mterp/armv5/...
* - verify by enabling ARM handler for that instruction in mterp config
* and running int:fast as above
- * - for the previous two, rebuild mterp by cd'ing to mterp and running
- * ./rebuild.sh; files get written into the out subdirectory
+ * - repeat for other platforms (x86, ...)
+ * (see notes in mterp/ReadMe.txt for rebuilding instructions)
*
* Verifier / optimizer:
* - update some stuff in analysis/DexOptimize.c, analysis/DexVerify.c,
* and/or analysis/CodeVerify.c as needed
- * - verify by running with "dalvik.vm.verify-bytecode = true" or
- * "-Xverify:all"
+ * - verify by running with verifier enabled (it's on by default)
*
* Tools:
* - update the OpCodeNames table in dexdump/OpCodeNames.c
diff --git a/libdex/OptInvocation.h b/libdex/OptInvocation.h
index e4c978e..d9708ca 100644
--- a/libdex/OptInvocation.h
+++ b/libdex/OptInvocation.h
@@ -40,6 +40,7 @@
#define DEXOPT_VERIFY_ENABLED (1 << 2)
#define DEXOPT_VERIFY_ALL (1 << 3)
#define DEXOPT_IS_BOOTSTRAP (1 << 4)
+#define DEXOPT_GEN_REGISTER_MAP (1 << 5)
#ifdef __cplusplus
diff --git a/tools/get-hprof b/tools/get-hprof
index f87a13c..d56d7ad 100755
--- a/tools/get-hprof
+++ b/tools/get-hprof
@@ -14,14 +14,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Grab a pair of hprof files using adb. If an argument is specified, grab
+# Grab an hprof file using adb. If an argument is specified, grab
# the so-named file. If no argument is specified, grab the last such file
# as found by using "ls".
FILE_BASE="$1"
if [ "x$FILE_BASE" = "x" ]; then
# Note: substr() is to get rid of the final carriage return.
- FILE_BASE=`adb shell ls '/data/misc/heap-dump*.hprof' | tail -1 | \
+ FILE_BASE=`adb shell ls -l '/data/misc/heap-dump*.hprof' | tail -1 | \
awk '{ printf("%s", substr($7, 1, length($7) - 1)); }'`
if [ "x$FILE_BASE" = "x" ]; then
echo "No file base defined."
@@ -29,22 +29,13 @@
fi
fi
-FILE_BASE=/data/misc/`echo $FILE_BASE | sed -e 's,^/data/misc/,,;s,-head$,,'`
-
-HEAD_FILE=/tmp/hprof-head
-TAIL_FILE=/tmp/hprof-tail
+FILE_BASE=/data/misc/${FILE_BASE}
OUT_FILE=heap-dump.hprof
-adb pull "${FILE_BASE}-head" "$HEAD_FILE"
-if [ "$?" -ne 0 ]; then
- echo "Failed pulling ${FILE_BASE}-head."
- exit 1
-fi
-adb pull "$FILE_BASE" "$TAIL_FILE"
+adb pull "$FILE_BASE" "$OUT_FILE"
if [ $? -ne 0 ]; then
echo "Failed pulling $FILE_BASE."
exit 1
fi
-cat "$HEAD_FILE" "$TAIL_FILE" > "$OUT_FILE"
-rm "$HEAD_FILE" "$TAIL_FILE"
echo "hat $OUT_FILE"
+exit 0
diff --git a/tools/hprof-conv/Android.mk b/tools/hprof-conv/Android.mk
new file mode 100644
index 0000000..fbac5fa
--- /dev/null
+++ b/tools/hprof-conv/Android.mk
@@ -0,0 +1,21 @@
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := HprofConv.c
+LOCAL_MODULE := hprof-conv
+include $(BUILD_HOST_EXECUTABLE)
+
diff --git a/tools/hprof-conv/HprofConv.c b/tools/hprof-conv/HprofConv.c
new file mode 100644
index 0000000..10f3d2c
--- /dev/null
+++ b/tools/hprof-conv/HprofConv.c
@@ -0,0 +1,719 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Strip Android-specific records out of hprof data, back-converting from
+ * 1.0.3 to 1.0.2. This removes some useful information, but allows
+ * Android hprof data to be handled by widely-available tools (like "jhat").
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+
+//#define VERBOSE_DEBUG
+#ifdef VERBOSE_DEBUG
+# define DBUG(...) fprintf(stderr, __VA_ARGS__)
+#else
+# define DBUG(...)
+#endif
+
+#ifndef FALSE
+# define FALSE 0
+# define TRUE (!FALSE)
+#endif
+
+typedef enum HprofBasicType {
+ HPROF_BASIC_OBJECT = 2,
+ HPROF_BASIC_BOOLEAN = 4,
+ HPROF_BASIC_CHAR = 5,
+ HPROF_BASIC_FLOAT = 6,
+ HPROF_BASIC_DOUBLE = 7,
+ HPROF_BASIC_BYTE = 8,
+ HPROF_BASIC_SHORT = 9,
+ HPROF_BASIC_INT = 10,
+ HPROF_BASIC_LONG = 11,
+} HprofBasicType;
+
+typedef enum HprofTag {
+ /* tags we must handle specially */
+ HPROF_TAG_HEAP_DUMP = 0x0c,
+ HPROF_TAG_HEAP_DUMP_SEGMENT = 0x1c,
+} HprofTag;
+
+typedef enum HprofHeapTag {
+ /* 1.0.2 tags */
+ HPROF_ROOT_UNKNOWN = 0xff,
+ HPROF_ROOT_JNI_GLOBAL = 0x01,
+ HPROF_ROOT_JNI_LOCAL = 0x02,
+ HPROF_ROOT_JAVA_FRAME = 0x03,
+ HPROF_ROOT_NATIVE_STACK = 0x04,
+ HPROF_ROOT_STICKY_CLASS = 0x05,
+ HPROF_ROOT_THREAD_BLOCK = 0x06,
+ HPROF_ROOT_MONITOR_USED = 0x07,
+ HPROF_ROOT_THREAD_OBJECT = 0x08,
+ HPROF_CLASS_DUMP = 0x20,
+ HPROF_INSTANCE_DUMP = 0x21,
+ HPROF_OBJECT_ARRAY_DUMP = 0x22,
+ HPROF_PRIMITIVE_ARRAY_DUMP = 0x23,
+
+ /* Android 1.0.3 tags */
+ HPROF_HEAP_DUMP_INFO = 0xfe,
+ HPROF_ROOT_INTERNED_STRING = 0x89,
+ HPROF_ROOT_FINALIZING = 0x8a,
+ HPROF_ROOT_DEBUGGER = 0x8b,
+ HPROF_ROOT_REFERENCE_CLEANUP = 0x8c,
+ HPROF_ROOT_VM_INTERNAL = 0x8d,
+ HPROF_ROOT_JNI_MONITOR = 0x8e,
+ HPROF_UNREACHABLE = 0x90,
+ HPROF_PRIMITIVE_ARRAY_NODATA_DUMP = 0xc3,
+} HprofHeapTag;
+
+#define kIdentSize 4
+#define kRecHdrLen 9
+
+
+/*
+ * ===========================================================================
+ * Expanding buffer
+ * ===========================================================================
+ */
+
+/* simple struct */
+typedef struct {
+ unsigned char* storage;
+ size_t curLen;
+ size_t maxLen;
+} ExpandBuf;
+
+/*
+ * Create an ExpandBuf.
+ */
+static ExpandBuf* ebAlloc(void)
+{
+ static const int kInitialSize = 64;
+
+ ExpandBuf* newBuf = (ExpandBuf*) malloc(sizeof(ExpandBuf));
+ if (newBuf == NULL)
+ return NULL;
+ newBuf->storage = (unsigned char*) malloc(kInitialSize);
+ newBuf->curLen = 0;
+ newBuf->maxLen = kInitialSize;
+
+ return newBuf;
+}
+
+/*
+ * Release the storage associated with an ExpandBuf.
+ */
+static void ebFree(ExpandBuf* pBuf)
+{
+ if (pBuf != NULL) {
+ free(pBuf->storage);
+ free(pBuf);
+ }
+}
+
+/*
+ * Return a pointer to the data buffer.
+ *
+ * The pointer may change as data is added to the buffer, so this value
+ * should not be cached.
+ */
+static inline unsigned char* ebGetBuffer(ExpandBuf* pBuf)
+{
+ return pBuf->storage;
+}
+
+/*
+ * Get the amount of data currently in the buffer.
+ */
+static inline size_t ebGetLength(ExpandBuf* pBuf)
+{
+ return pBuf->curLen;
+}
+
+/*
+ * Empty the buffer.
+ */
+static void ebClear(ExpandBuf* pBuf)
+{
+ pBuf->curLen = 0;
+}
+
+/*
+ * Ensure that the buffer can hold at least "size" additional bytes.
+ */
+static int ebEnsureCapacity(ExpandBuf* pBuf, int size)
+{
+ assert(size > 0);
+
+ if (pBuf->curLen + size > pBuf->maxLen) {
+ int newSize = pBuf->curLen + size + 128; /* oversize slightly */
+ unsigned char* newStorage = realloc(pBuf->storage, newSize);
+ if (newStorage == NULL) {
+ fprintf(stderr, "ERROR: realloc failed on size=%d\n", newSize);
+ return -1;
+ }
+
+ pBuf->storage = newStorage;
+ pBuf->maxLen = newSize;
+ }
+
+ assert(pBuf->curLen + size <= pBuf->maxLen);
+ return 0;
+}
+
+/*
+ * Add data to the buffer after ensuring it can hold it.
+ */
+static int ebAddData(ExpandBuf* pBuf, const void* data, size_t count)
+{
+ ebEnsureCapacity(pBuf, count);
+ memcpy(pBuf->storage + pBuf->curLen, data, count);
+ pBuf->curLen += count;
+ return 0;
+}
+
+/*
+ * Read a NULL-terminated string from the input.
+ */
+static int ebReadString(ExpandBuf* pBuf, FILE* in)
+{
+ int ic;
+
+ do {
+ ebEnsureCapacity(pBuf, 1);
+
+ ic = getc(in);
+ if (feof(in) || ferror(in)) {
+ fprintf(stderr, "ERROR: failed reading input\n");
+ return -1;
+ }
+
+ pBuf->storage[pBuf->curLen++] = (unsigned char) ic;
+ } while (ic != 0);
+
+ return 0;
+}
+
+/*
+ * Read some data, adding it to the expanding buffer.
+ *
+ * This will ensure that the buffer has enough space to hold the new data
+ * (plus the previous contents).
+ */
+static int ebReadData(ExpandBuf* pBuf, FILE* in, size_t count, int eofExpected)
+{
+ size_t actual;
+
+ assert(count > 0);
+
+ ebEnsureCapacity(pBuf, count);
+ actual = fread(pBuf->storage + pBuf->curLen, 1, count, in);
+ if (actual != count) {
+ if (eofExpected && feof(in) && !ferror(in)) {
+ /* return without reporting an error */
+ } else {
+ fprintf(stderr, "ERROR: read %d of %d bytes\n", actual, count);
+ return -1;
+ }
+ }
+
+ pBuf->curLen += count;
+ assert(pBuf->curLen <= pBuf->maxLen);
+
+ return 0;
+}
+
+/*
+ * Write the data from the buffer. Resets the data count to zero.
+ */
+static int ebWriteData(ExpandBuf* pBuf, FILE* out)
+{
+ size_t actual;
+
+ assert(pBuf->curLen > 0);
+ assert(pBuf->curLen <= pBuf->maxLen);
+
+ actual = fwrite(pBuf->storage, 1, pBuf->curLen, out);
+ if (actual != pBuf->curLen) {
+ fprintf(stderr, "ERROR: write %d of %d bytes\n", actual, pBuf->curLen);
+ return -1;
+ }
+
+ pBuf->curLen = 0;
+
+ return 0;
+}
+
+
+/*
+ * ===========================================================================
+ * Hprof stuff
+ * ===========================================================================
+ */
+
+/*
+ * Get a 2-byte value, in big-endian order, from memory.
+ */
+static uint16_t get2BE(const unsigned char* buf)
+{
+ uint16_t val;
+
+ val = (buf[0] << 8) | buf[1];
+ return val;
+}
+
+/*
+ * Get a 4-byte value, in big-endian order, from memory.
+ */
+static uint32_t get4BE(const unsigned char* buf)
+{
+ uint32_t val;
+
+ val = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+ return val;
+}
+
+/*
+ * Set a 4-byte value, in big-endian order.
+ */
+static void set4BE(unsigned char* buf, uint32_t val)
+{
+ buf[0] = val >> 24;
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val;
+}
+
+/*
+ * Get the size, in bytes, of one of the "basic types".
+ */
+static int computeBasicLen(HprofBasicType basicType)
+{
+ static const int sizes[] = { -1, -1, 4, -1, 1, 2, 4, 8, 1, 2, 4, 8 };
+ static const size_t maxSize = sizeof(sizes) / sizeof(sizes[0]);
+
+ assert(basicType >= 0);
+ if (basicType >= maxSize)
+ return -1;
+ return sizes[basicType];
+}
+
+/*
+ * Compute the length of a HPROF_CLASS_DUMP block.
+ */
+static int computeClassDumpLen(const unsigned char* origBuf, int len)
+{
+ const unsigned char* buf = origBuf;
+ int blockLen = 0;
+ int i, count;
+
+ blockLen += kIdentSize * 7 + 8;
+ buf += blockLen;
+ len -= blockLen;
+
+ if (len < 0)
+ return -1;
+
+ count = get2BE(buf);
+ buf += 2;
+ len -= 2;
+ DBUG("CDL: 1st count is %d\n", count);
+ for (i = 0; i < count; i++) {
+ HprofBasicType basicType;
+ int basicLen;
+
+ basicType = buf[2];
+ basicLen = computeBasicLen(basicType);
+ if (basicLen < 0) {
+ DBUG("ERROR: invalid basicType %d\n", basicType);
+ return -1;
+ }
+
+ buf += 2 + 1 + basicLen;
+ len -= 2 + 1 + basicLen;
+ if (len < 0)
+ return -1;
+ }
+
+ count = get2BE(buf);
+ buf += 2;
+ len -= 2;
+ DBUG("CDL: 2nd count is %d\n", count);
+ for (i = 0; i < count; i++) {
+ HprofBasicType basicType;
+ int basicLen;
+
+ basicType = buf[kIdentSize];
+ basicLen = computeBasicLen(basicType);
+ if (basicLen < 0) {
+ fprintf(stderr, "ERROR: invalid basicType %d\n", basicType);
+ return -1;
+ }
+
+ buf += kIdentSize + 1 + basicLen;
+ len -= kIdentSize + 1 + basicLen;
+ if (len < 0)
+ return -1;
+ }
+
+ count = get2BE(buf);
+ buf += 2;
+ len -= 2;
+ DBUG("CDL: 3rd count is %d\n", count);
+ for (i = 0; i < count; i++) {
+ buf += kIdentSize + 1;
+ len -= kIdentSize + 1;
+ if (len < 0)
+ return -1;
+ }
+
+ DBUG("Total class dump len: %d\n", buf - origBuf);
+ return buf - origBuf;
+}
+
+/*
+ * Compute the length of a HPROF_INSTANCE_DUMP block.
+ */
+static int computeInstanceDumpLen(const unsigned char* origBuf, int len)
+{
+ int extraCount = get4BE(origBuf + kIdentSize * 2 + 4);
+ return kIdentSize * 2 + 8 + extraCount;
+}
+
+/*
+ * Compute the length of a HPROF_OBJECT_ARRAY_DUMP block.
+ */
+static int computeObjectArrayDumpLen(const unsigned char* origBuf, int len)
+{
+ int arrayCount = get4BE(origBuf + kIdentSize + 4);
+ return kIdentSize * 2 + 8 + arrayCount * kIdentSize;
+}
+
+/*
+ * Compute the length of a HPROF_PRIMITIVE_ARRAY_DUMP block.
+ */
+static int computePrimitiveArrayDumpLen(const unsigned char* origBuf, int len)
+{
+ int arrayCount = get4BE(origBuf + kIdentSize + 4);
+ HprofBasicType basicType = origBuf[kIdentSize + 8];
+ int basicLen = computeBasicLen(basicType);
+
+ return kIdentSize + 9 + arrayCount * basicLen;
+}
+
+/*
+ * Crunch through a heap dump record, writing the original or converted
+ * data to "out".
+ */
+static int processHeapDump(ExpandBuf* pBuf, FILE* out)
+{
+ ExpandBuf* pOutBuf = ebAlloc();
+ unsigned char* origBuf = ebGetBuffer(pBuf);
+ unsigned char* buf = origBuf;
+ int len = ebGetLength(pBuf);
+ int result = -1;
+
+ pBuf = NULL; /* we just use the raw pointer from here forward */
+
+ /* copy the original header to the output buffer */
+ if (ebAddData(pOutBuf, buf, kRecHdrLen) != 0)
+ goto bail;
+
+ buf += kRecHdrLen; /* skip past record header */
+ len -= kRecHdrLen;
+
+ while (len > 0) {
+ unsigned char subType = buf[0];
+ int justCopy = TRUE;
+ int subLen;
+
+ DBUG("--- 0x%02x ", subType);
+ switch (subType) {
+ /* 1.0.2 types */
+ case HPROF_ROOT_UNKNOWN:
+ subLen = kIdentSize;
+ break;
+ case HPROF_ROOT_JNI_GLOBAL:
+ subLen = kIdentSize * 2;
+ break;
+ case HPROF_ROOT_JNI_LOCAL:
+ subLen = kIdentSize + 8;
+ break;
+ case HPROF_ROOT_JAVA_FRAME:
+ subLen = kIdentSize + 8;
+ break;
+ case HPROF_ROOT_NATIVE_STACK:
+ subLen = kIdentSize + 4;
+ break;
+ case HPROF_ROOT_STICKY_CLASS:
+ subLen = kIdentSize;
+ break;
+ case HPROF_ROOT_THREAD_BLOCK:
+ subLen = kIdentSize + 4;
+ break;
+ case HPROF_ROOT_MONITOR_USED:
+ subLen = kIdentSize;
+ break;
+ case HPROF_ROOT_THREAD_OBJECT:
+ subLen = kIdentSize + 8;
+ break;
+ case HPROF_CLASS_DUMP:
+ subLen = computeClassDumpLen(buf+1, len-1);
+ break;
+ case HPROF_INSTANCE_DUMP:
+ subLen = computeInstanceDumpLen(buf+1, len-1);
+ break;
+ case HPROF_OBJECT_ARRAY_DUMP:
+ subLen = computeObjectArrayDumpLen(buf+1, len-1);
+ break;
+ case HPROF_PRIMITIVE_ARRAY_DUMP:
+ subLen = computePrimitiveArrayDumpLen(buf+1, len-1);
+ break;
+
+ /* these were added for Android in 1.0.3 */
+ case HPROF_HEAP_DUMP_INFO:
+ justCopy = FALSE;
+ subLen = kIdentSize + 4;
+ // no 1.0.2 equivalent for this
+ break;
+ case HPROF_ROOT_INTERNED_STRING:
+ buf[0] = HPROF_ROOT_UNKNOWN;
+ subLen = kIdentSize;
+ break;
+ case HPROF_ROOT_FINALIZING:
+ buf[0] = HPROF_ROOT_UNKNOWN;
+ subLen = kIdentSize;
+ break;
+ case HPROF_ROOT_DEBUGGER:
+ buf[0] = HPROF_ROOT_UNKNOWN;
+ subLen = kIdentSize;
+ break;
+ case HPROF_ROOT_REFERENCE_CLEANUP:
+ buf[0] = HPROF_ROOT_UNKNOWN;
+ subLen = kIdentSize;
+ break;
+ case HPROF_ROOT_VM_INTERNAL:
+ buf[0] = HPROF_ROOT_UNKNOWN;
+ subLen = kIdentSize;
+ break;
+ case HPROF_ROOT_JNI_MONITOR:
+ /* keep the ident, drop the next 8 bytes */
+ buf[0] = HPROF_ROOT_UNKNOWN;
+ justCopy = FALSE;
+ ebAddData(pOutBuf, buf, 1 + kIdentSize);
+ subLen = kIdentSize + 8;
+ break;
+ case HPROF_UNREACHABLE:
+ buf[0] = HPROF_ROOT_UNKNOWN;
+ subLen = kIdentSize;
+ break;
+ case HPROF_PRIMITIVE_ARRAY_NODATA_DUMP:
+ buf[0] = HPROF_PRIMITIVE_ARRAY_DUMP;
+ buf[5] = buf[6] = buf[7] = buf[8] = 0; /* set array len to 0 */
+ subLen = kIdentSize + 9;
+ break;
+
+ /* shouldn't get here */
+ default:
+ fprintf(stderr, "ERROR: unexpected subtype 0x%02x at offset %d\n",
+ subType, buf - origBuf);
+ goto bail;
+ }
+
+ if (justCopy) {
+ /* copy source data */
+ DBUG("(%d)\n", 1 + subLen);
+ ebAddData(pOutBuf, buf, 1 + subLen);
+ } else {
+ /* other data has been written, or the sub-record omitted */
+ DBUG("(adv %d)\n", 1 + subLen);
+ }
+
+ /* advance to next entry */
+ buf += 1 + subLen;
+ len -= 1 + subLen;
+ }
+
+ /*
+ * Update the record length.
+ */
+ set4BE(ebGetBuffer(pOutBuf) + 5, ebGetLength(pOutBuf) - kRecHdrLen);
+
+ if (ebWriteData(pOutBuf, out) != 0)
+ goto bail;
+
+ result = 0;
+
+bail:
+ ebFree(pOutBuf);
+ return result;
+}
+
+/*
+ * Filter an hprof data file.
+ */
+static int filterData(FILE* in, FILE* out)
+{
+ ExpandBuf* pBuf;
+ int result = -1;
+
+ pBuf = ebAlloc();
+ if (pBuf == NULL)
+ goto bail;
+
+ /*
+ * Start with the header.
+ */
+ if (ebReadString(pBuf, in) != 0)
+ goto bail;
+
+ if (strcmp((const char*)ebGetBuffer(pBuf), "JAVA PROFILE 1.0.3") != 0) {
+ fprintf(stderr, "ERROR: expecting 1.0.3\n");
+ goto bail;
+ }
+
+ /* downgrade to 1.0.2 */
+ (ebGetBuffer(pBuf))[17] = '2';
+ if (ebWriteData(pBuf, out) != 0)
+ goto bail;
+
+ /*
+ * Copy:
+ * (4b) identifier size, always 4
+ * (8b) file creation date
+ */
+ if (ebReadData(pBuf, in, 12, FALSE) != 0)
+ goto bail;
+ if (ebWriteData(pBuf, out) != 0)
+ goto bail;
+
+ /*
+ * Read records until we hit EOF. Each record begins with:
+ * (1b) type
+ * (4b) timestamp
+ * (4b) length of data that follows
+ */
+ while (1) {
+ assert(ebGetLength(pBuf) == 0);
+
+ /* read type char */
+ if (ebReadData(pBuf, in, 1, TRUE) != 0)
+ goto bail;
+ if (feof(in))
+ break;
+
+ /* read the rest of the header */
+ if (ebReadData(pBuf, in, kRecHdrLen-1, FALSE) != 0)
+ goto bail;
+
+ unsigned char* buf = ebGetBuffer(pBuf);
+ unsigned char type;
+ unsigned int timestamp, length;
+
+ type = buf[0];
+ timestamp = get4BE(buf + 1);
+ length = get4BE(buf + 5);
+ buf = NULL; /* ptr invalid after next read op */
+
+ /* read the record data */
+ if (length != 0) {
+ if (ebReadData(pBuf, in, length, FALSE) != 0)
+ goto bail;
+ }
+
+ if (type == HPROF_TAG_HEAP_DUMP ||
+ type == HPROF_TAG_HEAP_DUMP_SEGMENT)
+ {
+ DBUG("Processing heap dump 0x%02x (%d bytes)\n",
+ type, length);
+ if (processHeapDump(pBuf, out) != 0)
+ goto bail;
+ ebClear(pBuf);
+ } else {
+ /* keep */
+ DBUG("Keeping 0x%02x (%d bytes)\n", type, length);
+ if (ebWriteData(pBuf, out) != 0)
+ goto bail;
+ }
+ }
+
+ result = 0;
+
+bail:
+ ebFree(pBuf);
+ return result;
+}
+
+/*
+ * Get args.
+ */
+int main(int argc, char** argv)
+{
+ FILE* in = stdin;
+ FILE* out = stdout;
+ int cc;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: hprof-conf infile outfile\n\n");
+ fprintf(stderr,
+ "Specify '-' for either or both to use stdin/stdout.\n\n");
+
+ fprintf(stderr,
+ "Copyright (C) 2009 The Android Open Source Project\n\n"
+ "This software is built from source code licensed under the "
+ "Apache License,\n"
+ "Version 2.0 (the \"License\"). You may obtain a copy of the "
+ "License at\n\n"
+ " http://www.apache.org/licenses/LICENSE-2.0\n\n"
+ "See the associated NOTICE file for this software for further "
+ "details.\n");
+
+ return 2;
+ }
+
+ if (strcmp(argv[1], "-") != 0) {
+ in = fopen(argv[1], "rb");
+ if (in == NULL) {
+ fprintf(stderr, "ERROR: failed to open input '%s': %s\n",
+ argv[1], strerror(errno));
+ return 1;
+ }
+ }
+ if (strcmp(argv[2], "-") != 0) {
+ out = fopen(argv[2], "wb");
+ if (out == NULL) {
+ fprintf(stderr, "ERROR: failed to open output '%s': %s\n",
+ argv[2], strerror(errno));
+ if (in != stdin)
+ fclose(in);
+ return 1;
+ }
+ }
+
+ cc = filterData(in, out);
+
+ if (in != stdin)
+ fclose(in);
+ if (out != stdout)
+ fclose(out);
+ return (cc != 0);
+}
+
diff --git a/vm/DalvikVersion.h b/vm/DalvikVersion.h
index 03d1382..4926fd0 100644
--- a/vm/DalvikVersion.h
+++ b/vm/DalvikVersion.h
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* Dalvik VM version info.
*/
@@ -24,13 +25,13 @@
*/
#define DALVIK_MAJOR_VERSION 1
#define DALVIK_MINOR_VERSION 0
-#define DALVIK_BUG_VERSION 0
+#define DALVIK_BUG_VERSION 1
/*
* VM build number. This must change whenever something that affects the
* way classes load changes, e.g. field ordering or vtable layout. Changing
* this guarantees that the optimized form of the DEX file is regenerated.
*/
-#define DALVIK_VM_BUILD 13
+#define DALVIK_VM_BUILD 14
#endif /*_DALVIK_VERSION*/
diff --git a/vm/Debugger.c b/vm/Debugger.c
index f8e3b75..c667893 100644
--- a/vm/Debugger.c
+++ b/vm/Debugger.c
@@ -2941,7 +2941,8 @@
void dvmDbgDdmSendChunk(int type, int len, const u1* buf)
{
if (gDvm.jdwpState == NULL) {
- LOGI("Ignoring DDM send req for type=0x%08x len=%d\n", type, len);
+ LOGI("Debugger thread not active, ignoring DDM send (t=0x%08x l=%d)\n",
+ type, len);
return;
}
diff --git a/vm/DvmDex.c b/vm/DvmDex.c
index 137e000..b5f8d02 100644
--- a/vm/DvmDex.c
+++ b/vm/DvmDex.c
@@ -117,8 +117,12 @@
DvmDex* pDvmDex;
DexFile* pDexFile;
MemMapping memMap;
+ int parseFlags = kDexParseDefault;
int result = -1;
+ if (gDvm.verifyDexChecksum)
+ parseFlags |= kDexParseVerifyChecksum;
+
if (lseek(fd, 0, SEEK_SET) < 0) {
LOGE("lseek rewind failed\n");
goto bail;
@@ -129,7 +133,7 @@
goto bail;
}
- pDexFile = dexFileParse(memMap.addr, memMap.length, kDexParseDefault);
+ pDexFile = dexFileParse(memMap.addr, memMap.length, parseFlags);
if (pDexFile == NULL) {
LOGE("DEX parse failed\n");
sysReleaseShmem(&memMap);
@@ -164,9 +168,13 @@
{
DvmDex* pDvmDex;
DexFile* pDexFile;
+ int parseFlags = kDexParseDefault;
int result = -1;
- pDexFile = dexFileParse(addr, len, kDexParseDefault);
+ if (gDvm.verifyDexChecksum)
+ parseFlags |= kDexParseVerifyChecksum;
+
+ pDexFile = dexFileParse(addr, len, parseFlags);
if (pDexFile == NULL) {
LOGE("DEX parse failed\n");
goto bail;
diff --git a/vm/Globals.h b/vm/Globals.h
index 82d01aa..f68e45d 100644
--- a/vm/Globals.h
+++ b/vm/Globals.h
@@ -92,12 +92,14 @@
int jniGrefLimit; // 0 means no limit
bool reduceSignals;
bool noQuitHandler;
+ bool verifyDexChecksum;
char* stackTraceFile; // for SIGQUIT-inspired output
bool logStdio;
DexOptimizerMode dexOptMode;
DexClassVerifyMode classVerifyMode;
+ bool generateRegisterMaps;
int assertionCtrlCount;
AssertionControl* assertionCtrl;
diff --git a/vm/Init.c b/vm/Init.c
index 036e36f..176910c 100644
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* Dalvik initialization, shutdown, and command-line argument processing.
*/
@@ -93,8 +94,10 @@
" -Xjnigreflimit:N (must be multiple of 100, >= 200)\n");
dvmFprintf(stderr, " -Xjniopts:{warnonly,forcecopy}\n");
dvmFprintf(stderr, " -Xdeadlockpredict:{off,warn,err,abort}\n");
- dvmFprintf(stderr, " -Xstacktracefile:<file name>");
- dvmFprintf(stderr, "\n\n");
+ dvmFprintf(stderr, " -Xstacktracefile:<filename>\n");
+ dvmFprintf(stderr, " -Xgenregmap\n");
+ dvmFprintf(stderr, " -Xcheckdexsum\n");
+ dvmFprintf(stderr, "\n");
dvmFprintf(stderr, "Configured with:"
#ifdef WITH_DEBUGGER
" debugger"
@@ -783,6 +786,12 @@
} else if (strncmp(argv[i], "-Xstacktracefile:", 17) == 0) {
gDvm.stackTraceFile = strdup(argv[i]+17);
+ } else if (strcmp(argv[i], "-Xgenregmap") == 0) {
+ gDvm.generateRegisterMaps = true;
+
+ } else if (strcmp(argv[i], "-Xcheckdexsum") == 0) {
+ gDvm.verifyDexChecksum = true;
+
} else {
if (!ignoreUnrecognized) {
dvmFprintf(stderr, "Unrecognized option '%s'\n", argv[i]);
@@ -1248,7 +1257,7 @@
* Returns 0 on success.
*/
int dvmPrepForDexOpt(const char* bootClassPath, DexOptimizerMode dexOptMode,
- DexClassVerifyMode verifyMode)
+ DexClassVerifyMode verifyMode, int dexoptFlags)
{
gDvm.initializing = true;
gDvm.optimizing = true;
@@ -1264,6 +1273,7 @@
/* set opt/verify modes */
gDvm.dexOptMode = dexOptMode;
gDvm.classVerifyMode = verifyMode;
+ gDvm.generateRegisterMaps = (dexoptFlags & DEXOPT_GEN_REGISTER_MAPS) != 0;
/*
* Initialize the heap, some basic thread control mutexes, and
diff --git a/vm/Init.h b/vm/Init.h
index 73d8fa6..8549338 100644
--- a/vm/Init.h
+++ b/vm/Init.h
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* VM initialization and shutdown.
*/
@@ -37,7 +38,7 @@
* asked to optimize a DEX file holding fundamental classes.
*/
int dvmPrepForDexOpt(const char* bootClassPath, DexOptimizerMode dexOptMode,
- DexClassVerifyMode verifyMode);
+ DexClassVerifyMode verifyMode, int dexoptFlags);
/*
* Unconditionally abort the entire VM. Try not to use this.
diff --git a/vm/SignalCatcher.c b/vm/SignalCatcher.c
index 3efc191..550f777 100644
--- a/vm/SignalCatcher.c
+++ b/vm/SignalCatcher.c
@@ -158,6 +158,7 @@
ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
printProcessName(&target);
dvmPrintDebugMessage(&target, "\n");
+ fflush(fp); /* emit at least the header if we crash during dump */
dvmDumpAllThreadsEx(&target, true);
fprintf(fp, "----- end %d -----\n", pid);
@@ -247,7 +248,7 @@
} else if (rcvd == SIGUSR1) {
#if WITH_HPROF
LOGI("SIGUSR1 forcing GC and HPROF dump\n");
- hprofDumpHeap();
+ hprofDumpHeap(NULL);
#else
LOGI("SIGUSR1 forcing GC (no HPROF)\n");
dvmCollectGarbage(false);
diff --git a/vm/Sync.c b/vm/Sync.c
index 96789c2..1f81349 100644
--- a/vm/Sync.c
+++ b/vm/Sync.c
@@ -527,7 +527,7 @@
* situation, but we need to handle it correctly.)
*/
if (mon->notifying + mon->interrupting > mon->waiting) {
- LOGI("threadid=%d: bogus mon %d+%d>%d; adjusting\n",
+ LOGD("threadid=%d: bogus mon %d+%d>%d; adjusting\n",
self->threadId, mon->notifying, mon->interrupting,
mon->waiting);
diff --git a/vm/alloc/Heap.c b/vm/alloc/Heap.c
index 4129a90..9ddc8be 100644
--- a/vm/alloc/Heap.c
+++ b/vm/alloc/Heap.c
@@ -829,11 +829,20 @@
#endif
if (gcHeap->hprofDumpOnGc) {
- gcHeap->hprofContext = hprofStartup("/data/misc");
+ char nameBuf[128];
+
+ if (gcHeap->hprofFileName == NULL) {
+ /* no filename was provided; invent one */
+ sprintf(nameBuf, "/data/misc/heap-dump-tm%d-pid%d.hprof",
+ (int) time(NULL), (int) getpid());
+ gcHeap->hprofFileName = nameBuf;
+ }
+ gcHeap->hprofContext = hprofStartup(gcHeap->hprofFileName);
if (gcHeap->hprofContext != NULL) {
hprofStartHeapDump(gcHeap->hprofContext);
}
gcHeap->hprofDumpOnGc = false;
+ gcHeap->hprofFileName = NULL;
}
#endif
@@ -1033,11 +1042,17 @@
}
#if WITH_HPROF
-void hprofDumpHeap()
+/*
+ * Perform garbage collection, writing heap information to the specified file.
+ *
+ * If "fileName" is NULL, a suitable name will be generated automatically.
+ */
+void hprofDumpHeap(const char* fileName)
{
dvmLockMutex(&gDvm.gcHeapLock);
gDvm.gcHeap->hprofDumpOnGc = true;
+ gDvm.gcHeap->hprofFileName = fileName;
dvmCollectGarbageInternal(false);
dvmUnlockMutex(&gDvm.gcHeapLock);
diff --git a/vm/alloc/HeapInternal.h b/vm/alloc/HeapInternal.h
index e3b212d..7851983 100644
--- a/vm/alloc/HeapInternal.h
+++ b/vm/alloc/HeapInternal.h
@@ -187,6 +187,7 @@
#if WITH_HPROF
bool hprofDumpOnGc;
+ const char* hprofFileName;
hprof_context_t *hprofContext;
#endif
};
diff --git a/vm/alloc/HeapSource.c b/vm/alloc/HeapSource.c
index 58952e8..d97290f 100644
--- a/vm/alloc/HeapSource.c
+++ b/vm/alloc/HeapSource.c
@@ -17,6 +17,7 @@
#include <cutils/mspace.h>
#include <limits.h> // for INT_MAX
#include <sys/mman.h>
+#include <errno.h>
#include "Dalvik.h"
#include "alloc/Heap.h"
@@ -298,6 +299,7 @@
* than the starting size.
*/
LOGV_HEAP("Creating VM heap of size %u\n", startSize);
+ errno = 0;
msp = create_contiguous_mspace_with_name(startSize/2,
absoluteMaxSize, /*locked=*/false, name);
if (msp != NULL) {
@@ -306,7 +308,11 @@
*/
mspace_set_max_allowed_footprint(msp, startSize);
} else {
- LOGE_HEAP("Can't create VM heap of size %u\n", startSize/2);
+ /* There's no guarantee that errno has meaning when the call
+ * fails, but it often does.
+ */
+ LOGE_HEAP("Can't create VM heap of size (%u,%u) (errno=%d)\n",
+ startSize/2, absoluteMaxSize, errno);
}
return msp;
diff --git a/vm/analysis/CodeVerify.c b/vm/analysis/CodeVerify.c
index b0e237e..911a479 100644
--- a/vm/analysis/CodeVerify.c
+++ b/vm/analysis/CodeVerify.c
@@ -29,6 +29,7 @@
*/
#include "Dalvik.h"
#include "analysis/CodeVerify.h"
+#include "analysis/RegisterMap.h"
#include "libdex/DexCatch.h"
#include "libdex/InstrUtils.h"
@@ -36,16 +37,22 @@
/*
- * If defined, store registers for all instructions, not just branch
- * targets. Increases memory usage and adds to CPU load. Only necessary
- * when generating data for exact GC.
+ * We don't need to store the register data for many instructions, because
+ * we either only need it at branch points (for verification) or GC points
+ * and branches (for verification + type-precise register analysis).
*/
-#define USE_FULL_TABLE false
+typedef enum RegisterTrackingMode {
+ kTrackRegsBranches,
+ kTrackRegsGcPoints,
+ kTrackRegsAll
+} RegisterTrackingMode;
/*
* Set this to enable dead code scanning. This is not required, but it's
* very useful when testing changes to the verifier (to make sure we're not
* skipping over stuff) and for checking the optimized output from "dx".
+ * The only reason not to do it is that it slightly increases the time
+ * required to perform verification.
*/
#define DEAD_CODE_SCAN true
@@ -82,21 +89,13 @@
#define RESULT_REGISTER(_insnRegCount) (_insnRegCount)
/*
- * RegType holds information about the type of data held in a register.
- * For most types it's a simple enum. For reference types it holds a
- * pointer to the ClassObject, and for uninitialized references it holds
- * an index into the UninitInstanceMap.
- */
-typedef u4 RegType;
-
-/*
* Big fat collection of registers.
*/
typedef struct RegisterTable {
/*
* Array of RegType arrays, one per address in the method. We only
- * set the pointers for addresses that are branch targets unless
- * USE_FULL_TABLE is true.
+ * set the pointers for certain addresses, based on what we're trying
+ * to accomplish.
*/
RegType** addrRegs;
@@ -104,7 +103,7 @@
* Number of registers we track for each instruction. This is equal
* to the method's declared "registersSize" plus kExtraRegs.
*/
- int insnRegCount;
+ int insnRegCountPlus;
/*
* A single large alloc, with all of the storage needed for addrRegs.
@@ -293,37 +292,34 @@
}
/*
- * Determine whether or not "srcType" and "checkType" have the same width.
- * The idea is to determine whether or not it's okay to use a sub-integer
- * instruction (say, sget-short) with a primitive field of a specific type.
+ * Determine whether or not "instrType" and "targetType" are compatible,
+ * for purposes of getting or setting a value in a field or array. The
+ * idea is that an instruction with a category 1nr type (say, aget-short
+ * or iput-boolean) is accessing a static field, instance field, or array
+ * entry, and we want to make sure sure that the operation is legal.
*
- * We should always be passed "definite" types here; pseudo-types like
- * kRegTypeZero are not expected. We could get kRegTypeUnknown if a type
- * lookup failed.
+ * At a minimum, source and destination must have the same width. We
+ * further refine this to assert that "short" and "char" are not
+ * compatible, because the sign-extension is different on the "get"
+ * operations. As usual, "float" and "int" are interoperable.
+ *
+ * We're not considering the actual contents of the register, so we'll
+ * never get "pseudo-types" like kRegTypeZero or kRegTypePosShort. We
+ * could get kRegTypeUnknown in "targetType" if a field or array class
+ * lookup failed. Category 2 types and references are checked elsewhere.
*/
-static bool isTypeWidthEqual1nr(RegType type1, RegType type2)
+static bool checkFieldArrayStore1nr(RegType instrType, RegType targetType)
{
- /* primitive sizes; we use zero for boolean so it's not equal to others */
- static const char sizeTab[kRegType1nrEND-kRegType1nrSTART+1] = {
- /* F 0 1 Z b B s S C I */
- 4, 8, 9, 0, 1, 1, 2, 2, 2, 4
- };
-
- assert(type1 != kRegTypeZero && type1 != kRegTypeOne &&
- type1 != kRegTypePosByte && type1 != kRegTypePosShort);
- assert(type2 != kRegTypeZero && type2 != kRegTypeOne &&
- type2 != kRegTypePosByte && type2 != kRegTypePosShort);
-
- if (type1 == type2)
+ if (instrType == targetType)
return true; /* quick positive; most common case */
- /* might be able to eliminate one of these by narrowly defining our args? */
- if (type1 < kRegType1nrSTART || type1 > kRegType1nrEND)
- return false;
- if (type2 < kRegType1nrSTART || type2 > kRegType1nrEND)
- return false;
+ if ((instrType == kRegTypeInteger && targetType == kRegTypeFloat) ||
+ (instrType == kRegTypeFloat && targetType == kRegTypeInteger))
+ {
+ return true;
+ }
- return sizeTab[type1-kRegType1nrSTART] == sizeTab[type2-kRegType1nrSTART];
+ return false;
}
/*
@@ -1476,9 +1472,17 @@
}
insnRegs[vdst] = newType;
- /* if it's an initialized ref, make sure it's not a prim class */
- assert(regTypeIsUninitReference(newType) ||
- !dvmIsPrimitiveClass(regTypeInitializedReferenceToClass(newType)));
+ /*
+ * In most circumstances we won't see a reference to a primitive
+ * class here (e.g. "D"), since that would mean the object in the
+ * register is actually a primitive type. It can happen as the
+ * result of an assumed-successful check-cast instruction in
+ * which the second argument refers to a primitive class. (In
+ * practice, such an instruction will always throw an exception.)
+ *
+ * This is not an issue for instructions like const-class, where
+ * the object in the register is a java.lang.Class instance.
+ */
break;
}
/* bad - fall through */
@@ -2443,20 +2447,22 @@
return;
}
+ /*
+ * The EMMA code coverage tool generates a static method that
+ * modifies a private static final field. The method is only
+ * called by <clinit>, so the code is reasonable if not quite
+ * kosher. (Attempting to *compile* code that does something
+ * like that will earn you a quick thumbs-down from javac.)
+ *
+ * The verifier in another popular VM doesn't complain about this,
+ * so we're going to allow classes to modify their own static
+ * final fields outside of class initializers. Further testing
+ * showed that modifications to instance fields are also allowed.
+ */
+#if 0
/* make sure we're in the right kind of constructor */
if (dvmIsStaticField(field)) {
- /*
- * The EMMA code coverage tool generates a static method that
- * modifies a private static final field. The method is only
- * called by <clinit>, so the code is reasonable if not quite
- * kosher. (Attempting to *compile* code that does something
- * like that will earn you a quick thumbs-down from javac.)
- *
- * The verifier in another popular VM doesn't complain about this,
- * so we're going to allow classes to modify their own static
- * final fields outside of class initializers.
- */
- if (false && !isClassInitMethod(meth)) {
+ if (!isClassInitMethod(meth)) {
LOG_VFY_METH(meth,
"VFY: can't modify final static field outside <clinit>\n");
*pOkay = false;
@@ -2468,6 +2474,7 @@
*pOkay = false;
}
}
+#endif
}
/*
@@ -2627,71 +2634,91 @@
* information to kRegTypeUnknown.
*/
static bool initRegisterTable(const Method* meth, const InsnFlags* insnFlags,
- RegisterTable* regTable)
+ RegisterTable* regTable, RegisterTrackingMode trackRegsFor)
{
const int insnsSize = dvmGetMethodInsnsSize(meth);
int i;
- regTable->insnRegCount = meth->registersSize + kExtraRegs;
+ regTable->insnRegCountPlus = meth->registersSize + kExtraRegs;
regTable->addrRegs = (RegType**) calloc(insnsSize, sizeof(RegType*));
if (regTable->addrRegs == NULL)
return false;
+ assert(insnsSize > 0);
+
/*
- * "Full" means "every address that holds the start of an instruction".
- * "Not full" means "every address that can be branched to".
+ * "All" means "every address that holds the start of an instruction".
+ * "Branches" and "GcPoints" mean just those addresses.
*
- * "Full" seems to require > 6x the memory on average. Fortunately we
- * don't need to hold on to it for very long.
+ * "GcPoints" fills about half the addresses, "Branches" about 15%.
*/
- if (USE_FULL_TABLE) {
- int insnCount = 0;
+ int interestingCount = 0;
+ //int insnCount = 0;
- for (i = 0; i < insnsSize; i++) {
- if (dvmInsnIsOpcode(insnFlags, i))
- insnCount++;
- }
+ for (i = 0; i < insnsSize; i++) {
+ bool interesting;
- regTable->regAlloc = (RegType*)
- calloc(regTable->insnRegCount * insnCount, sizeof(RegType));
- if (regTable->regAlloc == NULL)
+ switch (trackRegsFor) {
+ case kTrackRegsAll:
+ interesting = dvmInsnIsOpcode(insnFlags, i);
+ break;
+ case kTrackRegsGcPoints:
+ interesting = dvmInsnIsGcPoint(insnFlags, i) ||
+ dvmInsnIsBranchTarget(insnFlags, i);
+ break;
+ case kTrackRegsBranches:
+ interesting = dvmInsnIsBranchTarget(insnFlags, i);
+ break;
+ default:
+ dvmAbort();
return false;
-
- RegType* regPtr = regTable->regAlloc;
- for (i = 0; i < insnsSize; i++) {
- if (dvmInsnIsOpcode(insnFlags, i)) {
- regTable->addrRegs[i] = regPtr;
- regPtr += regTable->insnRegCount;
- }
- }
- assert(regPtr - regTable->regAlloc ==
- regTable->insnRegCount * insnCount);
- } else {
- int branchCount = 0;
-
- for (i = 0; i < insnsSize; i++) {
- if (dvmInsnIsBranchTarget(insnFlags, i))
- branchCount++;
- }
- assert(branchCount > 0);
-
- regTable->regAlloc = (RegType*)
- calloc(regTable->insnRegCount * branchCount, sizeof(RegType));
- if (regTable->regAlloc == NULL)
- return false;
-
- RegType* regPtr = regTable->regAlloc;
- for (i = 0; i < insnsSize; i++) {
- if (dvmInsnIsBranchTarget(insnFlags, i)) {
- regTable->addrRegs[i] = regPtr;
- regPtr += regTable->insnRegCount;
- }
}
- assert(regPtr - regTable->regAlloc ==
- regTable->insnRegCount * branchCount);
+ if (interesting)
+ interestingCount++;
+
+ /* count instructions, for display only */
+ //if (dvmInsnIsOpcode(insnFlags, i))
+ // insnCount++;
}
+ regTable->regAlloc = (RegType*)
+ calloc(regTable->insnRegCountPlus * interestingCount, sizeof(RegType));
+ if (regTable->regAlloc == NULL)
+ return false;
+
+ RegType* regPtr = regTable->regAlloc;
+ for (i = 0; i < insnsSize; i++) {
+ bool interesting;
+
+ switch (trackRegsFor) {
+ case kTrackRegsAll:
+ interesting = dvmInsnIsOpcode(insnFlags, i);
+ break;
+ case kTrackRegsGcPoints:
+ interesting = dvmInsnIsGcPoint(insnFlags, i) ||
+ dvmInsnIsBranchTarget(insnFlags, i);
+ break;
+ case kTrackRegsBranches:
+ interesting = dvmInsnIsBranchTarget(insnFlags, i);
+ break;
+ default:
+ dvmAbort();
+ return false;
+ }
+
+ if (interesting) {
+ regTable->addrRegs[i] = regPtr;
+ regPtr += regTable->insnRegCountPlus;
+ }
+ }
+
+ //LOGD("Tracking registers for %d, total %d of %d(%d) (%d%%)\n",
+ // TRACK_REGS_FOR, interestingCount, insnCount, insnsSize,
+ // (interestingCount*100) / insnCount);
+
+ assert(regPtr - regTable->regAlloc ==
+ regTable->insnRegCountPlus * interestingCount);
assert(regTable->addrRegs[0] != NULL);
return true;
}
@@ -2715,12 +2742,10 @@
assert(dvmIsArrayClass(resClass));
elemType = resClass->elementClass->primitiveType;
if (elemType == PRIM_NOT) {
- LOG_VFY("VFY: filled-new-array not yet supported on reference types\n");
- *pOkay = false;
- return;
+ expectedType = regTypeFromClass(resClass->elementClass);
+ } else {
+ expectedType = primitiveTypeToRegType(elemType);
}
-
- expectedType = primitiveTypeToRegType(elemType);
//LOGI("filled-new-array: %s -> %d\n", resClass->descriptor, expectedType);
/*
@@ -2760,6 +2785,7 @@
bool result = false;
const int insnsSize = dvmGetMethodInsnsSize(meth);
const u2* insns = meth->insns;
+ const bool generateRegisterMap = gDvm.generateRegisterMaps;
int i, offset;
bool isConditional;
RegisterTable regTable;
@@ -2767,7 +2793,7 @@
memset(®Table, 0, sizeof(regTable));
#ifndef NDEBUG
- checkMergeTab(); // only need to do this when table changes
+ checkMergeTab(); // only need to do this if table gets updated
#endif
/*
@@ -2796,9 +2822,12 @@
}
/*
- * Create register lists, and initialize them to "Unknown".
+ * Create register lists, and initialize them to "Unknown". If we're
+ * also going to create the register map, we need to retain the
+ * register lists for a larger set of addresses.
*/
- if (!initRegisterTable(meth, insnFlags, ®Table))
+ if (!initRegisterTable(meth, insnFlags, ®Table,
+ generateRegisterMap ? kTrackRegsGcPoints : kTrackRegsBranches))
goto bail;
/*
@@ -2815,6 +2844,30 @@
goto bail;
/*
+ * Generate a register map.
+ */
+ if (generateRegisterMap) {
+ RegisterMap* pMap;
+ VerifierData vd;
+
+ vd.method = meth;
+ vd.insnsSize = insnsSize;
+ vd.insnRegCount = meth->registersSize;
+ vd.insnFlags = insnFlags;
+ vd.addrRegs = regTable.addrRegs;
+
+ pMap = dvmGenerateRegisterMapV(&vd);
+ if (pMap != NULL) {
+ /*
+ * Tuck it into the Method struct. It will either get used
+ * directly or, if we're in dexopt, will be packed up and
+ * appended to the DEX file.
+ */
+ dvmSetRegisterMap((Method*)meth, pMap);
+ }
+ }
+
+ /*
* Success.
*/
result = true;
@@ -3776,7 +3829,7 @@
srcType = primitiveTypeToRegType(
resClass->elementClass->primitiveType);
- if (!isTypeWidthEqual1nr(tmpType, srcType)) {
+ if (!checkFieldArrayStore1nr(tmpType, srcType)) {
LOG_VFY("VFY: invalid aget-1nr, array type=%d with"
" inst type=%d (on %s)\n",
srcType, tmpType, resClass->descriptor);
@@ -3961,7 +4014,7 @@
resClass->elementClass->primitiveType);
assert(dstType != kRegTypeUnknown);
- if (!isTypeWidthEqual1nr(tmpType, dstType)) {
+ if (!checkFieldArrayStore1nr(tmpType, dstType)) {
LOG_VFY("VFY: invalid aput-1nr on %s (inst=%d dst=%d)\n",
resClass->descriptor, tmpType, dstType);
okay = false;
@@ -4108,7 +4161,7 @@
/* make sure the field's type is compatible with expectation */
fieldType = primSigCharToRegType(instField->field.signature[0]);
if (fieldType == kRegTypeUnknown ||
- !isTypeWidthEqual1nr(tmpType, fieldType))
+ !checkFieldArrayStore1nr(tmpType, fieldType))
{
LOG_VFY("VFY: invalid iget-1nr of %s.%s (inst=%d field=%d)\n",
instField->field.clazz->descriptor,
@@ -4232,7 +4285,7 @@
/* get type of field we're storing into */
fieldType = primSigCharToRegType(instField->field.signature[0]);
if (fieldType == kRegTypeUnknown ||
- !isTypeWidthEqual1nr(tmpType, fieldType))
+ !checkFieldArrayStore1nr(tmpType, fieldType))
{
LOG_VFY("VFY: invalid iput-1nr of %s.%s (inst=%d field=%d)\n",
instField->field.clazz->descriptor,
@@ -4376,7 +4429,7 @@
* because e.g. "int" and "float" are interchangeable.)
*/
fieldType = primSigCharToRegType(staticField->field.signature[0]);
- if (!isTypeWidthEqual1nr(tmpType, fieldType)) {
+ if (!checkFieldArrayStore1nr(tmpType, fieldType)) {
LOG_VFY("VFY: invalid sget-1nr of %s.%s (inst=%d actual=%d)\n",
staticField->field.clazz->descriptor,
staticField->field.name, tmpType, fieldType);
@@ -4486,7 +4539,7 @@
* can lead to trouble if we do 16-bit writes.
*/
fieldType = primSigCharToRegType(staticField->field.signature[0]);
- if (!isTypeWidthEqual1nr(tmpType, fieldType)) {
+ if (!checkFieldArrayStore1nr(tmpType, fieldType)) {
LOG_VFY("VFY: invalid sput-1nr of %s.%s (inst=%d actual=%d)\n",
staticField->field.clazz->descriptor,
staticField->field.name, tmpType, fieldType);
diff --git a/vm/analysis/CodeVerify.h b/vm/analysis/CodeVerify.h
index 487acfb..0cd4638 100644
--- a/vm/analysis/CodeVerify.h
+++ b/vm/analysis/CodeVerify.h
@@ -98,6 +98,15 @@
#define kRegTypeUninitMask 0xff
#define kRegTypeUninitShift 8
+/*
+ * RegType holds information about the type of data held in a register.
+ * For most types it's a simple enum. For reference types it holds a
+ * pointer to the ClassObject, and for uninitialized references it holds
+ * an index into the UninitInstanceMap.
+ */
+typedef u4 RegType;
+
+/* table with merge logic for primitive types */
extern const char gDvmMergeTab[kRegTypeMAX][kRegTypeMAX];
diff --git a/vm/analysis/DexOptimize.c b/vm/analysis/DexOptimize.c
index 89f3aa1..d086b99 100644
--- a/vm/analysis/DexOptimize.c
+++ b/vm/analysis/DexOptimize.c
@@ -321,6 +321,9 @@
* want to avoid this.
*
* For optimization and/or verification, we need to load all the classes.
+ *
+ * We don't check gDvm.generateRegisterMaps, since that is dependent
+ * upon the verifier state.
*/
if (gDvm.classVerifyMode == VERIFY_MODE_NONE &&
(gDvm.dexOptMode == OPTIMIZE_MODE_NONE ||
@@ -423,6 +426,8 @@
}
if (isBootstrap)
flags |= DEXOPT_IS_BOOTSTRAP;
+ if (gDvm.generateRegisterMaps)
+ flags |= DEXOPT_GEN_REGISTER_MAP;
sprintf(values[9], "%d", flags);
argv[curArg++] = values[9];
@@ -794,7 +799,8 @@
magic = optHdr.magic;
if (memcmp(magic, DEX_OPT_MAGIC, 4) != 0) {
- LOGW("DexOpt: incorrect opt magic number (0x%02x %02x %02x %02x)\n",
+ /* not a DEX file, or previous attempt was interrupted */
+ LOGD("DexOpt: incorrect opt magic number (0x%02x %02x %02x %02x)\n",
magic[0], magic[1], magic[2], magic[3]);
goto bail;
}
@@ -1627,9 +1633,13 @@
*/
resClass = dvmDexGetResolvedClass(pDvmDex, classIdx);
if (resClass == NULL) {
- resClass = dvmFindClassNoInit(
- dexStringByTypeIdx(pDvmDex->pDexFile, classIdx),
- referrer->classLoader);
+ const char* className = dexStringByTypeIdx(pDvmDex->pDexFile, classIdx);
+ if (className[0] != '\0' && className[1] == '\0') {
+ /* primitive type */
+ resClass = dvmFindPrimitiveClass(className[0]);
+ } else {
+ resClass = dvmFindClassNoInit(className, referrer->classLoader);
+ }
if (resClass == NULL) {
/* not found, exception should be raised */
LOGV("DexOpt: class %d (%s) not found\n",
diff --git a/vm/analysis/DexOptimize.h b/vm/analysis/DexOptimize.h
index ecb71d3..01aa828 100644
--- a/vm/analysis/DexOptimize.h
+++ b/vm/analysis/DexOptimize.h
@@ -30,6 +30,11 @@
OPTIMIZE_MODE_ALL /* optimize all classes */
} DexOptimizerMode;
+/* some additional bit flags for dexopt */
+enum DexoptFlags {
+ DEXOPT_GEN_REGISTER_MAPS = 1, /* generate register maps during verify */
+};
+
/*
* Given the full path to a DEX or Jar file, and (if appropriate) the name
* within the Jar, open the optimized version from the cache.
diff --git a/vm/analysis/DexVerify.c b/vm/analysis/DexVerify.c
index cf4bf22..0faafe6 100644
--- a/vm/analysis/DexVerify.c
+++ b/vm/analysis/DexVerify.c
@@ -527,15 +527,23 @@
{
const int insnCount = dvmGetMethodInsnsSize(meth);
const u2* insns = meth->insns;
- int i, width, offset, absOffset;
+ int i;
/* the start of the method is a "branch target" */
dvmInsnSetBranchTarget(insnFlags, 0, true);
for (i = 0; i < insnCount; /**/) {
- width = dvmInsnGetWidth(insnFlags, i);
+ static int gcMask = kInstrCanBranch | kInstrCanSwitch |
+ kInstrCanThrow | kInstrCanReturn;
+ int width = dvmInsnGetWidth(insnFlags, i);
+ OpCode opcode = *insns & 0xff;
+ InstructionFlags opFlags = dexGetInstrFlags(gDvm.instrFlags, opcode);
+ int offset, absOffset;
- switch (*insns & 0xff) {
+ if ((opFlags & gcMask) != 0)
+ dvmInsnSetGcPoint(insnFlags, i, true);
+
+ switch (opcode) {
case OP_NOP:
/* plain no-op or switch table data; nothing to do here */
break;
diff --git a/vm/analysis/DexVerify.h b/vm/analysis/DexVerify.h
index 4b0d693..9deaad9 100644
--- a/vm/analysis/DexVerify.h
+++ b/vm/analysis/DexVerify.h
@@ -57,4 +57,9 @@
*/
bool dvmVerifyClass(ClassObject* clazz, int verifyFlags);
+/*
+ * Release the storage associated with a RegisterMap.
+ */
+void dvmFreeRegisterMap(RegisterMap* pMap);
+
#endif /*_DALVIK_DEXVERIFY*/
diff --git a/vm/analysis/RegisterMap.c b/vm/analysis/RegisterMap.c
index eb243af..b02874a 100644
--- a/vm/analysis/RegisterMap.c
+++ b/vm/analysis/RegisterMap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,20 +28,41 @@
#include "libdex/DexCatch.h"
#include "libdex/InstrUtils.h"
+#include <stddef.h>
+
/*
-Notes on RegisterMap vs. verification
+Notes on just-in-time RegisterMap generation
-Much of this is redundant with the bytecode verifier. Unfortunately we
-can't do this at verification time unless we're willing to store the
-results in the optimized DEX file, which increases their size by about 25%
-unless we use compression, and for performance reasons we don't want to
-just re-run the verifier.
+Generating RegisterMap tables as part of verification is convenient because
+we generate most of what we need to know as part of doing the verify.
+The negative aspect of doing it this way is that we must store the
+result in the DEX file (if we're verifying ahead of time) or in memory
+(if verifying during class load) for every concrete non-native method,
+even if we never actually need the map during a GC.
-On the plus side, we know that verification has completed successfully --
-or at least are allowed to assume that it would -- so we skip a lot of
-the checks (like verifying that the register indices in instructions
-are reasonable).
+A simple but compact encoding of register map data increases the size of
+optimized DEX files by about 25%, so size considerations are important.
+
+We can instead generate the RegisterMap at the point where it is needed.
+In a typical application we only need to convert about 2% of the loaded
+methods, and we can generate type-precise roots reasonably quickly because
+(a) we know the method has already been verified and hence can make a
+lot of assumptions, and (b) we don't care what type of object a register
+holds, just whether or not it holds a reference, and hence can skip a
+lot of class resolution gymnastics.
+
+There are a couple of problems with this approach however. First, to
+get good performance we really want an implementation that is largely
+independent from the verifier, which means some duplication of effort.
+Second, we're dealing with post-dexopt code, which contains "quickened"
+instructions. We can't process those without either tracking type
+information (which slows us down) or storing additional data in the DEX
+file that allows us to reconstruct the original instructions (adds ~5%
+to the size of the ODEX).
+
+
+Implementation notes...
Both type-precise and live-precise information can be generated knowing
only whether or not a register holds a reference. We don't need to
@@ -50,15 +71,250 @@
initialize from simpler sources, e.g. the initial registers and return
type are set from the "shorty" signature rather than the full signature.
-The short-term storage needs are different; for example, the verifier
-stores 4-byte RegType values for every address that can be a branch
-target, while we store 1-byte SRegType values for every address that
-can be a GC point. There are many more GC points than branch targets.
-We could use a common data type here, but for larger methods it can mean
-the difference between 300KB and 1.2MB.
+The short-term storage needs for just-in-time register map generation can
+be much lower because we can use a 1-byte SRegType instead of a 4-byte
+RegType. On the other hand, if we're not doing type-precise analysis
+in the verifier we only need to store register contents at every branch
+target, rather than every GC point (which are much more frequent).
+Whether it happens in the verifier or independently, because this is done
+with native heap allocations that may be difficult to return to the system,
+an effort should be made to minimize memory use.
*/
+// fwd
+static void outputTypeVector(const RegType* regs, int insnRegCount, u1* data);
+static bool verifyMap(VerifierData* vdata, const RegisterMap* pMap);
+
+/*
+ * Generate the register map for a method that has just been verified
+ * (i.e. we're doing this as part of verification).
+ *
+ * For type-precise determination we have all the data we need, so we
+ * just need to encode it in some clever fashion.
+ *
+ * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure.
+ */
+RegisterMap* dvmGenerateRegisterMapV(VerifierData* vdata)
+{
+ RegisterMap* pMap = NULL;
+ RegisterMap* pResult = NULL;
+ RegisterMapFormat format;
+ u1 regWidth;
+ u1* mapData;
+ int i, bytesForAddr, gcPointCount;
+ int bufSize;
+
+ regWidth = (vdata->method->registersSize + 7) / 8;
+ if (vdata->insnsSize < 256) {
+ format = kFormatCompact8;
+ bytesForAddr = 1;
+ } else {
+ format = kFormatCompact16;
+ bytesForAddr = 2;
+ }
+
+ /*
+ * Count up the number of GC point instructions.
+ *
+ * NOTE: this does not automatically include the first instruction,
+ * since we don't count method entry as a GC point.
+ */
+ gcPointCount = 0;
+ for (i = 0; i < vdata->insnsSize; i++) {
+ if (dvmInsnIsGcPoint(vdata->insnFlags, i))
+ gcPointCount++;
+ }
+ if (gcPointCount >= 65536) {
+ /* we could handle this, but in practice we don't get near this */
+ LOGE("ERROR: register map can't handle %d gc points in one method\n",
+ gcPointCount);
+ goto bail;
+ }
+
+ /*
+ * Allocate a buffer to hold the map data.
+ */
+ bufSize = offsetof(RegisterMap, data);
+ bufSize += gcPointCount * (bytesForAddr + regWidth);
+
+ LOGD("+++ grm: %s.%s (adr=%d gpc=%d rwd=%d bsz=%d)\n",
+ vdata->method->clazz->descriptor, vdata->method->name,
+ bytesForAddr, gcPointCount, regWidth, bufSize);
+
+ pMap = (RegisterMap*) malloc(bufSize);
+ pMap->format = format;
+ pMap->regWidth = regWidth;
+ pMap->numEntries = gcPointCount;
+
+ /*
+ * Populate it.
+ */
+ mapData = pMap->data;
+ for (i = 0; i < vdata->insnsSize; i++) {
+ if (dvmInsnIsGcPoint(vdata->insnFlags, i)) {
+ assert(vdata->addrRegs[i] != NULL);
+ if (format == kFormatCompact8) {
+ *mapData++ = i;
+ } else /*kFormatCompact16*/ {
+ *mapData++ = i & 0xff;
+ *mapData++ = i >> 8;
+ }
+ outputTypeVector(vdata->addrRegs[i], vdata->insnRegCount, mapData);
+ mapData += regWidth;
+ }
+ }
+
+ LOGI("mapData=%p pMap=%p bufSize=%d\n", mapData, pMap, bufSize);
+ assert(mapData - (const u1*) pMap == bufSize);
+
+#if 1
+ if (!verifyMap(vdata, pMap))
+ goto bail;
+#endif
+
+ pResult = pMap;
+
+bail:
+ return pResult;
+}
+
+/*
+ * Release the storage held by a RegisterMap.
+ */
+void dvmFreeRegisterMap(RegisterMap* pMap)
+{
+ if (pMap == NULL)
+ return;
+
+ free(pMap);
+}
+
+/*
+ * Determine if the RegType value is a reference type.
+ *
+ * Ordinarily we include kRegTypeZero in the "is it a reference"
+ * check. There's no value in doing so here, because we know
+ * the register can't hold anything but zero.
+ */
+static inline bool isReferenceType(RegType type)
+{
+ return (type > kRegTypeMAX || type == kRegTypeUninit);
+}
+
+/*
+ * Given a line of registers, output a bit vector that indicates whether
+ * or not the register holds a reference type (which could be null).
+ *
+ * We use '1' to indicate it's a reference, '0' for anything else (numeric
+ * value, uninitialized data, merge conflict). Register 0 will be found
+ * in the low bit of the first byte.
+ */
+static void outputTypeVector(const RegType* regs, int insnRegCount, u1* data)
+{
+ u1 val = 0;
+ int i;
+
+ for (i = 0; i < insnRegCount; i++) {
+ RegType type = *regs++;
+ val >>= 1;
+ if (isReferenceType(type))
+ val |= 0x80; /* set hi bit */
+
+ if ((i & 0x07) == 7)
+ *data++ = val;
+ }
+ if ((i & 0x07) != 0) {
+ /* flush bits from last byte */
+ val >>= 8 - (i & 0x07);
+ *data++ = val;
+ }
+}
+
+/*
+ * Double-check the map.
+ *
+ * We run through all of the data in the map, and compare it to the original.
+ */
+static bool verifyMap(VerifierData* vdata, const RegisterMap* pMap)
+{
+ const u1* data = pMap->data;
+ int ent;
+
+ for (ent = 0; ent < pMap->numEntries; ent++) {
+ int addr;
+
+ switch (pMap->format) {
+ case kFormatCompact8:
+ addr = *data++;
+ break;
+ case kFormatCompact16:
+ addr = *data++;
+ addr |= (*data++) << 8;
+ break;
+ default:
+ /* shouldn't happen */
+ LOGE("GLITCH: bad format (%d)", pMap->format);
+ dvmAbort();
+ }
+
+ const RegType* regs = vdata->addrRegs[addr];
+ if (regs == NULL) {
+ LOGE("GLITCH: addr %d has no data\n", addr);
+ return false;
+ }
+
+ u1 val;
+ int i;
+
+ for (i = 0; i < vdata->method->registersSize; i++) {
+ bool bitIsRef, regIsRef;
+
+ val >>= 1;
+ if ((i & 0x07) == 0) {
+ /* load next byte of data */
+ val = *data++;
+ }
+
+ bitIsRef = val & 0x01;
+
+ RegType type = regs[i];
+ regIsRef = isReferenceType(type);
+
+ if (bitIsRef != regIsRef) {
+ LOGE("GLITCH: addr %d reg %d: bit=%d reg=%d(%d)\n",
+ addr, i, bitIsRef, regIsRef, type);
+ return false;
+ }
+ }
+
+ /* print the map as a binary string */
+ if (false) {
+ char outBuf[vdata->method->registersSize +1];
+ for (i = 0; i < vdata->method->registersSize; i++) {
+ if (isReferenceType(regs[i])) {
+ outBuf[i] = '1';
+ } else {
+ outBuf[i] = '0';
+ }
+ }
+ outBuf[i] = '\0';
+ LOGD(" %04d %s\n", addr, outBuf);
+ }
+ }
+
+ return true;
+}
+
+
+/*
+ * ===========================================================================
+ * Just-in-time generation
+ * ===========================================================================
+ */
+
+#if 0 /* incomplete implementation; may be removed entirely in the future */
+
/*
* This is like RegType in the verifier, but simplified. It holds a value
* from the reg type enum, or kRegTypeReference.
@@ -1152,12 +1408,13 @@
/*
* See comments in analysis/CodeVerify.c re: why some of these are
- * annoying to deal with. In here, "annoying" turns into "impossible",
- * since we make no effort to keep reference type info.
+ * annoying to deal with. It's worse in this implementation, because
+ * we're not keeping any information about the classes held in each
+ * reference register.
*
* Handling most of these would require retaining the field/method
* reference info that we discarded when the instructions were
- * quickened.
+ * quickened. This is feasible but not currently supported.
*/
case OP_EXECUTE_INLINE:
case OP_INVOKE_DIRECT_EMPTY:
@@ -1171,7 +1428,7 @@
case OP_INVOKE_VIRTUAL_QUICK_RANGE:
case OP_INVOKE_SUPER_QUICK:
case OP_INVOKE_SUPER_QUICK_RANGE:
- dvmAbort(); // can't work
+ dvmAbort(); // not implemented, shouldn't be here
break;
@@ -1431,3 +1688,5 @@
}
}
+#endif /*#if 0*/
+
diff --git a/vm/analysis/RegisterMap.h b/vm/analysis/RegisterMap.h
index 07071d2..2a890e7 100644
--- a/vm/analysis/RegisterMap.h
+++ b/vm/analysis/RegisterMap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+// ** UNDER CONSTRUCTION **
+
/*
* Declaration of register map data structure and related functions.
*/
@@ -21,30 +23,78 @@
#define _DALVIK_REGISTERMAP
/*
+ * Format enumeration for RegisterMap data area.
+ */
+typedef enum RegisterMapFormat {
+ kFormatUnknown = 0,
+ kFormatCompact8, /* compact layout, 8-bit addresses */
+ kFormatCompact16, /* compact layout, 16-bit addresses */
+ // TODO: compressed stream
+} RegisterMapFormat;
+
+/*
* This is a single variable-size structure. It may be allocated on the
- * heap or mapped out of a DEX file.
+ * heap or mapped out of a (post-dexopt) DEX file.
*/
-typedef struct RegisterMap {
+struct RegisterMap {
/* header */
- char addrWidth; /* bytes per address, 1 or 2 */
- char regWidth; /* bytes per register line, 1+ */
+ u1 format; /* enum RegisterMapFormat */
+ u1 regWidth; /* bytes per register line, 1+ */
+ u2 numEntries; /* number of entries */
- /* char pad0, pad1; */
-
- /* entries start here; 32-bit align guaranteed */
- u4 entries[1];
-} RegisterMap;
+ /* data starts here; no alignment guarantees made */
+ u1 data[1];
+};
/*
- * Generate the register map for a method.
+ * Generate the register map for a previously-verified method.
*
- * Returns a pointer to newly-allocated storage.
+ * Returns a pointer to a newly-allocated RegisterMap.
*/
-RegisterMap* dvmGenerateRegisterMap(const Method* meth);
+//RegisterMap* dvmGenerateRegisterMap(const Method* meth);
/*
- * Release the storage associated with a RegisterMap.
+ * Various bits of data generated by the verifier, wrapped up in a package
+ * for ease of use by the register map generator.
*/
-void dvmFreeRegisterMap(RegisterMap* pMap);
+typedef struct VerifierData {
+ /*
+ * The method we're working on.
+ */
+ const Method* method;
+
+ /*
+ * Number of instructions in the method.
+ */
+ int insnsSize;
+
+ /*
+ * Number of registers we track for each instruction. This is equal
+ * to the method's declared "registersSize". (Does not include the
+ * pending return value.)
+ */
+ int insnRegCount;
+
+ /*
+ * Instruction widths and flags, one entry per code unit.
+ */
+ InsnFlags* insnFlags;
+
+ /*
+ * Array of SRegType arrays, one entry per code unit. We only need
+ * entries for code units that hold the start of an "interesting"
+ * instruction. For register map generation, we're only interested
+ * in GC points.
+ */
+ RegType** addrRegs;
+} VerifierData;
+
+/*
+ * Generate the register map for a method that has just been verified
+ * (i.e. we're doing this as part of verification).
+ *
+ * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure.
+ */
+RegisterMap* dvmGenerateRegisterMapV(VerifierData* vdata);
#endif /*_DALVIK_REGISTERMAP*/
diff --git a/vm/hprof/Hprof.c b/vm/hprof/Hprof.c
index e195aee..66b46f4 100644
--- a/vm/hprof/Hprof.c
+++ b/vm/hprof/Hprof.c
@@ -13,44 +13,56 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+/*
+ * Preparation and completion of hprof data generation. The output is
+ * written into two files and then combined. This is necessary because
+ * we generate some of the data (strings and classes) while we dump the
+ * heap, and some analysis tools require that the class and string data
+ * appear first.
+ */
#include "Hprof.h"
+
+#include <string.h>
+#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>
-#define TWO_FILES 1
+
+#define kHeadSuffix "-hptemp"
hprof_context_t *
-hprofStartup(const char *outputDir)
+hprofStartup(const char *outputFileName)
{
hprof_context_t *ctx;
ctx = malloc(sizeof(*ctx));
if (ctx != NULL) {
+ int len = strlen(outputFileName);
+ char fileName[len + sizeof(kHeadSuffix)];
FILE *fp;
- struct timeval tv;
- /* Construct the output file name.
+ /* Construct the temp file name. This wasn't handed to us by the
+ * application, so we need to be careful about stomping on it.
*/
- int len = strlen(outputDir);
- len += 64; // hprofShutdown assumes that there's some slack
- gettimeofday(&tv, NULL);
- char *fileName = malloc(len);
- if (fileName == NULL) {
- LOGE("hprof: can't malloc %d bytes.\n", len);
+ sprintf(fileName, "%s" kHeadSuffix, outputFileName);
+ if (access(fileName, F_OK) == 0) {
+ LOGE("hprof: temp file %s exists, bailing\n", fileName);
free(ctx);
return NULL;
}
- snprintf(fileName, len, "%s/heap-dump-tm%d-pid%d.hprof",
- outputDir, (int)tv.tv_sec, getpid());
- fileName[len-1] = '\0';
- fp = fopen(fileName, "w");
+ fp = fopen(fileName, "w+");
if (fp == NULL) {
LOGE("hprof: can't open %s: %s.\n", fileName, strerror(errno));
free(ctx);
return NULL;
}
+ if (unlink(fileName) != 0) {
+ LOGW("hprof: WARNING: unable to remove temp file %s\n", fileName);
+ /* keep going */
+ }
LOGI("hprof: dumping VM heap to \"%s\".\n", fileName);
hprofStartup_String();
@@ -59,11 +71,9 @@
hprofStartup_StackFrame();
hprofStartup_Stack();
#endif
-#if TWO_FILES
- hprofContextInit(ctx, fileName, fp, false);
-#else
- hprofContextInit(ctx, fileName, fp, true);
-#endif
+
+ /* pass in "fp" for the temp file, and the name of the output file */
+ hprofContextInit(ctx, strdup(outputFileName), fp, false);
} else {
LOGE("hprof: can't allocate context.\n");
}
@@ -71,31 +81,59 @@
return ctx;
}
+/*
+ * Copy the entire contents of "srcFp" to "dstFp".
+ *
+ * Returns "true" on success.
+ */
+static bool
+copyFileToFile(FILE *dstFp, FILE *srcFp)
+{
+ char buf[65536];
+ size_t dataRead, dataWritten;
+
+ while (true) {
+ dataRead = fread(buf, 1, sizeof(buf), srcFp);
+ if (dataRead > 0) {
+ dataWritten = fwrite(buf, 1, dataRead, dstFp);
+ if (dataWritten != dataRead) {
+ LOGE("hprof: failed writing data (%d of %d): %s\n",
+ dataWritten, dataRead, strerror(errno));
+ return false;
+ }
+ } else {
+ if (feof(srcFp))
+ return true;
+ LOGE("hprof: failed reading data (res=%d): %s\n",
+ dataRead, strerror(errno));
+ return false;
+ }
+ }
+}
+
void
hprofShutdown(hprof_context_t *ctx)
{
-#if TWO_FILES
+ FILE *tempFp = ctx->fp;
FILE *fp;
- /* hprofStartup allocated some slack, so the strcat() should be ok.
- */
- char *fileName = strcat(ctx->fileName, "-head");
-
+ /* flush output to the temp file, then prepare the output file */
hprofFlushCurrentRecord(ctx);
- fclose(ctx->fp);
free(ctx->curRec.body);
+ ctx->curRec.body = NULL;
ctx->curRec.allocLen = 0;
+ ctx->fp = NULL;
- LOGI("hprof: dumping heap strings to \"%s\".\n", fileName);
- fp = fopen(fileName, "w");
+ LOGI("hprof: dumping heap strings to \"%s\".\n", ctx->fileName);
+ fp = fopen(ctx->fileName, "w");
if (fp == NULL) {
- LOGE("can't open %s: %s\n", fileName, strerror(errno));
+ LOGE("can't open %s: %s\n", ctx->fileName, strerror(errno));
+ fclose(tempFp);
free(ctx->fileName);
free(ctx);
return;
}
hprofContextInit(ctx, ctx->fileName, fp, true);
-#endif
hprofDumpStrings(ctx);
hprofDumpClasses(ctx);
@@ -122,7 +160,23 @@
hprofShutdown_StackFrame();
#endif
+ /*
+ * Append the contents of the temp file to the output file. The temp
+ * file was removed immediately after being opened, so it will vanish
+ * when we close it.
+ */
+ rewind(tempFp);
+ if (!copyFileToFile(ctx->fp, tempFp)) {
+ LOGW("hprof: file copy failed, hprof data may be incomplete\n");
+ /* finish up anyway */
+ }
+
+ fclose(tempFp);
fclose(ctx->fp);
free(ctx->fileName);
+ free(ctx->curRec.body);
free(ctx);
+
+ /* throw out a log message for the benefit of "runhat" */
+ LOGI("hprof: heap dump completed, temp file removed\n");
}
diff --git a/vm/hprof/Hprof.h b/vm/hprof/Hprof.h
index 6c120f3..e0e2d4b 100644
--- a/vm/hprof/Hprof.h
+++ b/vm/hprof/Hprof.h
@@ -178,7 +178,7 @@
*/
void hprofContextInit(hprof_context_t *ctx, char *fileName, FILE *fp,
- bool newFile);
+ bool writeHeader);
int hprofFlushRecord(hprof_record_t *rec, FILE *fp);
int hprofFlushCurrentRecord(hprof_context_t *ctx);
@@ -234,7 +234,7 @@
* Hprof.c functions
*/
-hprof_context_t *hprofStartup(const char *outputDir);
+hprof_context_t *hprofStartup(const char *outputFileName);
void hprofShutdown(hprof_context_t *ctx);
/*
@@ -244,7 +244,7 @@
* the heap implementation; these functions require heap knowledge,
* so they are implemented in Heap.c.
*/
-void hprofDumpHeap();
+void hprofDumpHeap(const char* fileName);
void dvmHeapSetHprofGcScanState(hprof_heap_tag_t state, u4 threadSerialNumber);
#endif // _DALVIK_HPROF_HPROF
diff --git a/vm/hprof/HprofOutput.c b/vm/hprof/HprofOutput.c
index 8571dac..c6d1cbc 100644
--- a/vm/hprof/HprofOutput.c
+++ b/vm/hprof/HprofOutput.c
@@ -55,7 +55,8 @@
} while (0)
void
-hprofContextInit(hprof_context_t *ctx, char *fileName, FILE *fp, bool newFile)
+hprofContextInit(hprof_context_t *ctx, char *fileName, FILE *fp,
+ bool writeHeader)
{
memset(ctx, 0, sizeof (*ctx));
ctx->fileName = fileName;
@@ -65,7 +66,7 @@
ctx->curRec.body = malloc(ctx->curRec.allocLen);
//xxx check for/return an error
- if (newFile) {
+ if (writeHeader) {
char magic[] = HPROF_MAGIC_STRING;
unsigned char buf[4];
struct timeval now;
diff --git a/vm/interp/Interp.c b/vm/interp/Interp.c
index 2eb2731..d2643de 100644
--- a/vm/interp/Interp.c
+++ b/vm/interp/Interp.c
@@ -548,7 +548,7 @@
width = arrayData[1];
size = arrayData[2] | (((u4)arrayData[3]) << 16);
- if (size != arrayObj->length) {
+ if (size > arrayObj->length) {
dvmThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", NULL);
return false;
}
diff --git a/vm/jdwp/JdwpHandler.c b/vm/jdwp/JdwpHandler.c
index e4b6f26..ff6ecf4 100644
--- a/vm/jdwp/JdwpHandler.c
+++ b/vm/jdwp/JdwpHandler.c
@@ -199,7 +199,7 @@
int dataLen, ExpandBuf* pReply)
{
/* text information on VM version */
- expandBufAddUtf8String(pReply, (const u1*) "Android DalvikVM 0.0.1");
+ expandBufAddUtf8String(pReply, (const u1*) "Android DalvikVM 1.0.1");
/* JDWP version numbers */
expandBufAdd4BE(pReply, 1); // major
expandBufAdd4BE(pReply, 5); // minor
diff --git a/vm/mterp/armv5te/OP_FILLED_NEW_ARRAY.S b/vm/mterp/armv5te/OP_FILLED_NEW_ARRAY.S
index 6cc450d..a9c2d3e 100644
--- a/vm/mterp/armv5te/OP_FILLED_NEW_ARRAY.S
+++ b/vm/mterp/armv5te/OP_FILLED_NEW_ARRAY.S
@@ -33,16 +33,18 @@
.L${opcode}_continue:
ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags
- ldrb r0, [r3, #1] @ r0<- descriptor[1]
+ ldrb r3, [r3, #1] @ r3<- descriptor[1]
.if $isrange
mov r1, r10 @ r1<- AA (length)
.else
mov r1, r10, lsr #4 @ r1<- B (length)
.endif
- cmp r0, #'I' @ array of ints?
+ cmp r3, #'I' @ array of ints?
+ cmpne r3, #'L' @ array of objects?
+ cmpne r3, #'[' @ array of arrays?
mov r9, r1 @ save length in r9
bne .L${opcode}_notimpl @ no, not handled yet
- bl dvmAllocPrimitiveArray @ r0<- call(typeCh, length, flags)
+ bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags)
cmp r0, #0 @ null return?
beq common_exceptionThrown @ alloc failed, handle exception
diff --git a/vm/mterp/armv5te/footer.S b/vm/mterp/armv5te/footer.S
index 70297b6..8f7cc41 100644
--- a/vm/mterp/armv5te/footer.S
+++ b/vm/mterp/armv5te/footer.S
@@ -379,22 +379,23 @@
/* call, r0 gets catchRelPc (a code-unit offset) */
bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp)
+
+ /* fix earlier stack overflow if necessary; may trash rFP */
+ ldrb r1, [r10, #offThread_stackOverflowed]
+ cmp r1, #0 @ did we overflow earlier?
+ beq 1f @ no, skip ahead
+ mov rFP, r0 @ save relPc result in rFP
+ mov r0, r10 @ r0<- self
+ bl dvmCleanupStackOverflow @ call(self)
+ mov r0, rFP @ restore result
+1:
+
+ /* update frame pointer and check result from dvmFindCatchBlock */
ldr rFP, [sp, #4] @ retrieve the updated rFP
cmp r0, #0 @ is catchRelPc < 0?
add sp, sp, #8 @ restore stack
bmi .LnotCaughtLocally
- /* fix stack overflow if necessary; must preserve r0 */
- ldrb r1, [r10, #offThread_stackOverflowed]
- cmp r1, #0 @ did we overflow earlier?
- beq 1f @ no, skip ahead
- mov r9, r0 @ r9<- r0 (save it)
- mov r0, r10 @ r0<- self
- bl dvmCleanupStackOverflow @ call(self)
- mov r0, r9 @ r0<- r9 (restore it)
- ldr r9, [r10, #offThread_exception] @ r9<- self->exception
-1:
-
/* adjust locals to match self->curFrame and updated PC */
SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area
ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method
@@ -694,7 +695,7 @@
.LstrDivideByZero:
.asciz "divide by zero"
.LstrFilledNewArrayNotImpl:
- .asciz "filled-new-array only implemented for 'int'"
+ .asciz "filled-new-array only implemented for objects and 'int'"
.LstrInternalError:
.asciz "Ljava/lang/InternalError;"
.LstrInstantiationError:
diff --git a/vm/mterp/c/gotoTargets.c b/vm/mterp/c/gotoTargets.c
index 1e14a9a..f52e3f0 100644
--- a/vm/mterp/c/gotoTargets.c
+++ b/vm/mterp/c/gotoTargets.c
@@ -12,7 +12,7 @@
{
ClassObject* arrayClass;
ArrayObject* newArray;
- int* contents;
+ u4* contents;
char typeCh;
int i;
u4 arg5;
@@ -64,31 +64,22 @@
dvmThrowException("Ljava/lang/RuntimeError;",
"bad filled array req");
GOTO_exceptionThrown();
- } else if (typeCh == 'L' || typeCh == '[') {
- /* create array of objects or array of arrays */
- /* TODO: need some work in the verifier before we allow this */
- LOGE("fnao not implemented\n");
- dvmThrowException("Ljava/lang/InternalError;",
- "filled-new-array not implemented for reference types");
- GOTO_exceptionThrown();
- } else if (typeCh != 'I') {
+ } else if (typeCh != 'L' && typeCh != '[' && typeCh != 'I') {
/* TODO: requires multiple "fill in" loops with different widths */
- LOGE("non-int not implemented\n");
+ LOGE("non-int primitives not implemented\n");
dvmThrowException("Ljava/lang/InternalError;",
"filled-new-array not implemented for anything but 'int'");
GOTO_exceptionThrown();
}
- assert(strchr("BCIFZ", typeCh) != NULL);
- newArray = dvmAllocPrimitiveArray(arrayClass->descriptor[1], vsrc1,
- ALLOC_DONT_TRACK);
+ newArray = dvmAllocArrayByClass(arrayClass, vsrc1, ALLOC_DONT_TRACK);
if (newArray == NULL)
GOTO_exceptionThrown();
/*
* Fill in the elements. It's legal for vsrc1 to be zero.
*/
- contents = (int*) newArray->contents;
+ contents = (u4*) newArray->contents;
if (methodCallRange) {
for (i = 0; i < vsrc1; i++)
contents[i] = GET_REGISTER(vdst+i);
@@ -645,6 +636,10 @@
* exception this won't happen until some other exception gets
* thrown. If the code keeps pushing the stack bounds we'll end
* up aborting the VM.
+ *
+ * Note we want to do this *after* the call to dvmFindCatchBlock,
+ * because that may need extra stack space to resolve exception
+ * classes (e.g. through a class loader).
*/
if (self->stackOverflowed)
dvmCleanupStackOverflow(self);
diff --git a/vm/mterp/out/InterpAsm-armv4.S b/vm/mterp/out/InterpAsm-armv4.S
index 253ff73..3de7aea 100644
--- a/vm/mterp/out/InterpAsm-armv4.S
+++ b/vm/mterp/out/InterpAsm-armv4.S
@@ -8056,16 +8056,18 @@
.LOP_FILLED_NEW_ARRAY_continue:
ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags
- ldrb r0, [r3, #1] @ r0<- descriptor[1]
+ ldrb r3, [r3, #1] @ r3<- descriptor[1]
.if 0
mov r1, r10 @ r1<- AA (length)
.else
mov r1, r10, lsr #4 @ r1<- B (length)
.endif
- cmp r0, #'I' @ array of ints?
+ cmp r3, #'I' @ array of ints?
+ cmpne r3, #'L' @ array of objects?
+ cmpne r3, #'[' @ array of arrays?
mov r9, r1 @ save length in r9
bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet
- bl dvmAllocPrimitiveArray @ r0<- call(typeCh, length, flags)
+ bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags)
cmp r0, #0 @ null return?
beq common_exceptionThrown @ alloc failed, handle exception
@@ -8133,16 +8135,18 @@
.LOP_FILLED_NEW_ARRAY_RANGE_continue:
ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags
- ldrb r0, [r3, #1] @ r0<- descriptor[1]
+ ldrb r3, [r3, #1] @ r3<- descriptor[1]
.if 1
mov r1, r10 @ r1<- AA (length)
.else
mov r1, r10, lsr #4 @ r1<- B (length)
.endif
- cmp r0, #'I' @ array of ints?
+ cmp r3, #'I' @ array of ints?
+ cmpne r3, #'L' @ array of objects?
+ cmpne r3, #'[' @ array of arrays?
mov r9, r1 @ save length in r9
bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet
- bl dvmAllocPrimitiveArray @ r0<- call(typeCh, length, flags)
+ bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags)
cmp r0, #0 @ null return?
beq common_exceptionThrown @ alloc failed, handle exception
@@ -9663,22 +9667,23 @@
/* call, r0 gets catchRelPc (a code-unit offset) */
bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp)
+
+ /* fix earlier stack overflow if necessary; may trash rFP */
+ ldrb r1, [r10, #offThread_stackOverflowed]
+ cmp r1, #0 @ did we overflow earlier?
+ beq 1f @ no, skip ahead
+ mov rFP, r0 @ save relPc result in rFP
+ mov r0, r10 @ r0<- self
+ bl dvmCleanupStackOverflow @ call(self)
+ mov r0, rFP @ restore result
+1:
+
+ /* update frame pointer and check result from dvmFindCatchBlock */
ldr rFP, [sp, #4] @ retrieve the updated rFP
cmp r0, #0 @ is catchRelPc < 0?
add sp, sp, #8 @ restore stack
bmi .LnotCaughtLocally
- /* fix stack overflow if necessary; must preserve r0 */
- ldrb r1, [r10, #offThread_stackOverflowed]
- cmp r1, #0 @ did we overflow earlier?
- beq 1f @ no, skip ahead
- mov r9, r0 @ r9<- r0 (save it)
- mov r0, r10 @ r0<- self
- bl dvmCleanupStackOverflow @ call(self)
- mov r0, r9 @ r0<- r9 (restore it)
- ldr r9, [r10, #offThread_exception] @ r9<- self->exception
-1:
-
/* adjust locals to match self->curFrame and updated PC */
SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area
ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method
@@ -9978,7 +9983,7 @@
.LstrDivideByZero:
.asciz "divide by zero"
.LstrFilledNewArrayNotImpl:
- .asciz "filled-new-array only implemented for 'int'"
+ .asciz "filled-new-array only implemented for objects and 'int'"
.LstrInternalError:
.asciz "Ljava/lang/InternalError;"
.LstrInstantiationError:
diff --git a/vm/mterp/out/InterpAsm-armv5te.S b/vm/mterp/out/InterpAsm-armv5te.S
index 344b900..9987ff5 100644
--- a/vm/mterp/out/InterpAsm-armv5te.S
+++ b/vm/mterp/out/InterpAsm-armv5te.S
@@ -8054,16 +8054,18 @@
.LOP_FILLED_NEW_ARRAY_continue:
ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags
- ldrb r0, [r3, #1] @ r0<- descriptor[1]
+ ldrb r3, [r3, #1] @ r3<- descriptor[1]
.if 0
mov r1, r10 @ r1<- AA (length)
.else
mov r1, r10, lsr #4 @ r1<- B (length)
.endif
- cmp r0, #'I' @ array of ints?
+ cmp r3, #'I' @ array of ints?
+ cmpne r3, #'L' @ array of objects?
+ cmpne r3, #'[' @ array of arrays?
mov r9, r1 @ save length in r9
bne .LOP_FILLED_NEW_ARRAY_notimpl @ no, not handled yet
- bl dvmAllocPrimitiveArray @ r0<- call(typeCh, length, flags)
+ bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags)
cmp r0, #0 @ null return?
beq common_exceptionThrown @ alloc failed, handle exception
@@ -8131,16 +8133,18 @@
.LOP_FILLED_NEW_ARRAY_RANGE_continue:
ldr r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
mov r2, #ALLOC_DONT_TRACK @ r2<- alloc flags
- ldrb r0, [r3, #1] @ r0<- descriptor[1]
+ ldrb r3, [r3, #1] @ r3<- descriptor[1]
.if 1
mov r1, r10 @ r1<- AA (length)
.else
mov r1, r10, lsr #4 @ r1<- B (length)
.endif
- cmp r0, #'I' @ array of ints?
+ cmp r3, #'I' @ array of ints?
+ cmpne r3, #'L' @ array of objects?
+ cmpne r3, #'[' @ array of arrays?
mov r9, r1 @ save length in r9
bne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl @ no, not handled yet
- bl dvmAllocPrimitiveArray @ r0<- call(typeCh, length, flags)
+ bl dvmAllocArrayByClass @ r0<- call(arClass, length, flags)
cmp r0, #0 @ null return?
beq common_exceptionThrown @ alloc failed, handle exception
@@ -9657,22 +9661,23 @@
/* call, r0 gets catchRelPc (a code-unit offset) */
bl dvmFindCatchBlock @ call(self, relPc, exc, scan?, &fp)
+
+ /* fix earlier stack overflow if necessary; may trash rFP */
+ ldrb r1, [r10, #offThread_stackOverflowed]
+ cmp r1, #0 @ did we overflow earlier?
+ beq 1f @ no, skip ahead
+ mov rFP, r0 @ save relPc result in rFP
+ mov r0, r10 @ r0<- self
+ bl dvmCleanupStackOverflow @ call(self)
+ mov r0, rFP @ restore result
+1:
+
+ /* update frame pointer and check result from dvmFindCatchBlock */
ldr rFP, [sp, #4] @ retrieve the updated rFP
cmp r0, #0 @ is catchRelPc < 0?
add sp, sp, #8 @ restore stack
bmi .LnotCaughtLocally
- /* fix stack overflow if necessary; must preserve r0 */
- ldrb r1, [r10, #offThread_stackOverflowed]
- cmp r1, #0 @ did we overflow earlier?
- beq 1f @ no, skip ahead
- mov r9, r0 @ r9<- r0 (save it)
- mov r0, r10 @ r0<- self
- bl dvmCleanupStackOverflow @ call(self)
- mov r0, r9 @ r0<- r9 (restore it)
- ldr r9, [r10, #offThread_exception] @ r9<- self->exception
-1:
-
/* adjust locals to match self->curFrame and updated PC */
SAVEAREA_FROM_FP(r1, rFP) @ r1<- new save area
ldr r1, [r1, #offStackSaveArea_method] @ r1<- new method
@@ -9972,7 +9977,7 @@
.LstrDivideByZero:
.asciz "divide by zero"
.LstrFilledNewArrayNotImpl:
- .asciz "filled-new-array only implemented for 'int'"
+ .asciz "filled-new-array only implemented for objects and 'int'"
.LstrInternalError:
.asciz "Ljava/lang/InternalError;"
.LstrInstantiationError:
diff --git a/vm/mterp/out/InterpAsm-x86.S b/vm/mterp/out/InterpAsm-x86.S
index e3ed65f..3917ea5 100644
--- a/vm/mterp/out/InterpAsm-x86.S
+++ b/vm/mterp/out/InterpAsm-x86.S
@@ -6529,15 +6529,20 @@
movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor
movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags
movzbl 1(%ecx),%ecx # ecx<- descriptor[1]
- movl %ecx,OUT_ARG0(%esp) # arg0<- typeCh
+ movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass
cmpb $'I',%cl # supported?
+ je 1f
+ cmpb $'L',%cl
+ je 1f
+ cmpb $'[',%cl
jne .LOP_FILLED_NEW_ARRAY_notimpl # no, not handled yet
+1:
.if (!0)
SPILL_TMP(rINST_FULL) # save copy, need "B" later
sarl $4,rINST_FULL
.endif
movl rINST_FULL,OUT_ARG1(%esp) # arg1<- A or AA (length)
- call dvmAllocPrimitiveArray # eax<- call(typeCh, length, flags)
+ call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags)
UNSPILL(rPC)
GET_GLUE(%ecx)
testl %eax,%eax # alloc successful?
@@ -6629,15 +6634,20 @@
movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor
movl $ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags
movzbl 1(%ecx),%ecx # ecx<- descriptor[1]
- movl %ecx,OUT_ARG0(%esp) # arg0<- typeCh
+ movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass
cmpb $'I',%cl # supported?
+ je 1f
+ cmpb $'L',%cl
+ je 1f
+ cmpb $'[',%cl
jne .LOP_FILLED_NEW_ARRAY_RANGE_notimpl # no, not handled yet
+1:
.if (!1)
SPILL_TMP(rINST_FULL) # save copy, need "B" later
sarl $4,rINST_FULL
.endif
movl rINST_FULL,OUT_ARG1(%esp) # arg1<- A or AA (length)
- call dvmAllocPrimitiveArray # eax<- call(typeCh, length, flags)
+ call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags)
UNSPILL(rPC)
GET_GLUE(%ecx)
testl %eax,%eax # alloc successful?
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index 02592bd..635a873 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -3037,7 +3037,7 @@
{
ClassObject* arrayClass;
ArrayObject* newArray;
- int* contents;
+ u4* contents;
char typeCh;
int i;
u4 arg5;
@@ -3089,31 +3089,22 @@
dvmThrowException("Ljava/lang/RuntimeError;",
"bad filled array req");
GOTO_exceptionThrown();
- } else if (typeCh == 'L' || typeCh == '[') {
- /* create array of objects or array of arrays */
- /* TODO: need some work in the verifier before we allow this */
- LOGE("fnao not implemented\n");
- dvmThrowException("Ljava/lang/InternalError;",
- "filled-new-array not implemented for reference types");
- GOTO_exceptionThrown();
- } else if (typeCh != 'I') {
+ } else if (typeCh != 'L' && typeCh != '[' && typeCh != 'I') {
/* TODO: requires multiple "fill in" loops with different widths */
- LOGE("non-int not implemented\n");
+ LOGE("non-int primitives not implemented\n");
dvmThrowException("Ljava/lang/InternalError;",
"filled-new-array not implemented for anything but 'int'");
GOTO_exceptionThrown();
}
- assert(strchr("BCIFZ", typeCh) != NULL);
- newArray = dvmAllocPrimitiveArray(arrayClass->descriptor[1], vsrc1,
- ALLOC_DONT_TRACK);
+ newArray = dvmAllocArrayByClass(arrayClass, vsrc1, ALLOC_DONT_TRACK);
if (newArray == NULL)
GOTO_exceptionThrown();
/*
* Fill in the elements. It's legal for vsrc1 to be zero.
*/
- contents = (int*) newArray->contents;
+ contents = (u4*) newArray->contents;
if (methodCallRange) {
for (i = 0; i < vsrc1; i++)
contents[i] = GET_REGISTER(vdst+i);
@@ -3670,6 +3661,10 @@
* exception this won't happen until some other exception gets
* thrown. If the code keeps pushing the stack bounds we'll end
* up aborting the VM.
+ *
+ * Note we want to do this *after* the call to dvmFindCatchBlock,
+ * because that may need extra stack space to resolve exception
+ * classes (e.g. through a class loader).
*/
if (self->stackOverflowed)
dvmCleanupStackOverflow(self);
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index cc23d33..d527cc0 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -3298,7 +3298,7 @@
{
ClassObject* arrayClass;
ArrayObject* newArray;
- int* contents;
+ u4* contents;
char typeCh;
int i;
u4 arg5;
@@ -3350,31 +3350,22 @@
dvmThrowException("Ljava/lang/RuntimeError;",
"bad filled array req");
GOTO_exceptionThrown();
- } else if (typeCh == 'L' || typeCh == '[') {
- /* create array of objects or array of arrays */
- /* TODO: need some work in the verifier before we allow this */
- LOGE("fnao not implemented\n");
- dvmThrowException("Ljava/lang/InternalError;",
- "filled-new-array not implemented for reference types");
- GOTO_exceptionThrown();
- } else if (typeCh != 'I') {
+ } else if (typeCh != 'L' && typeCh != '[' && typeCh != 'I') {
/* TODO: requires multiple "fill in" loops with different widths */
- LOGE("non-int not implemented\n");
+ LOGE("non-int primitives not implemented\n");
dvmThrowException("Ljava/lang/InternalError;",
"filled-new-array not implemented for anything but 'int'");
GOTO_exceptionThrown();
}
- assert(strchr("BCIFZ", typeCh) != NULL);
- newArray = dvmAllocPrimitiveArray(arrayClass->descriptor[1], vsrc1,
- ALLOC_DONT_TRACK);
+ newArray = dvmAllocArrayByClass(arrayClass, vsrc1, ALLOC_DONT_TRACK);
if (newArray == NULL)
GOTO_exceptionThrown();
/*
* Fill in the elements. It's legal for vsrc1 to be zero.
*/
- contents = (int*) newArray->contents;
+ contents = (u4*) newArray->contents;
if (methodCallRange) {
for (i = 0; i < vsrc1; i++)
contents[i] = GET_REGISTER(vdst+i);
@@ -3931,6 +3922,10 @@
* exception this won't happen until some other exception gets
* thrown. If the code keeps pushing the stack bounds we'll end
* up aborting the VM.
+ *
+ * Note we want to do this *after* the call to dvmFindCatchBlock,
+ * because that may need extra stack space to resolve exception
+ * classes (e.g. through a class loader).
*/
if (self->stackOverflowed)
dvmCleanupStackOverflow(self);
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index 7872236..64e5ccd 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -3018,7 +3018,7 @@
{
ClassObject* arrayClass;
ArrayObject* newArray;
- int* contents;
+ u4* contents;
char typeCh;
int i;
u4 arg5;
@@ -3070,31 +3070,22 @@
dvmThrowException("Ljava/lang/RuntimeError;",
"bad filled array req");
GOTO_exceptionThrown();
- } else if (typeCh == 'L' || typeCh == '[') {
- /* create array of objects or array of arrays */
- /* TODO: need some work in the verifier before we allow this */
- LOGE("fnao not implemented\n");
- dvmThrowException("Ljava/lang/InternalError;",
- "filled-new-array not implemented for reference types");
- GOTO_exceptionThrown();
- } else if (typeCh != 'I') {
+ } else if (typeCh != 'L' && typeCh != '[' && typeCh != 'I') {
/* TODO: requires multiple "fill in" loops with different widths */
- LOGE("non-int not implemented\n");
+ LOGE("non-int primitives not implemented\n");
dvmThrowException("Ljava/lang/InternalError;",
"filled-new-array not implemented for anything but 'int'");
GOTO_exceptionThrown();
}
- assert(strchr("BCIFZ", typeCh) != NULL);
- newArray = dvmAllocPrimitiveArray(arrayClass->descriptor[1], vsrc1,
- ALLOC_DONT_TRACK);
+ newArray = dvmAllocArrayByClass(arrayClass, vsrc1, ALLOC_DONT_TRACK);
if (newArray == NULL)
GOTO_exceptionThrown();
/*
* Fill in the elements. It's legal for vsrc1 to be zero.
*/
- contents = (int*) newArray->contents;
+ contents = (u4*) newArray->contents;
if (methodCallRange) {
for (i = 0; i < vsrc1; i++)
contents[i] = GET_REGISTER(vdst+i);
@@ -3651,6 +3642,10 @@
* exception this won't happen until some other exception gets
* thrown. If the code keeps pushing the stack bounds we'll end
* up aborting the VM.
+ *
+ * Note we want to do this *after* the call to dvmFindCatchBlock,
+ * because that may need extra stack space to resolve exception
+ * classes (e.g. through a class loader).
*/
if (self->stackOverflowed)
dvmCleanupStackOverflow(self);
diff --git a/vm/mterp/out/InterpC-x86.c b/vm/mterp/out/InterpC-x86.c
index 3134993..cd5fe95 100644
--- a/vm/mterp/out/InterpC-x86.c
+++ b/vm/mterp/out/InterpC-x86.c
@@ -1187,7 +1187,7 @@
{
ClassObject* arrayClass;
ArrayObject* newArray;
- int* contents;
+ u4* contents;
char typeCh;
int i;
u4 arg5;
@@ -1239,31 +1239,22 @@
dvmThrowException("Ljava/lang/RuntimeError;",
"bad filled array req");
GOTO_exceptionThrown();
- } else if (typeCh == 'L' || typeCh == '[') {
- /* create array of objects or array of arrays */
- /* TODO: need some work in the verifier before we allow this */
- LOGE("fnao not implemented\n");
- dvmThrowException("Ljava/lang/InternalError;",
- "filled-new-array not implemented for reference types");
- GOTO_exceptionThrown();
- } else if (typeCh != 'I') {
+ } else if (typeCh != 'L' && typeCh != '[' && typeCh != 'I') {
/* TODO: requires multiple "fill in" loops with different widths */
- LOGE("non-int not implemented\n");
+ LOGE("non-int primitives not implemented\n");
dvmThrowException("Ljava/lang/InternalError;",
"filled-new-array not implemented for anything but 'int'");
GOTO_exceptionThrown();
}
- assert(strchr("BCIFZ", typeCh) != NULL);
- newArray = dvmAllocPrimitiveArray(arrayClass->descriptor[1], vsrc1,
- ALLOC_DONT_TRACK);
+ newArray = dvmAllocArrayByClass(arrayClass, vsrc1, ALLOC_DONT_TRACK);
if (newArray == NULL)
GOTO_exceptionThrown();
/*
* Fill in the elements. It's legal for vsrc1 to be zero.
*/
- contents = (int*) newArray->contents;
+ contents = (u4*) newArray->contents;
if (methodCallRange) {
for (i = 0; i < vsrc1; i++)
contents[i] = GET_REGISTER(vdst+i);
@@ -1820,6 +1811,10 @@
* exception this won't happen until some other exception gets
* thrown. If the code keeps pushing the stack bounds we'll end
* up aborting the VM.
+ *
+ * Note we want to do this *after* the call to dvmFindCatchBlock,
+ * because that may need extra stack space to resolve exception
+ * classes (e.g. through a class loader).
*/
if (self->stackOverflowed)
dvmCleanupStackOverflow(self);
diff --git a/vm/mterp/x86/OP_FILLED_NEW_ARRAY.S b/vm/mterp/x86/OP_FILLED_NEW_ARRAY.S
index 85b468d..aa247a8 100644
--- a/vm/mterp/x86/OP_FILLED_NEW_ARRAY.S
+++ b/vm/mterp/x86/OP_FILLED_NEW_ARRAY.S
@@ -47,15 +47,20 @@
movl offClassObject_descriptor(%eax),%ecx # ecx<- arrayClass->descriptor
movl $$ALLOC_DONT_TRACK,OUT_ARG2(%esp) # arg2<- flags
movzbl 1(%ecx),%ecx # ecx<- descriptor[1]
- movl %ecx,OUT_ARG0(%esp) # arg0<- typeCh
+ movl %eax,OUT_ARG0(%esp) # arg0<- arrayClass
cmpb $$'I',%cl # supported?
+ je 1f
+ cmpb $$'L',%cl
+ je 1f
+ cmpb $$'[',%cl
jne .L${opcode}_notimpl # no, not handled yet
+1:
.if (!$isrange)
SPILL_TMP(rINST_FULL) # save copy, need "B" later
sarl $$4,rINST_FULL
.endif
movl rINST_FULL,OUT_ARG1(%esp) # arg1<- A or AA (length)
- call dvmAllocPrimitiveArray # eax<- call(typeCh, length, flags)
+ call dvmAllocArrayByClass # eax<- call(arrayClass, length, flags)
UNSPILL(rPC)
GET_GLUE(%ecx)
testl %eax,%eax # alloc successful?
diff --git a/vm/native/dalvik_system_VMDebug.c b/vm/native/dalvik_system_VMDebug.c
index 990494e..9eccb76 100644
--- a/vm/native/dalvik_system_VMDebug.c
+++ b/vm/native/dalvik_system_VMDebug.c
@@ -400,10 +400,10 @@
{
#if defined(WITH_PROFILER)
dvmStartInstructionCounting();
- RETURN_VOID();
#else
dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
#endif
+ RETURN_VOID();
}
/*
@@ -414,10 +414,10 @@
{
#if defined(WITH_PROFILER)
dvmStopInstructionCounting();
- RETURN_VOID();
#else
dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
#endif
+ RETURN_VOID();
}
/*
@@ -440,11 +440,10 @@
sched_yield();
memcpy(storage, gDvm.executedInstrCounts,
kNumDalvikInstructions * sizeof(int));
-
- RETURN_VOID();
#else
dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
#endif
+ RETURN_VOID();
}
/*
@@ -458,10 +457,10 @@
#if defined(WITH_PROFILER)
sched_yield();
memset(gDvm.executedInstrCounts, 0, kNumDalvikInstructions * sizeof(int));
- RETURN_VOID();
#else
dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
#endif
+ RETURN_VOID();
}
/*
@@ -501,10 +500,10 @@
* or -1 if the feature isn't supported.
*/
static void Dalvik_dalvik_system_VMDebug_threadCpuTimeNanos(const u4* args,
- JValue* pResult)
+ JValue* pResult)
{
jlong result;
-
+
#ifdef HAVE_POSIX_CLOCKS
struct timespec now;
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
@@ -516,49 +515,85 @@
RETURN_LONG(result);
}
+/*
+ * static void dumpHprofData(String fileName)
+ *
+ * Cause "hprof" data to be dumped. We can throw an IOException if an
+ * error occurs during file handling.
+ */
+static void Dalvik_dalvik_system_VMDebug_dumpHprofData(const u4* args,
+ JValue* pResult)
+{
+#ifdef WITH_HPROF
+ StringObject* fileNameStr = (StringObject*) args[0];
+ char* fileName;
+
+ if (fileNameStr == NULL) {
+ dvmThrowException("Ljava/lang/NullPointerException;", NULL);
+ RETURN_VOID();
+ }
+
+ fileName = dvmCreateCstrFromString(fileNameStr);
+ if (fileName == NULL) {
+ /* unexpected -- malloc failure? */
+ dvmThrowException("Ljava/lang/RuntimeException;", "malloc failure?");
+ RETURN_VOID();
+ }
+
+ hprofDumpHeap(fileName);
+ free(fileName);
+#else
+ dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL);
+#endif
+
+ RETURN_VOID();
+}
+
const DalvikNativeMethod dvm_dalvik_system_VMDebug[] = {
- { "getAllocCount", "(I)I",
+ { "getAllocCount", "(I)I",
Dalvik_dalvik_system_VMDebug_getAllocCount },
- { "resetAllocCount", "(I)V",
+ { "resetAllocCount", "(I)V",
Dalvik_dalvik_system_VMDebug_resetAllocCount },
//{ "print", "(Ljava/lang/String;)V",
// Dalvik_dalvik_system_VMDebug_print },
- { "startAllocCounting", "()V",
+ { "startAllocCounting", "()V",
Dalvik_dalvik_system_VMDebug_startAllocCounting },
- { "stopAllocCounting", "()V",
+ { "stopAllocCounting", "()V",
Dalvik_dalvik_system_VMDebug_stopAllocCounting },
- { "startMethodTracing", "(Ljava/lang/String;II)V",
+ { "startMethodTracing", "(Ljava/lang/String;II)V",
Dalvik_dalvik_system_VMDebug_startMethodTracing },
- { "stopMethodTracing", "()V",
+ { "stopMethodTracing", "()V",
Dalvik_dalvik_system_VMDebug_stopMethodTracing },
- { "startEmulatorTracing", "()V",
+ { "startEmulatorTracing", "()V",
Dalvik_dalvik_system_VMDebug_startEmulatorTracing },
- { "stopEmulatorTracing", "()V",
+ { "stopEmulatorTracing", "()V",
Dalvik_dalvik_system_VMDebug_stopEmulatorTracing },
- { "setAllocationLimit", "(I)I",
+ { "setAllocationLimit", "(I)I",
Dalvik_dalvik_system_VMDebug_setAllocationLimit },
- { "setGlobalAllocationLimit", "(I)I",
+ { "setGlobalAllocationLimit", "(I)I",
Dalvik_dalvik_system_VMDebug_setGlobalAllocationLimit },
- { "startInstructionCounting", "()V",
+ { "startInstructionCounting", "()V",
Dalvik_dalvik_system_VMDebug_startInstructionCounting },
- { "stopInstructionCounting", "()V",
+ { "stopInstructionCounting", "()V",
Dalvik_dalvik_system_VMDebug_stopInstructionCounting },
- { "resetInstructionCount", "()V",
+ { "resetInstructionCount", "()V",
Dalvik_dalvik_system_VMDebug_resetInstructionCount },
- { "getInstructionCount", "([I)V",
+ { "getInstructionCount", "([I)V",
Dalvik_dalvik_system_VMDebug_getInstructionCount },
- { "isDebuggerConnected", "()Z",
+ { "isDebuggerConnected", "()Z",
Dalvik_dalvik_system_VMDebug_isDebuggerConnected },
- { "isDebuggingEnabled", "()Z",
+ { "isDebuggingEnabled", "()Z",
Dalvik_dalvik_system_VMDebug_isDebuggingEnabled },
- { "lastDebuggerActivity", "()J",
+ { "lastDebuggerActivity", "()J",
Dalvik_dalvik_system_VMDebug_lastDebuggerActivity },
- { "printLoadedClasses", "(I)V",
+ { "printLoadedClasses", "(I)V",
Dalvik_dalvik_system_VMDebug_printLoadedClasses },
- { "getLoadedClassCount", "()I",
+ { "getLoadedClassCount", "()I",
Dalvik_dalvik_system_VMDebug_getLoadedClassCount },
- { "threadCpuTimeNanos", "()J",
+ { "threadCpuTimeNanos", "()J",
Dalvik_dalvik_system_VMDebug_threadCpuTimeNanos },
+ { "dumpHprofData", "(Ljava/lang/String;)V",
+ Dalvik_dalvik_system_VMDebug_dumpHprofData },
{ NULL, NULL, NULL },
};
diff --git a/vm/oo/Class.c b/vm/oo/Class.c
index 0d8114b..c7ab763 100644
--- a/vm/oo/Class.c
+++ b/vm/oo/Class.c
@@ -177,6 +177,10 @@
#if LOG_CLASS_LOADING
/*
* Logs information about a class loading with given timestamp.
+ *
+ * TODO: In the case where we fail in dvmLinkClass() and log the class as closing (type='<'),
+ * it would probably be better to use a new type code to indicate the failure. This change would
+ * require a matching change in the parser and analysis code in frameworks/base/tools/preload.
*/
static void logClassLoadWithTime(char type, ClassObject* clazz, u8 time) {
pid_t ppid = getppid();
@@ -196,7 +200,7 @@
}
#endif
-/*
+/*
* Some LinearAlloc unit tests.
*/
static void linearAllocTests()
@@ -1095,7 +1099,7 @@
*
* The class will be loaded and initialized if it has not already been.
* If necessary, the superclass will be loaded.
- *
+ *
* If the class can't be found, returns NULL with an appropriate exception
* raised.
*/
@@ -1391,7 +1395,7 @@
goto bail;
}
- /*
+ /*
* Lock the class while we link it so other threads must wait for us
* to finish. Set the "initThreadId" so we can identify recursive
* invocation.
@@ -1451,6 +1455,17 @@
dvmObjectNotifyAll(self, (Object*) clazz);
dvmUnlockObject(self, (Object*) clazz);
+#if LOG_CLASS_LOADING
+ LOG(LOG_INFO, "DVMLINK FAILED FOR CLASS ", "%s in %s\n",
+ clazz->descriptor, get_process_name());
+
+ /*
+ * TODO: It would probably be better to use a new type code here (instead of '<') to
+ * indicate the failure. This change would require a matching change in the parser
+ * and analysis code in frameworks/base/tools/preload.
+ */
+ logClassLoad('<', clazz);
+#endif
clazz = NULL;
if (gDvm.optimizing) {
/* happens with "external" libs */
@@ -1458,9 +1473,6 @@
} else {
LOGW("Link of class '%s' failed\n", descriptor);
}
-#if LOG_CLASS_LOADING
- logClassLoad('<', clazz);
-#endif
goto bail;
}
dvmObjectNotifyAll(self, (Object*) clazz);
@@ -1909,6 +1921,8 @@
free(meth->lines);
free(meth->locals);
#else
+ // TODO: call dvmFreeRegisterMap() if meth->registerMap was allocated
+ // on the system heap
UNUSED_PARAMETER(meth);
#endif
}
@@ -1990,11 +2004,11 @@
/*
* jniArgInfo (32-bit int) layout:
* SRRRHHHH HHHHHHHH HHHHHHHH HHHHHHHH
- *
+ *
* S - if set, do things the hard way (scan the signature)
* R - return-type enumeration
* H - target-specific hints
- *
+ *
* This info is used at invocation time by dvmPlatformInvoke. In most
* cases, the target-specific hints allow dvmPlatformInvoke to avoid
* having to fully parse the signature.
@@ -3620,7 +3634,7 @@
bool needRelease = false;
if (! parsed) {
- /*
+ /*
* TODO: Eventually verification should attempt to ensure
* that this can't happen at least due to a data integrity
* problem.
@@ -4255,6 +4269,32 @@
}
/*
+ * Add a RegisterMap to a Method. This is done when we verify the class
+ * and compute the register maps at class initialization time, which means
+ * that "pMap" is on the heap and should be freed when the Method is
+ * discarded.
+ */
+void dvmSetRegisterMap(Method* method, const RegisterMap* pMap)
+{
+ ClassObject* clazz = method->clazz;
+
+ if (method->registerMap != NULL) {
+ LOGW("WARNING: registerMap already set for %s.%s\n",
+ method->clazz->descriptor, method->name);
+ /* keep going */
+ }
+
+ /* might be virtual or direct */
+ dvmLinearReadWrite(clazz->classLoader, clazz->virtualMethods);
+ dvmLinearReadWrite(clazz->classLoader, clazz->directMethods);
+
+ method->registerMap = pMap;
+
+ dvmLinearReadOnly(clazz->classLoader, clazz->virtualMethods);
+ dvmLinearReadOnly(clazz->classLoader, clazz->directMethods);
+}
+
+/*
* dvmHashForeach callback. A nonzero return value causes foreach to
* bail out.
*/
@@ -4461,7 +4501,7 @@
*/
int dvmGetNumLoadedClasses()
{
- int count;
+ int count;
dvmHashTableLock(gDvm.loadedClasses);
count = dvmHashTableNumEntries(gDvm.loadedClasses);
dvmHashTableUnlock(gDvm.loadedClasses);
diff --git a/vm/oo/Class.h b/vm/oo/Class.h
index 67dbc1c77..349df3f 100644
--- a/vm/oo/Class.h
+++ b/vm/oo/Class.h
@@ -144,6 +144,11 @@
void dvmSetNativeFunc(const Method* method, DalvikBridgeFunc func,
const u2* insns);
+/*
+ * Set the method's "registerMap" field.
+ */
+void dvmSetRegisterMap(Method* method, const RegisterMap* pMap);
+
/* during DEX optimizing, add an extra DEX to the bootstrap class path */
INLINE void dvmSetBootPathExtraDex(DvmDex* pDvmDex);
diff --git a/vm/oo/Object.h b/vm/oo/Object.h
index 71d804d..7ef8dac 100644
--- a/vm/oo/Object.h
+++ b/vm/oo/Object.h
@@ -33,6 +33,7 @@
struct StaticField;
struct InstField;
struct Field;
+struct RegisterMap;
typedef struct DataObject DataObject;
typedef struct ClassObject ClassObject;
typedef struct StringObject StringObject;
@@ -43,6 +44,7 @@
typedef struct StaticField StaticField;
typedef struct InstField InstField;
typedef struct Field Field;
+typedef struct RegisterMap RegisterMap;
/*
* Native function pointer type.
@@ -461,6 +463,13 @@
*/
DalvikBridgeFunc nativeFunc;
+ /*
+ * Register map data, if available. This will point into the DEX file
+ * if the data was computed during pre-verification, or into the
+ * linear alloc area if not.
+ */
+ const RegisterMap* registerMap;
+
#ifdef WITH_PROFILER
bool inProfile;
#endif
diff --git a/vm/oo/Resolve.c b/vm/oo/Resolve.c
index 04c96db..52eeee0 100644
--- a/vm/oo/Resolve.c
+++ b/vm/oo/Resolve.c
@@ -64,6 +64,7 @@
{
DvmDex* pDvmDex = referrer->pDvmDex;
ClassObject* resClass;
+ const char* className;
/*
* Check the table first -- this gets called from the other "resolve"
@@ -85,9 +86,13 @@
*
* If this is an array class, we'll generate it here.
*/
- resClass = dvmFindClassNoInit(
- dexStringByTypeIdx(pDvmDex->pDexFile, classIdx),
- referrer->classLoader);
+ className = dexStringByTypeIdx(pDvmDex->pDexFile, classIdx);
+ if (className[0] != '\0' && className[1] == '\0') {
+ /* primitive type */
+ resClass = dvmFindPrimitiveClass(className[0]);
+ } else {
+ resClass = dvmFindClassNoInit(className, referrer->classLoader);
+ }
if (resClass != NULL) {
/*
diff --git a/vm/reflect/Annotation.c b/vm/reflect/Annotation.c
index 5b2afd9..c07c602 100644
--- a/vm/reflect/Annotation.c
+++ b/vm/reflect/Annotation.c
@@ -484,18 +484,6 @@
elemObj = (Object*) dvmResolveClass(clazz, idx, true);
setObject = true;
if (elemObj == NULL) {
- /* see if it's a primitive type - not common */
- dvmClearException(self);
- const char* className =
- dexStringByTypeIdx(clazz->pDvmDex->pDexFile, idx);
-
- if (className != NULL &&
- className[0] != '\0' && className[1] == '\0')
- {
- elemObj = (Object*) dvmFindPrimitiveClass(className[0]);
- }
- }
- if (elemObj == NULL) {
/* we're expected to throw a TypeNotPresentException here */
DexFile* pDexFile = clazz->pDvmDex->pDexFile;
const char* desc = dexStringByTypeIdx(pDexFile, idx);