more e2e test cases (#2450)

This commit is contained in:
fatedier
2021-06-18 16:48:36 +08:00
committed by GitHub
parent c7d4637382
commit 900454e58b
45 changed files with 1736 additions and 1953 deletions

View File

@@ -22,6 +22,7 @@ func NewAllocator(from int, to int, mod int, index int) *Allocator {
reserved: sets.NewInt(),
used: sets.NewInt(),
}
for i := from; i <= to; i++ {
if i%mod == index {
pa.reserved.Insert(i)
@@ -50,7 +51,7 @@ func (pa *Allocator) GetByName(portName string) int {
pa.mu.Lock()
defer pa.mu.Unlock()
for i := 0; i < 10; i++ {
for i := 0; i < 20; i++ {
port := pa.getByRange(builder.rangePortFrom, builder.rangePortTo)
if port == 0 {
return 0

View File

@@ -13,11 +13,17 @@ type Process struct {
stdOutput *bytes.Buffer
beforeStopHandler func()
stopped bool
}
func New(path string, params []string) *Process {
return NewWithEnvs(path, params, nil)
}
func NewWithEnvs(path string, params []string, envs []string) *Process {
ctx, cancel := context.WithCancel(context.Background())
cmd := exec.CommandContext(ctx, path, params...)
cmd.Env = envs
p := &Process{
cmd: cmd,
cancel: cancel,
@@ -34,6 +40,12 @@ func (p *Process) Start() error {
}
func (p *Process) Stop() error {
if p.stopped {
return nil
}
defer func() {
p.stopped = true
}()
if p.beforeStopHandler != nil {
p.beforeStopHandler()
}

View File

@@ -1,26 +1,44 @@
package request
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
"strconv"
"time"
libnet "github.com/fatedier/golib/net"
)
type Request struct {
protocol string
addr string
port int
body []byte
timeout time.Duration
proxyURL string
proxyHost string
protocol string
// for all protocol
addr string
port int
body []byte
timeout time.Duration
// for http
method string
host string
path string
headers map[string]string
proxyURL string
}
func New() *Request {
return &Request{
protocol: "tcp",
addr: "127.0.0.1",
method: "GET",
path: "/",
}
}
@@ -39,9 +57,13 @@ func (r *Request) UDP() *Request {
return r
}
func (r *Request) Proxy(url, host string) *Request {
func (r *Request) HTTP() *Request {
r.protocol = "http"
return r
}
func (r *Request) Proxy(url string) *Request {
r.proxyURL = url
r.proxyHost = host
return r
}
@@ -55,6 +77,29 @@ func (r *Request) Port(port int) *Request {
return r
}
func (r *Request) HTTPParams(method, host, path string, headers map[string]string) *Request {
r.method = method
r.host = host
r.path = path
r.headers = headers
return r
}
func (r *Request) HTTPHost(host string) *Request {
r.host = host
return r
}
func (r *Request) HTTPPath(path string) *Request {
r.path = path
return r
}
func (r *Request) HTTPHeaders(headers map[string]string) *Request {
r.headers = headers
return r
}
func (r *Request) Timeout(timeout time.Duration) *Request {
r.timeout = timeout
return r
@@ -65,28 +110,34 @@ func (r *Request) Body(content []byte) *Request {
return r
}
func (r *Request) Do() ([]byte, error) {
func (r *Request) Do() (*Response, error) {
var (
conn net.Conn
err error
)
addr := net.JoinHostPort(r.addr, strconv.Itoa(r.port))
// for protocol http
if r.protocol == "http" {
return sendHTTPRequest(r.method, fmt.Sprintf("http://%s%s", addr, r.path),
r.host, r.headers, r.proxyURL, r.body)
}
// for protocol tcp and udp
if len(r.proxyURL) > 0 {
if r.protocol != "tcp" {
return nil, fmt.Errorf("only tcp protocol is allowed for proxy")
}
conn, err = libnet.DialTcpByProxy(r.proxyURL, r.proxyHost)
conn, err = libnet.DialTcpByProxy(r.proxyURL, addr)
if err != nil {
return nil, err
}
} else {
if r.addr == "" {
r.addr = fmt.Sprintf("127.0.0.1:%d", r.port)
}
switch r.protocol {
case "tcp":
conn, err = net.Dial("tcp", r.addr)
conn, err = net.Dial("tcp", addr)
case "udp":
conn, err = net.Dial("udp", r.addr)
conn, err = net.Dial("udp", addr)
default:
return nil, fmt.Errorf("invalid protocol")
}
@@ -99,29 +150,63 @@ func (r *Request) Do() ([]byte, error) {
if r.timeout > 0 {
conn.SetDeadline(time.Now().Add(r.timeout))
}
return sendRequestByConn(conn, r.body)
buf, err := sendRequestByConn(conn, r.body)
if err != nil {
return nil, err
}
return &Response{Content: buf}, nil
}
func SendTCPRequest(port int, content []byte, timeout time.Duration) ([]byte, error) {
c, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", port))
if err != nil {
return nil, fmt.Errorf("connect to tcp server error: %v", err)
}
defer c.Close()
c.SetDeadline(time.Now().Add(timeout))
return sendRequestByConn(c, content)
type Response struct {
Code int
Header http.Header
Content []byte
}
func SendUDPRequest(port int, content []byte, timeout time.Duration) ([]byte, error) {
c, err := net.Dial("udp", fmt.Sprintf("127.0.0.1:%d", port))
if err != nil {
return nil, fmt.Errorf("connect to udp server error: %v", err)
func sendHTTPRequest(method, urlstr string, host string, headers map[string]string, proxy string, body []byte) (*Response, error) {
var inBody io.Reader
if len(body) != 0 {
inBody = bytes.NewReader(body)
}
req, err := http.NewRequest(method, urlstr, inBody)
if err != nil {
return nil, err
}
if host != "" {
req.Host = host
}
for k, v := range headers {
req.Header.Set(k, v)
}
tr := &http.Transport{
DialContext: (&net.Dialer{
Timeout: time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
if len(proxy) != 0 {
tr.Proxy = func(req *http.Request) (*url.URL, error) {
return url.Parse(proxy)
}
}
client := http.Client{Transport: tr}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer c.Close()
c.SetDeadline(time.Now().Add(timeout))
return sendRequestByConn(c, content)
ret := &Response{Code: resp.StatusCode, Header: resp.Header}
buf, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
ret.Content = buf
return ret, nil
}
func sendRequestByConn(c net.Conn, content []byte) ([]byte, error) {

View File

@@ -0,0 +1,133 @@
package client
import (
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"strconv"
"strings"
"github.com/fatedier/frp/client"
"github.com/fatedier/frp/test/e2e/pkg/utils"
)
type Client struct {
address string
authUser string
authPwd string
}
func New(host string, port int) *Client {
return &Client{
address: net.JoinHostPort(host, strconv.Itoa(port)),
}
}
func (c *Client) SetAuth(user, pwd string) {
c.authUser = user
c.authPwd = pwd
}
func (c *Client) GetProxyStatus(name string) (*client.ProxyStatusResp, error) {
req, err := http.NewRequest("GET", "http://"+c.address+"/api/status", nil)
if err != nil {
return nil, err
}
content, err := c.do(req)
if err != nil {
return nil, err
}
allStatus := &client.StatusResp{}
if err = json.Unmarshal([]byte(content), &allStatus); err != nil {
return nil, fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(content))
}
for _, s := range allStatus.TCP {
if s.Name == name {
return &s, nil
}
}
for _, s := range allStatus.UDP {
if s.Name == name {
return &s, nil
}
}
for _, s := range allStatus.HTTP {
if s.Name == name {
return &s, nil
}
}
for _, s := range allStatus.HTTPS {
if s.Name == name {
return &s, nil
}
}
for _, s := range allStatus.STCP {
if s.Name == name {
return &s, nil
}
}
for _, s := range allStatus.XTCP {
if s.Name == name {
return &s, nil
}
}
for _, s := range allStatus.SUDP {
if s.Name == name {
return &s, nil
}
}
return nil, fmt.Errorf("no proxy status found")
}
func (c *Client) Reload() error {
req, err := http.NewRequest("GET", "http://"+c.address+"/api/reload", nil)
if err != nil {
return err
}
_, err = c.do(req)
return err
}
func (c *Client) GetConfig() (string, error) {
req, err := http.NewRequest("GET", "http://"+c.address+"/api/config", nil)
if err != nil {
return "", err
}
return c.do(req)
}
func (c *Client) UpdateConfig(content string) error {
req, err := http.NewRequest("PUT", "http://"+c.address+"/api/config", strings.NewReader(content))
if err != nil {
return err
}
_, err = c.do(req)
return err
}
func (c *Client) setAuthHeader(req *http.Request) {
if c.authUser != "" || c.authPwd != "" {
req.Header.Set("Authorization", utils.BasicAuth(c.authUser, c.authPwd))
}
}
func (c *Client) do(req *http.Request) (string, error) {
c.setAuthHeader(req)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return "", fmt.Errorf("api status code [%d]", resp.StatusCode)
}
buf, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(buf), nil
}

View File

@@ -0,0 +1,10 @@
package utils
import (
"encoding/base64"
)
func BasicAuth(username, passwd string) string {
auth := username + ":" + passwd
return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))
}