Skip to content

Commit

Permalink
A number of improvements/bug fixes for contract client sdk
Browse files Browse the repository at this point in the history
Remove support for GipsyInvocation (everything is now the
same JSON RPC invocation). Add an invocation response
handler to convert the invocation_response into a python
data structure.

Add support for some additional tags in the json test
scripts.

Signed-off-by: Mic Bowman <[email protected]>
  • Loading branch information
cmickeyb authored and prakashngit committed Feb 19, 2020
1 parent ed4cbad commit 473668e
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 60 deletions.
2 changes: 1 addition & 1 deletion python/pdo/common/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.

__all__ = [ "config", "crypto", "logger", "secrets" ]
__all__ = [ "config", "crypto", "keys", "logger", "secrets", "utility" ]
18 changes: 12 additions & 6 deletions python/pdo/common/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@

__all__ = ['stream_to_logger', 'setup_loggers']

# provide a level that can be used to generate output
# at a very high priority, e.g. test information
HIGHLIGHT=35
logging.addLevelName(HIGHLIGHT, 'HIGHLIGHT')

## -----------------------------------------------------------------
## -----------------------------------------------------------------
class stream_to_logger(object):
Expand Down Expand Up @@ -67,15 +72,16 @@ def setup_loggers(config) :
else :
clog = logging.StreamHandler()
formatter = ColoredFormatter(
"%(log_color)s[%(asctime)s %(levelname)-8s%(name)s]%(reset)s %(white)s%(message)s",
"%(log_color)s[%(asctime)s %(levelname)s %(name)s]%(reset)s %(white)s%(message)s",
datefmt="%H:%M:%S",
reset=True,
log_colors={
'DEBUG': 'cyan',
'INFO': 'green',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'red',
'DEBUG': 'cyan',
'INFO': 'green',
'WARNING': 'yellow',
'HIGHLIGHT': 'purple',
'ERROR': 'red',
'CRITICAL': 'red',
}
)

Expand Down
2 changes: 2 additions & 0 deletions python/pdo/contract/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"add_replication_task",
"add_transaction_task",
"invocation_request",
"invocation_response",
"register_contract",
"start_replication_service",
"start_transaction_processing_service",
Expand All @@ -37,6 +38,7 @@
from pdo.contract.contract import add_enclave_to_contract
from pdo.contract.contract import register_contract
from pdo.contract.invocation import invocation_request
from pdo.contract.invocation import invocation_response
from pdo.contract.message import ContractMessage
from pdo.contract.request import ContractRequest
from pdo.contract.response import ContractResponse
Expand Down
37 changes: 7 additions & 30 deletions python/pdo/contract/invocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,13 @@ def serialize(self) :
request['KeywordParameters'] = self
return json.dumps(request)

# -----------------------------------------------------------------
# -----------------------------------------------------------------
class GipsyInvocationRequest(InvocationRequest) :
"""Invocation Request that encodes requests as a Scheme
s-expression. Assumes that all strings have been fully escaped
in the parameter lists.
"""

def __init__(self, method, *args, **kwargs) :
super(GipsyInvocationRequest, self).__init__(method, *args, **kwargs)

def serialize(self) :
"""construct an s-expression from positional and keyword parameters,
the expression will have the form '(method pp1 pp2 ... (kw1 v1) (kw2 v2) ..)
"""
params = list(self.__positional_parameters__)
for k in self.keys() :
params.append([k, self[k]])

params_sexpr = SchemeExpression.make_expression(params)
sexpr = SchemeExpression.cons(SchemeExpression.make_symbol(self.__method__), params_sexpr)
sexpr = SchemeExpression.make_list([sexpr])
sexpr = SchemeExpression.cons(SchemeExpression.make_symbol('quote'), sexpr)

logger.debug("gipsy invocation expression: {0}".format(str(sexpr)))
return str(sexpr)

# -----------------------------------------------------------------
def invocation_request(method, *args, **kwargs) :
if os.environ.get('PDO_INTERPRETER', 'gipsy') == 'gipsy':
return GipsyInvocationRequest(method, *args, **kwargs)

return InvocationRequest(method, *args, **kwargs)

# -----------------------------------------------------------------
def invocation_response(response_string) :
try :
return json.loads(response_string)
except Exception as e:
return str(response_string)
22 changes: 12 additions & 10 deletions python/pdo/contract/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@
# 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.
import os
import sys
import concurrent.futures
import queue
import time
import threading

from pdo.contract.invocation import invocation_response
import pdo.common.crypto as crypto
import pdo.common.keys as keys
from pdo.common.utility import deprecated

