Skip to content

Commit

Permalink
*: replace Err with Unknown and remove register verifier to model (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
overvenus authored and siddontang committed Jul 12, 2018
1 parent 150e501 commit b9593a5
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 60 deletions.
2 changes: 1 addition & 1 deletion cmd/rawkv/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var (
clientCase = flag.String("case", "register", "client test case, like bank,multi_bank")
historyFile = flag.String("history", "./history.log", "history file")
nemesises = flag.String("nemesis", "", "nemesis, seperated by name, like random_kill,all_kill")
verifyNames = flag.String("verifiers", "", "verifier names, seperate by comma, rawkv_register")
verifyNames = flag.String("verifiers", "", "verifier names, seperate by comma, register")
)

func main() {
Expand Down
6 changes: 3 additions & 3 deletions cmd/verifier/verify/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"log"
"strings"

"github.com/siddontang/chaos/db/rawkv"
"github.com/siddontang/chaos/db/tidb"
"github.com/siddontang/chaos/pkg/history"
"github.com/siddontang/chaos/pkg/model"
)

// Verify creates the verifier from verifer_names and verfies the history file.
Expand All @@ -21,8 +21,8 @@ func Verify(ctx context.Context, historyFile string, verfier_names string) {
verifier = tidb.BankVerifier{}
case "tidb_bank_tso":
verifier = tidb.BankTsoVerifier{}
case "rawkv_register":
verifier = rawkv.RegisterVerifier{}
case "register":
verifier = model.RegisterVerifier{}
case "":
continue
default:
Expand Down
43 changes: 2 additions & 41 deletions db/rawkv/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package rawkv

import (
"context"
"encoding/json"
"fmt"
"log"
"math/rand"
Expand All @@ -16,7 +15,6 @@ import (
// use mysql
_ "github.com/go-sql-driver/mysql"
"github.com/siddontang/chaos/pkg/core"
"github.com/siddontang/chaos/pkg/history"
"github.com/siddontang/chaos/pkg/model"
)

Expand Down Expand Up @@ -58,7 +56,7 @@ func (c *registerClient) TearDown(ctx context.Context, nodes []string, node stri
func (c *registerClient) invokeRead(ctx context.Context, r model.RegisterRequest) model.RegisterResponse {
val, err := c.db.Get(register)
if err != nil {
return model.RegisterResponse{Err: err}
return model.RegisterResponse{Unknown: true}
}
v, err := strconv.ParseInt(string(val), 10, 64)
if err != nil {
Expand All @@ -76,7 +74,7 @@ func (c *registerClient) Invoke(ctx context.Context, node string, r interface{})
val := fmt.Sprintf("%d", arg.Value)
err := c.db.Put(register, []byte(val))
if err != nil {
return model.RegisterResponse{Err: err}
return model.RegisterResponse{Unknown: true}
}
return model.RegisterResponse{}
}
Expand All @@ -101,29 +99,6 @@ func newRegisterEvent(v interface{}, id uint) porcupine.Event {
return porcupine.Event{Kind: porcupine.ReturnEvent, Value: v, Id: id}
}

// TODO: maybe we can put the paser under the package `pkg/model`.
type registerParser struct {
}

func (p registerParser) OnRequest(data json.RawMessage) (interface{}, error) {
r := model.RegisterRequest{}
err := json.Unmarshal(data, &r)
return r, err
}

func (p registerParser) OnResponse(data json.RawMessage) (interface{}, error) {
r := model.RegisterResponse{}
err := json.Unmarshal(data, &r)
if r.Err != nil {
return nil, err
}
return r, err
}

func (p registerParser) OnNoopResponse() interface{} {
return model.RegisterResponse{Err: fmt.Errorf("dummy error")}
}

// RegisterClientCreator creates a register test client for rawkv.
type RegisterClientCreator struct {
}
Expand All @@ -132,17 +107,3 @@ type RegisterClientCreator struct {
func (RegisterClientCreator) Create(node string) core.Client {
return &registerClient{}
}

// RegisterVerifier verifies the register history.
type RegisterVerifier struct {
}

// Verify verifies the register history.
func (RegisterVerifier) Verify(historyFile string) (bool, error) {
return history.VerifyHistory(historyFile, model.RegisterModel(), registerParser{})
}

// Name returns the name of the verifier.
func (RegisterVerifier) Name() string {
return "register_verifier"
}
45 changes: 42 additions & 3 deletions pkg/model/register.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package model

import (
"encoding/json"

"github.com/anishathalye/porcupine"
"github.com/siddontang/chaos/pkg/history"
)

// Op is an operation.
Expand All @@ -22,8 +25,8 @@ type RegisterRequest struct {

// RegisterResponse is the response returned by a register.
type RegisterResponse struct {
Err error
Value int
Unknown bool
Value int
}

// RegisterModel returns a read/write register model
Expand All @@ -40,7 +43,7 @@ func RegisterModel() porcupine.Model {

// read
if inp.Op == RegisterRead {
ok := out.Value == st || out.Err != nil
ok := out.Value == st || out.Unknown
return ok, st
}

Expand All @@ -55,3 +58,39 @@ func RegisterModel() porcupine.Model {
},
}
}

type registerParser struct {
}

func (p registerParser) OnRequest(data json.RawMessage) (interface{}, error) {
r := RegisterRequest{}
err := json.Unmarshal(data, &r)
return r, err
}

func (p registerParser) OnResponse(data json.RawMessage) (interface{}, error) {
r := RegisterResponse{}
err := json.Unmarshal(data, &r)
if r.Unknown {
return nil, err
}
return r, nil
}

func (p registerParser) OnNoopResponse() interface{} {
return RegisterResponse{Unknown: true}
}

// RegisterVerifier can verify a register history.
type RegisterVerifier struct {
}

// Verify verifies a register history.
func (RegisterVerifier) Verify(historyFile string) (bool, error) {
return history.VerifyHistory(historyFile, RegisterModel(), registerParser{})
}

// Name returns the name of the verifier.
func (RegisterVerifier) Name() string {
return "register_verifier"
}
79 changes: 67 additions & 12 deletions pkg/model/register_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package model

import (
"encoding/json"
"testing"

"github.com/anishathalye/porcupine"
Expand All @@ -12,9 +13,9 @@ func TestRegisterModel(t *testing.T) {
// section VII

ops := []porcupine.Operation{
{RegisterRequest{RegisterWrite, 100}, 0, RegisterResponse{nil, 0}, 100},
{RegisterRequest{RegisterRead, 0}, 25, RegisterResponse{nil, 100}, 75},
{RegisterRequest{RegisterRead, 0}, 30, RegisterResponse{nil, 0}, 60},
{RegisterRequest{RegisterWrite, 100}, 0, RegisterResponse{false, 0}, 100},
{RegisterRequest{RegisterRead, 0}, 25, RegisterResponse{false, 100}, 75},
{RegisterRequest{RegisterRead, 0}, 30, RegisterResponse{false, 0}, 60},
}
res := porcupine.CheckOperations(RegisterModel(), ops)
if res != true {
Expand All @@ -26,19 +27,19 @@ func TestRegisterModel(t *testing.T) {
{porcupine.CallEvent, RegisterRequest{RegisterWrite, 100}, 0},
{porcupine.CallEvent, RegisterRequest{RegisterRead, 0}, 1},
{porcupine.CallEvent, RegisterRequest{RegisterRead, 0}, 2},
{porcupine.ReturnEvent, RegisterResponse{nil, 0}, 2},
{porcupine.ReturnEvent, RegisterResponse{nil, 100}, 1},
{porcupine.ReturnEvent, RegisterResponse{nil, 0}, 0},
{porcupine.ReturnEvent, RegisterResponse{false, 0}, 2},
{porcupine.ReturnEvent, RegisterResponse{false, 100}, 1},
{porcupine.ReturnEvent, RegisterResponse{false, 0}, 0},
}
res = porcupine.CheckEvents(RegisterModel(), events)
if res != true {
t.Fatal("expected operations to be linearizable")
}

ops = []porcupine.Operation{
{RegisterRequest{RegisterWrite, 200}, 0, RegisterResponse{nil, 0}, 100},
{RegisterRequest{RegisterRead, 0}, 10, RegisterResponse{nil, 200}, 30},
{RegisterRequest{RegisterRead, 0}, 40, RegisterResponse{nil, 0}, 90},
{RegisterRequest{RegisterWrite, 200}, 0, RegisterResponse{false, 0}, 100},
{RegisterRequest{RegisterRead, 0}, 10, RegisterResponse{false, 200}, 30},
{RegisterRequest{RegisterRead, 0}, 40, RegisterResponse{false, 0}, 90},
}
res = porcupine.CheckOperations(RegisterModel(), ops)
if res != false {
Expand All @@ -49,13 +50,67 @@ func TestRegisterModel(t *testing.T) {
events = []porcupine.Event{
{porcupine.CallEvent, RegisterRequest{RegisterWrite, 200}, 0},
{porcupine.CallEvent, RegisterRequest{RegisterRead, 0}, 1},
{porcupine.ReturnEvent, RegisterResponse{nil, 200}, 1},
{porcupine.ReturnEvent, RegisterResponse{false, 200}, 1},
{porcupine.CallEvent, RegisterRequest{RegisterRead, 0}, 2},
{porcupine.ReturnEvent, RegisterResponse{nil, 0}, 2},
{porcupine.ReturnEvent, RegisterResponse{nil, 0}, 0},
{porcupine.ReturnEvent, RegisterResponse{false, 0}, 2},
{porcupine.ReturnEvent, RegisterResponse{false, 0}, 0},
}
res = porcupine.CheckEvents(RegisterModel(), events)
if res != false {
t.Fatal("expected operations to not be linearizable")
}
}

func TestRegisterParser(t *testing.T) {
parser := registerParser{}

for _, c := range []struct {
data []byte
req RegisterRequest
}{
{[]byte(`{"Op":false,"Value":0}`),
RegisterRequest{RegisterRead, 0}},
{[]byte(`{"Op":true,"Value":5135627519135374257}`),
RegisterRequest{RegisterWrite, 5135627519135374257}},
} {
raw := json.RawMessage{}
if err := json.Unmarshal(c.data, &raw); err != nil {
t.Fatalf("unexpected err: %v, req: %v", err, c.req)
}
r, err := parser.OnRequest(raw)
if err != nil {
t.Fatalf("unexpected err: %v, req: %v", err, c.req)
}
req := r.(RegisterRequest)
if req.Op != c.req.Op || req.Value != c.req.Value {
t.Fatalf("expected equal: %v, req: %v", req, c.req)
}
}

for _, c := range []struct {
data []byte
resp RegisterResponse
}{
{[]byte(`{"Unknown":false,"Value":0}`),
RegisterResponse{false, 0}},
{[]byte(`{"Unknown":false,"Value":5135627519135374257}`),
RegisterResponse{false, 5135627519135374257}},
{[]byte(`{"Unknown":true,"Value":7}`),
RegisterResponse{true, 7}},
} {
raw := json.RawMessage{}
if err := json.Unmarshal(c.data, &raw); err != nil {
t.Fatalf("unexpected err: %v, resp: %v", err, c.resp)
}
r, err := parser.OnResponse(raw)
if err != nil {
t.Fatalf("unexpected err: %v, resp: %v", err, c.resp)
}
if r != nil {
resp := r.(RegisterResponse)
if resp.Value != c.resp.Value || resp.Unknown != c.resp.Unknown {
t.Fatalf("expected equal: %v != %v", resp, c.resp)
}
}
}
}

0 comments on commit b9593a5

Please sign in to comment.