github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/discv5/sim_run_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2016 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package discv5
    26  
    27  import (
    28  	"bufio"
    29  	"bytes"
    30  	"encoding/binary"
    31  	"errors"
    32  	"fmt"
    33  	"io"
    34  	"os"
    35  	"os/exec"
    36  	"runtime"
    37  	"strings"
    38  	"testing"
    39  )
    40  
    41  func getnacl() (string, error) {
    42  	switch runtime.GOARCH {
    43  	case "amd64":
    44  		_, err := exec.LookPath("sel_ldr_x86_64")
    45  		return "amd64p32", err
    46  	case "i386":
    47  		_, err := exec.LookPath("sel_ldr_i386")
    48  		return "i386", err
    49  	default:
    50  		return "", errors.New("nacl is not supported on " + runtime.GOARCH)
    51  	}
    52  }
    53  
    54  //runwithplaygroundtime执行调用方
    55  //在启用faketime的nacl沙盒中。
    56  //
    57  //必须从test*函数调用此函数
    58  //当ishost为true时,调用方必须跳过实际测试。
    59  func runWithPlaygroundTime(t *testing.T) (isHost bool) {
    60  	if runtime.GOOS == "nacl" {
    61  		return false
    62  	}
    63  
    64  //打电话给对方。
    65  	callerPC, _, _, ok := runtime.Caller(1)
    66  	if !ok {
    67  		panic("can't get caller")
    68  	}
    69  	callerFunc := runtime.FuncForPC(callerPC)
    70  	if callerFunc == nil {
    71  		panic("can't get caller")
    72  	}
    73  	callerName := callerFunc.Name()[strings.LastIndexByte(callerFunc.Name(), '.')+1:]
    74  	if !strings.HasPrefix(callerName, "Test") {
    75  		panic("must be called from witin a Test* function")
    76  	}
    77  	testPattern := "^" + callerName + "$"
    78  
    79  //不幸的是,runtime.faketime(操场时间模式)只在nacl上工作。氯化钠
    80  //必须安装sdk并将其链接到路径才能使其工作。
    81  	arch, err := getnacl()
    82  	if err != nil {
    83  		t.Skip(err)
    84  	}
    85  
    86  //使用nacl编译并运行调用测试。
    87  //额外的标签确保使用了sim_main_test.go中的test main功能。
    88  	cmd := exec.Command("go", "test", "-v", "-tags", "faketime_simulation", "-timeout", "100h", "-run", testPattern, ".")
    89  	cmd.Env = append([]string{"GOOS=nacl", "GOARCH=" + arch}, os.Environ()...)
    90  	stdout, _ := cmd.StdoutPipe()
    91  	stderr, _ := cmd.StderrPipe()
    92  	go skipPlaygroundOutputHeaders(os.Stdout, stdout)
    93  	go skipPlaygroundOutputHeaders(os.Stderr, stderr)
    94  	if err := cmd.Run(); err != nil {
    95  		t.Error(err)
    96  	}
    97  
    98  //确保测试功能不会在(非Nacl)主机进程中运行。
    99  	return true
   100  }
   101  
   102  func skipPlaygroundOutputHeaders(out io.Writer, in io.Reader) {
   103  //附加输出可以不打印标题
   104  //在Nacl二进制文件开始运行之前(例如编译器错误消息)。
   105  	bufin := bufio.NewReader(in)
   106  	output, err := bufin.ReadBytes(0)
   107  	output = bytes.TrimSuffix(output, []byte{0})
   108  	if len(output) > 0 {
   109  		out.Write(output)
   110  	}
   111  	if err != nil {
   112  		return
   113  	}
   114  	bufin.UnreadByte()
   115  
   116  //回放头:0 0 p b<8字节时间><4字节数据长度>
   117  	head := make([]byte, 4+8+4)
   118  	for {
   119  		if _, err := io.ReadFull(bufin, head); err != nil {
   120  			if err != io.EOF {
   121  				fmt.Fprintln(out, "read error:", err)
   122  			}
   123  			return
   124  		}
   125  		if !bytes.HasPrefix(head, []byte{0x00, 0x00, 'P', 'B'}) {
   126  			fmt.Fprintf(out, "expected playback header, got %q\n", head)
   127  			io.Copy(out, bufin)
   128  			return
   129  		}
   130  //将数据复制到下一个标题。
   131  		size := binary.BigEndian.Uint32(head[12:])
   132  		io.CopyN(out, bufin, int64(size))
   133  	}
   134  }