2013-08-17 16:14:08 +02:00
|
|
|
package vegeta
|
2013-08-13 18:51:00 +02:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bufio"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
2013-08-20 11:17:03 -04:00
|
|
|
"regexp"
|
2013-08-13 18:51:00 +02:00
|
|
|
"math/rand"
|
|
|
|
|
"net/http"
|
|
|
|
|
"os"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
2013-08-17 16:14:08 +02:00
|
|
|
// Targets represents the http.Requests which will be issued during the test
|
2013-08-13 18:51:00 +02:00
|
|
|
type Targets []*http.Request
|
|
|
|
|
|
2013-08-17 16:14:08 +02:00
|
|
|
// NewTargetsFromFile reads and parses targets from a text file
|
2013-08-13 18:51:00 +02:00
|
|
|
func NewTargetsFromFile(filename string) (Targets, error) {
|
|
|
|
|
file, err := os.Open(filename)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return Targets{}, err
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
2013-08-17 16:14:08 +02:00
|
|
|
return readTargets(file)
|
2013-08-13 18:51:00 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-17 16:14:08 +02:00
|
|
|
// readTargets reads targets out of a line separated source skipping empty lines
|
|
|
|
|
func readTargets(source io.Reader) (Targets, error) {
|
2013-08-16 19:46:40 +02:00
|
|
|
scanner := bufio.NewScanner(source)
|
2013-08-17 16:14:08 +02:00
|
|
|
lines := make([]string, 0)
|
2013-08-16 19:46:40 +02:00
|
|
|
for scanner.Scan() {
|
|
|
|
|
line := scanner.Text()
|
2013-08-20 11:17:03 -04:00
|
|
|
|
|
|
|
|
if !skipLine(line) { // Not a comment or blank line
|
|
|
|
|
lines = append(lines, line)
|
2013-08-13 18:51:00 +02:00
|
|
|
}
|
2013-08-17 16:14:08 +02:00
|
|
|
}
|
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
|
|
|
return Targets{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NewTargets(lines)
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-20 11:17:03 -04:00
|
|
|
func skipLine(line string) (bool) {
|
|
|
|
|
return regexp.MustCompile(`^\s*((\/\/)|$)`).MatchString(line)
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-17 16:14:08 +02:00
|
|
|
// NewTargets instantiates Targets from a slice of strings
|
|
|
|
|
func NewTargets(lines []string) (Targets, error) {
|
|
|
|
|
targets := make([]*http.Request, 0)
|
|
|
|
|
for _, line := range lines {
|
2013-08-13 18:51:00 +02:00
|
|
|
parts := strings.SplitN(line, " ", 2)
|
|
|
|
|
if len(parts) != 2 {
|
|
|
|
|
return targets, fmt.Errorf("Invalid request format: `%s`", line)
|
|
|
|
|
}
|
|
|
|
|
// Build request
|
|
|
|
|
req, err := http.NewRequest(parts[0], parts[1], nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return targets, fmt.Errorf("Failed to build request: %s", err)
|
|
|
|
|
}
|
|
|
|
|
targets = append(targets, req)
|
|
|
|
|
}
|
|
|
|
|
return targets, nil
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-17 16:14:08 +02:00
|
|
|
// Shuffle randomly alters the order of Targets with the provided seed
|
2013-08-16 19:38:57 +02:00
|
|
|
func (t Targets) Shuffle(seed int64) {
|
|
|
|
|
rand.Seed(seed)
|
|
|
|
|
for i, rnd := range rand.Perm(len(t)) {
|
|
|
|
|
tmp := t[i]
|
|
|
|
|
t[i] = t[rnd]
|
|
|
|
|
t[rnd] = tmp
|
2013-08-13 18:51:00 +02:00
|
|
|
}
|
|
|
|
|
}
|