describe LinuxAdmin::Disk do describe "#local" do it "returns local disks" do expect(Dir).to receive(:glob).with(['/dev/[vhs]d[a-z]', '/dev/xvd[a-z]']). and_return(['/dev/hda', '/dev/sda']) disks = LinuxAdmin::Disk.local paths = disks.collect { |disk| disk.path } expect(paths).to include('/dev/hda') expect(paths).to include('/dev/sda') end end describe "#size" do it "uses fdisk" do disk = LinuxAdmin::Disk.new :path => '/dev/hda' expect(disk).to receive(:run!). with(disk.cmd(:fdisk), :params => {"-l" => nil}). and_return(double(:output => "")) disk.size end it "returns disk size" do fdisk = <<eos Disk /dev/hda: 500.1 GB, 500107862016 bytes 255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x3ddb508b Device Boot Start End Blocks Id System 1 1259MB 81.8GB 80.5GB primary ntfs 2 81.8GB 162GB 80.5GB primary ext4 3 162GB 163GB 1074MB logical linux-swap(v1) eos disk = LinuxAdmin::Disk.new :path => '/dev/hda' allow(disk).to receive(:run!).and_return(double(:output => fdisk)) expect(disk.size).to eq(500_107_862_016) end end describe "#partitions" do it "uses parted" do disk = LinuxAdmin::Disk.new :path => '/dev/hda' expect(disk).to receive(:run). with(disk.cmd(:parted), :params => { nil => %w(--script /dev/hda print) }).and_return(double(:output => "")) disk.partitions end it "returns [] on non-zero parted rc" do disk = LinuxAdmin::Disk.new :path => '/dev/hda' expect(disk).to receive(:run).and_return(double(:output => "", :exit_status => 1)) expect(disk.partitions).to eq([]) end it "sets partitons" do partitions = <<eos Model: ATA TOSHIBA MK5061GS (scsi) Disk /dev/sda: 500GB Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 1259MB 81.8GB 80.5GB primary ntfs 2 81.8GB 162GB 80.5GB primary ext4 3 162GB 163GB 1074MB logical linux-swap(v1) eos disk = LinuxAdmin::Disk.new expect(disk).to receive(:run).and_return(double(:output => partitions)) expect(disk.partitions[0].id).to eq(1) expect(disk.partitions[0].disk).to eq(disk) expect(disk.partitions[0].size).to eq(80.5.gigabytes) expect(disk.partitions[0].start_sector).to eq(1259.megabytes) expect(disk.partitions[0].end_sector).to eq(81.8.gigabytes) expect(disk.partitions[0].partition_type).to eq('primary') expect(disk.partitions[0].fs_type).to eq('ntfs') expect(disk.partitions[1].id).to eq(2) expect(disk.partitions[1].disk).to eq(disk) expect(disk.partitions[1].size).to eq(80.5.gigabytes) expect(disk.partitions[1].start_sector).to eq(81.8.gigabytes) expect(disk.partitions[1].end_sector).to eq(162.gigabytes) expect(disk.partitions[1].partition_type).to eq('primary') expect(disk.partitions[1].fs_type).to eq('ext4') expect(disk.partitions[2].id).to eq(3) expect(disk.partitions[2].disk).to eq(disk) expect(disk.partitions[2].size).to eq(1074.megabytes) expect(disk.partitions[2].start_sector).to eq(162.gigabytes) expect(disk.partitions[2].end_sector).to eq(163.gigabytes) expect(disk.partitions[2].partition_type).to eq('logical') expect(disk.partitions[2].fs_type).to eq('linux-swap(v1)') end end describe "#create_partitions" do before(:each) do @disk = LinuxAdmin::Disk.new(:path => '/dev/hda') end it "dispatches to create_partition" do expect(@disk).to receive(:create_partition).with("primary", "0%", "50%") @disk.create_partitions "primary", :start => "0%", :end => "50%" end context "multiple partitions specified" do it "calls create_partition for each partition" do expect(@disk).to receive(:create_partition).with("primary", "0%", "49%") expect(@disk).to receive(:create_partition).with("primary", "50%", "100%") @disk.create_partitions("primary", {:start => "0%", :end => "49%"}, {:start => "50%", :end => "100%"}) end context "partitions overlap" do it "raises argument error" do expect{ @disk.create_partitions("primary", {:start => "0%", :end => "50%"}, {:start => "49%", :end => "100%"}) }.to raise_error(ArgumentError) end end end end describe "#create_partition" do before(:each) do # test disk w/ existing partition @disk = LinuxAdmin::Disk.new :path => '/dev/hda' @disk.instance_variable_set(:@partitions, [LinuxAdmin::Partition.new(:id => 1, :end_sector => 1024)]) allow(@disk).to receive_messages(:has_partition_table? => true) end it "uses parted" do params = ['--script', '/dev/hda', 'mkpart', '-a', 'opt', 'primary', 1024, 2048] expect(@disk).to receive(:run!).with(@disk.cmd(:parted), :params => { nil => params }) @disk.create_partition 'primary', 1024 end it "accepts start/end params" do params = ['--script', '/dev/hda', 'mkpart', '-a', 'opt', 'primary', "0%", "50%"] expect(@disk).to receive(:run!).with(@disk.cmd(:parted), :params => { nil => params }) @disk.create_partition 'primary', "0%", "50%" end context "missing params" do it "raises ArgumentError" do expect{ @disk.create_partition 'primary' }.to raise_error(ArgumentError) expect{ @disk.create_partition 'primary', '0%', '50%', 100 }.to raise_error(ArgumentError) end end it "returns partition" do expect(@disk).to receive(:run!) # stub out call to parted partition = @disk.create_partition 'primary', 1024 expect(partition).to be_an_instance_of(LinuxAdmin::Partition) end it "increments partition id" do expect(@disk).to receive(:run!) # stub out call to parted partition = @disk.create_partition 'primary', 1024 expect(partition.id).to eq(2) end it "sets partition start to first unused sector on disk" do expect(@disk).to receive(:run!) # stub out call to parted partition = @disk.create_partition 'primary', 1024 expect(partition.start_sector).to eq(1024) end it "stores new partition locally" do expect(@disk).to receive(:run!) # stub out call to parted expect { @disk.create_partition 'primary', 1024 }.to change{@disk.partitions.size}.by(1) end it "creates partition table if missing" do allow(@disk).to receive_messages(:has_partition_table? => false) expect(@disk).to receive(:create_partition_table) expect(@disk).to receive(:run!) @disk.create_partition 'primary', 1024 end end describe "#has_partition_table?" do it "positive case" do disk = LinuxAdmin::Disk.new :path => '/dev/hda' expect(disk).to receive(:run).and_return(double(:output => "", :exit_status => 0)) expect(disk).to have_partition_table end it "negative case" do disk = LinuxAdmin::Disk.new :path => '/dev/hda' output = "\e[?1034h\r\rError: /dev/sdb: unrecognised disk label\n" expect(disk).to receive(:run).and_return(double(:output => output, :exit_status => 1)) expect(disk).not_to have_partition_table end end it "#create_partition_table" do disk = LinuxAdmin::Disk.new :path => '/dev/hda' options = {:params => {nil => %w(--script /dev/hda mklabel msdos)}} expect(disk).to receive(:run!).with(disk.cmd(:parted), options) disk.create_partition_table end describe "#clear!" do it "clears partitions" do disk = LinuxAdmin::Disk.new :path => '/dev/hda' expect(disk).to receive(:run).and_return(double(:output => "")) # stub out call to cmds disk.partitions << LinuxAdmin::Partition.new expect(disk).to receive(:run!) disk.clear! expect(disk.partitions).to be_empty end it "uses dd to clear partition table" do disk = LinuxAdmin::Disk.new :path => '/dev/hda' expect(disk).to receive(:run!). with(disk.cmd(:dd), :params => {'if=' => '/dev/zero', 'of=' => '/dev/hda', 'bs=' => 512, 'count=' => 1}) disk.clear! end it "returns self" do disk = LinuxAdmin::Disk.new :path => '/dev/hda' allow(disk).to receive(:run!) # stub out call to dd expect(disk.clear!).to eq(disk) end end end