【问题标题】:Tests using embedded postgres fail with Illegal State Exception使用嵌入式 postgres 的测试因非法状态异常而失败
【发布时间】:2019-09-21 07:25:33
【问题描述】:

我正在使用 otj-pg-embedded 针对嵌入式 postgres 数据库运行一些测试。虽然测试在本地运行良好,但在 Gitlab-CI 以非法状态异常运行时会失败。 Gitlab CI 构建它并运行不包含 otj-pg-embedded 的测试。

我已经注释掉了大部分测试类并将问题定位到:

public static SingleInstancePostgresRule pg = EmbeddedPostgresRules.singleInstance();
import com.goldfinger.models.AuditLog;
import com.opentable.db.postgres.embedded.FlywayPreparer;
import com.opentable.db.postgres.junit.EmbeddedPostgresRules;
import com.opentable.db.postgres.junit.PreparedDbRule;
import org.junit.*;
import org.junit.runner.RunWith;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
public class SQLAuditRepositoryTest {

    private static SQLAuditRepository sqlAuditRepository;
    private static AuditLog auditLog_1;
    private static AuditLog auditLog_2;
    private static AuditLog auditLog_3;
    private static List<AuditLog> auditLogList;

    @ClassRule
        public static SingleInstancePostgresRule pg = EmbeddedPostgresRules.singleInstance();


    @Test
    public void simpleTest() {
        assert (2 == 2);
    }
}

这是堆栈跟踪:

java.lang.IllegalStateException: Process [/tmp/embedded-pg/PG-06e3a92a2edb6ddd6dbdf5602d0252ca/bin/initdb, -A, trust, -U, postgres, -D, /tmp/epg6584640257265165384, -E, UTF-8] failed

    at com.opentable.db.postgres.embedded.EmbeddedPostgres.system(EmbeddedPostgres.java:626)
    at com.opentable.db.postgres.embedded.EmbeddedPostgres.initdb(EmbeddedPostgres.java:240)
...
... many lines here
...
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
    at java.lang.Thread.run(Thread.java:745)

这是 gitlab-ci.yml

image: java:latest
services:
  - postgres:latest
before_script:
  - export GRADLE_USER_HOME=`pwd`/.gradle

package:
  stage: build
  script:
    - ./gradlew assemble

