Commit a5629bc6 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Move out ASN.1 Random and Exhaustive value generation

parent 82c4a2c5
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# pylint: disable=C0302
"""
ASN.1 Value Editor - ASN.1 Value Generator
Two functions are provided:
compute_random_value - Generate a random GSER string for a given ASN.1 type
compute_combinations - Yields all combinations of values of an ASN.1 type
Copyright (c) 2016 European Space Agency
Author: Maxime Perrotin / contact maxime.perrotin@esa.int
"""
__all__ = ['compute_random_value', 'compute_combinations']
import random
import itertools
import opengeode
# Set of functions used by the simulator to compute a random value for
# a given ASN.1 type, return a Value Notation string
def compute_random_value(asn1_ty, pool):
''' Top-level, type-dispatching function
pool is the set of types from process.dataview attribute '''
basic = opengeode.ogParser.find_basic_type(asn1_ty.type, pool)
if basic.kind.startswith('Integer'):
return rand_int(basic)
elif basic.kind == 'BooleanType':
return rand_bool(basic)
elif basic.kind.startswith('Real'):
return rand_real(basic)
elif basic.kind == 'EnumeratedType':
return rand_enum(basic)
elif basic.kind == 'ChoiceType':
return compute_random_choice(basic, pool)
elif basic.kind in ('SequenceType', 'SetType'):
return compute_random_sequence(basic, pool)
elif basic.kind in ('SequenceOfType', 'SetOfType'):
return compute_random_sequenceof(basic, pool)
# Random values for basic types
rand_int = lambda ty: str(random.randint(long(ty.Min), long(ty.Max)))
rand_real = lambda ty: str(random.uniform(float(ty.Min), float(ty.Max)))
rand_bool = lambda _: random.choice(['TRUE', 'FALSE'])
rand_enum = lambda ty: random.choice(ty.EnumValues.keys())
def compute_random_choice(asn1_ty, pool):
''' Select randomly a choice item and set a random value '''
choice = random.choice(asn1_ty.Children.keys())
value_ty = asn1_ty.Children[choice]
value = compute_random_value(value_ty, pool)
return '{}: {}'.format(choice, value)
def compute_random_sequence(asn1_ty, pool):
''' Compute randomly the values of SEQUENCE fields '''
res = []
for name, ty in asn1_ty.Children.viewitems():
res.append('{} {}'.format(name, compute_random_value(ty, pool)))
return '{{ {} }}'.format(', '.join(res))
def compute_random_sequenceof(asn1_ty, pool):
''' Compute a list of a random size and random values '''
size = random.randint(int(asn1_ty.Min), int(asn1_ty.Max))
elems = []
for _ in xrange(size):
elems.append(compute_random_value(asn1_ty, pool))
return '{{ {} }}'.format(', '.join(elems))
# Set of functions used by the simulator to compute the combination input
# parameters for each ASN.1 data type. Yield ASN.1 Value Notation strings
# ASN.1 types must be in the format generated by ASN1SCC Python backend
def compute_combinations(asn1_ty, pool):
''' Top-level, type-dispatching function
"pool" is the set of types, found in the process.dataview attribute '''
basic = opengeode.ogParser.find_basic_type(asn1_ty.type, pool)
# Python2 has no "yield from"...
if basic.kind.startswith('Integer'):
for each in compute_integer_combinations(basic):
yield each
elif basic.kind == 'BooleanType':
for each in compute_boolean_combinations(basic):
yield each
elif basic.kind.startswith('Real'):
for each in compute_real_combinations(basic):
yield each
elif basic.kind == 'EnumeratedType':
for each in compute_enumerated_combinations(basic):
yield each
elif basic.kind == 'ChoiceType':
for each in compute_choice_combinations(basic, pool):
yield each
elif basic.kind in ('SequenceType', 'SetType'):
for each in compute_sequence_combinations(basic, pool):
yield each
elif basic.kind in ('SequenceOfType', 'SetOfType'):
for each in compute_sequenceof_combinations(basic, pool):
yield each
def compute_integer_combinations(asn1_ty, max_iter=0):
''' Generator returning all integer values, with optional limit '''
# Do not use xrange, it needs a value that fits in a C long
max_iter = (long(asn1_ty.Min)
+ max_iter) if max_iter != 0 else long(asn1_ty.Max)
for each in itertools.count(long(asn1_ty.Min)):
if each > max_iter:
break
yield str(each)
def compute_real_combinations(asn1_ty):
''' Generator returning three real values only (set is infinite) '''
yield asn1_ty.Min
yield str((float(asn1_ty.Max) + float(asn1_ty.Min)) / 2.0)
yield asn1_ty.Max
def compute_boolean_combinations(asn1_ty):
''' Generator returning all combinations of boolean '''
yield 'TRUE'
yield 'FALSE'
def compute_enumerated_combinations(asn1_ty):
''' Generator returning all combinations of enumerated '''
for each in asn1_ty.EnumValues.viewkeys():
yield each
def compute_choice_combinations(asn1_ty, pool):
''' Generator returning all combinations of choice components '''
for discr, value_ty in asn1_ty.Children.viewitems():
for each in compute_combinations(value_ty, pool):
yield '{}: {}'.format(discr, each)
def compute_sequence_combinations(asn1_ty, pool):
''' Generator returning all combinations of SEQUENCE types '''
# Prepare generators to compute combinations of each field
elems = (compute_combinations(sort, pool)
for sort in asn1_ty.Children.viewvalues())
# Combine all field generators to get the complete set of values
for each in itertools.product(*elems):
# each is a tuple with values for the sequence, join with fieldnames
pairs = itertools.izip(asn1_ty.Children.viewkeys(), each)
res = ('{} {}'.format(name, value) for name, value in pairs)
yield '{{ {} }}'.format(', '.join(res))
def compute_sequenceof_combinations(asn1_ty, pool):
''' Generator returning all combinations of arrays '''
for size in xrange(int(asn1_ty.Min), int(asn1_ty.Max) + 1):
elems = []
for _ in xrange(size):
elems.append(compute_combinations(asn1_ty, pool))
for each in itertools.product(*elems):
yield '{{ {} }}'.format(', '.join(each))
......@@ -21,7 +21,6 @@
import os
import ctypes
import itertools
import random
from functools import partial
from itertools import chain
......@@ -39,6 +38,7 @@ import vn
import vdm_vn
import resources
import vdmHandler
from ValueGenerator import compute_random_value, compute_combinations
try:
import opengeode
......@@ -62,151 +62,6 @@ CleanName = lambda name: name.replace(UNICODE_SEP, '.')
UnicodeName = lambda name: name.replace('.', UNICODE_SEP)
# Set of functions used by the simulator to compute a random value for
# a given ASN.1 type, return a Value Notation string
def compute_random_value(asn1_ty, pool):
''' Top-level, type-dispatching function
pool is the set of types from process.dataview attribute '''
basic = opengeode.ogParser.find_basic_type(asn1_ty.type, pool)
if basic.kind.startswith('Integer'):
return rand_int(basic)
elif basic.kind == 'BooleanType':
return rand_bool(basic)
elif basic.kind.startswith('Real'):
return rand_real(basic)
elif basic.kind == 'EnumeratedType':
return rand_enum(basic)
elif basic.kind == 'ChoiceType':
return compute_random_choice(basic, pool)
elif basic.kind in ('SequenceType', 'SetType'):
return compute_random_sequence(basic, pool)
elif basic.kind in ('SequenceOfType', 'SetOfType'):
return compute_random_sequenceof(basic, pool)
# Random values for basic types
rand_int = lambda ty: str(random.randint(long(ty.Min), long(ty.Max)))
rand_real = lambda ty: str(random.uniform(float(ty.Min), float(ty.Max)))
rand_bool = lambda _: random.choice(['TRUE', 'FALSE'])
rand_enum = lambda ty: random.choice(ty.EnumValues.keys())
def compute_random_choice(asn1_ty, pool):
''' Select randomly a choice item and set a random value '''
choice = random.choice(asn1_ty.Children.keys())
value_ty = asn1_ty.Children[choice]
value = compute_random_value(value_ty, pool)
return '{}: {}'.format(choice, value)
def compute_random_sequence(asn1_ty, pool):
''' Compute randomly the values of SEQUENCE fields '''
res = []
for name, ty in asn1_ty.Children.viewitems():
res.append('{} {}'.format(name, compute_random_value(ty, pool)))
return '{{ {} }}'.format(', '.join(res))
def compute_random_sequenceof(asn1_ty, pool):
''' Compute a list of a random size and random values '''
size = random.randint(int(asn1_ty.Min), int(asn1_ty.Max))
elems = []
for _ in xrange(size):
elems.append(compute_random_value(asn1_ty, pool))
return '{{ {} }}'.format(', '.join(elems))
# Set of functions used by the simulator to compute the combination input
# parameters for each ASN.1 data type. Yield ASN.1 Value Notation strings
# ASN.1 types must be in the format generated by ASN1SCC Python backend
def compute_combinations(asn1_ty, pool):
''' Top-level, type-dispatching function
"pool" is the set of types, found in the process.dataview attribute '''
basic = opengeode.ogParser.find_basic_type(asn1_ty.type, pool)
# Python2 has no "yield from"...
if basic.kind.startswith('Integer'):
for each in compute_integer_combinations(basic):
yield each
elif basic.kind == 'BooleanType':
for each in compute_boolean_combinations(basic):
yield each
elif basic.kind.startswith('Real'):
for each in compute_real_combinations(basic):
yield each
elif basic.kind == 'EnumeratedType':
for each in compute_enumerated_combinations(basic):
yield each
elif basic.kind == 'ChoiceType':
for each in compute_choice_combinations(basic, pool):
yield each
elif basic.kind in ('SequenceType', 'SetType'):
for each in compute_sequence_combinations(basic, pool):
yield each
elif basic.kind in ('SequenceOfType', 'SetOfType'):
for each in compute_sequenceof_combinations(basic, pool):
yield each
def compute_integer_combinations(asn1_ty, max_iter=0):
''' Generator returning all integer values, with optional limit '''
# Do not use xrange, it needs a value that fits in a C long
max_iter = (long(asn1_ty.Min)
+ max_iter) if max_iter != 0 else long(asn1_ty.Max)
for each in itertools.count(long(asn1_ty.Min)):
if each > max_iter:
break
yield str(each)
def compute_real_combinations(asn1_ty):
''' Generator returning three real values only (set is infinite) '''
yield asn1_ty.Min
yield str((float(asn1_ty.Max) + float(asn1_ty.Min)) / 2.0)
yield asn1_ty.Max
def compute_boolean_combinations(asn1_ty):
''' Generator returning all combinations of boolean '''
yield 'TRUE'
yield 'FALSE'
def compute_enumerated_combinations(asn1_ty):
''' Generator returning all combinations of enumerated '''
for each in asn1_ty.EnumValues.viewkeys():
yield each
def compute_choice_combinations(asn1_ty, pool):
''' Generator returning all combinations of choice components '''
for discr, value_ty in asn1_ty.Children.viewitems():
for each in compute_combinations(value_ty, pool):
yield '{}: {}'.format(discr, each)
def compute_sequence_combinations(asn1_ty, pool):
''' Generator returning all combinations of SEQUENCE types '''
# Prepare generators to compute combinations of each field
elems = (compute_combinations(sort, pool)
for sort in asn1_ty.Children.viewvalues())
# Combine all field generators to get the complete set of values
for each in itertools.product(*elems):
# each is a tuple with values for the sequence, join with fieldnames
pairs = itertools.izip(asn1_ty.Children.viewkeys(), each)
res = ('{} {}'.format(name, value) for name, value in pairs)
yield '{{ {} }}'.format(', '.join(res))
def compute_sequenceof_combinations(asn1_ty, pool):
''' Generator returning all combinations of arrays '''
for size in xrange(int(asn1_ty.Min), int(asn1_ty.Max) + 1):
elems = []
for _ in xrange(size):
elems.append(compute_combinations(asn1_ty, pool))
for each in itertools.product(*elems):
yield '{{ {} }}'.format(', '.join(each))
class SendTC(QUndoCommand):
''' Undo command to send a message to the running system '''
def __init__(self, handler, old_state):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment