Skip to content

Commit

Permalink
Merge pull request #434 from aau-network-security/feature/add-stresst…
Browse files Browse the repository at this point in the history
…est-cmd-#000

Feature/add stresstest cmd #000
  • Loading branch information
mrtrkmn committed Sep 8, 2020
2 parents 499f3e5 + 2c8b98a commit d71a2d3
Show file tree
Hide file tree
Showing 6 changed files with 400 additions and 137 deletions.
27 changes: 26 additions & 1 deletion client/cli/event.go
Expand Up @@ -34,7 +34,7 @@ func (c *Client) CmdEvent() *cobra.Command {
c.CmdEventResume(),
c.CmdEventList(),
c.CmdEventTeams(),

c.CmdEventLoadTest(),
c.CmdEventTeamRestart())

return cmd
Expand Down Expand Up @@ -303,6 +303,31 @@ func (c *Client) CmdEventTeams() *cobra.Command {
}
}

func (c *Client) CmdEventLoadTest() *cobra.Command {
var eventTag string
var numberOfTeams int32
cmd := &cobra.Command{
Use: "load",
Short: "Apply load test on an event",
Example: `hkn event load -t test -r 3 `,
Run: func(cmd *cobra.Command, args []string) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
r, err := c.rpcClient.StressEvent(ctx, &pb.TestEventLoadReq{EventName: eventTag, NumberOfTeams: numberOfTeams})

if err != nil {
PrintError(err)
return
}
fmt.Println(r.SignUpResult)
return
},
}
cmd.Flags().StringVarP(&eventTag, "tag", "t", "", "event tag")
cmd.Flags().Int32VarP(&numberOfTeams, "requests", "r", 1, "number of users")
return cmd
}

func (c *Client) CmdEventTeamRestart() *cobra.Command {
return &cobra.Command{
Use: "restart [event tag] [team id]",
Expand Down
91 changes: 91 additions & 0 deletions daemon/event.go
Expand Up @@ -2,8 +2,12 @@ package daemon

import (
"context"
"errors"
"fmt"
"math"
"math/rand"
"net/http"
"net/url"
"strconv"
"strings"
"time"
Expand All @@ -15,7 +19,14 @@ import (
"github.com/rs/zerolog/log"
)

const (
charSet = "abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
numSet = "0123456789"
)

var (
NoPrivilegeToStressTest = errors.New("No privilege to have stress test on Haaukins !")
NPUserMaxLabs = 40
NotAvailableTag = "not available tag, there is already an event which is either running, booked or suspended"
)
Expand Down Expand Up @@ -547,6 +558,86 @@ func (d *daemon) closeEvents() error {
return nil
}

// StressEvent is making requests to daemon to see how daemon can handle them
func (d *daemon) StressEvent(ctx context.Context, req *pb.TestEventLoadReq) (*pb.TestEventLoadResp, error) {
user, err := getUserFromIncomingContext(ctx)
if err != nil {
return &pb.TestEventLoadResp{}, err
}
if !user.SuperUser {
return &pb.TestEventLoadResp{}, NoPrivilegeToStressTest
}

ev, err := d.eventPool.GetEvent(store.Tag(req.EventName))
if ev == nil {
return &pb.TestEventLoadResp{}, fmt.Errorf("no such an event called %s, error: %v !", req.EventName, err)
}

if ev.GetConfig().Capacity < int(req.NumberOfTeams) {
return &pb.TestEventLoadResp{}, errors.New("event capacity is less than provided number of teams. skipping testing...")
}
var port, protocol string
if d.conf.Certs.Enabled {
port = strconv.FormatUint(uint64(d.conf.Port.Secure), 10)
protocol = "https://"
} else {
port = strconv.FormatUint(uint64(d.conf.Port.InSecure), 10)
protocol = "http://"
}
endPoint := fmt.Sprintf(protocol + req.EventName + "." + d.conf.Host.Http + ":" + port + "/signup")
resp := make(chan string)
for i := 0; i < int(req.NumberOfTeams); i++ {
go func() {
resp <- d.postRequest(endPoint, protocol)
}()
}
response := <-resp

return &pb.TestEventLoadResp{SignUpResult: response}, nil
}

// constructRandomValues will create random form for signing up
func constructRandomValues() url.Values {
name := stringWithCharset(10, charSet)
email := fmt.Sprintf("%s@%s.com", stringWithCharset(10, charSet), stringWithCharset(10, charSet))
password := fmt.Sprintf("%s", stringWithCharset(6, numSet))
form := url.Values{}
form.Add("email", email)
form.Add("team-name", name)
form.Add("password", password)
form.Add("password-repeat", password)
return form
}

func (d *daemon) postRequest(endPoint, protocol string) string {
hc := http.Client{}
v := constructRandomValues()
postReq, err := http.NewRequest("POST", endPoint, strings.NewReader(v.Encode()))
if err != nil {
return err.Error()
}
postReq.Form = v
postReq.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0")
postReq.Header.Add("Referer", protocol+endPoint)
postReq.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp, err := hc.Do(postReq)
if err != nil {
return err.Error()
}
return resp.Status
}

// StringWithCharset will return random characters
func stringWithCharset(length int, charset string) string {
var seededRand *rand.Rand = rand.New(
rand.NewSource(time.Now().UnixNano()))
b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
}

func isDelayed(customTime string) bool {
now := time.Now()
givenTime, _ := time.Parse(displayTimeFormat, customTime)
Expand Down

0 comments on commit d71a2d3

Please sign in to comment.