diff --git a/lib/metainfogen/generator.go b/lib/metainfogen/generator.go index 81e91450d..222f981c0 100644 --- a/lib/metainfogen/generator.go +++ b/lib/metainfogen/generator.go @@ -18,7 +18,6 @@ import ( "github.com/uber/kraken/core" "github.com/uber/kraken/lib/store" - "github.com/uber/kraken/lib/store/metadata" ) // Generator wraps static piece length configuration in order to determinstically @@ -43,19 +42,8 @@ func (g *Generator) Generate(d core.Digest) error { if err != nil { return fmt.Errorf("cache stat: %s", err) } - f, err := g.cas.GetCacheFileReader(d.Hex()) - if err != nil { - return fmt.Errorf("get cache file: %s", err) - } pieceLength := g.pieceLengthConfig.get(info.Size()) - mi, err := core.NewMetaInfo(d, f, pieceLength) - if err != nil { - return fmt.Errorf("create metainfo: %s", err) - } - if _, err := g.cas.SetCacheFileMetadata(d.Hex(), metadata.NewTorrentMeta(mi)); err != nil { - return fmt.Errorf("set metainfo: %s", err) - } - return nil + return g.cas.GenerateCacheFileMetaInfo(d, pieceLength) } // Get the piece length for the blob diff --git a/lib/store/ca_store.go b/lib/store/ca_store.go index f2c2f7653..f0b415720 100644 --- a/lib/store/ca_store.go +++ b/lib/store/ca_store.go @@ -310,10 +310,17 @@ func (s *CAStore) generateMetadataFromFile(name string, pieceLength int64) error if err != nil { return fmt.Errorf("get digest from file: %w", err) } - f, err := s.GetCacheFileReader(name) + return s.GenerateCacheFileMetaInfo(d, pieceLength) +} + +// GenerateCacheFileMetaInfo generates torrent metainfo for a cached blob +// and persists it alongside the cache file. +func (s *CAStore) GenerateCacheFileMetaInfo(d core.Digest, pieceLength int64) error { + f, err := s.GetCacheFileReader(d.Hex()) if err != nil { return fmt.Errorf("get cache file: %w", err) } + defer closers.Close(f) mi, err := core.NewMetaInfo(d, f, pieceLength) if err != nil { return fmt.Errorf("create metainfo: %w", err) diff --git a/lib/store/ca_store_test.go b/lib/store/ca_store_test.go index ed6e83e0a..71b4a53b3 100644 --- a/lib/store/ca_store_test.go +++ b/lib/store/ca_store_test.go @@ -243,6 +243,50 @@ func TestCAStoreCreateCacheFile(t *testing.T) { require.NoError(err) require.Equal(s1, string(b2)) } + +func TestCAStore_GenerateCacheFileMetaInfo(t *testing.T) { + require := require.New(t) + + s, cleanup := CAStoreFixture() + defer cleanup() + + const pieceLength = 10 + blob := core.SizedBlobFixture(100, pieceLength) + require.NoError(s.CreateCacheFile(blob.Digest.Hex(), bytes.NewReader(blob.Content))) + + require.NoError(s.GenerateCacheFileMetaInfo(blob.Digest, pieceLength)) + + var tm metadata.TorrentMeta + require.NoError(s.GetCacheFileMetadata(blob.Digest.Hex(), &tm)) + require.Equal(blob.MetaInfo, tm.MetaInfo) +} + +func TestCAStore_GenerateCacheFileMetaInfo_CacheFileMissing(t *testing.T) { + require := require.New(t) + + s, cleanup := CAStoreFixture() + defer cleanup() + + err := s.GenerateCacheFileMetaInfo(core.DigestFixture(), 10) + require.ErrorContains(err, "get cache file") +} + +func TestCAStore_GenerateCacheFileMetaInfo_InvalidPieceLength(t *testing.T) { + require := require.New(t) + + s, cleanup := CAStoreFixture() + defer cleanup() + + blob := core.NewBlobFixture() + require.NoError(s.CreateCacheFile(blob.Digest.Hex(), bytes.NewReader(blob.Content))) + + err := s.GenerateCacheFileMetaInfo(blob.Digest, 0) + require.EqualError(err, "create metainfo: piece length must be positive") + + var tm metadata.TorrentMeta + require.Error(s.GetCacheFileMetadata(blob.Digest.Hex(), &tm)) +} + func TestCAStoreConfig_WithMemoryCache(t *testing.T) { require := require.New(t)