mirror of
https://github.com/hanzoai/traces.git
synced 2026-10-30 18:20:41 +00:00
* Update proto for v1 backend * Functioning blocklist with new package * Functioning blocklist with existing package * Generate proto to existing package * Add wrapper around google UUID for proto marshaling * Update blocklist for wrapper type * Test WriteTenantIndex * Implement json for uuid * Almost functional backend tests * Passing backend tests * Improve UUID coverage and utility * TempoDB updates for UUID and struct type changes * Update method style for uuid.New() * Update method style for uuid.MustParse() * Add uuid.From helper * Update modules for UUID and proto struct types * Update poller integration test for UUID * Update tempo-cli for UUID and proto struct type changes * Lint and clean up * Fix serverless * Fix cli * Fix cli * Add fixture tests for roundtrip assurance between versions * Clean up notes from proto definition * Update backend/test * Be more specific about unmarshal UUID * Include event for compacted block * Use better json tag for compacted meta * Implement UnmarshalJson on CompcatedBlockMeta for embedded struct * Test for CompactedMeta marshal/unmarshal * Drop benchmark index * Clean commented code * Extend mocks to capture multiple writes * Update backend/test fixtures * Write both proto and json to the backend for all three files in all backends * Fix lint * Back UUID with google.UUID to avoid struct * Relocate pkg/uuid to tempodb/backend * Re-plumb UUID through tempodb * Re-plumb UUID through cmd * Re-plumb UUID through modules * Re-plumb UUID through integration/ * Drop package spec from tempo.proto * Improve encoding marshal performance * Drop block proto and tenantindex json * Drop additional proto include * Implement zstd tenant index compression * Add note about use of json in the dedicatedcolumns * Fix ingester local block * Spell * Revert mock update * Drop json fallback from tenantindex read * Replace single-tenant test fixtures * Update fixture replacement test * Improve error handling and fix test * Extend test for tenantindex round-trip * Small fixes * Revert "Drop json fallback from tenantindex read" This reverts commit 834ff5b85d8a8a4d7eb560fbb67ba8f3a5a3959a. * Add back mocks to capture multiple backend writes * Add back proto & json writitng/reading for tenantindex * Change TotalObjects type from int32 -> int64 The original change was int -> int32, which on 64bit machines is a downgrade that I overlooked. Raising here to int64 to maintain the size. * Store write buffer at object path in mocks to improve readability in tests * Avoid allocation in interface validation * Update note to include intern * Pluralize metas and compacted_metas fields * Fallback to json only on ErrDoesNotExist * Lint * Drop debug * Revert "Pluralize metas and compacted_metas fields" This reverts commit 46a8c36e37ac33e1ffc104287d898930e02cdd97. * Import original tenantindex and test contents for backwards compatibility * Update changelog
159 lines
4.5 KiB
Go
159 lines
4.5 KiB
Go
package local
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
crand "crypto/rand"
|
|
"fmt"
|
|
"math/rand"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/grafana/tempo/pkg/io"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/grafana/tempo/tempodb/backend"
|
|
)
|
|
|
|
const objectName = "test"
|
|
|
|
func TestReadWrite(t *testing.T) {
|
|
fakeTracesFile, err := os.CreateTemp("/tmp", "")
|
|
defer os.Remove(fakeTracesFile.Name())
|
|
assert.NoError(t, err, "unexpected error creating temp file")
|
|
|
|
r, w, _, err := New(&Config{
|
|
Path: t.TempDir(),
|
|
})
|
|
assert.NoError(t, err, "unexpected error creating local backend")
|
|
|
|
blockID := uuid.New()
|
|
tenantIDs := []string{"fake"}
|
|
|
|
for i := 0; i < 10; i++ {
|
|
tenantIDs = append(tenantIDs, fmt.Sprintf("%d", rand.Int()))
|
|
}
|
|
|
|
fakeMeta := &backend.BlockMeta{
|
|
BlockID: backend.UUID(blockID),
|
|
}
|
|
|
|
fakeObject := make([]byte, 20)
|
|
|
|
_, err = crand.Read(fakeObject)
|
|
assert.NoError(t, err, "unexpected error creating fakeObject")
|
|
|
|
ctx := context.Background()
|
|
for _, id := range tenantIDs {
|
|
fakeMeta.TenantID = id
|
|
err = w.Write(ctx, objectName, backend.KeyPathForBlock((uuid.UUID)(fakeMeta.BlockID), id), bytes.NewReader(fakeObject), int64(len(fakeObject)), nil)
|
|
assert.NoError(t, err, "unexpected error writing")
|
|
|
|
err = w.Write(ctx, backend.MetaName, backend.KeyPathForBlock((uuid.UUID)(fakeMeta.BlockID), id), bytes.NewReader(fakeObject), int64(len(fakeObject)), nil)
|
|
assert.NoError(t, err, "unexpected error meta.json")
|
|
err = w.Write(ctx, backend.CompactedMetaName, backend.KeyPathForBlock((uuid.UUID)(fakeMeta.BlockID), id), bytes.NewReader(fakeObject), int64(len(fakeObject)), nil)
|
|
assert.NoError(t, err, "unexpected error meta.compacted.json")
|
|
}
|
|
|
|
actualObject, size, err := r.Read(ctx, objectName, backend.KeyPathForBlock(blockID, tenantIDs[0]), nil)
|
|
assert.NoError(t, err, "unexpected error reading")
|
|
actualObjectBytes, err := io.ReadAllWithEstimate(actualObject, size)
|
|
assert.NoError(t, err, "unexpected error reading")
|
|
assert.Equal(t, fakeObject, actualObjectBytes)
|
|
|
|
actualReadRange := make([]byte, 5)
|
|
err = r.ReadRange(ctx, objectName, backend.KeyPathForBlock(blockID, tenantIDs[0]), 5, actualReadRange, nil)
|
|
assert.NoError(t, err, "unexpected error range")
|
|
assert.Equal(t, fakeObject[5:10], actualReadRange)
|
|
|
|
list, err := r.List(ctx, backend.KeyPath{tenantIDs[0]})
|
|
assert.NoError(t, err, "unexpected error listing")
|
|
assert.Len(t, list, 1)
|
|
assert.Equal(t, blockID.String(), list[0])
|
|
|
|
m, cm, err := r.ListBlocks(ctx, tenantIDs[0])
|
|
assert.NoError(t, err, "unexpected error listing blocks")
|
|
assert.Len(t, m, 1)
|
|
assert.Len(t, cm, 1)
|
|
}
|
|
|
|
func TestShutdownLeavesTenantsWithBlocks(t *testing.T) {
|
|
r, w, _, err := New(&Config{
|
|
Path: t.TempDir(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
blockID := backend.NewUUID()
|
|
contents := bytes.NewReader([]byte("test"))
|
|
tenant := "fake"
|
|
|
|
// write a "block"
|
|
err = w.Write(ctx, "test", backend.KeyPathForBlock((uuid.UUID)(blockID), tenant), contents, contents.Size(), nil)
|
|
require.NoError(t, err)
|
|
|
|
tenantExists(t, tenant, r)
|
|
blockExists(t, blockID, tenant, r)
|
|
|
|
// shutdown the backend
|
|
r.Shutdown()
|
|
|
|
tenantExists(t, tenant, r)
|
|
blockExists(t, blockID, tenant, r)
|
|
}
|
|
|
|
func TestShutdownRemovesTenantsWithoutBlocks(t *testing.T) {
|
|
r, w, c, err := New(&Config{
|
|
Path: t.TempDir(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
ctx := context.Background()
|
|
blockID := backend.NewUUID()
|
|
contents := bytes.NewReader([]byte("test"))
|
|
tenant := "tenant"
|
|
|
|
// write a "block"
|
|
err = w.Write(ctx, "test", backend.KeyPathForBlock((uuid.UUID)(blockID), tenant), contents, contents.Size(), nil)
|
|
require.NoError(t, err)
|
|
|
|
tenantExists(t, tenant, r)
|
|
blockExists(t, blockID, tenant, r)
|
|
|
|
// clear the block
|
|
err = c.ClearBlock((uuid.UUID)(blockID), tenant)
|
|
require.NoError(t, err)
|
|
|
|
tenantExists(t, tenant, r)
|
|
|
|
// block should not exist
|
|
blocks, err := r.List(ctx, backend.KeyPath{tenant})
|
|
require.NoError(t, err)
|
|
require.Len(t, blocks, 0)
|
|
|
|
// shutdown the backend
|
|
r.Shutdown()
|
|
|
|
// tenant should not exist
|
|
tenants, err := r.List(ctx, backend.KeyPath{})
|
|
require.NoError(t, err)
|
|
require.Len(t, tenants, 0)
|
|
}
|
|
|
|
func tenantExists(t *testing.T, tenant string, r backend.RawReader) {
|
|
tenants, err := r.List(context.Background(), backend.KeyPath{})
|
|
require.NoError(t, err)
|
|
require.Len(t, tenants, 1)
|
|
require.Equal(t, tenant, tenants[0])
|
|
}
|
|
|
|
func blockExists(t *testing.T, blockID backend.UUID, tenant string, r backend.RawReader) {
|
|
blocks, err := r.List(context.Background(), backend.KeyPath{tenant})
|
|
require.NoError(t, err)
|
|
require.Len(t, blocks, 1)
|
|
require.Equal(t, blockID.String(), blocks[0])
|
|
}
|