mirror of
https://github.com/mariocandela/beelzebub.git
synced 2025-07-01 18:47:26 -04:00
Refactoring, improve code coverage (#72)
* Refactoring, improve code coverage * Add unit test for gelAllFilesNameByDirName * Add codecov coverage into README.md * Improve coverage readFileBytesByFilePath
This commit is contained in:
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
[](https://github.com/mariocandela/beelzebub/actions/workflows/ci.yml) [](https://github.com/mariocandela/beelzebub/actions/workflows/docker-image.yml) [](https://github.com/mariocandela/beelzebub/actions/workflows/codeql.yml)
|
[](https://github.com/mariocandela/beelzebub/actions/workflows/ci.yml) [](https://github.com/mariocandela/beelzebub/actions/workflows/docker-image.yml) [](https://github.com/mariocandela/beelzebub/actions/workflows/codeql.yml)
|
||||||
[](https://goreportcard.com/report/github.com/mariocandela/beelzebub)
|
[](https://goreportcard.com/report/github.com/mariocandela/beelzebub)
|
||||||
|
[](https://codecov.io/gh/mariocandela/beelzebub)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@ -91,7 +92,9 @@ $ make test.unit
|
|||||||
To run integration tests:
|
To run integration tests:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
$ make test.dependencies.start
|
||||||
$ make test.integration
|
$ make test.integration
|
||||||
|
$ make test.dependencies.down
|
||||||
```
|
```
|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
|
@ -2,7 +2,6 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -127,7 +126,7 @@ func (bp configurationsParser) ReadConfigurationsServices() ([]BeelzebubServiceC
|
|||||||
}
|
}
|
||||||
|
|
||||||
func gelAllFilesNameByDirName(dirName string) ([]string, error) {
|
func gelAllFilesNameByDirName(dirName string) ([]string, error) {
|
||||||
files, err := ioutil.ReadDir(dirName)
|
files, err := os.ReadDir(dirName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -118,3 +119,54 @@ func TestReadConfigurationsServicesValid(t *testing.T) {
|
|||||||
assert.Equal(t, len(firstBeelzebubServiceConfiguration.Commands[0].Headers), 1)
|
assert.Equal(t, len(firstBeelzebubServiceConfiguration.Commands[0].Headers), 1)
|
||||||
assert.Equal(t, firstBeelzebubServiceConfiguration.Commands[0].Headers[0], "Content-Type: text/html")
|
assert.Equal(t, firstBeelzebubServiceConfiguration.Commands[0].Headers[0], "Content-Type: text/html")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGelAllFilesNameByDirName(t *testing.T) {
|
||||||
|
|
||||||
|
var dir = t.TempDir()
|
||||||
|
|
||||||
|
files, err := gelAllFilesNameByDirName(dir)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, 0, len(files))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGelAllFilesNameByDirNameFiles(t *testing.T) {
|
||||||
|
|
||||||
|
var dir = t.TempDir()
|
||||||
|
|
||||||
|
testFiles := []string{"file1.yaml", "file2.yaml", "file3.txt", "subdir", "file4.yaml"}
|
||||||
|
for _, filename := range testFiles {
|
||||||
|
filePath := dir + "/" + filename
|
||||||
|
file, err := os.Create(filePath)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
file.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
files, err := gelAllFilesNameByDirName(dir)
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, 3, len(files))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGelAllFilesNameByDirNameError(t *testing.T) {
|
||||||
|
|
||||||
|
files, err := gelAllFilesNameByDirName("nosuchfile")
|
||||||
|
|
||||||
|
assert.Nil(t, files)
|
||||||
|
assert.Equal(t, "open nosuchfile: no such file or directory", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadFileBytesByFilePath(t *testing.T) {
|
||||||
|
|
||||||
|
var dir = t.TempDir()
|
||||||
|
filePath := dir + "/test.yaml"
|
||||||
|
|
||||||
|
f, err := os.Create(filePath)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
bytes, err := readFileBytesByFilePath(filePath)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "", string(bytes))
|
||||||
|
}
|
||||||
|
@ -14,24 +14,18 @@ import (
|
|||||||
const (
|
const (
|
||||||
// Reference: https://www.engraved.blog/building-a-virtual-machine-inside/
|
// Reference: https://www.engraved.blog/building-a-virtual-machine-inside/
|
||||||
promptVirtualizeLinuxTerminal = "I want you to act as a Linux terminal. I will type commands and you will reply with what the terminal should show. I want you to only reply with the terminal output inside one unique code block, and nothing else. Do no write explanations. Do not type commands unless I instruct you to do so.\n\nA:pwd\n\nQ:/home/user\n\n"
|
promptVirtualizeLinuxTerminal = "I want you to act as a Linux terminal. I will type commands and you will reply with what the terminal should show. I want you to only reply with the terminal output inside one unique code block, and nothing else. Do no write explanations. Do not type commands unless I instruct you to do so.\n\nA:pwd\n\nQ:/home/user\n\n"
|
||||||
ChatGPTPluginName = "OpenAIGPTLinuxTerminal"
|
ChatGPTPluginName = "OpenAIGPTLinuxTerminal"
|
||||||
openAIGPTEndpoint = "https://api.openai.com/v1/completions"
|
openAIGPTEndpoint = "https://api.openai.com/v1/completions"
|
||||||
)
|
)
|
||||||
|
|
||||||
type History struct {
|
type History struct {
|
||||||
Input, Output string
|
Input, Output string
|
||||||
}
|
}
|
||||||
|
|
||||||
type OpenAIGPTVirtualTerminal struct {
|
type openAIGPTVirtualTerminal struct {
|
||||||
Histories []History
|
Histories []History
|
||||||
OpenAPIChatGPTSecretKey string
|
openAIKey string
|
||||||
client *resty.Client
|
client *resty.Client
|
||||||
}
|
|
||||||
|
|
||||||
func (openAIGPTVirtualTerminal *OpenAIGPTVirtualTerminal) InjectDependency() {
|
|
||||||
if openAIGPTVirtualTerminal.client == nil {
|
|
||||||
openAIGPTVirtualTerminal.client = resty.New()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Choice struct {
|
type Choice struct {
|
||||||
@ -65,6 +59,14 @@ type gptRequest struct {
|
|||||||
Stop []string `json:"stop"`
|
Stop []string `json:"stop"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Init(history []History, openAIKey string) *openAIGPTVirtualTerminal {
|
||||||
|
return &openAIGPTVirtualTerminal{
|
||||||
|
Histories: history,
|
||||||
|
openAIKey: openAIKey,
|
||||||
|
client: resty.New(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func buildPrompt(histories []History, command string) string {
|
func buildPrompt(histories []History, command string) string {
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
|
|
||||||
@ -79,7 +81,7 @@ func buildPrompt(histories []History, command string) string {
|
|||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (openAIGPTVirtualTerminal *OpenAIGPTVirtualTerminal) GetCompletions(command string) (string, error) {
|
func (openAIGPTVirtualTerminal *openAIGPTVirtualTerminal) GetCompletions(command string) (string, error) {
|
||||||
requestJson, err := json.Marshal(gptRequest{
|
requestJson, err := json.Marshal(gptRequest{
|
||||||
Model: "text-davinci-003",
|
Model: "text-davinci-003",
|
||||||
Prompt: buildPrompt(openAIGPTVirtualTerminal.Histories, command),
|
Prompt: buildPrompt(openAIGPTVirtualTerminal.Histories, command),
|
||||||
@ -94,14 +96,14 @@ func (openAIGPTVirtualTerminal *OpenAIGPTVirtualTerminal) GetCompletions(command
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if openAIGPTVirtualTerminal.OpenAPIChatGPTSecretKey == "" {
|
if openAIGPTVirtualTerminal.openAIKey == "" {
|
||||||
return "", errors.New("OpenAPIChatGPTSecretKey is empty")
|
return "", errors.New("openAIKey is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := openAIGPTVirtualTerminal.client.R().
|
response, err := openAIGPTVirtualTerminal.client.R().
|
||||||
SetHeader("Content-Type", "application/json").
|
SetHeader("Content-Type", "application/json").
|
||||||
SetBody(requestJson).
|
SetBody(requestJson).
|
||||||
SetAuthToken(openAIGPTVirtualTerminal.OpenAPIChatGPTSecretKey).
|
SetAuthToken(openAIGPTVirtualTerminal.openAIKey).
|
||||||
SetResult(&gptResponse{}).
|
SetResult(&gptResponse{}).
|
||||||
Post(openAIGPTEndpoint)
|
Post(openAIGPTEndpoint)
|
||||||
|
|
||||||
|
@ -46,7 +46,15 @@ func TestBuildPromptWithHistory(t *testing.T) {
|
|||||||
prompt)
|
prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildGetCompletions(t *testing.T) {
|
func TestBuildGetCompletionsFailValidation(t *testing.T) {
|
||||||
|
openAIGPTVirtualTerminal := Init(make([]History, 0), "")
|
||||||
|
|
||||||
|
_, err := openAIGPTVirtualTerminal.GetCompletions("test")
|
||||||
|
|
||||||
|
assert.Equal(t, "openAIKey is empty", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildGetCompletionsWithResults(t *testing.T) {
|
||||||
client := resty.New()
|
client := resty.New()
|
||||||
httpmock.ActivateNonDefault(client.GetClient())
|
httpmock.ActivateNonDefault(client.GetClient())
|
||||||
defer httpmock.DeactivateAndReset()
|
defer httpmock.DeactivateAndReset()
|
||||||
@ -68,10 +76,8 @@ func TestBuildGetCompletions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
openAIGPTVirtualTerminal := OpenAIGPTVirtualTerminal{
|
openAIGPTVirtualTerminal := Init(make([]History, 0), "sdjdnklfjndslkjanfk")
|
||||||
OpenAPIChatGPTSecretKey: "sdjdnklfjndslkjanfk",
|
openAIGPTVirtualTerminal.client = client
|
||||||
client: client,
|
|
||||||
}
|
|
||||||
|
|
||||||
//When
|
//When
|
||||||
str, err := openAIGPTVirtualTerminal.GetCompletions("ls")
|
str, err := openAIGPTVirtualTerminal.GetCompletions("ls")
|
||||||
@ -80,3 +86,31 @@ func TestBuildGetCompletions(t *testing.T) {
|
|||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "prova.txt", str)
|
assert.Equal(t, "prova.txt", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuildGetCompletionsWithoutResults(t *testing.T) {
|
||||||
|
client := resty.New()
|
||||||
|
httpmock.ActivateNonDefault(client.GetClient())
|
||||||
|
defer httpmock.DeactivateAndReset()
|
||||||
|
|
||||||
|
// Given
|
||||||
|
httpmock.RegisterResponder("POST", openAIGPTEndpoint,
|
||||||
|
func(req *http.Request) (*http.Response, error) {
|
||||||
|
resp, err := httpmock.NewJsonResponse(200, &gptResponse{
|
||||||
|
Choices: []Choice{},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return httpmock.NewStringResponse(500, ""), nil
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
openAIGPTVirtualTerminal := Init(make([]History, 0), "sdjdnklfjndslkjanfk")
|
||||||
|
openAIGPTVirtualTerminal.client = client
|
||||||
|
|
||||||
|
//When
|
||||||
|
_, err := openAIGPTVirtualTerminal.GetCompletions("ls")
|
||||||
|
|
||||||
|
//Then
|
||||||
|
assert.Equal(t, "no choices", err.Error())
|
||||||
|
}
|
||||||
|
@ -16,7 +16,7 @@ type ProtocolManager struct {
|
|||||||
|
|
||||||
func InitProtocolManager(tracerStrategy tracer.Strategy, strategy ServiceStrategy) *ProtocolManager {
|
func InitProtocolManager(tracerStrategy tracer.Strategy, strategy ServiceStrategy) *ProtocolManager {
|
||||||
return &ProtocolManager{
|
return &ProtocolManager{
|
||||||
tracer: tracer.Init(tracerStrategy),
|
tracer: tracer.GetInstance(tracerStrategy),
|
||||||
strategy: strategy,
|
strategy: strategy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,7 @@ func (sshStrategy *SSHStrategy) Init(beelzebubServiceConfiguration parser.Beelze
|
|||||||
commandOutput := command.Handler
|
commandOutput := command.Handler
|
||||||
|
|
||||||
if command.Plugin == plugins.ChatGPTPluginName {
|
if command.Plugin == plugins.ChatGPTPluginName {
|
||||||
openAIGPTVirtualTerminal := plugins.OpenAIGPTVirtualTerminal{Histories: histories, OpenAPIChatGPTSecretKey: beelzebubServiceConfiguration.Plugin.OpenAPIChatGPTSecretKey}
|
openAIGPTVirtualTerminal := plugins.Init(histories, beelzebubServiceConfiguration.Plugin.OpenAPIChatGPTSecretKey)
|
||||||
openAIGPTVirtualTerminal.InjectDependency()
|
|
||||||
|
|
||||||
if commandOutput, err = openAIGPTVirtualTerminal.GetCompletions(commandInput); err != nil {
|
if commandOutput, err = openAIGPTVirtualTerminal.GetCompletions(commandInput); err != nil {
|
||||||
log.Errorf("Error GetCompletions: %s, %s", commandInput, err.Error())
|
log.Errorf("Error GetCompletions: %s, %s", commandInput, err.Error())
|
||||||
@ -125,7 +124,7 @@ func (sshStrategy *SSHStrategy) Init(beelzebubServiceConfiguration parser.Beelze
|
|||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"port": beelzebubServiceConfiguration.Address,
|
"port": beelzebubServiceConfiguration.Address,
|
||||||
"commands": len(beelzebubServiceConfiguration.Commands),
|
"commands": len(beelzebubServiceConfiguration.Commands),
|
||||||
}).Infof("Init service %s", beelzebubServiceConfiguration.Protocol)
|
}).Infof("GetInstance service %s", beelzebubServiceConfiguration.Protocol)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
115
tracer/tracer.go
115
tracer/tracer.go
@ -1,11 +1,12 @@
|
|||||||
package tracer
|
package tracer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const Workers = 5
|
const Workers = 5
|
||||||
@ -44,8 +45,8 @@ const (
|
|||||||
TCP
|
TCP
|
||||||
)
|
)
|
||||||
|
|
||||||
func (status Protocol) String() string {
|
func (protocol Protocol) String() string {
|
||||||
return [...]string{"HTTP", "SSH", "TCP"}[status]
|
return [...]string{"HTTP", "SSH", "TCP"}[protocol]
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -66,49 +67,60 @@ type Tracer interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type tracer struct {
|
type tracer struct {
|
||||||
strategy Strategy
|
strategy Strategy
|
||||||
eventsChan chan Event
|
eventsChan chan Event
|
||||||
|
eventsTotal prometheus.Counter
|
||||||
|
eventsSSHTotal prometheus.Counter
|
||||||
|
eventsTCPTotal prometheus.Counter
|
||||||
|
eventsHTTPTotal prometheus.Counter
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var lock = &sync.Mutex{}
|
||||||
eventsTotal = promauto.NewCounter(prometheus.CounterOpts{
|
var singleton *tracer
|
||||||
Namespace: "beelzebub",
|
|
||||||
Name: "events_total",
|
|
||||||
Help: "The total number of events",
|
|
||||||
})
|
|
||||||
eventsSSHTotal = promauto.NewCounter(prometheus.CounterOpts{
|
|
||||||
Namespace: "beelzebub",
|
|
||||||
Name: "ssh_events_total",
|
|
||||||
Help: "The total number of SSH events",
|
|
||||||
})
|
|
||||||
eventsTCPTotal = promauto.NewCounter(prometheus.CounterOpts{
|
|
||||||
Namespace: "beelzebub",
|
|
||||||
Name: "tcp_events_total",
|
|
||||||
Help: "The total number of TCP events",
|
|
||||||
})
|
|
||||||
eventsHTTPTotal = promauto.NewCounter(prometheus.CounterOpts{
|
|
||||||
Namespace: "beelzebub",
|
|
||||||
Name: "http_events_total",
|
|
||||||
Help: "The total number of HTTP events",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
func Init(strategy Strategy) *tracer {
|
func GetInstance(strategy Strategy) *tracer {
|
||||||
tracer := &tracer{
|
if singleton == nil {
|
||||||
strategy: strategy,
|
lock.Lock()
|
||||||
eventsChan: make(chan Event, Workers),
|
defer lock.Unlock()
|
||||||
}
|
// This is to prevent expensive lock operations every time the GetInstance method is called
|
||||||
|
if singleton == nil {
|
||||||
for i := 0; i < Workers; i++ {
|
singleton = &tracer{
|
||||||
go func(i int) {
|
strategy: strategy,
|
||||||
log.Debug("Init trace worker: ", i)
|
eventsChan: make(chan Event, Workers),
|
||||||
for event := range tracer.eventsChan {
|
eventsTotal: promauto.NewCounter(prometheus.CounterOpts{
|
||||||
tracer.strategy(event)
|
Namespace: "beelzebub",
|
||||||
|
Name: "events_total",
|
||||||
|
Help: "The total number of events",
|
||||||
|
}),
|
||||||
|
eventsSSHTotal: promauto.NewCounter(prometheus.CounterOpts{
|
||||||
|
Namespace: "beelzebub",
|
||||||
|
Name: "ssh_events_total",
|
||||||
|
Help: "The total number of SSH events",
|
||||||
|
}),
|
||||||
|
eventsTCPTotal: promauto.NewCounter(prometheus.CounterOpts{
|
||||||
|
Namespace: "beelzebub",
|
||||||
|
Name: "tcp_events_total",
|
||||||
|
Help: "The total number of TCP events",
|
||||||
|
}),
|
||||||
|
eventsHTTPTotal: promauto.NewCounter(prometheus.CounterOpts{
|
||||||
|
Namespace: "beelzebub",
|
||||||
|
Name: "http_events_total",
|
||||||
|
Help: "The total number of HTTP events",
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}(i)
|
|
||||||
|
for i := 0; i < Workers; i++ {
|
||||||
|
go func(i int) {
|
||||||
|
log.Debug("GetInstance trace worker: ", i)
|
||||||
|
for event := range singleton.eventsChan {
|
||||||
|
singleton.strategy(event)
|
||||||
|
}
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tracer
|
return singleton
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tracer *tracer) setStrategy(strategy Strategy) {
|
func (tracer *tracer) setStrategy(strategy Strategy) {
|
||||||
@ -120,14 +132,17 @@ func (tracer *tracer) TraceEvent(event Event) {
|
|||||||
|
|
||||||
tracer.eventsChan <- event
|
tracer.eventsChan <- event
|
||||||
|
|
||||||
eventsTotal.Inc()
|
tracer.updatePrometheusCounters(event.Protocol)
|
||||||
|
}
|
||||||
switch event.Protocol {
|
|
||||||
case HTTP.String():
|
func (tracer *tracer) updatePrometheusCounters(protocol string) {
|
||||||
eventsHTTPTotal.Inc()
|
switch protocol {
|
||||||
case SSH.String():
|
case HTTP.String():
|
||||||
eventsSSHTotal.Inc()
|
tracer.eventsHTTPTotal.Inc()
|
||||||
case TCP.String():
|
case SSH.String():
|
||||||
eventsTCPTotal.Inc()
|
tracer.eventsSSHTotal.Inc()
|
||||||
}
|
case TCP.String():
|
||||||
|
tracer.eventsTCPTotal.Inc()
|
||||||
|
}
|
||||||
|
tracer.eventsTotal.Inc()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package tracer
|
package tracer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -10,7 +11,7 @@ import (
|
|||||||
func TestInit(t *testing.T) {
|
func TestInit(t *testing.T) {
|
||||||
mockStrategy := func(event Event) {}
|
mockStrategy := func(event Event) {}
|
||||||
|
|
||||||
tracer := Init(mockStrategy)
|
tracer := GetInstance(mockStrategy)
|
||||||
|
|
||||||
assert.NotNil(t, tracer.strategy)
|
assert.NotNil(t, tracer.strategy)
|
||||||
}
|
}
|
||||||
@ -25,7 +26,9 @@ func TestTraceEvent(t *testing.T) {
|
|||||||
eventCalled = event
|
eventCalled = event
|
||||||
}
|
}
|
||||||
|
|
||||||
tracer := Init(mockStrategy)
|
tracer := GetInstance(mockStrategy)
|
||||||
|
|
||||||
|
tracer.strategy = mockStrategy
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
tracer.TraceEvent(Event{
|
tracer.TraceEvent(Event{
|
||||||
@ -51,7 +54,7 @@ func TestSetStrategy(t *testing.T) {
|
|||||||
eventCalled = event
|
eventCalled = event
|
||||||
}
|
}
|
||||||
|
|
||||||
tracer := Init(mockStrategy)
|
tracer := GetInstance(mockStrategy)
|
||||||
|
|
||||||
tracer.setStrategy(mockStrategy)
|
tracer.setStrategy(mockStrategy)
|
||||||
|
|
||||||
@ -75,3 +78,42 @@ func TestStringStatus(t *testing.T) {
|
|||||||
assert.Equal(t, Stateless.String(), "Stateless")
|
assert.Equal(t, Stateless.String(), "Stateless")
|
||||||
assert.Equal(t, Interaction.String(), "Interaction")
|
assert.Equal(t, Interaction.String(), "Interaction")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mockCounter struct {
|
||||||
|
prometheus.Metric
|
||||||
|
prometheus.Collector
|
||||||
|
inc func()
|
||||||
|
add func(float64)
|
||||||
|
}
|
||||||
|
|
||||||
|
var counter = 0
|
||||||
|
|
||||||
|
func (m mockCounter) Inc() {
|
||||||
|
counter += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockCounter) Add(f float64) {
|
||||||
|
counter = int(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdatePrometheusCounters(t *testing.T) {
|
||||||
|
mockStrategy := func(event Event) {}
|
||||||
|
|
||||||
|
tracer := &tracer{
|
||||||
|
strategy: mockStrategy,
|
||||||
|
eventsChan: make(chan Event, Workers),
|
||||||
|
eventsTotal: mockCounter{},
|
||||||
|
eventsSSHTotal: mockCounter{},
|
||||||
|
eventsTCPTotal: mockCounter{},
|
||||||
|
eventsHTTPTotal: mockCounter{},
|
||||||
|
}
|
||||||
|
|
||||||
|
tracer.updatePrometheusCounters(SSH.String())
|
||||||
|
assert.Equal(t, 2, counter)
|
||||||
|
|
||||||
|
tracer.updatePrometheusCounters(HTTP.String())
|
||||||
|
assert.Equal(t, 4, counter)
|
||||||
|
|
||||||
|
tracer.updatePrometheusCounters(TCP.String())
|
||||||
|
assert.Equal(t, 6, counter)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user