Skip to content

Commit

Permalink
allow test to output json trace associated with its name
Browse files Browse the repository at this point in the history
  • Loading branch information
xhd2015 committed Mar 19, 2024
1 parent cbdc296 commit 1030fb3
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 32 deletions.
4 changes: 2 additions & 2 deletions cmd/xgo/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package main
import "fmt"

const VERSION = "1.0.1"
const REVISION = "6eca2e984823b4e5d9621e9bd82e4d8db2b18895+1"
const NUMBER = 81
const REVISION = "cbdc296ff629fdba79e44589f2ce7fa1891c85f1+1"
const NUMBER = 82

func getRevision() string {
return fmt.Sprintf("%s %s BUILD_%d", VERSION, REVISION, NUMBER)
Expand Down
4 changes: 2 additions & 2 deletions runtime/core/version.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package core

const VERSION = "1.0.1"
const REVISION = "6eca2e984823b4e5d9621e9bd82e4d8db2b18895+1"
const NUMBER = 81
const REVISION = "cbdc296ff629fdba79e44589f2ce7fa1891c85f1+1"
const NUMBER = 82
117 changes: 89 additions & 28 deletions runtime/trace/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"sync"
"testing"
"time"
"unsafe"

Expand All @@ -19,13 +19,43 @@ import (

const __XGO_SKIP_TRAP = true

// hold goroutine stacks, keyed by goroutine ptr
var stackMap sync.Map // uintptr(goroutine) -> *Root
var testInfoMaping sync.Map // uintptr(goroutine) -> *testInfo

type testInfo struct {
name string
}

func init() {
__xgo_link_on_test_start(func(t *testing.T, fn func(t *testing.T)) {
name := t.Name()
if name == "" {
return
}
key := uintptr(__xgo_link_getcurg())
testInfoMaping.LoadOrStore(key, &testInfo{
name: name,
})
})
__xgo_link_on_goexit(func() {
key := uintptr(__xgo_link_getcurg())
testInfoMaping.Delete(key)
})
}

// link by compiler
func __xgo_link_on_test_start(fn func(t *testing.T, fn func(t *testing.T))) {
}

// link by compiler
func __xgo_link_getcurg() unsafe.Pointer {
panic(errors.New("failed to link __xgo_link_getcurg"))
}

// hold goroutine stacks, keyed by goroutine ptr
var stackMap sync.Map // uintptr(goroutine) -> *Root
func __xgo_link_on_goexit(fn func()) {
panic("failed to link __xgo_link_on_goexit")
}

type Root struct {
// current executed function
Expand Down Expand Up @@ -115,41 +145,72 @@ func SetMarshalStack(fn func(stack *Stack) ([]byte, error)) {
marshalStack = fn
}

// this should also be marked as trap.Skip()
func emitTrace(stack *Stack) error {
// write to file
var trace []byte
var err error
func fmtStack(stack *Stack) (data []byte, err error) {
defer func() {
if e := recover(); e != nil {
if pe, ok := e.(error); ok {
err = pe
} else {
err = fmt.Errorf("panic: %v", e)
}
return
}
}()
if marshalStack != nil {
trace, err = marshalStack(stack)
} else {
trace, err = json.Marshal(stack)
}
if err != nil {
return err
return marshalStack(stack)
}
return json.Marshal(stack)
}

// this should also be marked as trap.Skip()
// TODO: may add callback for this
func emitTrace(stack *Stack) error {
var testName string

traceIDNum := int64(1)
ghex := fmt.Sprintf("g_%x", __xgo_link_getcurg())
traceID := "t_" + strconv.FormatInt(traceIDNum, 10)
key := uintptr(__xgo_link_getcurg())
tinfo, ok := testInfoMaping.Load(key)
if ok {
testName = tinfo.(*testInfo).name
}

xgoTraceOutput := getTraceOutput()
if xgoTraceOutput == "" {
xgoTraceOutput = time.Now().Format("trace_20060102_150405")
useStdout := xgoTraceOutput == "stdout"
subName := testName
if testName == "" {
traceIDNum := int64(1)
ghex := fmt.Sprintf("g_%x", __xgo_link_getcurg())
traceID := "t_" + strconv.FormatInt(traceIDNum, 10)
if xgoTraceOutput == "" {
traceDir := time.Now().Format("trace_20060102_150405")
subName = filepath.Join(traceDir, ghex, traceID)
} else if useStdout {
subName = fmt.Sprintf("%s/%s", ghex, traceID)
} else {
subName = filepath.Join(xgoTraceOutput, ghex, traceID)
}
}

if useStdout {
fmt.Printf("%s: ", subName)
}
if xgoTraceOutput == "stdout" {
// TODO: may add callback for this
fmt.Printf("%s/%s: ", ghex, traceID)
fmt.Println(string(trace))
var traceOut []byte
trace, stackErr := fmtStack(stack)
if stackErr != nil {
traceOut = []byte("error:" + stackErr.Error())
} else {
traceOut = trace
}

if useStdout {
fmt.Print(traceOut)
return nil
}

dir := filepath.Join(xgoTraceOutput, ghex)
err = os.MkdirAll(dir, 0755)
subFile := subName + ".json"
subDir := filepath.Dir(subFile)
err := os.MkdirAll(subDir, 0755)
if err != nil {
return err
}
file := filepath.Join(dir, traceID+".json")

return ioutil.WriteFile(file, trace, 0755)
return os.WriteFile(subFile, traceOut, 0755)
}

0 comments on commit 1030fb3

Please sign in to comment.