mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 02:03:20 -04:00 
			
		
		
		
	Move singleflight out of middleware/ (#217)
It is not middleware, so move it up one level. It was also use from core/ showing that indeed its use is not limited to middlewares.
This commit is contained in:
		
							
								
								
									
										85
									
								
								singleflight/singleflight_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								singleflight/singleflight_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| /* | ||||
| Copyright 2012 Google Inc. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|      http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package singleflight | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"sync" | ||||
| 	"sync/atomic" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| func TestDo(t *testing.T) { | ||||
| 	var g Group | ||||
| 	v, err := g.Do("key", func() (interface{}, error) { | ||||
| 		return "bar", nil | ||||
| 	}) | ||||
| 	if got, want := fmt.Sprintf("%v (%T)", v, v), "bar (string)"; got != want { | ||||
| 		t.Errorf("Do = %v; want %v", got, want) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		t.Errorf("Do error = %v", err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestDoErr(t *testing.T) { | ||||
| 	var g Group | ||||
| 	someErr := errors.New("Some error") | ||||
| 	v, err := g.Do("key", func() (interface{}, error) { | ||||
| 		return nil, someErr | ||||
| 	}) | ||||
| 	if err != someErr { | ||||
| 		t.Errorf("Do error = %v; want someErr", err) | ||||
| 	} | ||||
| 	if v != nil { | ||||
| 		t.Errorf("unexpected non-nil value %#v", v) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestDoDupSuppress(t *testing.T) { | ||||
| 	var g Group | ||||
| 	c := make(chan string) | ||||
| 	var calls int32 | ||||
| 	fn := func() (interface{}, error) { | ||||
| 		atomic.AddInt32(&calls, 1) | ||||
| 		return <-c, nil | ||||
| 	} | ||||
|  | ||||
| 	const n = 10 | ||||
| 	var wg sync.WaitGroup | ||||
| 	for i := 0; i < n; i++ { | ||||
| 		wg.Add(1) | ||||
| 		go func() { | ||||
| 			v, err := g.Do("key", fn) | ||||
| 			if err != nil { | ||||
| 				t.Errorf("Do error: %v", err) | ||||
| 			} | ||||
| 			if v.(string) != "bar" { | ||||
| 				t.Errorf("got %q; want %q", v, "bar") | ||||
| 			} | ||||
| 			wg.Done() | ||||
| 		}() | ||||
| 	} | ||||
| 	time.Sleep(100 * time.Millisecond) // let goroutines above block | ||||
| 	c <- "bar" | ||||
| 	wg.Wait() | ||||
| 	if got := atomic.LoadInt32(&calls); got != 1 { | ||||
| 		t.Errorf("number of calls = %d; want 1", got) | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user