Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration tests for JMX Scraper #1480

Merged
merged 12 commits into from
Oct 16, 2024

Conversation

robsunday
Copy link
Contributor

No description provided.

@robsunday robsunday changed the title Additional logger call Integration tests for JMX Scraper Oct 3, 2024
@robsunday robsunday marked this pull request as ready for review October 4, 2024 12:04
@robsunday robsunday requested a review from a team as a code owner October 4, 2024 12:04
Copy link
Contributor

@breedx-splk breedx-splk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused by this. Unless I'm missing something, you shouldn't have to find an ephemeral/open/unused port on the box running the tests -- just use a fixed port for JMX, use that fixed port in the jvm args for both rmi and jmx, and then docker itself should assign an ephemeral port on the outside surface of the container.

That's what the getMappedPort() then does for you -- it lets you know what external port docker assigned to the fixed internal port. Make sense?

With that, I think you can just delete the PortSelector class.

@SylvainJuge
Copy link
Contributor

Here we have multiple challenges, and using a fixed port mapping is a way to work-around the JMX/RMI implementation details, this is clearly not ideal and I don't know if we have a better option to test JMX with RMI. I haven't investigated deeper but it seems that using jmxmp instead of rmi protocol instead would be a better option for most integration tests.

In short:

  • setting com.sun.management.jmxremote.port=9999 will make the target JVM listen on port 9999
  • testcontainers map the 9999 JMX port to a random port, let's say 12345.
  • we build a JMX URI with localhost:12345 which allows to connect to the mapped port on the host
  • when connecting to localhost:12345 the server-side JMX implementation replies that a different host:port which in my case in Linux host is something like 172.20.0.xx:9999.
  • This host:port combination can be controlled with com.sun.management.jmxremote.rmi.port and java.rmi.server.hostname properties on the target JVM
  • this behavior is related to the RMI protocol itself and is problematic with NAT as it forces to use only a single host:port to be used at once.

Maybe here another option could also be to make sure that we have a network that is always accessible from the host like it does on Linux could be a simpler option.

@SylvainJuge
Copy link
Contributor

After failing to make things working with jmxmp, I think using a fixed port is an acceptable work-around for now:

  • it's only needed to test the JmxConnectorBuilder class with host-to-container communication, packaging the test and running it in a container would be way overkill and harder to debug in the future.
  • there is no impact on container-to-container communication for other integration tests.
  • it's simpler to have the same implementation for both mac and linux, the fact it works on Linux and in CI by default is almost "by accident"

I've opened a PR on this PR to simplify even further and reuse an available port implementation already in classpath: robsunday#1

Comment on lines -102 to -114
String targetHost = target.getHost();
Integer targetPort = target.getMappedPort(JMX_PORT);
logger.info(
"Target system started, JMX port: {} mapped to {}:{}", JMX_PORT, targetHost, targetPort);

// TODO : wait for metrics to be sent and add assertions on what is being captured
// for now we just test that we can connect to remote JMX using our client.
try (JMXConnector connector = JmxConnectorBuilder.createNew(targetHost, targetPort).build()) {
assertThat(connector.getMBeanServerConnection()).isNotNull();
} catch (IOException e) {
throw new RuntimeException(e);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[for reviewer] this part had to go anyway as it's now replaced by actual integration tests in #1485 , here it only checked the connection from the host as a proxy of "target JVM is working with JMX settings".

use fixed port for container-to-container
Comment on lines 89 to 91
// properties.put("com.sun.management.jmxremote.local.only", "false");
// properties.put("java.rmi.server.logCalls", "true");
//
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest either remove or include a code comment explaining why you may want to uncomment

Suggested change
// properties.put("com.sun.management.jmxremote.local.only", "false");
// properties.put("java.rmi.server.logCalls", "true");
//

@trask trask merged commit b0aae23 into open-telemetry:main Oct 16, 2024
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants