确保Linux中目录的可重复性


16

我经营一家托管的持续集成公司,我们在Linux上运行客户的代码。每次运行代码时,我们都在单独的虚拟机中运行它。经常出现的问题是,由于在VM上签出的代码的目录顺序,客户的测试有时会失败。

让我更详细地讲。在OSX上,HFS +文件系统可确保始终以相同顺序遍历目录。使用OSX的程序员认为,如果OSX在其计算机上可以运行,则它必须在任何地方都可以运行。但是它通常在Linux上不起作用,因为linux文件系统在遍历目录时不提供顺序保证。

例如,考虑有两个文件a.rb,b.rb。a.rb定义MyObject,而b.rb使用MyObject。如果先加载a.rb,则一切正常。如果首先加载b.rb,它将尝试访问未定义的变量MyObject,并失败。

但比这更糟糕的是,它并不总是会失败。由于未按顺序在Linux上对文件系统进行排序,因此在不同的计算机上将采用不同的顺序。情况更糟,因为有时测试通过,有时失败。这是最糟糕的结果。

所以我的问题是,有没有办法使文件系统的订购可重复。也许是ext4的标志,它表示它将始终以某种顺序遍历目录?还是其他具有此保证的文件系统?



除了真的答案-什么 “正确”的顺序?只是按字母数字排序?还是在CTIME之前?任意魔术?客户如何在部署时确保此订单?这个神奇的订单信息应该如何转移给您?
米歇尔尼克

@Michuelnik没有真正正确的顺序,但是可重复的事情意味着我们每次都得到相同的结果,这总比没有好。理想情况下,我们将使用HFS +排序,我认为这是按字母顺序排列的。
Paul Biggar

@Michuelnik这个问题对测试的影响比对部署的影响要大得多。部署通常在Linux上进行,但是如果出现故障,他们将对其进行修复。测试通常在OSX上运行,因此如果出现故障,一定是我们的错。
Paul Biggar

1
@PaulBiggar:我了解您的问题,并且我无法提供良好的解决方案(除非您可以找到一种方法来检测文件顺序是否是问题的原因)。但是我同意“可重复的成功要比不一致的失败更好”:如果我的开发(和CI)环境可以重复取得成功,但是我的部署平台具有“不可靠的失败”综合症,那么我确实处于困境。我宁愿尽快看到不可靠的故障越好(最好在我的开发系统,但至少我的CI系统)。
约阿希姆·绍尔

Answers:


16

我知道这不是您要寻找的答案,但是我相信正确的解决方案是避免依赖目录中文件的顺序。也许它在所有HFS +文件系统中始终是一致的,也许您可​​以找到一种使它在ext4或其他文件系统中保持一致的方法,但是从长远来看,这将使您付出更多的麻烦,而不是节省很多麻烦。当其他人使用您的应用程序而没有意识到它仅与某些类型的文件系统兼容而不与其他类型的文件系统兼容时,他们会感到非常讨厌。如果从备份还原文件系统,则顺序可能会更改。您可能会遇到兼容性问题,因为HFS +一致顺序和ext4一致顺序可能不相同。

只需阅读所有目录条目并按字典顺序对列表进行排序,然后再使用它。就像一样ls

您提到了文件a.rbb.rb,但是如果我们谈论的是编程语言源文件,那么每个文件是否不应该负责确保其导入所有依赖项?


问题是我们没有编写正在运行的代码。我们运行客户代码,但无法控制代码的编写方式。因此,我们的问题确实是我们为此被指责,因为它适用于他们的计算机,但不适用于我们的计算机。如果我们可以强迫所有人编写正确的代码,我们可以,但是那不在我们的能力范围内:)
Paul Biggar 2012年

10
@PaulBiggar:但不是“它运行在这里,但不是在生产中” 究竟是CI应该解决这一问题?换句话说:“为什么我的代码在您的系统中中断?” 应该回答“因为我们正在按照您的要求做!” ;-)
Joachim Sauer 2012年

4
我对其他人一无所知,但是当代码在我的计算机上工作然后在CI或同事的结帐失败时,我立即认为我需要修复某些与平台或环境相关的内容……
matt5784

1
确定在您不会在生产中使用的平台上开发应用程序是一个坏主意吗?让他们在与他们正在编写的平台上进行开发。
马修·伊夫

2
我不同意。我认为这是个好主意。从开发到测试服务器的迁移过程中会出现更多的故障。因此,在将代码移至生产服务器之前,代码要坚固得多。因此,在一个正确的或理论上的世界中,情况要好得多。在这个世界上,您可以强迫每个人编写正确的代码,也称为梦境。
Hennes

5

Linux readdir()中的POSIX调用不能保证任何一致的顺序。如果需要排序的结果,则处理文件的应用程序负责排序如何将它们呈现给调用函数。

/programming/8977441/does-readdir-guarantee-an-order

现在,既然您说的是客户的代码,并且无法修复,则可以更改用于提供一致readdir()调用的链接库。那将需要一些工作,值得提出自己的问题。有关此内容的快速参考,请参见http://www.ibm.com/developerworks/linux/library/l-glibc/index.html

更改此设置可能会产生其他一些我可能无法预见的问题。强烈警告您,但是如果您的客户不能接受适当的教育,则可能是一种解决方案。


1

告知您的客户,应明确说明其固有的订单依赖性。提供帮助客户以一种在所有系统上都可以进行编译的方式来表达依赖关系,并让客户采用捕获编译顺序依赖关系的更改流程。

如果客户希望能够在其他计算机上进行编译,则认为它们是免费的会令他们感到恼火。


我们肯定会这样做。但是,如果他们实际上成为我们的客户,这将很有用,以便我们能够做到这一点。
Paul Biggar

0

现代Linux(ext4)为文件列表添加了B树索引。他的作用之一是默认文件顺序取决于其名称的哈希值。

要禁用此功能,请使用:

tune2fs -O ^ dir_index

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.