Skip to content

Commit c2b746d

Browse files
Merge pull request #106 from utPLSQL/feature/issue-87-debug
#87 - Debug utPLSQL tests
2 parents 304c8bc + 7867223 commit c2b746d

20 files changed

+697
-397
lines changed

.gitignore

+35-15
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,47 @@
1+
# Compiled class file
12
*.class
2-
*._trace
3-
*.xtendbin
4-
*.DS_Store
3+
4+
# Log file
55
*.log
6-
**/target
7-
**/bin
8-
**/test-output
9-
**/xtend-gen
10-
**/.sonar
11-
**/.project
12-
**/.classpath
13-
**/.settings
14-
**/.idea
156

16-
# Mobile Tools for Java (J2ME)
17-
.mtj.tmp/
187

19-
# Package Files #
8+
9+
# Package Files
2010
*.jar
2111
*.war
12+
*.nar
2213
*.ear
14+
*.zip
15+
*.tar.gz
16+
*.rar
2317

2418
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2519
hs_err_pid*
2620

21+
# Xtend
22+
*._trace
23+
*.xtendbin
24+
**/xtend-gen
25+
26+
# SonarQube
27+
**/.sonar
28+
**/.scannerwork
29+
30+
# Eclipse / Visual Studio Code
31+
.project
32+
.classpath
33+
**/.settings
34+
35+
# IntelliJ
36+
**/.idea
37+
*.iml
38+
39+
# macOS
40+
*.DS_Store
41+
42+
# Windows
2743
Thumbs.db
44+
45+
# Targets
46+
**/target
47+
**/bin

sqldev/extension.xml

+12-2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@
106106
<property name="Category">Code-Editor</property>
107107
</properties>
108108
</action>
109+
<action id="utplsql.debug">
110+
<properties>
111+
<property name="Name">${MENU_DEBUG_TEST_LABEL}</property>
112+
<property name="SmallIcon">res:/org/utplsql/sqldev/resources/images/debug.png</property>
113+
<property name="Category">Code-Editor</property>
114+
</properties>
115+
</action>
109116
<action id="utplsql.generate">
110117
<properties>
111118
<property name="Name">${MENU_GENERATE_TEST_LABEL}</property>
@@ -120,6 +127,7 @@
120127
<update-rule rule="always-enabled">
121128
<action id="utplsql.test" />
122129
<action id="utplsql.coverage" />
130+
<action id="utplsql.debug" />
123131
<action id="utplsql.generate" />
124132
</update-rule>
125133
</update-rules>
@@ -132,7 +140,8 @@
132140
id="UTPLSQL_MENU" weight="2.0">
133141
<item action-ref="utplsql.test" weight="1.0" />
134142
<item action-ref="utplsql.coverage" weight="1.1" />
135-
<item action-ref="utplsql.generate" weight="1.2" />
143+
<item action-ref="utplsql.debug" weight="1.2" />
144+
<item action-ref="utplsql.generate" weight="1.3" />
136145
</section>
137146
</menu>
138147
</context-menu-hook>
@@ -142,7 +151,8 @@
142151
<section xmlns="http://jcp.org/jsr/198/extension-manifest"
143152
id="UTPLSQL_MENU" weight="2.0">
144153
<item action-ref="utplsql.test" weight="12.1" />
145-
<item action-ref="utplsql.coverage" weight="12.2" />
154+
<item action-ref="utplsql.debug" weight="12.2" />
155+
<item action-ref="utplsql.coverage" weight="12.3" />
146156
</section>
147157
</menu>
148158
</context-menu-hook>

