| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package bootrecord |
| |
| import ( |
| "testing" |
| "unsafe" |
| |
| "thinfs/fs/msdosfs/testutil" |
| ) |
| |
| func TestBootrecordLargeSize(t *testing.T) { |
| br := &brLarge{} |
| size := unsafe.Sizeof(*br) |
| if size != BootrecordSize { |
| t.Fatalf("Expected brLarge size: %d, but got %d", BootrecordSize, size) |
| } |
| align := unsafe.Alignof(*br) |
| if align != 1 { |
| t.Fatalf("Expected brLarge to have no alignment requirements, but Alignof is: %d", align) |
| } |
| } |
| |
| func TestValidFAT32(t *testing.T) { |
| fat := testutil.MkfsFAT(t, "1G", 2, 0, 4, 512) |
| d := fat.GetDevice() |
| |
| // Read the bootrecord into buf. |
| br, err := New(d) |
| if err != nil { |
| t.Fatal(err) |
| } else if br.Type() != FAT32 { |
| t.Fatal("FAT type was not FAT32, but it should have been") |
| } |
| |
| volumeSize := br.VolumeSize() |
| expectedVolumeSize := int64(1 << 30) // 1 GB |
| if volumeSize != expectedVolumeSize { |
| t.Fatalf("Expected volume size to be %d, but it was %d", expectedVolumeSize, volumeSize) |
| } |
| |
| active, numFATs, primary := br.MirroringInfo() |
| if !active { |
| t.Fatal("Expected mirroring to be active") |
| } else if numFATs != 2 { |
| t.Fatalf("Expected numFATs to be 2, but it was %d", numFATs) |
| } else if primary != 0 { |
| t.Fatalf("Expected primary to be 0, but it was %d", primary) |
| } |
| |
| numUsableClusters := br.NumUsableClusters() |
| |
| expectedReservedSectors := int64(32) |
| expectedSectorSize := int64(512) |
| expectedReserveClusters := int64(2) |
| expectedSectorsPerCluster := int64(4) |
| expectedSectorsPerFAT := int64(4081) |
| expectedNumUsableBytes := volumeSize |
| expectedNumUsableBytes -= expectedReservedSectors * expectedSectorSize |
| expectedNumUsableBytes -= int64(numFATs) * expectedSectorsPerFAT * expectedSectorSize |
| expectedNumUsableClusters := (expectedNumUsableBytes / (expectedSectorSize * expectedSectorsPerCluster)) - expectedReserveClusters |
| |
| if numUsableClusters != uint32(expectedNumUsableClusters) { |
| t.Fatalf("Expected numUsableClusters to be %d, but it was %d", expectedNumUsableClusters, numUsableClusters) |
| } |
| |
| d.Close() |
| fat.RmfsFAT() |
| } |
| |
| func TestInvalidFAT32SectorsPerFAT32(t *testing.T) { |
| fat := testutil.MkfsFAT(t, "1G", 2, 0, 4, 512) |
| d := fat.GetDevice() |
| |
| d.WriteAt([]byte{0}, 36) |
| d.WriteAt([]byte{0}, 37) |
| d.WriteAt([]byte{0}, 38) |
| d.WriteAt([]byte{0}, 39) |
| if _, err := New(d); err == nil { |
| t.Fatalf("Expected zero value for Sectors Per FAT32 to fail") |
| } |
| |
| d.Close() |
| fat.RmfsFAT() |
| } |
| |
| func TestInvalidFAT32RootCluster(t *testing.T) { |
| doTest := func(success bool, rootCluster int) { |
| fat := testutil.MkfsFAT(t, "1G", 2, 0, 4, 512) |
| d := fat.GetDevice() |
| |
| d.WriteAt([]byte{uint8(rootCluster)}, 44) |
| d.WriteAt([]byte{uint8(rootCluster >> 8)}, 45) |
| d.WriteAt([]byte{uint8(rootCluster >> 16)}, 46) |
| d.WriteAt([]byte{uint8(rootCluster >> 24)}, 47) |
| |
| if success { |
| if _, err := New(d); err != nil { |
| t.Fatal(err) |
| } |
| } else { |
| if _, err := New(d); err == nil { |
| t.Fatalf("Expected root cluster value %d to fail", rootCluster) |
| } |
| } |
| |
| d.Close() |
| fat.RmfsFAT() |
| } |
| |
| doTest(true, 2) |
| doTest(true, 3) |
| |
| doTest(false, 0) |
| doTest(false, 1) |
| doTest(false, 0x100000) |
| } |
| |
| func TestInvalidBackupBootSector(t *testing.T) { |
| fat := testutil.MkfsFAT(t, "1G", 2, 0, 4, 512) |
| d := fat.GetDevice() |
| |
| d.WriteAt([]byte{0}, 50) |
| d.WriteAt([]byte{0}, 51) |
| if _, err := New(d); err == nil { |
| t.Fatalf("Expected backup boot sector of zero to fail") |
| } |
| |
| d.WriteAt([]byte{50}, 50) |
| d.WriteAt([]byte{0}, 51) |
| if _, err := New(d); err == nil { |
| t.Fatalf("Expected backup boot sector larger than the number of reserved sectors to fail") |
| } |
| |
| d.Close() |
| fat.RmfsFAT() |
| } |
| |
| func TestInvalidFSInfoSector(t *testing.T) { |
| fat := testutil.MkfsFAT(t, "1G", 2, 0, 4, 512) |
| d := fat.GetDevice() |
| |
| d.WriteAt([]byte{0}, 48) |
| d.WriteAt([]byte{0}, 49) |
| if _, err := New(d); err == nil { |
| t.Fatalf("Expected fs info sector of zero to fail") |
| } |
| |
| d.WriteAt([]byte{50}, 48) |
| d.WriteAt([]byte{0}, 49) |
| if _, err := New(d); err == nil { |
| t.Fatalf("Expected fs info sector larger than the number of reserved sectors to fail") |
| } |
| |
| d.Close() |
| fat.RmfsFAT() |
| } |
| |
| func TestInvalidMirroringInfo(t *testing.T) { |
| fat := testutil.MkfsFAT(t, "1G", 2, 0, 4, 512) |
| d := fat.GetDevice() |
| |
| // The 40th byte in the FAT32 boot sector contains the following information: |
| // M _ _ _ F F F F |
| // 7 6 5 4 3 2 1 0 |
| // M: 0 if mirroring to all FATs, else 1. |
| // F: Number of primary FAT if, mirroring is disabled. |
| |
| // Primary FAT index 1 (valid, there are two FATs) |
| d.WriteAt([]byte{0x81}, 40) |
| if _, err := New(d); err != nil { |
| t.Fatal(err) |
| } |
| // Primary FAT index 2 (out of bounds) |
| d.WriteAt([]byte{0x82}, 40) |
| if _, err := New(d); err == nil { |
| t.Fatal("Expected error relating to invalid primary FAT") |
| } |
| |
| d.Close() |
| fat.RmfsFAT() |
| |
| } |