blob: afd9af2af4796537a63f10d8f3e66d023d9e26af [file] [log] [blame]
// 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)
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
}