go/src/runtime/time_test.go
Bryan C. Mills 3f8f929d60 cmd/link/internal/ld: move more of mustLinkExternal into internal/platform
internal/platform.MustLinkExternal is used in various places to
determine whether external linking is required. It should always
match what the linker actually requires, but today does not match
because the linker imposes additional constraints.

Updates #31544.

Change-Id: I0cc6ad587e95c607329dea5d60d29a5fb2a9e722
Reviewed-on: https://go-review.googlesource.com/c/go/+/472515
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
2023-03-02 16:34:21 +00:00

98 lines
2.0 KiB
Go

// Copyright 2019 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 runtime_test
import (
"bytes"
"encoding/binary"
"errors"
"internal/testenv"
"os/exec"
"reflect"
"runtime"
"testing"
)
func TestFakeTime(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("faketime not supported on windows")
}
// Faketime is advanced in checkdead. External linking brings in cgo,
// causing checkdead not working.
testenv.MustInternalLink(t, false)
t.Parallel()
exe, err := buildTestProg(t, "testfaketime", "-tags=faketime")
if err != nil {
t.Fatal(err)
}
var stdout, stderr bytes.Buffer
cmd := exec.Command(exe)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err = testenv.CleanCmdEnv(cmd).Run()
if err != nil {
t.Fatalf("exit status: %v\n%s", err, stderr.String())
}
t.Logf("raw stdout: %q", stdout.String())
t.Logf("raw stderr: %q", stderr.String())
f1, err1 := parseFakeTime(stdout.Bytes())
if err1 != nil {
t.Fatal(err1)
}
f2, err2 := parseFakeTime(stderr.Bytes())
if err2 != nil {
t.Fatal(err2)
}
const time0 = 1257894000000000000
got := [][]fakeTimeFrame{f1, f2}
var want = [][]fakeTimeFrame{{
{time0 + 1, "line 2\n"},
{time0 + 1, "line 3\n"},
{time0 + 1e9, "line 5\n"},
{time0 + 1e9, "2009-11-10T23:00:01Z"},
}, {
{time0, "line 1\n"},
{time0 + 2, "line 4\n"},
}}
if !reflect.DeepEqual(want, got) {
t.Fatalf("want %v, got %v", want, got)
}
}
type fakeTimeFrame struct {
time uint64
data string
}
func parseFakeTime(x []byte) ([]fakeTimeFrame, error) {
var frames []fakeTimeFrame
for len(x) != 0 {
if len(x) < 4+8+4 {
return nil, errors.New("truncated header")
}
const magic = "\x00\x00PB"
if string(x[:len(magic)]) != magic {
return nil, errors.New("bad magic")
}
x = x[len(magic):]
time := binary.BigEndian.Uint64(x)
x = x[8:]
dlen := binary.BigEndian.Uint32(x)
x = x[4:]
data := string(x[:dlen])
x = x[dlen:]
frames = append(frames, fakeTimeFrame{time, data})
}
return frames, nil
}