<commit_before>package main

import (
	"bytes"
	"fmt"
	"github.com/Comcast/webpa-common/logging"
	"github.com/Comcast/webpa-common/webhook"
	"github.com/stretchr/testify/assert"
	"io/ioutil"
	"net/http"
	"sync/atomic"
	"testing"
	"time"
)

var (
	testServerProfilerFactory = ServerProfilerFactory{
		Frequency: 10,
		Duration:  6,
		QueueSize: 100,
	}
)

// Make a simple RoundTrip implementation that let's me short-circuit the network
type transport struct {
	i  int32
	fn func(*http.Request, int) (*http.Response, error)
}

func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
	i := atomic.AddInt32(&t.i, 1)
	r, err := t.fn(req, int(i))
	return r, err
}

func getLogger() logging.Logger {
	loggerFactory := logging.DefaultLoggerFactory{}
	logger, _ := loggerFactory.NewLogger("test")

	return logger
}

func simpleSetup(trans *transport, cutOffPeriod time.Duration, matcher map[string][]string) (obs *OutboundSender, err error) {
	trans.fn = func(req *http.Request, count int) (resp *http.Response, err error) {
		resp = &http.Response{Status: "200 OK",
			StatusCode: 200,
		}
		return
	}

	obs, err = OutboundSenderFactory{
		Listener: webhook.W{
			URL:         "http://localhost:9999/foo",
			ContentType: "application/json",
			Secret:      "123456",
			Until:       time.Now().Add(60 * time.Second),
			Events:      []string{"iot", "test"},
			Matchers:    matcher,
		},

		Client:          &http.Client{Transport: trans},
		CutOffPeriod:    cutOffPeriod,
		NumWorkers:      10,
		QueueSize:       10,
		ProfilerFactory: testServerProfilerFactory,
		Logger:          getLogger(),
	}.New()
	return
}

func simpleJSONRequest() CaduceusRequest {
	req := CaduceusRequest{
		Payload:     []byte("Hello, world."),
		ContentType: "application/json",
		TargetURL:   "http://foo.com/api/v2/notification/device/mac:112233445566/event/iot",
	}

	return req
}

func simpleWrpRequest() CaduceusRequest {
	req := CaduceusRequest{
		Payload:     []byte("Hello, world."),
		ContentType: "application/wrp",
		TargetURL:   "http://foo.com/api/v2/notification/device/mac:112233445566/event/iot",
	}

	return req
}

// Simple test that covers the normal successful case with no extra matchers
func TestSimpleJSON(t *testing.T) {

	assert := assert.New(t)

	trans := &transport{}
	obs, err := simpleSetup(trans, time.Second, nil)
	assert.NotNil(obs)
	assert.Nil(err)

	req := simpleJSONRequest()

	obs.QueueJSON(req, "iot", "mac:112233445566", "1234")
	obs.QueueJSON(req, "test", "mac:112233445566", "1234")
	obs.QueueJSON(req, "no-match", "mac:112233445566", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(2), trans.i)
}

// Simple test that covers the normal successful case with extra matchers
func TestSimpleJSONWithMatchers(t *testing.T) {

	assert := assert.New(t)

	m := make(map[string][]string)
	m["device_id"] = []string{"mac:112233445566", "mac:112233445565"}

	trans := &transport{}
	obs, err := simpleSetup(trans, time.Second, m)
	assert.Nil(err)

	req := simpleJSONRequest()

	obs.QueueJSON(req, "iot", "mac:112233445565", "1234")
	obs.QueueJSON(req, "test", "mac:112233445566", "1234")
	obs.QueueJSON(req, "iot", "mac:112233445560", "1234")
	obs.QueueJSON(req, "test", "mac:112233445560", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(2), trans.i)
}

