Skip to content

Commit

Permalink
Merge branch 'main' into SDCCC-1236-NPE-in-Precondition
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-Draeger committed Feb 12, 2024
2 parents e8543f8 + 2a55741 commit 68b95d1
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 74 deletions.
12 changes: 6 additions & 6 deletions .github/license-check/header-MIT-draeger-java.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* This Source Code Form is subject to the terms of the MIT License.
* Copyright (c) %year% Draegerwerk AG & Co. KGaA.
*
* SPDX-License-Identifier: MIT
*/
/\*
\* This Source Code Form is subject to the terms of the MIT License.
\* Copyright \(c\) (?:([0-9]{4}-[0-9]{4})|([0-9]{4}))(?:, (?:([0-9]{4}-[0-9]{4})|([0-9]{4})))* Draegerwerk AG & Co. KGaA.
\*
\* SPDX-License-Identifier: MIT
\*/
5 changes: 5 additions & 0 deletions .github/license-check/license-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[DraegerLicenseMIT]
file_name_pattern: sdccc/src/**/*.java
file_header_encoding: utf-8
header_regex_file: .github/license-check/header-MIT-draeger-java.txt
header_regex_file_encoding: utf-8
9 changes: 0 additions & 9 deletions .github/license-check/license-config.json

This file was deleted.

8 changes: 4 additions & 4 deletions .github/workflows/license-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ jobs:
steps:
# Run `git checkout`
- uses: actions/checkout@v3
- uses: viperproject/check-license-header@v1
- uses: maximilianpilz/file-header-check@v1
with:
path: .
config: .github/license-check/license-config.json
strict: false # <boolean indicating whether files not covered by the configuration should be reported as errors>
config: '.github/license-check/license-config'
config-encoding: 'utf-8'
log-level: 'DEBUG'
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- a command line parameter to change the log level threshold of the log file

### Fixed

- a performance issue with xml unmarshalling due to finding an interface implementation for TransformerFactory
- slowdown and high memory usage due to large unfiltered logs, filter can be configured, default shrinks the log
- autocommit of the database being on, it is now always off
- local address resolver sometimes giving a wrong address
- local address resolver doing a probe which may not be tolerated by some peers
- potential NullPointerException in DescriptionModificationUptPrecondition.

## [8.0.1] - 2023-09-13
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ The following command line options are supported by the test tool, the first two
| device_bed | bed | the bed of the target provider, overrides setting from configuration if provided | no |
| ipaddress | ip | ip address of the adapter to use for communication, overrides setting from configuration if provided | no |
| test_run_directory | d | base directory to store test runs in, creates a timestamped SDCcc run | no |
| file_log_level | fll | log level to be used for the log file being created, e.g. DEBUG, defaults to INFO | no |

