github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/mixnet/queue_test.go (about) 1 // Copyright (c) 2015, Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License0. 14 15 package mixnet 16 17 import ( 18 "fmt" 19 "net" 20 "testing" 21 "time" 22 ) 23 24 // A dummy sever that reads a message from the connecting client. 25 func runDummyServerOne(ch chan<- testResult) { 26 l, err := net.Listen(network, localAddr) 27 if err != nil { 28 ch <- testResult{err, nil} 29 return 30 } 31 defer l.Close() 32 33 c, err := l.Accept() 34 if err != nil { 35 ch <- testResult{err, nil} 36 return 37 } 38 defer c.Close() 39 40 buf := make([]byte, MaxMsgBytes) 41 bytes, err := c.Read(buf) 42 if err != nil { 43 ch <- testResult{err, nil} 44 return 45 } 46 47 if _, err = c.Write(buf[:bytes]); err != nil { 48 ch <- testResult{err, nil} 49 return 50 } 51 ch <- testResult{nil, buf[:bytes]} 52 } 53 54 // A dummy server that accepts clientCt connections and waits for msgCt messages 55 // from each client. The message is echoed. 56 func runDummyServer(clientCt, msgCt int, ch chan<- testResult, addr chan<- string) { 57 l, err := net.Listen(network, localAddr) 58 if err != nil { 59 ch <- testResult{err, []byte{}} 60 return 61 } 62 defer l.Close() 63 addr <- l.Addr().String() 64 65 done := make(chan bool) 66 for i := 0; i < clientCt; i++ { 67 c, err := l.Accept() 68 if err != nil { 69 ch <- testResult{err, []byte{}} 70 return 71 } 72 73 go func(c net.Conn, clientNo int) { 74 defer c.Close() 75 buf := make([]byte, MaxMsgBytes+1) 76 for j := 0; j < msgCt; j++ { 77 bytes, err := c.Read(buf) 78 if err != nil { 79 ch <- testResult{err, nil} 80 } else { 81 _, err := c.Write(buf[:bytes]) 82 if err != nil { 83 ch <- testResult{err, nil} 84 } else { 85 bufCopy := make([]byte, bytes) 86 copy(bufCopy, buf[:bytes]) 87 ch <- testResult{nil, bufCopy} 88 } 89 } 90 done <- true 91 } 92 }(c, i) 93 } 94 95 for i := 0; i < clientCt*msgCt; i++ { 96 <-done 97 } 98 } 99 100 // Test enqeueing a bunch of messages and dequeueing them. 101 func TestQueueSend(t *testing.T) { 102 103 // batchSize must divide clientCt; otherwise the sendQueue will block forever. 104 batchSize := 2 105 clientCt := 4 106 msgCt := 3 107 108 timeout, _ := time.ParseDuration("2s") 109 sq := NewQueue(network, nil, batchSize, timeout) 110 kill := make(chan bool) 111 done := make(chan bool) 112 dstCh := make(chan testResult) 113 dstAddrCh := make(chan string) 114 115 go runDummyServer(clientCt, msgCt, dstCh, dstAddrCh) 116 dstAddr := <-dstAddrCh 117 118 go func() { 119 sq.DoQueue(kill) 120 done <- true 121 }() 122 123 go func() { 124 sq.DoQueueErrorHandler(nil, kill) 125 done <- true 126 }() 127 128 conns := make([]net.Conn, clientCt) 129 var err error 130 for i := 0; i < clientCt; i++ { 131 conns[i], err = net.DialTimeout(network, dstAddr, timeout) 132 if err != nil { 133 t.Error("Couldn't connect to server:", err) 134 } 135 } 136 137 for round := 0; round < msgCt; round++ { 138 // Enqueue some messages. 139 for i := 0; i < clientCt; i++ { 140 q := new(Queueable) 141 q.id = uint64(i) 142 q.conn = conns[i] 143 q.msg = []byte( 144 fmt.Sprintf("I am anonymous, but my ID is %d.", i)) 145 sq.Enqueue(q) 146 } 147 148 // Read results from destination server. 149 for i := 0; i < clientCt; i++ { 150 res := <-dstCh 151 if res.err != nil { 152 t.Error(res.err) 153 break 154 } else { 155 t.Log(string(res.msg)) 156 } 157 } 158 } 159 160 kill <- true 161 kill <- true 162 163 <-done 164 <-done 165 }