#! /usr/bin/env ruby require 'spec_helper' require 'puppet/ssl/inventory' describe Puppet::SSL::Inventory, :unless => Puppet.features.microsoft_windows? do let(:cert_inventory) { File.expand_path("/inven/tory") } before do @class = Puppet::SSL::Inventory end describe "when initializing" do it "should set its path to the inventory file" do Puppet[:cert_inventory] = cert_inventory @class.new.path.should == cert_inventory end end describe "when managing an inventory" do before do Puppet[:cert_inventory] = cert_inventory Puppet::FileSystem.stubs(:exist?).with(cert_inventory).returns true @inventory = @class.new @cert = mock 'cert' end describe "and creating the inventory file" do it "re-adds all of the existing certificates" do inventory_file = StringIO.new Puppet.settings.setting(:cert_inventory).stubs(:open).yields(inventory_file) cert1 = Puppet::SSL::Certificate.new("cert1") cert1.content = stub 'cert1', :serial => 2, :not_before => Time.now, :not_after => Time.now, :subject => "/CN=smocking" cert2 = Puppet::SSL::Certificate.new("cert2") cert2.content = stub 'cert2', :serial => 3, :not_before => Time.now, :not_after => Time.now, :subject => "/CN=mocking bird" Puppet::SSL::Certificate.indirection.expects(:search).with("*").returns [cert1, cert2] @inventory.rebuild expect(inventory_file.string).to match(/\/CN=smocking/) expect(inventory_file.string).to match(/\/CN=mocking bird/) end end describe "and adding a certificate" do it "should use the Settings to write to the file" do Puppet.settings.setting(:cert_inventory).expects(:open).with("a") @inventory.add(@cert) end it "should add formatted certificate information to the end of the file" do cert = Puppet::SSL::Certificate.new("mycert") cert.content = @cert fh = StringIO.new Puppet.settings.setting(:cert_inventory).expects(:open).with("a").yields(fh) @inventory.expects(:format).with(@cert).returns "myformat" @inventory.add(@cert) expect(fh.string).to eq("myformat") end end describe "and formatting a certificate" do before do @cert = stub 'cert', :not_before => Time.now, :not_after => Time.now, :subject => "mycert", :serial => 15 end it "should print the serial number as a 4 digit hex number in the first field" do @inventory.format(@cert).split[0].should == "0x000f" # 15 in hex end it "should print the not_before date in '%Y-%m-%dT%H:%M:%S%Z' format in the second field" do @cert.not_before.expects(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').returns "before_time" @inventory.format(@cert).split[1].should == "before_time" end it "should print the not_after date in '%Y-%m-%dT%H:%M:%S%Z' format in the third field" do @cert.not_after.expects(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').returns "after_time" @inventory.format(@cert).split[2].should == "after_time" end it "should print the subject in the fourth field" do @inventory.format(@cert).split[3].should == "mycert" end it "should add a carriage return" do @inventory.format(@cert).should =~ /\n$/ end it "should produce a line consisting of the serial number, start date, expiration date, and subject" do # Just make sure our serial and subject bracket the lines. @inventory.format(@cert).should =~ /^0x.+mycert$/ end end it "should be able to find a given host's serial number" do @inventory.should respond_to(:serial) end describe "and finding a serial number" do it "should return nil if the inventory file is missing" do Puppet::FileSystem.expects(:exist?).with(cert_inventory).returns false @inventory.serial(:whatever).should be_nil end it "should return the serial number from the line matching the provided name" do File.expects(:readlines).with(cert_inventory).returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"] @inventory.serial("me").should == 15 end it "should return the number as an integer" do File.expects(:readlines).with(cert_inventory).returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"] @inventory.serial("me").should == 15 end end describe "and finding all serial numbers" do it "should return nil if the inventory file is missing" do Puppet::FileSystem.expects(:exist?).with(cert_inventory).returns false @inventory.serials(:whatever).should be_empty end it "should return the all the serial numbers from the lines matching the provided name" do File.expects(:readlines).with(cert_inventory).returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n", "0x002 blah blah /CN=me\n"] @inventory.serials("me").should == [15, 2] end end end end