1package testing 2 3import ( 4 "crypto/md5" 5 "fmt" 6 "io" 7 "net/http" 8 "testing" 9 "time" 10 11 "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects" 12 th "github.com/gophercloud/gophercloud/testhelper" 13 fake "github.com/gophercloud/gophercloud/testhelper/client" 14) 15 16// HandleDownloadObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that 17// responds with a `Download` response. 18func HandleDownloadObjectSuccessfully(t *testing.T) { 19 th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { 20 th.TestMethod(t, r, "GET") 21 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 22 th.TestHeader(t, r, "Accept", "application/json") 23 w.Header().Set("Date", "Wed, 10 Nov 2009 23:00:00 GMT") 24 w.Header().Set("X-Static-Large-Object", "True") 25 w.WriteHeader(http.StatusOK) 26 fmt.Fprintf(w, "Successful download with Gophercloud") 27 }) 28} 29 30// ExpectedListInfo is the result expected from a call to `List` when full 31// info is requested. 32var ExpectedListInfo = []objects.Object{ 33 { 34 Hash: "451e372e48e0f6b1114fa0724aa79fa1", 35 LastModified: time.Date(2016, time.August, 17, 22, 11, 58, 602650000, time.UTC), //"2016-08-17T22:11:58.602650" 36 Bytes: 14, 37 Name: "goodbye", 38 ContentType: "application/octet-stream", 39 }, 40 { 41 Hash: "451e372e48e0f6b1114fa0724aa79fa1", 42 LastModified: time.Date(2016, time.August, 17, 22, 11, 58, 602650000, time.UTC), 43 Bytes: 14, 44 Name: "hello", 45 ContentType: "application/octet-stream", 46 }, 47} 48 49// ExpectedListSubdir is the result expected from a call to `List` when full 50// info is requested. 51var ExpectedListSubdir = []objects.Object{ 52 { 53 Subdir: "directory/", 54 }, 55} 56 57// ExpectedListNames is the result expected from a call to `List` when just 58// object names are requested. 59var ExpectedListNames = []string{"hello", "goodbye"} 60 61// HandleListObjectsInfoSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that 62// responds with a `List` response when full info is requested. 63func HandleListObjectsInfoSuccessfully(t *testing.T) { 64 th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { 65 th.TestMethod(t, r, "GET") 66 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 67 th.TestHeader(t, r, "Accept", "application/json") 68 69 w.Header().Set("Content-Type", "application/json") 70 r.ParseForm() 71 marker := r.Form.Get("marker") 72 switch marker { 73 case "": 74 fmt.Fprintf(w, `[ 75 { 76 "hash": "451e372e48e0f6b1114fa0724aa79fa1", 77 "last_modified": "2016-08-17T22:11:58.602650", 78 "bytes": 14, 79 "name": "goodbye", 80 "content_type": "application/octet-stream" 81 }, 82 { 83 "hash": "451e372e48e0f6b1114fa0724aa79fa1", 84 "last_modified": "2016-08-17T22:11:58.602650", 85 "bytes": 14, 86 "name": "hello", 87 "content_type": "application/octet-stream" 88 } 89 ]`) 90 case "hello": 91 fmt.Fprintf(w, `[]`) 92 default: 93 t.Fatalf("Unexpected marker: [%s]", marker) 94 } 95 }) 96} 97 98// HandleListSubdirSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that 99// responds with a `List` response when full info is requested. 100func HandleListSubdirSuccessfully(t *testing.T) { 101 th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { 102 th.TestMethod(t, r, "GET") 103 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 104 th.TestHeader(t, r, "Accept", "application/json") 105 106 w.Header().Set("Content-Type", "application/json") 107 r.ParseForm() 108 marker := r.Form.Get("marker") 109 switch marker { 110 case "": 111 fmt.Fprintf(w, `[ 112 { 113 "subdir": "directory/" 114 } 115 ]`) 116 case "directory/": 117 fmt.Fprintf(w, `[]`) 118 default: 119 t.Fatalf("Unexpected marker: [%s]", marker) 120 } 121 }) 122} 123 124// HandleListObjectNamesSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that 125// responds with a `List` response when only object names are requested. 126func HandleListObjectNamesSuccessfully(t *testing.T) { 127 th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) { 128 th.TestMethod(t, r, "GET") 129 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 130 th.TestHeader(t, r, "Accept", "text/plain") 131 132 w.Header().Set("Content-Type", "text/plain") 133 r.ParseForm() 134 marker := r.Form.Get("marker") 135 switch marker { 136 case "": 137 fmt.Fprintf(w, "hello\ngoodbye\n") 138 case "goodbye": 139 fmt.Fprintf(w, "") 140 default: 141 t.Fatalf("Unexpected marker: [%s]", marker) 142 } 143 }) 144} 145 146// HandleCreateTextObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux 147// that responds with a `Create` response. A Content-Type of "text/plain" is expected. 148func HandleCreateTextObjectSuccessfully(t *testing.T, content string) { 149 th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { 150 th.TestMethod(t, r, "PUT") 151 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 152 th.TestHeader(t, r, "Content-Type", "text/plain") 153 th.TestHeader(t, r, "Accept", "application/json") 154 155 hash := md5.New() 156 io.WriteString(hash, content) 157 localChecksum := hash.Sum(nil) 158 159 w.Header().Set("ETag", fmt.Sprintf("%x", localChecksum)) 160 w.WriteHeader(http.StatusCreated) 161 }) 162} 163 164// HandleCreateTextWithCacheControlSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler 165// mux that responds with a `Create` response. A Cache-Control of `max-age="3600", public` is expected. 166func HandleCreateTextWithCacheControlSuccessfully(t *testing.T, content string) { 167 th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { 168 th.TestMethod(t, r, "PUT") 169 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 170 th.TestHeader(t, r, "Cache-Control", `max-age="3600", public`) 171 th.TestHeader(t, r, "Accept", "application/json") 172 173 hash := md5.New() 174 io.WriteString(hash, content) 175 localChecksum := hash.Sum(nil) 176 177 w.Header().Set("ETag", fmt.Sprintf("%x", localChecksum)) 178 w.WriteHeader(http.StatusCreated) 179 }) 180} 181 182// HandleCreateTypelessObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler 183// mux that responds with a `Create` response. No Content-Type header may be present in the request, so that server- 184// side content-type detection will be triggered properly. 185func HandleCreateTypelessObjectSuccessfully(t *testing.T, content string) { 186 th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { 187 th.TestMethod(t, r, "PUT") 188 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 189 th.TestHeader(t, r, "Accept", "application/json") 190 191 if contentType, present := r.Header["Content-Type"]; present { 192 t.Errorf("Expected Content-Type header to be omitted, but was %#v", contentType) 193 } 194 195 hash := md5.New() 196 io.WriteString(hash, content) 197 localChecksum := hash.Sum(nil) 198 199 w.Header().Set("ETag", fmt.Sprintf("%x", localChecksum)) 200 w.WriteHeader(http.StatusCreated) 201 }) 202} 203 204// HandleCopyObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that 205// responds with a `Copy` response. 206func HandleCopyObjectSuccessfully(t *testing.T) { 207 th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { 208 th.TestMethod(t, r, "COPY") 209 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 210 th.TestHeader(t, r, "Accept", "application/json") 211 th.TestHeader(t, r, "Destination", "/newTestContainer/newTestObject") 212 w.WriteHeader(http.StatusCreated) 213 }) 214} 215 216// HandleDeleteObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that 217// responds with a `Delete` response. 218func HandleDeleteObjectSuccessfully(t *testing.T) { 219 th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { 220 th.TestMethod(t, r, "DELETE") 221 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 222 th.TestHeader(t, r, "Accept", "application/json") 223 w.WriteHeader(http.StatusNoContent) 224 }) 225} 226 227// HandleUpdateObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that 228// responds with a `Update` response. 229func HandleUpdateObjectSuccessfully(t *testing.T) { 230 th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { 231 th.TestMethod(t, r, "POST") 232 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 233 th.TestHeader(t, r, "Accept", "application/json") 234 th.TestHeader(t, r, "X-Object-Meta-Gophercloud-Test", "objects") 235 w.WriteHeader(http.StatusAccepted) 236 }) 237} 238 239// HandleGetObjectSuccessfully creates an HTTP handler at `/testContainer/testObject` on the test handler mux that 240// responds with a `Get` response. 241func HandleGetObjectSuccessfully(t *testing.T) { 242 th.Mux.HandleFunc("/testContainer/testObject", func(w http.ResponseWriter, r *http.Request) { 243 th.TestMethod(t, r, "HEAD") 244 th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) 245 th.TestHeader(t, r, "Accept", "application/json") 246 w.Header().Add("X-Object-Meta-Gophercloud-Test", "objects") 247 w.Header().Add("X-Static-Large-Object", "true") 248 w.WriteHeader(http.StatusNoContent) 249 }) 250} 251