Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ repos:
- id: check-added-large-files
- id: mixed-line-ending

- repo: https://github.com/rubocop/rubocop
rev: v1.86.2
hooks:
- id: rubocop
language_version: 3.4.7
args: ['--autocorrect', '--force-exclusion']

- repo: https://github.com/woodruffw/zizmor-pre-commit
rev: v1.25.2
hooks:
Expand Down
30 changes: 30 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
AllCops:
NewCops: enable
SuggestExtensions: false
TargetRubyVersion: 3.4

# Dockerfile_spec.rb filenames are intentional — they mirror the Dockerfile being tested
Naming/FileName:
Exclude:
- 'spec/**/*'

# Not required for a test-only project
Style/FrozenStringLiteralComment:
Enabled: false

# Spec helpers contain necessarily complex cleanup logic
Metrics/MethodLength:
Exclude:
- 'spec/**/*'

Metrics/AbcSize:
Exclude:
- 'spec/**/*'

Metrics/CyclomaticComplexity:
Exclude:
- 'spec/**/*'

Metrics/PerceivedComplexity:
Exclude:
- 'spec/**/*'
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.4.9
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
source "https://rubygems.org"
source 'https://rubygems.org'

gem 'docker-api', '~> 2.4'
gem 'rake', '~> 13.4'
Expand Down
13 changes: 7 additions & 6 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,25 @@ require 'rspec/core/rake_task'
# Enable Docker BuildKit for faster builds with better caching
ENV['DOCKER_BUILDKIT'] = '1'

task :spec => 'spec:all'
task :default => :spec
task spec: 'spec:all'
task default: :spec

namespace :spec do
targets = []
Dir.glob('./spec/*').each do |dir|
next unless File.directory?(dir)

target = File.basename(dir)
target = "_#{target}" if target == "default"
target = "_#{target}" if target == 'default'
targets << target
end

# Use multitask for parallel execution
multitask :all => targets
task :default => :all
multitask all: targets
task default: :all

targets.each do |target|
original_target = target == "_default" ? target[1..-1] : target
original_target = target == '_default' ? target[1..] : target
desc "Run serverspec tests to #{original_target}"
task target.to_sym do
# Run RSpec in a separate process with environment variable set
Expand Down
7 changes: 3 additions & 4 deletions spec/22/Dockerfile_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,20 @@
require 'node_tests'
require 'npm_tests'

tag = ENV['TARGET_HOST']
tag = ENV.fetch('TARGET_HOST', nil)

describe "#{tag}" do
describe tag.to_s do
include Helpers

before(:all) do
create_image(tag)
end

test_node("22.22.0")
test_node('22.22.0')

test_npm

after(:all) do
delete_image
end

end
7 changes: 3 additions & 4 deletions spec/24/Dockerfile_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,20 @@
require 'node_tests'
require 'npm_tests'

tag = ENV['TARGET_HOST']
tag = ENV.fetch('TARGET_HOST', nil)

describe "#{tag}" do
describe tag.to_s do
include Helpers

before(:all) do
create_image(tag)
end

test_node("24.13.0")
test_node('24.13.0')

test_npm

after(:all) do
delete_image
end

end
2 changes: 1 addition & 1 deletion spec/node_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
def test_node(version)
describe command('node -v') do
its(:exit_status) { should eq 0 }
its(:stdout) { should match /#{version}/ }
its(:stdout) { should match(/#{version}/) }
end
end
4 changes: 2 additions & 2 deletions spec/npm_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_npm
its(:exit_status) { should eq 0 }
end

describe command("echo \'{\"foo\":\"bar\"}\' | json foo") do
its(:stdout) { should match /bar/ }
describe command("echo '{\"foo\":\"bar\"}' | json foo") do
its(:stdout) { should match(/bar/) }
end
end
36 changes: 18 additions & 18 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Helpers
def create_image(version)
puts "Building image..."
puts 'Building image...'

begin
@image = Docker::Image.build_from_dir("#{version}/")
Expand All @@ -9,44 +9,44 @@ def create_image(version)
raise
end

set :os, :family => 'debian'
set :os, family: 'debian'
set :backend, :docker
set :docker_image, @image.id

puts "Running tests..."
puts 'Running tests...'
end

def delete_image
return unless @image

puts "Deleting image..."
puts 'Deleting image...'

# Remove specinfra's Docker backend finalizer before we clean up containers.
# Without this, the finalizer fires at process exit and tries to stop/delete
# containers we've already removed here, producing "Exception in finalizer" warnings.
begin
ObjectSpace.undefine_finalizer(Specinfra.backend)
rescue => e
rescue StandardError => e
puts "Warning: Could not undefine specinfra finalizer: #{e.message}"
end

# Stop and remove only containers created from this image
begin
Docker::Container.all(:all => true).each do |container|
Docker::Container.all(all: true).each do |container|
container_image = container.info['Image']
container_image_id = container.info['ImageID']

# Match image IDs - container IDs may have sha256: prefix and be full hashes
# while @image.id is the short ID
if container_image&.include?(@image.id) || container_image_id&.include?(@image.id)
begin
container.stop unless container.info['State'] == 'exited'
container.delete(:force => true)
rescue Docker::Error::NotModifiedError
# Container already stopped, ignore
rescue Docker::Error::DockerError => e
puts "Warning: Failed to cleanup container #{container.id[0..11]}: #{e.message}"
end
next unless container_image&.include?(@image.id) || container_image_id&.include?(@image.id)

begin
container.stop unless container.info['State'] == 'exited'
container.delete(force: true)
rescue Docker::Error::NotModifiedError
# Container already stopped, ignore
rescue Docker::Error::DockerError => e
puts "Warning: Failed to cleanup container #{container.id[0..11]}: #{e.message}"
end
end
rescue Docker::Error::DockerError => e
Expand All @@ -55,10 +55,10 @@ def delete_image

# Always attempt to remove the image, even if container cleanup failed
begin
@image.remove(:force => true)
puts "Image removed successfully"
@image.remove(force: true)
puts 'Image removed successfully'
rescue Docker::Error::NotFoundError
puts "Image already removed"
puts 'Image already removed'
rescue Docker::Error::DockerError => e
puts "Warning: Failed to remove image: #{e.message}"
end
Expand Down