github.com/GuanceCloud/cliutils@v1.1.21/pipeline/ptinput/funcs/fn_adjust_timezone_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 funcs
     7  
     8  import (
     9  	"fmt"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/GuanceCloud/cliutils/pipeline/ptinput"
    14  	"github.com/GuanceCloud/cliutils/point"
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  const Hour8 = int64(8 * time.Hour)
    19  
    20  func TestAdjustTimezone(t *testing.T) {
    21  	// local timezone: utc+0800
    22  	cst := time.FixedZone("CST", 8*3600)
    23  	time.Local = cst
    24  
    25  	tn := time.Now().Add(time.Minute * 10)
    26  	cases := []struct {
    27  		name, pl, in string
    28  		outkey       string
    29  		expect       time.Time
    30  		fail         bool
    31  	}{
    32  		// {
    33  		// 	name: "time fmt: ANSIC",
    34  		// 	in:   fmt.Sprintf(`{"time":"%s"}`, tn.UTC().Format(time.ANSIC)),
    35  		// 	pl: `
    36  		// 	json(_, time)
    37  		// 	default_time(time)
    38  		// `,
    39  		// 	outkey: "time",
    40  		// 	expect: time.Unix(0, tn.UnixNano()-int64(tn.Nanosecond())-Hour8),
    41  		// 	fail:   false,
    42  		// },
    43  		{
    44  			name: "time fmt: ANSIC",
    45  			in:   fmt.Sprintf(`{"time":"%s"}`, tn.UTC().Format(time.ANSIC)),
    46  			pl: `
    47  			json(_, time)
    48  			default_time(time)
    49  			adjust_timezone(time)
    50  		`,
    51  			outkey: "time",
    52  			expect: time.Unix(0, tn.UnixNano()-int64(tn.Nanosecond())-int64(time.Hour)),
    53  			fail:   false,
    54  		},
    55  	}
    56  
    57  	for idx, tc := range cases {
    58  		t.Run(tc.name, func(t *testing.T) {
    59  			runner, err := NewTestingRunner(tc.pl)
    60  			if err != nil {
    61  				if tc.fail {
    62  					t.Logf("[%d]expect error: %s", idx, err)
    63  				} else {
    64  					t.Errorf("[%d] failed: %s", idx, err)
    65  				}
    66  				return
    67  			}
    68  			{
    69  				pt := ptinput.NewPlPoint(
    70  					point.Logging, "test", nil, map[string]any{"message": tc.in}, time.Now())
    71  				errR := runScript(runner, pt)
    72  				if errR != nil {
    73  					t.Fatal(errR)
    74  				}
    75  
    76  				pt.KeyTime2Time()
    77  				var v interface{}
    78  				if tc.outkey != "time" {
    79  					v, _, _ = pt.Get(tc.outkey)
    80  				} else {
    81  					v = pt.PtTime()
    82  				}
    83  				assert.Equal(t, tc.expect, v)
    84  				t.Logf("[%d] PASS", idx)
    85  			}
    86  
    87  			{
    88  				pt := ptinput.NewPlPoint(point.Logging,
    89  					"test", nil, map[string]any{"message": tc.in}, time.Now())
    90  				errR := runScript(runner, pt)
    91  				if errR != nil {
    92  					t.Fatal(errR)
    93  				}
    94  
    95  				pt.KeyTime2Time()
    96  				var v interface{}
    97  				if tc.outkey != "time" {
    98  					v, _, _ = pt.Get(tc.outkey)
    99  				} else {
   100  					v = pt.PtTime()
   101  				}
   102  				assert.Equal(t, tc.expect, v)
   103  				t.Logf("[%d] PASS", idx)
   104  			}
   105  		})
   106  	}
   107  }
   108  
   109  func TestDetectTimezone(t *testing.T) {
   110  	// logTS, nowTS, minuteAllow, expTS
   111  	tn := time.Date(2022, 6, 1, 10, 11, 12, int(time.Millisecond), time.Local)
   112  
   113  	cases := []struct {
   114  		name          string
   115  		logTS         int64
   116  		nowTS         int64
   117  		durationAllow int64
   118  		expTS         int64
   119  		neq           int64
   120  	}{
   121  		{
   122  			name: "id 1, hour -2, minute -2, sec -2, nanosec -15",
   123  			// log: 2022-6-1 10:11:12.001
   124  			// now: 2022-6-1 12:11:14.014
   125  			// exp: 2022-6-1 12:11:12.001
   126  			logTS:         time.Date(2022, 6, 1, 10, 11, 12, int(time.Millisecond), time.Local).UnixNano(),
   127  			nowTS:         time.Date(2022, 6, 1, 12, 11, 14, int(time.Millisecond)*15, time.Local).UnixNano(),
   128  			expTS:         time.Date(2022, 6, 1, 12, 11, 12, int(time.Millisecond), time.Local).UnixNano(),
   129  			durationAllow: defaultMinuteDelta * int64(time.Minute),
   130  		},
   131  		{
   132  			name: "id 2, hour -2, minute 0, sec 0, nanosec +5",
   133  			// log: 2022-6-1 10:11:14.02
   134  			// now: 2022-6-1 12:11:14.014
   135  			// exp: 2022-7-5 12:11:14.02
   136  			logTS:         time.Date(2022, 6, 1, 10, 11, 14, int(time.Millisecond)*20, time.Local).UnixNano(),
   137  			nowTS:         time.Date(2022, 6, 1, 12, 11, 14, int(time.Millisecond)*15, time.Local).UnixNano(),
   138  			expTS:         time.Date(2022, 6, 1, 12, 11, 14, int(time.Millisecond)*20, time.Local).UnixNano(),
   139  			durationAllow: defaultMinuteDelta * int64(time.Minute),
   140  		},
   141  		{
   142  			name:          "id 3, hour -2, minute +2, sec +1",
   143  			logTS:         tn.Add(time.Minute*2 + time.Second - 2*time.Hour).UnixNano(),
   144  			nowTS:         tn.UnixNano(),
   145  			expTS:         tn.Add(time.Minute*2 + time.Second - time.Hour).UnixNano(),
   146  			durationAllow: defaultMinuteDelta * int64(time.Minute),
   147  		},
   148  		{
   149  			name:          "id 3, hour -1, minute -58, sec 0",
   150  			logTS:         time.Date(2022, 6, 1, 11, 1, 1, 0, time.Local).UnixNano(),
   151  			nowTS:         time.Date(2022, 6, 1, 12, 59, 1, 0, time.Local).UnixNano(),
   152  			expTS:         time.Date(2022, 6, 1, 13, 1, 1, 0, time.Local).UnixNano(),
   153  			durationAllow: defaultMinuteDelta * int64(time.Minute),
   154  		},
   155  	}
   156  	for _, v := range cases {
   157  		tsAct := detectTimezone(v.logTS, v.nowTS, v.durationAllow)
   158  
   159  		if v.neq != 0 {
   160  			tsAct += v.neq
   161  		}
   162  		assert.Equal(t, time.Unix(0, v.expTS),
   163  			time.Unix(0, tsAct),
   164  			fmt.Sprintf(v.name))
   165  	}
   166  }