aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/benchmark.go12
-rw-r--r--src/testing/benchmark_test.go11
-rw-r--r--src/testing/example.go4
-rw-r--r--src/testing/export_test.go4
-rw-r--r--src/testing/fstest/mapfs.go6
-rw-r--r--src/testing/fstest/testfs.go16
-rw-r--r--src/testing/fstest/testfs_test.go7
-rw-r--r--src/testing/fuzz.go10
-rw-r--r--src/testing/internal/testdeps/deps.go40
-rw-r--r--src/testing/newcover.go15
-rw-r--r--src/testing/testing.go47
-rw-r--r--src/testing/testing_other.go18
-rw-r--r--src/testing/testing_test.go3
-rw-r--r--src/testing/testing_windows.go38
-rw-r--r--src/testing/testing_windows_test.go25
15 files changed, 194 insertions, 62 deletions
diff --git a/src/testing/benchmark.go b/src/testing/benchmark.go
index 9491213ef1..80a1b7de77 100644
--- a/src/testing/benchmark.go
+++ b/src/testing/benchmark.go
@@ -12,7 +12,7 @@ import (
"math"
"os"
"runtime"
- "sort"
+ "slices"
"strconv"
"strings"
"sync"
@@ -123,7 +123,7 @@ func (b *B) StartTimer() {
runtime.ReadMemStats(&memStats)
b.startAllocs = memStats.Mallocs
b.startBytes = memStats.TotalAlloc
- b.start = time.Now()
+ b.start = highPrecisionTimeNow()
b.timerOn = true
}
}
@@ -133,7 +133,7 @@ func (b *B) StartTimer() {
// want to measure.
func (b *B) StopTimer() {
if b.timerOn {
- b.duration += time.Since(b.start)
+ b.duration += highPrecisionTimeSince(b.start)
runtime.ReadMemStats(&memStats)
b.netAllocs += memStats.Mallocs - b.startAllocs
b.netBytes += memStats.TotalAlloc - b.startBytes
@@ -156,7 +156,7 @@ func (b *B) ResetTimer() {
runtime.ReadMemStats(&memStats)
b.startAllocs = memStats.Mallocs
b.startBytes = memStats.TotalAlloc
- b.start = time.Now()
+ b.start = highPrecisionTimeNow()
}
b.duration = 0
b.netAllocs = 0
@@ -325,7 +325,7 @@ func (b *B) launch() {
func (b *B) Elapsed() time.Duration {
d := b.duration
if b.timerOn {
- d += time.Since(b.start)
+ d += highPrecisionTimeSince(b.start)
}
return d
}
@@ -443,7 +443,7 @@ func (r BenchmarkResult) String() string {
}
extraKeys = append(extraKeys, k)
}
- sort.Strings(extraKeys)
+ slices.Sort(extraKeys)
for _, k := range extraKeys {
buf.WriteByte('\t')
prettyPrint(buf, r.Extra[k], k)
diff --git a/src/testing/benchmark_test.go b/src/testing/benchmark_test.go
index 2987170827..66f555d1f1 100644
--- a/src/testing/benchmark_test.go
+++ b/src/testing/benchmark_test.go
@@ -6,8 +6,9 @@ package testing_test
import (
"bytes"
+ "cmp"
"runtime"
- "sort"
+ "slices"
"strings"
"sync/atomic"
"testing"
@@ -168,9 +169,9 @@ func ExampleB_ReportMetric() {
var compares int64
for i := 0; i < b.N; i++ {
s := []int{5, 4, 3, 2, 1}
- sort.Slice(s, func(i, j int) bool {
+ slices.SortFunc(s, func(a, b int) int {
compares++
- return s[i] < s[j]
+ return cmp.Compare(a, b)
})
}
// This metric is per-operation, so divide by b.N and
@@ -190,12 +191,12 @@ func ExampleB_ReportMetric_parallel() {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
s := []int{5, 4, 3, 2, 1}
- sort.Slice(s, func(i, j int) bool {
+ slices.SortFunc(s, func(a, b int) int {
// Because RunParallel runs the function many
// times in parallel, we must increment the
// counter atomically to avoid racing writes.
compares.Add(1)
- return s[i] < s[j]
+ return cmp.Compare(a, b)
})
}
})
diff --git a/src/testing/example.go b/src/testing/example.go
index 07aa5cb66c..b14477a406 100644
--- a/src/testing/example.go
+++ b/src/testing/example.go
@@ -6,7 +6,7 @@ package testing
import (
"fmt"
- "sort"
+ "slices"
"strings"
"time"
)
@@ -47,7 +47,7 @@ func runExamples(matchString func(pat, str string) (bool, error), examples []Int
func sortLines(output string) string {
lines := strings.Split(output, "\n")
- sort.Strings(lines)
+ slices.Sort(lines)
return strings.Join(lines, "\n")
}
diff --git a/src/testing/export_test.go b/src/testing/export_test.go
index 0022491ecd..10a5b04aee 100644
--- a/src/testing/export_test.go
+++ b/src/testing/export_test.go
@@ -5,3 +5,7 @@
package testing
var PrettyPrint = prettyPrint
+
+type HighPrecisionTime = highPrecisionTime
+
+var HighPrecisionTimeNow = highPrecisionTimeNow
diff --git a/src/testing/fstest/mapfs.go b/src/testing/fstest/mapfs.go
index f7f8ccd9ec..5e3720b0ed 100644
--- a/src/testing/fstest/mapfs.go
+++ b/src/testing/fstest/mapfs.go
@@ -8,7 +8,7 @@ import (
"io"
"io/fs"
"path"
- "sort"
+ "slices"
"strings"
"time"
)
@@ -100,8 +100,8 @@ func (fsys MapFS) Open(name string) (fs.File, error) {
for name := range need {
list = append(list, mapFileInfo{name, &MapFile{Mode: fs.ModeDir | 0555}})
}
- sort.Slice(list, func(i, j int) bool {
- return list[i].name < list[j].name
+ slices.SortFunc(list, func(a, b mapFileInfo) int {
+ return strings.Compare(a.name, b.name)
})
if file == nil {
diff --git a/src/testing/fstest/testfs.go b/src/testing/fstest/testfs.go
index 0fd7d4806f..080bcdd65f 100644
--- a/src/testing/fstest/testfs.go
+++ b/src/testing/fstest/testfs.go
@@ -12,7 +12,7 @@ import (
"io/fs"
"path"
"reflect"
- "sort"
+ "slices"
"strings"
"testing/iotest"
)
@@ -78,7 +78,7 @@ func testFS(fsys fs.FS, expected ...string) error {
list = append(list, k)
}
}
- sort.Strings(list)
+ slices.Sort(list)
if len(list) > 15 {
list = append(list[:10], "...")
}
@@ -362,9 +362,9 @@ func (t *fsTester) checkGlob(dir string, list []fs.DirEntry) {
return
}
- if !sort.StringsAreSorted(names) {
+ if !slices.IsSorted(names) {
t.errorf("%s: Glob(%#q): unsorted output:\n%s", dir, glob, strings.Join(names, "\n"))
- sort.Strings(names)
+ slices.Sort(names)
}
var problems []string
@@ -488,11 +488,11 @@ func (t *fsTester) checkDirList(dir, desc string, list1, list2 []fs.DirEntry) {
return
}
- sort.Slice(diffs, func(i, j int) bool {
- fi := strings.Fields(diffs[i])
- fj := strings.Fields(diffs[j])
+ slices.SortFunc(diffs, func(a, b string) int {
+ fa := strings.Fields(a)
+ fb := strings.Fields(b)
// sort by name (i < j) and then +/- (j < i, because + < -)
- return fi[1]+" "+fj[0] < fj[1]+" "+fi[0]
+ return strings.Compare(fa[1]+" "+fb[0], fb[1]+" "+fa[0])
})
t.errorf("%s: diff %s:\n\t%s", dir, desc, strings.Join(diffs, "\n\t"))
diff --git a/src/testing/fstest/testfs_test.go b/src/testing/fstest/testfs_test.go
index b9f10c613a..2ef1053a01 100644
--- a/src/testing/fstest/testfs_test.go
+++ b/src/testing/fstest/testfs_test.go
@@ -10,7 +10,8 @@ import (
"io/fs"
"os"
"path/filepath"
- "sort"
+ "slices"
+ "strings"
"testing"
)
@@ -61,8 +62,8 @@ func (f *shuffledFile) ReadDir(n int) ([]fs.DirEntry, error) {
//
// We do this to make sure that the TestFS test suite is not affected by the
// order of directory entries.
- sort.Slice(dirents, func(i, j int) bool {
- return dirents[i].Name() > dirents[j].Name()
+ slices.SortFunc(dirents, func(a, b fs.DirEntry) int {
+ return strings.Compare(b.Name(), a.Name())
})
return dirents, err
}
diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go
index baf1c7243c..d561225b3c 100644
--- a/src/testing/fuzz.go
+++ b/src/testing/fuzz.go
@@ -674,7 +674,7 @@ func fRunner(f *F, fn func(*F)) {
}
for root := &f.common; root.parent != nil; root = root.parent {
root.mu.Lock()
- root.duration += time.Since(root.start)
+ root.duration += highPrecisionTimeSince(root.start)
d := root.duration
root.mu.Unlock()
root.flushToParent(root.name, "--- FAIL: %s (%s)\n", root.name, fmtDuration(d))
@@ -687,7 +687,7 @@ func fRunner(f *F, fn func(*F)) {
}
// No panic or inappropriate Goexit.
- f.duration += time.Since(f.start)
+ f.duration += highPrecisionTimeSince(f.start)
if len(f.sub) > 0 {
// Unblock inputs that called T.Parallel while running the seed corpus.
@@ -700,9 +700,9 @@ func fRunner(f *F, fn func(*F)) {
for _, sub := range f.sub {
<-sub.signal
}
- cleanupStart := time.Now()
+ cleanupStart := highPrecisionTimeNow()
err := f.runCleanup(recoverAndReturnPanic)
- f.duration += time.Since(cleanupStart)
+ f.duration += highPrecisionTimeSince(cleanupStart)
if err != nil {
doPanic(err)
}
@@ -719,7 +719,7 @@ func fRunner(f *F, fn func(*F)) {
}
}()
- f.start = time.Now()
+ f.start = highPrecisionTimeNow()
f.resetRaces()
fn(f)
diff --git a/src/testing/internal/testdeps/deps.go b/src/testing/internal/testdeps/deps.go
index 868307550e..3b5dc7198f 100644
--- a/src/testing/internal/testdeps/deps.go
+++ b/src/testing/internal/testdeps/deps.go
@@ -26,6 +26,9 @@ import (
"time"
)
+// Cover indicates whether coverage is enabled.
+var Cover bool
+
// TestDeps is an implementation of the testing.testDeps interface,
// suitable for passing to [testing.MainStart].
type TestDeps struct{}
@@ -197,3 +200,40 @@ func (TestDeps) ResetCoverage() {
func (TestDeps) SnapshotCoverage() {
fuzz.SnapshotCoverage()
}
+
+var CoverMode string
+var Covered string
+
+// These variables below are set at runtime (via code in testmain) to point
+// to the equivalent functions in package internal/coverage/cfile; doing
+// things this way allows us to have tests import internal/coverage/cfile
+// only when -cover is in effect (as opposed to importing for all tests).
+var (
+ CoverSnapshotFunc func() float64
+ CoverProcessTestDirFunc func(dir string, cfile string, cm string, cpkg string, w io.Writer) error
+ CoverMarkProfileEmittedFunc func(val bool)
+)
+
+func (TestDeps) InitRuntimeCoverage() (mode string, tearDown func(string, string) (string, error), snapcov func() float64) {
+ if CoverMode == "" {
+ return
+ }
+ return CoverMode, coverTearDown, CoverSnapshotFunc
+}
+
+func coverTearDown(coverprofile string, gocoverdir string) (string, error) {
+ var err error
+ if gocoverdir == "" {
+ gocoverdir, err = os.MkdirTemp("", "gocoverdir")
+ if err != nil {
+ return "error setting GOCOVERDIR: bad os.MkdirTemp return", err
+ }
+ defer os.RemoveAll(gocoverdir)
+ }
+ CoverMarkProfileEmittedFunc(true)
+ cmode := CoverMode
+ if err := CoverProcessTestDirFunc(gocoverdir, coverprofile, cmode, Covered, os.Stdout); err != nil {
+ return "error generating coverage report", err
+ }
+ return "", nil
+}
diff --git a/src/testing/newcover.go b/src/testing/newcover.go
index 6199f3bd7b..ad2f622640 100644
--- a/src/testing/newcover.go
+++ b/src/testing/newcover.go
@@ -10,6 +10,7 @@ import (
"fmt"
"internal/goexperiment"
"os"
+ _ "unsafe" // for linkname
)
// cover2 variable stores the current coverage mode and a
@@ -20,10 +21,13 @@ var cover2 struct {
snapshotcov func() float64
}
-// registerCover2 is invoked during "go test -cover" runs by the test harness
-// code in _testmain.go; it is used to record a 'tear down' function
+// registerCover2 is invoked during "go test -cover" runs.
+// It is used to record a 'tear down' function
// (to be called when the test is complete) and the coverage mode.
func registerCover2(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error), snapcov func() float64) {
+ if mode == "" {
+ return
+ }
cover2.mode = mode
cover2.tearDown = tearDown
cover2.snapshotcov = snapcov
@@ -42,13 +46,6 @@ func coverReport2() {
}
}
-// testGoCoverDir returns the value passed to the -test.gocoverdir
-// flag by the Go command, if goexperiment.CoverageRedesign is
-// in effect.
-func testGoCoverDir() string {
- return *gocoverdir
-}
-
// coverage2 returns a rough "coverage percentage so far"
// number to support the testing.Coverage() function.
func coverage2() float64 {
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 9c1325a609..200fa659b8 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -72,14 +72,15 @@
// A sample benchmark function looks like this:
//
// func BenchmarkRandInt(b *testing.B) {
-// for i := 0; i < b.N; i++ {
+// for range b.N {
// rand.Int()
// }
// }
//
// The benchmark function must run the target code b.N times.
-// During benchmark execution, b.N is adjusted until the benchmark function lasts
-// long enough to be timed reliably. The output
+// It is called multiple times with b.N adjusted until the
+// benchmark function lasts long enough to be timed reliably.
+// The output
//
// BenchmarkRandInt-8 68453040 17.8 ns/op
//
@@ -91,7 +92,7 @@
// func BenchmarkBigLen(b *testing.B) {
// big := NewBig()
// b.ResetTimer()
-// for i := 0; i < b.N; i++ {
+// for range b.N {
// big.Len()
// }
// }
@@ -382,7 +383,7 @@ import (
"runtime"
"runtime/debug"
"runtime/trace"
- "sort"
+ "slices"
"strconv"
"strings"
"sync"
@@ -615,10 +616,10 @@ type common struct {
isParallel bool // Whether the test is parallel.
parent *common
- level int // Nesting depth of test or benchmark.
- creator []uintptr // If level > 0, the stack trace at the point where the parent called t.Run.
- name string // Name of test or benchmark.
- start time.Time // Time test or benchmark started
+ level int // Nesting depth of test or benchmark.
+ creator []uintptr // If level > 0, the stack trace at the point where the parent called t.Run.
+ name string // Name of test or benchmark.
+ start highPrecisionTime // Time test or benchmark started
duration time.Duration
barrier chan bool // To signal parallel subtests they may start. Nil when T.Parallel is not present (B) or not usable (when fuzzing).
signal chan bool // To signal a test is done.
@@ -1457,7 +1458,7 @@ func (t *T) Parallel() {
// We don't want to include the time we spend waiting for serial tests
// in the test duration. Record the elapsed time thus far and reset the
// timer afterwards.
- t.duration += time.Since(t.start)
+ t.duration += highPrecisionTimeSince(t.start)
// Add to the list of tests to be released by the parent.
t.parent.sub = append(t.parent.sub, t)
@@ -1486,8 +1487,8 @@ func (t *T) Parallel() {
if t.chatty != nil {
t.chatty.Updatef(t.name, "=== CONT %s\n", t.name)
}
- running.Store(t.name, time.Now())
- t.start = time.Now()
+ running.Store(t.name, highPrecisionTimeNow())
+ t.start = highPrecisionTimeNow()
// Reset the local race counter to ignore any races that happened while this
// goroutine was blocked, such as in the parent test or in other parallel
@@ -1619,7 +1620,7 @@ func tRunner(t *T, fn func(t *T)) {
// Flush the output log up to the root before dying.
for root := &t.common; root.parent != nil; root = root.parent {
root.mu.Lock()
- root.duration += time.Since(root.start)
+ root.duration += highPrecisionTimeSince(root.start)
d := root.duration
root.mu.Unlock()
root.flushToParent(root.name, "--- FAIL: %s (%s)\n", root.name, fmtDuration(d))
@@ -1634,7 +1635,7 @@ func tRunner(t *T, fn func(t *T)) {
doPanic(err)
}
- t.duration += time.Since(t.start)
+ t.duration += highPrecisionTimeSince(t.start)
if len(t.sub) > 0 {
// Run parallel subtests.
@@ -1652,10 +1653,10 @@ func tRunner(t *T, fn func(t *T)) {
// Run any cleanup callbacks, marking the test as running
// in case the cleanup hangs.
- cleanupStart := time.Now()
+ cleanupStart := highPrecisionTimeNow()
running.Store(t.name, cleanupStart)
err := t.runCleanup(recoverAndReturnPanic)
- t.duration += time.Since(cleanupStart)
+ t.duration += highPrecisionTimeSince(cleanupStart)
if err != nil {
doPanic(err)
}
@@ -1684,7 +1685,7 @@ func tRunner(t *T, fn func(t *T)) {
}
}()
- t.start = time.Now()
+ t.start = highPrecisionTimeNow()
t.resetRaces()
fn(t)
@@ -1732,7 +1733,7 @@ func (t *T) Run(name string, f func(t *T)) bool {
if t.chatty != nil {
t.chatty.Updatef(t.name, "=== RUN %s\n", t.name)
}
- running.Store(t.name, time.Now())
+ running.Store(t.name, highPrecisionTimeNow())
// Instead of reducing the running count of this test before calling the
// tRunner and increasing it afterwards, we rely on tRunner keeping the
@@ -1854,6 +1855,10 @@ func (f matchStringOnly) CheckCorpus([]any, []reflect.Type) error { return nil }
func (f matchStringOnly) ResetCoverage() {}
func (f matchStringOnly) SnapshotCoverage() {}
+func (f matchStringOnly) InitRuntimeCoverage() (mode string, tearDown func(string, string) (string, error), snapcov func() float64) {
+ return
+}
+
// Main is an internal function, part of the implementation of the "go test" command.
// It was exported because it is cross-package and predates "internal" packages.
// It is no longer used by "go test" but preserved, as much as possible, for other
@@ -1901,12 +1906,14 @@ type testDeps interface {
CheckCorpus([]any, []reflect.Type) error
ResetCoverage()
SnapshotCoverage()
+ InitRuntimeCoverage() (mode string, tearDown func(coverprofile string, gocoverdir string) (string, error), snapcov func() float64)
}
// MainStart is meant for use by tests generated by 'go test'.
// It is not meant to be called directly and is not subject to the Go 1 compatibility document.
// It may change signature from release to release.
func MainStart(deps testDeps, tests []InternalTest, benchmarks []InternalBenchmark, fuzzTargets []InternalFuzzTarget, examples []InternalExample) *M {
+ registerCover2(deps.InitRuntimeCoverage())
Init()
return &M{
deps: deps,
@@ -2372,10 +2379,10 @@ func (m *M) startAlarm() time.Time {
func runningList() []string {
var list []string
running.Range(func(k, v any) bool {
- list = append(list, fmt.Sprintf("%s (%v)", k.(string), time.Since(v.(time.Time)).Round(time.Second)))
+ list = append(list, fmt.Sprintf("%s (%v)", k.(string), highPrecisionTimeSince(v.(highPrecisionTime)).Round(time.Second)))
return true
})
- sort.Strings(list)
+ slices.Sort(list)
return list
}
diff --git a/src/testing/testing_other.go b/src/testing/testing_other.go
index 99a6276a4a..f91e3b4a2c 100644
--- a/src/testing/testing_other.go
+++ b/src/testing/testing_other.go
@@ -6,8 +6,26 @@
package testing
+import "time"
+
// isWindowsRetryable reports whether err is a Windows error code
// that may be fixed by retrying a failed filesystem operation.
func isWindowsRetryable(err error) bool {
return false
}
+
+// highPrecisionTime represents a single point in time.
+// On all systems except Windows, using time.Time is fine.
+type highPrecisionTime struct {
+ now time.Time
+}
+
+// highPrecisionTimeNow returns high precision time for benchmarking.
+func highPrecisionTimeNow() highPrecisionTime {
+ return highPrecisionTime{now: time.Now()}
+}
+
+// highPrecisionTimeSince returns duration since b.
+func highPrecisionTimeSince(b highPrecisionTime) time.Duration {
+ return time.Since(b.now)
+}
diff --git a/src/testing/testing_test.go b/src/testing/testing_test.go
index d3822dfd57..4a9303952e 100644
--- a/src/testing/testing_test.go
+++ b/src/testing/testing_test.go
@@ -762,7 +762,8 @@ func parseRunningTests(out []byte) (runningTests []string, ok bool) {
inRunningTests := false
for _, line := range strings.Split(string(out), "\n") {
if inRunningTests {
- if trimmed, ok := strings.CutPrefix(line, "\t"); ok {
+ // Package testing adds one tab, the panic printer adds another.
+ if trimmed, ok := strings.CutPrefix(line, "\t\t"); ok {
if name, _, ok := strings.Cut(trimmed, " "); ok {
runningTests = append(runningTests, name)
continue
diff --git a/src/testing/testing_windows.go b/src/testing/testing_windows.go
index fd48ae9579..ebe4e01d23 100644
--- a/src/testing/testing_windows.go
+++ b/src/testing/testing_windows.go
@@ -9,7 +9,9 @@ package testing
import (
"errors"
"internal/syscall/windows"
+ "math/bits"
"syscall"
+ "time"
)
// isWindowsRetryable reports whether err is a Windows error code
@@ -30,3 +32,39 @@ func isWindowsRetryable(err error) bool {
}
return false
}
+
+// highPrecisionTime represents a single point in time with query performance counter.
+// time.Time on Windows has low system granularity, which is not suitable for
+// measuring short time intervals.
+//
+// TODO: If Windows runtime implements high resolution timing then highPrecisionTime
+// can be removed.
+type highPrecisionTime struct {
+ now int64
+}
+
+// highPrecisionTimeNow returns high precision time for benchmarking.
+func highPrecisionTimeNow() highPrecisionTime {
+ var t highPrecisionTime
+ // This should always succeed for Windows XP and above.
+ t.now = windows.QueryPerformanceCounter()
+ return t
+}
+
+func (a highPrecisionTime) sub(b highPrecisionTime) time.Duration {
+ delta := a.now - b.now
+
+ if queryPerformanceFrequency == 0 {
+ queryPerformanceFrequency = windows.QueryPerformanceFrequency()
+ }
+ hi, lo := bits.Mul64(uint64(delta), uint64(time.Second)/uint64(time.Nanosecond))
+ quo, _ := bits.Div64(hi, lo, uint64(queryPerformanceFrequency))
+ return time.Duration(quo)
+}
+
+var queryPerformanceFrequency int64
+
+// highPrecisionTimeSince returns duration since a.
+func highPrecisionTimeSince(a highPrecisionTime) time.Duration {
+ return highPrecisionTimeNow().sub(a)
+}
diff --git a/src/testing/testing_windows_test.go b/src/testing/testing_windows_test.go
new file mode 100644
index 0000000000..e75232dede
--- /dev/null
+++ b/src/testing/testing_windows_test.go
@@ -0,0 +1,25 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package testing_test
+
+import (
+ "testing"
+ "time"
+)
+
+var sink time.Time
+var sinkHPT testing.HighPrecisionTime
+
+func BenchmarkTimeNow(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sink = time.Now()
+ }
+}
+
+func BenchmarkHighPrecisionTimeNow(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ sinkHPT = testing.HighPrecisionTimeNow()
+ }
+}