You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: split_merge_grouper_test.go
    path of file: ./repos/pyroscope/pkg/compactor
    
    the code of the file until where you have to start completion: // SPDX-License-Identifier: AGPL-3.0-only
// Provenance-includes-location: https://github.com/grafana/mimir/blob/main/pkg/compactor/split_merge_grouper_test.go
// Provenance-includes-license: Apache-2.0
// Provenance-includes-copyright: The Cortex Authors.

package compactor

import (
	"testing"
	"time"

	"github.com/oklog/ulid"
	"github.com/prometheus/common/model"
	"github.com/stretchr/testify/assert"

	"github.com/grafana/pyroscope/pkg/phlaredb/block"
	"github.com/grafana/pyroscope/pkg/phlaredb/sharding"
)

func TestPlanCompaction(t *testing.T) {
	const userID = "user-1"

	block1 := ulid.MustNew(1, nil)   // Hash: 283204220
	block2 := ulid.MustNew(2, nil)   // Hash: 444110359
	block3 := ulid.MustNew(3, nil)   // Hash: 3253786510
	block4 := ulid.MustNew(4, nil)   // Hash: 122298081
	block5 := ulid.MustNew(5, nil)   // Hash: 2931974232
	block6 := ulid.MustNew(6, nil)   // Hash: 3092880371
	block7 := ulid.MustNew(7, nil)   // Hash: 1607589226
	block8 := ulid.MustNew(8, nil)   // Hash: 2771068093
	block9 := ulid.MustNew(9, nil)   // Hash: 1285776948
	block10 := ulid.MustNew(10, nil) // Hash: 1446683087

	tests := map[string]struct {
		ranges      []int64
		shardCount  uint32
		splitGroups uint32
		blocks      []*block.Meta
		expected    []*job
	}{
		"no input blocks": {
			ranges:   []int64{20},
			blocks:   nil,
			expected: nil,
		},
		"should split a single block if == smallest compaction range": {
			ranges:     []int64{20, 40},
			shardCount: 1,
			blocks: []*block.Meta{
				{ULID: block1, MinTime: 0, MaxTime: 20},
			},
			ex
    
func TestGroupBlocksByShardID(t *testing.T) {
	block1 := ulid.MustNew(1, nil)
	block2 := ulid.MustNew(2, nil)
	block3 := ulid.MustNew(3, nil)
	block4 := ulid.MustNew(4, nil)

	tests := map[string]struct {
		blocks   []*block.Meta
		expected map[string][]*block.Meta
	}{
		"no input blocks": {
			blocks:   nil,
			expected: map[string][]*block.Meta{},
		},
		"only 1 block in input with shard ID": {
			blocks: []*block.Meta{
				{ULID: block1, Labels: map[string]string{sharding.CompactorShardIDLabel: "1"}},
			},
			expected: map[string][]*block.Meta{
				"1": {
					{ULID: block1, Labels: map[string]string{sharding.CompactorShardIDLabel: "1"}},
				},
			},
		},
		"only 1 block in input without shard ID": {
			blocks: []*block.Meta{
				{ULID: block1},
			},
			expected: map[string][]*block.Meta{
				"": {
					{ULID: block1},
				},
			},
		},
		"multiple blocks per shard ID": {
			blocks: []*block.Meta{
				{ULID: block1, Labels: map[string]string{sharding.CompactorShardIDLabel: "1"}},
				{ULID: block2, Labels: map[string]string{sharding.CompactorShardIDLabel: "2"}},
				{ULID: block3, Labels: map[string]string{sharding.CompactorShardIDLabel: "1"}},
				{ULID: block4},
			},
			expected: map[string][]*block.Meta{
				"": {
					{ULID: block4},
				},
				"1": {
					{ULID: block1, Labels: map[string]string{sharding.CompactorShardIDLabel: "1"}},
					{ULID: block3, Labels: map[string]string{sharding.CompactorShardIDLabel: "1"}},
				},
				"2": {
					{ULID: block2, Labels: map[string]string{sharding.CompactorShardIDLabel: "2"}},
				},
			},
		},
	}

	for testName, testData := range tests {
		t.Run(testName, func(t *testing.T) {
			assert.Equal(t, testData.expected, groupBlocksByShardID(testData.blocks))
		})
	}
}