Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

#102 Run tests with code coverage#105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
PhilippSalvisberg merged 19 commits intomasterfromfeature/issue-102-code-coverage
May 30, 2020
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
19 commits
Select commitHold shift + click to select a range
8be0c92
add methods produceReportWithCoverage and getHtmlCoverage
PhilippSalvisbergMay 30, 2020
9605a71
add test for produceReportWithCoverage
PhilippSalvisbergMay 30, 2020
c18c484
execute setup and teardown per test
PhilippSalvisbergMay 30, 2020
758872c
add null checks for parameters
PhilippSalvisbergMay 30, 2020
55b8727
add public openInBrowser method
PhilippSalvisbergMay 30, 2020
fd0d3df
reuse code coverage test setup with actual coverage result
PhilippSalvisbergMay 30, 2020
5284796
add support to run tests with code coverage in one run
PhilippSalvisbergMay 30, 2020
b1985e6
add test with code coverage
PhilippSalvisbergMay 30, 2020
e280483
run code coverage via realtime reporter if possible
PhilippSalvisbergMay 30, 2020
22610ee
no dedicated connection required anymore
PhilippSalvisbergMay 30, 2020
e677de7
configure default fetch size of 100 (except for consumeReport)
PhilippSalvisbergMay 30, 2020
667b5fc
add resources for code coverage (icon and tooltip text)
PhilippSalvisbergMay 30, 2020
c2e7b12
calculate default schemas and provide getter; handle test env.
PhilippSalvisbergMay 30, 2020
acfb60e
populate default value for schemas under test
PhilippSalvisbergMay 30, 2020
6f5e7cb
test calcuation of default schemas under test
PhilippSalvisbergMay 30, 2020
89565a4
add code coverage to toolbar of realtime reporter (all tests)
PhilippSalvisbergMay 30, 2020
d589045
use list of schemas instead of top schema as default
PhilippSalvisbergMay 30, 2020
84ffaeb
amend test based on new default logic
PhilippSalvisbergMay 30, 2020
64cbad0
add code coverage context menu on overview table
PhilippSalvisbergMay 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,19 +22,28 @@
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import org.utplsql.sqldev.dal.RealtimeReporterDao;
import org.utplsql.sqldev.dal.UtplsqlDao;
import org.utplsql.sqldev.exception.GenericDatabaseAccessException;
import org.utplsql.sqldev.exception.GenericRuntimeException;
import org.utplsql.sqldev.model.DatabaseTools;
import org.utplsql.sqldev.model.FileTools;
import org.utplsql.sqldev.model.preference.PreferenceModel;
import org.utplsql.sqldev.runner.UtplsqlRunner;
import org.utplsql.sqldev.ui.coverage.CodeCoverageReporterDialog;

import oracle.ide.config.Preferences;

public class CodeCoverageReporter {
private static final Logger logger = Logger.getLogger(CodeCoverageReporter.class.getName());

private String connectionName;
private Connection conn;
private List<String> pathList;
private List<String> includeObjectList;
Expand All@@ -47,14 +56,17 @@ public CodeCoverageReporter(final List<String> pathList, final List<String> incl
final String connectionName) {
this.pathList = pathList;
this.includeObjectList = includeObjectList;
setDefaultSchema();
setConnection(connectionName);
}

// constructor for testing purposes only
public CodeCoverageReporter(final List<String> pathList, final List<String> includeObjectList,
final Connection conn) {
this.pathList = pathList;
this.includeObjectList = includeObjectList;
this.conn = conn;
setDefaultSchema();
}

private void setConnection(final String connectionName) {
Expand All@@ -64,7 +76,32 @@ private void setConnection(final String connectionName) {
throw new NullPointerException();
} else {
// must be closed manually
conn = DatabaseTools.cloneConnection(connectionName);
this.connectionName = connectionName;
this.conn = DatabaseTools.getConnection(connectionName);
}
}

private void setDefaultSchema() {
if (includeObjectList != null && !includeObjectList.isEmpty()) {
// use the owner with the most hits in includeObjectList
HashMap<String, Integer> owners = new HashMap<>();
for (String entry : includeObjectList) {
String[] obj = entry.toUpperCase().split("\\.");
if (obj.length == 2) {
// only if objectOwner and objectName are available
Integer count = owners.get(obj[0]);
if (count == null) {
count = 1;
} else {
count++;
}
owners.put(obj[0], count);
}
}
List<String> sortedOwners = owners.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed()).map(Map.Entry::getKey)
.collect(Collectors.toList());
schemas = String.join(", ", sortedOwners);
}
}

