blob: a68d973220c89df48014a59f0e04917a59a375c8 [file] [log] [blame]
Philipp Schrader5562df72022-02-16 20:56:51 -08001package static
2
3import (
Emily Markovafaecfe12023-07-01 12:40:03 -07004 "errors"
Philipp Schrader5562df72022-02-16 20:56:51 -08005 "fmt"
6 "io/ioutil"
7 "net/http"
8 "testing"
9
Emily Markovafaecfe12023-07-01 12:40:03 -070010 "github.com/frc971/971-Robot-Code/scouting/db"
Philipp Schrader5562df72022-02-16 20:56:51 -080011 "github.com/frc971/971-Robot-Code/scouting/webserver/server"
12)
13
Emily Markovafaecfe12023-07-01 12:40:03 -070014type MockDatabase struct {
15 images []db.PitImage
16}
17
18func (database *MockDatabase) QueryPitImageByChecksum(checksum string) (db.PitImage, error) {
19 for _, data := range database.images {
20 if data.CheckSum == checksum {
21 return data, nil
22 }
23 }
24
25 return db.PitImage{}, errors.New("Could not find pit image")
26}
27
Philipp Schrader45721a72022-04-02 16:27:53 -070028func expectEqual(t *testing.T, actual string, expected string) {
29 if actual != expected {
30 t.Error("Expected ", actual, " to equal ", expected)
31 }
32}
33
Philipp Schrader5562df72022-02-16 20:56:51 -080034func TestServing(t *testing.T) {
Emily Markovafaecfe12023-07-01 12:40:03 -070035 database := MockDatabase{
36 images: []db.PitImage{
37 {
38 TeamNumber: "971", CheckSum: "3yi32rhewd23",
39 ImagePath: "abc.png", ImageData: []byte("hello"),
40 },
41 },
42 }
43
Philipp Schrader5562df72022-02-16 20:56:51 -080044 cases := []struct {
45 // The path to request from the server.
46 path string
47 // The data that the server is expected to return at the
48 // specified path.
49 expectedData string
50 }{
Philipp Schrader45721a72022-04-02 16:27:53 -070051 {"/", "<h1>This is the index</h1>\n"},
Philipp Schrader5562df72022-02-16 20:56:51 -080052 {"/root.txt", "Hello, this is the root page!"},
53 {"/page.txt", "Hello from a page!"},
Emily Markovafaecfe12023-07-01 12:40:03 -070054 {"/sha256/3yi32rhewd23/abc.png", "hello"},
Philipp Schrader5562df72022-02-16 20:56:51 -080055 }
56
57 scoutingServer := server.NewScoutingServer()
Emily Markovafaecfe12023-07-01 12:40:03 -070058 ServePages(scoutingServer, "test_pages", &database)
Philipp Schrader5562df72022-02-16 20:56:51 -080059 scoutingServer.Start(8080)
Philipp Schrader45721a72022-04-02 16:27:53 -070060 defer scoutingServer.Stop()
Philipp Schrader5562df72022-02-16 20:56:51 -080061
62 // Go through all the test cases, and run them against the running webserver.
63 for _, c := range cases {
64 dataReceived := getData(c.path, t)
Philipp Schrader45721a72022-04-02 16:27:53 -070065 expectEqual(t, dataReceived, c.expectedData)
Philipp Schrader5562df72022-02-16 20:56:51 -080066 }
Philipp Schrader5562df72022-02-16 20:56:51 -080067}
68
Philipp Schrader45721a72022-04-02 16:27:53 -070069// Makes sure that requesting / sets the proper headers so it doesn't get
70// cached.
71func TestDisallowedCache(t *testing.T) {
Emily Markovafaecfe12023-07-01 12:40:03 -070072 database := MockDatabase{}
Alex Perryb2f76522022-03-30 21:02:05 -070073 scoutingServer := server.NewScoutingServer()
Emily Markovafaecfe12023-07-01 12:40:03 -070074 ServePages(scoutingServer, "test_pages", &database)
Alex Perryb2f76522022-03-30 21:02:05 -070075 scoutingServer.Start(8080)
Philipp Schrader45721a72022-04-02 16:27:53 -070076 defer scoutingServer.Stop()
77
78 resp, err := http.Get("http://localhost:8080/")
79 if err != nil {
80 t.Fatal("Failed to get data ", err)
81 }
82 expectEqual(t, resp.Header.Get("Expires"), "Thu, 01 Jan 1970 00:00:00 UTC")
83 expectEqual(t, resp.Header.Get("Cache-Control"), "no-cache, private, max-age=0")
84 expectEqual(t, resp.Header.Get("Pragma"), "no-cache")
85 expectEqual(t, resp.Header.Get("X-Accel-Expires"), "0")
86}
87
88// Makes sure that requesting anything other than / doesn't set the "do not
89// cache" headers.
90func TestAllowedCache(t *testing.T) {
Emily Markovafaecfe12023-07-01 12:40:03 -070091 database := MockDatabase{}
Philipp Schrader45721a72022-04-02 16:27:53 -070092 scoutingServer := server.NewScoutingServer()
Emily Markovafaecfe12023-07-01 12:40:03 -070093 ServePages(scoutingServer, "test_pages", &database)
Philipp Schrader45721a72022-04-02 16:27:53 -070094 scoutingServer.Start(8080)
95 defer scoutingServer.Stop()
Alex Perryb2f76522022-03-30 21:02:05 -070096
97 resp, err := http.Get("http://localhost:8080/root.txt")
98 if err != nil {
99 t.Fatalf("Failed to get data ", err)
100 }
Philipp Schrader45721a72022-04-02 16:27:53 -0700101 expectEqual(t, resp.Header.Get("Expires"), "")
102 expectEqual(t, resp.Header.Get("Cache-Control"), "")
103 expectEqual(t, resp.Header.Get("Pragma"), "")
104 expectEqual(t, resp.Header.Get("X-Accel-Expires"), "")
Alex Perryb2f76522022-03-30 21:02:05 -0700105}
106
Philipp Schrader45721a72022-04-02 16:27:53 -0700107func TestSha256(t *testing.T) {
Emily Markovafaecfe12023-07-01 12:40:03 -0700108 database := MockDatabase{
109 images: []db.PitImage{
110 {
111 TeamNumber: "971", CheckSum: "3yi32rhewd23",
112 ImagePath: "abc.png", ImageData: []byte{32, 54, 23, 00},
113 },
114 },
115 }
Philipp Schrader45721a72022-04-02 16:27:53 -0700116 scoutingServer := server.NewScoutingServer()
Emily Markovafaecfe12023-07-01 12:40:03 -0700117 ServePages(scoutingServer, "test_pages", &database)
Philipp Schrader45721a72022-04-02 16:27:53 -0700118 scoutingServer.Start(8080)
119 defer scoutingServer.Stop()
120
Emily Markovafaecfe12023-07-01 12:40:03 -0700121 //Validate receiving the correct byte sequence from image request.
122 byteDataReceived := getData("sha256/3yi32rhewd23/abc.png", t)
123 expectEqual(t, string(byteDataReceived), string([]byte{32, 54, 23, 00}))
124
Philipp Schrader45721a72022-04-02 16:27:53 -0700125 // Validate a valid checksum.
126 dataReceived := getData("sha256/553b9b29647a112136986cf93c57b988d1f12dc43d3b774f14a24e58d272dbff/root.txt", t)
127 expectEqual(t, dataReceived, "Hello, this is the root page!")
128
129 // Make a request with an invalid checksum and make sure we get a 404.
130 resp, err := http.Get("http://localhost:8080/sha256/0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef/root.txt")
131 if err != nil {
132 t.Fatal("Failed to get data ", err)
Alex Perryb2f76522022-03-30 21:02:05 -0700133 }
Philipp Schrader45721a72022-04-02 16:27:53 -0700134 expectEqual(t, resp.Status, "404 Not Found")
Philipp Schrader67fe6d02022-04-16 15:37:40 -0700135
136 // Make a request with a valid checksum but invalid path and make sure
137 // we get a 400.
138 resp, err = http.Get("http://localhost:8080/sha256/553b9b29647a112136986cf93c57b988d1f12dc43d3b774f14a24e58d272dbff/not_root.txt")
139 if err != nil {
140 t.Fatal("Failed to get data ", err)
141 }
142 expectEqual(t, resp.Status, "400 Bad Request")
Alex Perryb2f76522022-03-30 21:02:05 -0700143}
144
Philipp Schrader5562df72022-02-16 20:56:51 -0800145// Retrieves the data at the specified path. If an error occurs, the test case
146// is terminated and failed.
147func getData(path string, t *testing.T) string {
148 resp, err := http.Get(fmt.Sprintf("http://localhost:8080/%s", path))
149 if err != nil {
150 t.Fatalf("Failed to get data ", err)
151 }
152 // Error out if the return status is anything other than 200 OK.
153 if resp.Status != "200 OK" {
Philipp Schrader45721a72022-04-02 16:27:53 -0700154 t.Fatal("Received a status code other than 200:", resp.Status)
Philipp Schrader5562df72022-02-16 20:56:51 -0800155 }
156 // Read the response body.
157 body, err := ioutil.ReadAll(resp.Body)
158 if err != nil {
159 t.Fatalf("Failed to read body")
160 }
161 // Decode the body and return it.
162 return string(body)
163}