### Enabling Tests
The *test_configuration.toml* file contains the identifiers of all implemented requirement tests. It is located in the
Expand All @@ -233,7 +234,8 @@ be changed with the command line argument `test_run_directory` (see Section **Ru
saved in that folder. Each test run gets its own directory named according to the scheme
*SDCcc-Testrun_YYYY-MM-DDTHH-mm-SS*. Inside this directory there is a subdirectory *Database* and three files
*SDCcc.log*, *TEST-SDCcc_direct.xml* and *TEST-SDCcc_invariant.xml*. *Database* is a database in which all messages
exchanged during the test run are recorded. *SDCcc.log* is the complete log file of the test run. The test results
exchanged during the test run are recorded. *SDCcc.log* is the complete log file of the test run
in accordance to the log file log level. The test results
are located in the two result XML files, *TEST-SDCcc_direct.xml* for the direct tests and *TEST-SDCcc_invariant.xml*
for the invariant tests.

Expand Down
118 changes: 70 additions & 48 deletions sdccc/src/main/java/com/draeger/medical/sdccc/TestSuite.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* This Source Code Form is subject to the terms of the MIT License.
* Copyright (c) 2023 Draegerwerk AG & Co. KGaA.
* Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA.
*
* SPDX-License-Identifier: MIT
*/
Expand Down Expand Up @@ -620,70 +620,92 @@ public static void setupSwingTheme()
* @param args array of command line arguments
*/
public static void main(final String[] args) throws IOException {
// improve xml interaction performance
setSystemProperties();

// parse command line options
final var cmdLine = new CommandLineOptions(args);

// setup logging
final var testRunDir = TestRunConfig.createTestRunDirectory(
cmdLine.getTestRunDirectory().orElse(null));
final var logConfig = LoggingConfigurator.loggerConfig(testRunDir);
final var logConfig = LoggingConfigurator.loggerConfig(testRunDir, cmdLine.getFileLogLevel());
checkLogConfig(logConfig);

Configurator.initialize(logConfig);
final var ctx = (LoggerContext) LogManager.getContext(false);
ctx.setConfiguration(logConfig);
ctx.updateLoggers();
// we can only log this after setting up the logger
LOG.info("Using test run directory {}", testRunDir);
try (final var ignored = Configurator.initialize(logConfig)) {
final var ctx = (LoggerContext) LogManager.getContext(false);
ctx.setConfiguration(logConfig);
ctx.updateLoggers();
// we can only log this after setting up the logger
LOG.info("Using test run directory {}", testRunDir);

try {
setupSwingTheme();
} catch (final ClassNotFoundException
| UnsupportedLookAndFeelException
| InstantiationException
| IllegalAccessException e) {
LOG.warn("Error while setting swing look and feel options.", e);
}
try {
setupSwingTheme();
} catch (final ClassNotFoundException
| UnsupportedLookAndFeelException
| InstantiationException
| IllegalAccessException e) {
LOG.warn("Error while setting swing look and feel options.", e);
}

final Injector injector = createTestRunInjector(cmdLine, testRunDir);
final Injector injector = createTestRunInjector(cmdLine, testRunDir);

final TriggerOnErrorOrWorseLogAppender triggerOnErrorOrWorseLogAppender =
findTriggerOnErrorOrWorseLogAppender(logConfig);
if (triggerOnErrorOrWorseLogAppender == null) {
// should never happen
throw new IllegalStateException("Could not find an TriggerOnErrorOrWorseLogAppender in the logConfig.");
}
triggerOnErrorOrWorseLogAppender.setOnErrorOrWorseHandler((LogEvent event) -> {
final TestRunObserver testRunObserver = injector.getInstance(TestRunObserver.class);
// stop observing the logs
triggerOnErrorOrWorseLogAppender.setOnErrorOrWorseHandler(null);
// invalidate test run
testRunObserver.invalidateTestRun("TriggerOnErrorOrWorseLogAppender observed an ERROR or worse."
+ " Invalidating TestRun."
+ " Please see the Log for more Details.");
});

String versionString =
triggerOnErrorOrWorseLogAppender.getClass().getPackage().getImplementationVersion();
if (versionString != null) {
versionString = " version " + versionString;
} else {
versionString = "";
}
LOG.info("Starting SDCcc {}", versionString);
final TriggerOnErrorOrWorseLogAppender triggerOnErrorOrWorseLogAppender =
findTriggerOnErrorOrWorseLogAppender(logConfig);
if (triggerOnErrorOrWorseLogAppender == null) {
// should never happen
throw new IllegalStateException("Could not find an TriggerOnErrorOrWorseLogAppender in the logConfig.");
}
triggerOnErrorOrWorseLogAppender.setOnErrorOrWorseHandler((LogEvent event) -> {
final TestRunObserver testRunObserver = injector.getInstance(TestRunObserver.class);
// stop observing the logs
triggerOnErrorOrWorseLogAppender.setOnErrorOrWorseHandler(null);
// invalidate test run
testRunObserver.invalidateTestRun("TriggerOnErrorOrWorseLogAppender observed an ERROR or worse."
+ " Invalidating TestRun."
+ " Please see the Log for more Details.");
});

String versionString =
triggerOnErrorOrWorseLogAppender.getClass().getPackage().getImplementationVersion();
if (versionString != null) {
versionString = " version " + versionString;
} else {
versionString = "";
}
LOG.info("Starting SDCcc {}", versionString);

try {
try {

InjectorTestBase.setInjector(injector);
final var testSuite = injector.getInstance(TestSuite.class);
TestSuite.exit(testSuite.runTestSuite(), false, injector, testRunDir);
} catch (final RuntimeException | Error e) {
InjectorTestBase.setInjector(injector);
final var testSuite = injector.getInstance(TestSuite.class);
TestSuite.exit(testSuite.runTestSuite(), false, injector, testRunDir);
} catch (final RuntimeException | Error e) {

LOG.error("Unchecked exception while setting up or running the TestSuite", e);
TestSuite.exit(0, true, injector, testRunDir);
LOG.error("Unchecked exception while setting up or running the TestSuite", e);
TestSuite.exit(0, true, injector, testRunDir);
}
}
}

private static void setSystemProperties() {
System.setProperty(
"javax.xml.xpath.XPathFactory:http://java.sun.com/jaxp/xpath/dom",
"com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl");
System.setProperty(
"javax.xml.stream.XMLEventFactory", "com.sun.xml.internal.stream.events.XMLEventFactoryImpl");
System.setProperty("javax.xml.stream.XMLInputFactory", "com.sun.xml.internal.stream.XMLInputFactoryImpl");
System.setProperty(
"javax.xml.parsers.DocumentBuilderFactory",
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
System.setProperty(
"javax.xml.validation.SchemaFactory:http://www.w3.org/2001/XMLSchema",
"com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory");
System.setProperty(
"javax.xml.parsers.SAXParserFactory", "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
}

private static TriggerOnErrorOrWorseLogAppender findTriggerOnErrorOrWorseLogAppender(
final BuiltConfiguration logConfig) {
for (Map.Entry<String, Appender> entry : logConfig.getAppenders().entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* This Source Code Form is subject to the terms of the MIT License.
* Copyright (c) 2023 Draegerwerk AG & Co. KGaA.
* Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA.
*
* SPDX-License-Identifier: MIT
*/
Expand All @@ -21,6 +21,7 @@
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Expand All @@ -41,6 +42,7 @@ public class CommandLineOptions {
private static final String DEVICE_LOCATION_BED = "device_bed";
private static final String IP_ADDRESS = "ipaddress";
private static final String TEST_RUN_DIRECTORY = "test_run_directory";
private static final String FILE_LOG_LEVEL = "file_log_level";
private final Path configPath;
private final Path testConfigPath;
private final String deviceEpr;
Expand All @@ -52,6 +54,7 @@ public class CommandLineOptions {
private final String deviceBed;
private final String ipAddress;
private final String testRunDirectory;
private final Level fileLogLevel;

/**
* Parse the command line options passed.
Expand Down Expand Up @@ -96,6 +99,7 @@ public CommandLineOptions(final String[] commandLineArguments) {
this.deviceBed = cmd.getOptionValue(DEVICE_LOCATION_BED);
this.ipAddress = cmd.getOptionValue(IP_ADDRESS);
this.testRunDirectory = cmd.getOptionValue(TEST_RUN_DIRECTORY);
this.fileLogLevel = Level.toLevel(cmd.getOptionValue(FILE_LOG_LEVEL), Level.INFO);
}

private Options setupOptions() {
Expand Down Expand Up @@ -172,6 +176,12 @@ private Options setupOptions() {
testRunDirectoryOpt.setRequired(false);
options.addOption(testRunDirectoryOpt);
}
{
final String description = "The log level to be used for the log file. e.g. DEBUG . The default is INFO.";
final var fileLogLevelOpt = new Option("fll", FILE_LOG_LEVEL, true, description);
fileLogLevelOpt.setRequired(false);
options.addOption(fileLogLevelOpt);
}

return options;
}
Expand Down Expand Up @@ -233,6 +243,10 @@ public Optional<String> getTestRunDirectory() {
return Optional.ofNullable(testRunDirectory);
}

public Level getFileLogLevel() {
return this.fileLogLevel;
}

private static void printNetworkAdapterInformation() throws SocketException {
System.out.println("%nAvailable network adapters are:%n");
final Iterator<NetworkInterface> networkInterfaceIterator =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* This Source Code Form is subject to the terms of the MIT License.
* Copyright (c) 2023 Draegerwerk AG & Co. KGaA.
* Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA.
*
* SPDX-License-Identifier: MIT
*/
Expand All @@ -15,6 +15,7 @@
import com.draeger.medical.sdccc.messages.guice.ManipulationInfoFactory;
import com.draeger.medical.sdccc.messages.guice.MessageFactory;
import com.draeger.medical.sdccc.sdcri.CustomCryptoSettings;
import com.draeger.medical.sdccc.sdcri.LocalAddressResolverImpl;
import com.draeger.medical.sdccc.sdcri.testclient.TestClient;
import com.draeger.medical.sdccc.sdcri.testclient.TestClientImpl;
import com.draeger.medical.sdccc.util.junit.guice.XmlReportFactory;
Expand All @@ -24,6 +25,7 @@
import com.google.inject.Singleton;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import org.somda.sdc.dpws.crypto.CryptoSettings;
import org.somda.sdc.dpws.network.LocalAddressResolver;

/**
* Module which provides default guice bindings for SDCcc.
Expand All @@ -44,5 +46,6 @@ protected void configure() {
bind(ClassUtil.class).to(ClassUtilImpl.class);
bind(HibernateConfig.class).to(HibernateConfigImpl.class).in(Singleton.class);
bind(Manipulations.class).to(GRpcManipulations.class).in(Singleton.class);
bind(LocalAddressResolver.class).to(LocalAddressResolverImpl.class).in(Singleton.class);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* This Source Code Form is subject to the terms of the MIT License.
* Copyright (c) 2023 Draegerwerk AG & Co. KGaA.
* Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA.
*
* SPDX-License-Identifier: MIT
*/
Expand Down Expand Up @@ -67,6 +67,7 @@ public Configuration getConfiguration() {
config.setProperty(Environment.ORDER_UPDATES, TRUE_SETTING_VALUE);
config.setProperty(Environment.ORDER_INSERTS, TRUE_SETTING_VALUE);
config.setProperty(Environment.BATCH_VERSIONED_DATA, TRUE_SETTING_VALUE);
config.setProperty(Environment.AUTOCOMMIT, FALSE_SETTING_VALUE);

config.addAnnotatedClass(HTTPHeaderEntity.class);
config.addAnnotatedClass(MdibVersionGroupEntity.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* This Source Code Form is subject to the terms of the MIT License.
* Copyright (c) 2024 Draegerwerk AG & Co. KGaA.
*
* SPDX-License-Identifier: MIT
*/

package com.draeger.medical.sdccc.sdcri;

import com.draeger.medical.sdccc.configuration.TestSuiteConfig;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import java.util.Optional;
import org.somda.sdc.dpws.network.LocalAddressResolver;

/**
* Implementation of {@linkplain LocalAddressResolver} that uses the configured address.
*/
@Singleton
public class LocalAddressResolverImpl implements LocalAddressResolver {
private final String adapterAddress;

@Inject
LocalAddressResolverImpl(@Named(TestSuiteConfig.NETWORK_INTERFACE_ADDRESS) final String adapterAddress) {
this.adapterAddress = adapterAddress;
}

@Override
public Optional<String> getLocalAddress(final String remoteUri) {
return Optional.of(adapterAddress);
}
}
Loading

0 comments on commit 68b95d1

Please sign in to comment.