github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/platform/time_test.go (about)

     1  package platform
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/bananabytelabs/wazero/internal/testing/require"
     8  	"github.com/bananabytelabs/wazero/sys"
     9  )
    10  
    11  func Test_NewFakeWalltime(t *testing.T) {
    12  	wt := NewFakeWalltime()
    13  
    14  	// Base should be the same as FakeEpochNanos
    15  	sec, nsec := wt()
    16  	ft := time.UnixMicro(FakeEpochNanos / time.Microsecond.Nanoseconds()).UTC()
    17  	require.Equal(t, ft, time.Unix(sec, int64(nsec)).UTC())
    18  
    19  	// next reading should increase by 1ms
    20  	sec, nsec = wt()
    21  	require.Equal(t, ft.Add(time.Millisecond), time.Unix(sec, int64(nsec)).UTC())
    22  }
    23  
    24  func Test_NewFakeNanotime(t *testing.T) {
    25  	nt := NewFakeNanotime()
    26  
    27  	require.Equal(t, int64(0), nt())
    28  
    29  	// next reading should increase by 1ms
    30  	require.Equal(t, int64(time.Millisecond), nt())
    31  }
    32  
    33  func Test_Walltime(t *testing.T) {
    34  	now := time.Now().Unix()
    35  	sec, nsec := Walltime()
    36  
    37  	// Loose test that the second variant is close to now.
    38  	// The only thing that could flake this is a time adjustment during the test.
    39  	require.True(t, now == sec || now == sec-1)
    40  
    41  	// Verify bounds of nanosecond fraction as measuring it precisely won't work.
    42  	require.True(t, nsec >= 0)
    43  	require.True(t, nsec < int32(time.Second.Nanoseconds()))
    44  }
    45  
    46  func Test_Nanotime(t *testing.T) {
    47  	tests := []struct {
    48  		name     string
    49  		nanotime sys.Nanotime
    50  	}{
    51  		{"Nanotime", Nanotime},
    52  		{"nanotimePortable", nanotimePortable},
    53  	}
    54  
    55  	for _, tt := range tests {
    56  		tc := tt
    57  		t.Run(tc.name, func(t *testing.T) {
    58  			delta := time.Since(nanoBase).Nanoseconds()
    59  			nanos := Nanotime()
    60  
    61  			// It takes more than a nanosecond to make the two clock readings required
    62  			// to implement time.Now. Hence, delta will always be less than nanos.
    63  			require.True(t, delta <= nanos)
    64  		})
    65  	}
    66  }
    67  
    68  func Test_Nanotime_ensure_monotonic(t *testing.T) {
    69  	n1 := Nanotime()
    70  	time.Sleep(time.Millisecond)
    71  	n2 := Nanotime()
    72  	require.True(t, n1 < n2)
    73  }
    74  
    75  func Test_Nanosleep(t *testing.T) {
    76  	// In CI, Nanosleep(50ms) returned after 197ms.
    77  	// As we can't control the platform clock, we have to be lenient
    78  	ns := int64(50 * time.Millisecond)
    79  	max := ns * 5
    80  
    81  	start := Nanotime()
    82  	Nanosleep(ns)
    83  	duration := Nanotime() - start
    84  
    85  	require.True(t, duration > 0 && duration < max, "Nanosleep(%d) slept for %d", ns, duration)
    86  }