| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2015 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-23 18:35:11 +02:00
										 |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-13 16:04:06 +02:00
										 |  |  | package nat | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"net" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This test checks that autodisc doesn't hang and returns | 
					
						
							|  |  |  | // consistent results when multiple goroutines call its methods | 
					
						
							|  |  |  | // concurrently. | 
					
						
							|  |  |  | func TestAutoDiscRace(t *testing.T) { | 
					
						
							|  |  |  | 	ad := startautodisc("thing", func() Interface { | 
					
						
							|  |  |  | 		time.Sleep(500 * time.Millisecond) | 
					
						
							|  |  |  | 		return extIP{33, 44, 55, 66} | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Spawn a few concurrent calls to ad.ExternalIP. | 
					
						
							|  |  |  | 	type rval struct { | 
					
						
							|  |  |  | 		ip  net.IP | 
					
						
							|  |  |  | 		err error | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	results := make(chan rval, 50) | 
					
						
							|  |  |  | 	for i := 0; i < cap(results); i++ { | 
					
						
							|  |  |  | 		go func() { | 
					
						
							|  |  |  | 			ip, err := ad.ExternalIP() | 
					
						
							|  |  |  | 			results <- rval{ip, err} | 
					
						
							|  |  |  | 		}() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check that they all return the correct result within the deadline. | 
					
						
							| 
									
										
										
										
											2015-05-27 14:10:02 +02:00
										 |  |  | 	deadline := time.After(2 * time.Second) | 
					
						
							| 
									
										
										
										
											2015-05-13 16:04:06 +02:00
										 |  |  | 	for i := 0; i < cap(results); i++ { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case <-deadline: | 
					
						
							|  |  |  | 			t.Fatal("deadline exceeded") | 
					
						
							|  |  |  | 		case rval := <-results: | 
					
						
							|  |  |  | 			if rval.err != nil { | 
					
						
							|  |  |  | 				t.Errorf("result %d: unexpected error: %v", i, rval.err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			wantIP := net.IP{33, 44, 55, 66} | 
					
						
							|  |  |  | 			if !bytes.Equal(rval.ip, wantIP) { | 
					
						
							|  |  |  | 				t.Errorf("result %d: got IP %v, want %v", i, rval.ip, wantIP) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |