github.com/GuanceCloud/cliutils@v1.1.21/point/pbpoint_test.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  package point
     7  
     8  import (
     9  	"encoding/json"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/GuanceCloud/cliutils"
    15  	proto "github.com/gogo/protobuf/proto"
    16  	"github.com/stretchr/testify/assert"
    17  )
    18  
    19  var name = "abc"
    20  
    21  func BenchmarkMarshal(b *testing.B) {
    22  	cases := []struct {
    23  		name   string
    24  		repeat int
    25  	}{
    26  		{
    27  			name:   "10-points",
    28  			repeat: 10,
    29  		},
    30  
    31  		{
    32  			name:   "1000-points",
    33  			repeat: 1000,
    34  		},
    35  	}
    36  
    37  	for _, tc := range cases {
    38  		b.Run(tc.name+"_pb-marshal", func(b *testing.B) {
    39  			pbpts := RandPBPoints(tc.repeat)
    40  
    41  			for i := 0; i < b.N; i++ {
    42  				if _, err := proto.Marshal(pbpts); err != nil {
    43  					b.Error(err)
    44  				}
    45  			}
    46  		})
    47  
    48  		b.Run(tc.name+"_lp-marshal", func(b *testing.B) {
    49  			pts := RandPoints(tc.repeat)
    50  			for i := 0; i < b.N; i++ {
    51  				arr := []string{}
    52  				for i := 0; i < len(pts); i++ {
    53  					arr = append(arr, pts[i].LineProto())
    54  				}
    55  				x := strings.Join(arr, "\n")
    56  				_ = x
    57  			}
    58  		})
    59  
    60  		b.Logf("----------------------------------------------")
    61  
    62  		b.Run(tc.name+"_pb-unmarshal", func(b *testing.B) {
    63  			pbpts := RandPBPoints(tc.repeat)
    64  
    65  			pb, err := proto.Marshal(pbpts)
    66  			assert.NoError(b, err)
    67  
    68  			for i := 0; i < b.N; i++ {
    69  				var pt PBPoints
    70  				if err := proto.Unmarshal(pb, &pt); err != nil {
    71  					b.Error(err)
    72  				}
    73  			}
    74  		})
    75  
    76  		b.Run(tc.name+"_lp-unmarshal", func(b *testing.B) {
    77  			pts := RandPoints(tc.repeat)
    78  			arr := []string{}
    79  			for i := 0; i < len(pts); i++ {
    80  				arr = append(arr, pts[i].LineProto())
    81  			}
    82  			ptbytes := []byte(strings.Join(arr, "\n"))
    83  
    84  			for i := 0; i < b.N; i++ {
    85  				if _, err := parseLPPoints(ptbytes, nil); err != nil {
    86  					b.Error(err)
    87  				}
    88  			}
    89  		})
    90  	}
    91  }
    92  
    93  func TestPBPointJSON(t *testing.T) {
    94  	cases := []struct {
    95  		name   string
    96  		tags   map[string]string
    97  		fields map[string]interface{}
    98  		time   time.Time
    99  		warns  []*Warn
   100  		debugs []*Debug
   101  	}{
   102  		{
   103  			name: "simple",
   104  			tags: nil,
   105  			fields: map[string]interface{}{
   106  				"f1": int64(123),
   107  				"f2": 123.4,
   108  				"f3": false,
   109  				"f4": "abc",
   110  				"f5": []byte("xyz"),
   111  				"f6": uint64(1234567890),
   112  			},
   113  			time: time.Unix(0, 123),
   114  		},
   115  
   116  		{
   117  			name: "simple-2",
   118  			tags: map[string]string{
   119  				"t1": "123",
   120  				"t2": "xyz",
   121  			},
   122  			fields: map[string]interface{}{
   123  				"f1": int64(123),
   124  				"f2": 123.4,
   125  				"f3": false,
   126  				"f4": "abc",
   127  				"f5": []byte("xyz"),
   128  				"f6": uint64(1234567890),
   129  			},
   130  			time: time.Unix(0, 123),
   131  		},
   132  
   133  		{
   134  			name: "with-warnings",
   135  			tags: map[string]string{
   136  				"t1": "123",
   137  			},
   138  			fields: map[string]interface{}{
   139  				"t1": "dulicated key in tags", // triger warnning
   140  				"f1": int64(123),
   141  			},
   142  			time: time.Unix(0, 123),
   143  		},
   144  
   145  		{
   146  			name: "with-debugs",
   147  			tags: map[string]string{
   148  				"t1": "123",
   149  			},
   150  			fields: map[string]interface{}{
   151  				"t1": "dulicated key in tags",
   152  				"f1": int64(123),
   153  			},
   154  			time:   time.Unix(0, 123),
   155  			debugs: []*Debug{{Info: "some debug info"}},
   156  		},
   157  	}
   158  
   159  	for _, tc := range cases {
   160  		t.Run(tc.name, func(t *testing.T) {
   161  			pt, err := NewPoint(tc.name, tc.tags, tc.fields, WithEncoding(Protobuf), WithTime(tc.time), WithKeySorted(true))
   162  
   163  			assert.NoError(t, err)
   164  
   165  			for _, d := range tc.debugs {
   166  				pt.AddDebug(d)
   167  			}
   168  
   169  			// json
   170  			pbjson, err := json.Marshal(pt)
   171  			assert.NoError(t, err)
   172  
   173  			// test if debug/warns included in json
   174  			if len(pt.pt.Debugs) > 0 {
   175  				assert.Contains(t, string(pbjson), "debugs", "%s not include `debugs'", string(pbjson))
   176  			}
   177  
   178  			if len(pt.pt.Warns) > 0 {
   179  				assert.Contains(t, string(pbjson), "warns", "%s not include `warns'", string(pbjson))
   180  			}
   181  
   182  			// unmarshal
   183  			var unmarshalPt Point
   184  			assert.NoError(t, json.Unmarshal(pbjson, &unmarshalPt))
   185  
   186  			// json unmarshaled point should equal to origin point
   187  			assert.True(t, pt.Equal(&unmarshalPt))
   188  
   189  			// encode to pb
   190  			enc := GetEncoder(WithEncEncoding(Protobuf))
   191  			defer PutEncoder(enc)
   192  
   193  			batches, err := enc.Encode([]*Point{&unmarshalPt})
   194  			assert.NoError(t, err)
   195  			assert.Equal(t, 1, len(batches))
   196  
   197  			// decode the pb
   198  			// test equality: decoded pb point equal(json format) the point before encode
   199  			dec := GetDecoder(WithDecEncoding(Protobuf))
   200  
   201  			pts, err := dec.Decode(batches[0])
   202  			assert.NoError(t, err)
   203  			assert.Equal(t, 1, len(pts))
   204  
   205  			// test equality on origin json
   206  			assert.Equal(t, string(pbjson),
   207  				func() string {
   208  					j, err := json.Marshal(pts[0])
   209  					assert.NoError(t, err)
   210  					return string(j)
   211  				}())
   212  
   213  			t.Logf("pb json after:\n%s", pts[0].Pretty())
   214  
   215  			if len(pt.pt.Warns) > 0 {
   216  				assert.Contains(t, string(pbjson), "warns")
   217  			}
   218  
   219  			if len(tc.debugs) > 0 {
   220  				assert.Contains(t, string(pbjson), "debugs")
   221  			}
   222  		})
   223  	}
   224  }
   225  
   226  func TestPBPointPayload(t *testing.T) {
   227  	cases := []struct {
   228  		name   string
   229  		repeat int
   230  	}{
   231  		{
   232  			name:   "100-point",
   233  			repeat: 100,
   234  		},
   235  
   236  		{
   237  			name:   "1000-point",
   238  			repeat: 1000,
   239  		},
   240  
   241  		{
   242  			name:   "10000-point",
   243  			repeat: 10000,
   244  		},
   245  	}
   246  
   247  	for _, tc := range cases {
   248  		t.Run(tc.name, func(t *testing.T) {
   249  			lppts := RandPoints(tc.repeat)
   250  			pbpts := RandPBPoints(tc.repeat)
   251  
   252  			pb, err := proto.Marshal(pbpts)
   253  			assert.NoError(t, err)
   254  			t.Logf("pb len: %d", len(pb))
   255  
   256  			ratio, size := func() (float64, int) {
   257  				x, err := cliutils.GZip(pb)
   258  				assert.NoError(t, err)
   259  				return float64(len(x)) / float64(len(pb)), len(x)
   260  			}()
   261  			t.Logf("pb gz ratio: %f/%d", ratio, size)
   262  
   263  			// line-protocol
   264  			ptStrArr := []string{}
   265  			for i := 0; i < tc.repeat; i++ {
   266  				str := lppts[i].LineProto()
   267  
   268  				ptStrArr = append(ptStrArr, str)
   269  			}
   270  
   271  			ptstr := strings.Join(ptStrArr, "\n")
   272  			ratio, size = func() (float64, int) {
   273  				x, err := cliutils.GZipStr(ptstr)
   274  				assert.NoError(t, err)
   275  				return float64(len(x)) / float64(len(ptstr)), len(x)
   276  			}()
   277  			t.Logf("lp len: %d", len(ptstr))
   278  			t.Logf("lp gz ratio: %f/%d", ratio, size)
   279  		})
   280  	}
   281  }