package erasureencode import ( "fmt" "testing" ) // example uses a tiny shard size for testing // ex: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, g, h] ShardSize(2) RS(3,2) // c0: [01, 67, cd] [s0, s3, s6] // c1: [23, 89, ef] [s1, s4, s7] // c2: [45, ab, gh] [s2, s5, s8] // read(7, 7) // desired plan 0,3,1; 1,2,2; 2,2,2; 0,4,2 -> 7; 89; ab; cd func TestPlan_EvenStride_Full(t *testing.T) { params := Params{ Size: 18, Stride: 2, Shards: 3, Parity: 2, } expected := []ChunkShardMeta{ ChunkShardMeta{Chunk: 0, ChunkOffset: 3, GlobalOffset: 7, Size: 1}, ChunkShardMeta{Chunk: 1, ChunkOffset: 2, GlobalOffset: 8, Size: 2}, ChunkShardMeta{Chunk: 2, ChunkOffset: 2, GlobalOffset: 10, Size: 2}, ChunkShardMeta{Chunk: 0, ChunkOffset: 4, GlobalOffset: 12, Size: 2}, } actual := params.Plan(7, 7) if len(actual) != len(expected) { t.Errorf(`Expected output to have length of %x, got %x`, len(expected), len(actual)) } for i, actualItem := range actual { if fmt.Sprintf("%#v", actualItem) != fmt.Sprintf("%#v", expected[i]) { t.Errorf(`Expected %#v to equal %#v at %d`, actualItem, expected[i], i) } else { // fmt.Printf("ok: %#v\n", actualItem) } } } // example uses a tiny shard size for testing // ex: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f] ShardSize(2) RS(3,2) // c0: [01, 67, cd] [s0, s3, s6] // c1: [23, 89, ef] [s1, s4, s7] // c2: [45, ab, !!] [s2, s5, s8] // read(7, 7) // desired plan 0,3,1; 1,2,2; 2,2,2; 0,4,2 -> 7; 89; ab; cd func TestPlan_EvenStride_Short2(t *testing.T) { params := Params{ Size: 16, Stride: 2, Shards: 3, Parity: 2, } expected := []ChunkShardMeta{ ChunkShardMeta{Chunk: 0, ChunkOffset: 3, GlobalOffset: 7, Size: 1}, ChunkShardMeta{Chunk: 1, ChunkOffset: 2, GlobalOffset: 8, Size: 2}, ChunkShardMeta{Chunk: 2, ChunkOffset: 2, GlobalOffset: 10, Size: 2}, ChunkShardMeta{Chunk: 0, ChunkOffset: 4, GlobalOffset: 12, Size: 2}, } actual := params.Plan(7, 7) if len(actual) != len(expected) { t.Errorf(`Expected output to have length of %x, got %x`, len(expected), len(actual)) } for i, actualItem := range actual { if fmt.Sprintf("%#v", actualItem) != fmt.Sprintf("%#v", expected[i]) { t.Errorf(`Expected %#v to equal %#v at %d`, actualItem, expected[i], i) } else { // fmt.Printf("ok: %#v\n", actualItem) } } } // example uses a tiny shard size for testing // ex: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, g] ShardSize(2) RS(3,2) // c0: [01, 67, cd] [s0, s3, s6] // c1: [23, 89, ef] [s1, s4, s7] // c2: [45, ab, g!] [s2, s5, s8] // read(7, 7) // desired plan 0,3,1; 1,2,2; 2,2,2; 0,4,2 -> 7; 89; ab; cd func TestPlan_EvenStride_Short1(t *testing.T) { params := Params{ Size: 17, Stride: 2, Shards: 3, Parity: 2, } expected := []ChunkShardMeta{ ChunkShardMeta{Chunk: 0, ChunkOffset: 3, GlobalOffset: 7, Size: 1}, ChunkShardMeta{Chunk: 1, ChunkOffset: 2, GlobalOffset: 8, Size: 2}, ChunkShardMeta{Chunk: 2, ChunkOffset: 2, GlobalOffset: 10, Size: 2}, ChunkShardMeta{Chunk: 0, ChunkOffset: 4, GlobalOffset: 12, Size: 2}, } actual := params.Plan(7, 7) if len(actual) != len(expected) { t.Errorf(`Expected output to have length of %x, got %x`, len(expected), len(actual)) } for i, actualItem := range actual { if fmt.Sprintf("%#v", actualItem) != fmt.Sprintf("%#v", expected[i]) { t.Errorf(`Expected %#v to equal %#v at %d`, actualItem, expected[i], i) } else { // fmt.Printf("ok: %#v\n", actualItem) } } } // example uses a tiny shard size for testing // ex: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d] ShardSize(2) RS(3,2) // c0: [01, 67, c] [s0, s3, s6] // c1: [23, 89, d] [s1, s4, s7] // c2: [45, ab, !] [s2, s5, s8] // read(7, 7) // desired plan 0,3,1; 1,2,2; 2,2,2; 0,4,1; 1,4,1 -> 7; 89; ab; c; d func TestPlan_OddStride_Short1(t *testing.T) { params := Params{ Size: 13, Stride: 2, Shards: 3, Parity: 2, } expected := []ChunkShardMeta{ ChunkShardMeta{Chunk: 0, ChunkOffset: 3, GlobalOffset: 7, Size: 1}, ChunkShardMeta{Chunk: 1, ChunkOffset: 2, GlobalOffset: 8, Size: 2}, ChunkShardMeta{Chunk: 2, ChunkOffset: 2, GlobalOffset: 10, Size: 2}, ChunkShardMeta{Chunk: 0, ChunkOffset: 4, GlobalOffset: 12, Size: 1}, ChunkShardMeta{Chunk: 1, ChunkOffset: 4, GlobalOffset: 13, Size: 1}, } actual := params.Plan(7, 7) if len(actual) != len(expected) { t.Errorf(`Expected output to have length of %x, got %x`, len(expected), len(actual)) } for i, actualItem := range actual { if fmt.Sprintf("%#v", actualItem) != fmt.Sprintf("%#v", expected[i]) { t.Errorf(`Expected %#v to equal %#v at %d`, actualItem, expected[i], i) } else { // fmt.Printf("ok: %#v\n", actualItem) } } } func TestPlan_OddStride_Full(t *testing.T) { params := Params{ Size: 14, Stride: 2, Shards: 3, Parity: 2, } expected := []ChunkShardMeta{ ChunkShardMeta{Chunk: 0, ChunkOffset: 3, GlobalOffset: 7, Size: 1}, ChunkShardMeta{Chunk: 1, ChunkOffset: 2, GlobalOffset: 8, Size: 2}, ChunkShardMeta{Chunk: 2, ChunkOffset: 2, GlobalOffset: 10, Size: 2}, ChunkShardMeta{Chunk: 0, ChunkOffset: 4, GlobalOffset: 12, Size: 1}, ChunkShardMeta{Chunk: 1, ChunkOffset: 4, GlobalOffset: 13, Size: 1}, } actual := params.Plan(7, 7) if len(actual) != len(expected) { t.Errorf(`Expected output to have length of %x, got %x`, len(expected), len(actual)) } for i, actualItem := range actual { if fmt.Sprintf("%#v", actualItem) != fmt.Sprintf("%#v", expected[i]) { t.Errorf(`Expected %#v to equal %#v at %d`, actualItem, expected[i], i) } else { // fmt.Printf("ok: %#v\n", actualItem) } } }