// Simple test that covers the normal successful case with extra wildcard matcher
func TestSimpleJSONWithWildcardMatchers(t *testing.T) {

	assert := assert.New(t)

	trans := &transport{}

	m := make(map[string][]string)
	m["device_id"] = []string{"mac:112233445566", ".*"}

	obs, err := simpleSetup(trans, time.Second, m)
	assert.Nil(err)

	req := simpleJSONRequest()

	obs.QueueJSON(req, "iot", "mac:112233445565", "1234")
	obs.QueueJSON(req, "test", "mac:112233445566", "1234")
	obs.QueueJSON(req, "iot", "mac:112233445560", "1234")
	obs.QueueJSON(req, "test", "mac:112233445560", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(4), trans.i)
}

// // Simple test that covers the normal successful case with no extra matchers
// func TestSimpleWrp(t *testing.T) {
//
// 	assert := assert.New(t)
//
// 	trans := &transport{}
// 	obs, err := simpleSetup(trans, time.Second, nil)
// 	assert.NotNil(obs)
// 	assert.Nil(err)
//
// 	req := simpleJSONRequest()
//
// 	obs.QueueWrp(req, nil, "iot", "mac:112233445566", "1234")
// 	obs.QueueWrp(req, nil, "test", "mac:112233445566", "1234")
// 	obs.QueueWrp(req, nil, "no-match", "mac:112233445566", "1234")
//
// 	obs.Shutdown(true)
//
// 	assert.Equal(int32(2), trans.i)
// }

// Simple test that checks for invalid match regex
func TestInvalidMatchRegex(t *testing.T) {

	assert := assert.New(t)

	trans := &transport{}

	m := make(map[string][]string)
	m["device_id"] = []string{"[[:112233445566"}

	obs, err := simpleSetup(trans, time.Second, m)
	assert.Nil(obs)
	assert.NotNil(err)
}

// Simple test that checks for invalid cutoff period
func TestInvalidCutOffPeriod(t *testing.T) {

	assert := assert.New(t)

	trans := &transport{}

	obs, err := simpleSetup(trans, 0*time.Second, nil)
	assert.Nil(obs)
	assert.NotNil(err)
}
<commit_msg>Working more on unit tests for the outbound sender wrp stuff.<commit_after>package main

import (
	"bytes"
	"fmt"
	"github.com/Comcast/webpa-common/logging"
	"github.com/Comcast/webpa-common/webhook"
	"github.com/stretchr/testify/assert"
	"io/ioutil"
	"net/http"
	"sync/atomic"
	"testing"
	"time"
)

var (
	testServerProfilerFactory = ServerProfilerFactory{
		Frequency: 10,
		Duration:  6,
		QueueSize: 100,
	}
)

// Make a simple RoundTrip implementation that let's me short-circuit the network
type transport struct {
	i  int32
	fn func(*http.Request, int) (*http.Response, error)
}

func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
	i := atomic.AddInt32(&t.i, 1)
	r, err := t.fn(req, int(i))
	return r, err
}

func getLogger() logging.Logger {
	loggerFactory := logging.DefaultLoggerFactory{}
	logger, _ := loggerFactory.NewLogger("test")

	return logger
}

func simpleSetup(trans *transport, cutOffPeriod time.Duration, matcher map[string][]string) (obs *OutboundSender, err error) {
	trans.fn = func(req *http.Request, count int) (resp *http.Response, err error) {
		resp = &http.Response{Status: "200 OK",
			StatusCode: 200,
		}
		return
	}

	obs, err = OutboundSenderFactory{
		Listener: webhook.W{
			URL:         "http://localhost:9999/foo",
			ContentType: "application/json",
			Secret:      "123456",
			Until:       time.Now().Add(60 * time.Second),
			Events:      []string{"iot", "test"},
			Matchers:    matcher,
		},

		Client:          &http.Client{Transport: trans},
		CutOffPeriod:    cutOffPeriod,
		NumWorkers:      10,
		QueueSize:       10,
		ProfilerFactory: testServerProfilerFactory,
		Logger:          getLogger(),
	}.New()
	return
}

