diff --git a/covertest/client.go b/covertest/client.go index 631c527..c7eb848 100644 --- a/covertest/client.go +++ b/covertest/client.go @@ -1,12 +1,8 @@ package covertest import ( - "fmt" - "os" - "strings" "testing" - "github.com/nspcc-dev/neo-go/pkg/compiler" "github.com/nspcc-dev/neo-go/pkg/core" "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/transaction" @@ -135,110 +131,3 @@ func TestInvoke(bc *core.Blockchain, tx *transaction.Transaction) ([]InstrHash, ops, err := Run(ic.VM) return ops, ic.VM, err } - -type coverline struct { - Doc string - Opcode int - StartLine int - StartCol int - EndLine int - EndCol int - WTFnumber int - IsCovered bool -} - -// MakeCoverage generates an output file with coverage info in correct format -func (c *ContractInvoker) MakeCoverage(t testing.TB, ctrdi *ContractWithDebugInfo, ctrPath string, fileName string) { - docs := getDocuments(t, ctrdi.DebugInfo.Documents, ctrPath) - cov := getSeqPoints(t, ctrdi.DebugInfo, docs) - for _, iMethod := range c.Methods { - countInstructions(cov, iMethod.Instructions) - } - printToFile(t, cov, fileName) -} - -func getDocuments(t testing.TB, docs []string, substr string) []int { - res := make([]int, 0, len(docs)) - - for i, cDoc := range docs { - if strings.Contains(cDoc, substr) { - res = append(res, i) - } - } - if len(res) == 0 { - t.Log("Cannot get document\n") - t.FailNow() - } - return res -} - -func getSeqPoints(t testing.TB, di *compiler.DebugInfo, docs []int) []coverline { - res := make([]coverline, 0, 10) - - for _, method := range di.Methods { - maxLine := method.Range.End - for _, seqPoint := range method.SeqPoints { - if isValidDocument(seqPoint.Document, docs) && seqPoint.Opcode < int(maxLine) { - res = append(res, coverline{ - Doc: di.Documents[seqPoint.Document], - Opcode: seqPoint.Opcode, - StartLine: seqPoint.StartLine, - StartCol: seqPoint.StartCol, - EndLine: seqPoint.EndLine, - EndCol: seqPoint.EndCol, - WTFnumber: 1, - IsCovered: false, - }) - } - } - } - return res -} - -func isValidDocument(iDocToCheck int, docs []int) bool { - for _, iDoc := range docs { - if iDoc == iDocToCheck { - return true - } - } - return false -} - -func countInstructions(cov []coverline, codes []InstrHash) { - for i := 0; i < len(cov); i++ { - for _, code := range codes { - if code.Offset == cov[i].Opcode { - cov[i].IsCovered = true - //cov[i].WTFnumber++ - //break - } - } - } -} - -func printToFile(t testing.TB, cov []coverline, name string) { - f, err := os.OpenFile(name, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) - require.NoError(t, err) - - defer f.Close() - - fi, err := os.Stat(name) - require.NoError(t, err) - firstToWrite := "" - if fi.Size() == 0 { - firstToWrite = "mode: set\n" - } - - _, err = f.WriteString(firstToWrite) - require.NoError(t, err) - - for _, info := range cov { - covered := 0 - if info.IsCovered { - covered++ - } - line := fmt.Sprintf("%s:%d.%d,%d.%d %d %d\n", info.Doc, info.StartLine, info.StartCol, info.EndLine, info.EndCol, info.WTFnumber, covered) - _, err = f.WriteString(line) - require.NoError(t, err) - } -} diff --git a/covertest/cover.go b/covertest/cover.go new file mode 100644 index 0000000..c76acc3 --- /dev/null +++ b/covertest/cover.go @@ -0,0 +1,118 @@ +package covertest + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/nspcc-dev/neo-go/pkg/compiler" + "github.com/stretchr/testify/require" +) + +type coverline struct { + Doc string + Opcode int + StartLine int + StartCol int + EndLine int + EndCol int + WTFnumber int + IsCovered bool +} + +// MakeCoverage generates an output file with coverage info in correct format +func (c *ContractInvoker) MakeCoverage(t testing.TB, ctrdi *ContractWithDebugInfo, ctrPath string, fileName string) { + docs := getDocuments(t, ctrdi.DebugInfo.Documents, ctrPath) + cov := getSeqPoints(t, ctrdi.DebugInfo, docs) + for _, iMethod := range c.Methods { + countInstructions(cov, iMethod.Instructions) + } + printToFile(t, cov, fileName) +} + +func getDocuments(t testing.TB, docs []string, substr string) []int { + res := make([]int, 0, len(docs)) + + for i, cDoc := range docs { + if strings.Contains(cDoc, substr) { + res = append(res, i) + } + } + if len(res) == 0 { + t.Log("Cannot get document\n") + t.FailNow() + } + return res +} + +func getSeqPoints(t testing.TB, di *compiler.DebugInfo, docs []int) []coverline { + res := make([]coverline, 0, 10) + + for _, method := range di.Methods { + maxLine := method.Range.End + for _, seqPoint := range method.SeqPoints { + if isValidDocument(seqPoint.Document, docs) && seqPoint.Opcode < int(maxLine) { + res = append(res, coverline{ + Doc: di.Documents[seqPoint.Document], + Opcode: seqPoint.Opcode, + StartLine: seqPoint.StartLine, + StartCol: seqPoint.StartCol, + EndLine: seqPoint.EndLine, + EndCol: seqPoint.EndCol, + WTFnumber: 1, + IsCovered: false, + }) + } + } + } + return res +} + +func isValidDocument(iDocToCheck int, docs []int) bool { + for _, iDoc := range docs { + if iDoc == iDocToCheck { + return true + } + } + return false +} + +func countInstructions(cov []coverline, codes []InstrHash) { + for i := 0; i < len(cov); i++ { + for _, code := range codes { + if code.Offset == cov[i].Opcode { + cov[i].IsCovered = true + //cov[i].WTFnumber++ + //break + } + } + } +} + +func printToFile(t testing.TB, cov []coverline, name string) { + f, err := os.OpenFile(name, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + require.NoError(t, err) + + defer f.Close() + + fi, err := os.Stat(name) + require.NoError(t, err) + firstToWrite := "" + if fi.Size() == 0 { + firstToWrite = "mode: set\n" + } + + _, err = f.WriteString(firstToWrite) + require.NoError(t, err) + + for _, info := range cov { + covered := 0 + if info.IsCovered { + covered++ + } + line := fmt.Sprintf("%s:%d.%d,%d.%d %d %d\n", info.Doc, info.StartLine, info.StartCol, info.EndLine, info.EndCol, info.WTFnumber, covered) + _, err = f.WriteString(line) + require.NoError(t, err) + } +}