Testcontainers FTP容器与真实服务器路径导航不一致问题求助
解决Testcontainers FTP容器与真实服务器路径导航不一致的问题
问题描述
测试连接公共FTP并获取文件名的类时,遇到目录结构相同但Testcontainers FTP容器与真实服务器路径导航行为不一致的情况:
- 真实服务器中,调用
ftp.changeWorkingDirectory("/out/published")可成功切换目录;但在Testcontainers容器中该方法返回false,必须改用相对路径ftp.changeWorkingDirectory("out/published")才能生效。 - 真实服务器上执行
ftp.listNames("/out/published/tverskaya_obl/purchaseNotice/daily")能正常获取文件列表;但容器中仅能使用相对路径ftp.listNames("tverskaya_obl/purchaseNotice/daily")成功。
测试代码
创建Testcontainers容器和目录的代码如下:
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @SpringBootTest(properties = "ftp.host = localhost") class PurchaseFZ223FtpServiceTest { private static final int PORT = 21; private static final String USER = ""; private static final String PASSWORD = ""; private static final int PASSIVE_MODE_PORT = 21000; @Autowired FtpService ftpService; private static final FixedHostPortGenericContainer ftp = new FixedHostPortGenericContainer<>( "delfer/alpine-ftp-server:latest") .withFixedExposedPort(PASSIVE_MODE_PORT, PASSIVE_MODE_PORT) .withExposedPorts(PORT) .withEnv("USERS", USER + "|" + PASSWORD) .withEnv("MIN_PORT", String.valueOf(PASSIVE_MODE_PORT)) .withEnv("MAX_PORT", String.valueOf(PASSIVE_MODE_PORT)); @BeforeAll void init() throws NoSuchFieldException, IllegalAccessException, IOException { ftp.start(); FTPClient client =new FTPClient(); client.connect("localhost", ftp.getMappedPort(PORT)); client.enterLocalPassiveMode(); client.login(USER, PASSWORD); client.makeDirectory("out"); client.makeDirectory("out/published"); client.makeDirectory("out/published/tverskaya_obl"); client.makeDirectory("out/published/tverskaya_obl/purchaseNotice"); client.makeDirectory("out/published/tverskaya_obl/purchaseNotice/daily"); client.changeWorkingDirectory("out/published"); client.storeFile("list_regions.txt", new ByteArrayInputStream("tverskaya_obl".getBytes(StandardCharsets.UTF_8))); client.changeWorkingDirectory("tverskaya_obl/purchaseNotice/daily"); client.storeFile("purchaseNotice_Tverskaya_obl_20221209_000000_20221209_235959_daily_001.xml.txt", new ByteArrayInputStream("test".getBytes(StandardCharsets.UTF_8))); } }
问题原因
你使用的delfer/alpine-ftp-server容器默认会给用户开启chroot jail限制,用户登录后默认处于专属的家目录(如/home/<user>),所有路径都会被限制在这个目录内。而真实FTP服务器可能未开启chroot,或者根目录直接映射到系统根路径,因此绝对路径/out/published在真实服务器中指向系统根下的目录,在容器中却会被解析为用户家目录外的路径,自然无法找到。
解决办法
方案1:修改容器配置,禁用chroot限制
添加CHROOT=false环境变量,关闭容器的chroot限制,让用户登录后直接处于系统根目录,这样容器的路径行为就和真实服务器一致:
private static final FixedHostPortGenericContainer ftp = new FixedHostPortGenericContainer<>( "delfer/alpine-ftp-server:latest") .withFixedExposedPort(PASSIVE_MODE_PORT, PASSIVE_MODE_PORT) .withExposedPorts(PORT) .withEnv("USERS", USER + "|" + PASSWORD) .withEnv("MIN_PORT", String.valueOf(PASSIVE_MODE_PORT)) .withEnv("MAX_PORT", String.valueOf(PASSIVE_MODE_PORT)) .withEnv("CHROOT", "false"); // 新增该行禁用chroot
方案2:统一测试中的路径处理逻辑
若不想修改容器配置,可在测试代码中统一使用相对路径,或者先获取用户当前工作目录,再基于该目录构建路径:
// 登录后获取当前工作目录 String currentWorkingDir = client.printWorkingDirectory(); // 后续操作统一使用相对路径,或基于currentWorkingDir拼接绝对路径
内容的提问来源于stack exchange,提问作者user19282140
相关产品推荐
相关产品推荐

