github.com/thanos-io/thanos@v0.32.5/pkg/block/metadata/meta_test.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package metadata
     5  
     6  import (
     7  	"bytes"
     8  	"io"
     9  	"testing"
    10  
    11  	"github.com/efficientgo/core/testutil"
    12  	"github.com/oklog/ulid"
    13  	"github.com/prometheus/prometheus/tsdb"
    14  )
    15  
    16  func TestMeta_ReadWrite(t *testing.T) {
    17  	t.Run("empty write/read/write", func(t *testing.T) {
    18  		b := bytes.Buffer{}
    19  		testutil.Ok(t, Meta{}.Write(&b))
    20  		testutil.Equals(t, `{
    21  	"ulid": "00000000000000000000000000",
    22  	"minTime": 0,
    23  	"maxTime": 0,
    24  	"stats": {},
    25  	"compaction": {
    26  		"level": 0
    27  	},
    28  	"version": 0,
    29  	"thanos": {
    30  		"labels": null,
    31  		"downsample": {
    32  			"resolution": 0
    33  		},
    34  		"source": "",
    35  		"index_stats": {}
    36  	}
    37  }
    38  `, b.String())
    39  		_, err := Read(io.NopCloser(&b))
    40  		testutil.NotOk(t, err)
    41  		testutil.Equals(t, "unexpected meta file version 0", err.Error())
    42  	})
    43  
    44  	t.Run("real write/read/write", func(t *testing.T) {
    45  		b := bytes.Buffer{}
    46  		m1 := Meta{
    47  			BlockMeta: tsdb.BlockMeta{
    48  				ULID:    ulid.MustNew(5, nil),
    49  				MinTime: 2424,
    50  				MaxTime: 134,
    51  				Version: 1,
    52  				Compaction: tsdb.BlockMetaCompaction{
    53  					Sources: []ulid.ULID{ulid.MustNew(1, nil), ulid.MustNew(2, nil)},
    54  					Parents: []tsdb.BlockDesc{
    55  						{
    56  							ULID:    ulid.MustNew(3, nil),
    57  							MinTime: 442,
    58  							MaxTime: 24225,
    59  						},
    60  					},
    61  					Level: 123,
    62  				},
    63  				Stats: tsdb.BlockStats{NumChunks: 14, NumSamples: 245, NumSeries: 4},
    64  			},
    65  			Thanos: Thanos{
    66  				Version: 1,
    67  				Labels:  map[string]string{"ext": "lset1"},
    68  				Source:  ReceiveSource,
    69  				Files: []File{
    70  					{RelPath: "chunks/000001", SizeBytes: 3751},
    71  					{RelPath: "index", SizeBytes: 401},
    72  					{RelPath: "meta.json"},
    73  				},
    74  				Downsample: ThanosDownsample{
    75  					Resolution: 123144,
    76  				},
    77  				IndexStats: IndexStats{
    78  					SeriesMaxSize: 2000,
    79  					ChunkMaxSize:  1000,
    80  				},
    81  			},
    82  		}
    83  		testutil.Ok(t, m1.Write(&b))
    84  		testutil.Equals(t, `{
    85  	"ulid": "00000000050000000000000000",
    86  	"minTime": 2424,
    87  	"maxTime": 134,
    88  	"stats": {
    89  		"numSamples": 245,
    90  		"numSeries": 4,
    91  		"numChunks": 14
    92  	},
    93  	"compaction": {
    94  		"level": 123,
    95  		"sources": [
    96  			"00000000010000000000000000",
    97  			"00000000020000000000000000"
    98  		],
    99  		"parents": [
   100  			{
   101  				"ulid": "00000000030000000000000000",
   102  				"minTime": 442,
   103  				"maxTime": 24225
   104  			}
   105  		]
   106  	},
   107  	"version": 1,
   108  	"thanos": {
   109  		"version": 1,
   110  		"labels": {
   111  			"ext": "lset1"
   112  		},
   113  		"downsample": {
   114  			"resolution": 123144
   115  		},
   116  		"source": "receive",
   117  		"files": [
   118  			{
   119  				"rel_path": "chunks/000001",
   120  				"size_bytes": 3751
   121  			},
   122  			{
   123  				"rel_path": "index",
   124  				"size_bytes": 401
   125  			},
   126  			{
   127  				"rel_path": "meta.json"
   128  			}
   129  		],
   130  		"index_stats": {
   131  			"series_max_size": 2000,
   132  			"chunk_max_size": 1000
   133  		}
   134  	}
   135  }
   136  `, b.String())
   137  		retMeta, err := Read(io.NopCloser(&b))
   138  		testutil.Ok(t, err)
   139  		testutil.Equals(t, m1, *retMeta)
   140  	})
   141  
   142  	t.Run("missing external labels write/read/write", func(t *testing.T) {
   143  		b := bytes.Buffer{}
   144  		m1 := Meta{
   145  			BlockMeta: tsdb.BlockMeta{
   146  				ULID:    ulid.MustNew(5, nil),
   147  				MinTime: 2424,
   148  				MaxTime: 134,
   149  				Version: 1,
   150  				Compaction: tsdb.BlockMetaCompaction{
   151  					Sources: []ulid.ULID{ulid.MustNew(1, nil), ulid.MustNew(2, nil)},
   152  					Parents: []tsdb.BlockDesc{
   153  						{
   154  							ULID:    ulid.MustNew(3, nil),
   155  							MinTime: 442,
   156  							MaxTime: 24225,
   157  						},
   158  					},
   159  					Level: 123,
   160  				},
   161  				Stats: tsdb.BlockStats{NumChunks: 14, NumSamples: 245, NumSeries: 4},
   162  			},
   163  			Thanos: Thanos{
   164  				Version: 1,
   165  				Source:  ReceiveSource,
   166  				Files: []File{
   167  					{RelPath: "index", SizeBytes: 1313},
   168  				},
   169  				Downsample: ThanosDownsample{
   170  					Resolution: 123144,
   171  				},
   172  			},
   173  		}
   174  		testutil.Ok(t, m1.Write(&b))
   175  		testutil.Equals(t, `{
   176  	"ulid": "00000000050000000000000000",
   177  	"minTime": 2424,
   178  	"maxTime": 134,
   179  	"stats": {
   180  		"numSamples": 245,
   181  		"numSeries": 4,
   182  		"numChunks": 14
   183  	},
   184  	"compaction": {
   185  		"level": 123,
   186  		"sources": [
   187  			"00000000010000000000000000",
   188  			"00000000020000000000000000"
   189  		],
   190  		"parents": [
   191  			{
   192  				"ulid": "00000000030000000000000000",
   193  				"minTime": 442,
   194  				"maxTime": 24225
   195  			}
   196  		]
   197  	},
   198  	"version": 1,
   199  	"thanos": {
   200  		"version": 1,
   201  		"labels": null,
   202  		"downsample": {
   203  			"resolution": 123144
   204  		},
   205  		"source": "receive",
   206  		"files": [
   207  			{
   208  				"rel_path": "index",
   209  				"size_bytes": 1313
   210  			}
   211  		],
   212  		"index_stats": {}
   213  	}
   214  }
   215  `, b.String())
   216  		retMeta, err := Read(io.NopCloser(&b))
   217  		testutil.Ok(t, err)
   218  
   219  		// We expect map to be empty but allocated.
   220  		testutil.Equals(t, map[string]string(nil), m1.Thanos.Labels)
   221  		m1.Thanos.Labels = map[string]string{}
   222  		testutil.Equals(t, m1, *retMeta)
   223  	})
   224  
   225  	t.Run("extensions write/read/write", func(t *testing.T) {
   226  		b := bytes.Buffer{}
   227  		m1 := Meta{
   228  			BlockMeta: tsdb.BlockMeta{
   229  				ULID:    ulid.MustNew(5, nil),
   230  				MinTime: 2424,
   231  				MaxTime: 134,
   232  				Version: 1,
   233  				Compaction: tsdb.BlockMetaCompaction{
   234  					Level: 123,
   235  				},
   236  				Stats: tsdb.BlockStats{NumChunks: 14, NumSamples: 245, NumSeries: 4},
   237  			},
   238  			Thanos: Thanos{
   239  				Labels: map[string]string{"ext": "lset1"},
   240  				Source: ReceiveSource,
   241  				Downsample: ThanosDownsample{
   242  					Resolution: 123144,
   243  				},
   244  				Extensions: &TestExtensions{
   245  					Field1: 1,
   246  					Field2: "test_string",
   247  				},
   248  			},
   249  		}
   250  		testutil.Ok(t, m1.Write(&b))
   251  		testutil.Equals(t, `{
   252  	"ulid": "00000000050000000000000000",
   253  	"minTime": 2424,
   254  	"maxTime": 134,
   255  	"stats": {
   256  		"numSamples": 245,
   257  		"numSeries": 4,
   258  		"numChunks": 14
   259  	},
   260  	"compaction": {
   261  		"level": 123
   262  	},
   263  	"version": 1,
   264  	"thanos": {
   265  		"labels": {
   266  			"ext": "lset1"
   267  		},
   268  		"downsample": {
   269  			"resolution": 123144
   270  		},
   271  		"source": "receive",
   272  		"index_stats": {},
   273  		"extensions": {
   274  			"field1": 1,
   275  			"field2": "test_string"
   276  		}
   277  	}
   278  }
   279  `, b.String())
   280  		retMeta, err := Read(io.NopCloser(&b))
   281  		testutil.Ok(t, err)
   282  		retExtensions, err := retMeta.Thanos.ParseExtensions(&TestExtensions{})
   283  		_, ok := retExtensions.(*TestExtensions)
   284  		testutil.Equals(t, true, ok)
   285  		testutil.Ok(t, err)
   286  		testutil.Equals(t, m1.Thanos.Extensions, retExtensions)
   287  	})
   288  
   289  	t.Run("empty extensions write/read/write", func(t *testing.T) {
   290  		b := bytes.Buffer{}
   291  		m1 := Meta{
   292  			BlockMeta: tsdb.BlockMeta{
   293  				ULID:    ulid.MustNew(5, nil),
   294  				MinTime: 2424,
   295  				MaxTime: 134,
   296  				Version: 1,
   297  				Compaction: tsdb.BlockMetaCompaction{
   298  					Level: 123,
   299  				},
   300  				Stats: tsdb.BlockStats{NumChunks: 14, NumSamples: 245, NumSeries: 4},
   301  			},
   302  			Thanos: Thanos{
   303  				Labels: map[string]string{"ext": "lset1"},
   304  				Source: ReceiveSource,
   305  				Downsample: ThanosDownsample{
   306  					Resolution: 123144,
   307  				},
   308  			},
   309  		}
   310  		testutil.Ok(t, m1.Write(&b))
   311  		testutil.Equals(t, `{
   312  	"ulid": "00000000050000000000000000",
   313  	"minTime": 2424,
   314  	"maxTime": 134,
   315  	"stats": {
   316  		"numSamples": 245,
   317  		"numSeries": 4,
   318  		"numChunks": 14
   319  	},
   320  	"compaction": {
   321  		"level": 123
   322  	},
   323  	"version": 1,
   324  	"thanos": {
   325  		"labels": {
   326  			"ext": "lset1"
   327  		},
   328  		"downsample": {
   329  			"resolution": 123144
   330  		},
   331  		"source": "receive",
   332  		"index_stats": {}
   333  	}
   334  }
   335  `, b.String())
   336  		retMeta, err := Read(io.NopCloser(&b))
   337  		testutil.Ok(t, err)
   338  		retExtensions, err := retMeta.Thanos.ParseExtensions(&TestExtensions{})
   339  		testutil.Ok(t, err)
   340  		testutil.Equals(t, m1.Thanos.Extensions, retExtensions)
   341  	})
   342  }
   343  
   344  type TestExtensions struct {
   345  	Field1 int    `json:"field1"`
   346  	Field2 string `json:"field2"`
   347  }