├── .circleci └── config.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── cmd └── gotling │ └── main.go ├── data ├── fleetdata.csv └── testdata.csv ├── docs ├── gotling-console.png ├── gotling-dashboard.png ├── gotling-dashboard1.png ├── gotling-dashboard2.png ├── gotling-overview.png ├── gotling-report1.png ├── gotling-seq.png ├── gotling-seq.puml └── xd-setup.md ├── go.mod ├── go.sum ├── internal └── pkg │ ├── action │ ├── action.go │ ├── actionbuilder.go │ ├── httpaction.go │ ├── httpreq.go │ ├── sleepaction.go │ ├── sleepaction_test.go │ ├── tcpaction.go │ ├── tcpreq.go │ ├── udpaction.go │ └── udpreq.go │ ├── feeder │ └── feeder.go │ ├── result │ ├── httpreqresult.go │ ├── httpresulthandler.go │ ├── resultwriter.go │ ├── statframe.go │ └── tcpreqresult.go │ ├── runtime │ └── globals.go │ ├── server │ └── wsserver.go │ ├── testdef │ ├── testdef_validator.go │ └── testdefinition.go │ └── util │ └── variableprocessor.go ├── samples ├── demoheaders.yml ├── demosimulation.yml ├── invalid.yml ├── ltest00.yml ├── ltest01.yml ├── spring-xd-demo.yml ├── withpost.yml ├── xmldemo-invalid.yml └── xmldemo.yml ├── static └── index.html └── templates └── placeholder.txt /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 # use CircleCI 2.0 2 | jobs: # basic units of work in a run 3 | build: # runs not using Workflows must have a `build` job as entry point 4 | docker: # run the steps with Docker 5 | # CircleCI Go images available at: https://hub.docker.com/r/circleci/golang/ 6 | - image: circleci/golang:1.13-buster-node-browsers-legacy # circleci/golang:1.13.10 # 7 | 8 | # environment variables for the build itself 9 | environment: 10 | GO111MODULE: "on" # Enable go 1.11 modules support 11 | TEST_RESULTS: /tmp/test-results # path to where test results will be saved 12 | 13 | # steps that comprise the `build` job 14 | steps: 15 | - checkout # check out source code to working directory 16 | - run: mkdir -p $TEST_RESULTS # create the test results directory 17 | 18 | - restore_cache: # restores saved cache if no changes are detected since last run 19 | keys: 20 | - go-mod-v1-{{ checksum "go.sum" }} 21 | 22 | # Code quality checks 23 | - run: 24 | name: Run go vet 25 | command: | 26 | make vet 2>&1 | tee ${TEST_RESULTS}/go-vet.out 27 | 28 | - run: 29 | name: Run unit tests 30 | # Store the results of our tests in the $TEST_RESULTS directory 31 | command: | 32 | make test | tee ${TEST_RESULTS}/go-test.out 33 | 34 | - run: 35 | name: Build application 36 | command: | 37 | make release 38 | 39 | - save_cache: # Store cache in the /go/pkg directory 40 | key: go-mod-v1-{{ checksum "go.sum" }} 41 | paths: 42 | - "/go/pkg/mod" 43 | 44 | - store_artifacts: # Upload test summary for display in Artifacts 45 | path: /tmp/test-results 46 | destination: raw-test-output 47 | 48 | - store_test_results: # Upload test results for display in Test Summary 49 | path: /tmp/test-results 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | .idea 26 | *.iml 27 | bin 28 | out 29 | dist 30 | results 31 | vendor 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ErikL 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | GOPACKAGES = $(shell go list ./... | grep -v /vendor/) 2 | TEST_RESULTS=/tmp/test-results 3 | 4 | build: 5 | mkdir -p bin 6 | GO111MODULE=on go build -o bin/gotling cmd/gotling/main.go 7 | 8 | ci: 9 | GO111MODULE=on;go build cmd/gotling/main.go 10 | 11 | test: 12 | mkdir -p ${TEST_RESULTS} 13 | @go test -coverprofile=${TEST_RESULTS}/unittest.out -v $(GOPACKAGES) 14 | @go tool cover -html=${TEST_RESULTS}/unittest.out -o ${TEST_RESULTS}/unittest-coverage.html 15 | rm -f ${TEST_RESULTS}/unittest.out 16 | 17 | vet: 18 | go vet ./... 19 | 20 | fmt: 21 | go fmt ./... 22 | 23 | release: 24 | mkdir -p dist 25 | GO111MODULE=on GOOS=darwin go build -o dist/gotling-darwin-amd64 cmd/gotling/main.go 26 | GO111MODULE=on GOOS=linux go build -o dist/gotling-linux-amd64 cmd/gotling/main.go 27 | GO111MODULE=on GOOS=windows go build -o dist/gotling-windows-amd64 cmd/gotling/main.go -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gotling 2 | 3 | [](https://circleci.com/gh/eriklupander/gotling) 4 | 5 | Simple golang-based load test application using YAML documents as specification. 6 | 7 | For a more full-blown explanation of what Gotling is about, see my blog post here: http://callistaenterprise.se/blogg/teknik/2015/11/22/gotling/ 8 | 9 | ### Recent updates 10 | - UPDATE 2020-05-11: The `sleep` actions now also accepts golang `time.Duration` strings, i.e. `500ms` `2s` or `3m` etc. Any pure numbers specified are still treated as whole seconds. 11 | - UPDATE 2020-04-22: [Leon Stigter](https://github.com/retgits) added support for adding arbitrary HTTP headers 12 | - UPDATE 2020-04-08: [Leon Stigter](https://github.com/retgits) fixed the JSONPath problem 13 | - UPDATE 2019-04-04: I've updated gotling to use Go modules and changed the project structure to follow [https://github.com/golang-standards/project-layout](https://github.com/golang-standards/project-layout) better** 14 | 15 | ### Disclaimer 16 | Please note that this was my very first golang program back in 2015 and it's still (2020) probably full of anti-patterns and other nasty stuff. I'm not actively developing Gotling but I'll happily accept sensible PRs! 17 | 18 | ## What it does 19 | - Provides high-throughput load testing of HTTP services 20 | - Supports GET, POST, PUT and DELETE 21 | - Live metrics using HTML5 canvas from canvasjs 22 | - Request URLs and bodies can contain ${paramName} parameters 23 | - ${paramName} values can be extracted from HTTP response bodies and bound to a User context 24 | - Capturing Set-Cookie response headers 25 | - POST data can be inlined or read from template files 26 | - TCP/UDP sockets 27 | - Can send line-terminated text strings 28 | - Possible to use ${varname} variables in payload 29 | - Does not currently support body parsing or variable extraction from data incoming on the TCP/UDP socket. 30 | 31 | ## Building 32 | Requires Go 1.11 or later to be installed on your computer. 33 | 34 | ### NEW: Build using Go Modules 35 | 36 | As per 2019-04-03 gotling shall be built using Go modules and there's a Makefile to help out. 37 | 38 | #### 1. Clone the source from github 39 | 40 | git clone https://github.com/eriklupander/gotling.git 41 | 42 | #### 2. Build using Make 43 | 44 | cd gotling 45 | make build 46 | 47 | #### 3. Building for other OS's 48 | 49 | make release 50 | 51 | Check the dist/ folder for binaries for OS X, Linux and Window (AMD64) 52 | 53 | Note! You still need the samples, data and log folders in the same root directory as your gotling binary when running. 54 | 55 | #### 4. Running 56 | If you built gotling using _make build_, you'll find your binary in the bin/ folder. Try running the sample "xmldemo": 57 | 58 | > ./bin/gotling samples/xmldemo.yml 59 | 60 | ## Usage 61 | Define your test setup in a .yml file 62 | 63 | --- 64 | iterations: 10 # Number of iterations per user 65 | users: 10 # Number of users 66 | rampup: 20 # seconds 67 | actions: # List of actions. Currently supports http, tcp, udp, sleep 68 | - http: 69 | method: GET # GET, POST, PUT, DELETE 70 | url: http://localhost:8183/courses # URL. Can include ${paramName} parameters 71 | accept: json # Only 'json' is currently supported 72 | response: # Defines response handling 73 | jsonpath: $[*].id+ # JsonPath expression to capture data from JSON response 74 | variable: courseId # Parameter name for captured value 75 | index: first # If > 1 results found - which result to store in 'variable': 76 | # first, random, last 77 | - sleep: 78 | duration: 3 # Sleep duration in seconds. Will block current user 79 | - http: 80 | method: GET 81 | url: http://localhost:8183/courses/${courseId} 82 | accept: json 83 | response: 84 | jsonpath: $.author+ 85 | variable: author 86 | index: first 87 | - sleep: 88 | duration: 300ms # Note sleep using time.Duration format. 89 | - tcp: 90 | address: 127.0.0.1:8081 # TCP socket connection 91 | payload: |TYPE|1|${UID}|${email} # Sample data using parameter substitution 92 | 93 | ### HTTP headers 94 | Gotling supports adding HTTP headers in the YAML specification: 95 | 96 | - http: 97 | title: Some title 98 | method: POST 99 | headers: 100 | foo: bar 101 | hello: world 102 | url: http://localhost:9183/mypath 103 | body: '{"id":100,"name":"Some name","author":"${author}-${someId}","created":"2015-10-23T21:33:38.254+02:00","baseLatitude":45.634353,"baseLongitude":11.3424324}' 104 | accept: application/json 105 | 106 | To give this a try, create a [RequestBin URL](http://requestbin.net/) will collect requests made to it and let you inspect them in a human-friendly way and paste that URL in the [demoheaders.yml](./samples/demoheaders.yml) on line 9. 107 | 108 | ### HTTP POST bodies 109 | Gotling supports POST/PUT bodies either directly inlined in the YAML specification, or read from a template file: 110 | 111 | #### Inlined 112 | 113 | - http: 114 | title: Some title 115 | method: POST 116 | url: http://localhost:9183/mypath 117 | body: '{"id":100,"name":"Some name","author":"${author}-${someId}","created":"2015-10-23T21:33:38.254+02:00","baseLatitude":45.634353,"baseLongitude":11.3424324}' 118 | accept: application/json 119 | 120 | Note that we use _body_ in the inlined example 121 | 122 | #### From template 123 | 124 | - http: 125 | title: Submit query 126 | method: POST 127 | url: http://localhost:8080/myxmlservice 128 | template: myproject/MyFancySOAPRequest.xml 129 | accept: application/xml 130 | 131 | In this example, we use _template_ instead of _body_. The _myproject/_ folder should always be placed in the /templates directory in the root of the project. Note that ${varName} variable substitution from feeders (see below) or values captured from previous responses in the action sequence can be used in template files. 132 | 133 | ### Feeders and user context 134 | Gotling currently support CSV feeds of data. First line needs to be comma-separated headers with the following lines containing data, e.g: 135 | 136 | id,name,size 137 | 1,Bear,Large 138 | 2,Cat,Small 139 | 3,Deer,Medium 140 | 141 | These values can be accessed through ${varname} matching the column header. 142 | 143 | #### The UID 144 | Each "user" gets a unique "UID" assigned to it, typically an integer from 10000 + random(no of users). Perhaps I can tweak this to either use UUID's or configurable intervals. Anyway, the UID can be used using ${UID} and can be useful for grouping data etc. 145 | 146 | ### Capturing cookies 147 | It's quite common that you need to load-test a secured API. Gotling provides a mechanism that allows you to capture Set-Cookie response headers which then will be automatically applied to subsequent HTTP actions for the current user. 148 | 149 | Here is an example where a form-based login POST is used for logging in and storing the returned JSESSIONID cookie 150 | 151 | - http: 152 | title: Login 153 | method: POST 154 | url: https://some.host.name/login 155 | body: 'put your urlencoded form data here' 156 | accept: '*/*' 157 | contentType: application/x-www-form-urlencoded 158 | storeCookie: JSESSIONID 159 | 160 | 161 | ### Variable capture from HTTP response bodies 162 | It's possible to use jsonpath OR xmlpath to capture variables from HTTP responses (json or xml) and use in subsequent invocations during the ongoing sequence of actions. See ${courseId} in the sample above. 163 | 164 | A similar sample for xmlpath: 165 | 166 | - http: 167 | method: GET 168 | url: http://www.w3schools.com/xml/cd_catalog.xml 169 | accept: text/xml 170 | response: 171 | xmlpath: //title 172 | variable: myTitleVar 173 | index: random 174 | - http: 175 | method: GET 176 | url: http://some.other.service.maybe/authors/${myTitleVar} 177 | accept: json 178 | 179 | Please note that a response definition only may contain either a jsonpath OR an xmlpath. You can't have both. 180 | 181 | For more on xmlpath, see [xmlpath](https://godoc.org/gopkg.in/xmlpath.v2) 182 | 183 | ##### Important note: xmlpath for Go does not support xml namespaces! 184 | 185 | ### HTTPS support 186 | Gotling currently supports HTTPS, including hosts using self-signed certificates. 187 | 188 | In the future, we'll probably add an option to allow/disallow unsecure https. 189 | 190 | ## Realtime dashboard 191 | Access at http://localhost:8182 192 | 193 | Click "connect" to connect to the currently executing test. 194 | 195 |  196 | 197 | ## HTML reports 198 | Not functional right now :( 199 | 200 | ## Uses the following libraries 201 | - github.com/davecheney/profile 202 | - gopkg.in/yaml.v2 203 | - gopkg.in/xmlpath.v2 204 | - gorilla/websocket 205 | - highcharts 206 | 207 | ## License 208 | Licensed under the MIT license. 209 | 210 | See LICENSE 211 | -------------------------------------------------------------------------------- /cmd/gotling/main.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package main 25 | 26 | import ( 27 | "fmt" 28 | "github.com/eriklupander/gotling/internal/pkg/action" 29 | "github.com/eriklupander/gotling/internal/pkg/feeder" 30 | "github.com/eriklupander/gotling/internal/pkg/result" 31 | "github.com/eriklupander/gotling/internal/pkg/runtime" 32 | ws "github.com/eriklupander/gotling/internal/pkg/server" 33 | "github.com/eriklupander/gotling/internal/pkg/testdef" 34 | "gopkg.in/yaml.v2" 35 | "io/ioutil" 36 | "log" 37 | "os" 38 | "sync" 39 | "time" 40 | //"github.com/davecheney/profile" 41 | "math/rand" 42 | "strconv" 43 | ) 44 | 45 | func main() { 46 | 47 | spec := parseSpecFile() 48 | 49 | // defer profile.Start(profile.CPUProfile).Stop() 50 | 51 | // Start the web socket server, will not block exit until forced 52 | go ws.StartWsServer() 53 | 54 | runtime.SimulationStart = time.Now() 55 | dir, _ := os.Getwd() 56 | dat, _ := ioutil.ReadFile(dir + "/" + spec) 57 | 58 | var t testdef.TestDef 59 | err := yaml.Unmarshal([]byte(dat), &t) 60 | fail(err) 61 | 62 | if !testdef.ValidateTestDefinition(&t) { 63 | return 64 | } 65 | 66 | actions, isValid := action.BuildActionList(&t) 67 | if !isValid { 68 | return 69 | } 70 | 71 | if t.Feeder.Type == "csv" { 72 | feeder.Csv(t.Feeder.Filename, ",") 73 | } else if t.Feeder.Type != "" { 74 | log.Fatal("Unsupported feeder type: " + t.Feeder.Type) 75 | } 76 | 77 | result.OpenResultsFile(dir + "/results/log/latest.log") 78 | spawnUsers(&t, actions) 79 | 80 | fmt.Printf("Done in %v\n", time.Since(runtime.SimulationStart)) 81 | fmt.Println("Building reports, please wait...") 82 | result.CloseResultsFile() 83 | //buildReport() 84 | } 85 | 86 | func parseSpecFile() string { 87 | if len(os.Args) == 1 { 88 | fmt.Println("No command line arguments, exiting...") 89 | panic("Cannot start simulation, no YAML simulaton specification supplied as command-line argument") 90 | } 91 | var s, sep string 92 | for i := 1; i < len(os.Args); i++ { 93 | s += sep + os.Args[i] 94 | sep = " " 95 | } 96 | if s == "" { 97 | panic(fmt.Sprintf("Specified simulation file '%s' is not a .yml file", s)) 98 | } 99 | return s 100 | } 101 | 102 | func spawnUsers(t *testdef.TestDef, actions []action.Action) { 103 | resultsChannel := make(chan result.HttpReqResult, 10000) // buffer? 104 | go result.AcceptResults(resultsChannel) 105 | wg := sync.WaitGroup{} 106 | for i := 0; i < t.Users; i++ { 107 | wg.Add(1) 108 | UID := strconv.Itoa(rand.Intn(t.Users+1) + 10000) 109 | go launchActions(t, resultsChannel, &wg, actions, UID) 110 | var waitDuration float32 = float32(t.Rampup) / float32(t.Users) 111 | time.Sleep(time.Duration(int(1000*waitDuration)) * time.Millisecond) 112 | } 113 | fmt.Println("All users started, waiting at WaitGroup") 114 | wg.Wait() 115 | } 116 | 117 | func launchActions(t *testdef.TestDef, resultsChannel chan result.HttpReqResult, wg *sync.WaitGroup, actions []action.Action, UID string) { 118 | var sessionMap = make(map[string]string) 119 | 120 | for i := 0; i < t.Iterations; i++ { 121 | 122 | // Make sure the sessionMap is cleared before each iteration - except for the UID which stays 123 | cleanSessionMapAndResetUID(UID, sessionMap) 124 | 125 | // If we have feeder data, pop an item and push its key-value pairs into the sessionMap 126 | feedSession(t, sessionMap) 127 | 128 | // Iterate over the actions. Note the use of the command-pattern like Execute method on the Action interface 129 | for _, action := range actions { 130 | if action != nil { 131 | action.Execute(resultsChannel, sessionMap) 132 | } 133 | } 134 | } 135 | wg.Done() 136 | } 137 | 138 | func cleanSessionMapAndResetUID(UID string, sessionMap map[string]string) { 139 | // Optimization? Delete all entries rather than reallocate map from scratch for each new iteration. 140 | for k := range sessionMap { 141 | delete(sessionMap, k) 142 | } 143 | sessionMap["UID"] = UID 144 | } 145 | 146 | func feedSession(t *testdef.TestDef, sessionMap map[string]string) { 147 | if t.Feeder.Type != "" { 148 | go feeder.NextFromFeeder() // Do async 149 | feedData := <-feeder.FeedChannel // Will block here until feeder delivers value over the FeedChannel 150 | for item := range feedData { 151 | sessionMap[item] = feedData[item] 152 | } 153 | } 154 | } 155 | 156 | func fail(err error) { 157 | if err != nil { 158 | fmt.Printf("%v\n", err.Error()) 159 | os.Exit(1) 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /data/fleetdata.csv: -------------------------------------------------------------------------------- 1 | id,lat,lon,dp1,dp2,dp3,dp4,dp5 2 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 3 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 4 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 5 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 6 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 7 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 8 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 9 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 10 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 11 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 12 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 13 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 14 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 15 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 16 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 17 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 18 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 19 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 20 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 21 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 22 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 23 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 24 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 25 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 26 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 27 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 28 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 29 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 30 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 31 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 32 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 33 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 34 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 35 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 36 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 37 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 38 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 39 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 40 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 41 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 42 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 43 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 44 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 45 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 46 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 47 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 48 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 49 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 50 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 51 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 52 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 53 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 54 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 55 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 56 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 57 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 58 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 59 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 60 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 61 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 62 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 63 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 64 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 65 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 66 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 67 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 68 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 69 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 70 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 71 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 72 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 73 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 74 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 75 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 76 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 77 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 78 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 79 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 80 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 81 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 82 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 83 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 84 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 85 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 86 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 87 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 88 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 89 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 90 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 91 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 92 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 93 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 94 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 95 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 96 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 97 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 98 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 99 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 100 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 101 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 102 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 103 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 104 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 105 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 106 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 107 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 108 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 109 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 110 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 111 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 112 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 113 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 114 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 115 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 116 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 117 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 118 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 119 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 120 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 121 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 122 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 123 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 124 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 125 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 126 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 127 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 128 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 129 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 130 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 131 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 132 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 133 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 134 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 135 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 136 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 137 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 138 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 139 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 140 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 141 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 142 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 143 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 144 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 145 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 146 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 147 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 148 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 149 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 150 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 151 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 152 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 153 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 154 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 155 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 156 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 157 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 158 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 159 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 160 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 161 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 162 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 163 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 164 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 165 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 166 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 167 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 168 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 169 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 170 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 171 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 172 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 173 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 174 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 175 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 176 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 177 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 178 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 179 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 180 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 181 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 182 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 183 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 184 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 185 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 186 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 187 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 188 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 189 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 190 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 191 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 192 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 193 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 194 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 195 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 196 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 197 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 198 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 199 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 200 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 201 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 202 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 203 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 204 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 205 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 206 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 207 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 208 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 209 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 210 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 211 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 212 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 213 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 214 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 215 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 216 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 217 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 218 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 219 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 220 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 221 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 222 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 223 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 224 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 225 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 226 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 227 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 228 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 229 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 230 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 231 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 232 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 233 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 234 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 235 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 236 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 237 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 238 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 239 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 240 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 241 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 242 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 243 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 244 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 245 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 246 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 247 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 248 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 249 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 250 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 251 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 252 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 253 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 254 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 255 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 256 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 257 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 258 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 259 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 260 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 261 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 262 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 263 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 264 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 265 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 266 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 267 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 268 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 269 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 270 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 271 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 272 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 273 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 274 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 275 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 276 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 277 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 278 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 279 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 280 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 281 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 282 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 283 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 284 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 285 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 286 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 287 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 288 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 289 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 290 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 291 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 292 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 293 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 294 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 295 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 296 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 297 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 298 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 299 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 300 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 301 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 302 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 303 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 304 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 305 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 306 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 307 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 308 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 309 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 310 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 311 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 312 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 313 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 314 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 315 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 316 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 317 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 318 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 319 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 320 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 321 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 322 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 323 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 324 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 325 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 326 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 327 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 328 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 329 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 330 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 331 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 332 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 333 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 334 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 335 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 336 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 337 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 338 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 339 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 340 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 341 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 342 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 343 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 344 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 345 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 346 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 347 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 348 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 349 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 350 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 351 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 352 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 353 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 354 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 355 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 356 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 357 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 358 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 359 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 360 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 361 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 362 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 363 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 364 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 365 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 366 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 367 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 368 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 369 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 370 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 371 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 372 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 373 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 374 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 375 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 376 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 377 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 378 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 379 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 380 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 381 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 382 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 383 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 384 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 385 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 386 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 387 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 388 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 389 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 390 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 391 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 392 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 393 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 394 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 395 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 396 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 397 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 398 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 399 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 400 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 401 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 402 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 403 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 404 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 405 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 406 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 407 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 408 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 409 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 410 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 411 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 412 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 413 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 414 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 415 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 416 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 417 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 418 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 419 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 420 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 421 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 422 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 423 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 424 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 425 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 426 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 427 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 428 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 429 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 430 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 431 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 432 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 433 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 434 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 435 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 436 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 437 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 438 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 439 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 440 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 441 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 442 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 443 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 444 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 445 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 446 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 447 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 448 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 449 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 450 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 451 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 452 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 453 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 454 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 455 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 456 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 457 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 458 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 459 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 460 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 461 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 462 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 463 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 464 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 465 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 466 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 467 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 468 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 469 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 470 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 471 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 472 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 473 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 474 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 475 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 476 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 477 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 478 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 479 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 480 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 481 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 482 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 483 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 484 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 485 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 486 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 487 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 488 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 489 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 490 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 491 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 492 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 493 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 494 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 495 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 496 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 497 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 498 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 499 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 500 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 501 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 502 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 503 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 504 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 505 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 506 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 507 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 508 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 509 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 510 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 511 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 512 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 513 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 514 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 515 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 516 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 517 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 518 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 519 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 520 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 521 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 522 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 523 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 524 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 525 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 526 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 527 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 528 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 529 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 530 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 531 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 532 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 533 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 534 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 535 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 536 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 537 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 538 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 539 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 540 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 541 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 542 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 543 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 544 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 545 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 546 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 547 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 548 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 549 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 550 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 551 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 552 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 553 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 554 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 555 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 556 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 557 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 558 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 559 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 560 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 561 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 562 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 563 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 564 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 565 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 566 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 567 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 568 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 569 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 570 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 571 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 572 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 573 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 574 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 575 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 576 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 577 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 578 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 579 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 580 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 581 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 582 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 583 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 584 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 585 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 586 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 587 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 588 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 589 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 590 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 591 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 592 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 593 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 594 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 595 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 596 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 597 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 598 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 599 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 600 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 601 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 602 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 603 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 604 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 605 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 606 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 607 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 608 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 609 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 610 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 611 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 612 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 613 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 614 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 615 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 616 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 617 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 618 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 619 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 620 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 621 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 622 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 623 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 624 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 625 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 626 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 627 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 628 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 629 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 630 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 631 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 632 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 633 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 634 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 635 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 636 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 637 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 638 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 639 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 640 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 641 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 642 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 643 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 644 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 645 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 646 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 647 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 648 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 649 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 650 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 651 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 652 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 653 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 654 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 655 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 656 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 657 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 658 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 659 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 660 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 661 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 662 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 663 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 664 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 665 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 666 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 667 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 668 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 669 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 670 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 671 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 672 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 673 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 674 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 675 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 676 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 677 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 678 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 679 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 680 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 681 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 682 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 683 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 684 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 685 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 686 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 687 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 688 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 689 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 690 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 691 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 692 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 693 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 694 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 695 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 696 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 697 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 698 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 699 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 700 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 701 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 702 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 703 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 704 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 705 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 706 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 707 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 708 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 709 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 710 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 711 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 712 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 713 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 714 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 715 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 716 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 717 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 718 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 719 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 720 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 721 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 722 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 723 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 724 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 725 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 726 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 727 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 728 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 729 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 730 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 731 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 732 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 733 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 734 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 735 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 736 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 737 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 738 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 739 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 740 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 741 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 742 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 743 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 744 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 745 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 746 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 747 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 748 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 749 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 750 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 751 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 752 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 753 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 754 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 755 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 756 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 757 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 758 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 759 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 760 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 761 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 762 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 763 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 764 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 765 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 766 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 767 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 768 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 769 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 770 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 771 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 772 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 773 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 774 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 775 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 776 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 777 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 778 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 779 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 780 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 781 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 782 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 783 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 784 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 785 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 786 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 787 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 788 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 789 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 790 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 791 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 792 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 793 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 794 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 795 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 796 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 797 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 798 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 799 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 800 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 801 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 802 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 803 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 804 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 805 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 806 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 807 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 808 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 809 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 810 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 811 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 812 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 813 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 814 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 815 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 816 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 817 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 818 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 819 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 820 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 821 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 822 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 823 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 824 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 825 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 826 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 827 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 828 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 829 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 830 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 831 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 832 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 833 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 834 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 835 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 836 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 837 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 838 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 839 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 840 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 841 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 842 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 843 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 844 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 845 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 846 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 847 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 848 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 849 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 850 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 851 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 852 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 853 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 854 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 855 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 856 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 857 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 858 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 859 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 860 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 861 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 862 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 863 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 864 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 865 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 866 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 867 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 868 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 869 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 870 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 871 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 872 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 873 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 874 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 875 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 876 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 877 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 878 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 879 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 880 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 881 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 882 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 883 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 884 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 885 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 886 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 887 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 888 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 889 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 890 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 891 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 892 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 893 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 894 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 895 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 896 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 897 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 898 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 899 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 900 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 901 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 902 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 903 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 904 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 905 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 906 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 907 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 908 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 909 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 910 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 911 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 912 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 913 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 914 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 915 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 916 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 917 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 918 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 919 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 920 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 921 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 922 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 923 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 924 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 925 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 926 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 927 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 928 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 929 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 930 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 931 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 932 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 933 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 934 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 935 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 936 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 937 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 938 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 939 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 940 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 941 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 942 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 943 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 944 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 945 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 946 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 947 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 948 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 949 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 950 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 951 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 952 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 953 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 954 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 955 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 956 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 957 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 958 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 959 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 960 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 961 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 962 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 963 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 964 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 965 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 966 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 967 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 968 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 969 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 970 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 971 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 972 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 973 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 974 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 975 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 976 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 977 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 978 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 979 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 980 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 981 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 982 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 983 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 984 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 985 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 986 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 987 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 988 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 989 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 990 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 991 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 992 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 993 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 994 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 995 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 996 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 997 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 998 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 999 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1000 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1001 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1002 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1003 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1004 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1005 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1006 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1007 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1008 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1009 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1010 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1011 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1012 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1013 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1014 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1015 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1016 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1017 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1018 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1019 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1020 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1021 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1022 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1023 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1024 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1025 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1026 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1027 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1028 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1029 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1030 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1031 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1032 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1033 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1034 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1035 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1036 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1037 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1038 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1039 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1040 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1041 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1042 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1043 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1044 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1045 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1046 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1047 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1048 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1049 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1050 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1051 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1052 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1053 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1054 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1055 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1056 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1057 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1058 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1059 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1060 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1061 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1062 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1063 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1064 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1065 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1066 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1067 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1068 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1069 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1070 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1071 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1072 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1073 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1074 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1075 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1076 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1077 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1078 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1079 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1080 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1081 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1082 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1083 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1084 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1085 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1086 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1087 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1088 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1089 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1090 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1091 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1092 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1093 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1094 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1095 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1096 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1097 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1098 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1099 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1100 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1101 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1102 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1103 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1104 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 1105 | 10001,54.454535,11.543534,3213.5454,123,0.0000343,44,43455.434 -------------------------------------------------------------------------------- /data/testdata.csv: -------------------------------------------------------------------------------- 1 | personNr,namn,telefon 2 | 19000101-9801,Erik1 Eriksson1,031-131311 3 | 19000102-9818,Erik2 Eriksson2,031-131312 4 | 19000103-9809,Erik3 Eriksson3,031-131313 5 | 19000104-9816,Erik4 Eriksson4,031-131314 -------------------------------------------------------------------------------- /docs/gotling-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eriklupander/gotling/24222d238fd89509a1506ad0a115a71b2f6050f2/docs/gotling-console.png -------------------------------------------------------------------------------- /docs/gotling-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eriklupander/gotling/24222d238fd89509a1506ad0a115a71b2f6050f2/docs/gotling-dashboard.png -------------------------------------------------------------------------------- /docs/gotling-dashboard1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eriklupander/gotling/24222d238fd89509a1506ad0a115a71b2f6050f2/docs/gotling-dashboard1.png -------------------------------------------------------------------------------- /docs/gotling-dashboard2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eriklupander/gotling/24222d238fd89509a1506ad0a115a71b2f6050f2/docs/gotling-dashboard2.png -------------------------------------------------------------------------------- /docs/gotling-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eriklupander/gotling/24222d238fd89509a1506ad0a115a71b2f6050f2/docs/gotling-overview.png -------------------------------------------------------------------------------- /docs/gotling-report1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eriklupander/gotling/24222d238fd89509a1506ad0a115a71b2f6050f2/docs/gotling-report1.png -------------------------------------------------------------------------------- /docs/gotling-seq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eriklupander/gotling/24222d238fd89509a1506ad0a115a71b2f6050f2/docs/gotling-seq.png -------------------------------------------------------------------------------- /docs/gotling-seq.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | Alice -> Bob: Authentication Request 3 | Bob --> Alice: Authentication Response 4 | 5 | Alice -> Bob: Another authentication Request 6 | Alice <-- Bob: another authentication Response 7 | @enduml -------------------------------------------------------------------------------- /docs/xd-setup.md: -------------------------------------------------------------------------------- 1 | # Setting up Spring XD as load target 2 | 3 | To test a pure "write" scenario when developing a Gotling test, Spring XD can be utilized to provide HTTP and TCP endpoints in a convenient way. 4 | 5 | ### XD distributed mode setup 6 | Running XD in distributed mode needs a number of subsystems to work properly, this is how to set them up: 7 | 8 | #### ZooKeeper 9 | To start the server (on Mac OS X or Linux. Windows, don't know): 10 | bin/zkServer.sh start-foreground ../spring-xd-1.2.1.RELEASE/zookeeper/conf/zoo.cfg. 11 | 12 | #### Redis 13 | Spring XD ships with the Redis source code and can be compiled or downloaded- 14 | - Go to the redis/bin subdirectory under the Spring XD install path and run _install-redis_ script to build 15 | - From the root path of the Redis install, start by executing _../bin/redis-server redis.conf_ 16 | 17 | #### HSQLDB 18 | Change to the hsqldb path in the Spring XD install dir and start HSQLDB by running bin/hsqldb-server 19 | 20 | #### SPRING XD 21 | (1) Change the transport from Rabbit to Redis by uncommenting and modifying the xd.transport parameter as shown: 22 | 23 | #XD data transport (default is redis for distributed, local for single node) 24 | xd: 25 | transport: redis 26 | 27 | (2) Configure the HSQLDB connection parameters, in this case the included default values will suffice - it is necessary to just uncomment the parameters. 28 | 29 | 30 | #Change the database host, port and name 31 | hsql: 32 | server: 33 | host: localhost 34 | port: 9101 35 | dbname: xdjob 36 | #Change database username and password 37 | spring: 38 | datasource: 39 | url: jdbc:hsqldb:hsql://${hsql.server.host:localhost}:${hsql.server.port:9101}/${hsql.server.dbname:xdjob} 40 | username: sa 41 | password: 42 | driverClassName: org.hsqldb.jdbc.JDBCDriver 43 | validationQuery: select 1 from INFORMATION_SCHEMA.SYSTEM_USERS 44 | (3) Let's also enable the ability to shut down containers from the Admin UI. Follow the instructions in the configuration file, and uncomment the parameters. 45 | 46 | #--- 47 | spring: 48 | profiles: container 49 | management: 50 | port: 0 51 | (4) Setup the Redis connection parameters, using the default host and port. 52 | 53 | spring: 54 | redis: 55 | port: 6379 56 | host: localhost 57 | (5) Finally, setup the ZooKeeper connection properties. 58 | 59 | # namespace is the path under the root where XD's top level nodes will be created 60 | # client connect string: host1:port1,host2:port2,...,hostN:portN 61 | zk: 62 | namespace: xd 63 | client: 64 | connect: localhost:2181 65 | 66 | 67 | ### Starting Spring XD 68 | - Open a new shell, and start the Admin server by executing the spring-xd-1.2.1.RELEASE/xd/bin/xd-admin shell script. 69 | - Start up a container in another shell by executing spring-xd-1.2.1.RELEASE/xd/bin/xd-container. 70 | - Start a XD shell by: spring-xd-1.2.1.RELEASE/shell/bin> ./xd-shell 71 | 72 | 73 | ### Creating some streams and taps 74 | TCP listener 75 | 76 | stream create --name tcptest --definition "tcp --port=8081 --outputType=text/plain | log" --deploy 77 | HTTP listener 78 | 79 | stream create --name httptest --definition "http --port=10000 | log" --deploy 80 | TCP tap/counter 81 | 82 | stream create --name tcptap --definition "tap:stream:tcptest > counter --name=tcpcount" --deploy 83 | HTTP tap/counter 84 | 85 | stream create --name httptap --definition "tap:stream:httptest > counter --name=httpcount" --deploy 86 | 87 | 88 | ### Access Web GUI 89 | http://localhost:9393/admin-ui 90 | 91 | Remember that counters only becomes available in the GUI once some data have passed into them. 92 | 93 | 94 | ### Sample use-case: Fleet data 95 | 96 | OpenStreetMap API's can be used to generate polyline or .gpx files for a road-following route: 97 | Example, Gothenburg to Trollhättan 98 | 99 | http://router.project-osrm.org/viaroute?loc=57.703033,12.000526&loc=57.166582,12.529290&instructions=false&alt=false&output=gpx 100 | 101 | See https://github.com/Project-OSRM/osrm-backend/wiki/Server-api 102 | 103 | See also: http://mathematica.stackexchange.com/questions/11521/using-j-link-to-decode-google-maps-polyline-strings 104 | 105 | The .gpx file is probably the easiest to transform into a feeder. To provide a good simulation, we'll probably need to generate a few hundred or so routes with random "start point" along the route. 106 | I think the feeder format needs to be something like: 107 | 108 | route1,route2,route3,...,routeN 109 | 57.10|12.30,57.90|12.70,58.30|11.40,... 110 | 57.11|12.31,57.91|12.71,58.31|11.41,... 111 | 57.12|12.32,57.92|12.72,58.32|11.42,... 112 | 113 | I.e. each route goes into a column of its own. This won't quite work unless all routes are normalized to the same number of coords but that can probably be arranged. 114 | 115 | So - first generate a number of routes using the OSM API (beware of their usage terms, no spamming!) and save as .gpx files. Then put those into a folder or something and build a matrix we can transform into the appropriate csv format. 116 | 117 | Another option is to allow "namespaced" feeders. E.g. one user gets exclusive right to _one_ csv resource. Each CSV resource is namespaced by its file name and then bound to a user and its values accessed through $${varname} or something denoting them from "global" feeders. -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/eriklupander/gotling 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/gorilla/websocket v0.0.0-20160217174351-4935ba31a2ad 7 | github.com/kr/pretty v0.1.0 // indirect 8 | github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 9 | github.com/stretchr/testify v1.5.1 10 | golang.org/x/net v0.0.0-20190403144856-b630fd6fe46b // indirect 11 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect 12 | gopkg.in/xmlpath.v2 v2.0.0-20150820204837-860cbeca3ebc 13 | gopkg.in/yaml.v2 v2.2.2 14 | ) 15 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/gorilla/websocket v0.0.0-20160217174351-4935ba31a2ad h1:VMjKMEwHVdi4qE7T4DjJfLdMn4/k/JIQmEb+zAz58Ec= 4 | github.com/gorilla/websocket v0.0.0-20160217174351-4935ba31a2ad/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= 5 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 6 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 7 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 8 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 9 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 10 | github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI= 11 | github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= 12 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 13 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 14 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 15 | github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= 16 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 17 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 18 | golang.org/x/net v0.0.0-20190403144856-b630fd6fe46b h1:/zjbcJPEGAyu6Is/VBOALsgdi4z9+kz/Vtdm6S+beD0= 19 | golang.org/x/net v0.0.0-20190403144856-b630fd6fe46b/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 20 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 21 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 22 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 23 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 24 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 25 | gopkg.in/xmlpath.v2 v2.0.0-20150820204837-860cbeca3ebc h1:LMEBgNcZUqXaP7evD1PZcL6EcDVa2QOFuI+cqM3+AJM= 26 | gopkg.in/xmlpath.v2 v2.0.0-20150820204837-860cbeca3ebc/go.mod h1:N8UOSI6/c2yOpa/XDz3KVUiegocTziPiqNkeNTMiG1k= 27 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 28 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 29 | -------------------------------------------------------------------------------- /internal/pkg/action/action.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package action 25 | 26 | import "github.com/eriklupander/gotling/internal/pkg/result" 27 | 28 | type Action interface { 29 | Execute(resultsChannel chan result.HttpReqResult, sessionMap map[string]string) 30 | } 31 | -------------------------------------------------------------------------------- /internal/pkg/action/actionbuilder.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package action 25 | 26 | import ( 27 | "io/ioutil" 28 | "log" 29 | "os" 30 | 31 | "github.com/eriklupander/gotling/internal/pkg/testdef" 32 | ) 33 | 34 | func BuildActionList(t *testdef.TestDef) ([]Action, bool) { 35 | var valid bool = true 36 | actions := make([]Action, len(t.Actions), len(t.Actions)) 37 | for _, element := range t.Actions { 38 | for key, value := range element { 39 | var action Action 40 | actionMap := value.(map[interface{}]interface{}) 41 | switch key { 42 | case "sleep": 43 | action = NewSleepAction(actionMap) 44 | break 45 | case "http": 46 | action = NewHttpAction(actionMap) 47 | break 48 | case "tcp": 49 | action = NewTcpAction(actionMap) 50 | case "udp": 51 | action = NewUdpAction(actionMap) 52 | break 53 | default: 54 | valid = false 55 | log.Fatal("Unknown action type encountered: " + key) 56 | break 57 | } 58 | if valid { 59 | actions = append(actions, action) 60 | } 61 | } 62 | } 63 | return actions, valid 64 | } 65 | 66 | func getBody(action map[interface{}]interface{}) string { 67 | //var body string = "" 68 | if action["body"] != nil { 69 | return action["body"].(string) 70 | } else { 71 | return "" 72 | } 73 | } 74 | 75 | func getTemplate(action map[interface{}]interface{}) string { 76 | if action["template"] != nil { 77 | var templateFile = action["template"].(string) 78 | dir, _ := os.Getwd() 79 | templateData, _ := ioutil.ReadFile(dir + "/templates/" + templateFile) 80 | return string(templateData) 81 | } else { 82 | return "" 83 | } 84 | } 85 | 86 | func getHeaders(action map[interface{}]interface{}) map[string]string { 87 | headers := make(map[string]string) 88 | if action["headers"] != nil { 89 | hm := action["headers"].(map[interface{}]interface{}) 90 | for key, value := range hm { 91 | headers[key.(string)] = value.(string) 92 | } 93 | } 94 | return headers 95 | } 96 | -------------------------------------------------------------------------------- /internal/pkg/action/httpaction.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package action 25 | 26 | import ( 27 | "log" 28 | 29 | "github.com/eriklupander/gotling/internal/pkg/result" 30 | ) 31 | 32 | type HttpAction struct { 33 | Method string `yaml:"method"` 34 | Url string `yaml:"url"` 35 | Body string `yaml:"body"` 36 | Template string `yaml:"template"` 37 | Accept string `yaml:"accept"` 38 | ContentType string `yaml:"contentType"` 39 | Title string `yaml:"title"` 40 | ResponseHandler HttpResponseHandler `yaml:"response"` 41 | StoreCookie string `yaml:"storeCookie"` 42 | Headers map[string]string `yaml:"headers"` 43 | } 44 | 45 | func (h HttpAction) Execute(resultsChannel chan result.HttpReqResult, sessionMap map[string]string) { 46 | DoHttpRequest(h, resultsChannel, sessionMap) 47 | } 48 | 49 | type HttpResponseHandler struct { 50 | Jsonpath string `yaml:"jsonpath"` 51 | Xmlpath string `yaml:"xmlpath"` 52 | Variable string `yaml:"variable"` 53 | Index string `yaml:"index"` 54 | } 55 | 56 | func NewHttpAction(a map[interface{}]interface{}) HttpAction { 57 | valid := true 58 | if a["url"] == "" || a["url"] == nil { 59 | log.Println("Error: HttpAction must define a URL.") 60 | valid = false 61 | } 62 | if a["method"] == nil || (a["method"] != "GET" && a["method"] != "POST" && a["method"] != "PUT" && a["method"] != "DELETE") { 63 | log.Println("Error: HttpAction must specify a HTTP method: GET, POST, PUT or DELETE") 64 | valid = false 65 | } 66 | if a["title"] == nil || a["title"] == "" { 67 | log.Println("Error: HttpAction must define a title.") 68 | valid = false 69 | } 70 | 71 | if a["body"] != nil && a["template"] != nil { 72 | log.Println("Error: A HttpAction can not define both a 'body' and a 'template'.") 73 | valid = false 74 | } 75 | 76 | if a["response"] != nil { 77 | r := a["response"].(map[interface{}]interface{}) 78 | if r["index"] == nil || r["index"] == "" || (r["index"] != "first" && r["index"] != "last" && r["index"] != "random") { 79 | log.Println("Error: HttpAction ResponseHandler must define an Index of either of: first, last or random.") 80 | valid = false 81 | } 82 | if (r["jsonpath"] == nil || r["jsonpath"] == "") && (r["xmlpath"] == nil || r["xmlpath"] == "") { 83 | log.Println("Error: HttpAction ResponseHandler must define a Jsonpath or a Xmlpath.") 84 | valid = false 85 | } 86 | if (r["jsonpath"] != nil && r["jsonpath"] != "") && (r["xmlpath"] != nil && r["xmlpath"] != "") { 87 | log.Println("Error: HttpAction ResponseHandler can only define either a Jsonpath OR a Xmlpath.") 88 | valid = false 89 | } 90 | 91 | // TODO perhaps compile Xmlpath expressions so we can validate early? 92 | 93 | if r["variable"] == nil || r["variable"] == "" { 94 | log.Println("Error: HttpAction ResponseHandler must define a Variable.") 95 | valid = false 96 | } 97 | } 98 | 99 | if !valid { 100 | log.Fatalf("Your YAML defintion contains an invalid HttpAction, see errors listed above.") 101 | } 102 | var responseHandler HttpResponseHandler 103 | if a["response"] != nil { 104 | response := a["response"].(map[interface{}]interface{}) 105 | 106 | if response["jsonpath"] != nil && response["jsonpath"] != "" { 107 | responseHandler.Jsonpath = response["jsonpath"].(string) 108 | } 109 | if response["xmlpath"] != nil && response["xmlpath"] != "" { 110 | responseHandler.Xmlpath = response["xmlpath"].(string) 111 | } 112 | 113 | responseHandler.Variable = response["variable"].(string) 114 | responseHandler.Index = response["index"].(string) 115 | } 116 | 117 | accept := "text/html,application/json,application/xhtml+xml,application/xml,text/plain" 118 | if a["accept"] != nil && len(a["accept"].(string)) > 0 { 119 | accept = a["accept"].(string) 120 | } 121 | 122 | var contentType string 123 | if a["contentType"] != nil && len(a["contentType"].(string)) > 0 { 124 | contentType = a["contentType"].(string) 125 | } 126 | 127 | var storeCookie string 128 | if a["storeCookie"] != nil && a["storeCookie"].(string) != "" { 129 | storeCookie = a["storeCookie"].(string) 130 | } 131 | 132 | httpAction := HttpAction{ 133 | a["method"].(string), 134 | a["url"].(string), 135 | getBody(a), 136 | getTemplate(a), 137 | accept, 138 | contentType, 139 | a["title"].(string), 140 | responseHandler, 141 | storeCookie, 142 | getHeaders(a), 143 | } 144 | 145 | return httpAction 146 | } 147 | -------------------------------------------------------------------------------- /internal/pkg/action/httpreq.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package action 25 | 26 | import ( 27 | "bytes" 28 | "crypto/tls" 29 | "encoding/json" 30 | "fmt" 31 | "io/ioutil" 32 | "log" 33 | "math/rand" 34 | "net/http" 35 | "reflect" 36 | "strings" 37 | "time" 38 | 39 | "github.com/eriklupander/gotling/internal/pkg/result" 40 | "github.com/eriklupander/gotling/internal/pkg/runtime" 41 | "github.com/eriklupander/gotling/internal/pkg/testdef" 42 | "github.com/eriklupander/gotling/internal/pkg/util" 43 | "github.com/oliveagle/jsonpath" 44 | "gopkg.in/xmlpath.v2" 45 | ) 46 | 47 | // Accepts a Httpaction and a one-way channel to write the results to. 48 | func DoHttpRequest(httpAction HttpAction, resultsChannel chan result.HttpReqResult, sessionMap map[string]string) { 49 | req := buildHttpRequest(httpAction, sessionMap) 50 | 51 | start := time.Now() 52 | var DefaultTransport http.RoundTripper = &http.Transport{ 53 | TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 54 | } 55 | resp, err := DefaultTransport.RoundTrip(req) 56 | 57 | if err != nil { 58 | log.Printf("HTTP request failed: %s", err) 59 | } else { 60 | elapsed := time.Since(start) 61 | responseBody, err := ioutil.ReadAll(resp.Body) 62 | if err != nil { 63 | //log.Fatal(err) 64 | log.Printf("Reading HTTP response failed: %s\n", err) 65 | httpReqResult := buildHttpResult(0, resp.StatusCode, elapsed.Nanoseconds(), httpAction.Title) 66 | 67 | resultsChannel <- httpReqResult 68 | } else { 69 | defer resp.Body.Close() 70 | 71 | if httpAction.StoreCookie != "" { 72 | for _, cookie := range resp.Cookies() { 73 | 74 | if cookie.Name == httpAction.StoreCookie { 75 | sessionMap["____"+cookie.Name] = cookie.Value 76 | } 77 | } 78 | } 79 | 80 | // if action specifies response action, parse using regexp/jsonpath 81 | processResult(httpAction, sessionMap, responseBody) 82 | 83 | httpReqResult := buildHttpResult(len(responseBody), resp.StatusCode, elapsed.Nanoseconds(), httpAction.Title) 84 | 85 | resultsChannel <- httpReqResult 86 | } 87 | } 88 | } 89 | 90 | func buildHttpResult(contentLength int, status int, elapsed int64, title string) result.HttpReqResult { 91 | httpReqResult := result.HttpReqResult{ 92 | Type: "HTTP", 93 | Latency: elapsed, 94 | Size: contentLength, 95 | Status: status, 96 | Title: title, 97 | When: time.Since(runtime.SimulationStart).Nanoseconds(), 98 | } 99 | return httpReqResult 100 | } 101 | 102 | func buildHttpRequest(httpAction HttpAction, sessionMap map[string]string) *http.Request { 103 | var req *http.Request 104 | var err error 105 | if httpAction.Body != "" { 106 | reader := strings.NewReader(util.SubstParams(sessionMap, httpAction.Body)) 107 | req, err = http.NewRequest(httpAction.Method, util.SubstParams(sessionMap, httpAction.Url), reader) 108 | } else if httpAction.Template != "" { 109 | reader := strings.NewReader(util.SubstParams(sessionMap, httpAction.Template)) 110 | req, err = http.NewRequest(httpAction.Method, util.SubstParams(sessionMap, httpAction.Url), reader) 111 | } else { 112 | req, err = http.NewRequest(httpAction.Method, util.SubstParams(sessionMap, httpAction.Url), nil) 113 | } 114 | if err != nil { 115 | log.Fatal(err) 116 | } 117 | 118 | // Add headers 119 | req.Header.Add("Accept", httpAction.Accept) 120 | if httpAction.ContentType != "" { 121 | req.Header.Add("Content-Type", httpAction.ContentType) 122 | } 123 | 124 | for key, value := range httpAction.Headers { 125 | req.Header.Add(key, value) 126 | } 127 | 128 | if hostHeader, found := httpAction.Headers["host"]; found { 129 | req.Host = hostHeader 130 | } 131 | 132 | if hostHeader, found := httpAction.Headers["Host"]; found { 133 | req.Host = hostHeader 134 | } 135 | 136 | // Add cookies stored by subsequent requests in the sessionMap having the kludgy ____ prefix 137 | for key, value := range sessionMap { 138 | if strings.HasPrefix(key, "____") { 139 | 140 | cookie := http.Cookie{ 141 | Name: key[4:], 142 | Value: value, 143 | } 144 | 145 | req.AddCookie(&cookie) 146 | } 147 | } 148 | 149 | return req 150 | } 151 | 152 | /** 153 | * If the httpAction specifies a Jsonpath in the Response, try to extract value(s) 154 | * from the responseBody. 155 | * 156 | * TODO extract both Jsonpath handling and Xmlpath handling into separate functions, and write tests for them. 157 | */ 158 | func processResult(httpAction HttpAction, sessionMap map[string]string, responseBody []byte) { 159 | if httpAction.ResponseHandler.Jsonpath != "" { 160 | jsonPattern, err := jsonpath.Compile(httpAction.ResponseHandler.Jsonpath) 161 | if err != nil { 162 | log.Fatal(err) 163 | } 164 | 165 | var jsonData interface{} 166 | json.Unmarshal(responseBody, &jsonData) 167 | 168 | res, err := jsonPattern.Lookup(jsonData) 169 | if err != nil { 170 | log.Fatal(err) 171 | } 172 | 173 | var resultArray []string 174 | v := reflect.ValueOf(res) 175 | switch v.Kind() { 176 | case reflect.String: 177 | resultArray = []string{res.(string)} 178 | case reflect.Slice: 179 | a := res.([]interface{}) 180 | resultArray = make([]string, len(a)) 181 | for idx, val := range a { 182 | resultArray[idx] = fmt.Sprintf("%s", val) 183 | } 184 | default: 185 | log.Printf("Unknown type [%T]", reflect.TypeOf(res)) 186 | } 187 | passResultIntoSessionMap(resultArray, httpAction, sessionMap) 188 | } 189 | 190 | if httpAction.ResponseHandler.Xmlpath != "" { 191 | path := xmlpath.MustCompile(httpAction.ResponseHandler.Xmlpath) 192 | r := bytes.NewReader(responseBody) 193 | root, err := xmlpath.Parse(r) 194 | 195 | if err != nil { 196 | log.Fatal(err) 197 | } 198 | 199 | iterator := path.Iter(root) 200 | hasNext := iterator.Next() 201 | if hasNext { 202 | resultsArray := make([]string, 0, 10) 203 | for { 204 | if hasNext { 205 | node := iterator.Node() 206 | resultsArray = append(resultsArray, node.String()) 207 | hasNext = iterator.Next() 208 | } else { 209 | break 210 | } 211 | } 212 | passResultIntoSessionMap(resultsArray, httpAction, sessionMap) 213 | } 214 | } 215 | 216 | // log.Println(string(responseBody)) 217 | } 218 | 219 | /** 220 | * Trims leading and trailing byte r from string s 221 | */ 222 | func trimChar(s string, r byte) string { 223 | sz := len(s) 224 | 225 | if sz > 0 && s[sz-1] == r { 226 | s = s[:sz-1] 227 | } 228 | sz = len(s) 229 | if sz > 0 && s[0] == r { 230 | s = s[1:sz] 231 | } 232 | return s 233 | } 234 | 235 | func passResultIntoSessionMap(resultsArray []string, httpAction HttpAction, sessionMap map[string]string) { 236 | resultCount := len(resultsArray) 237 | 238 | if resultCount > 0 { 239 | switch httpAction.ResponseHandler.Index { 240 | case testdef.FIRST: 241 | sessionMap[httpAction.ResponseHandler.Variable] = resultsArray[0] 242 | break 243 | case testdef.LAST: 244 | sessionMap[httpAction.ResponseHandler.Variable] = resultsArray[resultCount-1] 245 | break 246 | case testdef.RANDOM: 247 | if resultCount > 1 { 248 | rand.Seed(time.Now().UnixNano()) 249 | sessionMap[httpAction.ResponseHandler.Variable] = resultsArray[rand.Intn(resultCount-1)] 250 | } else { 251 | sessionMap[httpAction.ResponseHandler.Variable] = resultsArray[0] 252 | } 253 | break 254 | } 255 | 256 | } else { 257 | // TODO how to handle requested, but missing result? 258 | } 259 | } 260 | -------------------------------------------------------------------------------- /internal/pkg/action/sleepaction.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package action 25 | 26 | import ( 27 | "fmt" 28 | "github.com/eriklupander/gotling/internal/pkg/result" 29 | "time" 30 | ) 31 | 32 | type SleepAction struct { 33 | Duration time.Duration `yaml:"duration"` 34 | } 35 | 36 | func (s SleepAction) Execute(resultsChannel chan result.HttpReqResult, sessionMap map[string]string) { 37 | time.Sleep(s.Duration) 38 | } 39 | 40 | func NewSleepAction(a map[interface{}]interface{}) SleepAction { 41 | switch val := a["duration"].(type) { 42 | case int: 43 | return SleepAction{Duration: time.Second * time.Duration(val)} 44 | case string: 45 | dur, err := time.ParseDuration(val) 46 | if err != nil { 47 | fmt.Printf("Error trying to parse duration '%v' from string representation into Go duration format. Error: %v\n", val, err.Error()) 48 | panic(err.Error()) 49 | } 50 | return SleepAction{Duration:dur} 51 | case time.Duration: 52 | return SleepAction{Duration: val} 53 | default: 54 | fmt.Printf("unsupported Sleep value type. Supported is int or string (golang time.Duration), was %T\n", val) 55 | panic("unsupported sleep value") 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /internal/pkg/action/sleepaction_test.go: -------------------------------------------------------------------------------- 1 | package action 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestSleepAction_ExecuteWithDurationFormat(t *testing.T) { 10 | action := NewSleepAction(map[interface{}]interface{}{"duration":"100ms"}) 11 | start := time.Now() 12 | action.Execute(nil, nil) 13 | assert.Greater(t, time.Since(start).Milliseconds(), int64(99)) 14 | } 15 | 16 | func TestSleepAction_ExecuteWithIntegerFormat(t *testing.T) { 17 | action := NewSleepAction(map[interface{}]interface{}{"duration":1}) 18 | start := time.Now() 19 | action.Execute(nil, nil) 20 | assert.Greater(t, time.Since(start).Milliseconds(), int64(999)) 21 | } -------------------------------------------------------------------------------- /internal/pkg/action/tcpaction.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package action 25 | 26 | import "github.com/eriklupander/gotling/internal/pkg/result" 27 | 28 | type TcpAction struct { 29 | Address string `yaml:"address"` 30 | Payload string `yaml:"payload"` 31 | Title string `yaml:"title"` 32 | } 33 | 34 | func (t TcpAction) Execute(resultsChannel chan result.HttpReqResult, sessionMap map[string]string) { 35 | DoTcpRequest(t, resultsChannel, sessionMap) 36 | } 37 | 38 | func NewTcpAction(a map[interface{}]interface{}) TcpAction { 39 | 40 | // TODO validation 41 | return TcpAction{ 42 | a["address"].(string), 43 | a["payload"].(string), 44 | a["title"].(string), 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /internal/pkg/action/tcpreq.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package action 25 | 26 | import ( 27 | "fmt" 28 | "github.com/eriklupander/gotling/internal/pkg/result" 29 | "github.com/eriklupander/gotling/internal/pkg/runtime" 30 | "github.com/eriklupander/gotling/internal/pkg/util" 31 | "net" 32 | "time" 33 | ) 34 | 35 | var conn net.Conn 36 | 37 | // Accepts a TcpAction and a one-way channel to write the results to. 38 | func DoTcpRequest(tcpAction TcpAction, resultsChannel chan result.HttpReqResult, sessionMap map[string]string) { 39 | 40 | address := util.SubstParams(sessionMap, tcpAction.Address) 41 | payload := util.SubstParams(sessionMap, tcpAction.Payload) 42 | 43 | if conn == nil { 44 | var err error 45 | conn, err = net.Dial("tcp", address) 46 | if err != nil { 47 | fmt.Printf("TCP socket closed, error: %s\n", err) 48 | conn = nil 49 | return 50 | } 51 | // conn.SetDeadline(time.Now().Add(100 * time.Millisecond)) 52 | } 53 | 54 | start := time.Now() 55 | 56 | _, err := fmt.Fprintf(conn, payload+"\r\n") 57 | if err != nil { 58 | fmt.Printf("TCP request failed with error: %s\n", err) 59 | conn = nil 60 | } 61 | 62 | elapsed := time.Since(start) 63 | resultsChannel <- buildTcpResult(0, 200, elapsed.Nanoseconds(), tcpAction.Title) 64 | 65 | } 66 | 67 | func buildTcpResult(contentLength int, status int, elapsed int64, title string) result.HttpReqResult { 68 | httpReqResult := result.HttpReqResult{ 69 | Type: "TCP", 70 | Latency: elapsed, 71 | Size: contentLength, 72 | Status: status, 73 | Title: title, 74 | When: time.Since(runtime.SimulationStart).Nanoseconds(), 75 | } 76 | return httpReqResult 77 | } 78 | -------------------------------------------------------------------------------- /internal/pkg/action/udpaction.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package action 25 | 26 | import ( 27 | "github.com/eriklupander/gotling/internal/pkg/result" 28 | ) 29 | 30 | type UdpAction struct { 31 | Address string `yaml:"address"` 32 | Payload string `yaml:"payload"` 33 | Title string `yaml:"title"` 34 | } 35 | 36 | func (t UdpAction) Execute(resultsChannel chan result.HttpReqResult, sessionMap map[string]string) { 37 | DoUdpRequest(t, resultsChannel, sessionMap) 38 | } 39 | 40 | func NewUdpAction(a map[interface{}]interface{}) UdpAction { 41 | payload, ok := a["payload"].(string) 42 | if !ok { 43 | return UdpAction{} 44 | } 45 | address, ok := a["address"].(string) 46 | if !ok { 47 | return UdpAction{} 48 | } 49 | title, ok := a["title"].(string) 50 | if !ok { 51 | return UdpAction{} 52 | } 53 | return UdpAction{ 54 | address, 55 | payload, 56 | title, 57 | } 58 | } 59 | 60 | /* 61 | 62 | */ 63 | -------------------------------------------------------------------------------- /internal/pkg/action/udpreq.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package action 25 | 26 | import ( 27 | "fmt" 28 | "github.com/eriklupander/gotling/internal/pkg/result" 29 | "github.com/eriklupander/gotling/internal/pkg/runtime" 30 | "github.com/eriklupander/gotling/internal/pkg/util" 31 | "net" 32 | "time" 33 | ) 34 | 35 | var udpconn *net.UDPConn 36 | 37 | // Accepts a UdpAction and a one-way channel to write the results to. 38 | func DoUdpRequest(udpAction UdpAction, resultsChannel chan result.HttpReqResult, sessionMap map[string]string) { 39 | 40 | address := util.SubstParams(sessionMap, udpAction.Address) 41 | payload := util.SubstParams(sessionMap, udpAction.Payload) 42 | 43 | if udpconn == nil { 44 | ServerAddr, err := net.ResolveUDPAddr("udp", address) //"127.0.0.1:10001") 45 | if err != nil { 46 | fmt.Println("Error ResolveUDPAddr remote: " + err.Error()) 47 | } 48 | 49 | LocalAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") 50 | if err != nil { 51 | fmt.Println("Error ResolveUDPAddr local: " + err.Error()) 52 | } 53 | 54 | udpconn, err = net.DialUDP("udp", LocalAddr, ServerAddr) 55 | if err != nil { 56 | fmt.Println("Error Dial: " + err.Error()) 57 | } 58 | } 59 | //defer Conn.Close() 60 | start := time.Now() 61 | 62 | if udpconn != nil { 63 | _, err := fmt.Fprintf(udpconn, payload+"\r\n") 64 | if err != nil { 65 | fmt.Printf("UDP request failed with error: %s\n", err) 66 | udpconn = nil 67 | } 68 | } 69 | 70 | elapsed := time.Since(start) 71 | resultsChannel <- buildUdpResult(0, 200, elapsed.Nanoseconds(), udpAction.Title) 72 | 73 | } 74 | 75 | func buildUdpResult(contentLength int, status int, elapsed int64, title string) result.HttpReqResult { 76 | httpReqResult := result.HttpReqResult{ 77 | Type: "UDP", 78 | Latency: elapsed, 79 | Size: contentLength, 80 | Status: status, 81 | Title: title, 82 | When: time.Since(runtime.SimulationStart).Nanoseconds(), 83 | } 84 | return httpReqResult 85 | } 86 | -------------------------------------------------------------------------------- /internal/pkg/feeder/feeder.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package feeder 25 | 26 | import ( 27 | "bufio" 28 | "fmt" 29 | "log" 30 | "os" 31 | "strings" 32 | "sync" 33 | ) 34 | 35 | var data []map[string]string 36 | var index = 0 37 | 38 | var l sync.Mutex 39 | 40 | // "public" synchronized channel for delivering feeder data 41 | var FeedChannel chan map[string]string 42 | 43 | // 44 | func NextFromFeeder() { 45 | 46 | if data != nil && len(data) > 0 { 47 | 48 | // Push data into the FeedChannel 49 | // fmt.Printf("Current index: %d of total size: %d\n", index, len(data)) 50 | FeedChannel <- data[index] 51 | 52 | // Cycle, does this need to be synchronized? 53 | l.Lock() 54 | if index < len(data)-1 { 55 | index += 1 56 | } else { 57 | index = 0 58 | } 59 | l.Unlock() 60 | } 61 | 62 | } 63 | 64 | func Csv(filename string, separator string) { 65 | dir, _ := os.Getwd() 66 | file, _ := os.Open(dir + "/data/" + filename) 67 | 68 | scanner := bufio.NewScanner(file) 69 | var lines int = 0 70 | 71 | data = make([]map[string]string, 0, 0) 72 | 73 | // Scan the first line, should contain headers. 74 | scanner.Scan() 75 | headers := strings.Split(scanner.Text(), separator) 76 | 77 | for scanner.Scan() { 78 | line := strings.Split(scanner.Text(), separator) 79 | item := make(map[string]string) 80 | for n := 0; n < len(headers); n++ { 81 | item[headers[n]] = line[n] 82 | } 83 | data = append(data, item) 84 | lines += 1 85 | } 86 | 87 | if err := scanner.Err(); err != nil { 88 | log.Fatal(err) 89 | } 90 | index = 0 91 | fmt.Printf("CSV feeder fed with %d lines of data\n", lines) 92 | FeedChannel = make(chan map[string]string) 93 | } 94 | -------------------------------------------------------------------------------- /internal/pkg/result/httpreqresult.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package result 25 | 26 | type HttpReqResult struct { 27 | Type string 28 | Latency int64 29 | Size int 30 | Status int 31 | Title string 32 | When int64 33 | } 34 | -------------------------------------------------------------------------------- /internal/pkg/result/httpresulthandler.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package result 25 | 26 | import ( 27 | "encoding/json" 28 | "fmt" 29 | "github.com/eriklupander/gotling/internal/pkg/runtime" 30 | "github.com/eriklupander/gotling/internal/pkg/server" 31 | "time" 32 | ) 33 | 34 | /** 35 | * Loops indefinitely. The inner loop runs for exactly one second before submitting its 36 | * results to the WebSocket handler, then the aggregates are reset and restarted. 37 | */ 38 | func aggregatePerSecondHandler(perSecondChannel chan *HttpReqResult) { 39 | 40 | for { 41 | 42 | totalReq := 0 43 | totalLatency := 0 44 | until := time.Now().UnixNano() + 1000000000 45 | for time.Now().UnixNano() < until { 46 | select { 47 | case msg := <-perSecondChannel: 48 | totalReq++ 49 | totalLatency += int(msg.Latency / 1000) // measure in microseconds 50 | default: 51 | // Can be trouble. Uses too much CPU if low, limits throughput if too high 52 | time.Sleep(100 * time.Microsecond) 53 | } 54 | } 55 | // concurrently assemble the result and send it off to the websocket. 56 | go assembleAndSendResult(totalReq, totalLatency) 57 | } 58 | 59 | } 60 | 61 | func assembleAndSendResult(totalReq int, totalLatency int) { 62 | avgLatency := 0 63 | if totalReq > 0 { 64 | avgLatency = totalLatency / totalReq 65 | } 66 | statFrame := StatFrame{ 67 | time.Since(runtime.SimulationStart).Nanoseconds() / 1000000000, // seconds 68 | avgLatency, // microseconds 69 | totalReq, 70 | } 71 | fmt.Printf("Time: %d Avg latency: %d μs (%d ms) req/s: %d\n", statFrame.Time, statFrame.Latency, statFrame.Latency/1000, statFrame.Reqs) 72 | 73 | serializedFrame, _ := json.Marshal(statFrame) 74 | server.BroadcastStatFrame(serializedFrame) 75 | } 76 | 77 | /** 78 | * Starts the per second aggregator and then forwards any HttpRequestResult messages to it through the channel. 79 | */ 80 | func AcceptResults(resChannel chan HttpReqResult) { 81 | perSecondAggregatorChannel := make(chan *HttpReqResult, 5) 82 | go aggregatePerSecondHandler(perSecondAggregatorChannel) 83 | for { 84 | select { 85 | case msg := <-resChannel: 86 | perSecondAggregatorChannel <- &msg 87 | writeResult(&msg) // sync write result to file for later processing. 88 | break 89 | case <-time.After(100 * time.Microsecond): 90 | break 91 | // default: 92 | // // This is troublesome. If too high, throughput is bad. Too low, CPU use goes up too much 93 | // // Using a sync channel kills performance 94 | // time.Sleep(100 * time.Microsecond) 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /internal/pkg/result/resultwriter.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package result 25 | 26 | import ( 27 | "bufio" 28 | "encoding/json" 29 | "os" 30 | ) 31 | 32 | var w *bufio.Writer 33 | var f *os.File 34 | var err error 35 | 36 | var opened bool = false 37 | 38 | func OpenResultsFile(fileName string) { 39 | if !opened { 40 | opened = true 41 | } else { 42 | return 43 | } 44 | f, err = os.Create(fileName) 45 | if err != nil { 46 | os.Mkdir("results", 0777) 47 | os.Mkdir("results/log", 0777) 48 | f, err = os.Create(fileName) 49 | if err != nil { 50 | panic(err) 51 | } 52 | } 53 | w = bufio.NewWriter(f) 54 | _, err = w.WriteString(string("var logdata = '")) 55 | } 56 | 57 | func CloseResultsFile() { 58 | if opened { 59 | _, err = w.WriteString(string("';")) 60 | w.Flush() 61 | f.Close() 62 | } 63 | // Do nothing if not opened 64 | } 65 | 66 | func writeResult(httpResult *HttpReqResult) { 67 | jsonString, err := json.Marshal(httpResult) 68 | if err != nil { 69 | panic(err) 70 | } 71 | _, err = w.WriteString(string(jsonString)) 72 | _, err = w.WriteString("|") 73 | 74 | if err != nil { 75 | panic(err) 76 | } 77 | w.Flush() 78 | 79 | } 80 | -------------------------------------------------------------------------------- /internal/pkg/result/statframe.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package result 25 | 26 | type StatFrame struct { 27 | Time int64 `json:"time"` 28 | Latency int `json:"latency"` 29 | Reqs int `json:"reqs"` 30 | } 31 | -------------------------------------------------------------------------------- /internal/pkg/result/tcpreqresult.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package result 25 | 26 | type TcpReqResult struct { 27 | Type string 28 | Latency int64 29 | Size int 30 | Status int 31 | Title string 32 | When int64 33 | } 34 | -------------------------------------------------------------------------------- /internal/pkg/runtime/globals.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | import "time" 4 | 5 | var SimulationStart time.Time 6 | -------------------------------------------------------------------------------- /internal/pkg/server/wsserver.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package server 25 | 26 | import ( 27 | // "time" 28 | "fmt" 29 | // "math/rand" 30 | "flag" 31 | "github.com/gorilla/websocket" 32 | "log" 33 | "net/http" 34 | ) 35 | 36 | var addr = flag.String("addr", "localhost:8182", "http service address") 37 | 38 | var upgrader = websocket.Upgrader{} // use default options 39 | 40 | func Remove(item int) { 41 | connectionRegistry = append(connectionRegistry[:item], connectionRegistry[item+1:]...) 42 | } 43 | 44 | func BroadcastStatFrame(statFrame []byte) { 45 | for index, wsConn := range connectionRegistry { 46 | err := wsConn.WriteMessage(1, statFrame) 47 | if err != nil { 48 | 49 | // Detected disconnected channel. Need to clean up. 50 | fmt.Printf("Could not write to channel: %v", err) 51 | wsConn.Close() 52 | Remove(index) 53 | } 54 | } 55 | } 56 | 57 | var connectionRegistry = make([]*websocket.Conn, 0, 10) 58 | 59 | func registerChannel(w http.ResponseWriter, r *http.Request) { 60 | if r.URL.Path != "/start" { 61 | http.Error(w, "Not found", 404) 62 | return 63 | } 64 | if r.Method != "GET" { 65 | http.Error(w, "Method not allowed", 405) 66 | return 67 | } 68 | c, err := upgrader.Upgrade(w, r, nil) 69 | if err != nil { 70 | log.Print("upgrade:", err) 71 | return 72 | } 73 | connectionRegistry = append(connectionRegistry, c) 74 | 75 | } 76 | 77 | func StartWsServer() { 78 | fmt.Println("Starting WebSocket server") 79 | flag.Parse() 80 | log.SetFlags(0) 81 | 82 | http.HandleFunc("/start", registerChannel) 83 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 84 | http.ServeFile(w, r, "static/"+r.URL.Path[1:]) 85 | }) 86 | err := http.ListenAndServe(*addr, nil) 87 | if err != nil { 88 | panic("ListenAndServe: " + err.Error()) 89 | } 90 | fmt.Println("Started WebSocket server") 91 | } 92 | -------------------------------------------------------------------------------- /internal/pkg/testdef/testdef_validator.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package testdef 25 | 26 | import ( 27 | "log" 28 | ) 29 | 30 | // TODO refactor this so it runs before parsing the actions 31 | 32 | func ValidateTestDefinition(t *TestDef) bool { 33 | var valid = true 34 | if t.Iterations == 0 { 35 | log.Println("Iterations not set, must be > 0") 36 | valid = false 37 | } 38 | if t.Rampup < 0 { 39 | log.Println("Rampup not defined. must be > -1") 40 | valid = false 41 | } 42 | if t.Users == 0 { 43 | log.Println("Users must be > 0") 44 | valid = false 45 | } 46 | return valid 47 | } 48 | -------------------------------------------------------------------------------- /internal/pkg/testdef/testdefinition.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package testdef 25 | 26 | const FIRST = "first" 27 | const LAST = "last" 28 | const RANDOM = "random" 29 | 30 | type TestDef struct { 31 | Iterations int `yaml:"iterations"` 32 | Users int `yaml:"users"` 33 | Rampup int `yaml:"rampup"` 34 | Feeder Feeder `yaml:"feeder"` 35 | Actions []map[string]interface{} `yaml:"actions"` 36 | } 37 | 38 | type Feeder struct { 39 | Type string `yaml:"type"` 40 | Filename string `yaml:"filename"` 41 | } 42 | -------------------------------------------------------------------------------- /internal/pkg/util/variableprocessor.go: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2015 ErikL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | package util 25 | 26 | import ( 27 | "net/url" 28 | "regexp" 29 | "strings" 30 | ) 31 | 32 | var re = regexp.MustCompile("\\$\\{([a-zA-Z0-9]{0,})\\}") 33 | 34 | func SubstParams(sessionMap map[string]string, textData string) string { 35 | if strings.ContainsAny(textData, "${") { 36 | res := re.FindAllStringSubmatch(textData, -1) 37 | for _, v := range res { 38 | textData = strings.Replace(textData, "${"+v[1]+"}", url.QueryEscape(sessionMap[v[1]]), 1) 39 | } 40 | return textData 41 | } else { 42 | return textData 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples/demoheaders.yml: -------------------------------------------------------------------------------- 1 | --- 2 | iterations: 3 3 | users: 2 4 | rampup: 3 5 | actions: 6 | - http: 7 | title: Post to RequestBin 8 | method: POST 9 | url: http://requestbin.net/r/189w13m1 10 | headers: 11 | hello: world 12 | foo: bar 13 | accept: json 14 | - sleep: 15 | duration: 3 -------------------------------------------------------------------------------- /samples/demosimulation.yml: -------------------------------------------------------------------------------- 1 | --- 2 | iterations: 10 3 | users: 1 4 | rampup: 0 5 | actions: 6 | - sleep: 7 | duration: 333ms 8 | - http: 9 | title: Read google.com 10 | method: GET 11 | url: https://www.google.com 12 | accept: json -------------------------------------------------------------------------------- /samples/invalid.yml: -------------------------------------------------------------------------------- 1 | --- 2 | iterations: 1 3 | users: 1 4 | rampup: 0 5 | feeder: 6 | type: csv #csv, json 7 | filename: testdata.csv 8 | actions: 9 | - sleep: 10 | duration: 1 11 | - http: 12 | title: Get all courses 13 | method: GET 14 | url: http://localhost:9183/courses 15 | accept: json 16 | response: 17 | jsonpath: $[*].id+ 18 | variable: courseId 19 | index: random # first, random, last 20 | - sleep: 21 | duration: 3 22 | - http: 23 | title: Get course 24 | method: GET 25 | url: http://localhost:9183/courses/${courseId} 26 | accept: json 27 | response: 28 | jsonpath: $.author+ 29 | variable: author 30 | index: first # first, random, last 31 | - sleep: 32 | duration: 3 -------------------------------------------------------------------------------- /samples/ltest00.yml: -------------------------------------------------------------------------------- 1 | --- 2 | iterations: 8 3 | users: 2000 4 | rampup: 20 5 | actions: 6 | - http: 7 | title: Get all courses 8 | method: GET 9 | url: http://localhost:9183/courses 10 | accept: json 11 | response: 12 | jsonpath: $[*].id+ 13 | variable: courseId 14 | index: random # first, random, last 15 | - sleep: 16 | duration: 3 17 | - http: 18 | title: Get course 19 | method: GET 20 | url: http://localhost:9183/courses/${courseId} 21 | accept: json 22 | - sleep: 23 | duration: 3 24 | -------------------------------------------------------------------------------- /samples/ltest01.yml: -------------------------------------------------------------------------------- 1 | --- ### Loadtest 1 2 | iterations: 20 3 | users: 20 4 | rampup: 10 5 | actions: 6 | - type: http 7 | method: GET 8 | url: http://127.0.0.1:8080/courses 9 | accept: json # optional 10 | response: 11 | find: '"id":[0-9],' 12 | var: courseId 13 | index: random # first, random, last 14 | - type: sleep 15 | duration: 3 16 | - type: http 17 | method: GET 18 | url: http://127.0.0.1:8080/courses/${courseId} 19 | accept: json # optional 20 | - type: sleep 21 | duration: 3 22 | 23 | - tcp: 24 | address: 127.0.0.1:8081 25 | payload: ACT|LOGIN|${personNr}|${namn}\n 26 | outputs: 27 | - type: websocket 28 | url: http://127.0.0.1:9090/dashboard 29 | - type: html 30 | - type: console -------------------------------------------------------------------------------- /samples/spring-xd-demo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | iterations: 500 3 | users: 2000 4 | rampup: 60 5 | feeder: 6 | type: csv #csv, json 7 | filename: fleetdata.csv 8 | actions: 9 | - sleep: 10 | duration: 1 11 | - http: 12 | title: Submit data 13 | method: POST 14 | url: http://localhost:10000 15 | accept: json 16 | body: '{"vehicleid":${UID},"lat":${lat},"lon":${lon}}' 17 | - sleep: 18 | duration: 1 19 | - tcp: 20 | title: TCP packet 21 | address: 127.0.0.1:8181 22 | payload: ${UID}|${dp1}|${dp2}|${dp3}|${dp4}|${dp5} 23 | -------------------------------------------------------------------------------- /samples/withpost.yml: -------------------------------------------------------------------------------- 1 | --- 2 | iterations: 5 3 | users: 1000 4 | rampup: 30 5 | actions: 6 | - http: 7 | method: GET 8 | url: http://localhost:9183/courses 9 | accept: json 10 | response: 11 | jsonpath: $[*].id+ 12 | variable: courseId 13 | index: first # first, random, last 14 | - sleep: 15 | duration: 3 16 | - http: 17 | method: GET 18 | url: http://localhost:9183/courses/${courseId} 19 | accept: json 20 | response: 21 | jsonpath: $.author+ 22 | variable: author 23 | index: first # first, random, last 24 | - sleep: 25 | duration: 3 26 | - http: 27 | method: POST 28 | url: http://localhost:9183/courses 29 | body: '{"id":100,"name":"Fjällbacka","author":"${author}-${courseId}","created":"2015-10-23T21:33:38.254+02:00","baseLatitude":45.634353,"baseLongitude":11.3424324,"holes":[]}' 30 | accept: json 31 | - sleep: 32 | duration: 2 -------------------------------------------------------------------------------- /samples/xmldemo-invalid.yml: -------------------------------------------------------------------------------- 1 | --- 2 | iterations: 1 3 | users: 1 4 | rampup: 3 5 | actions: 6 | - http: 7 | title: Read sample XML file 8 | method: GET 9 | url: http://www.w3schools.com/xml/cd_catalog.xml 10 | accept: text/xml 11 | response: 12 | xmlpath: ///TITLE 13 | jsonpath: $[*].id+ 14 | variable: noteTo 15 | index: random # first, random, last 16 | - sleep: 17 | duration: 3 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/xmldemo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | iterations: 1 3 | users: 1 4 | rampup: 3 5 | actions: 6 | - http: 7 | title: Read sample XML file 8 | method: GET 9 | url: http://www.w3schools.com/xml/cd_catalog.xml 10 | accept: text/xml 11 | response: 12 | xmlpath: ///TITLE 13 | variable: noteTo 14 | index: random # first, random, last 15 | - sleep: 16 | duration: 3 17 | 18 | 19 | -------------------------------------------------------------------------------- /static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |