我正在基于this example构建Elasticsearch插件。该插件使用Gradle进行构建,测试,集成测试等。我想使用IntelliJ在Elasticsearch集成测试中设置断点并对其进行调试。我不在乎是从IntelliJ内部还是在IntelliJ外部运行Gradle构建,但是现在在两种情况下我都遇到了问题。我将在下面描述我的设置和问题:
首先,我通过CLI下载并构建/测试示例项目:
$ pip install cookiecutter
$ cookiecutter gh:spinscale/cookiecutter-elasticsearch-ingest-processor
$ # keep all default settings when prompted...
$ gradle build # (also runs the test and integTest tasks)
运行正常,测试通过。我使用Gradle($ gradle idea
)生成IntelliJ项目,并在IntelliJ中将其打开(目录上显示绿色的Gradle图标)。我使用默认的gradle-wrapper选项,并在打开时保留所有其他默认值。
第一个问题:我打开IntelliJ的Gradle窗口(视图>工具窗口> Gradle),但是我看不到项目中定义的任何Gradle任务。这似乎没什么大不了的,但是拥有它们会很好。
现在,我想在IntelliJ中运行测试,因此我在org.elasticsearch.plugin.ingest.awesome.AwesomeProcessorTests
中打开测试。此类从Elasticsearch扩展了ESTestCase
类,但没有直接测试任何Elasticsearch API交互。
第二个问题:我使用班级名称旁边的绿色小三角形运行此测试班级。这将失败,并显示错误java.lang.RuntimeException: unable to install test security manager
。
我发现可以通过编辑运行配置并添加VM参数-Dtests.security.manager=false
来解决此问题。现在,简单的测试可以运行并通过,我还可以设置断点并对其进行调试。
现在,我想直接测试一些Elasticsearch功能,因此我编写了一个新的集成测试类,该类扩展了类ESIntegTestCase
。测试应该到达Elasticsearch _cat/plugins
端点,并检查响应字符串是否为非空。
public class SimpleIT extends ESIntegTestCase {
private RestClient restClient;
@Before
public void setUp() throws Exception {
super.setUp();
this.restClient = getRestClient();
}
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singletonList(IngestAwesomePlugin.class);
}
public void testPluginInstallation() throws IOException {
Response response = restClient.performRequest("GET", "_cat/plugins");
String body = EntityUtils.toString(response.getEntity());
assertTrue(body.length() > 0);
}
}
当我通过CLI(gradle integTest
)运行此命令时,测试通过。如果添加故意失败的断言(例如assertTrue(body.length() < 0
),则测试将失败。这样看来行得通。
第三个问题:当我从IntelliJ(小绿色三角形)中运行相同的测试时,出现错误:
java.lang.IllegalArgumentException: no hosts provided
at __randomizedtesting.SeedInfo.seed([6F620686489164F5:270C27B7060A2BA1]:0)
at org.elasticsearch.client.RestClientBuilder.<init>(RestClientBuilder.java:68)
at org.elasticsearch.client.RestClient.builder(RestClient.java:124)
at org.elasticsearch.test.ESIntegTestCase.createRestClient(ESIntegTestCase.java:2261)
at org.elasticsearch.test.ESIntegTestCase.createRestClient(ESIntegTestCase.java:2248)
at org.elasticsearch.test.ESIntegTestCase.createRestClient(ESIntegTestCase.java:2242)
at org.elasticsearch.test.ESIntegTestCase.getRestClient(ESIntegTestCase.java:2236)
at org.elasticsearch.plugin.ingest.awesome.SimpleIT.setUp(SimpleIT.java:36)
这映射到我称为getRestClient()
的行,这意味着IntelliJ阻止了Gradle / Elasticsearch集成测试设置,否则该设置可从CLI进行。
FWIW,我仍然可以在此行上设置断点并在IntelliJ中调试测试类,它将在该行停止。
现在,我尝试通过CLI运行集成测试,在IntelliJ中设置一个断点,并使用IntelliJ的远程调试器将其附加到测试中。
我设置了新的“远程”运行配置,并保留默认设置(传输套接字,调试器模式附加,主机localhost
,端口5005)。在“使用模块的类路径搜索源”选项中,我尝试了所有可能的设置。
我在getRestClient()
行上设置了一个断点,并通过CLI通过远程调试选项运行Gradle:
$ GRADLE_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005" gradle integTest
第四个问题:如预期的那样,Gradle进程挂起,显示Listening for transport dt_socket at address: 5005
。我在IntelliJ中启动新的远程任务,然后Gradle进程继续运行。不幸的是,它一直贯穿整个过程,并且不会在断点处停止。测试仍然通过。
我已经在网上广泛搜索了各种附加到Gradle调试器的方法。我已经看到了许多有关禁用守护程序的事情,并且我还尝试使用--system-prop
传递调试参数,但是到目前为止,没有任何方法可以解决此问题。