require 'unit_helper' require 'vagrant' require 'vagrant-lxc/container' describe Vagrant::LXC::Container do let(:name) { nil } subject { described_class.new(name) } describe 'container name validation' do let(:unknown_container) { described_class.new('unknown', cli) } let(:valid_container) { described_class.new('valid', cli) } let(:new_container) { described_class.new(nil) } let(:cli) { fire_double('Vagrant::LXC::Container::CLI', list: ['valid']) } it 'raises a NotFound error if an unknown container name gets provided' do expect { unknown_container.validate! }.to raise_error(Vagrant::LXC::Container::NotFound) end it 'does not raise a NotFound error if a valid container name gets provided' do expect { valid_container.validate! }.to_not raise_error(Vagrant::LXC::Container::NotFound) end it 'does not raise a NotFound error if nil is provider as name' do expect { new_container.validate! }.to_not raise_error(Vagrant::LXC::Container::NotFound) end end describe 'creation' do let(:name) { 'random-container-name' } let(:template_name) { 'template-name' } let(:rootfs_cache) { '/path/to/cache' } let(:public_key_path) { Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s } let(:cli) { fire_double('Vagrant::LXC::Container::CLI', :create => true, :name= => true) } subject { described_class.new(name, cli) } before do SecureRandom.stub(hex: name) subject.create 'template-name' => template_name, 'rootfs-cache-path' => rootfs_cache, 'template-opts' => { '--foo' => 'bar'} end it 'creates container with the right arguments' do cli.should have_received(:create).with( template_name, '--auth-key' => public_key_path, '--cache' => rootfs_cache, '--foo' => 'bar' ) end end describe 'destruction' do let(:name) { 'container-name' } let(:cli) { fire_double('Vagrant::LXC::Container::CLI', destroy: true) } subject { described_class.new(name, cli) } before { subject.destroy } it 'delegates to cli object' do cli.should have_received(:destroy) end end describe 'start' do let(:config) { mock(:config, start_opts: ['a=1', 'b=2']) } let(:name) { 'container-name' } let(:cli) { fire_double('Vagrant::LXC::Container::CLI', start: true) } subject { described_class.new(name, cli) } before do cli.stub(:transition_to).and_yield(cli) end it 'starts container with configured lxc settings' do cli.should_receive(:start).with(['a=1', 'b=2'], nil) subject.start(config) end it 'expects a transition to running state to take place' do cli.should_receive(:transition_to).with(:running) subject.start(config) end end describe 'halt' do let(:name) { 'container-name' } let(:cli) { fire_double('Vagrant::LXC::Container::CLI', shutdown: true) } subject { described_class.new(name, cli) } before do cli.stub(:transition_to).and_yield(cli) end it 'delegates to cli shutdown' do cli.should_receive(:shutdown) subject.halt end it 'expects a transition to running state to take place' do cli.should_receive(:transition_to).with(:stopped) subject.halt end end describe 'state' do let(:name) { 'random-container-name' } let(:cli_state) { :something } let(:cli) { fire_double('Vagrant::LXC::Container::CLI', state: cli_state) } subject { described_class.new(name, cli) } it 'delegates to cli' do subject.state.should == cli_state end end describe 'assigned ip' do # This ip is set on the sample-arp-output fixture based on mac address from # sample-config fixture let(:ip) { "10.0.3.30" } let(:conf_file_contents) { File.read('spec/fixtures/sample-config') } let(:name) { 'random-container-name' } context 'when container mac address gets returned from the first `arp` call' do before do @arp_output = File.read('spec/fixtures/sample-arp-output') subject.stub(:raw) { mock(stdout: "#{@arp_output}\n", exit_code: 0) } File.stub(read: conf_file_contents) end it 'gets parsed from `arp` based on lxc mac address' do subject.assigned_ip.should == ip subject.should have_received(:raw).with('arp', '-n') end end pending 'when mac address is not returned from an `arp` call' end end