swappableMux is now public and Append() now updates Server.Handler

Co-authored-by: Roberto Abdelkader Martínez Pérez <robertomartinezp@gmail.com>
This commit is contained in:
pancho horrillo
2019-10-10 20:06:05 +02:00
parent 0c408497a3
commit df5d38e94f
8 changed files with 74 additions and 42 deletions
+7 -7
View File
@@ -8,34 +8,34 @@ import (
"github.com/gorilla/mux"
)
type swappableMux struct {
type SwappableMux struct {
m sync.RWMutex
root *mux.Router
}
func New() *swappableMux {
return &swappableMux{
func New() *SwappableMux {
return &SwappableMux{
root: mux.NewRouter(),
}
}
func (sm *swappableMux) get() *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) {
func (sm *SwappableMux) set(mux *mux.Router) {
sm.m.Lock()
sm.root = mux
sm.m.Unlock()
}
func (sm *swappableMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (sm *SwappableMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
sm.get().ServeHTTP(w, r)
}
func (sm *swappableMux) Update(rs []model.Route) {
func (sm *SwappableMux) Update(rs []model.Route) {
sm.set(gorillize(rs, handlerBuilder))
}
+11 -11
View File
@@ -30,7 +30,7 @@ func TestNewReturnsAProperlyInitializedMux(t *testing.T) {
}
func TestSwappableMuxGetReturnsTheCurrentMux(t *testing.T) {
sm := swappableMux{}
sm := SwappableMux{}
mux := sm.get()
if !reflect.DeepEqual(mux, sm.root) {
t.Errorf("Returned mux is not the same %#v", mux)
@@ -38,7 +38,7 @@ func TestSwappableMuxGetReturnsTheCurrentMux(t *testing.T) {
}
func TestSwappableMuxGetReturnsADifferentInstance(t *testing.T) {
sm := swappableMux{}
sm := SwappableMux{}
mux := sm.get()
if &mux == &sm.root {
t.Error("Returned mux is the same instance")
@@ -46,7 +46,7 @@ func TestSwappableMuxGetReturnsADifferentInstance(t *testing.T) {
}
func TestSwappableMuxGetWaitsForTheMutexToBeReleased(t *testing.T) {
sm := swappableMux{}
sm := SwappableMux{}
sm.m.Lock()
defer sm.m.Unlock()
@@ -64,7 +64,7 @@ func TestSwappableMuxGetWaitsForTheMutexToBeReleased(t *testing.T) {
}
func TestSwappableMuxGetIsAbleToReadWhileOthersAreReading(t *testing.T) {
sm := swappableMux{}
sm := SwappableMux{}
sm.m.RLock()
defer sm.m.RUnlock()
@@ -82,7 +82,7 @@ func TestSwappableMuxGetIsAbleToReadWhileOthersAreReading(t *testing.T) {
}
func TestSwappableMuxSetSetsTheGivenMux(t *testing.T) {
sm := swappableMux{}
sm := SwappableMux{}
m := mux.NewRouter()
// nolint
m.KeepContext = true
@@ -96,7 +96,7 @@ func TestSwappableMuxSetSetsTheGivenMux(t *testing.T) {
}
func TestSwappableMuxSetSetsTheSameInstance(t *testing.T) {
sm := swappableMux{}
sm := SwappableMux{}
m := mux.NewRouter()
sm.set(m)
@@ -107,7 +107,7 @@ func TestSwappableMuxSetSetsTheSameInstance(t *testing.T) {
}
func TestSwappableMuxSetWaitsForWriterToReleaseMutex(t *testing.T) {
sm := swappableMux{}
sm := SwappableMux{}
sm.m.Lock()
defer sm.m.Unlock()
@@ -125,7 +125,7 @@ func TestSwappableMuxSetWaitsForWriterToReleaseMutex(t *testing.T) {
}
func TestSwappableMuxSetWaitsForReadersToReleaseMutex(t *testing.T) {
sm := swappableMux{}
sm := SwappableMux{}
sm.m.RLock()
defer sm.m.RUnlock()
@@ -148,7 +148,7 @@ func TestServeHTTPCallsInnerMux(t *testing.T) {
m := mux.NewRouter()
m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { called = true })
sm := swappableMux{root: m}
sm := SwappableMux{root: m}
req := httptest.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
@@ -166,7 +166,7 @@ func TestServeHTTPCanServeWhenMuxIsReadLocked(t *testing.T) {
m := mux.NewRouter()
m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { called = true })
sm := swappableMux{root: m}
sm := SwappableMux{root: m}
sm.m.RLock()
req := httptest.NewRequest("GET", "/", nil)
@@ -187,7 +187,7 @@ func TestServeHTTPCallsInnerMuxAfterAcquiringLock(t *testing.T) {
m := mux.NewRouter()
m.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { called = true })
sm := swappableMux{root: m}
sm := SwappableMux{root: m}
sm.m.Lock()
req := httptest.NewRequest("GET", "/", nil)
-7
View File
@@ -1,7 +0,0 @@
package user
import (
"github.com/BBVA/kapow/internal/server/user/state"
)
var Routes = state.New()
-14
View File
@@ -1,14 +0,0 @@
package user
import (
"reflect"
"testing"
"github.com/BBVA/kapow/internal/server/user/state"
)
func TestPackageHaveASingletonEmptyRouteList(t *testing.T) {
if !reflect.DeepEqual(Routes, state.New()) {
t.Error("Routes is not an empty safeRouteList")
}
}
+5 -1
View File
@@ -2,9 +2,13 @@ package user
import (
"net/http"
"github.com/BBVA/kapow/internal/server/user/mux"
)
var Server http.Server
var Server = http.Server{
Handler: mux.New(),
}
func Run() {
}
+38
View File
@@ -1,3 +1,41 @@
package user
import (
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/BBVA/kapow/internal/server/model"
"github.com/BBVA/kapow/internal/server/user/mux"
)
// TODO TestRunRunsAnHTTPServer(t *testing.T) {}
func TestAppendUpdatesMuxWithProvideRoute(t *testing.T) {
Server = http.Server{
Handler: mux.New(),
}
srl := New()
route := model.Route{
Method: "GET",
Pattern: "/",
Entrypoint: "/bin/sh -c",
Command: "jaillover > /tmp/kapow-test-append-updates-mux",
}
os.Remove("/tmp/kapow-test-append-updates-mux")
defer os.Remove("/tmp/kapow-test-append-updates-mux")
srl.Append(route)
req := httptest.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
Server.Handler.ServeHTTP(w, req)
if _, err := os.Stat("/tmp/kapow-test-append-updates-mux"); os.IsNotExist(err) {
t.Error("Routes not updated")
} else if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
}
@@ -1,10 +1,11 @@
package state
package user
import (
"errors"
"sync"
"github.com/BBVA/kapow/internal/server/model"
"github.com/BBVA/kapow/internal/server/user/mux"
)
type safeRouteList struct {
@@ -12,6 +13,8 @@ type safeRouteList struct {
m *sync.RWMutex
}
var Routes safeRouteList = New()
func New() safeRouteList {
return safeRouteList{
rs: []model.Route{},
@@ -25,6 +28,8 @@ func (srl *safeRouteList) Append(r model.Route) model.Route {
l := len(srl.rs)
srl.m.Unlock()
Server.Handler.(*mux.SwappableMux).Update(srl.Snapshot())
return model.Route{Index: l - 1}
}
@@ -1,6 +1,6 @@
// +build !race
package state
package user
import (
"reflect"
@@ -271,3 +271,9 @@ func TestDeleteWaitsForReadersToFinishReading(t *testing.T) {
default:
}
}
func TestPackageHaveASingletonEmptyRouteList(t *testing.T) {
if !reflect.DeepEqual(Routes, New()) {
t.Error("Routes is not an empty safeRouteList")
}
}