func TestDeleteOnlyRule(t *testing.T) {
	r1 := &CentralizedRule{
		ruleName: "r1",
		priority: 5,
	}
	rules := []*CentralizedRule{r1}
	index := map[string]*CentralizedRule{
		"r1": r1,
	}
	m := &CentralizedManifest{
		Rules: rules,
		Index: index,
	}
	a := map[*CentralizedRule]bool{}
	m.prune(a)
	assert.Equal(t, 0, len(m.Rules))
	assert.Equal(t, 0, len(m.Index))
	_, ok := m.Index["r1"]
	assert.False(t, ok)
}
Assert that deleting the only rule from the array removes the rule
package sampling
import (
	"testing"
	"github.com/stretchr/testify/assert"
	xraySvc "github.com/aws/aws-sdk-go/service/xray"
	"github.com/aws/aws-xray-sdk-go/utils"
)
func TestCreateUserRule(t *testing.T) {
	resARN := "*"
	r1 := &CentralizedRule{
		ruleName: "r1",
		priority: 5,
	}
	r3 := &CentralizedRule{
		ruleName: "r3",
		priority: 7,
	}
	rules := []*CentralizedRule{r1, r3}
	index := map[string]*CentralizedRule{
		"r1": r1,
		"r3": r3,
	}
	m := &CentralizedManifest{
		Rules: rules,
		Index: index,
	}
	serviceName := "www.foo.com"
	httpMethod := "POST"
	urlPath := "/bar/*"
	reservoirSize := int64(10)
	fixedRate := float64(0.05)
	ruleName := "r2"
	host := "local"
	priority := int64(6)
	serviceTye := "*"
	new := &xraySvc.SamplingRule{
		ServiceName:   &serviceName,
		HTTPMethod:    &httpMethod,
		URLPath:       &urlPath,
		ReservoirSize: &reservoirSize,
		FixedRate:     &fixedRate,
		RuleName:      &ruleName,
		Priority:      &priority,
		Host:          &host,
		ServiceType:   &serviceTye,
		ResourceARN:   &resARN,
	}
	clock := &utils.DefaultClock{}
	rand := &utils.DefaultRand{}
	p := &Properties{
		ServiceName: serviceName,
		HTTPMethod:  httpMethod,
		URLPath:     urlPath,
		FixedTarget: reservoirSize,
		Rate:        fixedRate,
		Host:        host,
	}
	cr := &CentralizedReservoir{
		reservoir: &reservoir{
			capacity: 10,
		},
		interval: 10,
	}
	exp := &CentralizedRule{
		reservoir:   cr,
		ruleName:    ruleName,
		priority:    priority,
		Properties:  p,
		clock:       clock,
		rand:        rand,
		serviceType: serviceTye,
		resourceARN: resARN,
	}
	r2, err := m.putRule(new)
	assert.Nil(t, err)
	assert.Equal(t, exp, r2)
	r2, ok := m.Index["r2"]
	assert.True(t, ok)
	assert.Equal(t, exp, r2)
	r2 = m.Rules[2]
	assert.Equal(t, exp, r2)
}
func TestCreateDefaultRule(t *testing.T) {
	m := &CentralizedManifest{
		Index: map[string]*CentralizedRule{},
	}
	reservoirSize := int64(10)
	fixedRate := float64(0.05)
	ruleName := "Default"
	new := &xraySvc.SamplingRule{
		ReservoirSize: &reservoirSize,
		FixedRate:     &fixedRate,
		RuleName:      &ruleName,
	}
	clock := &utils.DefaultClock{}
	rand := &utils.DefaultRand{}
	p := &Properties{
		FixedTarget: reservoirSize,
		Rate:        fixedRate,
	}
	cr := &CentralizedReservoir{
		reservoir: &reservoir{
			capacity: reservoirSize,
		},
		interval: 10,
	}
	exp := &CentralizedRule{
		reservoir:  cr,
		ruleName:   ruleName,
		Properties: p,
		clock:      clock,
		rand:       rand,
	}
	r, err := m.putRule(new)
	assert.Nil(t, err)
	assert.Equal(t, exp, r)
	assert.Equal(t, exp, m.Default)
}
func TestUpdateDefaultRule(t *testing.T) {
	clock := &utils.DefaultClock{}
	rand := &utils.DefaultRand{}
	r := &CentralizedRule{
		ruleName: "Default",
		Properties: &Properties{
			FixedTarget: 10,
			Rate:        0.05,
		},
		reservoir: &CentralizedReservoir{
			reservoir: &reservoir{
				capacity: 10,
			},
		},
		clock: clock,
		rand:  rand,
	}
	m := &CentralizedManifest{
		Default: r,
	}
	reservoirSize := int64(20)
	fixedRate := float64(0.06)
	ruleName := "Default"
	updated := &xraySvc.SamplingRule{
		ReservoirSize: &reservoirSize,
		FixedRate:     &fixedRate,
		RuleName:      &ruleName,
	}
	p := &Properties{
		FixedTarget: reservoirSize,
		Rate:        fixedRate,
	}
	cr := &CentralizedReservoir{
		reservoir: &reservoir{
			capacity: reservoirSize,
		},
	}
	exp := &CentralizedRule{
		reservoir:  cr,
		ruleName:   ruleName,
		Properties: p,
		clock:      clock,
		rand:       rand,
	}
	r, err := m.putRule(updated)
	assert.Nil(t, err)
	assert.Equal(t, exp, r)
	assert.Equal(t, exp, m.Default)
}
func TestCreateUserRuleNoOp(t *testing.T) {
	resARN := "*"
	serviceTye := ""
	attributes := make(map[string]*string)
	r1 := &CentralizedRule{
		ruleName: "r1",
		priority: 5,
	}
	r3 := &CentralizedRule{
		ruleName: "r3",
		priority: 7,
		reservoir: &CentralizedReservoir{
			reservoir: &reservoir{},
		},
	}
	rules := []*CentralizedRule{r1, r3}
	index := map[string]*CentralizedRule{
		"r1": r1,
		"r3": r3,
	}
	m := &CentralizedManifest{
		Rules: rules,
		Index: index,
	}
	serviceName := "www.foo.com"
	httpMethod := "POST"
	urlPath := "/bar/*"
	reservoirSize := int64(10)
	fixedRate := float64(0.05)
	ruleName := "r3"
	priority := int64(6)
	host := "h"
	new := &xraySvc.SamplingRule{
		ServiceName:   &serviceName,
		HTTPMethod:    &httpMethod,
		URLPath:       &urlPath,
		ReservoirSize: &reservoirSize,
		FixedRate:     &fixedRate,
		RuleName:      &ruleName,
		Priority:      &priority,
		Host:          &host,
		ResourceARN:   &resARN,
		ServiceType:   &serviceTye,
		Attributes:    attributes,
	}
	r, err := m.putRule(new)
	assert.Nil(t, err)
	assert.Equal(t, r3, r)
	assert.Equal(t, 2, len(m.Rules))
	assert.Equal(t, 2, len(m.Index))
	assert.Equal(t, r1, m.Rules[0])
	assert.Equal(t, r3, m.Rules[1])
}
func TestUpdateUserRule(t *testing.T) {
	resARN := "*"
	serviceTye := ""
	attributes := make(map[string]*string)
	r1 := &CentralizedRule{
		ruleName: "r1",
		priority: 5,
		Properties: &Properties{
			ServiceName: "*.foo.com",
			HTTPMethod:  "GET",
			URLPath:     "/resource/*",
			FixedTarget: 15,
			Rate:        0.04,
		},
		reservoir: &CentralizedReservoir{
			reservoir: &reservoir{
				capacity: 5,
			},
		},
		resourceARN: resARN,
		serviceType: serviceTye,
		attributes:  attributes,
	}
	rules := []*CentralizedRule{r1}
	index := map[string]*CentralizedRule{
		"r1": r1,
	}
	m := &CentralizedManifest{
		Rules: rules,
		Index: index,
	}
	serviceName := "www.foo.com"
	httpMethod := "POST"
	urlPath := "/bar/*"
	reservoirSize := int64(10)
	fixedRate := float64(0.05)
	ruleName := "r1"
	priority := int64(6)
	host := "h"
	updated := &xraySvc.SamplingRule{
		ServiceName:   &serviceName,
		HTTPMethod:    &httpMethod,
		URLPath:       &urlPath,
		ReservoirSize: &reservoirSize,
		FixedRate:     &fixedRate,
		RuleName:      &ruleName,
		Priority:      &priority,
		Host:          &host,
		ResourceARN:   &resARN,
		ServiceType:   &serviceTye,
		Attributes:    attributes,
	}
	p := &Properties{
		ServiceName: serviceName,
		HTTPMethod:  httpMethod,
		URLPath:     urlPath,
		FixedTarget: reservoirSize,
		Rate:        fixedRate,
		Host:        host,
	}
	cr := &CentralizedReservoir{
		reservoir: &reservoir{
			capacity: 10,
		},
	}
	exp := &CentralizedRule{
		reservoir:   cr,
		ruleName:    ruleName,
		priority:    priority,
		Properties:  p,
		resourceARN: resARN,
		serviceType: serviceTye,
		attributes:  attributes,
	}
	r, err := m.putRule(updated)
	assert.Nil(t, err)
	assert.Equal(t, exp, r)
	assert.Equal(t, exp, m.Index["r1"])
	assert.Equal(t, exp, m.Rules[0])
	assert.Equal(t, 1, len(m.Rules))
	assert.Equal(t, 1, len(m.Index))
}
func TestPutRuleRecovery(t *testing.T) {
	resARN := "*"
	serviceTye := ""
	attributes := make(map[string]*string)
	rules := []*CentralizedRule{}
	index := map[string]*CentralizedRule{}
	m := &CentralizedManifest{
		Rules: rules,
		Index: index,
	}
	serviceName := "www.foo.com"
	httpMethod := "POST"
	fixedRate := float64(0.05)
	ruleName := "r2"
	priority := int64(6)
	new := &xraySvc.SamplingRule{
		ServiceName: &serviceName,
		HTTPMethod:  &httpMethod,
		FixedRate:   &fixedRate,
		RuleName:    &ruleName,
		Priority:    &priority,
		ResourceARN: &resARN,
		ServiceType: &serviceTye,
		Attributes:  attributes,
	}
	r, err := m.putRule(new)
	assert.NotNil(t, err)
	assert.Nil(t, r)
	assert.Nil(t, m.Default)
	assert.Equal(t, 0, len(m.Index))
	assert.Equal(t, 0, len(m.Rules))
}
func TestDeleteLastRule(t *testing.T) {
	r1 := &CentralizedRule{
		ruleName: "r1",
		priority: 5,
	}
	r2 := &CentralizedRule{
		ruleName: "r2",
		priority: 6,
	}
	r3 := &CentralizedRule{
		ruleName: "r3",
		priority: 7,
	}
	rules := []*CentralizedRule{r1, r2, r3}
	index := map[string]*CentralizedRule{
		"r1": r1,
		"r2": r2,
		"r3": r3,
	}
	m := &CentralizedManifest{
		Rules: rules,
		Index: index,
	}
	a := map[*CentralizedRule]bool{
		r1: true,
		r2: true,
	}
	m.prune(a)
	assert.Equal(t, 2, len(m.Rules))
	assert.Equal(t, 2, len(m.Index))
	_, ok := m.Index["r3"]
	assert.False(t, ok)
	assert.Equal(t, r1, m.Index["r1"])
	assert.Equal(t, r2, m.Index["r2"])
	assert.Equal(t, r1, m.Rules[0])
	assert.Equal(t, r2, m.Rules[1])
}
func TestDeleteMiddleRule(t *testing.T) {
	r1 := &CentralizedRule{
		ruleName: "r1",
		priority: 5,
	}
	r2 := &CentralizedRule{
		ruleName: "r2",
		priority: 6,
	}
	r3 := &CentralizedRule{
		ruleName: "r3",
		priority: 7,
	}
	rules := []*CentralizedRule{r1, r2, r3}
	index := map[string]*CentralizedRule{
		"r1": r1,
		"r2": r2,
		"r3": r3,
	}
	m := &CentralizedManifest{
		Rules: rules,
		Index: index,
	}
	a := map[*CentralizedRule]bool{
		r1: true,
		r3: true,
	}
	m.prune(a)
	assert.Equal(t, 2, len(m.Rules))
	assert.Equal(t, 2, len(m.Index))
	_, ok := m.Index["r2"]
	assert.False(t, ok)
	assert.Equal(t, r1, m.Index["r1"])
	assert.Equal(t, r3, m.Index["r3"])
	assert.Equal(t, r1, m.Rules[0])
	assert.Equal(t, r3, m.Rules[1])
}
func TestDeleteFirstRule(t *testing.T) {
	r1 := &CentralizedRule{
		ruleName: "r1",
		priority: 5,
	}
	r2 := &CentralizedRule{
		ruleName: "r2",
		priority: 6,
	}
	r3 := &CentralizedRule{
		ruleName: "r3",
		priority: 7,
	}
	rules := []*CentralizedRule{r1, r2, r3}
	index := map[string]*CentralizedRule{
		"r1": r1,
		"r2": r2,
		"r3": r3,
	}
	m := &CentralizedManifest{
		Rules: rules,
		Index: index,
	}
	a := map[*CentralizedRule]bool{
		r2: true,
		r3: true,
	}
	m.prune(a)
	assert.Equal(t, 2, len(m.Rules))
	assert.Equal(t, 2, len(m.Index))
	_, ok := m.Index["r1"]
	assert.False(t, ok)
	assert.Equal(t, r2, m.Index["r2"])
	assert.Equal(t, r3, m.Index["r3"])
	assert.Equal(t, r2, m.Rules[0])
	assert.Equal(t, r3, m.Rules[1])
}