sqldev/pom.xml

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<!--suppress ALL -->
12
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
23
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
34
<modelVersion>4.0.0</modelVersion>
@@ -142,6 +143,20 @@
142143
<scope>system</scope>
143144
<systemPath>${sqldev.basedir}/jdev/extensions/oracle.jdeveloper.java.core.jar</systemPath>
144145
</dependency>
146+
<dependency>
147+
<groupId>oracle</groupId>
148+
<artifactId>oracle.jdeveloper.runner.jar</artifactId>
149+
<version>13.0.0</version>
150+
<scope>system</scope>
151+
<systemPath>${sqldev.basedir}/jdev/extensions/oracle.jdeveloper.runner.jar</systemPath>
152+
</dependency>
153+
<dependency>
154+
<groupId>oracle</groupId>
155+
<artifactId>oracle.ide.runner</artifactId>
156+
<version>19.3.0</version>
157+
<scope>system</scope>
158+
<systemPath>${sqldev.basedir}/ide/extensions/oracle.ide.runner.jar</systemPath>
159+
</dependency>
145160
<!-- SQL Developer specific dependencies part 2 (used for tests only) -->
146161
<dependency>
147162
<groupId>oracle</groupId>
@@ -172,6 +187,12 @@
172187
<artifactId>spring-jdbc</artifactId>
173188
<version>5.2.6.RELEASE</version>
174189
</dependency>
190+
<dependency>
191+
<!-- transitive reference, but IntelliJ wants to have it explicit (to avoid warnings) -->
192+
<groupId>org.springframework</groupId>
193+
<artifactId>spring-core</artifactId>
194+
<version>5.2.6.RELEASE</version>
195+
</dependency>
175196
<dependency>
176197
<!-- used for HtmlUtils.htmlEscape in RunnerPanel -->
177198
<groupId>org.springframework</groupId>
@@ -191,7 +212,13 @@
191212
<version>4.12</version>
192213
<scope>test</scope>
193214
</dependency>
194-
</dependencies>
215+
<dependency>
216+
<groupId>org.jetbrains</groupId>
217+
<artifactId>annotations</artifactId>
218+
<version>13.0</version>
219+
<scope>compile</scope>
220+
</dependency>
221+
</dependencies>
195222

196223
<!-- Build Settings -->
197224
<build>
@@ -370,6 +397,13 @@
370397
</configuration>
371398
</plugin>
372399
<plugin>
400+
<!-- builds the OSGi bundle including MANIFEST.MF with build version number and properties -->
401+
<!-- IMPORTANT NOTICE: -->
402+
<!-- disable OSGi facets in IntelliJ (2020.1) to get rid of the following types of warnings/errors: -->
403+
<!-- - Warning:osgi: [org.utplsql.sqldev] Host ...= for this fragment/require bundle cannot be found on the classpath -->
404+
<!-- - Warning:osgi: [org.utplsql.sqldev] No translation found for macro: ... -->
405+
<!-- - Error:osgi: [org.utplsql.sqldev] Input file does not exist: target/classes/META-INF/extension.xml -->
406+
<!-- - Error:osgi: [org.utplsql.sqldev] Invalid value for Bundle-Version, ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion} does not match \d{1,9}(\.\d{1,9}(\.\d{1,9}(\.[-\w]+)?)?)? -->
373407
<groupId>org.apache.felix</groupId>
374408
<artifactId>maven-bundle-plugin</artifactId>
375409
<version>4.2.1</version>
@@ -405,9 +439,11 @@
405439
oracle.javatools,
406440
oracle.javatools-nodeps,
407441
oracle.jdeveloper.db.connection,
442+
oracle.jdeveloper.runner,
408443
oracle.idert,
409444
oracle.ide,
410445
oracle.ide.db,
446+
oracle.ide.runner,
411447
oracle.sqldeveloper,
412448
oracle.sqldeveloper.utils,
413449
oracle.sqldeveloper.worksheet,

sqldev/src/main/java/org/utplsql/sqldev/dal/RealtimeReporterDao.java

+57-42
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@
1717

1818
import java.io.IOException;
1919
import java.io.StringReader;
20-
import java.sql.CallableStatement;
2120
import java.sql.Clob;
2221
import java.sql.Connection;
2322
import java.sql.ResultSet;
24-
import java.sql.SQLException;
2523
import java.util.List;
2624
import java.util.logging.Logger;
2725

@@ -54,12 +52,13 @@
5452

5553
import oracle.jdbc.OracleTypes;
5654

