func (s *ScorecardSuite) TestMultipleRules() {
	rules := []Rule{{"op:read", 1}, {"op:read", 2}}
	req1 := []Tag{"op:read", "gid:13"}
	req2 := []Tag{"op:read", "gid:42"}
	sc := NewScorecard(rules)
	ret := sc.TrackRequest(req1)
	require.True(s.T(), ret.Tracked)
	ret = sc.TrackRequest(req2)
	require.False(s.T(), ret.Tracked)
	require.Equal(s.T(), ret.Violated, Rule{"op:read", 1})
	require.Equal(s.T(), ret.Value, uint(1))
	require.Equal(s.T(), ret.Tag, Tag("op:read"))
}
Test multiple matching rules will always match the first
package scorecard
import (
	"fmt"
	insecure_random "math/rand"
	"sync"
	"testing"
	"time"
	"github.com/stretchr/testify/require"
	"github.com/stretchr/testify/suite"
)
type ScorecardSuite struct {
	suite.Suite
}
func TestScorecardSuite(t *testing.T) {
	suite.
		Run(t, new(ScorecardSuite))
}
func (s *ScorecardSuite) TestBasics() {
	req1 := []Tag{"meta_www", "TeamUserAssoc", "GID_10", "Point_Read"}
	req2 := []Tag{"meta_api", "UserEntity", "GID_20", "Point_Read"}
	req3 := []Tag{"meta_www", "TeamUserAssoc", "GID_30", "List_Read"}
	sc := NewScorecard([]Rule{})
	ret1 := sc.TrackRequest(req1)
	require.True(s.T(), ret1.Tracked)
	ret2 := sc.TrackRequest(req2)
	require.True(s.T(), ret2.Tracked)
	ret3 := sc.TrackRequest(req3)
	require.True(s.T(), ret3.Tracked)
	vals := sc.Inspect()
	require.Equal(s.T(), len(vals), 9)
	require.Contains(s.T(), vals, Tag("meta_www"))
	require.Equal(s.T(), vals[Tag("meta_www")], uint(2))
	require.Contains(s.T(), vals, Tag("TeamUserAssoc"))
	require.Equal(s.T(), vals[Tag("TeamUserAssoc")], uint(2))
	require.Contains(s.T(), vals, Tag("GID_10"))
	require.Equal(s.T(), vals[Tag("GID_10")], uint(1))
	require.Contains(s.T(), vals, Tag("Point_Read"))
	require.Equal(s.T(), vals[Tag("Point_Read")], uint(2))
	require.Contains(s.T(), vals, Tag("meta_api"))
	require.Equal(s.T(), vals[Tag("meta_api")], uint(1))
	require.Contains(s.T(), vals, Tag("UserEntity"))
	require.Equal(s.T(), vals[Tag("UserEntity")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_20"))
	require.Equal(s.T(), vals[Tag("GID_20")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_30"))
	require.Equal(s.T(), vals[Tag("GID_30")], uint(1))
	require.Contains(s.T(), vals, Tag("List_Read"))
	require.Equal(s.T(), vals[Tag("List_Read")], uint(1))
	ret3.Untrack()
	vals = sc.Inspect()
	require.Equal(s.T(), len(vals), 7)
	require.Contains(s.T(), vals, Tag("meta_www"))
	require.Equal(s.T(), vals[Tag("meta_www")], uint(1))
	require.Contains(s.T(), vals, Tag("TeamUserAssoc"))
	require.Equal(s.T(), vals[Tag("TeamUserAssoc")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_10"))
	require.Equal(s.T(), vals[Tag("GID_10")], uint(1))
	require.Contains(s.T(), vals, Tag("Point_Read"))
	require.Equal(s.T(), vals[Tag("Point_Read")], uint(2))
	require.Contains(s.T(), vals, Tag("meta_api"))
	require.Equal(s.T(), vals[Tag("meta_api")], uint(1))
	require.Contains(s.T(), vals, Tag("UserEntity"))
	require.Equal(s.T(), vals[Tag("UserEntity")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_20"))
	require.Equal(s.T(), vals[Tag("GID_20")], uint(1))
	ret2.Untrack()
	vals = sc.Inspect()
	require.Equal(s.T(), len(vals), 4)
	require.Contains(s.T(), vals, Tag("meta_www"))
	require.Equal(s.T(), vals[Tag("meta_www")], uint(1))
	require.Contains(s.T(), vals, Tag("TeamUserAssoc"))
	require.Equal(s.T(), vals[Tag("TeamUserAssoc")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_10"))
	require.Equal(s.T(), vals[Tag("GID_10")], uint(1))
	require.Contains(s.T(), vals, Tag("Point_Read"))
	require.Equal(s.T(), vals[Tag("Point_Read")], uint(1))
	ret1.Untrack()
	vals = sc.Inspect()
	require.Equal(s.T(), len(vals), 0)
}
func (s *ScorecardSuite) TestRepeatedUntrack() {
	req1 := []Tag{"meta_www", "TeamUserAssoc", "GID_10", "Point_Read"}
	req2 := []Tag{"meta_api", "UserEntity", "GID_20", "Point_Read"}
	req3 := []Tag{"meta_www", "TeamUserAssoc", "GID_30", "List_Read"}
	sc := NewScorecard([]Rule{})
	ret1 := sc.TrackRequest(req1)
	require.True(s.T(), ret1.Tracked)
	ret2 := sc.TrackRequest(req2)
	require.True(s.T(), ret2.Tracked)
	ret3 := sc.TrackRequest(req3)
	require.True(s.T(), ret3.Tracked)
	vals := sc.Inspect()
	require.Equal(s.T(), len(vals), 9)
	require.Contains(s.T(), vals, Tag("meta_www"))
	require.Equal(s.T(), vals[Tag("meta_www")], uint(2))
	require.Contains(s.T(), vals, Tag("TeamUserAssoc"))
	require.Equal(s.T(), vals[Tag("TeamUserAssoc")], uint(2))
	require.Contains(s.T(), vals, Tag("GID_10"))
	require.Equal(s.T(), vals[Tag("GID_10")], uint(1))
	require.Contains(s.T(), vals, Tag("Point_Read"))
	require.Equal(s.T(), vals[Tag("Point_Read")], uint(2))
	require.Contains(s.T(), vals, Tag("meta_api"))
	require.Equal(s.T(), vals[Tag("meta_api")], uint(1))
	require.Contains(s.T(), vals, Tag("UserEntity"))
	require.Equal(s.T(), vals[Tag("UserEntity")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_20"))
	require.Equal(s.T(), vals[Tag("GID_20")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_30"))
	require.Equal(s.T(), vals[Tag("GID_30")], uint(1))
	require.Contains(s.T(), vals, Tag("List_Read"))
	require.Equal(s.T(), vals[Tag("List_Read")], uint(1))
	ret3.Untrack()
	vals = sc.Inspect()
	require.Equal(s.T(), len(vals), 7)
	require.Contains(s.T(), vals, Tag("meta_www"))
	require.Equal(s.T(), vals[Tag("meta_www")], uint(1))
	require.Contains(s.T(), vals, Tag("TeamUserAssoc"))
	require.Equal(s.T(), vals[Tag("TeamUserAssoc")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_10"))
	require.Equal(s.T(), vals[Tag("GID_10")], uint(1))
	require.Contains(s.T(), vals, Tag("Point_Read"))
	require.Equal(s.T(), vals[Tag("Point_Read")], uint(2))
	require.Contains(s.T(), vals, Tag("meta_api"))
	require.Equal(s.T(), vals[Tag("meta_api")], uint(1))
	require.Contains(s.T(), vals, Tag("UserEntity"))
	require.Equal(s.T(), vals[Tag("UserEntity")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_20"))
	require.Equal(s.T(), vals[Tag("GID_20")], uint(1))
	ret3.Untrack()
	vals = sc.Inspect()
	require.Equal(s.T(), len(vals), 7)
	require.Contains(s.T(), vals, Tag("meta_www"))
	require.Equal(s.T(), vals[Tag("meta_www")], uint(1))
	require.Contains(s.T(), vals, Tag("TeamUserAssoc"))
	require.Equal(s.T(), vals[Tag("TeamUserAssoc")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_10"))
	require.Equal(s.T(), vals[Tag("GID_10")], uint(1))
	require.Contains(s.T(), vals, Tag("Point_Read"))
	require.Equal(s.T(), vals[Tag("Point_Read")], uint(2))
	require.Contains(s.T(), vals, Tag("meta_api"))
	require.Equal(s.T(), vals[Tag("meta_api")], uint(1))
	require.Contains(s.T(), vals, Tag("UserEntity"))
	require.Equal(s.T(), vals[Tag("UserEntity")], uint(1))
	require.Contains(s.T(), vals, Tag("GID_20"))
	require.Equal(s.T(), vals[Tag("GID_20")], uint(1))
}
func (s *ScorecardSuite) TestRegex() {
	var benchmarkRules = []Rule{
		{"traffic:live_traffic;source:metaserver*", 400},
		{"traffic:live_traffic;source:*", 50},
	}
	bc := NewScorecard(benchmarkRules)
	request := []Tag{
		"client_id:meta",
		"source:metaserver_courier_live_site-main.py",
		"traffic:live_traffic",
		"rpc_op:ep_add_or_get_for_ke",
		"datatype:PublicDomainSuffixEntity",
		"op:read_xtxn_conflict",
	}
	for i := 0; i < 51; i++ {
		info := bc.TrackRequest(request)
		require.Truef(s.T(), info.Tracked, "Violated: %s", info.Violated)
	}
}
func (s *ScorecardSuite) TestIsolatedRequest() {
	rules := []Rule{{"op:read", 2}}
	req1 := []Tag{"op:read", "gid:13"}
	req2 := []Tag{"op:read", "gid:42"}
	req3 := []Tag{"op:read", "gid:1337"}
	sc := NewScorecard(rules)
	ret1 := sc.TrackRequest(req1)
	require.True(s.T(), ret1.Tracked)
	vals := sc.Inspect()
	require.Equal(s.T(), len(vals), 2)
	require.Contains(s.T(), vals, Tag("op:read"))
	require.Equal(s.T(), vals[Tag("op:read")], uint(1))
	require.Contains(s.T(), vals, Tag("gid:13"))
	require.Equal(s.T(), vals[Tag("gid:13")], uint(1))
	ret2 := sc.TrackRequest(req2)
	require.True(s.T(), ret2.Tracked)
	vals = sc.Inspect()
	require.Equal(s.T(), len(vals), 3)
	require.Contains(s.T(), vals, Tag("op:read"))
	require.Equal(s.T(), vals[Tag("op:read")], uint(2))
	require.Contains(s.T(), vals, Tag("gid:13"))
	require.Equal(s.T(), vals[Tag("gid:13")], uint(1))
	require.Contains(s.T(), vals, Tag("gid:42"))
	require.Equal(s.T(), vals[Tag("gid:42")], uint(1))
	ret3 := sc.TrackRequest(req3)
	require.False(s.T(), ret3.Tracked)
	require.Equal(s.T(), ret3.Violated, Rule{"op:read", 2})
	require.Equal(s.T(), ret3.Value, uint(2))
	require.Equal(s.T(), ret3.Tag, Tag("op:read"))
	vals = sc.Inspect()
	require.Equal(s.T(), len(vals), 3)
	require.Contains(s.T(), vals, Tag("op:read"))
	require.Equal(s.T(), vals[Tag("op:read")], uint(2))
	require.Contains(s.T(), vals, Tag("gid:13"))
	require.Equal(s.T(), vals[Tag("gid:13")], uint(1))
	require.Contains(s.T(), vals, Tag("gid:42"))
	require.Equal(s.T(), vals[Tag("gid:42")], uint(1))
	ret3.Untrack()
	vals = sc.Inspect()
	require.Equal(s.T(), len(vals), 3)
	require.Contains(s.T(), vals, Tag("op:read"))
	require.Equal(s.T(), vals[Tag("op:read")], uint(2))
	require.Contains(s.T(), vals, Tag("gid:13"))
	require.Equal(s.T(), vals[Tag("gid:13")], uint(1))
	require.Contains(s.T(), vals, Tag("gid:42"))
	require.Equal(s.T(), vals[Tag("gid:42")], uint(1))
	ret1.Untrack()
	vals = sc.Inspect()
	require.Equal(s.T(), len(vals), 2)
	require.Contains(s.T(), vals, Tag("op:read"))
	require.Equal(s.T(), vals[Tag("op:read")], uint(1))
	require.Contains(s.T(), vals, Tag("gid:42"))
	require.Equal(s.T(), vals[Tag("gid:42")], uint(1))
	ret2.Untrack()
	vals = sc.Inspect()
	require.Equal(s.T(), len(vals), 0)
}