Skip to content

Commit

Permalink
fix(store): fix inf.Dec and big.Int compare
Browse files Browse the repository at this point in the history
changes in check of responses rows procces:
*rows data unmarshalling into byte slices.
*rows data compare as byte slices, without transformation to 'GO' types.
*rows diff information now more user friendly and can be customed. Diff collect row by row to string slice and can be transferred anywhere with better readable.
  • Loading branch information
illia-li committed Dec 9, 2023
1 parent 16a7413 commit d04ca41
Show file tree
Hide file tree
Showing 37 changed files with 3,642 additions and 160 deletions.
123 changes: 123 additions & 0 deletions pkg/store/comp/compare_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright 2019 ScyllaDB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package comp

import (
"fmt"
"strings"
)

// Info contains information about responses difference.
type Info []string

func (d *Info) Len() int {
return len(*d)
}

func (d *Info) Add(in ...string) {
*d = append(*d, in...)
}

func (d *Info) String() string {
return strings.Join(*d, "\n")
}

func GetCompareInfoSimple(d Results) Info {
lenTest := d.LenRowsTest()
lenOracle := d.LenRowsOracle()
switch {
case lenTest == 0 && lenOracle == 0:
return nil
// responses don`t have rows
case lenTest == lenOracle:
// responses have rows and have same rows count
equalRowsCount := equalRowsSameLen(d)
// equalRowsSameLen function simultaneously deletes equal rows in Test and Oracle stores.
// So we can check rows only one of the stores.
if d.LenRowsTest() < 1 {
return nil
}
return Info{fmt.Sprintf("responses have %d equal rows and unequal rows %d", equalRowsCount, d.LenRowsTest())}
default:
// responses have different rows count
return Info{fmt.Sprintf("different rows count in responses: from test store-%d, from oracle store-%d", lenTest, lenOracle)}
}
}

func GetCompareInfoDetailed(d Results) Info {
lenTest := d.LenRowsTest()
lenOracle := d.LenRowsOracle()
switch {
case lenTest == 0 && lenOracle == 0:
return nil
// responses don`t have rows
case lenTest < 1 || lenOracle < 1:
// one of the responses without rows.
diff := make(Info, 0)
diff.Add(fmt.Sprintf("different rows count in responses: from test store-%d, from oracle store-%d", lenTest, lenOracle))
diff.Add(d.StringAllRows("unequal")...)
return diff
case lenTest == lenOracle:
// responses have rows and have same rows count
equalRowsCount := equalRowsSameLen(d)
// equalRowsSameLen function simultaneously deletes equal rows in Test and Oracle stores.
// So we can check rows only one of the stores.
if d.LenRowsTest() < 1 {
return nil
}
diff := make(Info, 0)
diff.Add(fmt.Sprintf("responses have %d equal rows and unequal rows: test store %d; oracle store %d", equalRowsCount, d.LenRowsTest(), d.LenRowsOracle()))
diff.Add(d.StringAllRows("unequal")...)
return diff
default:
// responses have rows and have different rows count
diff := make(Info, 0)
equalRowsCount := equalRowsDiffLen(d)
diff.Add(fmt.Sprintf("responses have %d equal rows and unequal rows: test store %d; oracle store %d", equalRowsCount, d.LenRowsTest(), d.LenRowsOracle()))
diff.Add(d.StringAllRows("unequal")...)
return diff
}
}

// equalRowsSameLen returns count of equal rows of stores simultaneously deletes equal rows.
// Applies when oracle and test stores have same rows count.
func equalRowsSameLen(d Results) int {
if d.LenRowsTest() == 1 {
return d.EqualSingeRow()
}
equalRowsCount := d.EasyEqualRowsTest()
if d.LenRowsTest() != 0 {
equalRowsCount += d.EqualRowsTest()
}
return equalRowsCount
}

// equalRowsDiffLen returns count of equal rows of stores simultaneously deletes equal rows.
// Applies when oracle and test stores have different rows count.
func equalRowsDiffLen(d Results) int {
equalRowsCount := 0
if d.LenRowsTest() > d.LenRowsOracle() {
equalRowsCount = d.EasyEqualRowsOracle()
if d.LenRowsOracle() > 0 {
equalRowsCount += d.EqualRowsOracle()
}
} else {
equalRowsCount = d.EasyEqualRowsTest()
if d.LenRowsTest() > 0 {
equalRowsCount += d.EqualRowsTest()
}
}
return equalRowsCount
}
137 changes: 137 additions & 0 deletions pkg/store/comp/compare_info_mv_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright 2019 ScyllaDB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//nolint:thelper

package comp

import (
"fmt"
"testing"

"github.com/scylladb/gemini/pkg/store/mv"
"github.com/scylladb/gemini/pkg/store/sv"
)

