Skip to content

Commit

Permalink
add test for go1.23rc1
Browse files Browse the repository at this point in the history
  • Loading branch information
xhd2015 committed Jul 21, 2024
1 parent b2c1918 commit 2d7e447
Show file tree
Hide file tree
Showing 38 changed files with 1,601 additions and 21 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/go-next.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: Go Next

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:

tests-with-go-next:
strategy:
matrix:
os: [ ubuntu-latest]
go: [ '1.23rc1' ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3

- name: Set up Go
run: |
curl -fsSL -o go.tar.gz "https://go.dev/dl/go${{matrix.go}}.linux-amd64.tar.gz"
mkdir setup
tar -C setup -xzf go.tar.gz
ls setup
GOROOT=$PWD/setup/go PATH=$PWD/setup/go/bin:$PATH go version
- name: Test
run: GOROOT=$PWD/setup/go PATH=$PWD/setup/go/bin:$PATH go run ./script/run-test --reset-instrument --debug -v
4 changes: 2 additions & 2 deletions cmd/xgo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,8 +711,8 @@ func checkGoVersion(goroot string, noInstrument bool) (*goinfo.GoVersion, error)
}
if !noInstrument {
minor := goVersion.Minor
if goVersion.Major != 1 || (minor < 17 || minor > 22) {
return nil, fmt.Errorf("only supports go1.17.0 ~ go1.22.1, current: %s", goVersionStr)
if goVersion.Major != 1 || (minor < 17 || minor > 23) {
return nil, fmt.Errorf("only supports go1.17 ~ go1.23, current: %s", goVersionStr)
}
}
return goVersion, nil
Expand Down
2 changes: 1 addition & 1 deletion cmd/xgo/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func patchRuntimeAndCompiler(origGoroot string, goroot string, xgoSrc string, go
}

// runtime
err := patchRuntimeAndTesting(goroot, goVersion)
err := patchRuntimeAndTesting(origGoroot, goroot, goVersion)
if err != nil {
return err
}
Expand Down
6 changes: 4 additions & 2 deletions cmd/xgo/patch/runtime_def.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ func __xgo_get_pc_name_impl(pc uintptr) string {
`

// start with go1.21, the runtime.FuncForPC(pc).Name()
// was wrapped in funcNameForPrint(...), we unwrap it
// NOTE: when upgrading to go1.23, should check
// is wrapped in funcNameForPrint(...), we unwrap it.
// it is confirmed that in go1.21,go1.22 and go1.23,
// the name is wrapped.
// NOTE: when upgrading to go1.24, should check
// the implementation again
const RuntimeGetFuncName_Go121 = `
func __xgo_get_pc_name_impl(pc uintptr) string {
Expand Down
3 changes: 3 additions & 0 deletions cmd/xgo/patch_compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ func patchCompilerNoder(goroot string, goVersion *goinfo.GoVersion) error {
noderFiles = patch.NoderFiles_1_21
} else if minor == 22 {
noderFiles = patch.NoderFiles_1_21
} else if minor == 23 {
// TODO: verify
noderFiles = patch.NoderFiles_1_21
}
}
if noderFiles == "" {
Expand Down
69 changes: 56 additions & 13 deletions cmd/xgo/patch_runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (

"github.com/xhd2015/xgo/cmd/xgo/patch"
"github.com/xhd2015/xgo/support/filecopy"
"github.com/xhd2015/xgo/support/fileutil"
"github.com/xhd2015/xgo/support/goinfo"
ast_patch "github.com/xhd2015/xgo/support/transform/patch"
)

var xgoAutoGenRegisterFuncHelper = _FilePath{"src", "runtime", "__xgo_autogen_register_func_helper.go"}
Expand Down Expand Up @@ -57,12 +59,12 @@ var runtimeFiles = []_FilePath{
timeSleep,
}

func patchRuntimeAndTesting(goroot string, goVersion *goinfo.GoVersion) error {
func patchRuntimeAndTesting(origGoroot string, goroot string, goVersion *goinfo.GoVersion) error {
err := patchRuntimeProc(goroot, goVersion)
if err != nil {
return err
}
err = patchRuntimeTesting(goroot)
err = patchRuntimeTesting(origGoroot, goroot, goVersion)
if err != nil {
return err
}
Expand Down Expand Up @@ -114,8 +116,8 @@ func addRuntimeFunctions(goroot string, goVersion *goinfo.GoVersion, xgoSrc stri
}

// func name patch
if goVersion.Major > 1 || goVersion.Minor > 22 {
panic("should check the implementation of runtime.FuncForPC(pc).Name() to ensure __xgo_get_pc_name is not wrapped in print format above go1.22")
if goVersion.Major > 1 || goVersion.Minor > 23 {
panic("should check the implementation of runtime.FuncForPC(pc).Name() to ensure __xgo_get_pc_name is not wrapped in print format above go1.23,it is confirmed that in go1.21,go1.22 and go1.23 the name is wrapped in funcNameForPrint(...).")
}
if goVersion.Major > 1 || goVersion.Minor >= 21 {
content = append(content, []byte(patch.RuntimeGetFuncName_Go121)...)
Expand Down Expand Up @@ -149,14 +151,17 @@ func patchRuntimeProc(goroot string, goVersion *goinfo.GoVersion) error {
)

procDecl := `func newproc(fn`
newProc := `newg := newproc1(fn, gp, pc)`
if goVersion.Major == 1 && goVersion.Minor <= 17 {
// to avoid typo check
const size = "s" + "i" + "z"
procDecl = `func newproc(` + size + ` int32`
newProc = `newg := newproc1(fn, argp, ` + size + `, gp, pc)`
newProc := `newg := newproc1(fn, gp, pc, false, waitReasonZero)`
if goVersion.Major == 1 {
if goVersion.Minor <= 17 {
// to avoid typo check
const size = "s" + "i" + "z"
procDecl = `func newproc(` + size + ` int32`
newProc = `newg := newproc1(fn, argp, ` + size + `, gp, pc)`
} else if goVersion.Minor <= 22 {
newProc = `newg := newproc1(fn, gp, pc)`
}
}

// see https://github.com/xhd2015/xgo/issues/67
content = addContentAtIndex(
content,
Expand Down Expand Up @@ -206,8 +211,46 @@ func patchRuntimeProc(goroot string, goVersion *goinfo.GoVersion) error {
return nil
}

func patchRuntimeTesting(goroot string) error {
return testingFilePatch.Apply(goroot, nil)
func patchRuntimeTesting(origGoroot string, goroot string, goVersion *goinfo.GoVersion) error {
if goVersion.Major == 1 && goVersion.Minor <= 22 {
return testingFilePatch.Apply(goroot, nil)
}
// go 1.23
srcFile := testingFilePatch.FilePath.Join(origGoroot)
srcCode, err := fileutil.ReadFile(srcFile)
if err != nil {
return err
}
newCode, err := ast_patch.Patch(string(srcCode), `package testing
//prepend <define_callbacks>`+toInsertCode(patch.TestingCallbackDeclarations+patch.TestingEndCallbackDeclarations)+`
func tRunner(t *T, fn func(t *T)) {
//...
t.start = highPrecisionTimeNow()
//prepend <apply_callbacks>`+toInsertCode(patch.TestingStart+patch.TestingEnd)+`
fn(t)
}
`)
if err != nil {
return err
}
err = fileutil.WriteFile(testingFilePatch.FilePath.Join(goroot), []byte(newCode))
if err != nil {
return err
}
return nil
}

func toInsertCode(code string) string {
lines := strings.Split(code, "\n")
for i, line := range lines {
if i == 0 {
lines[i] = " " + line
} else {
lines[i] = "// " + line
}
}
return strings.Join(lines, "\n")
}

// only required if need to mock time.Sleep
Expand Down
4 changes: 2 additions & 2 deletions cmd/xgo/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import "fmt"

// auto updated
const VERSION = "1.0.46"
const REVISION = "ab32ad121c57c321089d61906f2dd36898b7bcd1+1"
const NUMBER = 294
const REVISION = "b2c1918871f0a8bc3ea4bb9cf46e297d21c5f433+1"
const NUMBER = 295

// manually updated
const CORE_VERSION = "1.0.43"
Expand Down
124 changes: 124 additions & 0 deletions support/assert/diff.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package assert

import (
"encoding/json"
"fmt"
"os"
"os/exec"
"path/filepath"
"reflect"

"github.com/xhd2015/xgo/support/cmd"
"github.com/xhd2015/xgo/support/fileutil"
)

// Diff compares two values, resulting in a human readable diff format.
func Diff(expected interface{}, actual interface{}) string {
if res, ok := tryDiffError(expected, actual); ok {
return res
}
// check if any is error type
expectedTxt, err := toDiffableText(expected)
if err != nil {
return err.Error()
}
actualTxt, err := toDiffableText(actual)
if err != nil {
return err.Error()
}
diff, err := diffText([]byte(expectedTxt), []byte(actualTxt))
if err != nil {
sep := ""
if diff != "" {
sep = ", "
}
diff += sep + "err: " + err.Error()
}
return diff
}

func toDiffableText(v interface{}) (string, error) {
if v == nil {
return "nil", nil
}
if v, ok := toPlainString(v); ok {
return tryPrettyJSONText(v)
}
text, err := prettyObj(v)
if err != nil {
return "", fmt.Errorf("marshal %T: %v", v, err)
}
return string(text), nil
}

func prettyObj(v interface{}) ([]byte, error) {
return json.MarshalIndent(v, "", " ")
}

func toPlainString(v interface{}) (string, bool) {
switch v := v.(type) {
case string:
return v, true
case []byte:
return string(v), true
case json.RawMessage:
return string(v), true
}

// slow
rv := reflect.ValueOf(v)
switch rv.Kind() {
case reflect.String:
return rv.String(), true
case reflect.Slice:
if rv.Elem().Kind() == reflect.Uint8 {
// []byte
return string(rv.Bytes()), true
}
}
return "", false
}

func tryPrettyJSONText(s string) (string, error) {
if s == "" || s == "null" {
return s, nil
}
var v interface{}
err := json.Unmarshal([]byte(s), &v)
if err != nil {
return s, nil
}
text, err := json.MarshalIndent(v, "", " ")
if err != nil {
return "", err
}
return string(text), nil
}

func diffText(expected []byte, actual []byte) (string, error) {
tmpDir, err := os.MkdirTemp("", "diff")
if err != nil {
return "", err
}
defer os.RemoveAll(tmpDir)

// var jsonExpected []byte
// var jsonActual []byte

err = fileutil.WriteFile(filepath.Join(tmpDir, "expected"), expected)
if err != nil {
return "", err
}
err = fileutil.WriteFile(filepath.Join(tmpDir, "actual"), actual)
if err != nil {
return "", err
}

diff, err := cmd.Dir(tmpDir).Output("git", "diff", "--no-index", "--no-color", "--", "expected", "actual")
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() != 0 {
err = nil
}
}
return diff, err
}
44 changes: 44 additions & 0 deletions support/assert/err.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package assert

import "fmt"

func tryDiffError(expected interface{}, actual interface{}) (string, bool) {
expectedErr, expectedOK := expected.(error)
actualErr, actualOK := actual.(error)
if expectedOK != actualOK {
if expectedOK {
return fmt.Sprintf("expect: error %s, actual: %T %s", expectedErr.Error(), actual, actual), true
}
return fmt.Sprintf("expect: %T %s, actual: error %s", expectedErr, expectedErr, actualErr.Error()), true
}
if !expectedOK {
return "", false
}
res := diffError(expectedErr, actualErr)
if res == nil {
return "", true
}
return res.Error(), true
}

func diffError(expected error, actual error) error {
if expected == actual {
return nil
}
if expected == nil {
if actual != nil {
return fmt.Errorf("expect no error, actual: %v", actual)
}
return nil
}
if actual == nil {
return fmt.Errorf("expect error: %v, actual nil", expected)
}

e := expected.Error()
a := actual.Error()
if e != a {
return fmt.Errorf("expect err: %v, actual: %v", e, a)
}
return nil
}
12 changes: 11 additions & 1 deletion support/goinfo/goinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,17 @@ func ParseGoVersionNumber(version string) (*GoVersion, error) {
verList := strings.Split(version, ".")
for i := 0; i < 3; i++ {
if i < len(verList) {
verInt, err := strconv.ParseInt(verList[i], 10, 64)
num := verList[i]
if i == 1 {
// 1.23rc1
idx := strings.IndexFunc(num, func(r rune) bool {
return r < '0' || r > '9'
})
if idx > 0 {
num = num[:idx]
}
}
verInt, err := strconv.ParseInt(num, 10, 64)
if err != nil {
return nil, fmt.Errorf("unrecognized version, expect number, found: %s", version)
}
Expand Down
Loading

0 comments on commit 2d7e447

Please sign in to comment.