github.com/m3db/m3@v1.5.0/src/metrics/rules/view/rollup_test.go (about)

     1  // Copyright (c) 2018 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package view
    22  
    23  import (
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/m3db/m3/src/metrics/aggregation"
    28  	"github.com/m3db/m3/src/metrics/pipeline"
    29  	"github.com/m3db/m3/src/metrics/policy"
    30  	"github.com/m3db/m3/src/metrics/transformation"
    31  	xtime "github.com/m3db/m3/src/x/time"
    32  
    33  	"github.com/stretchr/testify/require"
    34  )
    35  
    36  func TestRollupTargetEqual(t *testing.T) {
    37  	rr1, err := pipeline.NewRollupOp(
    38  		pipeline.GroupByRollupType,
    39  		"name",
    40  		[]string{"tag1", "tag2"},
    41  		aggregation.DefaultID,
    42  	)
    43  	require.NoError(t, err)
    44  	rr2, err := pipeline.NewRollupOp(
    45  		pipeline.GroupByRollupType,
    46  		"name",
    47  		[]string{"tag2", "tag1"},
    48  		aggregation.DefaultID,
    49  	)
    50  	require.NoError(t, err)
    51  
    52  	target1 := RollupTarget{
    53  		Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
    54  			{
    55  				Type:        pipeline.AggregationOpType,
    56  				Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
    57  			},
    58  			{
    59  				Type:           pipeline.TransformationOpType,
    60  				Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
    61  			},
    62  			{
    63  				Type:   pipeline.RollupOpType,
    64  				Rollup: rr1,
    65  			},
    66  		}),
    67  		StoragePolicies: policy.StoragePolicies{
    68  			policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
    69  			policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
    70  			policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
    71  		},
    72  	}
    73  	target2 := RollupTarget{
    74  		Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
    75  			{
    76  				Type:        pipeline.AggregationOpType,
    77  				Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
    78  			},
    79  			{
    80  				Type:           pipeline.TransformationOpType,
    81  				Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
    82  			},
    83  			{
    84  				Type:   pipeline.RollupOpType,
    85  				Rollup: rr2,
    86  			},
    87  		}),
    88  		StoragePolicies: policy.StoragePolicies{
    89  			policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
    90  			policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
    91  			policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
    92  		},
    93  	}
    94  	require.True(t, target1.Equal(&target2))
    95  }
    96  
    97  func TestRollupTargetNotEqual(t *testing.T) {
    98  	rr1, err := pipeline.NewRollupOp(
    99  		pipeline.GroupByRollupType,
   100  		"name",
   101  		[]string{"tag2", "tag1"},
   102  		aggregation.DefaultID,
   103  	)
   104  	require.NoError(t, err)
   105  	rr2, err := pipeline.NewRollupOp(
   106  		pipeline.GroupByRollupType,
   107  		"name",
   108  		[]string{"tag2", "tag1"},
   109  		aggregation.DefaultID,
   110  	)
   111  	require.NoError(t, err)
   112  	rr3, err := pipeline.NewRollupOp(
   113  		pipeline.GroupByRollupType,
   114  		"name",
   115  		[]string{"tag2", "tag1"},
   116  		aggregation.MustCompressTypes(aggregation.Sum),
   117  	)
   118  	require.NoError(t, err)
   119  	rr4, err := pipeline.NewRollupOp(
   120  		pipeline.GroupByRollupType,
   121  		"name",
   122  		[]string{"tag2", "tag1"},
   123  		aggregation.MustCompressTypes(aggregation.Sum),
   124  	)
   125  	require.NoError(t, err)
   126  
   127  	targets := []RollupTarget{
   128  		{
   129  			Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   130  				{
   131  					Type:        pipeline.AggregationOpType,
   132  					Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   133  				},
   134  				{
   135  					Type:           pipeline.TransformationOpType,
   136  					Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   137  				},
   138  				{
   139  					Type:   pipeline.RollupOpType,
   140  					Rollup: rr1,
   141  				},
   142  			}),
   143  			StoragePolicies: policy.StoragePolicies{
   144  				policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   145  				policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   146  				policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   147  			},
   148  		},
   149  		{
   150  			Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   151  				{
   152  					Type:           pipeline.TransformationOpType,
   153  					Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   154  				},
   155  				{
   156  					Type:   pipeline.RollupOpType,
   157  					Rollup: rr2,
   158  				},
   159  			}),
   160  			StoragePolicies: policy.StoragePolicies{
   161  				policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   162  				policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   163  				policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   164  			},
   165  		},
   166  		{
   167  			Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   168  				{
   169  					Type:           pipeline.TransformationOpType,
   170  					Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   171  				},
   172  				{
   173  					Type:   pipeline.RollupOpType,
   174  					Rollup: rr3,
   175  				},
   176  			}),
   177  			StoragePolicies: policy.StoragePolicies{
   178  				policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   179  				policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   180  				policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   181  			},
   182  		},
   183  		{
   184  			Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   185  				{
   186  					Type:           pipeline.TransformationOpType,
   187  					Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   188  				},
   189  				{
   190  					Type:   pipeline.RollupOpType,
   191  					Rollup: rr4,
   192  				},
   193  			}),
   194  			StoragePolicies: policy.StoragePolicies{
   195  				policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   196  			},
   197  		},
   198  		{
   199  			Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   200  				{
   201  					Type:           pipeline.TransformationOpType,
   202  					Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   203  				},
   204  				{
   205  					Type:   pipeline.RollupOpType,
   206  					Rollup: rr4,
   207  				},
   208  			}),
   209  			StoragePolicies: policy.StoragePolicies{
   210  				policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   211  			},
   212  			ResendEnabled: true,
   213  		},
   214  	}
   215  
   216  	for i := 0; i < len(targets); i++ {
   217  		for j := i + 1; j < len(targets); j++ {
   218  			require.False(t, targets[i].Equal(&targets[j]))
   219  		}
   220  	}
   221  }
   222  
   223  func TestRollupTargetEqualNilCases(t *testing.T) {
   224  	var (
   225  		rt1 *RollupTarget
   226  		rt2 RollupTarget
   227  	)
   228  	require.True(t, rt1.Equal(nil))
   229  	require.False(t, rt2.Equal(rt1))
   230  }
   231  
   232  func TestRollupRuleEqual(t *testing.T) {
   233  	rr1, err := pipeline.NewRollupOp(
   234  		pipeline.GroupByRollupType,
   235  		"name",
   236  		[]string{"tag2", "tag1"},
   237  		aggregation.DefaultID,
   238  	)
   239  	require.NoError(t, err)
   240  	rr2, err := pipeline.NewRollupOp(
   241  		pipeline.GroupByRollupType,
   242  		"name",
   243  		[]string{"tag2", "tag1"},
   244  		aggregation.DefaultID,
   245  	)
   246  	require.NoError(t, err)
   247  
   248  	rule1 := RollupRule{
   249  		ID:            "rr_id",
   250  		Name:          "rr_name",
   251  		CutoverMillis: 1234,
   252  		Filter:        "filter",
   253  		Targets: []RollupTarget{
   254  			{
   255  				Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   256  					{
   257  						Type:        pipeline.AggregationOpType,
   258  						Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   259  					},
   260  					{
   261  						Type:           pipeline.TransformationOpType,
   262  						Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   263  					},
   264  					{
   265  						Type:   pipeline.RollupOpType,
   266  						Rollup: rr1,
   267  					},
   268  				}),
   269  				StoragePolicies: policy.StoragePolicies{
   270  					policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   271  					policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   272  					policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   273  				},
   274  			},
   275  		},
   276  		LastUpdatedAtMillis: 1234,
   277  		LastUpdatedBy:       "john",
   278  	}
   279  	rule2 := RollupRule{
   280  		ID:            "rr_id",
   281  		Name:          "rr_name",
   282  		CutoverMillis: 1234,
   283  		Filter:        "filter",
   284  		Targets: []RollupTarget{
   285  			{
   286  				Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   287  					{
   288  						Type:        pipeline.AggregationOpType,
   289  						Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   290  					},
   291  					{
   292  						Type:           pipeline.TransformationOpType,
   293  						Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   294  					},
   295  					{
   296  						Type:   pipeline.RollupOpType,
   297  						Rollup: rr2,
   298  					},
   299  				}),
   300  				StoragePolicies: policy.StoragePolicies{
   301  					policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   302  					policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   303  					policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   304  				},
   305  			},
   306  		},
   307  		LastUpdatedAtMillis: 1234,
   308  		LastUpdatedBy:       "john",
   309  	}
   310  	require.True(t, rule1.Equal(&rule2))
   311  }
   312  
   313  func TestRollupRuleNotEqual(t *testing.T) {
   314  	rr1, err := pipeline.NewRollupOp(
   315  		pipeline.GroupByRollupType,
   316  		"name",
   317  		[]string{"tag2", "tag1"},
   318  		aggregation.DefaultID,
   319  	)
   320  	require.NoError(t, err)
   321  	rr2, err := pipeline.NewRollupOp(
   322  		pipeline.GroupByRollupType,
   323  		"name",
   324  		[]string{"tag2", "tag1"},
   325  		aggregation.DefaultID,
   326  	)
   327  	require.NoError(t, err)
   328  
   329  	rules := []RollupRule{
   330  		{
   331  			ID:            "rr_id",
   332  			Name:          "rr_name",
   333  			CutoverMillis: 1234,
   334  			Filter:        "filter",
   335  			Targets: []RollupTarget{
   336  				{
   337  					Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   338  						{
   339  							Type:        pipeline.AggregationOpType,
   340  							Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   341  						},
   342  						{
   343  							Type:           pipeline.TransformationOpType,
   344  							Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   345  						},
   346  						{
   347  							Type:   pipeline.RollupOpType,
   348  							Rollup: rr1,
   349  						},
   350  					}),
   351  					StoragePolicies: policy.StoragePolicies{
   352  						policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   353  						policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   354  						policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   355  					},
   356  				},
   357  			},
   358  			LastUpdatedAtMillis: 1234,
   359  			LastUpdatedBy:       "john",
   360  		},
   361  		{
   362  			ID:            "rr_id",
   363  			Name:          "rr_name",
   364  			CutoverMillis: 1234,
   365  			Filter:        "filter2",
   366  			Targets: []RollupTarget{
   367  				{
   368  					Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   369  						{
   370  							Type:        pipeline.AggregationOpType,
   371  							Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   372  						},
   373  						{
   374  							Type:           pipeline.TransformationOpType,
   375  							Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   376  						},
   377  						{
   378  							Type:   pipeline.RollupOpType,
   379  							Rollup: rr2,
   380  						},
   381  					}),
   382  					StoragePolicies: policy.StoragePolicies{
   383  						policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   384  						policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   385  						policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   386  					},
   387  				},
   388  			},
   389  			LastUpdatedAtMillis: 1234,
   390  			LastUpdatedBy:       "john",
   391  		},
   392  		{
   393  			ID:            "rr_id",
   394  			Name:          "rr_name",
   395  			CutoverMillis: 1234,
   396  			Filter:        "filter2",
   397  			Targets: []RollupTarget{
   398  				{
   399  					Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   400  						{
   401  							Type:        pipeline.AggregationOpType,
   402  							Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   403  						},
   404  						{
   405  							Type:           pipeline.TransformationOpType,
   406  							Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   407  						},
   408  					}),
   409  					StoragePolicies: policy.StoragePolicies{
   410  						policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   411  						policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   412  						policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   413  					},
   414  				},
   415  			},
   416  			LastUpdatedAtMillis: 1234,
   417  			LastUpdatedBy:       "john",
   418  		},
   419  		{
   420  			ID:            "rr_id",
   421  			Name:          "rr_name",
   422  			CutoverMillis: 1234,
   423  			Filter:        "filter2",
   424  			Targets: []RollupTarget{
   425  				{
   426  					Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   427  						{
   428  							Type:        pipeline.AggregationOpType,
   429  							Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   430  						},
   431  						{
   432  							Type:           pipeline.TransformationOpType,
   433  							Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   434  						},
   435  					}),
   436  					StoragePolicies: policy.StoragePolicies{
   437  						policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   438  					},
   439  				},
   440  			},
   441  			LastUpdatedAtMillis: 1234,
   442  			LastUpdatedBy:       "john",
   443  		},
   444  		{
   445  			ID:            "rr_id2",
   446  			Name:          "rr_name",
   447  			CutoverMillis: 1234,
   448  			Filter:        "filter2",
   449  			Targets: []RollupTarget{
   450  				{
   451  					Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   452  						{
   453  							Type:        pipeline.AggregationOpType,
   454  							Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   455  						},
   456  						{
   457  							Type:           pipeline.TransformationOpType,
   458  							Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   459  						},
   460  					}),
   461  					StoragePolicies: policy.StoragePolicies{
   462  						policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   463  					},
   464  				},
   465  			},
   466  			LastUpdatedAtMillis: 1234,
   467  			LastUpdatedBy:       "john",
   468  		},
   469  	}
   470  
   471  	for i := 0; i < len(rules); i++ {
   472  		for j := i + 1; j < len(rules); j++ {
   473  			require.False(t, rules[i].Equal(&rules[j]))
   474  		}
   475  	}
   476  }
   477  
   478  func TestRollupRuleEqualNilCases(t *testing.T) {
   479  	var (
   480  		rr1 *RollupRule
   481  		rr2 RollupRule
   482  	)
   483  	require.True(t, rr1.Equal(nil))
   484  	require.False(t, rr2.Equal(rr1))
   485  }
   486  
   487  func TestRollupTargetsEqual(t *testing.T) {
   488  	rr1, err := pipeline.NewRollupOp(
   489  		pipeline.GroupByRollupType,
   490  		"name",
   491  		[]string{"tag2", "tag1"},
   492  		aggregation.DefaultID,
   493  	)
   494  	require.NoError(t, err)
   495  	rr2, err := pipeline.NewRollupOp(
   496  		pipeline.GroupByRollupType,
   497  		"name2",
   498  		[]string{"tag1"},
   499  		aggregation.DefaultID,
   500  	)
   501  	require.NoError(t, err)
   502  	rr3, err := pipeline.NewRollupOp(
   503  		pipeline.GroupByRollupType,
   504  		"name",
   505  		[]string{"tag2", "tag1"},
   506  		aggregation.DefaultID,
   507  	)
   508  	require.NoError(t, err)
   509  	rr4, err := pipeline.NewRollupOp(
   510  		pipeline.GroupByRollupType,
   511  		"name2",
   512  		[]string{"tag1"},
   513  		aggregation.DefaultID,
   514  	)
   515  	require.NoError(t, err)
   516  
   517  	targets1 := rollupTargets{
   518  		{
   519  			Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   520  				{
   521  					Type:        pipeline.AggregationOpType,
   522  					Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   523  				},
   524  				{
   525  					Type:           pipeline.TransformationOpType,
   526  					Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   527  				},
   528  				{
   529  					Type:   pipeline.RollupOpType,
   530  					Rollup: rr1,
   531  				},
   532  			}),
   533  			StoragePolicies: policy.StoragePolicies{
   534  				policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   535  				policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   536  				policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   537  			},
   538  		},
   539  		{
   540  			Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   541  				{
   542  					Type:   pipeline.RollupOpType,
   543  					Rollup: rr2,
   544  				},
   545  			}),
   546  			StoragePolicies: policy.StoragePolicies{
   547  				policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   548  			},
   549  		},
   550  	}
   551  	targets2 := rollupTargets{
   552  		{
   553  			Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   554  				{
   555  					Type:        pipeline.AggregationOpType,
   556  					Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   557  				},
   558  				{
   559  					Type:           pipeline.TransformationOpType,
   560  					Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   561  				},
   562  				{
   563  					Type:   pipeline.RollupOpType,
   564  					Rollup: rr3,
   565  				},
   566  			}),
   567  			StoragePolicies: policy.StoragePolicies{
   568  				policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   569  				policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   570  				policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   571  			},
   572  		},
   573  		{
   574  			Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   575  				{
   576  					Type:   pipeline.RollupOpType,
   577  					Rollup: rr4,
   578  				},
   579  			}),
   580  			StoragePolicies: policy.StoragePolicies{
   581  				policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   582  			},
   583  		},
   584  	}
   585  	require.True(t, targets1.Equal(targets2))
   586  }
   587  
   588  func TestRollupTargetsNotEqual(t *testing.T) {
   589  	rr1, err := pipeline.NewRollupOp(
   590  		pipeline.GroupByRollupType,
   591  		"name",
   592  		[]string{"tag2", "tag1"},
   593  		aggregation.DefaultID,
   594  	)
   595  	require.NoError(t, err)
   596  	rr2, err := pipeline.NewRollupOp(
   597  		pipeline.GroupByRollupType,
   598  		"name2",
   599  		[]string{"tag1"},
   600  		aggregation.DefaultID,
   601  	)
   602  	require.NoError(t, err)
   603  	rr3, err := pipeline.NewRollupOp(
   604  		pipeline.GroupByRollupType,
   605  		"name",
   606  		[]string{"tag2", "tag1"},
   607  		aggregation.DefaultID,
   608  	)
   609  	require.NoError(t, err)
   610  	rr4, err := pipeline.NewRollupOp(
   611  		pipeline.GroupByRollupType,
   612  		"name2",
   613  		[]string{"tag2"},
   614  		aggregation.DefaultID,
   615  	)
   616  	require.NoError(t, err)
   617  	rr5, err := pipeline.NewRollupOp(
   618  		pipeline.GroupByRollupType,
   619  		"name",
   620  		[]string{"tag2", "tag1"},
   621  		aggregation.DefaultID,
   622  	)
   623  	require.NoError(t, err)
   624  
   625  	targetsList := []rollupTargets{
   626  		{
   627  			{
   628  				Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   629  					{
   630  						Type:        pipeline.AggregationOpType,
   631  						Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   632  					},
   633  					{
   634  						Type:           pipeline.TransformationOpType,
   635  						Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   636  					},
   637  					{
   638  						Type:   pipeline.RollupOpType,
   639  						Rollup: rr1,
   640  					},
   641  				}),
   642  				StoragePolicies: policy.StoragePolicies{
   643  					policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   644  					policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   645  					policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   646  				},
   647  			},
   648  			{
   649  				Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   650  					{
   651  						Type:   pipeline.RollupOpType,
   652  						Rollup: rr2,
   653  					},
   654  				}),
   655  				StoragePolicies: policy.StoragePolicies{
   656  					policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   657  				},
   658  			},
   659  		},
   660  		{
   661  			{
   662  				Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   663  					{
   664  						Type:        pipeline.AggregationOpType,
   665  						Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   666  					},
   667  					{
   668  						Type:           pipeline.TransformationOpType,
   669  						Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   670  					},
   671  					{
   672  						Type:   pipeline.RollupOpType,
   673  						Rollup: rr3,
   674  					},
   675  				}),
   676  				StoragePolicies: policy.StoragePolicies{
   677  					policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   678  					policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   679  					policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   680  				},
   681  			},
   682  			{
   683  				Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   684  					{
   685  						Type:   pipeline.RollupOpType,
   686  						Rollup: rr4,
   687  					},
   688  				}),
   689  				StoragePolicies: policy.StoragePolicies{
   690  					policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   691  				},
   692  			},
   693  		},
   694  		{
   695  			{
   696  				Pipeline: pipeline.NewPipeline([]pipeline.OpUnion{
   697  					{
   698  						Type:        pipeline.AggregationOpType,
   699  						Aggregation: pipeline.AggregationOp{Type: aggregation.Sum},
   700  					},
   701  					{
   702  						Type:           pipeline.TransformationOpType,
   703  						Transformation: pipeline.TransformationOp{Type: transformation.PerSecond},
   704  					},
   705  					{
   706  						Type:   pipeline.RollupOpType,
   707  						Rollup: rr5,
   708  					},
   709  				}),
   710  				StoragePolicies: policy.StoragePolicies{
   711  					policy.NewStoragePolicy(10*time.Second, xtime.Second, 12*time.Hour),
   712  					policy.NewStoragePolicy(time.Minute, xtime.Minute, 24*time.Hour),
   713  					policy.NewStoragePolicy(5*time.Minute, xtime.Minute, 48*time.Hour),
   714  				},
   715  			},
   716  		},
   717  	}
   718  
   719  	for i := 0; i < len(targetsList); i++ {
   720  		for j := i + 1; j < len(targetsList); j++ {
   721  			require.False(t, targetsList[i].Equal(targetsList[j]))
   722  		}
   723  	}
   724  }