55+
@SuppressWarnings("StringBufferReplaceableByString")
5756
public class RealtimeReporterDao {
5857
private static final Logger logger = Logger.getLogger(RealtimeReporterDao.class.getName());
5958
private static final int FIRST_VERSION_WITH_REALTIME_REPORTER = 3001004;
6059
private final XMLTools xmlTools = new XMLTools();
61-
private Connection conn;
62-
private JdbcTemplate jdbcTemplate;
60+
private final Connection conn;
61+
private final JdbcTemplate jdbcTemplate;
6362

6463
public RealtimeReporterDao(final Connection conn) {
6564
this.conn = conn;
@@ -72,12 +71,23 @@ public boolean isSupported() {
7271
.normalizedUtPlsqlVersionNumber() >= RealtimeReporterDao.FIRST_VERSION_WITH_REALTIME_REPORTER;
7372
}
7473

75-
public void produceReport(final String reporterId, final List<String> pathList) {
74+
// used for execution via PL/SQL Debugger
75+
public String getProduceReportPlsql(final String reporterId, final List<String> pathList) {
76+
return getProduceReportPlsql(reporterId, pathList, false);
77+
}
78+
79+
private String getProduceReportPlsql(final String reporterId, final List<String> pathList, boolean useBindVariable) {
7680
StringBuilder sb = new StringBuilder();
7781
sb.append("DECLARE\n");
7882
sb.append(" l_reporter ut_realtime_reporter := ut_realtime_reporter();\n");
7983
sb.append("BEGIN\n");
80-
sb.append(" l_reporter.set_reporter_id(?);\n");
84+
if (useBindVariable) {
85+
sb.append(" l_reporter.set_reporter_id(?);\n");
86+
} else {
87+
sb.append(" l_reporter.set_reporter_id('");
88+
sb.append(reporterId);
89+
sb.append("');\n");
90+
}
8191
sb.append(" l_reporter.output_buffer.init();\n");
8292
sb.append(" sys.dbms_output.enable(NULL);\n");
8393
sb.append(" ut_runner.run(\n");
@@ -88,7 +98,11 @@ public void produceReport(final String reporterId, final List<String> pathList)
8898
sb.append(" );\n");
8999
sb.append(" sys.dbms_output.disable;\n");
90100
sb.append("END;");
91-
final String plsql = sb.toString();
101+
return sb.toString();
102+
}
103+
104+
public void produceReport(final String reporterId, final List<String> pathList) {
105+
final String plsql = getProduceReportPlsql(reporterId, pathList, true);
92106
final Object[] binds = { reporterId };
93107
jdbcTemplate.update(plsql, binds);
94108
}
@@ -135,35 +149,37 @@ public void produceReportWithCoverage(final String realtimeReporterId, final Str
135149
}
136150

137151
public void consumeReport(final String reporterId, final RealtimeReporterEventConsumer consumer) {
152+
consumeReport(reporterId, consumer, 60);
153+
}
154+
155+
public void consumeReport(final String reporterId, final RealtimeReporterEventConsumer consumer, final int timeoutSeconds) {
138156
StringBuilder sb = new StringBuilder();
139157
sb.append("DECLARE\n");
140158
sb.append(" l_reporter ut_realtime_reporter := ut_realtime_reporter();\n");
141159
sb.append("BEGIN\n");
142160
sb.append(" l_reporter.set_reporter_id(?);\n");
143-
sb.append(" ? := l_reporter.get_lines_cursor();\n");
161+
sb.append(" ? := l_reporter.get_lines_cursor(a_initial_timeout => ?);\n");
144162
sb.append("END;");
145163
final String plsql = sb.toString();
146164
jdbcTemplate.setFetchSize(1);
147165
try {
148-
jdbcTemplate.execute(plsql, new CallableStatementCallback<Void>() {
149-
@Override
150-
public Void doInCallableStatement(final CallableStatement cs) throws SQLException {
151-
cs.setString(1, reporterId);
152-
cs.registerOutParameter(2, OracleTypes.CURSOR);
153-
cs.execute();
154-
final ResultSet rs = (ResultSet) cs.getObject(2);
155-
while (rs.next()) {
156-
final String itemType = rs.getString("item_type");
157-
final Clob textClob = rs.getClob("text");
158-
final String textString = textClob.getSubString(1, ((int) textClob.length()));
159-
final RealtimeReporterEvent event = convert(itemType, textString);
160-
if (event != null) {
161-
consumer.process(event);
162-
}
166+
jdbcTemplate.execute(plsql, (CallableStatementCallback<Void>) cs -> {
167+
cs.setString(1, reporterId);
168+
cs.setInt(3, timeoutSeconds);
169+
cs.registerOutParameter(2, OracleTypes.CURSOR);
170+
cs.execute();
171+
final ResultSet rs = (ResultSet) cs.getObject(2);
172+
while (rs.next()) {
173+
final String itemType = rs.getString("item_type");
174+
final Clob textClob = rs.getClob("text");
175+
final String textString = textClob.getSubString(1, ((int) textClob.length()));
176+
final RealtimeReporterEvent event = convert(itemType, textString);
177+
if (event != null) {
178+
consumer.process(event);
163179
}
164-
rs.close();
165-
return null;
166180
}
181+
rs.close();
182+
return null;
167183
});
168184
} finally {
169185
jdbcTemplate.setFetchSize(UtplsqlDao.FETCH_ROWS);
@@ -179,24 +195,21 @@ public String getHtmlCoverage(final String reporterId) {
179195
sb.append(" ? := l_reporter.get_lines_cursor();\n");
180196
sb.append("END;");
181197
final String plsql = sb.toString();
182-
return jdbcTemplate.execute(plsql, new CallableStatementCallback<String>() {
183-
@Override
184-
public String doInCallableStatement(final CallableStatement cs) throws SQLException {
185-
cs.setString(1, reporterId);
186-
cs.registerOutParameter(2, OracleTypes.CURSOR);
187-
cs.execute();
188-
final StringBuilder sb = new StringBuilder();
189-
final ResultSet rs = (ResultSet) cs.getObject(2);
190-
while (rs.next()) {
191-
final String text = rs.getString("text");
192-
if (text != null) {
193-
sb.append(text);
194-
sb.append('\n');
195-
}
198+
return jdbcTemplate.execute(plsql, (CallableStatementCallback<String>) cs -> {
199+
cs.setString(1, reporterId);
200+
cs.registerOutParameter(2, OracleTypes.CURSOR);
201+
cs.execute();
202+
final StringBuilder sb1 = new StringBuilder();
203+
final ResultSet rs = (ResultSet) cs.getObject(2);
204+
while (rs.next()) {
205+
final String text = rs.getString("text");
206+
if (text != null) {
207+
sb1.append(text);
208+
sb1.append('\n');
196209
}
197-
rs.close();
198-
return sb.toString();
199210
}
211+
rs.close();
212+
return sb1.toString();
200213
});
201214
}
202215

@@ -231,14 +244,15 @@ private RealtimeReporterEvent convert(final String itemType, final String text)
231244
}
232245
}
233246

247+
@SuppressWarnings("DuplicatedCode")
234248
private RealtimeReporterEvent convertToPreRunEvent(final Document doc) {
235249
final PreRunEvent event = new PreRunEvent();
236250
final Node totalNumberOfTestsNode = xmlTools.getNode(doc, "/event/totalNumberOfTests");
237251
String totalNumberOfTestsTextContent = null;
238252
if (totalNumberOfTestsNode != null) {
239253
totalNumberOfTestsTextContent = totalNumberOfTestsNode.getTextContent();
240254
}
241-
event.setTotalNumberOfTests(Integer.valueOf(totalNumberOfTestsTextContent));
255+
event.setTotalNumberOfTests(Integer.valueOf(totalNumberOfTestsTextContent != null ? totalNumberOfTestsTextContent : "0"));
242256
final NodeList nodes = xmlTools.getNodeList(doc, "/event/items/*");
243257
for (int i = 0; i < nodes.getLength(); i++) {
244258
final Node node = nodes.item(i);
@@ -311,6 +325,7 @@ private RealtimeReporterEvent convertToPostTestEvent(final Document doc) {
311325
return event;
312326
}
313327

328+
@SuppressWarnings("DuplicatedCode")
314329
private void populate(final Suite suite, final Node node) {
315330
if (node instanceof Element) {
316331
suite.setId(xmlTools.getAttributeValue(node, "id"));

0 commit comments

Comments
 (0)