Files
2025-08-07 19:23:48 +08:00

248 lines
7.5 KiB
Go

// Copyright 2021 EMQ Technologies Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package timex
import (
"testing"
"time"
)
func TestAlignTimeToWindow(t *testing.T) {
tests := []struct {
name string
input time.Time
size time.Duration
expected time.Time
}{
{
name: "对齐到1分钟窗口",
input: time.Date(2024, 1, 1, 12, 35, 56, 789000000, time.UTC),
size: 3 * time.Minute,
expected: time.Date(2024, 1, 1, 12, 33, 0, 0, time.UTC),
},
{
name: "对齐到5分钟窗口",
input: time.Date(2024, 1, 1, 12, 37, 56, 789000000, time.UTC),
size: 5 * time.Minute,
expected: time.Date(2024, 1, 1, 12, 35, 0, 0, time.UTC),
},
{
name: "对齐到1小时窗口",
input: time.Date(2024, 1, 1, 12, 34, 56, 789000000, time.UTC),
size: time.Hour,
expected: time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC),
},
{
name: "对齐到1天窗口",
input: time.Date(2024, 1, 1, 12, 34, 56, 789000000, time.UTC),
size: 24 * time.Hour,
expected: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
},
{
name: "零时刻对齐测试",
input: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
size: time.Hour,
expected: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := AlignTimeToWindow(tt.input, tt.size)
if !got.Equal(tt.expected) {
t.Errorf("AlignTimeToWindow() = %v, want %v", got, tt.expected)
}
})
}
}
// TestAlignTime 测试 AlignTime 函数
func TestAlignTime(t *testing.T) {
tests := []struct {
name string
input time.Time
timeUnit time.Duration
roundUp bool
expected time.Time
}{
{
name: "向下对齐到分钟",
input: time.Date(2024, 1, 1, 12, 35, 45, 0, time.UTC),
timeUnit: time.Minute,
roundUp: false,
expected: time.Date(2024, 1, 1, 12, 35, 0, 0, time.UTC),
},
{
name: "向上对齐到分钟",
input: time.Date(2024, 1, 1, 12, 35, 45, 0, time.UTC),
timeUnit: time.Minute,
roundUp: true,
expected: time.Date(2024, 1, 1, 12, 36, 0, 0, time.UTC),
},
{
name: "向下对齐到小时",
input: time.Date(2024, 1, 1, 12, 35, 45, 0, time.UTC),
timeUnit: time.Hour,
roundUp: false,
expected: time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC),
},
{
name: "向上对齐到小时",
input: time.Date(2024, 1, 1, 12, 35, 45, 0, time.UTC),
timeUnit: time.Hour,
roundUp: true,
expected: time.Date(2024, 1, 1, 13, 0, 0, 0, time.UTC),
},
{
name: "向下对齐到秒",
input: time.Date(2024, 1, 1, 12, 35, 45, 500000000, time.UTC),
timeUnit: time.Second,
roundUp: false,
expected: time.Date(2024, 1, 1, 12, 35, 45, 0, time.UTC),
},
{
name: "向上对齐到秒",
input: time.Date(2024, 1, 1, 12, 35, 45, 500000000, time.UTC),
timeUnit: time.Second,
roundUp: true,
expected: time.Date(2024, 1, 1, 12, 35, 46, 0, time.UTC),
},
{
name: "精确对齐时间向下",
input: time.Date(2024, 1, 1, 12, 35, 0, 0, time.UTC),
timeUnit: time.Minute,
roundUp: false,
expected: time.Date(2024, 1, 1, 12, 35, 0, 0, time.UTC),
},
{
name: "精确对齐时间向上",
input: time.Date(2024, 1, 1, 12, 35, 0, 0, time.UTC),
timeUnit: time.Minute,
roundUp: true,
expected: time.Date(2024, 1, 1, 12, 35, 0, 0, time.UTC),
},
{
name: "向下对齐到天",
input: time.Date(2024, 1, 1, 12, 35, 45, 0, time.UTC),
timeUnit: 24 * time.Hour,
roundUp: false,
expected: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
},
{
name: "向上对齐到天",
input: time.Date(2024, 1, 1, 12, 35, 45, 0, time.UTC),
timeUnit: 24 * time.Hour,
roundUp: true,
expected: time.Date(2024, 1, 2, 0, 0, 0, 0, time.UTC),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := AlignTime(tt.input, tt.timeUnit, tt.roundUp)
if !got.Equal(tt.expected) {
t.Errorf("AlignTime() = %v, want %v", got, tt.expected)
}
})
}
}
// TestAlignTimeEdgeCases 测试 AlignTime 函数的边界情况
func TestAlignTimeEdgeCases(t *testing.T) {
// 测试零时间
zeroTime := time.Time{}
result := AlignTime(zeroTime, time.Minute, true)
expected := zeroTime.Truncate(time.Minute)
if !result.Equal(expected) {
t.Errorf("AlignTime with zero time failed: expected %v, got %v", expected, result)
}
// 测试非常小的时间单位
testTime := time.Date(2024, 1, 1, 12, 35, 45, 123456789, time.UTC)
result = AlignTime(testTime, time.Nanosecond, true)
expected = testTime.Truncate(time.Nanosecond)
if !result.Equal(expected) {
t.Errorf("AlignTime with nanosecond failed: expected %v, got %v", expected, result)
}
// 测试非常大的时间单位
result = AlignTime(testTime, 365*24*time.Hour, false) // 一年
expected = testTime.Truncate(365 * 24 * time.Hour)
if !result.Equal(expected) {
t.Errorf("AlignTime with year unit failed: expected %v, got %v", expected, result)
}
}
// TestAlignTimeToWindowEdgeCases 测试 AlignTimeToWindow 函数的边界情况
func TestAlignTimeToWindowEdgeCases(t *testing.T) {
// 测试零时间
zeroTime := time.Time{}
result := AlignTimeToWindow(zeroTime, time.Minute)
if !result.Equal(zeroTime) {
t.Errorf("AlignTimeToWindow with zero time failed: expected %v, got %v", zeroTime, result)
}
// 测试非常小的窗口大小
testTime := time.Date(2024, 1, 1, 12, 35, 45, 123456789, time.UTC)
result = AlignTimeToWindow(testTime, time.Nanosecond)
expected := testTime.Add(time.Duration(-testTime.UnixNano() % int64(time.Nanosecond)))
if !result.Equal(expected) {
t.Errorf("AlignTimeToWindow with nanosecond failed: expected %v, got %v", expected, result)
}
// 测试窗口大小为1秒的情况
result = AlignTimeToWindow(testTime, time.Second)
expectedNano := testTime.UnixNano() - (testTime.UnixNano() % int64(time.Second))
expected = time.Unix(0, expectedNano)
if !result.Equal(expected) {
t.Errorf("AlignTimeToWindow with second failed: expected %v, got %v", expected, result)
}
}
// TestTimeFunctionsConcurrency 测试时间函数的并发安全性
func TestTimeFunctionsConcurrency(t *testing.T) {
testTime := time.Date(2024, 1, 1, 12, 35, 45, 123456789, time.UTC)
// 启动多个 goroutine 并发调用时间函数
done := make(chan bool, 20)
for i := 0; i < 20; i++ {
go func() {
for j := 0; j < 100; j++ {
// 测试 AlignTimeToWindow
result1 := AlignTimeToWindow(testTime, time.Minute)
expected1 := testTime.Add(time.Duration(-testTime.UnixNano() % int64(time.Minute)))
if !result1.Equal(expected1) {
t.Errorf("Concurrent AlignTimeToWindow failed: expected %v, got %v", expected1, result1)
return
}
// 测试 AlignTime
result2 := AlignTime(testTime, time.Minute, true)
expected2 := testTime.Truncate(time.Minute).Add(time.Minute)
if !result2.Equal(expected2) {
t.Errorf("Concurrent AlignTime failed: expected %v, got %v", expected2, result2)
return
}
}
done <- true
}()
}
// 等待所有 goroutine 完成
for i := 0; i < 20; i++ {
<-done
}
}