Skip to content

Commit

Permalink
moving newFeature related code from serializePR
Browse files Browse the repository at this point in the history
  • Loading branch information
aslesarenko authored and kushti committed Jun 8, 2024
1 parent 2baf8ca commit e7bd2a3
Show file tree
Hide file tree
Showing 11 changed files with 634 additions and 398 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ import org.ergoplatform.ErgoBox.RegisterId
import org.ergoplatform.settings.ErgoAlgos
import pprint.{PPrinter, Tree}
import sigma.ast.SCollection.{SBooleanArray, SByteArray, SByteArray2}
import sigma.ast._
import sigma.ast.{ConstantNode, FuncValue, MethodCall, ValueCompanion, _}
import sigma.crypto.EcPointType
import sigma.data.{AvlTreeData, AvlTreeFlags, CollType, PrimitiveType, TrivialProp}
import sigma.serialization.GroupElementSerializer
import sigma.{Coll, GroupElement}
import sigma.ast.{ConstantNode, FuncValue, ValueCompanion}
import sigmastate._
import sigmastate.crypto.GF2_192_Poly
import sigma.ast.MethodCall

import java.math.BigInteger
import scala.collection.compat.immutable.ArraySeq
import scala.collection.mutable
Expand Down
6 changes: 6 additions & 0 deletions parsers/shared/src/test/scala/sigmastate/lang/LangTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,10 @@ trait LangTests extends Matchers with NegativeTesting {
node
}))(tree)
}

/** Execute the given `block` having `version` as both activated and ErgoTree version. */
def runWithVersion[T](version: Byte)(block: => T): T = {
VersionContext.withVersions(version, version)(block)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import SigmaPredef.PredefinedFuncRegistry
import sigma.ast.syntax._
import sigmastate.lang.parsers.ParserException
import sigma.serialization.OpCodes
import sigmastate.helpers.SigmaPPrint

class SigmaParserTest extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with LangTests {
import StdSigmaBuilder._
Expand All @@ -34,6 +35,17 @@ class SigmaParserTest extends AnyPropSpec with ScalaCheckPropertyChecks with Mat
}
}

/** Checks parsing result, printing the actual value as a test vector if expected value
* is not equal to actual.
*/
def checkParsed(x: String, expected: SValue) = {
val parsed = parse(x)
if (expected != parsed) {
SigmaPPrint.pprintln(parsed, width = 100)
}
parsed shouldBe expected
}

def parseWithException(x: String): SValue = {
SigmaParser(x) match {
case Parsed.Success(v, _) => v
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import sigma.SigmaDslTesting
import sigma.ast._
import sigma.data.{AvlTreeData, AvlTreeFlags, CBox, CollType, Digest32Coll}
import ErgoTree.HeaderType
import sigmastate.eval._
import sigma.ast.MethodCall
import sigma.serialization.OpCodes
import sigmastate.utils.Helpers
Expand Down
126 changes: 126 additions & 0 deletions sc/shared/src/test/scala/sigma/LanguageSpecificationBase.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package sigma

import org.scalatest.BeforeAndAfterAll
import sigma.ast.JitCost
import sigma.eval.{EvalSettings, Profiler}
import sigmastate.CompilerCrossVersionProps
import sigmastate.interpreter.CErgoTreeEvaluator
import scala.util.Success

/** Base class for language test suites (one suite for each language version: 5.0, 6.0, etc.)
* Each suite tests every method of every SigmaDsl type to be equivalent to
* the evaluation of the corresponding ErgoScript operation.
*
* The properties of this suite exercise two interpreters: the current (aka `old`
* interpreter) and the new interpreter for a next soft-fork. After the soft-fork is
* released, the new interpreter becomes current at which point the `old` and `new`
* interpreters in this suite should be equivalent. This change is reflected in this
* suite by commiting changes in expected values.
* The `old` and `new` interpreters are compared like the following:
* 1) for existingFeature the interpreters should be equivalent
* 2) for changedFeature the test cases contain different expected values
* 3) for newFeature the old interpreter should throw and the new interpreter is checked
* against expected values.
*
* This suite can be used for Cost profiling, i.e. measurements of operations times and
* comparing them with cost parameters of the operations.
*
* The following settings should be specified for profiling:
* isMeasureOperationTime = true
* isMeasureScriptTime = true
* isLogEnabled = false
* printTestVectors = false
* costTracingEnabled = false
* isTestRun = true
* perTestWarmUpIters = 1
* nBenchmarkIters = 1
*/
abstract class LanguageSpecificationBase extends SigmaDslTesting
with CompilerCrossVersionProps
with BeforeAndAfterAll { suite =>

/** Version of the language (ErgoScript/ErgoTree) which is specified by this suite. */
def languageVersion: Byte

/** Use VersionContext so that each property in this suite runs under correct
* parameters.
*/
protected override def testFun_Run(testName: String, testFun: => Any): Unit = {
VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) {
super.testFun_Run(testName, testFun)
}
}

implicit override val generatorDrivenConfig: PropertyCheckConfiguration = PropertyCheckConfiguration(minSuccessful = 30)

val evalSettingsInTests = CErgoTreeEvaluator.DefaultEvalSettings.copy(
isMeasureOperationTime = true,
isMeasureScriptTime = true,
isLogEnabled = false, // don't commit the `true` value (travis log is too high)
printTestVectors = false, // don't commit the `true` value (travis log is too high)

/** Should always be enabled in tests (and false by default)
* Should be disabled for cost profiling, which case the new costs are not checked.
*/
costTracingEnabled = true,
profilerOpt = Some(CErgoTreeEvaluator.DefaultProfiler),
isTestRun = true
)

def warmupSettings(p: Profiler) = evalSettingsInTests.copy(
isLogEnabled = false,
printTestVectors = false,
profilerOpt = Some(p)
)

implicit override def evalSettings: EvalSettings = {
warmupProfiler match {
case Some(p) => warmupSettings(p)
case _ => evalSettingsInTests
}
}

override val perTestWarmUpIters = 0

override val nBenchmarkIters = 0

override val okRunTestsWithoutMCLowering: Boolean = true

implicit def IR = createIR()

def testCases[A, B](cases: Seq[(A, Expected[B])], f: Feature[A, B]) = {
val table = Table(("x", "y"), cases: _*)
forAll(table) { (x, expectedRes) =>
val res = f.checkEquality(x)
val resValue = res.map(_._1)
val (expected, expDetailsOpt) = expectedRes.newResults(ergoTreeVersionInTests)
checkResult(resValue, expected.value, failOnTestVectors = true,
"SigmaDslSpecifiction#testCases: compare expected new result with res = f.checkEquality(x)")
res match {
case Success((value, details)) =>
details.cost shouldBe JitCost(expected.verificationCost.get)
expDetailsOpt.foreach(expDetails =>
if (details.trace != expDetails.trace) {
printCostDetails(f.script, details)
details.trace shouldBe expDetails.trace
}
)
}
}
}

override protected def beforeAll(): Unit = {
prepareSamples[BigInt]
prepareSamples[GroupElement]
prepareSamples[AvlTree]
prepareSamples[Box]
prepareSamples[PreHeader]
prepareSamples[Header]
prepareSamples[(BigInt, BigInt)]
prepareSamples[(GroupElement, GroupElement)]
prepareSamples[(AvlTree, AvlTree)]
prepareSamples[(Box, Box)]
prepareSamples[(PreHeader, PreHeader)]
prepareSamples[(Header, Header)]
}
}
Loading

0 comments on commit e7bd2a3

Please sign in to comment.