func TestGenerateNewBlobPath_Unique(t *testing.T) {
	n := 200
	bs := blobstore.NewMockBlobStore()

	for i := 0; i < n; i++ {
		bpath, err := blobstore.GenerateNewBlobPath(bs)
		if err != nil {
			t.Errorf("Failed to GenerateNewBlobPath on %d iter: %v", i, err)
		}

		bh, err := bs.Open(bpath, flags.O_RDONLY)
		if err != nil {
			t.Errorf("open bpath \"%s\" failed: %v", bpath, err)
		}
		if err := bh.PWrite(0, HelloWorld); err != nil {
			t.Errorf("write helloworld to bpath \"%s\" failed: %v", bpath, err)
		}
		if err := bh.Close(); err != nil {
			t.Errorf("close bpath \"%s\" failed: %v", bpath, err)
		}
	}

	if len(bs.Paths) != n {
		t.Errorf("Expected %d unique entries, but found %d entries", n, len(bs.Paths))
	}
}
func TestChunkedFileIO_SingleChunk(t *testing.T) {
	caio := NewSimpleDBChunksArrayIO()
	bs := blobstore.NewMockBlobStore()
	cfio := chunkstore.NewChunkedFileIO(bs, TestCipher(), caio)

	// Disable Chunk framing for testing
	cfio.OverrideNewChunkIOForTesting(func(bh blobstore.BlobHandle, c btncrypt.Cipher, offset int64) blobstore.BlobHandle { return bh })

	if err := cfio.PWrite(123, HelloWorld); err != nil {
		t.Errorf("PWrite failed: %v", err)
		return
	}
	if err := cfio.PWrite(456, HelloWorld); err != nil {
		t.Errorf("PWrite failed: %v", err)
		return
	}

	if len(caio.cs) != 1 {
		t.Errorf("len(caio.cs) %d", len(caio.cs))
		return
	}
	if caio.cs[0].Offset != 0 {
		t.Errorf("Chunk at invalid offset: %d", caio.cs[1].Offset)
	}
	bh := bs.Paths[caio.cs[0].BlobPath]
	if bh.Log[0].Offset != 123 {
		t.Errorf("Chunk write at invalid offset: %d", bh.Log[0].Offset)
	}
	if bh.Log[1].Offset != 456 {
		t.Errorf("Chunk write at invalid offset: %d", bh.Log[0].Offset)
	}
}
func TestChunkedFileIO_MultiChunk(t *testing.T) {
	caio := NewSimpleDBChunksArrayIO()
	bs := blobstore.NewMockBlobStore()
	cfio := chunkstore.NewChunkedFileIO(bs, TestCipher(), caio)

	// Disable Chunk framing for testing
	cfio.OverrideNewChunkIOForTesting(func(bh blobstore.BlobHandle, c btncrypt.Cipher, offset int64) blobstore.BlobHandle { return bh })

	if err := cfio.PWrite(chunkstore.ChunkSplitSize+12345, HelloWorld); err != nil {
		t.Errorf("PWrite failed: %v", err)
		return
	}
	if err := cfio.PWrite(123, HelloWorld); err != nil {
		t.Errorf("PWrite failed: %v", err)
		return
	}

	if len(caio.cs) != 2 {
		t.Errorf("len(caio.cs) %d", len(caio.cs))
		return
	}
	if caio.cs[0].Offset != 0 {
		t.Errorf("Chunk at invalid offset: %d", caio.cs[1].Offset)
	}
	bh := bs.Paths[caio.cs[0].BlobPath]
	if bh.Log[0].Offset != 123 {
		t.Errorf("Chunk write at invalid offset: %d", bh.Log[0].Offset)
	}
	if caio.cs[1].Offset != chunkstore.ChunkSplitSize {
		t.Errorf("Split chunk at invalid offset: %d", caio.cs[1].Offset)
	}
	bh = bs.Paths[caio.cs[1].BlobPath]
	if bh.Log[0].Offset != 12345 {
		t.Errorf("Split chunk write at invalid offset: %d", bh.Log[0].Offset)
	}

	if err := cfio.PWrite(chunkstore.ChunkSplitSize-5, HelloWorld); err != nil {
		t.Errorf("PWrite failed: %v", err)
		return
	}
	bh = bs.Paths[caio.cs[1].BlobPath]
	if !reflect.DeepEqual(bh.Log[1], blobstore.MockBlobStoreOperation{'W', 0, 7, HelloWorld[5]}) {
		fmt.Printf("? %+v\n", bh.Log[1])
	}
}