func simpleJSONRequest() CaduceusRequest {
	req := CaduceusRequest{
		Payload:     []byte("Hello, world."),
		ContentType: "application/json",
		TargetURL:   "http://foo.com/api/v2/notification/device/mac:112233445566/event/iot",
	}

	return req
}

func simpleWrpRequest() CaduceusRequest {
	req := CaduceusRequest{
		Payload:     []byte("Hello, world."),
		ContentType: "application/wrp",
		TargetURL:   "http://foo.com/api/v2/notification/device/mac:112233445566/event/iot",
	}

	return req
}

// Simple test that covers the normal successful case with no extra matchers
func TestSimpleJSON(t *testing.T) {

	assert := assert.New(t)

	trans := &transport{}
	obs, err := simpleSetup(trans, time.Second, nil)
	assert.NotNil(obs)
	assert.Nil(err)

	req := simpleJSONRequest()

	obs.QueueJSON(req, "iot", "mac:112233445566", "1234")
	obs.QueueJSON(req, "test", "mac:112233445566", "1234")
	obs.QueueJSON(req, "no-match", "mac:112233445566", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(2), trans.i)
}

// Simple test that covers the normal successful case with extra matchers
func TestSimpleJSONWithMatchers(t *testing.T) {

	assert := assert.New(t)

	m := make(map[string][]string)
	m["device_id"] = []string{"mac:112233445566", "mac:112233445565"}

	trans := &transport{}
	obs, err := simpleSetup(trans, time.Second, m)
	assert.Nil(err)

	req := simpleJSONRequest()

	obs.QueueJSON(req, "iot", "mac:112233445565", "1234")
	obs.QueueJSON(req, "test", "mac:112233445566", "1234")
	obs.QueueJSON(req, "iot", "mac:112233445560", "1234")
	obs.QueueJSON(req, "test", "mac:112233445560", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(2), trans.i)
}

// Simple test that covers the normal successful case with extra wildcard matcher
func TestSimpleJSONWithWildcardMatchers(t *testing.T) {

	assert := assert.New(t)

	trans := &transport{}

	m := make(map[string][]string)
	m["device_id"] = []string{"mac:112233445566", ".*"}

	obs, err := simpleSetup(trans, time.Second, m)
	assert.Nil(err)

	req := simpleJSONRequest()

	obs.QueueJSON(req, "iot", "mac:112233445565", "1234")
	obs.QueueJSON(req, "test", "mac:112233445566", "1234")
	obs.QueueJSON(req, "iot", "mac:112233445560", "1234")
	obs.QueueJSON(req, "test", "mac:112233445560", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(4), trans.i)
}

// Simple test that covers the normal successful case with no extra matchers
func TestSimpleWrp(t *testing.T) {

	assert := assert.New(t)

	trans := &transport{}
	obs, err := simpleSetup(trans, time.Second, nil)
	assert.NotNil(obs)
	assert.Nil(err)

	req := simpleWrpRequest()

	obs.QueueWrp(req, nil, "iot", "mac:112233445566", "1234")
	obs.QueueWrp(req, nil, "test", "mac:112233445566", "1234")
	obs.QueueWrp(req, nil, "no-match", "mac:112233445566", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(2), trans.i)
}

// Simple test that covers the normal successful case with extra matchers
func TestSimpleWrpWithMatchers(t *testing.T) {

	assert := assert.New(t)

	m := make(map[string][]string)
	m["device_id"] = []string{"mac:112233445566", "mac:112233445565"}

	trans := &transport{}
	obs, err := simpleSetup(trans, time.Second, m)
	assert.Nil(err)

	req := simpleWrpRequest()

	obs.QueueWrp(req, nil, "iot", "mac:112233445565", "1234")
	obs.QueueWrp(req, nil, "test", "mac:112233445566", "1234")
	obs.QueueWrp(req, nil, "iot", "mac:112233445560", "1234")
	obs.QueueWrp(req, nil, "test", "mac:112233445560", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(2), trans.i)
}

