Move swappableMux and its methods to its own module
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
type swappableMux struct {
|
||||||
|
m sync.RWMutex
|
||||||
|
root mux.Router
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *swappableMux) get() mux.Router {
|
||||||
|
sm.m.RLock()
|
||||||
|
defer sm.m.RUnlock()
|
||||||
|
|
||||||
|
return sm.root
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *swappableMux) set(mux mux.Router) {
|
||||||
|
sm.m.Lock()
|
||||||
|
sm.root = mux
|
||||||
|
sm.m.Unlock()
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSwappableMuxGetReturnsTheCurrentMux(t *testing.T) {
|
||||||
|
sm := swappableMux{}
|
||||||
|
mux := sm.get()
|
||||||
|
if !reflect.DeepEqual(mux, sm.root) {
|
||||||
|
t.Errorf("Returned mux is not the same %#v", mux)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSwappableMuxGetReturnsADifferentInstance(t *testing.T) {
|
||||||
|
sm := swappableMux{}
|
||||||
|
mux := sm.get()
|
||||||
|
if &mux == &sm.root {
|
||||||
|
t.Error("Returned mux is the same instance")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSwappableMuxGetWaitsForTheMutexToBeReleased(t *testing.T) {
|
||||||
|
sm := swappableMux{}
|
||||||
|
|
||||||
|
sm.m.Lock()
|
||||||
|
defer sm.m.Unlock()
|
||||||
|
|
||||||
|
c := make(chan mux.Router)
|
||||||
|
go func() { c <- sm.get() }()
|
||||||
|
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-c:
|
||||||
|
t.Error("Didn't acquire the mutex")
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSwappableMuxGetIsAbleToReadWhileOthersAreReading(t *testing.T) {
|
||||||
|
sm := swappableMux{}
|
||||||
|
|
||||||
|
sm.m.RLock()
|
||||||
|
defer sm.m.RUnlock()
|
||||||
|
|
||||||
|
c := make(chan mux.Router)
|
||||||
|
go func() { c <- sm.get() }()
|
||||||
|
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-c:
|
||||||
|
default:
|
||||||
|
t.Error("The mutex cannot be acquired")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSwappableMuxSetSetsTheGivenMux(t *testing.T) {
|
||||||
|
sm := swappableMux{}
|
||||||
|
mux := mux.Router{
|
||||||
|
KeepContext: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
sm.set(mux)
|
||||||
|
|
||||||
|
if !sm.root.KeepContext {
|
||||||
|
t.Error("mux not set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSwappableMuxSetSetsADifferentInstance(t *testing.T) {
|
||||||
|
sm := swappableMux{}
|
||||||
|
mux := mux.Router{}
|
||||||
|
|
||||||
|
sm.set(mux)
|
||||||
|
|
||||||
|
if &mux == &sm.root {
|
||||||
|
t.Error("Set mux is the same instance")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSwappableMuxSetWaitsForWriterToReleaseMutex(t *testing.T) {
|
||||||
|
sm := swappableMux{}
|
||||||
|
|
||||||
|
sm.m.Lock()
|
||||||
|
defer sm.m.Unlock()
|
||||||
|
|
||||||
|
c := make(chan bool)
|
||||||
|
go func() { sm.set(mux.Router{}); c <- true }()
|
||||||
|
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-c:
|
||||||
|
t.Error("Didn't acquire the mutex")
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSwappableMuxSetWaitsForReadersToReleaseMutex(t *testing.T) {
|
||||||
|
sm := swappableMux{}
|
||||||
|
|
||||||
|
sm.m.RLock()
|
||||||
|
defer sm.m.RUnlock()
|
||||||
|
|
||||||
|
c := make(chan bool)
|
||||||
|
go func() { sm.set(mux.Router{}); c <- true }()
|
||||||
|
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-c:
|
||||||
|
t.Error("Didn't acquire the mutex")
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,29 +2,8 @@ package user
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type swappableMux struct {
|
|
||||||
m sync.RWMutex
|
|
||||||
root mux.Router
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sm *swappableMux) get() mux.Router {
|
|
||||||
sm.m.RLock()
|
|
||||||
defer sm.m.RUnlock()
|
|
||||||
|
|
||||||
return sm.root
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sm *swappableMux) set(mux mux.Router) {
|
|
||||||
sm.m.Lock()
|
|
||||||
sm.root = mux
|
|
||||||
sm.m.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
var Server http.Server
|
var Server http.Server
|
||||||
|
|
||||||
func Run() {
|
func Run() {
|
||||||
|
|||||||
@@ -1,123 +1,3 @@
|
|||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO TestRunRunsAnHTTPServer(t *testing.T) {}
|
// TODO TestRunRunsAnHTTPServer(t *testing.T) {}
|
||||||
|
|
||||||
func TestSwappableMuxGetReturnsTheCurrentMux(t *testing.T) {
|
|
||||||
sm := swappableMux{}
|
|
||||||
mux := sm.get()
|
|
||||||
if !reflect.DeepEqual(mux, sm.root) {
|
|
||||||
t.Errorf("Returned mux is not the same %#v", mux)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSwappableMuxGetReturnsADifferentInstance(t *testing.T) {
|
|
||||||
sm := swappableMux{}
|
|
||||||
mux := sm.get()
|
|
||||||
if &mux == &sm.root {
|
|
||||||
t.Error("Returned mux is the same instance")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSwappableMuxGetWaitsForTheMutexToBeReleased(t *testing.T) {
|
|
||||||
sm := swappableMux{}
|
|
||||||
|
|
||||||
sm.m.Lock()
|
|
||||||
defer sm.m.Unlock()
|
|
||||||
|
|
||||||
c := make(chan mux.Router)
|
|
||||||
go func() { c <- sm.get() }()
|
|
||||||
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-c:
|
|
||||||
t.Error("Didn't acquire the mutex")
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSwappableMuxGetIsAbleToReadWhileOthersAreReading(t *testing.T) {
|
|
||||||
sm := swappableMux{}
|
|
||||||
|
|
||||||
sm.m.RLock()
|
|
||||||
defer sm.m.RUnlock()
|
|
||||||
|
|
||||||
c := make(chan mux.Router)
|
|
||||||
go func() { c <- sm.get() }()
|
|
||||||
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-c:
|
|
||||||
default:
|
|
||||||
t.Error("The mutex cannot be acquired")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSwappableMuxSetSetsTheGivenMux(t *testing.T) {
|
|
||||||
sm := swappableMux{}
|
|
||||||
mux := mux.Router{
|
|
||||||
KeepContext: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
sm.set(mux)
|
|
||||||
|
|
||||||
if !sm.root.KeepContext {
|
|
||||||
t.Error("mux not set")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSwappableMuxSetSetsADifferentInstance(t *testing.T) {
|
|
||||||
sm := swappableMux{}
|
|
||||||
mux := mux.Router{}
|
|
||||||
|
|
||||||
sm.set(mux)
|
|
||||||
|
|
||||||
if &mux == &sm.root {
|
|
||||||
t.Error("Set mux is the same instance")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSwappableMuxSetWaitsForWriterToReleaseMutex(t *testing.T) {
|
|
||||||
sm := swappableMux{}
|
|
||||||
|
|
||||||
sm.m.Lock()
|
|
||||||
defer sm.m.Unlock()
|
|
||||||
|
|
||||||
c := make(chan bool)
|
|
||||||
go func() { sm.set(mux.Router{}); c <- true }()
|
|
||||||
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-c:
|
|
||||||
t.Error("Didn't acquire the mutex")
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSwappableMuxSetWaitsForReadersToReleaseMutex(t *testing.T) {
|
|
||||||
sm := swappableMux{}
|
|
||||||
|
|
||||||
sm.m.RLock()
|
|
||||||
defer sm.m.RUnlock()
|
|
||||||
|
|
||||||
c := make(chan bool)
|
|
||||||
go func() { sm.set(mux.Router{}); c <- true }()
|
|
||||||
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-c:
|
|
||||||
t.Error("Didn't acquire the mutex")
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user