java - 使用 IntelliJ 和 Gradle 调试 Elasticsearch 插件集成测试
问题描述
我正在基于这个示例构建一个 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
. 该类扩展了ESTestCase
Elasticsearch 的类,但不直接测试任何 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
它来传递调试参数,但到目前为止还没有解决这个问题。
解决方案
推荐阅读
- c# - DirectoryInfo.Exists 即使在文件夹被删除后也返回 true
- ios - 为什么 Apple 生成的强密码自动填充没有文字?
- c# - EF Core 单个 DELETE 语句
- laravel-5.8 - 数据库不存在,但在 pgsql 中存在
- javascript - 使用 Moment.js 将 UTC 日期和时间转换为本地日期和时间
- azure-iot-edge - OPC Publisher 和消息路由
- javascript - 为什么 getTime() 返回不一致的值?
- c# - 使用 C# 删除 SFTP 服务器中 zip 文件中的文件
- swift - 我无法在表格视图中插入新行
- typescript - 像控制台记者一样设置 Jasmine