From 923ea79719f55fe499f57196da907f4fea907690 Mon Sep 17 00:00:00 2001 From: aram price Date: Fri, 10 Jul 2026 17:16:24 -0700 Subject: [PATCH] Remove fakefs gem from bosh-director Replace all FakeFS usage in unit specs with Dir.mktmpdir-based real filesystem isolation and allow(File).to receive stubs, so the gem can be dropped entirely. Changes per file: - spec/support/file_helpers.rb: replace FakeFS::FileSystem.clone and fake-file creation with allow(File).to receive(:read) stubs for cert paths read from the YAML fixture (so stubs stay aligned if fixture changes) - external_cpi_spec.rb, external_cpi_response_wrapper_spec.rb: use a real tmpdir for the CPI task log directory; remove FileUtils.mkdir_p on the fake /var/vcap path - config_spec.rb, instance_spec.rb, snapshot_manager_spec.rb: remove FakeFS::SpecHelpers (configure_fake_config_files now uses stubs) - rendered_templates_writer_spec.rb: write rendered templates into a real Dir.mktmpdir instead of the hardcoded /out path - compressed_rendered_job_templates_spec.rb: scope Dir.mktmpdir-backed tmpdir to the #contents and #sha1 contexts; #write uses a static path since all filesystem operations are mocked there - task_remover_spec.rb: create task output dirs under a real tmpdir; update Dir[] assertions accordingly; use File.exist? instead of Dir[...].to_not be_nil (Dir[] returns Array, never nil); remove FakeFS.deactivate!/activate! - ssh_spec.rb: remove FakeFS entirely (Jobs::Ssh performs no filesystem I/O - it writes results via TaskDBWriter to the DB) - Gemfile, bosh-director.gemspec: drop fakefs dependency - Gemfile.lock: updated by bundle install --- src/Gemfile | 1 - src/Gemfile.lock | 2 -- src/bosh-director/bosh-director.gemspec | 1 - .../spec/support/file_helpers.rb | 12 +++---- .../director/api/snapshot_manager_spec.rb | 4 +-- .../bosh/director/api/task_remover_spec.rb | 13 +++---- .../spec/unit/bosh/director/config_spec.rb | 34 +++++++++---------- .../compressed_rendered_job_templates_spec.rb | 26 +++++++------- .../rendered_templates_writer_spec.rb | 16 ++++----- .../director/deployment_plan/instance_spec.rb | 4 +-- .../spec/unit/bosh/director/jobs/ssh_spec.rb | 3 -- .../external_cpi_response_wrapper_spec.rb | 8 ++--- .../spec/unit/clouds/external_cpi_spec.rb | 10 +++--- src/vendor/cache/fakefs-3.2.1.gem | 3 -- 14 files changed, 56 insertions(+), 81 deletions(-) delete mode 100644 src/vendor/cache/fakefs-3.2.1.gem diff --git a/src/Gemfile b/src/Gemfile index 85143d52307..d3c8399d1ad 100644 --- a/src/Gemfile +++ b/src/Gemfile @@ -17,7 +17,6 @@ group :development, :test do gem 'async-rspec' gem 'factory_bot' - gem 'fakefs' gem 'minitar' gem 'rspec' gem 'simplecov', require: false diff --git a/src/Gemfile.lock b/src/Gemfile.lock index 2b0cdcc369e..8795b762af6 100644 --- a/src/Gemfile.lock +++ b/src/Gemfile.lock @@ -155,7 +155,6 @@ GEM tzinfo factory_bot (6.6.0) activesupport (>= 6.1.0) - fakefs (3.2.1) ffi (1.17.4) fiber-annotation (0.2.0) fiber-local (1.1.0) @@ -355,7 +354,6 @@ DEPENDENCIES bosh-nats-sync! bundle-audit factory_bot - fakefs minitar mysql2 parallel_tests diff --git a/src/bosh-director/bosh-director.gemspec b/src/bosh-director/bosh-director.gemspec index b199c4219cf..98ef456f512 100644 --- a/src/bosh-director/bosh-director.gemspec +++ b/src/bosh-director/bosh-director.gemspec @@ -59,7 +59,6 @@ Gem::Specification.new do |spec| spec.add_dependency 'tzinfo-data' spec.add_dependency 'unix-crypt' - spec.add_development_dependency 'fakefs' spec.add_development_dependency 'factory_bot' spec.add_development_dependency 'minitar' spec.add_development_dependency 'rack-test' diff --git a/src/bosh-director/spec/support/file_helpers.rb b/src/bosh-director/spec/support/file_helpers.rb index 57f4b6ff775..081f38a3b2f 100644 --- a/src/bosh-director/spec/support/file_helpers.rb +++ b/src/bosh-director/spec/support/file_helpers.rb @@ -21,12 +21,12 @@ def add_file(filepath, contents = nil) end end - def configure_fake_config_files(config_path) - FakeFS::FileSystem.clone(config_path) - FileUtils.mkdir_p('/path/to') - File.write('/path/to/server_ca_path','server_ca_path') - File.write('/path/to/client_ca_certificate_path','client_ca_certificate_path') - File.write('/path/to/client_ca_private_key_path','client_ca_private_key_path') + def stub_config_file_reads(config_path) + nats_config = YAML.safe_load(File.read(config_path))['nats'] + allow(File).to receive(:read).and_call_original + allow(File).to receive(:read).with(nats_config['server_ca_path']).and_return('server_ca_path') + allow(File).to receive(:read).with(nats_config['client_ca_certificate_path']).and_return('client_ca_certificate_path') + allow(File).to receive(:read).with(nats_config['client_ca_private_key_path']).and_return('client_ca_private_key_path') end end end diff --git a/src/bosh-director/spec/unit/bosh/director/api/snapshot_manager_spec.rb b/src/bosh-director/spec/unit/bosh/director/api/snapshot_manager_spec.rb index 8f4aa016b06..42cf54777bc 100644 --- a/src/bosh-director/spec/unit/bosh/director/api/snapshot_manager_spec.rb +++ b/src/bosh-director/spec/unit/bosh/director/api/snapshot_manager_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require 'fakefs/spec_helpers' module Bosh::Director describe Api::SnapshotManager do @@ -127,12 +126,11 @@ module Bosh::Director end describe 'class methods' do - include FakeFS::SpecHelpers let(:config_path) { asset_path('test-director-config.yml') } let(:config) { YAML.load_file(config_path) } before do - configure_fake_config_files(config_path) + stub_config_file_reads(config_path) Config.configure(config) allow(Config).to receive(:enable_snapshots).and_return(true) diff --git a/src/bosh-director/spec/unit/bosh/director/api/task_remover_spec.rb b/src/bosh-director/spec/unit/bosh/director/api/task_remover_spec.rb index 170f0f2276d..4c2bf7ca72a 100644 --- a/src/bosh-director/spec/unit/bosh/director/api/task_remover_spec.rb +++ b/src/bosh-director/spec/unit/bosh/director/api/task_remover_spec.rb @@ -1,14 +1,14 @@ require 'spec_helper' -require 'fakefs/spec_helpers' require 'bosh/director/api/task_remover' module Bosh::Director::Api describe TaskRemover do - include FakeFS::SpecHelpers + let(:task_output_dir) { Dir.mktmpdir } + after { FileUtils.rm_rf(task_output_dir) } def make_n_tasks(num_tasks, task_type: default_type, checkpoint_time: inside_retention, deployment: 'deployment1') num_tasks.times do |i| - task = FactoryBot.create(:models_task, state: 'done', output: "/director/tasks/#{task_type}_#{i}", checkpoint_time: checkpoint_time, deployment_name: deployment, type: task_type) + task = FactoryBot.create(:models_task, state: 'done', output: "#{task_output_dir}/#{task_type}_#{i}", checkpoint_time: checkpoint_time, deployment_name: deployment, type: task_type) FileUtils.mkpath(task.output) end end @@ -141,11 +141,8 @@ def tasks before do FactoryBot.create(:models_task, state: 'done', output: nil) - FakeFS.deactivate! end - after { FakeFS.activate! } - it 'does not fail' do expect do remover.remove(default_type) @@ -267,9 +264,9 @@ def tasks it 'removes files belonging to task' do expect { remover.remove_task(first_task) } - .to change { Dir["/director/tasks/#{default_type}_*"].count }.from(2).to(1) + .to change { Dir["#{task_output_dir}/#{default_type}_*"].count }.from(2).to(1) - expect(Dir['/director/tasks/type_1']).to_not be_nil + expect(File.exist?("#{task_output_dir}/#{default_type}_1")).to be true end it 'does not fail when called multiple times on the same task, writes a debug log' do diff --git a/src/bosh-director/spec/unit/bosh/director/config_spec.rb b/src/bosh-director/spec/unit/bosh/director/config_spec.rb index 34298d1b901..60e8b2ab74c 100644 --- a/src/bosh-director/spec/unit/bosh/director/config_spec.rb +++ b/src/bosh-director/spec/unit/bosh/director/config_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require 'fakefs/spec_helpers' # # This supplants the config_old_spec.rb behavior. We are @@ -7,30 +6,31 @@ # describe Bosh::Director::Config do - include FakeFS::SpecHelpers let(:test_config_path) { asset_path('test-director-config.yml') } let(:test_config) { YAML.safe_load(File.read(test_config_path)) } let(:temp_dir) { Dir.mktmpdir } + let(:blobstore_dir) do + File.join(temp_dir, 'blobstore').tap {|dir| FileUtils.mkdir_p(dir)} + end let(:base_config) do - blobstore_dir = File.join(temp_dir, 'blobstore') - FileUtils.mkdir_p(blobstore_dir) - - config = YAML.safe_load(File.read(test_config_path)) - config['dir'] = temp_dir - config['blobstore'] = { - 'provider' => 'local', - 'options' => { - 'blobstore_path' => blobstore_dir, - }, - } - config['snapshots']['enabled'] = true - config + YAML.safe_load(File.read(test_config_path)).tap do |config| + config['dir'] = temp_dir + config['blobstore'] = { + 'provider' => 'local', + 'options' => { + 'blobstore_path' => blobstore_dir, + }, + } + config['snapshots']['enabled'] = true + end end before do - configure_fake_config_files(test_config_path) + stub_config_file_reads(test_config_path) end + after { FileUtils.rm_rf(temp_dir) } + describe 'initialization' do it 'loads config from a yaml file' do config = described_class.load_file(asset_path('test-director-config.yml')) @@ -461,8 +461,6 @@ { 'blobstore_path' => blobstore_dir } end - after { FileUtils.rm_rf(temp_dir) } - describe 'authentication configuration' do let(:test_config) { base_config.merge('user_management' => { 'provider' => provider }) } diff --git a/src/bosh-director/spec/unit/bosh/director/core/templates/compressed_rendered_job_templates_spec.rb b/src/bosh-director/spec/unit/bosh/director/core/templates/compressed_rendered_job_templates_spec.rb index 25e7eee5715..d957cf80510 100644 --- a/src/bosh-director/spec/unit/bosh/director/core/templates/compressed_rendered_job_templates_spec.rb +++ b/src/bosh-director/spec/unit/bosh/director/core/templates/compressed_rendered_job_templates_spec.rb @@ -1,13 +1,13 @@ require 'spec_helper' -require 'fakefs/spec_helpers' require 'bosh/director/core/templates/compressed_rendered_job_templates' require 'bosh/director/core/templates/rendered_job_template' module Bosh::Director::Core::Templates describe CompressedRenderedJobTemplates do - subject { described_class.new('/tmp/file-path') } - describe '#write' do + let(:tmp_file_path) { '/tmp/fake-compressed-output' } + subject { described_class.new(tmp_file_path) } + let(:rendered_job_template) do instance_double( 'Bosh::Director::Core::Templates::RenderedJobTemplate', @@ -30,19 +30,20 @@ module Bosh::Director::Core::Templates [rendered_job_template], '/tmp/path/for/non-compressed/templates').ordered expect(tar_gzipper).to receive(:compress).with( - '/tmp/path/for/non-compressed/templates', %w(.), '/tmp/file-path').ordered + '/tmp/path/for/non-compressed/templates', %w(.), tmp_file_path).ordered subject.write([rendered_job_template]) end end describe '#contents' do - include FakeFS::SpecHelpers - - before { Dir.mkdir('/tmp') } + let(:tmpdir) { Dir.mktmpdir } + let(:tmp_file_path) { File.join(tmpdir, 'file-path') } + after { FileUtils.rm_rf(tmpdir) } + subject { described_class.new(tmp_file_path) } context 'when file exists' do - before { File.open('/tmp/file-path', 'w') { |f| f.write('fake-content') } } + before { File.write(tmp_file_path, 'fake-content') } it 'returns IO object for given path' do expect(subject.contents.readlines).to eq(['fake-content']) @@ -59,12 +60,13 @@ module Bosh::Director::Core::Templates end describe '#sha1' do - include FakeFS::SpecHelpers - - before { Dir.mkdir('/tmp') } + let(:tmpdir) { Dir.mktmpdir } + let(:tmp_file_path) { File.join(tmpdir, 'file-path') } + after { FileUtils.rm_rf(tmpdir) } + subject { described_class.new(tmp_file_path) } context 'when file exists' do - before { File.open('/tmp/file-path', 'w') { |f| f.write("fake-content\n") } } + before { File.write(tmp_file_path, "fake-content\n") } it 'returns sha1 of contents at given path' do expect(subject.sha1).to eq('ce0962ad2eeee3cab242191bc5ea6122c2ec8e36') diff --git a/src/bosh-director/spec/unit/bosh/director/core/templates/rendered_templates_writer_spec.rb b/src/bosh-director/spec/unit/bosh/director/core/templates/rendered_templates_writer_spec.rb index 88ec93acb26..6e36f1b6cba 100644 --- a/src/bosh-director/spec/unit/bosh/director/core/templates/rendered_templates_writer_spec.rb +++ b/src/bosh-director/spec/unit/bosh/director/core/templates/rendered_templates_writer_spec.rb @@ -1,13 +1,10 @@ require 'spec_helper' -require 'fakefs/spec_helpers' require 'bosh/director/core/templates/rendered_templates_writer' require 'bosh/director/core/templates/rendered_job_template' require 'bosh/director/core/templates/rendered_file_template' module Bosh::Director::Core::Templates describe RenderedTemplatesWriter do - include FakeFS::SpecHelpers - let(:rendered_file_template) do instance_double('Bosh::Director::Core::Templates::RenderedFileTemplate', dest_filepath: 'bin/script-filename', @@ -32,17 +29,16 @@ module Bosh::Director::Core::Templates subject(:rendered_templates_writer) { RenderedTemplatesWriter.new } - before do - FileUtils.mkdir_p('/out') - end + let(:tmpdir) { Dir.mktmpdir } + after { FileUtils.rm_rf(tmpdir) } describe '#write' do it 'writes the rendered templates to the provided directory' do - rendered_templates_writer.write([rendered_template], '/out') + rendered_templates_writer.write([rendered_template], tmpdir) - expect(File.read('/out/job-template-name/monit')).to eq('monit file contents') - expect(File.read('/out/job-template-name/bin/script-filename')).to eq('script file contents') - expect(File.read('/out/job-template-name/config/with/deeper/path/filename.cfg')).to eq('config file contents') + expect(File.read(File.join(tmpdir, 'job-template-name', 'monit'))).to eq('monit file contents') + expect(File.read(File.join(tmpdir, 'job-template-name', 'bin', 'script-filename'))).to eq('script file contents') + expect(File.read(File.join(tmpdir, 'job-template-name', 'config', 'with', 'deeper', 'path', 'filename.cfg'))).to eq('config file contents') end end end diff --git a/src/bosh-director/spec/unit/bosh/director/deployment_plan/instance_spec.rb b/src/bosh-director/spec/unit/bosh/director/deployment_plan/instance_spec.rb index eaaa47da089..b6f16a85c61 100644 --- a/src/bosh-director/spec/unit/bosh/director/deployment_plan/instance_spec.rb +++ b/src/bosh-director/spec/unit/bosh/director/deployment_plan/instance_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require 'fakefs/spec_helpers' module Bosh::Director::DeploymentPlan describe Instance do @@ -495,7 +494,6 @@ module Bosh::Director::DeploymentPlan end describe '#update_instance_settings' do - include FakeFS::SpecHelpers let(:config_path) { asset_path('test-director-config.yml') } let(:config) { YAML.load_file(config_path) } @@ -516,7 +514,7 @@ module Bosh::Director::DeploymentPlan let(:vm) { instance_model.active_vm } before do - configure_fake_config_files(config_path) + stub_config_file_reads(config_path) Bosh::Director::Config.configure(config) allow(instance_model).to receive(:active_persistent_disks).and_return(active_persistent_disks) allow(Bosh::Director::AgentClient).to receive(:with_agent_id) diff --git a/src/bosh-director/spec/unit/bosh/director/jobs/ssh_spec.rb b/src/bosh-director/spec/unit/bosh/director/jobs/ssh_spec.rb index 46e381efc95..75c7342a051 100644 --- a/src/bosh-director/spec/unit/bosh/director/jobs/ssh_spec.rb +++ b/src/bosh-director/spec/unit/bosh/director/jobs/ssh_spec.rb @@ -1,10 +1,7 @@ require 'spec_helper' -require 'fakefs/spec_helpers' module Bosh::Director describe Jobs::Ssh do - include FakeFS::SpecHelpers - subject(:job) do described_class.new(deployment.id, 'target' => target, 'command' => 'fake-command', 'params' => { 'user' => 'user-ssh' }) end diff --git a/src/bosh-director/spec/unit/clouds/external_cpi_response_wrapper_spec.rb b/src/bosh-director/spec/unit/clouds/external_cpi_response_wrapper_spec.rb index 2b1a79f8aae..fe125946e6f 100644 --- a/src/bosh-director/spec/unit/clouds/external_cpi_response_wrapper_spec.rb +++ b/src/bosh-director/spec/unit/clouds/external_cpi_response_wrapper_spec.rb @@ -1,14 +1,14 @@ require 'spec_helper' -require 'fakefs/spec_helpers' describe Bosh::Clouds::ExternalCpiResponseWrapper do - include FakeFS::SpecHelpers + let(:tmpdir) { Dir.mktmpdir } + after { FileUtils.rm_rf(tmpdir) } let(:cpi_response) { JSON.dump(result: nil, error: nil, log: '') } let(:cpi_error) { 'fake-stderr-data' } let(:additional_expected_args) { nil } let(:exit_status) { instance_double('Process::Status', exitstatus: 0) } - let(:cpi_log_path) { '/var/vcap/task/5/cpi' } + let(:cpi_log_path) { File.join(tmpdir, 'cpi') } let(:logger) { double(:logger, debug: nil) } let(:config) { double('Bosh::Director::Config', logger: logger, cpi_task_log: cpi_log_path, preferred_cpi_api_version: 3) } @@ -48,7 +48,6 @@ def self.it_should_raise_error(method, error_type, error_msg, *arguments) before do allow(File).to receive(:executable?).with('/path/to/fake-cpi/bin/cpi').and_return(true) - FileUtils.mkdir_p('/var/vcap/task/5') allow(Open3).to receive(:popen3).and_yield(stdin, stdout, stderr, wait_thread) allow(Random).to receive(:rand).and_return('fake-request-id') end @@ -65,7 +64,6 @@ def self.it_calls_cpi_method(method, *arguments) before do allow(File).to receive(:executable?).with('/path/to/fake-cpi/bin/cpi').and_return(true) - FileUtils.mkdir_p('/var/vcap/task/5') allow(Open3).to receive(:popen3).and_yield(stdin, stdout, stderr, wait_thread) allow(Random).to receive(:rand).and_return('fake-request-id') end diff --git a/src/bosh-director/spec/unit/clouds/external_cpi_spec.rb b/src/bosh-director/spec/unit/clouds/external_cpi_spec.rb index dd030ef6ac1..90679efd9c6 100644 --- a/src/bosh-director/spec/unit/clouds/external_cpi_spec.rb +++ b/src/bosh-director/spec/unit/clouds/external_cpi_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' -require 'fakefs/spec_helpers' describe Bosh::Clouds::ExternalCpi do - include FakeFS::SpecHelpers + let(:tmpdir) { Dir.mktmpdir } + after { FileUtils.rm_rf(tmpdir) } subject(:external_cpi) { described_class.new('/path/to/fake-cpi/bin/cpi', 'fake-director-uuid', logger) } @@ -16,11 +16,10 @@ def self.it_calls_cpi_method(method, *arguments, api_version: 1) let(:method) { method } let(:cpi_response) { JSON.dump(result: nil, error: nil, log: '') } let(:cpi_error) { 'fake-stderr-data' } - let(:cpi_log_path) { '/var/vcap/task/5/cpi' } + let(:cpi_log_path) { File.join(tmpdir, 'cpi') } let(:logger) { double(:logger, debug: nil, info: nil) } let(:config) { double('Bosh::Director::Config', logger: logger, cpi_task_log: cpi_log_path) } before { stub_const('Bosh::Director::Config', config) } - before { FileUtils.mkdir_p('/var/vcap/task/5') } let(:wait_thread) do double('Process::Waiter', value: double('Process::Status', exitstatus: exit_status)) @@ -647,14 +646,13 @@ def self.it_raises_an_error_with_ok_to_retry(error_class) context 'Fix for a deadlock scenario when a cpi sub-process sends an incomplete line (missing "\n") to STDOUT' do let(:logger) { Logging::Logger.new('ExternalCpi') } - let(:cpi_log_path) { '/var/vcap/task/5/cpi' } + let(:cpi_log_path) { File.join(tmpdir, 'cpi') } let(:config) { double('Bosh::Director::Config', logger: logger, cpi_task_log: cpi_log_path) } let(:external_cpi_executable) { File.expand_path('../../assets/bin/dummy_cpi', __dir__) } let(:external_cpi) { described_class.new(external_cpi_executable, 'fake-director-uuid', logger) } before do stub_const('Bosh::Director::Config', config) - FileUtils.mkdir_p('/var/vcap/task/5') allow(File).to receive(:executable?).with(external_cpi_executable).and_return(true) allow(Open3).to receive(:popen3).and_wrap_original do |original_method, *args, &block| # We need to make sure Open3.popen3 gets called with a env path where ruby exists. diff --git a/src/vendor/cache/fakefs-3.2.1.gem b/src/vendor/cache/fakefs-3.2.1.gem deleted file mode 100644 index 68de5eafee4..00000000000 --- a/src/vendor/cache/fakefs-3.2.1.gem +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ea4cdd9dc891136cf232a7f586defaeb664e7947b0ddde213bf455dc42a4fdea -size 32768