go-ethereum/p2p/simulations/rest_api_server_test.go
zelig 15b8c39f96 p2p: network testing framework and protocol abstraction
subpackages:

* adapters:
  * msgpipes for simulated test connections
  * rlpx the RLPx adapter for normal non-test use
  * simnet simulated in-process network adapter
* protocols: easy-to-setup protocols
* simulations:
  * simulated network using simnet adapter
  * (local cluster of nodes running their own p2p server)
  * (remote cluster of nodes managed via docker)
* testing: test resource drivers
  * exchange: trigger/expect style driver for single node and its peers
  * sessions:   for unit testing protocols and protocol modules
  * (network: for network testing, benchmarking, stats, correctness, fault tolerance)

see more in the README-s in each subpackage
2016-10-27 07:44:09 +01:00

137 lines
2.6 KiB
Go

package simulations
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"testing"
)
const testPort = "8889"
type testController struct {
}
func (self *testController) SetResource(id string, c Controller) {
}
func (self *testController) Resource(id string) (Controller, error) {
if id == "missing" {
return nil, fmt.Errorf("missing")
}
return Controller(self), nil
}
func (self *testController) Handle(method string) (returnHandler, error) {
switch method {
case "POST":
case "DELETE":
default:
return nil, fmt.Errorf("allowed methods: POST DELETE")
}
return handlerf(method), nil
}
func handlerf(method string) returnHandler {
return func(r io.Reader) (io.ReadSeeker, error) {
body, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
if string(body) == "invalid" {
return nil, fmt.Errorf("invalid body")
}
return io.ReadSeeker(bytes.NewReader([]byte("response"))), nil
}
}
func init() {
StartRestApiServer(testPort, &testController{})
}
type testRequest struct {
method string
path string
body string
response string
status int
}
type ReadCloser struct {
io.Reader
}
func (ReadCloser) Close() {}
func testResponses(t *testing.T, reqs ...*testRequest) {
for _, req := range reqs {
path := url(testPort, req.path)
var r *http.Response
var err error
switch req.method {
case "POST":
r, err = http.Post(path, "text/json", ReadCloser{bytes.NewReader([]byte(req.body))})
default:
r, err = http.Get(path)
}
if err != nil {
t.Fatalf("unexpected error on request: %v", err)
}
if r.StatusCode != req.status {
t.Fatalf("unexpected status on request: got %v, expected %v", r.StatusCode, req.status)
}
body, err := ioutil.ReadAll(r.Body)
if err != nil {
t.Fatalf("unexpected error on reading body: %v", err)
}
if string(body) != req.response {
t.Fatalf("unexpected response body. got '%s', expected '%v'", body, req.response)
}
}
}
func TestServerMethodNotAllowed(t *testing.T) {
testResponses(t,
&testRequest{
"GET",
"anypath",
"anybody",
"method GET not allowed (allowed methods: POST DELETE)\n",
http.StatusMethodNotAllowed,
})
}
func TestServerInvalid(t *testing.T) {
testResponses(t,
&testRequest{
"POST",
"anypath",
"invalid",
"handler error: invalid body\n",
http.StatusBadRequest,
})
}
func TestServerResourceNotFound(t *testing.T) {
testResponses(t,
&testRequest{
"POST",
"missing",
"anybody",
"resource missing not found\n",
http.StatusNotFound,
})
}
func TestServerSuccess(t *testing.T) {
testResponses(t,
&testRequest{
"POST",
"anypath",
"anybody",
"response",
http.StatusOK,
})
}