route/internal/tun2/server_test.go

233 lines
4.3 KiB
Go
Raw Normal View History

2017-10-03 20:20:23 +00:00
package tun2
import (
2017-10-04 06:43:31 +00:00
"bytes"
2017-10-03 20:20:23 +00:00
"context"
2017-10-04 06:43:31 +00:00
"encoding/json"
2017-10-03 20:20:23 +00:00
"fmt"
"io/ioutil"
2017-10-04 06:43:31 +00:00
"net"
2017-10-03 20:20:23 +00:00
"net/http"
2017-10-04 06:43:31 +00:00
"net/http/httptest"
"os"
2017-10-03 20:20:23 +00:00
"strings"
"testing"
2017-10-04 06:43:31 +00:00
"time"
2017-10-03 20:20:23 +00:00
"github.com/Xe/uuid"
)
2017-10-04 06:43:31 +00:00
// testing constants
const (
user = "shachi"
token = "orcaz r kewl"
noPermToken = "aw heck"
otherUserToken = "even more heck"
domain = "cetacean.club"
)
2017-10-03 20:20:23 +00:00
func TestNewServerNullConfig(t *testing.T) {
_, err := NewServer(nil)
if err == nil {
t.Fatalf("expected NewServer(nil) to fail, got non-failure")
}
}
func TestGen502Page(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
req, err := http.NewRequest("GET", "http://cetacean.club", nil)
if err != nil {
t.Fatal(err)
}
substring := uuid.New()
req = req.WithContext(ctx)
req.Header.Add("X-Request-Id", substring)
req.Host = "cetacean.club"
resp := gen502Page(req)
if resp == nil {
t.Fatalf("expected response to be non-nil")
}
if resp.Body != nil {
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(data), substring) {
fmt.Println(string(data))
t.Fatalf("502 page did not contain needed substring %q", substring)
}
}
}
2017-10-04 06:43:31 +00:00
func TestBackendAuthV1(t *testing.T) {
st := MockStorage()
s, err := NewServer(&ServerConfig{
Storage: st,
})
if err != nil {
t.Fatal(err)
}
st.AddRoute(domain, user)
st.AddToken(token, user, []string{"connect"})
st.AddToken(noPermToken, user, nil)
st.AddToken(otherUserToken, "cadey", []string{"connect"})
cases := []struct {
name string
auth Auth
wantErr bool
}{
{
name: "basic everything should work",
auth: Auth{
Token: token,
Domain: domain,
},
wantErr: false,
},
{
name: "invalid domain",
auth: Auth{
Token: token,
Domain: "aw.heck",
},
wantErr: true,
},
{
name: "invalid token",
auth: Auth{
Token: "asdfwtweg",
Domain: domain,
},
wantErr: true,
},
{
name: "invalid token scopes",
auth: Auth{
Token: noPermToken,
Domain: domain,
},
wantErr: true,
},
{
name: "user token doesn't match domain owner",
auth: Auth{
Token: otherUserToken,
Domain: domain,
},
wantErr: true,
},
}
for _, cs := range cases {
t.Run(cs.name, func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
data, err := json.Marshal(cs.auth)
if err != nil {
t.Fatal(err)
}
_, _, err = s.backendAuthv1(ctx, bytes.NewBuffer(data))
if cs.wantErr && err == nil {
t.Fatalf("auth did not err as expected")
}
if !cs.wantErr && err != nil {
t.Fatalf("unexpected auth err: %v", err)
}
})
}
}
func TestBackendRouting(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
st := MockStorage()
st.AddRoute(domain, user)
st.AddToken(token, user, []string{"connect"})
s, err := NewServer(&ServerConfig{
Storage: st,
})
if err != nil {
t.Fatal(err)
}
l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
go s.Listen(l, false)
cases := []struct {
name string
should200 bool
handler http.HandlerFunc
}{
{
name: "200 everything's okay",
should200: true,
handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "HTTP 200, everything is okay :)", http.StatusOK)
}),
},
}
for _, cs := range cases {
t.Run(cs.name, func(t *testing.T) {
ts := httptest.NewServer(cs.handler)
defer ts.Close()
cc := &ClientConfig{
ConnType: "tcp",
ServerAddr: l.Addr().String(),
Token: token,
BackendURL: ts.URL,
2017-10-04 07:26:43 +00:00
Domain: domain,
forceTCPClear: true,
2017-10-04 06:43:31 +00:00
}
c, err := NewClient(cc)
if err != nil {
t.Fatal(err)
}
2017-10-04 07:26:43 +00:00
go c.Connect(ctx) // TODO: fix the client library so this ends up actually getting cleaned up
2017-10-04 06:43:31 +00:00
2017-10-04 07:26:43 +00:00
time.Sleep(time.Second)
2017-10-04 06:43:31 +00:00
req, err := http.NewRequest("GET", "http://cetacean.club/", nil)
if err != nil {
t.Fatal(err)
}
resp, err := s.RoundTrip(req)
if err != nil {
t.Fatalf("error in doing round trip: %v", err)
}
if cs.should200 && resp.StatusCode != http.StatusOK {
resp.Write(os.Stdout)
t.Fatalf("got status %d instead of StatusOK", resp.StatusCode)
}
})
}
}