Back to Repositories

Testing Procfile Management Implementation in ddollar/foreman

This test suite validates the functionality of Foreman’s Procfile handling, focusing on file loading, parsing, and manipulation capabilities. The tests ensure robust processing of process definitions and proper error handling in the Foreman process manager.

Test Coverage Overview

The test suite provides comprehensive coverage of Procfile operations including:

Key functionality tested:
  • File loading and parsing
  • Process entry manipulation
  • File writing capabilities
  • Error handling for empty files
Edge cases covered include empty Procfile validation, non-existent entry retrieval, and various process name formats including hyphens and underscores.

Implementation Analysis

The testing approach utilizes RSpec’s behavior-driven development framework with FakeFS for file system isolation. The tests employ a systematic pattern of arranging test data, performing operations, and verifying outcomes using RSpec expectations. Technical implementation includes mock file operations, instance variable inspection, and regex-based entry validation.

Technical Details

Testing tools and configuration:
  • RSpec for test framework
  • FakeFS for file system simulation
  • Pathname and tmpdir libraries for file handling
  • Custom helper methods for Procfile writing
The suite uses RSpec’s described_class feature for flexible class referencing and subject blocks for test instance management.

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Isolated test environments using FakeFS
  • Consistent test structure and naming
  • Comprehensive error case coverage
  • Clear separation of setup and assertions
  • Efficient test data management

ddollar/foreman

spec/foreman/procfile_spec.rb

            
require 'spec_helper'
require 'foreman/procfile'
require 'pathname'
require 'tmpdir'

describe Foreman::Procfile, :fakefs do
  subject { Foreman::Procfile.new }

  it "can load from a file" do
    write_procfile
    subject.load "Procfile"
    expect(subject["alpha"]).to eq("./alpha")
    expect(subject["bravo"]).to eq("./bravo")
  end

  it "loads a passed-in Procfile" do
    write_procfile
    procfile = Foreman::Procfile.new("Procfile")
    expect(procfile["alpha"]).to   eq("./alpha")
    expect(procfile["bravo"]).to   eq("./bravo")
    expect(procfile["foo-bar"]).to eq("./foo-bar")
    expect(procfile["foo_bar"]).to eq("./foo_bar")
  end

  it "raises an error if Procfile is empty" do
    write_file "Procfile" do |procfile|
      procfile.puts
    end

    expect { Foreman::Procfile.new("Procfile") }.to raise_error described_class::EmptyFileError
  end

  it 'only creates Procfile entries for lines matching regex' do
    write_procfile
    procfile = Foreman::Procfile.new("Procfile")
    keys = procfile.instance_variable_get(:@entries).map(&:first)
    expect(keys).to match_array(%w[alpha bravo foo-bar foo_bar])
  end

  it "returns nil when attempting to retrieve an non-existing entry" do
    write_procfile
    procfile = Foreman::Procfile.new("Procfile")
    expect(procfile["unicorn"]).to eq(nil)
  end

  it "can have a process appended to it" do
    subject["charlie"] = "./charlie"
    expect(subject["charlie"]).to eq("./charlie")
  end

  it "can write to a string" do
    subject["foo"] = "./foo"
    subject["bar"] = "./bar"
    expect(subject.to_s).to eq("foo: ./foo\nbar: ./bar")
  end

  it "can write to a file" do
    subject["foo"] = "./foo"
    subject["bar"] = "./bar"
    Dir.mkdir('/tmp')
    subject.save "/tmp/proc"
    expect(File.read("/tmp/proc")).to eq("foo: ./foo\nbar: ./bar\n")
  end

end