gpt4 book ai didi

ruby - 使用Serverspec进行空的gem缓存检查失败,以进行Docker镜像构建测试

转载 作者:行者123 更新时间:2023-12-02 20:07:43 25 4
gpt4 key购买 nike

我目前在通过Serverspec测试Docker镜像构建时遇到问题。简而言之,我想做的是确保在图像构建期间明确清除Ruby gems构建缓存,例如通过在Dockerfile中发布rm -rf /usr/lib/ruby/gems/*/cache/*.gem

我正在使用的Dockerfile骨架如下所示:

 # Dockerfile

FROM alpine:3.7

RUN apk add --no-cache \
dumb-init \
ruby \
&& apk add --no-cache --virtual .build-deps \
build-base \
ruby-dev

RUN gem install --no-rdoc --no-ri json \
&& gem install --no-rdoc --no-ri oj

RUN apk del .build-deps \
&& rm -rf /var/cache/apk/* \
/tmp/* /var/tmp/*

在添加gem cache remove命令之前,我实现了以下Serverspec测试,以便能够从失败的测试开始:
 # ./spec/Dockerfile_spec.rb

describe "Dockerfile" do
before(:all) do
@image = Docker::Image.build_from_dir('.')
@image.tag(repo: 'demo', tag: 'latest')

set :os, family: :alpine
set :backend, :docker
set :docker_image, @image.id
end


it "removes build dependencies during cleanup" do
# Some more assertions
# ...
expect(Dir.glob('/usr/lib/ruby/gems/*/cache/*.gem').size).to eq 0
end
end

假设上面的Dockerfile,测试运行为绿色:
 $ bundle exec rspec spec/Dockerfile_spec.rb
....
Finished in 3.95 seconds (files took 0.24091 seconds to load)
4 examples, 0 failures

但是,情况并非如此,因为gem缓存尚未清除,因此不为空,即我希望相应的断言在测试执行期间失败。

通过从新生成的镜像启动容器并检查gems缓存目录,可以轻松地验证这一点:
 $ docker run --rm -it demo:latest sh
/ # ls /usr/lib/ruby/gems/2.4.0/cache/
json-2.1.0.gem oj-3.4.0.gem

进行另一种测试并期望使用非空目录,执行失败并显示错误消息:
 # ./spec/Dockerfile.rb

it "removes build dependencies during cleanup" do
# Some more assertions
# ...
expect(Dir.glob('/usr/lib/ruby/gems/*/cache/*.gem').size).to_not eq 0
end


# Command line

$ bundle exec rspec spec/Dockerfile_spec.rb
.F..

Failures:

1) Dockerfile removes build dependencies during cleanup
Failure/Error: expect(Dir.glob('/usr/lib/ruby/gems/*/cache/*.gem').size).to_not eq 0

expected: value != 0
got: 0

(compared using ==)

因此,很明显, Dir.glob()命令在gems缓存目录中未返回正确数量的文件。

有趣的是,在容器内手动运行 Dir.glob()命令会返回预期结果:
 $ docker run --rm -it demo:latest sh
/ # apk add --no-cache ruby-irb
...
/ # irb
irb(main):001:0> Dir.glob('/usr/lib/ruby/gems/*/cache/*.gem').size
=> 2

首先,这使我认为测试不是在容器内而是在主机上正确执行的,但是进一步的实验无法证实这一点。

你有什么主意吗这可能是Serverspec / Rspec问题吗?

谢谢!

编辑

First, this made me think that the test is not properly executed within the container but on the host instead, but further experiments could not confirm this.



我终于发现这个假设是错误的。实际上,无论出于何种原因, Dir.glob()调用都是在容器外部执行的。

最佳答案

我终于弄清楚出了什么问题,实际上很简单:

假设我们有一个像这样的Serverspec测试用例:

it "removes build dependencies during cleanup" do
# Some more assertions
# ...
expect(Dir.glob('/usr/lib/ruby/gems/*/cache/*.gem').size).to_not eq 0
end

现在在执行过程中发生的是,在调用 Dir.glob()例程之前先评估 expect()调用。因此,正如我在帖子中已经指出的那样, Dir.glob()命令在容器范围之外运行,而是检查相应的主机目录。
如果要检查容器文件夹是否为空,则可以按以下步骤实现:
it "clears gem/apk caches as well as tmp files/dirs" do
expect(command('ls /usr/lib/ruby/gems/*/cache/*.gem | wc -l').stdout).to eq "0\n"
end

诚然,这可能不是最漂亮,最优雅的解决方案,但基本上可以完成工作。如果您还有其他想法和建议,请随时发布。

关于ruby - 使用Serverspec进行空的gem缓存检查失败,以进行Docker镜像构建测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48644823/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com