From 10586bae95c1c825578fd26bb95fa3c159ea75ec Mon Sep 17 00:00:00 2001 From: pancho horrillo Date: Mon, 7 Oct 2019 19:05:59 +0200 Subject: [PATCH] Add internal/server/user/server{,_test}.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Roberto Abdelkader Martínez Pérez --- go.mod | 2 +- internal/server/user/server.go | 31 +++++++ internal/server/user/server_test.go | 123 ++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 internal/server/user/server.go create mode 100644 internal/server/user/server_test.go diff --git a/go.mod b/go.mod index 299196f..74eb86e 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.12 require ( github.com/google/uuid v1.1.1 // indirect - github.com/gorilla/mux v1.7.3 // indirect + github.com/gorilla/mux v1.7.3 github.com/spf13/cobra v0.0.5 gopkg.in/h2non/gock.v1 v1.0.15 ) diff --git a/internal/server/user/server.go b/internal/server/user/server.go new file mode 100644 index 0000000..98edb84 --- /dev/null +++ b/internal/server/user/server.go @@ -0,0 +1,31 @@ +package user + +import ( + "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 + +func Run() { +} diff --git a/internal/server/user/server_test.go b/internal/server/user/server_test.go new file mode 100644 index 0000000..c7d1777 --- /dev/null +++ b/internal/server/user/server_test.go @@ -0,0 +1,123 @@ +package user + +import ( + "reflect" + "testing" + "time" + + "github.com/gorilla/mux" +) + +// 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: + } +}