-
Notifications
You must be signed in to change notification settings - Fork 222
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split the fake HTTP server out into its own package for testing to ke…
…ep the testing code cleaner
- Loading branch information
Showing
2 changed files
with
190 additions
and
150 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
Oops, something went wrong.