// Simple test that covers the normal successful case with extra wildcard matcher
func TestSimpleWrpWithWildcardMatchers(t *testing.T) {

	assert := assert.New(t)

	trans := &transport{}

	m := make(map[string][]string)
	m["device_id"] = []string{"mac:112233445566", ".*"}

	obs, err := simpleSetup(trans, time.Second, m)
	assert.Nil(err)

	req := simpleWrpRequest()

	obs.QueueWrp(req, nil, "iot", "mac:112233445565", "1234")
	obs.QueueWrp(req, nil, "test", "mac:112233445566", "1234")
	obs.QueueWrp(req, nil, "iot", "mac:112233445560", "1234")
	obs.QueueWrp(req, nil, "test", "mac:112233445560", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(4), trans.i)
}

// Simple test that covers the normal successful case with extra matchers
func TestSimpleWrpWithMetadata(t *testing.T) {

	assert := assert.New(t)

	m := make(map[string][]string)
	m["device_id"] = []string{"mac:112233445566", "mac:112233445565"}
	m["metadata"] = []string{"cheese", "crackers"}

	trans := &transport{}
	obs, err := simpleSetup(trans, time.Second, m)
	assert.Nil(err)

	req := simpleWrpRequest()

	wrpMeta := make(map[string]string)
	wrpMeta["metadata"] = "crackers"

	obs.QueueWrp(req, wrpMeta, "iot", "mac:112233445565", "1234")
	obs.QueueWrp(req, wrpMeta, "test", "mac:112233445566", "1234")
	obs.QueueWrp(req, wrpMeta, "iot", "mac:112233445560", "1234")
	obs.QueueWrp(req, wrpMeta, "test", "mac:112233445560", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(2), trans.i)
}

// Simple test that covers the normal successful case with extra matchers
func TestInvalidWrpMetadata(t *testing.T) {

	assert := assert.New(t)

	m := make(map[string][]string)
	m["device_id"] = []string{"mac:112233445566", "mac:112233445565"}
	m["metadata"] = []string{"cheese", "crackers"}

	trans := &transport{}
	obs, err := simpleSetup(trans, time.Second, m)
	assert.Nil(err)

	req := simpleWrpRequest()

	wrpMeta := make(map[string]string)
	wrpMeta["metadata"] = "notpresent"

	obs.QueueWrp(req, wrpMeta, "iot", "mac:112233445565", "1234")
	obs.QueueWrp(req, wrpMeta, "test", "mac:112233445566", "1234")
	obs.QueueWrp(req, wrpMeta, "iot", "mac:112233445560", "1234")
	obs.QueueWrp(req, wrpMeta, "test", "mac:112233445560", "1234")

	obs.Shutdown(true)

	assert.Equal(int32(2), trans.i)
}

// Simple test that checks for invalid match regex
func TestInvalidMatchRegex(t *testing.T) {

	assert := assert.New(t)

	trans := &transport{}

	m := make(map[string][]string)
	m["device_id"] = []string{"[[:112233445566"}

	obs, err := simpleSetup(trans, time.Second, m)
	assert.Nil(obs)
	assert.NotNil(err)
}

// Simple test that checks for invalid cutoff period
func TestInvalidCutOffPeriod(t *testing.T) {

	assert := assert.New(t)

	trans := &transport{}

	obs, err := simpleSetup(trans, 0*time.Second, nil)
	assert.Nil(obs)
	assert.NotNil(err)
}

{'fraction_non_alphanumeric': 0.16933568308941843, 'fraction_numerical': 0.07968738027737338, 'mean_word_length': 4.74219093708755, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6014621', 'n_tokens_mistral': 5631, 'n_tokens_neox': 4826, 'n_words': 1030}