Expand All@@ -83,12 +120,57 @@ private ArrayList<String> toStringList(final String s) {
private void run() {
logger.fine(() -> "Running code coverage reporter for " + pathList + "...");
try {
final UtplsqlDao dal = new UtplsqlDao(conn);
final String content = dal.htmlCodeCoverage(pathList, toStringList(schemas),
final RealtimeReporterDao dao = new RealtimeReporterDao(conn);
PreferenceModel preferences;
try {
preferences = PreferenceModel.getInstance(Preferences.getPreferences());
} catch (NoClassDefFoundError error) {
// not running in SQL Developer (in tests)
preferences = PreferenceModel.getInstance(null);
}
if (preferences.isUseRealtimeReporter() && dao.isSupported() && connectionName != null) {
runCodeCoverageWithRealtimeReporter();
} else {
runCodeCoverageStandalone();
}
} finally {
if (frame != null) {
frame.exit();
}
}
}

private void runCodeCoverageWithRealtimeReporter() {
final UtplsqlRunner runner = new UtplsqlRunner(pathList, toStringList(schemas), toStringList(includeObjects),
toStringList(excludeObjects), connectionName);
runner.runTestAsync();
}

private void runCodeCoverageStandalone() {
Connection coverageConn = null;
try {
coverageConn = conn != null ? conn : DatabaseTools.cloneConnection(connectionName);
final UtplsqlDao dao = new UtplsqlDao(coverageConn);
final String html = dao.htmlCodeCoverage(pathList, toStringList(schemas),
toStringList(includeObjects), toStringList(excludeObjects));
openInBrowser(html);
} finally {
try {
if (coverageConn != null && conn == null) {
// close only if connection has been cloned
DatabaseTools.closeConnection(coverageConn);
}
} catch (GenericDatabaseAccessException e) {
// ignore
}
}
}

public static void openInBrowser(String html) {
try {
final File file = File.createTempFile("utplsql_", ".html");
logger.fine(() -> "Writing result to " + file + "...");
FileTools.writeFile(file.toPath(), Arrays.asList(content.split(System.lineSeparator())), StandardCharsets.UTF_8);
FileTools.writeFile(file.toPath(), Arrays.asList(html.split(System.lineSeparator())), StandardCharsets.UTF_8);
final URL url = file.toURI().toURL();
logger.fine(() -> "Opening " + url.toExternalForm() + " in browser...");
final Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
Expand All@@ -97,21 +179,12 @@ private void run() {
logger.fine(() -> url.toExternalForm() + " opened in browser.");
} else {
logger.severe(
() -> "Could not launch " + file + "in browser. No default browser defined on this system.");
() -> "Could not launch " + file + "in browser. No default browser defined on this system.");
}
} catch (Exception e) {
final String msg = "Error whilerunning code coveragefor " + pathList + ".";
final String msg = "Error whileopening code coverageHTML report in browser.";
logger.severe(() -> msg);
throw new GenericRuntimeException(msg, e);
} finally {
try {
DatabaseTools.closeConnection(conn);
} catch (GenericDatabaseAccessException e) {
// ignore
}
if (frame != null) {
frame.exit();
}
}
}

Expand DownExpand Up@@ -143,6 +216,10 @@ public void setSchemas(final String schemas) {
this.schemas = schemas;
}

public String getSchemas() {
return schemas;
}

public void setIncludeObjects(final String includeObjects) {
this.includeObjects = includeObjects;
}
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -64,7 +64,7 @@ public class RealtimeReporterDao {
public RealtimeReporterDao(final Connection conn) {
this.conn = conn;
jdbcTemplate = new JdbcTemplate(new SingleConnectionDataSource(conn, true));
jdbcTemplate.setFetchSize(1);
jdbcTemplate.setFetchSize(UtplsqlDao.FETCH_ROWS);
}

public boolean isSupported() {
Expand DownExpand Up@@ -93,6 +93,47 @@ public void produceReport(final String reporterId, final List<String> pathList)
jdbcTemplate.update(plsql, binds);
}

public void produceReportWithCoverage(final String realtimeReporterId, final String coverageReporterId,
final List<String> pathList, final List<String> schemaList, final List<String> includeObjectList,
final List<String> excludeObjectList) {
StringBuilder sb = new StringBuilder();
sb.append("DECLARE\n");
sb.append(" l_rt_rep ut_realtime_reporter := ut_realtime_reporter();\n");
sb.append(" l_cov_rep ut_coverage_html_reporter := ut_coverage_html_reporter();\n");
sb.append("BEGIN\n");
sb.append(" l_rt_rep.set_reporter_id(?);\n");
sb.append(" l_rt_rep.output_buffer.init();\n");
sb.append(" l_cov_rep.set_reporter_id(?);\n");
sb.append(" l_cov_rep.output_buffer.init();\n");
sb.append(" sys.dbms_output.enable(NULL);\n");
sb.append(" ut_runner.run(\n");
sb.append(" a_paths => ut_varchar2_list(\n");
sb.append(StringTools.getCSV(pathList, 31));
sb.append(" ),\n");
if (schemaList != null && !schemaList.isEmpty()) {
sb.append(" a_coverage_schemes => ut_varchar2_list(\n");
sb.append(StringTools.getCSV(schemaList, 31));
sb.append(" ),\n");
}
if (includeObjectList != null && !includeObjectList.isEmpty()) {
sb.append(" a_include_objects => ut_varchar2_list(\n");
sb.append(StringTools.getCSV(includeObjectList, 31));
sb.append(" ),\n");
}
if (excludeObjectList != null && !excludeObjectList.isEmpty()) {
sb.append(" a_exclude_objects => ut_varchar2_list(\n");
sb.append(StringTools.getCSV(excludeObjectList, 31));
sb.append(" ),\n");
}
sb.append(" a_reporters => ut_reporters(l_rt_rep, l_cov_rep)\n");
sb.append(" );\n");
sb.append(" sys.dbms_output.disable;\n");
sb.append("END;");
final String plsql = sb.toString();
final Object[] binds = { realtimeReporterId, coverageReporterId };
jdbcTemplate.update(plsql, binds);
}

public void consumeReport(final String reporterId, final RealtimeReporterEventConsumer consumer) {
StringBuilder sb = new StringBuilder();
sb.append("DECLARE\n");
Expand All@@ -102,28 +143,63 @@ public void consumeReport(final String reporterId, final RealtimeReporterEventCo
sb.append(" ? := l_reporter.get_lines_cursor();\n");
sb.append("END;");
final String plsql = sb.toString();
jdbcTemplate.execute(plsql, new CallableStatementCallback<Void>() {
jdbcTemplate.setFetchSize(1);
try {
jdbcTemplate.execute(plsql, new CallableStatementCallback<Void>() {
@Override
public Void doInCallableStatement(final CallableStatement cs) throws SQLException {
cs.setString(1, reporterId);
cs.registerOutParameter(2, OracleTypes.CURSOR);
cs.execute();
final ResultSet rs = (ResultSet) cs.getObject(2);
while (rs.next()) {
final String itemType = rs.getString("item_type");
final Clob textClob = rs.getClob("text");
final String textString = textClob.getSubString(1, ((int) textClob.length()));
final RealtimeReporterEvent event = convert(itemType, textString);
if (event != null) {
consumer.process(event);
}
}
rs.close();
return null;
}
});
} finally {
jdbcTemplate.setFetchSize(UtplsqlDao.FETCH_ROWS);
}
}

public String getHtmlCoverage(final String reporterId) {
StringBuilder sb = new StringBuilder();
sb.append("DECLARE\n");
sb.append(" l_reporter ut_coverage_html_reporter := ut_coverage_html_reporter();\n");
sb.append("BEGIN\n");
sb.append(" l_reporter.set_reporter_id(?);\n");
sb.append(" ? := l_reporter.get_lines_cursor();\n");
sb.append("END;");
final String plsql = sb.toString();
return jdbcTemplate.execute(plsql, new CallableStatementCallback<String>() {
@Override
publicVoid doInCallableStatement(final CallableStatement cs) throws SQLException {
publicString doInCallableStatement(final CallableStatement cs) throws SQLException {
cs.setString(1, reporterId);
cs.registerOutParameter(2, OracleTypes.CURSOR);
cs.execute();
final ResultSet rs = ((ResultSet) cs.getObject(2));
final StringBuilder sb = new StringBuilder();
final ResultSet rs = (ResultSet) cs.getObject(2);
while (rs.next()) {
final String itemType = rs.getString("item_type");
final Clob textClob = rs.getClob("text");
final String textString = textClob.getSubString(1, ((int) textClob.length()));
final RealtimeReporterEvent event = convert(itemType, textString);
if (event != null) {
consumer.process(event);
final String text = rs.getString("text");
if (text != null) {
sb.append(text);
sb.append('\n');
}
}
rs.close();
returnnull;
returnsb.toString();
}
});
}

}
private RealtimeReporterEvent convert(final String itemType, final String text) {
logger.fine(() -> "\n---- " + itemType + " ----\n" + text);
try {
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,6 +42,7 @@ public class UtplsqlDao {
public static final int FIRST_VERSION_WITH_ANNOTATION_API = 3001003;
public static final int FIRST_VERSION_WITHOUT_INTERNAL_API = 3001008;
public static final int FIRST_VERSION_WITH_HAS_SUITES_API = 3001008;
public static final int FETCH_ROWS = 100;
private JdbcTemplate jdbcTemplate;
// cache fields
private Boolean cachedDbaViewAccessible;
Expand All@@ -50,6 +51,7 @@ public class UtplsqlDao {

public UtplsqlDao(final Connection conn) {
jdbcTemplate = new JdbcTemplate(new SingleConnectionDataSource(conn, true));
jdbcTemplate.setFetchSize(FETCH_ROWS);
}

/**
Expand DownExpand Up@@ -918,17 +920,17 @@ public String htmlCodeCoverage(final List<String> pathList, final List<String> s
sb.append(" a_paths => ut_varchar2_list(\n");
sb.append(StringTools.getCSV(pathList, 16));
sb.append(" ),\n");
if (!schemaList.isEmpty()) {
if (schemaList != null &&!schemaList.isEmpty()) {
sb.append(" a_coverage_schemes => ut_varchar2_list(\n");
sb.append(StringTools.getCSV(schemaList, 16));
sb.append(" ),\n");
}
if (!includeObjectList.isEmpty()) {
if (includeObjectList != null &&!includeObjectList.isEmpty()) {
sb.append(" a_include_objects => ut_varchar2_list(\n");
sb.append(StringTools.getCSV(includeObjectList, 16));
sb.append(" ),\n");
}
if (!excludeObjectList.isEmpty()) {
if (excludeObjectList != null &&excludeObjectList.isEmpty()) {
sb.append(" a_exclude_objects => ut_varchar2_list(\n");
sb.append(StringTools.getCSV(excludeObjectList, 16));
sb.append(" ),\n");
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp