Skip to content

Commit 9b6064e

Browse files
committed
Split the fake HTTP server out into its own package for testing to keep the testing code cleaner
1 parent 62c85a3 commit 9b6064e

File tree

2 files changed

+190
-150
lines changed

2 files changed

+190
-150
lines changed

fakeserver/fakeserver.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package fakeserver
2+
3+
import (
4+
"log"
5+
"net/http"
6+
"time"
7+
"encoding/json"
8+
"fmt"
9+
"io/ioutil"
10+
"strings"
11+
)
12+
13+
type fakeserver struct {
14+
server *http.Server
15+
objects map[string]map[string]interface{}
16+
debug bool
17+
}
18+
19+
func NewFakeServer(i_port int, i_objects map[string]map[string]interface{}, i_start bool, i_debug bool) *fakeserver {
20+
serverMux := http.NewServeMux()
21+
22+
svr := &fakeserver{
23+
debug: i_debug,
24+
objects: i_objects,
25+
}
26+
27+
serverMux.HandleFunc("/", svr.handle_api_object)
28+
29+
api_object_server := &http.Server{
30+
Addr: fmt.Sprintf("127.0.0.1:%d", i_port),
31+
Handler: serverMux,
32+
}
33+
34+
svr.server = api_object_server
35+
36+
if i_start { svr.Start() }
37+
38+
return svr
39+
}
40+
41+
func(svr *fakeserver)Start() {
42+
go svr.server.ListenAndServe()
43+
44+
/* Let the server start */
45+
time.Sleep(1 * time.Second)
46+
}
47+
48+
func(svr *fakeserver)Shutdown() {
49+
svr.server.Close()
50+
}
51+
52+
53+
func (svr *fakeserver)handle_api_object (w http.ResponseWriter, r *http.Request) {
54+
var obj map[string]interface{}
55+
var id string
56+
var ok bool
57+
svr.debug = true
58+
59+
/* Assume this will never fail */
60+
b, _ := ioutil.ReadAll(r.Body)
61+
62+
if svr.debug {
63+
log.Printf("fakeserver.go: Recieved request: %+v\n", r)
64+
log.Printf("fakeserver.go: BODY: %s\n", string(b))
65+
log.Printf("fakeserver.go: IDs and objects:\n")
66+
for id, obj := range svr.objects {
67+
log.Printf(" %s: %+v\n", id, obj)
68+
}
69+
}
70+
71+
parts := strings.Split(r.RequestURI, "/")
72+
if svr.debug {log.Printf("fakeserver.go: Split request up into %d parts: %v\n", len(parts), parts) }
73+
/* If it was a valid request, there will be three parts
74+
and the ID will exist */
75+
if len(parts) == 4 {
76+
id = parts[3]
77+
obj, ok = svr.objects[id];
78+
if svr.debug { log.Printf("fakeserver.go: Detected ID %s (exists: %t, method: %s)", id, ok, r.Method) }
79+
/* Make sure the object requested exists unless it's being created */
80+
if !ok {
81+
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
82+
return
83+
}
84+
} else if r.RequestURI != "/api/objects" {
85+
/* How did something get to this handler with the wrong number of args??? */
86+
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
87+
return
88+
}
89+
90+
if r.Method == "DELETE" {
91+
/* Get rid of this one */
92+
delete(svr.objects, id)
93+
if svr.debug { log.Printf("fakeserver.go: Object deleted.\n") }
94+
return
95+
}
96+
/* if data was sent, parse the data */
97+
if string(b) != "" {
98+
if svr.debug { log.Printf("fakeserver.go: data sent - unmarshalling from JSON: %s\n", string(b)) }
99+
100+
err := json.Unmarshal(b, &obj)
101+
if err != nil {
102+
/* Failure goes back to the user as a 500. Log data here for
103+
debugging (which shouldn't ever fail!) */
104+
log.Fatalf("fakeserver.go: Unmarshal of request failed: %s\n", err);
105+
log.Fatalf("\nBEGIN passed data:\n%s\nEND passed data.", string(b));
106+
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
107+
return
108+
} else {
109+
/* In the case of POST above, id is not yet known - set it here */
110+
if id == "" {
111+
if val, ok := obj["id"]; ok {
112+
id = fmt.Sprintf("%v", val)
113+
} else if val, ok := obj["Id"]; ok {
114+
id = fmt.Sprintf("%v", val)
115+
} else if val, ok := obj["ID"]; ok {
116+
id = fmt.Sprintf("%v", val)
117+
} else {
118+
http.Error(w, "POST sent with no id field in the data. Cannot persist this!", http.StatusBadRequest)
119+
return
120+
}
121+
}
122+
123+
/* Overwrite our stored test object */
124+
if svr.debug {
125+
log.Printf("fakeserver.go: Overwriting %s with new data:%+v\n", id, obj)
126+
}
127+
svr.objects[id] = obj
128+
129+
/* Coax the data we were sent back to JSON and send it to the user */
130+
b, _ := json.Marshal(obj)
131+
w.Write(b)
132+
return
133+
}
134+
} else {
135+
/* No data was sent... must be just a retrieval */
136+
if svr.debug { log.Printf("fakeserver.go: Returning object.\n") }
137+
b, _ := json.Marshal(obj)
138+
w.Write(b)
139+
return
140+
}
141+
142+
/* All cases by now should have already returned... something wasn't handled */
143+
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
144+
return
145+
}

0 commit comments

Comments
 (0)