URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [old/] [netchan/] [netchan_test.go] - Rev 747
Compare with Previous | Blame | View Log
// Copyright 2010 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 netchanimport ("net""strings""testing""time")const count = 10 // number of items in most testsconst closeCount = 5 // number of items when sender closes earlyconst base = 23func exportSend(exp *Exporter, n int, t *testing.T, done chan bool) {ch := make(chan int)err := exp.Export("exportedSend", ch, Send)if err != nil {t.Fatal("exportSend:", err)}go func() {for i := 0; i < n; i++ {ch <- base + i}close(ch)if done != nil {done <- true}}()}func exportReceive(exp *Exporter, t *testing.T, expDone chan bool) {ch := make(chan int)err := exp.Export("exportedRecv", ch, Recv)expDone <- trueif err != nil {t.Fatal("exportReceive:", err)}for i := 0; i < count; i++ {v, ok := <-chif !ok {if i != closeCount {t.Errorf("exportReceive expected close at %d; got one at %d", closeCount, i)}break}if v != base+i {t.Errorf("export Receive: bad value: expected %d+%d=%d; got %d", base, i, base+i, v)}}}func importSend(imp *Importer, n int, t *testing.T, done chan bool) {ch := make(chan int)err := imp.ImportNValues("exportedRecv", ch, Send, 3, -1)if err != nil {t.Fatal("importSend:", err)}go func() {for i := 0; i < n; i++ {ch <- base + i}close(ch)if done != nil {done <- true}}()}func importReceive(imp *Importer, t *testing.T, done chan bool) {ch := make(chan int)err := imp.ImportNValues("exportedSend", ch, Recv, 3, count)if err != nil {t.Fatal("importReceive:", err)}for i := 0; i < count; i++ {v, ok := <-chif !ok {if i != closeCount {t.Errorf("importReceive expected close at %d; got one at %d", closeCount, i)}break}if v != base+i {t.Errorf("importReceive: bad value: expected %d+%d=%d; got %+d", base, i, base+i, v)}}if done != nil {done <- true}}func TestExportSendImportReceive(t *testing.T) {exp, imp := pair(t)exportSend(exp, count, t, nil)importReceive(imp, t, nil)}func TestExportReceiveImportSend(t *testing.T) {exp, imp := pair(t)expDone := make(chan bool)done := make(chan bool)go func() {exportReceive(exp, t, expDone)done <- true}()<-expDoneimportSend(imp, count, t, nil)<-done}func TestClosingExportSendImportReceive(t *testing.T) {exp, imp := pair(t)exportSend(exp, closeCount, t, nil)importReceive(imp, t, nil)}func TestClosingImportSendExportReceive(t *testing.T) {exp, imp := pair(t)expDone := make(chan bool)done := make(chan bool)go func() {exportReceive(exp, t, expDone)done <- true}()<-expDoneimportSend(imp, closeCount, t, nil)<-done}func TestErrorForIllegalChannel(t *testing.T) {exp, imp := pair(t)// Now export a channel.ch := make(chan int, 1)err := exp.Export("aChannel", ch, Send)if err != nil {t.Fatal("export:", err)}ch <- 1234close(ch)// Now try to import a different channel.ch = make(chan int)err = imp.Import("notAChannel", ch, Recv, 1)if err != nil {t.Fatal("import:", err)}// Expect an error now. Start a timeout.timeout := make(chan bool, 1) // buffered so closure will not hang around.go func() {time.Sleep(10 * time.Second) // very long, to give even really slow machines a chance.timeout <- true}()select {case err = <-imp.Errors():if strings.Index(err.Error(), "no such channel") < 0 {t.Error("wrong error for nonexistent channel:", err)}case <-timeout:t.Error("import of nonexistent channel did not receive an error")}}// Not a great test but it does at least invoke Drain.func TestExportDrain(t *testing.T) {exp, imp := pair(t)done := make(chan bool)go func() {exportSend(exp, closeCount, t, nil)done <- true}()<-donego importReceive(imp, t, done)exp.Drain(0)<-done}// Not a great test but it does at least invoke Drain.func TestImportDrain(t *testing.T) {exp, imp := pair(t)expDone := make(chan bool)go exportReceive(exp, t, expDone)<-expDoneimportSend(imp, closeCount, t, nil)imp.Drain(0)}// Not a great test but it does at least invoke Sync.func TestExportSync(t *testing.T) {exp, imp := pair(t)done := make(chan bool)exportSend(exp, closeCount, t, nil)go importReceive(imp, t, done)exp.Sync(0)<-done}// Test hanging up the send side of an export.// TODO: test hanging up the receive side of an export.func TestExportHangup(t *testing.T) {exp, imp := pair(t)ech := make(chan int)err := exp.Export("exportedSend", ech, Send)if err != nil {t.Fatal("export:", err)}// Prepare to receive two values. We'll actually deliver only one.ich := make(chan int)err = imp.ImportNValues("exportedSend", ich, Recv, 1, 2)if err != nil {t.Fatal("import exportedSend:", err)}// Send one value, receive it.const Value = 1234ech <- Valuev := <-ichif v != Value {t.Fatal("expected", Value, "got", v)}// Now hang up the channel. Importer should see it close.exp.Hangup("exportedSend")v, ok := <-ichif ok {t.Fatal("expected channel to be closed; got value", v)}}// Test hanging up the send side of an import.// TODO: test hanging up the receive side of an import.func TestImportHangup(t *testing.T) {exp, imp := pair(t)ech := make(chan int)err := exp.Export("exportedRecv", ech, Recv)if err != nil {t.Fatal("export:", err)}// Prepare to Send two values. We'll actually deliver only one.ich := make(chan int)err = imp.ImportNValues("exportedRecv", ich, Send, 1, 2)if err != nil {t.Fatal("import exportedRecv:", err)}// Send one value, receive it.const Value = 1234ich <- Valuev := <-echif v != Value {t.Fatal("expected", Value, "got", v)}// Now hang up the channel. Exporter should see it close.imp.Hangup("exportedRecv")v, ok := <-echif ok {t.Fatal("expected channel to be closed; got value", v)}}// loop back exportedRecv to exportedSend,// but receive a value from ctlch before starting the loop.func exportLoopback(exp *Exporter, t *testing.T) {inch := make(chan int)if err := exp.Export("exportedRecv", inch, Recv); err != nil {t.Fatal("exportRecv")}outch := make(chan int)if err := exp.Export("exportedSend", outch, Send); err != nil {t.Fatal("exportSend")}ctlch := make(chan int)if err := exp.Export("exportedCtl", ctlch, Recv); err != nil {t.Fatal("exportRecv")}go func() {<-ctlchfor i := 0; i < count; i++ {x := <-inchif x != base+i {t.Errorf("exportLoopback expected %d; got %d", i, x)}outch <- x}}()}// This test checks that channel operations can proceed// even when other concurrent operations are blocked.func TestIndependentSends(t *testing.T) {exp, imp := pair(t)exportLoopback(exp, t)importSend(imp, count, t, nil)done := make(chan bool)go importReceive(imp, t, done)// wait for export side to try to deliver some values.time.Sleep(250 * time.Millisecond)ctlch := make(chan int)if err := imp.ImportNValues("exportedCtl", ctlch, Send, 1, 1); err != nil {t.Fatal("importSend:", err)}ctlch <- 0<-done}// This test cross-connects a pair of exporter/importer pairs.type value struct {I intSource string}func TestCrossConnect(t *testing.T) {e1, i1 := pair(t)e2, i2 := pair(t)crossExport(e1, e2, t)crossImport(i1, i2, t)}// Export side of cross-traffic.func crossExport(e1, e2 *Exporter, t *testing.T) {s := make(chan value)err := e1.Export("exportedSend", s, Send)if err != nil {t.Fatal("exportSend:", err)}r := make(chan value)err = e2.Export("exportedReceive", r, Recv)if err != nil {t.Fatal("exportReceive:", err)}go crossLoop("export", s, r, t)}// Import side of cross-traffic.func crossImport(i1, i2 *Importer, t *testing.T) {s := make(chan value)err := i2.Import("exportedReceive", s, Send, 2)if err != nil {t.Fatal("import of exportedReceive:", err)}r := make(chan value)err = i1.Import("exportedSend", r, Recv, 2)if err != nil {t.Fatal("import of exported Send:", err)}crossLoop("import", s, r, t)}// Cross-traffic: send and receive 'count' numbers.func crossLoop(name string, s, r chan value, t *testing.T) {for si, ri := 0, 0; si < count && ri < count; {select {case s <- value{si, name}:si++case v := <-r:if v.I != ri {t.Errorf("loop: bad value: expected %d, hello; got %+v", ri, v)}ri++}}}const flowCount = 100// test flow control from exporter to importer.func TestExportFlowControl(t *testing.T) {exp, imp := pair(t)sendDone := make(chan bool, 1)exportSend(exp, flowCount, t, sendDone)ch := make(chan int)err := imp.ImportNValues("exportedSend", ch, Recv, 20, -1)if err != nil {t.Fatal("importReceive:", err)}testFlow(sendDone, ch, flowCount, t)}// test flow control from importer to exporter.func TestImportFlowControl(t *testing.T) {exp, imp := pair(t)ch := make(chan int)err := exp.Export("exportedRecv", ch, Recv)if err != nil {t.Fatal("importReceive:", err)}sendDone := make(chan bool, 1)importSend(imp, flowCount, t, sendDone)testFlow(sendDone, ch, flowCount, t)}func testFlow(sendDone chan bool, ch <-chan int, N int, t *testing.T) {go func() {time.Sleep(500 * time.Millisecond)sendDone <- false}()if <-sendDone {t.Fatal("send did not block")}n := 0for i := range ch {t.Log("after blocking, got value ", i)n++}if n != N {t.Fatalf("expected %d values; got %d", N, n)}}func pair(t *testing.T) (*Exporter, *Importer) {c0, c1 := net.Pipe()exp := NewExporter()go exp.ServeConn(c0)imp := NewImporter(c1)return exp, imp}
