github.com/annchain/OG@v0.0.9/p2p/message_test.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package p2p
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/hex"
    22  	"fmt"
    23  	"io"
    24  	"runtime"
    25  	"strings"
    26  	"testing"
    27  	"time"
    28  )
    29  
    30  func ExampleMessagePipe() {
    31  	rw1, rw2 := MsgPipe()
    32  	go func() {
    33  		Send(rw1, 8, []byte{0, 0})
    34  		Send(rw1, 5, []byte{1, 1})
    35  		rw1.Close()
    36  	}()
    37  
    38  	for {
    39  		msg, err := rw2.ReadMsg()
    40  		if err != nil {
    41  			break
    42  		}
    43  		data, err := msg.GetPayLoad()
    44  		//err = msg.Decode(&data)
    45  		if err != nil {
    46  			panic(err)
    47  		}
    48  		fmt.Printf("msg: %d, %x\n", msg.Code, data)
    49  	}
    50  	// Output:
    51  	// msg: 8, 0000
    52  	// msg: 5, 0101
    53  	time.Sleep(time.Second)
    54  }
    55  
    56  /*
    57  
    58  func ExampleMsgPipe() {
    59  	rw1, rw2 := MsgPipe()
    60  	go func() {
    61  		SendRlp(rw1, 8, [][]byte{{0, 0}})
    62  		SendRlp(rw1, 5, [][]byte{{1, 1}})
    63  		rw1.Close()
    64  	}()
    65  
    66  	for {
    67  		msg, err := rw2.ReadMsg()
    68  		if err != nil {
    69  			break
    70  		}
    71  		var data [][]byte
    72  		msg.Decode(&data)
    73  		fmt.Printf("msg: %d, %x\n", msg.Code, data[0])
    74  	}
    75  	// Output:
    76  	// msg: 8, 0000
    77  	// msg: 5, 0101
    78  }
    79  
    80  */
    81  
    82  func TestMsgPipeUnblockWrite(t *testing.T) {
    83  loop:
    84  	for i := 0; i < 100; i++ {
    85  		rw1, rw2 := MsgPipe()
    86  		done := make(chan struct{})
    87  		go func() {
    88  			if err := Send(rw1, 1, nil); err == nil {
    89  				t.Error("EncodeMsg returned nil error")
    90  			} else if err != ErrPipeClosed {
    91  				t.Errorf("EncodeMsg returned wrong error: got %v, want %v", err, ErrPipeClosed)
    92  			}
    93  			close(done)
    94  		}()
    95  
    96  		// this call should ensure that EncodeMsg is waiting to
    97  		// deliver sometimes. if this isn't done, Close is likely to
    98  		// be executed before EncodeMsg starts and then we won't test
    99  		// all the cases.
   100  		runtime.Gosched()
   101  
   102  		rw2.Close()
   103  		select {
   104  		case <-done:
   105  		case <-time.After(200 * time.Millisecond):
   106  			t.Errorf("write didn't unblock")
   107  			break loop
   108  		}
   109  	}
   110  }
   111  
   112  // This test should panic if concurrent close isn't implemented correctly.
   113  func TestMsgPipeConcurrentClose(t *testing.T) {
   114  	rw1, _ := MsgPipe()
   115  	for i := 0; i < 10; i++ {
   116  		go rw1.Close()
   117  	}
   118  }
   119  
   120  func TestEOFSignal(t *testing.T) {
   121  	rb := make([]byte, 10)
   122  
   123  	// empty reader
   124  	eof := make(chan struct{}, 1)
   125  	sig := &eofSignal{new(bytes.Buffer), 0, eof}
   126  	if n, err := sig.Read(rb); n != 0 || err != io.EOF {
   127  		t.Errorf("Read returned unexpected values: (%v, %v)", n, err)
   128  	}
   129  	select {
   130  	case <-eof:
   131  	default:
   132  		t.Error("EOF chan not signaled")
   133  	}
   134  
   135  	// count before error
   136  	eof = make(chan struct{}, 1)
   137  	sig = &eofSignal{bytes.NewBufferString("aaaaaaaa"), 4, eof}
   138  	if n, err := sig.Read(rb); n != 4 || err != nil {
   139  		t.Errorf("Read returned unexpected values: (%v, %v)", n, err)
   140  	}
   141  	select {
   142  	case <-eof:
   143  	default:
   144  		t.Error("EOF chan not signaled")
   145  	}
   146  
   147  	// error before count
   148  	eof = make(chan struct{}, 1)
   149  	sig = &eofSignal{bytes.NewBufferString("aaaa"), 999, eof}
   150  	if n, err := sig.Read(rb); n != 4 || err != nil {
   151  		t.Errorf("Read returned unexpected values: (%v, %v)", n, err)
   152  	}
   153  	if n, err := sig.Read(rb); n != 0 || err != io.EOF {
   154  		t.Errorf("Read returned unexpected values: (%v, %v)", n, err)
   155  	}
   156  	select {
   157  	case <-eof:
   158  	default:
   159  		t.Error("EOF chan not signaled")
   160  	}
   161  
   162  	// no signal if neither occurs
   163  	eof = make(chan struct{}, 1)
   164  	sig = &eofSignal{bytes.NewBufferString("aaaaaaaaaaaaaaaaaaaaa"), 999, eof}
   165  	if n, err := sig.Read(rb); n != 10 || err != nil {
   166  		t.Errorf("Read returned unexpected values: (%v, %v)", n, err)
   167  	}
   168  	select {
   169  	case <-eof:
   170  		t.Error("unexpected EOF signal")
   171  	default:
   172  	}
   173  }
   174  
   175  func unhex(str string) []byte {
   176  	r := strings.NewReplacer("\t", "", " ", "", "\n", "")
   177  	b, err := hex.DecodeString(r.Replace(str))
   178  	if err != nil {
   179  		panic(fmt.Sprintf("invalid hex string: %q", str))
   180  	}
   181  	return b
   182  }