Attaching a remote host process in ByteBuddy - byte-buddy

I am new to ByteBuddy and trying to setup instrumentation for a process running on a remote process.
My remote process is started with -XX:+StartAttachListener.
Created a simple Maven project with the following in the pom.
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
<version>1.10.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy -->
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.10.7</version>
</dependency>
Created an agent class with a premain method.
public class Agent {
public static void premain(String args, Instrumentation instrumentation) {
System.out.println("Premain");
File file ;
try {
file = (new File("Agent.jar"));
ByteBuddyAgent.attach(file,"18467");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Questions:-
Do I need to generate Agent.jar here? Or else, it comes with byte-buddy?
ByteBuddyAgent.attach doesn't take the remote hostname. How can I define the remote host process to attach? Or else, byte buddy should be running in the same host where the Java process in running.
The below example to run the agent along with the jar under test.
java -javaagent:/path/to/agent.jar -cp jar-under-test.jar Foo.Main
How to run the agent attacher as a separate process to attach the java agent to a java process running on a remote host?

Remote attachment in Java is only possible not only from the same host but also only from the same OS user. This is meant as a security mechanism as it would otherwise be fairly simple to take over any Java process from a remote location.
Byte Buddy simply provides wrappers around it. You can use byte-buddy-agent.jar as your agent and attach it either to your own process (ByteBuddyAgent.install()) or to a remote one ByteBuddyAgent.attach(pid, new File("byte-buddy-agent.jar")). An instance of Instrumentation is then available via Installer class to the entire Java process. Adding byte-buddy-agent.jar to the command line has the same effect for that process.

Related

How to start WinAppDriver programmatically in the remote machine

My test setup consist of 2 windows machines, first one test runner which will have the my test code in c# and the second one test agent machine where winappdriver is installed along with application under test.
I would like to start the winappdriver in the test agent through the C# code and the code would run on the test runner. Also, I would like to close the winappdriver once test execution is over.
How this could be done? Appreciate any lead on this.
For Java specific projects: You can Do it in following ways-
Assumin WinAppDriver is installed in default location-i.e. C:/Program Files (x86)/Windows Application Driver
1st:
String command = "C:/Program Files (x86)/Windows Application Driver/WinAppDriver.exe";
Runtime.getRuntime().exec(command);
2nd:
String command = "C:/Program Files (x86)/Windows Application Driver/WinAppDriver.exe";
ProcessBuilder builder = new ProcessBuilder(command).inheritIO();
Process process = builder.start();
Dont forget to dispose it by-
winDriver.close();
winDriver.quit();
or for 2nd approach-
process.destroy();
Convert them as part of you init or BeforeTest Methods as needed.
You can use [BeforeTestRun] attribute in your Test initialize class. Assuming the winappdriver is installed in the same path in the test machines. I use it in my azure agents
[BeforeTestRun]
public static void TestSetup()
{
Process.Start(#"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe");
Process.Start(#"Your application Path");
}
After the test run, if you want to close the Winappdriver, you can use AfterTestRun Attribute. Basepage has the static instance of the WinappDriver
[AfterTestRun]
public static void TearDownReport()
{
BasePage.WindowsDriver.Close();
BasePage.WindowsDriver.Dispose();
}

Selenium navigate().to() stuck without error

I am running tests using TestNG, chromium and Selenium, in Java, on two machines:
my own laptop
a Mac Mini I do not have physical access to, that I connect via SSH, that has the same identical project structure as the project on my laptop.
Both machines operate behind the same corporate proxy.
The issue I am having is the following:
while the tests run smoothly on my machine, when I execute the command to start them on the Mac Mini, the execution stops when telling the Selenium WebDriver to navigate to any specified url using driver.navigate().to(url) or driver.get(url); causing the program to freeze without throwing any exception, essentially remaining on hold.
The code resembles the following:
in the #BeforeClass beforeClass() driver is initialized with an instance of ChromeDriver using ChromeOptions. Among other settings, I add the following arguments to the ChromeOptions like such chromeOptions.addArguments(options): where options is things like --disable-web-security, --allow-running-insecure-content, --allow-insecure-localhost and most importantly: --proxy-server=address:port (e.g. --proxy-server=172.26.44.146:3128).
in the #BeforeMethod beforeMethod() after checking that the driver is not null and that the URL url is a valid one, I execute something similar to the stylized following code:
try {
log.debug("Navigating to: " + url);
driver.navigate().to(url);
log.debug("Navigated to url: " + driver.getCurrentUrl());
} catch (Exception e) {
log.error("Unable to navigate at page: " + url.toString());
throw e;
}
As I said, when running the test on the Mac Mini via SSH using the command line in a similar fashion to: java -cp WORKSPACE org.testng.TestNG testng.xml the code stops executing and freezes at log.debug("Navigating to: " + url); essentially not producing other output and forcing me to manually stop the execution of the test.
As additional information, tests are run using chromium version 72.0.3609.0.
The ChromeOptions also receive the following proxy setting (like such: chromeOptions.setProxy(p);) where p is a Proxy with
p.setProxyType(ProxyType.MANUAL);
p.setAutodetect(false);
I suspect an issue with the proxy (and am doubtful I have correctly preconfigured the program), but, quite frankly, I am puzzled by the fact that the same script runs locally on my machine and is unable to run locally on the Mac Mini when the tests are launched via SSH.

ActiveMQ in-memory broker not starting when tests running in IntelliJ IDEA

So I'm running an integration test/spec using configuration for an ActiveMQ in-memory broker.
SomeSpec.groovy:
#SpringApplicationConfiguration(SomeApplication.class)
#WebIntegrationTest(randomPort = true)
class SomeSpec extends Specification {
application.properties
spring.activemq.in-memory=true
spring.activemq.pooled=false
The in memory broker starts up and runs fine when I do gradle test and
also runs fine when used with gradle bootRun at the command line. However when I run inside IntelliJ without explicitly having it run gradle test the in memory broker does not start and the tests fail.
How can I take and advantage of the nice test/spec running features in IntelliJ but still have it initialize the in memory queue properly? I know with Grails you could run with JUnit or Grails. Is there something similar with Spring/SpringBoot so everything starts up properly.
It's probably because your config files are not refreshed under project/out/production/config/ location.
When you run it from cmd line, it takes the latest application.properties, so every thing is fine.
But Idea takes the already compiled config files, and if they are not rebuilt inside Idea then it still loads the load configuration.

Jenkins plugin - environment variables

I am using Jenkins with Testswarm and this plugin (forked sources).
I want to get a "job name" for Testswarm containing the Jenkins job name, build number and svn revision number.
Putting JOB_NAME in the configuration field does not help, the variable is not replaced by its value.
So I modified the plugin source code to get the Jenkins environment variables but all I get are "null"s.
Here is the culprit code. (in src/main/java/com/javaclimber/jenkins/testswarmplugin/TestSwarmBuilder.java from line 205)
I researched a lot concerning this functionnality and I did not find a working example for getting a variable.
public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
...
EnvVars envVars = build.getEnvironment(listener);
...
envVars.get("JOB_NAME")
}
I am not at ease in Java and I am stuck at this point.
Any idea anyone, please ?
Update: java used version
java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.5) (6b24-1.11.5-0ubuntu1~10.04.2)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
Replacing
EnvVars envVars = build.getEnvironment(listener);
By
EnvVars envVars = new EnvVars();
envVars = build.getEnvironment(listener);
did the trick...
What version of Java are you using?
According to this, to get an environment variable, you need to add the following:
String job_name = System.getenv("JOB_NAME");
Have you tried this instead?
Also, I'm not sure what the configuration field looks like, but did you try using $JOB_NAME instead of JOB_NAME ?
Jenkins pipelines appear to execute on the server, so the original post may be missing a variable defined for the agent (either via the server's agent definition or via the agent's OS).
I don't know the Jenkins pipeline way of obtaining the agent's environment.
I stumbled over this and searched a while for a solution, so for the next user the answer: If you need the environment variables, overwrite
public void perform(Run<?, ?> run, FilePath workspace, EnvVars env, Launcher launcher, TaskListener listener)
instead of
public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener)
and use the EnvVars from the parameters. (See also https://issues.jenkins.io/browse/JENKINS-29144)

Running ScalaTest in IntelliJ removes everything but idea_rt.jar from classpath

I am trying to run a ScalaTest test case from IntelliJ
I specify the class path to use in the run/debug configuration dialogue and this appears to work ok.
However, if I try to interrogate this classpath using System.getProperty("java.class.path")
I only get the idea_rt.jar
This wouldn't be a problem except I am trying to do this inside an Integration test:
val execArgs = Array("java",
"-classpath",
System.getProperty("java.class.path"),
mainClass,
args)
val process = Runtime.getRuntime.exec(execArgs)
And, of course, my mainClass is not found.
My config.
scalatest_2.9.2-1.8.RC1
IntelliJ IDEA 11.1.3
scala-library-2.9.2
scala plugin version 0.5.977
Try to edit bin/idea.properties or Info.plist if you are on Mac, set this to true:
#---------------------------------------------------------------------
# Configure if a special launcher should be used when running processes from within IDE.
# Using Launcher enables "soft exit" and "thread dump" features
#---------------------------------------------------------------------
idea.no.launcher=true