wa-lang.org/wazero@v1.0.2/imports/wasi_snapshot_preview1/clock_test.go (about)

     1  package wasi_snapshot_preview1
     2  
     3  import (
     4  	_ "embed"
     5  	"testing"
     6  
     7  	"wa-lang.org/wazero"
     8  	"wa-lang.org/wazero/internal/testing/require"
     9  )
    10  
    11  func Test_clockResGet(t *testing.T) {
    12  	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig())
    13  	defer r.Close(testCtx)
    14  
    15  	expectedMemoryMicro := []byte{
    16  		'?',                                     // resultResolution is after this
    17  		0xe8, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // little endian-encoded resolution (fixed to 1000).
    18  		'?', // stopped after encoding
    19  	}
    20  
    21  	expectedMemoryNano := []byte{
    22  		'?',                                    // resultResolution is after this
    23  		0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // little endian-encoded resolution (fixed to 1000).
    24  		'?', // stopped after encoding
    25  	}
    26  
    27  	tests := []struct {
    28  		name           string
    29  		clockID        uint32
    30  		expectedMemory []byte
    31  		expectedLog    string
    32  	}{
    33  		{
    34  			name:           "Realtime",
    35  			clockID:        clockIDRealtime,
    36  			expectedMemory: expectedMemoryMicro,
    37  			expectedLog: `
    38  --> proxy.clock_res_get(id=0,result.resolution=1)
    39  	==> wasi_snapshot_preview1.clock_res_get(id=0,result.resolution=1)
    40  	<== ESUCCESS
    41  <-- (0)
    42  `,
    43  		},
    44  		{
    45  			name:           "Monotonic",
    46  			clockID:        clockIDMonotonic,
    47  			expectedMemory: expectedMemoryNano,
    48  			expectedLog: `
    49  --> proxy.clock_res_get(id=1,result.resolution=1)
    50  	==> wasi_snapshot_preview1.clock_res_get(id=1,result.resolution=1)
    51  	<== ESUCCESS
    52  <-- (0)
    53  `,
    54  		},
    55  	}
    56  
    57  	for _, tt := range tests {
    58  		tc := tt
    59  
    60  		t.Run(tc.name, func(t *testing.T) {
    61  			defer log.Reset()
    62  
    63  			maskMemory(t, testCtx, mod, len(tc.expectedMemory))
    64  
    65  			resultResolution := uint32(1) // arbitrary offset
    66  			requireErrno(t, ErrnoSuccess, mod, functionClockResGet, uint64(tc.clockID), uint64(resultResolution))
    67  			require.Equal(t, tc.expectedLog, "\n"+log.String())
    68  
    69  			actual, ok := mod.Memory().Read(testCtx, 0, uint32(len(tc.expectedMemory)))
    70  			require.True(t, ok)
    71  			require.Equal(t, tc.expectedMemory, actual)
    72  		})
    73  	}
    74  }
    75  
    76  func Test_clockResGet_Unsupported(t *testing.T) {
    77  	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig())
    78  	defer r.Close(testCtx)
    79  
    80  	tests := []struct {
    81  		name          string
    82  		clockID       uint32
    83  		expectedErrno Errno
    84  		expectedLog   string
    85  	}{
    86  		{
    87  			name:          "process cputime",
    88  			clockID:       2,
    89  			expectedErrno: ErrnoInval,
    90  			expectedLog: `
    91  --> proxy.clock_res_get(id=2,result.resolution=1)
    92  	==> wasi_snapshot_preview1.clock_res_get(id=2,result.resolution=1)
    93  	<== EINVAL
    94  <-- (28)
    95  `,
    96  		},
    97  		{
    98  			name:          "thread cputime",
    99  			clockID:       3,
   100  			expectedErrno: ErrnoInval,
   101  			expectedLog: `
   102  --> proxy.clock_res_get(id=3,result.resolution=1)
   103  	==> wasi_snapshot_preview1.clock_res_get(id=3,result.resolution=1)
   104  	<== EINVAL
   105  <-- (28)
   106  `,
   107  		},
   108  		{
   109  			name:          "undefined",
   110  			clockID:       100,
   111  			expectedErrno: ErrnoInval,
   112  			expectedLog: `
   113  --> proxy.clock_res_get(id=100,result.resolution=1)
   114  	==> wasi_snapshot_preview1.clock_res_get(id=100,result.resolution=1)
   115  	<== EINVAL
   116  <-- (28)
   117  `,
   118  		},
   119  	}
   120  
   121  	for _, tt := range tests {
   122  		tc := tt
   123  
   124  		t.Run(tc.name, func(t *testing.T) {
   125  			defer log.Reset()
   126  
   127  			resultResolution := uint32(1) // arbitrary offset
   128  			requireErrno(t, tc.expectedErrno, mod, functionClockResGet, uint64(tc.clockID), uint64(resultResolution))
   129  			require.Equal(t, tc.expectedLog, "\n"+log.String())
   130  		})
   131  	}
   132  }
   133  
   134  func Test_clockTimeGet(t *testing.T) {
   135  	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig())
   136  	defer r.Close(testCtx)
   137  
   138  	tests := []struct {
   139  		name           string
   140  		clockID        uint32
   141  		expectedMemory []byte
   142  		expectedLog    string
   143  	}{
   144  		{
   145  			name:    "Realtime",
   146  			clockID: clockIDRealtime,
   147  			expectedMemory: []byte{
   148  				'?',                                          // resultTimestamp is after this
   149  				0x0, 0x0, 0x1f, 0xa6, 0x70, 0xfc, 0xc5, 0x16, // little endian-encoded epochNanos
   150  				'?', // stopped after encoding
   151  			},
   152  			expectedLog: `
   153  --> proxy.clock_time_get(id=0,precision=0,result.timestamp=1)
   154  	==> wasi_snapshot_preview1.clock_time_get(id=0,precision=0,result.timestamp=1)
   155  	<== ESUCCESS
   156  <-- (0)
   157  `,
   158  		},
   159  		{
   160  			name:    "Monotonic",
   161  			clockID: clockIDMonotonic,
   162  			expectedMemory: []byte{
   163  				'?',                                    // resultTimestamp is after this
   164  				0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // fake nanotime starts at zero
   165  				'?', // stopped after encoding
   166  			},
   167  			expectedLog: `
   168  --> proxy.clock_time_get(id=1,precision=0,result.timestamp=1)
   169  	==> wasi_snapshot_preview1.clock_time_get(id=1,precision=0,result.timestamp=1)
   170  	<== ESUCCESS
   171  <-- (0)
   172  `,
   173  		},
   174  	}
   175  
   176  	for _, tt := range tests {
   177  		tc := tt
   178  		t.Run(tc.name, func(t *testing.T) {
   179  			defer log.Reset()
   180  
   181  			maskMemory(t, testCtx, mod, len(tc.expectedMemory))
   182  
   183  			resultTimestamp := uint32(1) // arbitrary offset
   184  			requireErrno(t, ErrnoSuccess, mod, functionClockTimeGet, uint64(tc.clockID), 0 /* TODO: precision */, uint64(resultTimestamp))
   185  			require.Equal(t, tc.expectedLog, "\n"+log.String())
   186  
   187  			actual, ok := mod.Memory().Read(testCtx, 0, uint32(len(tc.expectedMemory)))
   188  			require.True(t, ok)
   189  			require.Equal(t, tc.expectedMemory, actual)
   190  		})
   191  	}
   192  }
   193  
   194  func Test_clockTimeGet_Unsupported(t *testing.T) {
   195  	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig())
   196  	defer r.Close(testCtx)
   197  
   198  	tests := []struct {
   199  		name          string
   200  		clockID       uint32
   201  		expectedErrno Errno
   202  		expectedLog   string
   203  	}{
   204  		{
   205  			name:          "process cputime",
   206  			clockID:       2,
   207  			expectedErrno: ErrnoInval,
   208  			expectedLog: `
   209  --> proxy.clock_time_get(id=2,precision=0,result.timestamp=1)
   210  	==> wasi_snapshot_preview1.clock_time_get(id=2,precision=0,result.timestamp=1)
   211  	<== EINVAL
   212  <-- (28)
   213  `,
   214  		},
   215  		{
   216  			name:          "thread cputime",
   217  			clockID:       3,
   218  			expectedErrno: ErrnoInval,
   219  			expectedLog: `
   220  --> proxy.clock_time_get(id=3,precision=0,result.timestamp=1)
   221  	==> wasi_snapshot_preview1.clock_time_get(id=3,precision=0,result.timestamp=1)
   222  	<== EINVAL
   223  <-- (28)
   224  `,
   225  		},
   226  		{
   227  			name:          "undefined",
   228  			clockID:       100,
   229  			expectedErrno: ErrnoInval,
   230  			expectedLog: `
   231  --> proxy.clock_time_get(id=100,precision=0,result.timestamp=1)
   232  	==> wasi_snapshot_preview1.clock_time_get(id=100,precision=0,result.timestamp=1)
   233  	<== EINVAL
   234  <-- (28)
   235  `,
   236  		},
   237  	}
   238  
   239  	for _, tt := range tests {
   240  		tc := tt
   241  
   242  		t.Run(tc.name, func(t *testing.T) {
   243  			defer log.Reset()
   244  
   245  			resultTimestamp := uint32(1) // arbitrary offset
   246  
   247  			requireErrno(t, tc.expectedErrno, mod, functionClockTimeGet, uint64(tc.clockID), uint64(0) /* TODO: precision */, uint64(resultTimestamp))
   248  			require.Equal(t, tc.expectedLog, "\n"+log.String())
   249  		})
   250  	}
   251  }
   252  
   253  func Test_clockTimeGet_Errors(t *testing.T) {
   254  	mod, r, log := requireProxyModule(t, wazero.NewModuleConfig())
   255  	defer r.Close(testCtx)
   256  
   257  	memorySize := mod.Memory().Size(testCtx)
   258  
   259  	tests := []struct {
   260  		name                     string
   261  		resultTimestamp, argvLen uint32
   262  		expectedLog              string
   263  	}{
   264  		{
   265  			name:            "resultTimestamp out-of-memory",
   266  			resultTimestamp: memorySize,
   267  			expectedLog: `
   268  --> proxy.clock_time_get(id=0,precision=0,result.timestamp=65536)
   269  	==> wasi_snapshot_preview1.clock_time_get(id=0,precision=0,result.timestamp=65536)
   270  	<== EFAULT
   271  <-- (21)
   272  `,
   273  		},
   274  		{
   275  			name:            "resultTimestamp exceeds the maximum valid address by 1",
   276  			resultTimestamp: memorySize - 4 + 1, // 4 is the size of uint32, the type of the count of args
   277  			expectedLog: `
   278  --> proxy.clock_time_get(id=0,precision=0,result.timestamp=65533)
   279  	==> wasi_snapshot_preview1.clock_time_get(id=0,precision=0,result.timestamp=65533)
   280  	<== EFAULT
   281  <-- (21)
   282  `,
   283  		},
   284  	}
   285  
   286  	for _, tt := range tests {
   287  		tc := tt
   288  
   289  		t.Run(tc.name, func(t *testing.T) {
   290  			defer log.Reset()
   291  
   292  			requireErrno(t, ErrnoFault, mod, functionClockTimeGet, uint64(0) /* TODO: id */, uint64(0) /* TODO: precision */, uint64(tc.resultTimestamp))
   293  			require.Equal(t, tc.expectedLog, "\n"+log.String())
   294  		})
   295  	}
   296  }