Skip to content

Commit

Permalink
Merge pull request #99 from ddosify/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
kursataktas authored Dec 15, 2022
2 parents 1fd3ba5 + d81780e commit d515b9d
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 18 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ name: Coverage

on:
push:
branches: [ master ]
branches:
- master
- develop
pull_request:
branches: [ master ]
branches:
- master
- develop

jobs:

Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@ name: Test

on:
push:
branches: [ master ]
branches:
- master
- develop
pull_request:
branches: [ master ]
branches:
- master
- develop

jobs:

test:
strategy:
matrix:
go-version: [1.17.x, 1.18.x]
go-version: [1.18.x, 1.19.x]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ curl -sSfL https://raw.githubusercontent.com/ddosify/ddosify/master/scripts/inst

### Go install from source (macOS, FreeBSD, Linux, Windows)

*Minimum supported Go version is 1.18*

```bash
go install -v go.ddosify.com/ddosify@latest
```
Expand Down
5 changes: 2 additions & 3 deletions config_examples/config.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// This file contains full features of Ddosify as a reference. Don't use it directly.
{
"request_count": 20, // This field will be deprecated, please use iteration_count instead.
"request_count": 30, // This field will be deprecated, please use iteration_count instead.
"iteration_count": 30,
"request_count": 20, // this field will be deprecated, use iteration_count
"debug" : "false, // use this field for debugging, see verbose result
"debug" : false, // use this field for debugging, see verbose result
"load_type": "linear",
"duration": 5,
"manual_load": [
Expand Down
7 changes: 4 additions & 3 deletions core/report/stdout.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package report
import (
"encoding/json"
"fmt"
"io"
"net/http"
"sort"
"strings"
Expand Down Expand Up @@ -183,14 +184,14 @@ func (s *stdout) printInDebugMode(input chan *types.ScenarioResult) {
}
}

func printBody(w *tabwriter.Writer, contentType string, body interface{}) {
func printBody(w io.Writer, contentType string, body interface{}) {
if strings.Contains(contentType, "application/json") {
valPretty, _ := json.MarshalIndent(body, "", " ")
fmt.Fprintf(w, "%s\n", valPretty)
fmt.Fprintf(w, "%s", valPretty)
} else {
// html unescaped text
// if xml came as decoded, we could pretty print it like json
fmt.Fprintf(w, "%s\n", body.(string))
fmt.Fprintf(w, "%s", body.(string))
}
}

Expand Down
18 changes: 11 additions & 7 deletions core/report/stdoutJson.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,9 @@ var strKeyToJsonKey = map[string]string{
func (v verboseHttpRequestInfo) MarshalJSON() ([]byte, error) {
if v.Error != "" {
type alias struct {
StepId uint16 `json:"stepId"`
Request struct {
StepId uint16 `json:"stepId"`
StepName string `json:"stepName"`
Request struct {
Url string `json:"url"`
Method string `json:"method"`
Headers map[string]string `json:"headers"`
Expand All @@ -171,16 +172,18 @@ func (v verboseHttpRequestInfo) MarshalJSON() ([]byte, error) {
}

a := alias{
Request: v.Request,
Error: v.Error,
StepId: v.StepId,
Request: v.Request,
Error: v.Error,
StepId: v.StepId,
StepName: v.StepName,
}
return json.Marshal(a)
}

type alias struct {
StepId uint16 `json:"stepId"`
Request struct {
StepId uint16 `json:"stepId"`
StepName string `json:"stepName"`
Request struct {
Url string `json:"url"`
Method string `json:"method"`
Headers map[string]string `json:"headers"`
Expand All @@ -195,6 +198,7 @@ func (v verboseHttpRequestInfo) MarshalJSON() ([]byte, error) {

a := alias{
StepId: v.StepId,
StepName: v.StepName,
Request: v.Request,
Response: v.Response,
}
Expand Down
65 changes: 65 additions & 0 deletions core/report/stdoutJson_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,3 +294,68 @@ func TestStdoutJsonDebugModePrintsValidJson(t *testing.T) {
<-testDoneChan

}

func TestVerboseHttpInfoMarshallingErrorCase(t *testing.T) {
errorStr := "there is error"
vError := verboseHttpRequestInfo{
StepId: 0,
StepName: "",
Request: struct {
Url string "json:\"url\""
Method string "json:\"method\""
Headers map[string]string "json:\"headers\""
Body interface{} "json:\"body\""
}{},
Error: errorStr,
}

bytesWithErrorAndNoResponse, _ := vError.MarshalJSON()

var aliasStruct map[string]interface{}
json.Unmarshal(bytesWithErrorAndNoResponse, &aliasStruct)

val, errExists := aliasStruct["error"]
_, respExists := aliasStruct["response"]

if !errExists {
t.Errorf("Verbose Http Info should have error key")
} else if val != errorStr {
t.Errorf("Verbose Http Info should have error value as : %s, found: %s", errorStr, val)
} else if respExists {
t.Errorf("Verbose Http Info should not have response in case of error")
}
}

func TestVerboseHttpInfoMarshallingSuccessCase(t *testing.T) {
noErrorStr := ""
vSuccess := verboseHttpRequestInfo{
StepId: 0,
StepName: "",
Request: struct {
Url string "json:\"url\""
Method string "json:\"method\""
Headers map[string]string "json:\"headers\""
Body interface{} "json:\"body\""
}{},
Response: struct {
StatusCode int "json:\"statusCode\""
Headers map[string]string "json:\"headers\""
Body interface{} "json:\"body\""
}{},
Error: noErrorStr,
}

bytesWithResponseAndNoError, _ := vSuccess.MarshalJSON()

var aliasStruct map[string]interface{}
json.Unmarshal(bytesWithResponseAndNoError, &aliasStruct)

_, errExists := aliasStruct["error"]
_, respExists := aliasStruct["response"]

if errExists {
t.Errorf("Verbose Http Info should not have error key in success case")
} else if !respExists {
t.Errorf("Verbose Http Info should have response in success case")
}
}
107 changes: 107 additions & 0 deletions core/report/stdout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@
package report

import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"os"
"reflect"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -219,3 +225,104 @@ func TestStart(t *testing.T) {
t.Errorf("2Expected %#v, Found %#v", expectedResult, *s.result)
}
}

func TestPrintJsonBody(t *testing.T) {
var byteArr []byte
buffer := bytes.NewBuffer(byteArr)

contentTypeJson := "application/json"
body := map[string]interface{}{"x": "y"}
printBody(buffer, contentTypeJson, body)

printedBody := buffer.Bytes()

if !json.Valid(printedBody) {
t.Errorf("Printed body is not valid json: %v", string(printedBody))
}
}

func TestPrintBodyAsString(t *testing.T) {
var byteArr []byte
buffer := bytes.NewBuffer(byteArr)

contentTypeAny := "any"
body := "argentina"
printBody(buffer, contentTypeAny, body)

printedBody := buffer.Bytes()

if string(printedBody) != body {
t.Errorf("Printed body does not match expected: %s, found: %v", body, string(printedBody))
}
}

func TestStdoutPrintsHeadlinesInDebugMode(t *testing.T) {
s := &stdout{}
s.Init(true)
testDoneChan := make(chan struct{}, 1)

// listen to output
realOut := out
r, w, _ := os.Pipe()
out = w
defer func() {
out = realOut
}()

inputChan := make(chan *types.ScenarioResult, 1)
inputChan <- &types.ScenarioResult{
StepResults: []*types.ScenarioStepResult{
{
StepID: 0,
StepName: "",
RequestID: [16]byte{},
StatusCode: 0,
RequestTime: time.Time{},
Duration: 0,
ContentLength: 0,
Err: types.RequestError{},
DebugInfo: map[string]interface{}{
"requestBody": []byte{},
"requestHeaders": http.Header{},
"url": "",
"method": "",
"responseBody": []byte{},
"responseHeaders": http.Header{},
},
Custom: map[string]interface{}{},
},
},
}
close(inputChan)

go func() {
s.Start(inputChan)
w.Close()
}()

go func() {
// wait for print and debug
<-s.DoneChan()

printedOutput, err := ioutil.ReadAll(r)
t.Log(err)
t.Log(printedOutput)

outStr := string(printedOutput)
if !strings.Contains(outStr, "REQUEST") ||
!strings.Contains(outStr, "Request Headers:") ||
!strings.Contains(outStr, "Request Body:") ||
!strings.Contains(outStr, "RESPONSE") ||
!strings.Contains(outStr, "StatusCode:") ||
!strings.Contains(outStr, "Response Headers:") ||
!strings.Contains(outStr, "Response Body:") {

t.Errorf("One or multiple headlines are missing in stdout debug mode")
}

testDoneChan <- struct{}{}
}()

<-testDoneChan

}

0 comments on commit d515b9d

Please sign in to comment.