from pdo.contract.state import ContractState
from pdo.contract.replication import ReplicationRequest, start_replication_service, stop_replication_service, add_replication_task
from pdo.contract.transaction import TransactionRequest, start_transaction_processing_service, stop_transacion_processing_service, add_transaction_task
from pdo.contract.replication import ReplicationRequest
from pdo.contract.replication import start_replication_service
from pdo.contract.replication import stop_replication_service
from pdo.contract.replication import add_replication_task
from pdo.contract.transaction import TransactionRequest
from pdo.contract.transaction import start_transaction_processing_service
from pdo.contract.transaction import stop_transacion_processing_service
from pdo.contract.transaction import add_transaction_task

import logging
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -54,8 +54,10 @@ def __init__(self, request, response) :
:param request: the ContractRequest object corresponding to the response
:param response: diction containing the response from the enclave
"""

self.status = response['Status']
self.invocation_response = response['InvocationResponse']
self.invocation_response_raw = response['InvocationResponse']
self.invocation_response = invocation_response(response['InvocationResponse'])
self.state_changed = response['StateChanged']
self.new_state_object = request.contract_state
#if the new state is same as the old state, then change set is empty
Expand Down
35 changes: 23 additions & 12 deletions python/pdo/test/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@

import pdo.contract as contract_helper
from pdo.contract.response import ContractResponse
import pdo.common.crypto as crypto
import pdo.common.keys as keys
import pdo.common.secrets as secrets
import pdo.common.utility as putils
from pdo.common import crypto
from pdo.common import keys
from pdo.common import utility as putils
from pdo.common import config as pconfig
from pdo.common import logger as plogger

import logging
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -358,8 +359,15 @@ def UpdateTheContract(config, enclaves, contract, contract_invoker_keys) :
test_list = list(reader)

elif test_file.endswith('.json') :
# there is currently no support to set these values outside of the
# configuration file and that is not going to change soon
test_max_level = config.get('Test', {}).get('MaxLevel', 0)

reader = json.load(efile)
for test in reader :
if test.get('test-level', 0) > test_max_level :
continue

method = test['MethodName']
pparms = test.get('PositionalParameters',[])
kparms = test.get('KeywordParameters',{})
Expand All @@ -372,35 +380,40 @@ def UpdateTheContract(config, enclaves, contract, contract_invoker_keys) :
for test in test_list :
expression = test['expression']

if test.get('description') :
logger.log(plogger.HIGHLIGHT,"TEST[{0}] : {1}".format(total_tests, test['description'].format(**test)))

try :
total_tests += 1
update_request = contract.create_update_request(contract_invoker_keys, expression, enclave_to_use)
update_response = update_request.evaluate()

result = update_response.invocation_response[:15]
if len(update_response.invocation_response) >= 15 :
raw_result = str(update_response.invocation_response)
result = raw_result[:15]
if len(raw_result) >= 15 :
result += "..."

unpacked_response = contract_helper.invocation_response(raw_result)
if update_response.status is False :
logger.info('failed: {0} --> {1}'.format(expression, result))
if test['invert'] is None or test['invert'] != 'fail' :
if test.get('invert') is None or test.get('invert') != 'fail' :
total_failed += 1
logger.warn('inverted test failed: %s instead of %s', result, test['expected'])

if test['expected'] and not re.match(test['expected'], update_response.invocation_response) :
elif test.get('expected') and not re.match(test.get('expected'), raw_result) :
total_failed += 1
logger.warn('test failed: %s instead of %s', result, test['expected'])

continue

logger.info('{0} --> {1}'.format(expression, result))

if test['expected'] and not re.match(test['expected'], update_response.invocation_response) :
if test.get('expected') and not re.match(test.get('expected'), raw_result) :
total_failed += 1
logger.warn('test failed: %s instead of %s', result, test['expected'])

except Exception as e:
logger.error('enclave failed to evaluation expression; %s', str(e))
logger.error('enclave failed to evaluate expression; %s', str(e))
ErrorShutdown()

# if this operation did not change state then there is nothing to commit
Expand Down Expand Up @@ -517,8 +530,6 @@ def Main() :
global use_eservice
global use_pservice

import pdo.common.config as pconfig
import pdo.common.logger as plogger

# parse out the configuration file first
conffiles = [ 'pcontract.toml', 'enclave.toml' ]
Expand Down
2 changes: 1 addition & 1 deletion python/pdo/test/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ def UpdateTheContract(config, contract, enclaves, contract_invoker_keys) :
logger.info('{0} --> {1}'.format(expression, update_response.invocation_response))

except Exception as e:
logger.error('enclave failed to evaluation expression; %s', str(e))
logger.error('enclave failed to evaluate expression; %s', str(e))
ErrorShutdown()

# if this operation did not change state then there is nothing to commit
Expand Down

0 comments on commit 473668e

Please sign in to comment.