Skip to content

Commit

Permalink
Split the fake HTTP server out into its own package for testing to ke…
Browse files Browse the repository at this point in the history
…ep the testing code cleaner
  • Loading branch information
DRuggeri committed Apr 27, 2018
1 parent 62c85a3 commit 9b6064e
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 150 deletions.
145 changes: 145 additions & 0 deletions fakeserver/fakeserver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package fakeserver

import (
"log"
"net/http"
"time"
"encoding/json"
"fmt"
"io/ioutil"
"strings"
)

type fakeserver struct {
server *http.Server
objects map[string]map[string]interface{}
debug bool
}

func NewFakeServer(i_port int, i_objects map[string]map[string]interface{}, i_start bool, i_debug bool) *fakeserver {
serverMux := http.NewServeMux()

svr := &fakeserver{
debug: i_debug,
objects: i_objects,
}

serverMux.HandleFunc("/", svr.handle_api_object)

api_object_server := &http.Server{
Addr: fmt.Sprintf("127.0.0.1:%d", i_port),
Handler: serverMux,
}

svr.server = api_object_server

if i_start { svr.Start() }

return svr
}

func(svr *fakeserver)Start() {
go svr.server.ListenAndServe()

/* Let the server start */
time.Sleep(1 * time.Second)
}

func(svr *fakeserver)Shutdown() {
svr.server.Close()
}


func (svr *fakeserver)handle_api_object (w http.ResponseWriter, r *http.Request) {
var obj map[string]interface{}
var id string
var ok bool
svr.debug = true

/* Assume this will never fail */
b, _ := ioutil.ReadAll(r.Body)

if svr.debug {
log.Printf("fakeserver.go: Recieved request: %+v\n", r)
log.Printf("fakeserver.go: BODY: %s\n", string(b))
log.Printf("fakeserver.go: IDs and objects:\n")
for id, obj := range svr.objects {
log.Printf(" %s: %+v\n", id, obj)
}
}

parts := strings.Split(r.RequestURI, "/")
if svr.debug {log.Printf("fakeserver.go: Split request up into %d parts: %v\n", len(parts), parts) }
/* If it was a valid request, there will be three parts
and the ID will exist */
if len(parts) == 4 {
id = parts[3]
obj, ok = svr.objects[id];
if svr.debug { log.Printf("fakeserver.go: Detected ID %s (exists: %t, method: %s)", id, ok, r.Method) }
/* Make sure the object requested exists unless it's being created */
if !ok {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
} else if r.RequestURI != "/api/objects" {
/* How did something get to this handler with the wrong number of args??? */
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}

if r.Method == "DELETE" {
/* Get rid of this one */
delete(svr.objects, id)
if svr.debug { log.Printf("fakeserver.go: Object deleted.\n") }
return
}
/* if data was sent, parse the data */
if string(b) != "" {
if svr.debug { log.Printf("fakeserver.go: data sent - unmarshalling from JSON: %s\n", string(b)) }

err := json.Unmarshal(b, &obj)
if err != nil {
/* Failure goes back to the user as a 500. Log data here for
debugging (which shouldn't ever fail!) */
log.Fatalf("fakeserver.go: Unmarshal of request failed: %s\n", err);
log.Fatalf("\nBEGIN passed data:\n%s\nEND passed data.", string(b));
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
} else {
/* In the case of POST above, id is not yet known - set it here */
if id == "" {
if val, ok := obj["id"]; ok {
id = fmt.Sprintf("%v", val)
} else if val, ok := obj["Id"]; ok {
id = fmt.Sprintf("%v", val)
} else if val, ok := obj["ID"]; ok {
id = fmt.Sprintf("%v", val)
} else {
http.Error(w, "POST sent with no id field in the data. Cannot persist this!", http.StatusBadRequest)
return
}
}

/* Overwrite our stored test object */
if svr.debug {
log.Printf("fakeserver.go: Overwriting %s with new data:%+v\n", id, obj)
}
svr.objects[id] = obj

/* Coax the data we were sent back to JSON and send it to the user */
b, _ := json.Marshal(obj)
w.Write(b)
return
}
} else {
/* No data was sent... must be just a retrieval */
if svr.debug { log.Printf("fakeserver.go: Returning object.\n") }
b, _ := json.Marshal(obj)
w.Write(b)
return
}

/* All cases by now should have already returned... something wasn't handled */
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
Loading

0 comments on commit 9b6064e

Please sign in to comment.