Reported by Andrey Grigoriev:
When using an Oracle Cursor as an outparam in a result element, SQLUnit says:
"Parent already exists for this element: outparam"
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This was because I was trying to reuse code by parsing the <resultset> tag in the <outparam type="CURSOR"> tag as part of a <result>, and did not detach it from the parent <outparam> tag before using it.
There are some related fixes as well, in the DatabaseResult.equals() method, where there was a ClassCastException thrown because I was trying to compare a DatabaseResult object with a String because this was coming back from the outparam CURSOR. Both problems have been fixed and checked into CVS.
Note that because I do not have access to an Oracle database, I am unable to actually test this. I checked that the parsing works against a PostgreSQL database which does not support CURSOR's returned as OUTPARAMS. If someone has access to an Oracle database (I will probably ask Andrey, since he pointed out the bug), would appreciate it if you could test this with a CURSOR returned from the procedure on an OUTPARAM.
Thanks
Sujit
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
More information sent by Andrei by email and kept here for reference.
><test name="get_bw_list - 1">
> <call>
> <stmt>{ call cwbwlist.get_uri_list(?,?,?,?)}</stmt>
> <param id="1" type="VARCHAR"></param>
> <param id="2" type="VARCHAR"></param>
> <param id="3" type="VARCHAR"></param>
> <param id="4" type="CURSOR" inout="out">${pList}</param>
> </call>
> <result>
> <outparam id="4" type="CURSOR">
> <resultset id="1">
> <row id="1">
> <col id="1" name="ADDRESS" type="VARCHAR">101</col>
> <row>
> <resultset>
> <outparam>>
> </result>
></test>
>
> And here is the result:
>
> sqlunit-nested:
> [sqlunit] Getting connection(DEFAULT)
> [sqlunit] Setting up test...
> [sqlunit] Running test[1]: get_bw_list - 1 (1272ms)
> [sqlunit] 0
> [sqlunit] Tearing down test...
> [sqlunit] SQLUnit Tests Failed: In file:
> C:\tests\get_feature_by_code.xml, tests: 1, failures:
> 1,
> errors = 0
> [sqlunit] net.sourceforge.sqlunit.SQLUnitException:
> One or more SQLUnit Tests failed, see the cons
> ole for details
> [sqlunit] at
> net.sourceforge.antsqlunittask.SqlunitTask.execute(SqlunitTask.java:118)
> [sqlunit] at
> org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:193)
> [sqlunit] at
> org.apache.tools.ant.Task.perform(Task.java:341)
> [sqlunit] at
> org.apache.tools.ant.Target.execute(Target.java:309)
> [sqlunit] at
> org.apache.tools.ant.Target.performTasks(Target.java:336)
> [sqlunit] at
> org.apache.tools.ant.Project.executeTarget(Project.java:1339)
> [sqlunit] at
> org.apache.tools.ant.Project.executeTargets(Project.java:1255)
> [sqlunit] at
> org.apache.tools.ant.Main.runBuild(Main.java:609)
> [sqlunit] at
> org.apache.tools.ant.Main.start(Main.java:196)
> [sqlunit] at
> org.apache.tools.ant.Main.main(Main.java:235)
> [sqlunit] One or more SQLUnit Tests failed, see the
> console for details
>
> Is there any way to get more detailed understanding of
> what is going on?
>
--
I was able to localize bug, but I am not very familiar
with the code, so here is the story:
This code is a few last lines before outer catch
blocks in that function.
varName contains ${pList}
outParamType[i] = -10
Seems like obj is NOT null
Thanks.
Hello!
When I do not declare variable pList from previous
example, it works without exception, but does not
detect failed tests. I set rowcount="100" when cursor
is empty and test still passes. I even change type of
field and it was not detected.
---
No stack trace available. none generated even with debug and haltOnFailure set to true.
---
Looks like we caught a memory leak (is such a thing possible in Java?) or at least a memory location containing junk. In the CallHandler (line 197) I initialized an array of ResultSet[0] but populated the first element in the line immediately after that.
Still being tested by Andrei
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I made change you suggested, and now there is new
exception: Closed Resultset: getMetaData. Which may be
OK, because my function currently return empty cursor
and it could be closed. I will do more on that
tomorrow.
and then, next morning...
Hello!
It is getting better. I created procedure that opens a
cursor and returns one record, but it reports an error
when the result matches the expected values:
[sqlunit] No match on value at outparam index=1
[sqlunit] *** expected:
[sqlunit] <result>
[sqlunit] <outparam id="1" type="CURSOR">
[sqlunit] <result>
[sqlunit] <resultset id="1">
[sqlunit] <row id="1">
[sqlunit] <col id="1"
type="NUMERIC">1</col>
[sqlunit] <col id="2"
type="VARCHAR">Default Class Of Service</col>
[sqlunit] </row>
[sqlunit] </resultset>
[sqlunit] </result>
[sqlunit] </outparam>
[sqlunit] </result>
[sqlunit] *** but got:
[sqlunit] <result>
[sqlunit] <outparam id="1" type="CURSOR">
[sqlunit] <result>
[sqlunit] <resultset id="1">
[sqlunit] <row id="1">
[sqlunit] <col id="1"
type="NUMERIC">1</col>
[sqlunit] <col id="2"
type="VARCHAR">Default Class Of Service</col>
[sqlunit] </row>
[sqlunit] </resultset>
[sqlunit] </result>
[sqlunit] </outparam>
[sqlunit] </result>
The reason for this strange behavior was that I was trying to do an equals on the DatabaseResult object in the outparam, and for various historical reasons, the equality check is implemented in customEquals(). The equals() method simply did the java compare (memory location) which obviously failed, I made a change to CVS and let Andrei know that he could pick it up, and here is his response.
--
Hello!
The latest code from CVS appears to be working - it
passes on correct tests and reports failure on
incorrect ones.
Thanks.
--
This was on Tuesday, and today's Friday. The reason it took this long for me to put this fix into the 3.1 release (it was in CVS all this time) was because I had to make some changes in the documentation to give credits to the people who have helped with the testing, and because I was trying to get docbook installed on my new laptop. Its done now, although it still throws out lots of warnings.
Anyway, the fix to the bug is finally in version 3.1. Many thanks to Andrei for his work in testing this.
-sujit
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Reported by Andrey Grigoriev:
When using an Oracle Cursor as an outparam in a result element, SQLUnit says:
"Parent already exists for this element: outparam"
This was because I was trying to reuse code by parsing the <resultset> tag in the <outparam type="CURSOR"> tag as part of a <result>, and did not detach it from the parent <outparam> tag before using it.
There are some related fixes as well, in the DatabaseResult.equals() method, where there was a ClassCastException thrown because I was trying to compare a DatabaseResult object with a String because this was coming back from the outparam CURSOR. Both problems have been fixed and checked into CVS.
Note that because I do not have access to an Oracle database, I am unable to actually test this. I checked that the parsing works against a PostgreSQL database which does not support CURSOR's returned as OUTPARAMS. If someone has access to an Oracle database (I will probably ask Andrey, since he pointed out the bug), would appreciate it if you could test this with a CURSOR returned from the procedure on an OUTPARAM.
Thanks
Sujit
More information sent by Andrei by email and kept here for reference.
><test name="get_bw_list - 1">
> <call>
> <stmt>{ call cwbwlist.get_uri_list(?,?,?,?)}</stmt>
> <param id="1" type="VARCHAR"></param>
> <param id="2" type="VARCHAR"></param>
> <param id="3" type="VARCHAR"></param>
> <param id="4" type="CURSOR" inout="out">${pList}</param>
> </call>
> <result>
> <outparam id="4" type="CURSOR">
> <resultset id="1">
> <row id="1">
> <col id="1" name="ADDRESS" type="VARCHAR">101</col>
> <row>
> <resultset>
> <outparam>>
> </result>
></test>
>
> And here is the result:
>
> sqlunit-nested:
> [sqlunit] Getting connection(DEFAULT)
> [sqlunit] Setting up test...
> [sqlunit] Running test[1]: get_bw_list - 1 (1272ms)
> [sqlunit] 0
> [sqlunit] Tearing down test...
> [sqlunit] SQLUnit Tests Failed: In file:
> C:\tests\get_feature_by_code.xml, tests: 1, failures:
> 1,
> errors = 0
> [sqlunit] net.sourceforge.sqlunit.SQLUnitException:
> One or more SQLUnit Tests failed, see the cons
> ole for details
> [sqlunit] at
> net.sourceforge.antsqlunittask.SqlunitTask.execute(SqlunitTask.java:118)
> [sqlunit] at
> org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:193)
> [sqlunit] at
> org.apache.tools.ant.Task.perform(Task.java:341)
> [sqlunit] at
> org.apache.tools.ant.Target.execute(Target.java:309)
> [sqlunit] at
> org.apache.tools.ant.Target.performTasks(Target.java:336)
> [sqlunit] at
> org.apache.tools.ant.Project.executeTarget(Project.java:1339)
> [sqlunit] at
> org.apache.tools.ant.Project.executeTargets(Project.java:1255)
> [sqlunit] at
> org.apache.tools.ant.Main.runBuild(Main.java:609)
> [sqlunit] at
> org.apache.tools.ant.Main.start(Main.java:196)
> [sqlunit] at
> org.apache.tools.ant.Main.main(Main.java:235)
> [sqlunit] One or more SQLUnit Tests failed, see the
> console for details
>
> Is there any way to get more detailed understanding of
> what is going on?
>
--
I was able to localize bug, but I am not very familiar
with the code, so here is the story:
The root cause of the exception is
public synchronized static void setValue(String
param, String value) {
symbols.put(param, value);
}
When I commend symbols.put line, it works ok. It
crashes when it is being call from
CallHandler::processElement
SymbolTable.setValue(varName,
SqlTypeUtils.convertToString(obj, outParamType[i]));
This code is a few last lines before outer catch
blocks in that function.
varName contains ${pList}
outParamType[i] = -10
Seems like obj is NOT null
Thanks.
Hello!
When I do not declare variable pList from previous
example, it works without exception, but does not
detect failed tests. I set rowcount="100" when cursor
is empty and test still passes. I even change type of
field and it was not detected.
---
No stack trace available. none generated even with debug and haltOnFailure set to true.
---
Looks like we caught a memory leak (is such a thing possible in Java?) or at least a memory location containing junk. In the CallHandler (line 197) I initialized an array of ResultSet[0] but populated the first element in the line immediately after that.
Still being tested by Andrei
More news from Andrei:
Hello!
I made change you suggested, and now there is new
exception: Closed Resultset: getMetaData. Which may be
OK, because my function currently return empty cursor
and it could be closed. I will do more on that
tomorrow.
and then, next morning...
Hello!
It is getting better. I created procedure that opens a
cursor and returns one record, but it reports an error
when the result matches the expected values:
[sqlunit] No match on value at outparam index=1
[sqlunit] *** expected:
[sqlunit] <result>
[sqlunit] <outparam id="1" type="CURSOR">
[sqlunit] <result>
[sqlunit] <resultset id="1">
[sqlunit] <row id="1">
[sqlunit] <col id="1"
type="NUMERIC">1</col>
[sqlunit] <col id="2"
type="VARCHAR">Default Class Of Service</col>
[sqlunit] </row>
[sqlunit] </resultset>
[sqlunit] </result>
[sqlunit] </outparam>
[sqlunit] </result>
[sqlunit] *** but got:
[sqlunit] <result>
[sqlunit] <outparam id="1" type="CURSOR">
[sqlunit] <result>
[sqlunit] <resultset id="1">
[sqlunit] <row id="1">
[sqlunit] <col id="1"
type="NUMERIC">1</col>
[sqlunit] <col id="2"
type="VARCHAR">Default Class Of Service</col>
[sqlunit] </row>
[sqlunit] </resultset>
[sqlunit] </result>
[sqlunit] </outparam>
[sqlunit] </result>
The reason for this strange behavior was that I was trying to do an equals on the DatabaseResult object in the outparam, and for various historical reasons, the equality check is implemented in customEquals(). The equals() method simply did the java compare (memory location) which obviously failed, I made a change to CVS and let Andrei know that he could pick it up, and here is his response.
--
Hello!
The latest code from CVS appears to be working - it
passes on correct tests and reports failure on
incorrect ones.
Thanks.
--
This was on Tuesday, and today's Friday. The reason it took this long for me to put this fix into the 3.1 release (it was in CVS all this time) was because I had to make some changes in the documentation to give credits to the people who have helped with the testing, and because I was trying to get docbook installed on my new laptop. Its done now, although it still throws out lots of warnings.
Anyway, the fix to the bug is finally in version 3.1. Many thanks to Andrei for his work in testing this.
-sujit