Merge pull request #601 from yaoshengzhe/fix_rename_queryrules_test

rename query rules and query rule info tests
This commit is contained in:
Shengzhe 2015-04-20 10:30:42 -07:00
Родитель b50603c10f 4f3a6d6cbe
Коммит 0199cf0de2
4 изменённых файлов: 191 добавлений и 9 удалений

Просмотреть файл

@ -36,7 +36,8 @@ func (qri *QueryRuleInfo) RegisterQueryRuleSource(ruleSource string) {
qri.mu.Lock()
defer qri.mu.Unlock()
if _, existed := qri.queryRulesMap[ruleSource]; existed {
log.Fatal("Query rule source " + ruleSource + " has been registered")
log.Errorf("Query rule source " + ruleSource + " has been registered")
panic("Query rule source " + ruleSource + " has been registered")
}
qri.queryRulesMap[ruleSource] = NewQueryRules()
}

Просмотреть файл

@ -33,7 +33,7 @@ func setupQueryRules() {
var qr *QueryRule
// mock keyrange rules
keyrangeRules = NewQueryRules()
dml_plans := []struct {
dmlPlans := []struct {
planID planbuilder.PlanType
onAbsent bool
}{
@ -43,7 +43,7 @@ func setupQueryRules() {
{planbuilder.PLAN_DML_PK, false},
{planbuilder.PLAN_DML_SUBQUERY, false},
}
for _, plan := range dml_plans {
for _, plan := range dmlPlans {
qr = NewQueryRule(
fmt.Sprintf("enforce keyspace_id range for %v", plan.planID),
fmt.Sprintf("keyspace_id_not_in_range_%v", plan.planID),
@ -71,6 +71,47 @@ func setupQueryRules() {
otherRules.Add(qr)
}
func TestQueryRuleInfoRegisterARegisteredSource(t *testing.T) {
setupQueryRules()
qri := NewQueryRuleInfo()
qri.RegisterQueryRuleSource(keyrangeQueryRules)
defer func() {
err := recover()
if err == nil {
t.Fatalf("should get an error for registering a registered query rule source ")
}
}()
qri.RegisterQueryRuleSource(keyrangeQueryRules)
}
func TestQueryRuleInfoSetRulesWithNil(t *testing.T) {
setupQueryRules()
qri := NewQueryRuleInfo()
qri.RegisterQueryRuleSource(keyrangeQueryRules)
err := qri.SetRules(keyrangeQueryRules, keyrangeRules)
if err != nil {
t.Errorf("Failed to set keyrange QueryRules : %s", err)
}
qrs, err := qri.GetRules(keyrangeQueryRules)
if err != nil {
t.Errorf("GetRules failed to retrieve keyrangeQueryRules that has been set: %s", err)
}
if !reflect.DeepEqual(qrs, keyrangeRules) {
t.Errorf("keyrangeQueryRules retrived is %v, but the expected value should be %v", qrs, keyrangeRules)
}
qri.SetRules(keyrangeQueryRules, nil)
qrs, err = qri.GetRules(keyrangeQueryRules)
if err != nil {
t.Errorf("GetRules failed to retrieve keyrangeQueryRules that has been set: %s", err)
}
if !reflect.DeepEqual(qrs, NewQueryRules()) {
t.Errorf("keyrangeQueryRules retrived is %v, but the expected value should be %v", qrs, keyrangeRules)
}
}
func TestQueryRuleInfoGetSetQueryRules(t *testing.T) {
setupQueryRules()
qri := NewQueryRuleInfo()

Просмотреть файл

@ -268,7 +268,7 @@ func (qr *QueryRule) AddBindVarCond(name string, onAbsent, onMismatch bool, op O
goto Error
}
case key.KeyRange:
if op < QR_IN && op > QR_NOTIN {
if op < QR_IN || op > QR_NOTIN {
goto Error
}
converted = bvcKeyRange(v)
@ -904,7 +904,7 @@ func buildBindVarCondition(bvc interface{}) (name string, onAbsent, onMismatch b
}
onMismatch, ok = v.(bool)
if !ok {
err = NewTabletError(ErrFail, "want bool for OnAbsent")
err = NewTabletError(ErrFail, "want bool for OnMismatch")
return
}
return

Просмотреть файл

@ -5,6 +5,7 @@
package tabletserver
import (
"encoding/json"
"regexp"
"strings"
"testing"
@ -30,6 +31,11 @@ func TestQueryRules(t *testing.T) {
t.Errorf("want:\n%#v\ngot:\n%#v", qr2, qrf)
}
qrf = qrs.Find("unknown_rule")
if qrf != nil {
t.Fatalf("rule: unknown_rule does not exist, should get nil")
}
if qrs.rules[0] != qr1 {
t.Errorf("want:\n%#v\ngot:\n%#v", qr1, qrs.rules[0])
}
@ -46,6 +52,11 @@ func TestQueryRules(t *testing.T) {
if qrs.rules[0] != qr2 {
t.Errorf("want:\n%#v\ngot:\n%#v", qr2, qrf)
}
qrf = qrs.Delete("unknown_rule")
if qrf != nil {
t.Fatalf("delete an unknown_rule, should return nil")
}
}
// TestCopy tests for deep copy
@ -425,6 +436,10 @@ var bvtestcases = []BindVarTestCase{
{BindVarCond{"a", true, true, QR_IN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, uint64(0), false},
{BindVarCond{"a", true, true, QR_IN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, uint64(0x5000000000000000), true},
{BindVarCond{"a", true, true, QR_IN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, uint64(0x7000000000000000), false},
{BindVarCond{"a", true, true, QR_IN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, int(-1), false},
{BindVarCond{"a", true, true, QR_IN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, int16(-1), false},
{BindVarCond{"a", true, true, QR_IN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, int32(-1), false},
{BindVarCond{"a", true, true, QR_IN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, int64(-1), false},
{BindVarCond{"a", true, true, QR_IN, strKeyRange("b", "d")}, "a", false},
{BindVarCond{"a", true, true, QR_IN, strKeyRange("b", "d")}, "c", true},
{BindVarCond{"a", true, true, QR_IN, strKeyRange("b", "d")}, "e", false},
@ -433,6 +448,10 @@ var bvtestcases = []BindVarTestCase{
{BindVarCond{"a", true, true, QR_NOTIN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, uint64(0), true},
{BindVarCond{"a", true, true, QR_NOTIN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, uint64(0x5000000000000000), false},
{BindVarCond{"a", true, true, QR_NOTIN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, uint64(0x7000000000000000), true},
{BindVarCond{"a", true, true, QR_NOTIN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, int(-1), true},
{BindVarCond{"a", true, true, QR_NOTIN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, int16(-1), true},
{BindVarCond{"a", true, true, QR_NOTIN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, int32(-1), true},
{BindVarCond{"a", true, true, QR_NOTIN, numKeyRange(0x4000000000000000, 0x6000000000000000)}, int64(-1), true},
{BindVarCond{"a", true, true, QR_NOTIN, strKeyRange("b", "d")}, "a", true},
{BindVarCond{"a", true, true, QR_NOTIN, strKeyRange("b", "d")}, "c", false},
{BindVarCond{"a", true, true, QR_NOTIN, strKeyRange("b", "d")}, "e", true},
@ -762,12 +781,11 @@ var invalidjsons = []InvalidJSONCase{
{`[{"BindVarConds": [{"Name": "a", "OnAbsent": true, "Operator": "SGE", "Value": 1}]}]`, "want string: 1"},
{`[{"BindVarConds": [{"Name": "a", "OnAbsent": true, "Operator": "SGT", "Value": 1}]}]`, "want string: 1"},
{`[{"BindVarConds": [{"Name": "a", "OnAbsent": true, "Operator": "SLE", "Value": 1}]}]`, "want string: 1"},
{`[{"BindVarConds": [{"Name": "a", "OnAbsent": true, "Operator": "MATCH", "Value": 1}]}]`, "want string: 1"},
{`[{"BindVarConds": [{"Name": "a", "OnAbsent": true, "Operator": "NOMATCH", "Value": 1}]}]`, "want string: 1"},
{`[{"BindVarConds": [{"Name": "a", "OnAbsent": true, "Operator": 123, "Value": "1"}]}]`, "want string for Operator"},
{`[{"Unknown": [{"Name": "a"}]}]`, "unrecognized tag Unknown"},
{`[{"BindVarConds": [{"Name": "a", "OnAbsent": true, "Operator": "ILE", "Value": "1"}]}]`, "OnMismatch missing in BindVarConds"},
{`[{"BindVarConds": [{"Name": "a", "OnAbsent": true, "OnMismatch": true, "Operator": "MATCH", "Value": "["}]}]`, "processing [: error parsing regexp: missing closing ]: `[$`"},
{`[{"BindVarConds": [{"Name": "a", "OnAbsent": true, "OnMismatch": true, "Operator": "NOMATCH", "Value": "["}]}]`, "processing [: error parsing regexp: missing closing ]: `[$`"},
{`[{"Action": 1 }]`, "want string for Action"},
@ -784,7 +802,129 @@ func TestInvalidJSON(t *testing.T) {
}
recvd := strings.Replace(err.Error(), "error: ", "", 1)
if recvd != tcase.err {
t.Errorf("want '%v', got '%v'", tcase.err, recvd)
t.Errorf("invalid json: %s, want '%v', got '%v'", tcase.input, tcase.err, recvd)
}
}
qrs := NewQueryRules()
err := qrs.UnmarshalJSON([]byte(`{`))
terr, ok := err.(*TabletError)
if !ok {
t.Fatalf("invalid json, should get a tablet error")
}
if terr.ErrorType != ErrFail {
t.Fatalf("should get ErrFail")
}
}
func TestBuildQueryRuleActionFail(t *testing.T) {
var ruleInfo map[string]interface{}
err := json.Unmarshal([]byte(`{"Action": "FAIL" }`), &ruleInfo)
if err != nil {
t.Fatalf("failed to unmarshal json, got error: %v", err)
}
qr, err := BuildQueryRule(ruleInfo)
if err != nil {
t.Fatalf("build query rule should succeed")
}
if qr.act != QR_FAIL {
t.Fatalf("action should fail")
}
}
func TestBuildQueryRuleFailureModes(t *testing.T) {
var err error
var errStr string
_, err = BuildQueryRule(map[string]interface{}{
"BindVarConds": []interface{}{map[string]interface{}{"Name": "a", "OnAbsent": true, "Operator": QR_IN, "Value": key.KeyRange{}}},
})
if err == nil {
t.Fatalf("should get an error")
}
errStr = strings.Replace(err.Error(), "error: ", "", 1)
if errStr != "want string for Operator" {
t.Fatalf("expect to get error: want string for Operator, but got: %v", err)
}
_, err = BuildQueryRule(map[string]interface{}{
"BindVarConds": []interface{}{map[string]interface{}{"Name": "a", "OnAbsent": true, "Operator": "IN", "Value": 1}},
})
if err == nil {
t.Fatalf("should get an error")
}
errStr = strings.Replace(err.Error(), "error: ", "", 1)
if errStr != "want keyrange for Value" {
t.Fatalf("expect to get error: want keyrange for Value, but got: %v", err)
}
_, err = BuildQueryRule(map[string]interface{}{
"BindVarConds": []interface{}{map[string]interface{}{"Name": "a", "OnAbsent": true, "Operator": "IN", "Value": map[string]interface{}{}}},
})
if err == nil {
t.Fatalf("should get an error")
}
errStr = strings.Replace(err.Error(), "error: ", "", 1)
if errStr != "Start missing in KeyRange" {
t.Fatalf("expect to get error: Start missing in KeyRange, but got: %v", err)
}
_, err = BuildQueryRule(map[string]interface{}{
"BindVarConds": []interface{}{map[string]interface{}{"Name": "a", "OnAbsent": true, "Operator": "IN", "Value": map[string]interface{}{"Start": 1}}},
})
if err == nil {
t.Fatalf("should get an error")
}
errStr = strings.Replace(err.Error(), "error: ", "", 1)
if errStr != "want string for Start" {
t.Fatalf("expect to get error: want string for Start, but got: %v", err)
}
_, err = BuildQueryRule(map[string]interface{}{
"BindVarConds": []interface{}{map[string]interface{}{"Name": "a", "OnAbsent": true, "Operator": "IN", "Value": map[string]interface{}{"Start": "1"}}},
})
if err == nil {
t.Fatalf("should get an error")
}
errStr = strings.Replace(err.Error(), "error: ", "", 1)
if errStr != "End missing in KeyRange" {
t.Fatalf("expect to get error: End missing in KeyRange, but got: %v", err)
}
_, err = BuildQueryRule(map[string]interface{}{
"BindVarConds": []interface{}{map[string]interface{}{"Name": "a", "OnAbsent": true, "Operator": "IN", "Value": map[string]interface{}{"Start": "1", "End": 2}}},
})
if err == nil {
t.Fatalf("should get an error")
}
errStr = strings.Replace(err.Error(), "error: ", "", 1)
if errStr != "want string for End" {
t.Fatalf("expect to get error: want string for End, but got: %v", err)
}
_, err = BuildQueryRule(map[string]interface{}{
"BindVarConds": []interface{}{map[string]interface{}{"Name": "a", "OnAbsent": true, "OnMismatch": "invalid", "Operator": "IN", "Value": map[string]interface{}{"Start": "1", "End": "2"}}},
})
if err == nil {
t.Fatalf("should get an error")
}
errStr = strings.Replace(err.Error(), "error: ", "", 1)
if errStr != "want bool for OnMismatch" {
t.Fatalf("expect to get error: want bool for OnMismatch, but got: %v", err)
}
}
func TestBadAddBindVarCond(t *testing.T) {
qr1 := NewQueryRule("rule 1", "r1", QR_FAIL)
err := qr1.AddBindVarCond("a", true, false, QR_MATCH, uint64(1))
if err == nil {
t.Fatalf("invalid op: QR_MATCH for value type: uint64")
}
err = qr1.AddBindVarCond("a", true, false, QR_NOTIN, "test")
if err == nil {
t.Fatalf("invalid op: QR_NOTIN for value type: string")
}
err = qr1.AddBindVarCond("a", true, false, QR_LT, key.KeyRange{})
if err == nil {
t.Fatalf("invalid op: QR_LT for value type: key.KeyRange")
}
}