test:
  stage: test
  script:
  - ./gradlew check
  artifacts:
    reports:
      junit: build/test-results/test/*.xml


任何帮助将不胜感激。

【问题讨论】:

  • 除了重启电脑,我还没有弄清楚如何停止嵌入式 Postgress 在后台运行。它有助于解决这个问题。
  • 我在 macOS 12.1 Monterey 上遇到了同样的问题,问题似乎是 postgres 的二进制文件引发了“分段错误”错误。里卡多的评论和这个讨论似乎有帮助:github.com/opentable/otj-pg-embedded/issues/…

标签: java postgresql gitlab-ci


【解决方案1】:

如果在升级到 macOS 11.x+(到 BigSur)后停止

对于 Mac 用户(尤其是新的 BigSur),已经有一个 issue 可以解决这个问题。

目前还没有一个明确的“修复”,但我已经通过安装postgresql 来解决问题:

brew install postgresql

不确定是否同样适用于其他操作系统。

【讨论】:

  • 工作。谢谢。大苏尔破坏了几件事:)
【解决方案2】:

我在 MacOS M1 上使用嵌入式 postgres 运行测试时遇到了类似问题:

java.lang.IllegalStateException: Process [/var/folders/g_/jxzv9glj0p13njlzpr9xtcfm0000gn/T/embedded-pg/PG-4f38c8a8b2500189835f8ec1b75de81b/bin/initdb, -A, trust, -U, postgres, -D, /var/folders/g_/jxzv9glj0p13njlzpr9xtcfm0000gn/T/pg-embedded-009358be-3e95-4dbe-aa7a-01a9008511cb-3277843270072134584/epg524445573999525527, -E, UTF-8] failed

我复制粘贴了命令并在 shell 上运行它:

/var/folders/g_/jxzv9glj0p13njlzpr9xtcfm0000gn/T/embedded-pg/PG-4f38c8a8b2500189835f8ec1b75de81b/bin/initdb -A trust -U postgres -D /var/folders/g_/jxzv9glj0p13njlzpr9xtcfm0000gn/T/pg-embedded-009358be-3e95-4dbe-aa7a-01a9008511cb-3277843270072134584/epg524445573999525527 -E UTF-8

输出给我一个提示:

Running bootstrap script ... 2021-02-17 08:18:21.008 WET [28692] FATAL:  could not create shared memory segment: Cannot allocate memory
2021-02-17 08:18:21.008 WET [28692] DETAIL:  Failed system call was shmget(key=5432001, size=56, 03600).
2021-02-17 08:18:21.008 WET [28692] HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter.  You might need to reconfigure the kernel with larger SHMALL.
    The PostgreSQL documentation contains more information about shared memory configuration.
child process exited with exit code 1
initdb: removing contents of data directory "/var/folders/g_/jxzv9glj0p13njlzpr9xtcfm0000gn/T/pg-embedded-cbe6f5f8-24b2-4431-afec-6e7aeb1dbb5d-8656684715588054403/epg6904898061245880853"

然后我在 shell 上运行:

sudo sysctl kern.sysv.shmmax=104857600
sudo sysctl kern.sysv.shmall=25600

它奏效了。

【讨论】:

  • 这是一个很好的调试提示,在我的例子中,它向我展示了上面关于 macos 问题的答案会有所帮助。我在调用命令后得到了这个:dyld: Library not loaded: @loader_path/../lib/libpq.5.dylib
【解决方案3】:

flyway/embedded-pg 也有同样的问题。似乎临时文件在某些​​时候变得损坏。重启会修复它(直到它再次发生)或者你可以删除/tmp/embedded-pg/中的PG-*目录

【讨论】:

    【解决方案4】:

    在 macOS 12.1 Monterey 中,我通过下载 postgres 二进制文件并让 EmbeddedPostgres 解决我描述的问题 here 解决了同样的问题

    # download binaries, here for postgres 12.9
    curl -O http://get.enterprisedb.com/postgresql/postgresql-12.9-1-osx- 
    binaries.zip --output-dir /tmp/
    
    # unzip it in /tmp/
    unzip /tmp/postgresql-12.9-1-osx-binaries.zip -d /tmp/postgresql-12.9-1-osx-binaries/
    

    然后在代码中:

    import com.opentable.db.postgres.embedded.EmbeddedPostgres;
    import java.io.File;
    
    EmbeddedPostgres pg = EmbeddedPostgres
      .builder()
      .setPgDirectoryResolver(
         dir -> new File("/tmp/postgresql-12.9-1-osx-binaries/pgsql/"))
      .start();
    

    【讨论】:

      【解决方案5】:

      Windows 用户可能会遇到类似的问题。 我的情况是尝试为嵌入式 postgres 运行集成测试:

      java.lang.IllegalStateException:进程 [C:\Users....\AppData\Local\Temp\embedded-pg\PG-02224a4f280160581d2144dec70deaf8\bin\initdb.exe, -A, 信任, -U, postgres, -D, C:\Users....\AppData\Local\Temp\epg7146074401943849308, -E, UTF-8] 失败

      当尝试从终端运行此命令时,您将遇到类似于以下 dll 库的问题:

      加载共享库时出错:msvcr120.dll: 无法打开共享 目标文件:没有这样的文件或目录

      为解决此问题,应安装 Visual C++ Redistributable Packages for Visual Studio 2013。 你可以从官方microsoft site找到它

      【讨论】:

        猜你喜欢
        • 2015-12-07
        • 2014-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多