Skip to content

Commit

Permalink
#8 Added test setup for debugging in UDFs (#9)
Browse files Browse the repository at this point in the history
* #8 Added test setup for debugging in UDFs

Co-authored-by: Muhammet Orazov <[email protected]>
  • Loading branch information
jakobbraun and morazow authored Oct 28, 2020
1 parent 1a34f85 commit 599cf57
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 16 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,30 @@ This repository contains tools for debugging UDFs.
Install as maven dependency.
You can get the dependency declaration by clicking the maven badge above.

## Typical Usage

Typically, you use this package together with [test-db-builder-java](https://github.com/exasol/test-db-builder-java) and [exasol-testcontainers](https://github.com/exasol/exasol-testcontainers) as follows:

```java
final UdfTestSetup udfTestSetup = new UdfTestSetup(getTestHostIp());
final ExasolObjectFactory testDbBuilder = new ExasolObjectFactory(EXASOL.createConnection(),
ExasolObjectConfiguration.builder().withJvmOptions(udfTestSetup.getJvmOptions()).build());
```

## Modules

This package contains multiple modules that you can enable on runtime by setting the corresponding system property to `true`.
Typically, you do so by appending `-D<PROPERTY_NAME>="true"` to your JVM call.


### Debugging

System property: `test.debug`

This module instructs the UDF JVMs to connect to a Java debugger listening on the default port 8000 on you machine, running the tests.


## Additional Information

* [Changelog](doc/changes/changelog.md)
* [Dependencies](NOTICE)
* [Dependencies](NOTICE)
5 changes: 3 additions & 2 deletions doc/changes/changes_0.2.0.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# udf-debugging-java 0.2.0, released 2020-XX-XX
# udf-debugging-java 0.2.0, released 2020-10-28

Code name:
Code name: Test setup for UDF debugging

## Features / Enhancements

* #5: Sonar Cloud setup
* #6: Changed default value of getSelectionThatIsSentToTheAdapter to empty string
* #8: Added test setup for debugging in UDFs

## Dependency Updates:

Expand Down
33 changes: 20 additions & 13 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@
<version>${jacoco.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down Expand Up @@ -362,19 +368,20 @@
<configuration>
<noticeTemplate>NOTICE.template</noticeTemplate>
<licenseMapping>
<param>https://source.jasig.org/licenses/license-mappings.xml</param>
</licenseMapping>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>-->
<licenseMapping>
<param>https://source.jasig.org/licenses/license-mappings.xml</param>
</licenseMapping>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
-->
</plugins>
<testResources>
<testResource>
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/exasol/udfdebugging/Module.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.exasol.udfdebugging;

import java.util.stream.Stream;

public interface Module {

public Stream<String> getJvmOptions();
}
26 changes: 26 additions & 0 deletions src/main/java/com/exasol/udfdebugging/ModuleFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.exasol.udfdebugging;

public interface ModuleFactory {

/**
* Get if this module is enabled by system property.
*
* @return {@code true} if this module is enabled
*/
public boolean isEnabled();

/**
* Get the name of the property to enable this module.
*
* @return name of the property to enable this module
*/
public String getModulePropertyName();

/**
* Build the {@link Module}.
*
* @param testHostIpAddress IP address of the host running this UDF Test Setup under which UDFs can reach it
* @return built {@link Module}
*/
public Module buildModule(final String testHostIpAddress);
}
55 changes: 55 additions & 0 deletions src/main/java/com/exasol/udfdebugging/UdfTestSetup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.exasol.udfdebugging;

import java.util.List;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.exasol.udfdebugging.modules.debugging.DebuggingModuleFactory;

/**
* Test setup for testing UDFs in the database.
*/
public class UdfTestSetup {
private static final List<ModuleFactory> AVAILABLE_MODULES = List.of(new DebuggingModuleFactory());
private static final Logger LOGGER = LoggerFactory.getLogger(UdfTestSetup.class);
private final List<Module> enabledModules;

/**
* Create a new instance of {@link UdfTestSetup}.
*
* @param testHostIpAddress IP address of the host running this UDF Test Setup under which UDFs can reach it
*/
public UdfTestSetup(final String testHostIpAddress) {
this.enabledModules = AVAILABLE_MODULES.stream().filter(ModuleFactory::isEnabled)
.map(moduleFactory -> moduleFactory.buildModule(testHostIpAddress)).collect(Collectors.toList());
printInfoMessage();
}

/**
* Get JVM options required for this setup.
*
* @return array of JVM options
*/
public String[] getJvmOptions() {
return this.enabledModules.stream().flatMap(Module::getJvmOptions).toArray(String[]::new);
}

private void printInfoMessage() {
if (LOGGER.isInfoEnabled()) {
LOGGER.info(getInfoMessage());
}
}

private String getInfoMessage() {
final StringBuilder messageBuilder = new StringBuilder("Udf Test Setup Configuration:\n");
AVAILABLE_MODULES.forEach(module -> {
messageBuilder.append(module.getModulePropertyName());
messageBuilder.append(":\t");
messageBuilder.append(module.isEnabled() ? "enabled" : "disabled");
messageBuilder.append("\n");
});
return messageBuilder.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.exasol.udfdebugging.modules;

import com.exasol.udfdebugging.Module;
import com.exasol.udfdebugging.ModuleFactory;

/**
* Abstract basis for {@link Module}.
*/
public abstract class AbstractModuleFactory implements ModuleFactory {
private final String moduleProperty;

/**
* Create a new instance of {@link AbstractModuleFactory}.
*
* @param moduleName name of the module
*/
protected AbstractModuleFactory(final String moduleName) {
this.moduleProperty = "test." + moduleName;
}

@Override
public final boolean isEnabled() {
return System.getProperty(this.moduleProperty, "false").equals("true");
}

@Override
public String getModulePropertyName() {
return this.moduleProperty;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.exasol.udfdebugging.modules.debugging;

import java.util.stream.Stream;

import com.exasol.udfdebugging.Module;

public class DebuggingModule implements Module {
public static final String DEBUGGING_PORT = "8000";
private final String testHostIpAddress;

/**
* Create a new instance of {@link DebuggingModule}.
*
* @param testHostIpAddress IP address of the host running this UDF Test Setup under which UDFs can reach it
*/
public DebuggingModule(final String testHostIpAddress) {
this.testHostIpAddress = testHostIpAddress;
}

@Override
public Stream<String> getJvmOptions() {
return Stream.of("-agentlib:jdwp=transport=dt_socket,server=n,address=" + this.testHostIpAddress + ":"
+ DEBUGGING_PORT + ",suspend=y");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.exasol.udfdebugging.modules.debugging;

import com.exasol.udfdebugging.Module;
import com.exasol.udfdebugging.modules.AbstractModuleFactory;

public class DebuggingModuleFactory extends AbstractModuleFactory {
/**
* Create a new instance of {@link DebuggingModuleFactory}.
*/
public DebuggingModuleFactory() {
super("debug");
}

@Override
public Module buildModule(final String testHostIpAddress) {
return new DebuggingModule(testHostIpAddress);
}
}
39 changes: 39 additions & 0 deletions src/test/java/com/exasol/udfdebugging/UdfTestSetupTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.exasol.udfdebugging;

import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;

import java.util.Arrays;
import java.util.List;

import org.junit.jupiter.api.Test;

class UdfTestSetupTest {
public static final String DEBUG_PROPERTY = "test.debug";
private static final String EXPECTED_DEBUG_JVM_OPTION = "-agentlib:jdwp=transport=dt_socket,server=n,address=1.2.3.4:8000,suspend=y";

@Test
void testDebuggingEnabled() {
System.setProperty(DEBUG_PROPERTY, "true");
final UdfTestSetup udfTestSetup = new UdfTestSetup("1.2.3.4");
final List<String> jvmOptions = Arrays.asList(udfTestSetup.getJvmOptions());
assertThat(jvmOptions, hasItem(EXPECTED_DEBUG_JVM_OPTION));
}

@Test
void testDebuggingIsDisabledByDefault() {
System.clearProperty(DEBUG_PROPERTY);
final UdfTestSetup udfTestSetup = new UdfTestSetup("1.2.3.4");
final List<String> jvmOptions = Arrays.asList(udfTestSetup.getJvmOptions());
assertThat(jvmOptions, not(hasItem(EXPECTED_DEBUG_JVM_OPTION)));
}

@Test
void testDebuggingDisabled() {
System.setProperty(DEBUG_PROPERTY, "false");
final UdfTestSetup udfTestSetup = new UdfTestSetup("1.2.3.4");
final List<String> jvmOptions = Arrays.asList(udfTestSetup.getJvmOptions());
assertThat(jvmOptions, not(hasItem(EXPECTED_DEBUG_JVM_OPTION)));
}
}

0 comments on commit 599cf57

Please sign in to comment.