class VMTestCase(TestCase): engine = None econtext = None def setUp(self): self.engine = ExecutionEngine() self.econtext = ExecutionContext() def test_add_operations(self): self.engine.EvaluationStack.PushT(StackItem.New(2)) self.engine.EvaluationStack.PushT(StackItem.New(3)) self.engine.ExecuteOp(OpCode.ADD, self.econtext) self.assertEqual(len(self.engine.EvaluationStack.Items), 1) self.assertEqual(self.engine.EvaluationStack.Items[0], StackItem.New(5)) def test_sub_operations(self): self.engine.EvaluationStack.PushT(StackItem.New(2)) self.engine.EvaluationStack.PushT(StackItem.New(3)) self.engine.ExecuteOp(OpCode.SUB, self.econtext) self.assertEqual(len(self.engine.EvaluationStack.Items), 1) self.assertEqual(self.engine.EvaluationStack.Items[0], StackItem.New(-1))
def Runtime_Log(self, engine: ExecutionEngine): item = engine.CurrentContext.EvaluationStack.Pop() # will raise an exception for types that don't support it item.GetByteArray() # if we pass we can call the convenience method to pretty print the data message = item.GetString() hash = UInt160(data=engine.CurrentContext.ScriptHash()) tx_hash = None if engine.ScriptContainer: tx_hash = engine.ScriptContainer.Hash engine.write_log(str(message)) # Build and emit smart contract event self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.RUNTIME_LOG, ContractParameter(ContractParameterType.String, value=message), hash, GetBlockchain().Height + 1, tx_hash, test_mode=engine.testMode)) return True
def execute_test(data: dict): global test_count, skipped_test_count for test in data['tests']: test_count += 1 # interop service service = InteropService.InteropService() # message provider script_container = None message = test.get("message", None) if message: script_container = MessageProvider(message) # prepare script table script_table = None # there are currently no tests that load a script table so I don't know the format or key value they'll use # create engine and run engine = ExecutionEngine(crypto=Crypto.Default(), service=service, container=script_container, table=script_table, exit_on_error=True) # TODO: should enforce 0x<data> rule in the JSON test case if test['script'].startswith('0x'): script = test['script'][2:] else: script = test['script'] try: script = binascii.unhexlify(script) except binascii.Error: print(f"Skipping test {data['category']}-{data['name']}, cannot read script data") test_count -= 1 skipped_test_count += 1 continue engine.LoadScript(script) steps = test.get('steps', None) if steps is None: continue for i, step in enumerate(steps): actions = step.get('actions', []) for action in actions: if action == "StepInto": engine.StepInto() elif action == "Execute": engine.Execute() elif action == "StepOver": raise ValueError("StepOver not supported!") elif action == "StepOut": raise ValueError("StepOut not supported!") test_name = test.get("name", "") msg = f"{data['category']}-{data['name']}-{test_name}-{i}" assert_result(engine, step['result'], msg)
class TestVMErrors(BoaTest): engine = ExecutionEngine() script = None @classmethod def setUpClass(cls): super(TestVMErrors, cls).setUpClass() output = Compiler.instance().load('%s/sc_vm_errors.py' % os.path.dirname(__file__)).default cls.script = output.write() settings.set_loglevel(DEBUG) @patch('logzero.logger.error') def test_invalid_array_index(self, mocked_logger): tx, results, total_ops, engine = TestBuild(self.script, [1, ['my_arg0']], self.GetWallet1(), '0210', '07') mocked_logger.assert_called_with( StringIn('Array index') and StringIn('exceeds list length')) @patch('logzero.logger.error') def test_negative_array_indexing(self, mocked_logger): tx, results, total_ops, engine = TestBuild(self.script, [2, ['my_arg0']], self.GetWallet1(), '0210', '07') mocked_logger.assert_called_with( StringIn("Array index is less than zero")) @patch('logzero.logger.error') def test_invalid_type_indexing(self, mocked_logger): tx, results, total_ops, engine = TestBuild(self.script, [3, ['my_arg0']], self.GetWallet1(), '0210', '07') mocked_logger.assert_called_with( StringIn("Cannot access item at index") and StringIn("Item is not an array or dict but of type")) @patch('logzero.logger.error') def test_invalid_appcall(self, mocked_logger): tx, results, total_ops, engine = TestBuild(self.script, [4, ['my_arg0']], self.GetWallet1(), '0210', '07', dynamic=True) mocked_logger.assert_called_with( StringIn("Trying to call an unknown contract")) # make sure this test is always last because we change the logging level @patch('logzero.logger.error') def test_no_logging_if_loglevel_not_debug(self, mocked_logger): settings.set_loglevel(INFO) tx, results, total_ops, engine = TestBuild(self.script, [1, ['my_arg0']], self.GetWallet1(), '0210', '07') self.assertEqual(0, mocked_logger.call_count)
def Runtime_Log(self, engine: ExecutionEngine): message = engine.CurrentContext.EvaluationStack.Pop().GetString() hash = UInt160(data=engine.CurrentContext.ScriptHash()) tx_hash = None if engine.ScriptContainer: tx_hash = engine.ScriptContainer.Hash engine.write_log(str(message)) # Build and emit smart contract event self.events_to_dispatch.append(SmartContractEvent(SmartContractEvent.RUNTIME_LOG, ContractParameter(ContractParameterType.String, value=message), hash, Blockchain.Default().Height + 1, tx_hash, test_mode=engine.testMode)) return True
class TestVMErrors(BoaTest): engine = ExecutionEngine() script = None @classmethod def setUpClass(cls): super(TestVMErrors, cls).setUpClass() output = Compiler.instance().load('%s/sc_vm_errors.py' % os.path.dirname(__file__)).default cls.script = output.write() @patch('logzero.logger.error') def test_invalid_array_index(self, mocked_logger): tx, results, total_ops, engine = TestBuild(self.script, [1, ['my_arg0']], self.GetWallet1(), '0210', '07') mocked_logger.assert_called_with( StringIn('Array index') and StringIn('exceeds list length')) @patch('logzero.logger.error') def test_negative_array_indexing(self, mocked_logger): tx, results, total_ops, engine = TestBuild(self.script, [2, ['my_arg0']], self.GetWallet1(), '0210', '07') mocked_logger.assert_called_with( StringIn("Attempting to access an array using a negative index")) @patch('logzero.logger.error') def test_invalid_type_indexing(self, mocked_logger): tx, results, total_ops, engine = TestBuild(self.script, [3, ['my_arg0']], self.GetWallet1(), '0210', '07') mocked_logger.assert_called_with( StringIn("Cannot access item at index") and StringIn("Item is not an array but of type")) @patch('logzero.logger.error') def test_invalid_appcall(self, mocked_logger): tx, results, total_ops, engine = TestBuild(self.script, [4, ['my_arg0']], self.GetWallet1(), '0210', '07', dynamic=True) mocked_logger.assert_called_with( StringIn("Trying to call an unknown contract"))
class TestVMErrors(BoaTest): engine = ExecutionEngine() script = None @classmethod def setUpClass(cls): super(TestVMErrors, cls).setUpClass() output = Compiler.instance().load('%s/sc_vm_errors.py' % os.path.dirname(__file__)).default cls.script = output.write() def test_invalid_array_index(self): with self.assertLogHandler('vm', DEBUG) as log_context: tx, results, total_ops, engine = TestBuild(self.script, [1, ['my_arg0']], self.GetWallet1(), '0210', '07') self.assertTrue(len(log_context.output) > 0) log_msg = log_context.output[0] self.assertTrue("Array index" in log_msg and "exceeds list length" in log_msg) def test_negative_array_indexing(self): with self.assertLogHandler('vm', DEBUG) as log_context: tx, results, total_ops, engine = TestBuild(self.script, [2, ['my_arg0']], self.GetWallet1(), '0210', '07') self.assertTrue(len(log_context.output) > 0) log_msg = log_context.output[0] self.assertTrue("Array index is less than zero" in log_msg) def test_invalid_type_indexing(self): with self.assertLogHandler('vm', DEBUG) as log_context: tx, results, total_ops, engine = TestBuild(self.script, [3, [1]], self.GetWallet1(), '0210', '07') self.assertTrue(len(log_context.output) > 0) log_msg = log_context.output[0] # an index of 1 for an array with length one is out of bounds self.assertTrue("Item is not an Array or Map but of type" in log_msg) def test_invalid_appcall(self): with self.assertLogHandler('vm', DEBUG) as log_context: tx, results, total_ops, engine = TestBuild(self.script, [4, ['my_arg0']], self.GetWallet1(), '0210', '07', dynamic=True) found = False for log_msg in log_context.output: if "Trying to call an unknown contract" in log_msg: found = True break self.assertTrue(found) def test_no_logging_if_loglevel_not_debug(self): with self.assertLogHandler('vm', INFO) as log_context: tx, results, total_ops, engine = TestBuild(self.script, [1, ['my_arg0']], self.GetWallet1(), '0210', '07') self.assertEqual(len(log_context.output), 0)
class TestUnclosedWhileLoop(BoaTest): engine = ExecutionEngine() script = None @classmethod def setUpClass(cls): super(TestUnclosedWhileLoop, cls).setUpClass() # the following script is a simple contract that is basically `while True` cls.script = binascii.unhexlify(b'00c56b620000') @classmethod def tearDownClass(cls): super(TestUnclosedWhileLoop, cls).tearDownClass() def test_unclosed_loop_script(self): with self.assertLogHandler('vm', DEBUG) as log_context: tx, results, total_ops, engine = TestBuild(self.script, [], self.GetWallet1(), '', 'ff') self.assertTrue(len(log_context.output) > 0) self.assertTrue("Too many free operations processed" in log_context.output[0])
class TestUnclosedWhileLoop(BoaTest): engine = ExecutionEngine() script = None @classmethod def setUpClass(cls): super(TestUnclosedWhileLoop, cls).setUpClass() # the following script is a simple contract that is basically `while True` cls.script = binascii.unhexlify(b'00c56b620000') settings.set_loglevel(DEBUG) @classmethod def tearDownClass(cls): super(TestUnclosedWhileLoop, cls).tearDownClass() settings.set_loglevel(INFO) @patch('logzero.logger.debug') def test_unclosed_loop_script(self, mocked_logger): tx, results, total_ops, engine = TestBuild(self.script, [], self.GetWallet1(), '', 'ff') mocked_logger.assert_called_with( StringIn('Too many free operations processed'))
def setUp(self): self.engine = ExecutionEngine() self.econtext = ExecutionContext(Script(self.engine.Crypto, b''), 0) self.engine.InvocationStack.PushT(self.econtext)
def setUp(self): self.engine = ExecutionEngine() self.econtext = ExecutionContext(engine=self.engine)
class InteropTest(TestCase): engine = None econtext = None @classmethod def setUpClass(cls): super(InteropTest, cls).setUpClass() settings.set_loglevel(DEBUG) def setUp(self): self.engine = ExecutionEngine() self.econtext = ExecutionContext(engine=self.engine) def test_interop_map1(self): map = Map() self.assertEqual(map.Keys, []) self.assertEqual(map.Values, []) map.SetItem(Integer(BigInteger(3)), ByteArray(b'abc')) self.assertEqual(map.Keys, [Integer(BigInteger(3))]) self.assertEqual(map.Values, [ByteArray(b'abc')]) def test_interop_map2(self): map = Map({'a': 1, 'b': 2, 'c': 3}) self.assertEqual(map.Count, 3) self.assertEqual(map.ContainsKey('a'), True) self.assertEqual(map.Contains('a'), False) map.Clear() self.assertEqual(map.GetMap(), {}) def test_interop_map3(self): map = Map({'a': 1, 'b': 2, 'c': 3}) self.assertEqual(map.GetBoolean(), True) with self.assertRaises(Exception) as context: map.GetByteArray() with self.assertRaises(Exception) as context: map.GetBigInteger() map2 = Map({'a': 1, 'b': 2, 'c': 3}) self.assertEqual(map, map2) self.assertTrue(map.Remove('a'), True) self.assertEqual(map.Count, 2) self.assertNotEqual(map, map2) self.assertEqual(map.TryGetValue('b'), (True, 2)) self.assertEqual(map.TryGetValue('h'), (False, None)) map.SetItem('h', 9) self.assertEqual(map.GetItem('h'), 9) self.assertEqual(map.GetMap(), {'b': 2, 'c': 3, 'h': 9}) def test_op_map1(self): self.engine.ExecuteOp(OpCode.NEWMAP, self.econtext) self.assertEqual(len(self.econtext.EvaluationStack.Items), 1) self.assertIsInstance(self.econtext.EvaluationStack.Items[0], Map) self.assertEqual(self.econtext.EvaluationStack.Items[0].GetMap(), {}) def test_op_map2(self): self.engine.ExecuteOp(OpCode.NEWMAP, self.econtext) self.econtext.EvaluationStack.PushT(StackItem.New('mykey')) self.econtext.EvaluationStack.PushT(StackItem.New('myVal')) self.engine.ExecuteOp(OpCode.SETITEM, self.econtext) self.assertEqual(len(self.econtext.EvaluationStack.Items), 0) def test_op_map3(self): # set item should fail if not enough things on estack self.econtext.EvaluationStack.PushT(StackItem.New('myvalue')) self.econtext.EvaluationStack.PushT(StackItem.New('mykey')) with self.assertRaises(Exception) as context: self.engine.ExecuteOp(OpCode.SETITEM, self.econtext) self.assertEqual(len(self.econtext.EvaluationStack.Items), 0) self.assertEqual(self.engine.State, VMState.BREAK) @patch('logzero.logger.error') def test_op_map4(self, mocked_logger): # set item should fail if these are out of order self.econtext.EvaluationStack.PushT(StackItem.New('mykey')) self.engine.ExecuteOp(OpCode.NEWMAP, self.econtext) self.econtext.EvaluationStack.PushT(StackItem.New('myVal')) self.engine.ExecuteOp(OpCode.SETITEM, self.econtext) self.assertEqual(self.engine.State, VMState.FAULT | VMState.BREAK) mocked_logger.assert_called_with(StringIn('VMFault.KEY_IS_COLLECTION')) @patch('logzero.logger.error') def test_op_map5(self, mocked_logger): # set item should fail if these are out of order self.econtext.EvaluationStack.PushT(StackItem.New('mykey')) self.econtext.EvaluationStack.PushT(StackItem.New('mykey')) self.econtext.EvaluationStack.PushT(StackItem.New('myVal')) self.engine.ExecuteOp(OpCode.SETITEM, self.econtext) self.assertEqual(self.engine.State, VMState.FAULT | VMState.BREAK) mocked_logger.assert_called_with( StringIn('VMFault.SETITEM_INVALID_TYPE')) @patch('logzero.logger.error') def test_op_map6(self, mocked_logger): # we can pick an item from a dict self.econtext.EvaluationStack.PushT( Map(dict={StackItem.New('a'): StackItem.New(4)})) self.econtext.EvaluationStack.PushT(StackItem.New('a')) self.engine.ExecuteOp(OpCode.PICKITEM, self.econtext) self.assertEqual(len(self.econtext.EvaluationStack.Items), 1) self.assertEqual( self.econtext.EvaluationStack.Items[0].GetBigInteger(), 4) @patch('logzero.logger.error') def test_op_map7(self, mocked_logger): # pick item with key is collection causes error self.econtext.EvaluationStack.PushT( Map(dict={StackItem.New('a'): StackItem.New(4)})) self.econtext.EvaluationStack.PushT( Map(dict={StackItem.New('a'): StackItem.New(4)})) self.engine.ExecuteOp(OpCode.PICKITEM, self.econtext) self.assertEqual(self.engine.State, VMState.FAULT | VMState.BREAK) mocked_logger.assert_called_with(StringIn('VMFault.KEY_IS_COLLECTION')) @patch('logzero.logger.error') def test_op_map8(self, mocked_logger): # pick item on non collection causes error self.econtext.EvaluationStack.PushT(StackItem.New('a')) self.econtext.EvaluationStack.PushT(StackItem.New('a')) self.engine.ExecuteOp(OpCode.PICKITEM, self.econtext) self.assertEqual(self.engine.State, VMState.FAULT | VMState.BREAK) mocked_logger.assert_called_with( StringIn('Cannot access item at index') and StringIn('Item is not an array or dict')) @patch('logzero.logger.error') def test_op_map9(self, mocked_logger): # pick item key not found self.econtext.EvaluationStack.PushT( Map(dict={StackItem.New('a'): StackItem.New(4)})) self.econtext.EvaluationStack.PushT(StackItem.New('b')) self.engine.ExecuteOp(OpCode.PICKITEM, self.econtext) self.assertEqual(self.engine.State, VMState.FAULT | VMState.BREAK) mocked_logger.assert_called_with( StringIn('VMFault.DICT_KEY_NOT_FOUND')) def test_op_map10(self): # pick item key not found self.econtext.EvaluationStack.PushT( Map( dict={ StackItem.New('a'): StackItem.New(4), StackItem.New('b'): StackItem.New(5) })) self.engine.ExecuteOp(OpCode.KEYS, self.econtext) self.assertIsInstance(self.econtext.EvaluationStack.Items[0], Array) items = self.econtext.EvaluationStack.Items[0].GetArray() self.assertEqual(items, [StackItem.New('a'), StackItem.New('b')]) def test_op_map11(self): self.econtext.EvaluationStack.PushT( Map( dict={ StackItem.New('a'): StackItem.New(4), StackItem.New('b'): StackItem.New(5) })) self.engine.ExecuteOp(OpCode.VALUES, self.econtext) self.assertIsInstance(self.econtext.EvaluationStack.Items[0], Array) items = self.econtext.EvaluationStack.Items[0].GetArray() self.assertEqual(items, [StackItem.New(4), StackItem.New(5)]) def test_op_map12(self): self.econtext.EvaluationStack.PushT( Map( dict={ StackItem.New('a'): StackItem.New(4), StackItem.New('b'): StackItem.New(5) })) self.econtext.EvaluationStack.PushT(StackItem.New('b')) self.engine.ExecuteOp(OpCode.HASKEY, self.econtext) self.assertEqual(self.econtext.EvaluationStack.Items[0].GetBoolean(), True) def test_op_map13(self): self.econtext.EvaluationStack.PushT( Map( dict={ StackItem.New('a'): StackItem.New(4), StackItem.New('b'): StackItem.New(5) })) self.econtext.EvaluationStack.PushT(StackItem.New('c')) self.engine.ExecuteOp(OpCode.HASKEY, self.econtext) self.assertEqual(self.econtext.EvaluationStack.Items[0].GetBoolean(), False)
def setUp(self): self.engine = ExecutionEngine(crypto=Crypto.Default()) self.econtext = ExecutionContext()
class VMTestCase(TestCase): engine = None econtext = None def setUp(self): self.engine = ExecutionEngine(crypto=Crypto.Default()) self.econtext = ExecutionContext() def test_add_operations(self): self.engine.EvaluationStack.PushT(StackItem.New(2)) self.engine.EvaluationStack.PushT(StackItem.New(3)) self.engine.ExecuteOp(OpCode.ADD, self.econtext) self.assertEqual(len(self.engine.EvaluationStack.Items), 1) self.assertEqual(self.engine.EvaluationStack.Items[0], StackItem.New(5)) def test_sub_operations(self): self.engine.EvaluationStack.PushT(StackItem.New(2)) self.engine.EvaluationStack.PushT(StackItem.New(3)) self.engine.ExecuteOp(OpCode.SUB, self.econtext) self.assertEqual(len(self.engine.EvaluationStack.Items), 1) self.assertEqual(self.engine.EvaluationStack.Items[0], StackItem.New(-1)) def test_verify_sig(self): # push message ( should be hexlified ) self.engine.EvaluationStack.PushT(StackItem.New(b'616263646566')) # sig sig = binascii.unhexlify( b'cd0ca967d11cea78e25ad16f15dbe77672258bfec59ff3617c95e317acff063a48d35f71aa5ce7d735977412186e1572507d0f4d204c5bcb6c90e03b8b857fbd' ) self.engine.EvaluationStack.PushT(StackItem.New(sig)) # pubkey pubkey = binascii.unhexlify( b'036fbcb5e138c1ce5360e861674c03228af735a9114a5b7fb4121b8350129f3ffe' ) self.engine.EvaluationStack.PushT(pubkey) self.engine.ExecuteOp(OpCode.VERIFY, self.econtext) res = self.engine.EvaluationStack.Pop() self.assertEqual(res, StackItem.New(True)) def test_verify_sig_fail(self): # push message ( should be hexlified ) self.engine.EvaluationStack.PushT(StackItem.New(b'616263646566')) # sig sig = binascii.unhexlify( b'cd0ca967d11cea78e25ad16f15dbe77672258bfec59ff3617c95e317acff063a48d35f71aa5ce7d735977412186e1572507d0f4d204c5bcb6c90e03b8b857fbd' ) self.engine.EvaluationStack.PushT(StackItem.New(sig)) # pubkey pubkey = binascii.unhexlify( b'036fbcb5e138c1ce5360e861674c03228af735a9114a5b7fb4121b8350129f3ffd' ) self.engine.EvaluationStack.PushT(pubkey) self.engine.ExecuteOp(OpCode.VERIFY, self.econtext) res = self.engine.EvaluationStack.Pop() self.assertEqual(res, StackItem.New(False))
def setUp(self): self.engine = ExecutionEngine() self.econtext = ExecutionContext() self.state_reader = StateReader()
class InteropTest(NeoTestCase): engine = None econtext = None @classmethod def setUpClass(cls): super(InteropTest, cls).setUpClass() def setUp(self): self.engine = ExecutionEngine() self.econtext = ExecutionContext(engine=self.engine) def test_interop_map1(self): map = Map() self.assertEqual(map.Keys, []) self.assertEqual(map.Values, []) map.SetItem(Integer(BigInteger(3)), ByteArray(b'abc')) self.assertEqual(map.Keys, [Integer(BigInteger(3))]) self.assertEqual(map.Values, [ByteArray(b'abc')]) def test_interop_map2(self): map = Map({'a': 1, 'b': 2, 'c': 3}) self.assertEqual(map.Count, 3) self.assertEqual(map.ContainsKey('a'), True) self.assertEqual(map.Contains('a'), False) map.Clear() self.assertEqual(map.GetMap(), {}) def test_interop_map3(self): map = Map({'a': 1, 'b': 2, 'c': 3}) self.assertEqual(map.GetBoolean(), True) with self.assertRaises(Exception) as context: map.GetByteArray() with self.assertRaises(Exception) as context: map.GetBigInteger() map2 = Map({'a': 1, 'b': 2, 'c': 3}) self.assertEqual(map, map2) self.assertTrue(map.Remove('a'), True) self.assertEqual(map.Count, 2) self.assertNotEqual(map, map2) self.assertEqual(map.TryGetValue('b'), (True, 2)) self.assertEqual(map.TryGetValue('h'), (False, None)) map.SetItem('h', 9) self.assertEqual(map.GetItem('h'), 9) self.assertEqual(map.GetMap(), {'b': 2, 'c': 3, 'h': 9}) def test_op_map1(self): self.engine.ExecuteOp(OpCode.NEWMAP, self.econtext) self.assertEqual(len(self.econtext.EvaluationStack.Items), 1) self.assertIsInstance(self.econtext.EvaluationStack.Items[0], Map) self.assertEqual(self.econtext.EvaluationStack.Items[0].GetMap(), {}) def test_op_map2(self): self.engine.ExecuteOp(OpCode.NEWMAP, self.econtext) self.econtext.EvaluationStack.PushT(StackItem.New('mykey')) self.econtext.EvaluationStack.PushT(StackItem.New('myVal')) self.engine.ExecuteOp(OpCode.SETITEM, self.econtext) self.assertEqual(len(self.econtext.EvaluationStack.Items), 0) def test_op_map3(self): # set item should fail if not enough things on estack self.econtext.EvaluationStack.PushT(StackItem.New('myvalue')) self.econtext.EvaluationStack.PushT(StackItem.New('mykey')) with self.assertRaises(Exception) as context: self.engine.ExecuteOp(OpCode.SETITEM, self.econtext) self.assertEqual(len(self.econtext.EvaluationStack.Items), 0) self.assertEqual(self.engine.State, VMState.BREAK) def test_op_map4(self): with self.assertLogHandler('vm', logging.DEBUG) as log_context: # set item should fail if these are out of order self.econtext.EvaluationStack.PushT(StackItem.New('mykey')) self.engine.ExecuteOp(OpCode.NEWMAP, self.econtext) self.econtext.EvaluationStack.PushT(StackItem.New('myVal')) self.engine.ExecuteOp(OpCode.SETITEM, self.econtext) self.assertEqual(self.engine.State, VMState.FAULT) self.assertTrue(len(log_context.output) > 0) self.assertTrue( 'VMFault.KEY_IS_COLLECTION' in log_context.output[0]) def test_op_map5(self): # need to set vm logging level to DEBUG or we will immediately exit `VM_FAULT_and_report()` with self.assertLogHandler('vm', logging.DEBUG) as log_context: # set item should fail if these are out of order self.econtext.EvaluationStack.PushT(StackItem.New('mykey')) self.econtext.EvaluationStack.PushT(StackItem.New('mykey')) self.econtext.EvaluationStack.PushT(StackItem.New('myVal')) self.engine.ExecuteOp(OpCode.SETITEM, self.econtext) self.assertEqual(self.engine.State, VMState.FAULT) self.assertTrue(len(log_context.output) > 0) self.assertEqual(log_context.records[0].levelname, 'DEBUG') self.assertTrue( 'VMFault.SETITEM_INVALID_TYPE' in log_context.output[0]) def test_op_map6(self): # we can pick an item from a dict self.econtext.EvaluationStack.PushT( Map(dict={StackItem.New('a'): StackItem.New(4)})) self.econtext.EvaluationStack.PushT(StackItem.New('a')) self.engine.ExecuteOp(OpCode.PICKITEM, self.econtext) self.assertEqual(len(self.econtext.EvaluationStack.Items), 1) self.assertEqual( self.econtext.EvaluationStack.Items[0].GetBigInteger(), 4) def test_op_map7(self): with self.assertLogHandler('vm', logging.DEBUG) as log_context: # pick item with key is collection causes error self.econtext.EvaluationStack.PushT( Map(dict={StackItem.New('a'): StackItem.New(4)})) self.econtext.EvaluationStack.PushT( Map(dict={StackItem.New('a'): StackItem.New(4)})) self.engine.ExecuteOp(OpCode.PICKITEM, self.econtext) self.assertEqual(self.engine.State, VMState.FAULT) self.assertTrue(len(log_context.output) > 0) self.assertTrue( 'VMFault.KEY_IS_COLLECTION' in log_context.output[0]) def test_op_map8(self): with self.assertLogHandler('vm', logging.DEBUG) as log_context: # pick item out of bounds self.econtext.EvaluationStack.PushT(StackItem.New('a')) self.econtext.EvaluationStack.PushT(StackItem.New('a')) self.engine.ExecuteOp(OpCode.PICKITEM, self.econtext) self.assertTrue(len(log_context.output) > 0) log_msg = log_context.output[0] expected_msg = "Array index is less than zero or 97 exceeds list length 1" self.assertTrue(expected_msg in log_msg) self.assertEqual(self.engine.State, VMState.FAULT) def test_op_map9(self): with self.assertLogHandler('vm', logging.DEBUG) as log_context: # pick item key not found self.econtext.EvaluationStack.PushT( Map(dict={StackItem.New('a'): StackItem.New(4)})) self.econtext.EvaluationStack.PushT(StackItem.New('b')) self.engine.ExecuteOp(OpCode.PICKITEM, self.econtext) self.assertEqual(self.engine.State, VMState.FAULT) self.assertTrue(len(log_context.output) > 0) self.assertTrue( 'VMFault.DICT_KEY_NOT_FOUND' in log_context.output[0]) def test_op_map10(self): # pick item key not found self.econtext.EvaluationStack.PushT( Map( dict={ StackItem.New('a'): StackItem.New(4), StackItem.New('b'): StackItem.New(5) })) self.engine.ExecuteOp(OpCode.KEYS, self.econtext) self.assertIsInstance(self.econtext.EvaluationStack.Items[0], Array) items = self.econtext.EvaluationStack.Items[0].GetArray() self.assertEqual(items, [StackItem.New('a'), StackItem.New('b')]) def test_op_map11(self): self.econtext.EvaluationStack.PushT( Map( dict={ StackItem.New('a'): StackItem.New(4), StackItem.New('b'): StackItem.New(5) })) self.engine.ExecuteOp(OpCode.VALUES, self.econtext) self.assertIsInstance(self.econtext.EvaluationStack.Items[0], Array) items = self.econtext.EvaluationStack.Items[0].GetArray() self.assertEqual(items, [StackItem.New(4), StackItem.New(5)]) def test_op_map12(self): self.econtext.EvaluationStack.PushT( Map( dict={ StackItem.New('a'): StackItem.New(4), StackItem.New('b'): StackItem.New(5) })) self.econtext.EvaluationStack.PushT(StackItem.New('b')) self.engine.ExecuteOp(OpCode.HASKEY, self.econtext) self.assertEqual(self.econtext.EvaluationStack.Items[0].GetBoolean(), True) def test_op_map13(self): self.econtext.EvaluationStack.PushT( Map( dict={ StackItem.New('a'): StackItem.New(4), StackItem.New('b'): StackItem.New(5) })) self.econtext.EvaluationStack.PushT(StackItem.New('c')) self.engine.ExecuteOp(OpCode.HASKEY, self.econtext) self.assertEqual(self.econtext.EvaluationStack.Items[0].GetBoolean(), False)
def setUp(self): self.engine = ExecutionEngine() self.econtext = ExecutionContext(Script(self.engine.Crypto, b''), 0) self.engine.InvocationStack.PushT(self.econtext) self.service = StateMachine(None, None)
def setUp(self): self.engine = ExecutionEngine() self.econtext = ExecutionContext(Script(self.engine.Crypto, b''), 0) self.engine.InvocationStack.PushT(self.econtext) snapshot = GetBlockchain()._db.createSnapshot() self.state_reader = StateReader(TriggerType.Application, snapshot)