func TestGetCompareInfoMV(t *testing.T) {
var test mv.Results
for idx := range testCases {
tests := 2
if testCases[idx].diffs > 0 {
tests = 4
}
for tests > 0 {
test.Test.Rows, test.Oracle.Rows, test.Test.Types, test.Oracle.Types = rndSameRowsMV(testCases[idx].test, testCases[idx].oracle)
// Add names
if len(test.Test.Rows) > 0 {
test.Test.Names = make([]string, len(test.Test.Rows[0]))
for col := range test.Test.Rows[0] {
test.Test.Names[col] = fmt.Sprintf("col%d", col)
}
}
if len(test.Oracle.Rows) > 0 {
test.Oracle.Names = make([]string, len(test.Oracle.Rows[0]))
for col := range test.Oracle.Rows[0] {
test.Oracle.Names[col] = fmt.Sprintf("col%d", col)
}
}
if testCases[idx].diffs > 0 {
if tests%2 == 0 {
corruptRows(&test.Test.Rows, testCases[idx].diffs)
} else {
corruptRows(&test.Oracle.Rows, testCases[idx].diffs)
}
}
result := Info{}
errFuncName := "GetCompareInfoDetailed"
if tests%2 == 0 {
errFuncName = "GetCompareInfoSimple"
result = GetCompareInfoSimple(&test)
} else {
result = GetCompareInfoDetailed(&test)
}
if len(result) > 0 && !testCases[idx].haveDif {
t.Fatalf("wrong %s work. test case:%+v \nresult should be empty, but have:%s\n"+
"mv.Results.Test.Rows:%+v\n"+
"mv.Results.Oracle.Rows:%+v", errFuncName, testCases[idx], result, test.Test.Rows, test.Oracle.Rows)
}
if len(result) == 0 && testCases[idx].haveDif {
t.Fatalf("wrong %s work. test case:%+v \nresult should be not empty\n"+
"mv.Results.Test.Rows:%+v\n"+
"mv.Results.Oracle.Rows:%+v", errFuncName, testCases[idx], test.Test.Rows, test.Oracle.Rows)
}
if len(result) > 0 {
fmt.Printf("%s from mv.Results of test case:%+v\n", errFuncName, testCases[idx])
fmt.Println(result.String())
}
tests--
}
}
}

func TestGetCompareInfoSV(t *testing.T) {
var test sv.Results
for idx := range testCases {
tests := 2
if testCases[idx].diffs > 0 {
tests = 4
}
for tests > 0 {
test.Test.Rows, test.Oracle.Rows, test.Test.Types, test.Oracle.Types = rndSameRowsSV(testCases[idx].test, testCases[idx].oracle)
// Add names
if len(test.Test.Rows) > 0 {
test.Test.Names = make([]string, len(test.Test.Rows[0]))
for col := range test.Test.Rows[0] {
test.Test.Names[col] = fmt.Sprintf("col%d", col)
}
}
if len(test.Oracle.Rows) > 0 {
test.Oracle.Names = make([]string, len(test.Oracle.Rows[0]))
for col := range test.Oracle.Rows[0] {
test.Oracle.Names[col] = fmt.Sprintf("col%d", col)
}
}
if testCases[idx].diffs > 0 {
if tests%2 == 0 {
corruptRowsSV(&test.Test.Rows, testCases[idx].diffs)
} else {
corruptRowsSV(&test.Oracle.Rows, testCases[idx].diffs)
}
}
result := Info{}
errFuncName := "GetCompareInfoDetailed"
if tests%2 == 0 {
errFuncName = "GetCompareInfoSimple"
result = GetCompareInfoSimple(&test)
} else {
result = GetCompareInfoDetailed(&test)
}
if len(result) > 0 && !testCases[idx].haveDif {
t.Fatalf("wrong %s work. test case:%+v \nresult should be empty, but have:%s\n"+
"mv.Results.Test.Rows:%+v\n"+
"mv.Results.Oracle.Rows:%+v", errFuncName, testCases[idx], result, test.Test.Rows, test.Oracle.Rows)
}
if len(result) == 0 && testCases[idx].haveDif {
t.Fatalf("wrong %s work. test case:%+v \nresult should be not empty\n"+
"mv.Results.Test.Rows:%+v\n"+
"mv.Results.Oracle.Rows:%+v", errFuncName, testCases[idx], test.Test.Rows, test.Oracle.Rows)
}
if len(result) > 0 {
fmt.Printf("%s from mv.Results of test case:%+v\n", errFuncName, testCases[idx])
fmt.Println(result.String())
}
tests--
}
}
}
44 changes: 44 additions & 0 deletions pkg/store/comp/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2019 ScyllaDB
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package comp

// Results interface for comparison Test and Oracle rows
type Results interface {
// EqualSingeRow equals fist rows and deletes if equal, returns count of equal rows.
// Equals only the first Oracle and Test rows without `for` cycle.
// Most responses have only one row.
EqualSingeRow() int

// EasyEqualRowsTest returns count of equal rows into stores simultaneously deletes equal rows.
// Most cases have no difference between Oracle and Test rows, therefore the fastest compare way to compare
// Test and Oracle responses row by row.
// Travels through Test rows.
EasyEqualRowsTest() int
// EasyEqualRowsOracle same as EasyEqualRowsTest, but travels through Oracle rows.
EasyEqualRowsOracle() int

// EqualRowsTest equals all rows and deletes if equal, returns count of equal rows.
// For cases then EasyEqualRowsTest did not bring full success.
// Travels through Test rows.
EqualRowsTest() int
// EqualRowsOracle same as EqualRowsTest, but travels through Oracle rows.
EqualRowsOracle() int

LenRowsOracle() int
LenRowsTest() int

StringAllRows(prefix string) []string
HaveRows() bool
}
Loading

0 comments on commit d04ca41

Please sign in to comment.