#!/usr/bin/env python2
# coding: utf-8
"""Test Path Constraint."""

import unittest
from triton import *


class TestPathConstraint(unittest.TestCase):

    """Testing path constraint."""

    def setUp(self):
        """Define the arch."""
        self.ctx = TritonContext()
        self.ctx.setArchitecture(ARCH.X86)

        trace = [
            b"\x25\xff\xff\xff\x3f",      # and eax, 0x3fffffff
            b"\x81\xe3\xff\xff\xff\x3f",  # and ebx, 0x3fffffff
            b"\x31\xd1",                  # xor ecx, edx
            b"\x31\xfa",                  # xor edx, edi
            b"\x31\xD8",                  # xor eax, ebx
            b"\x0F\x84\x55\x00\x00\x00",  # je 0x55
        ]

        self.ctx.convertRegisterToSymbolicVariable(self.ctx.registers.eax)
        self.ctx.convertRegisterToSymbolicVariable(self.ctx.registers.ebx)

        for opcodes in trace:
            self.ctx.processing(Instruction(opcodes))

    def test_getPathPredicate(self):
        """Test getPathPredicate"""
        astCtx = self.ctx.getAstContext()
        crst = self.ctx.getPathPredicate()
        self.assertNotEqual(len(self.ctx.getModel(crst)), 0)
        self.assertNotEqual(len(self.ctx.getModel(astCtx.lnot(crst))), 0)

    def test_getPathConstraints(self):
        """Test getPathConstraints"""
        pco = self.ctx.getPathConstraints()
        self.assertEqual(len(pco), 1)

    def test_isMultipleBranches(self):
        pc = self.ctx.getPathConstraints()[0]
        self.assertTrue(pc.isMultipleBranches())

    def test_getTakenPredicate(self):
        pc = self.ctx.getPathConstraints()[0]
        self.assertEqual(pc.getTakenPredicate().evaluate(), 1)

    def test_getTakenAddress(self):
        pc = self.ctx.getPathConstraints()[0]
        self.assertEqual(pc.getTakenAddress(), 91)

    def test_getBranchConstraints(self):
        pc = self.ctx.getPathConstraints()[0].getBranchConstraints()

        self.assertTrue(pc[0]['isTaken'])
        self.assertFalse(pc[1]['isTaken'])

        self.assertEqual(pc[0]['srcAddr'], pc[1]['srcAddr'])

        self.assertEqual(pc[0]['dstAddr'], 91)
        self.assertEqual(pc[1]['dstAddr'], 23)

@@ -2153,8 +2153,676 @@
 '%5D, 23)%0A
+%0A    def test_pushpop(self):%0A        ast = self.ctx.getAstContext()%0A        pc  = self.ctx.getPathPredicate()%0A        opc = pc%0A%0A        self.assertEqual(str(pc), %22(and (= (_ bv1 1) (_ bv1 1)) (= (ite (= ref!35 (_ bv1 1)) (_ bv91 32) (_ bv23 32)) (_ bv91 32)))%22)%0A        self.ctx.pushPathConstraint(ast.equal(ast.bvtrue(), ast.bvtrue()))%0A%0A        pc  = self.ctx.getPathPredicate()%0A        self.assertEqual(str(pc), %22(and (and (= (_ bv1 1) (_ bv1 1)) (= (ite (= ref!35 (_ bv1 1)) (_ bv91 32) (_ bv23 32)) (_ bv91 32))) (= (_ bv1 1) (_ bv1 1)))%22)%0A%0A        self.ctx.popPathConstraint()%0A        pc  = self.ctx.getPathPredicate()%0A        self.assertEqual(str(pc), str(opc))%0A

Fix #350: Add unittest