Pseudo randomly add checks

This commit is contained in:
Bhargava Shastry 2019-07-29 16:38:24 +02:00
parent 00accd9daa
commit 3a6f28589e
2 changed files with 56 additions and 30 deletions

View File

@ -295,20 +295,20 @@ void ProtoConverter::visit(ValueType const& _x)
{ {
switch (_x.value_type_oneof_case()) switch (_x.value_type_oneof_case())
{ {
case ValueType::kInty: case ValueType::kInty:
visit(_x.inty()); visit(_x.inty());
break; break;
case ValueType::kByty: case ValueType::kByty:
visit(_x.byty()); visit(_x.byty());
break; break;
case ValueType::kAdty: case ValueType::kAdty:
visit(_x.adty()); visit(_x.adty());
break; break;
case ValueType::kBoolty: case ValueType::kBoolty:
visit(_x.boolty()); visit(_x.boolty());
break; break;
case ValueType::VALUE_TYPE_ONEOF_NOT_SET: case ValueType::VALUE_TYPE_ONEOF_NOT_SET:
break; break;
} }
} }
@ -328,7 +328,7 @@ void ProtoConverter::visit(StructType const&)
std::string ProtoConverter::arrayDimInfoAsString(ArrayDimensionInfo const& _x) std::string ProtoConverter::arrayDimInfoAsString(ArrayDimensionInfo const& _x)
{ {
unsigned arrLength = getArrayLengthFromFuzz(_x.length()); unsigned arrLength = getStaticArrayLengthFromFuzz(_x.length());
if (_x.is_static()) if (_x.is_static())
return Whiskers(R"([<length>])") return Whiskers(R"([<length>])")
("length", std::to_string(arrLength)) ("length", std::to_string(arrLength))
@ -398,7 +398,7 @@ ProtoConverter::DataType ProtoConverter::getDataTypeByBaseType(ArrayType const&
// Adds a resize operation for a given dimension of type `_type` and expression referenced // Adds a resize operation for a given dimension of type `_type` and expression referenced
// by `_var`. `_isStatic` is true for statically sized dimensions, false otherwise. // by `_var`. `_isStatic` is true for statically sized dimensions, false otherwise.
// `_arrayLen` is equal to length of statically sized array dimension. For dynamically // `_arrayLen` is equal to length of statically sized array dimension. For dynamically
// sized dimension, we use `getArrayLengthFromFuzz()` and a monotonically increasing // sized dimension, we use `getDynArrayLengthFromFuzz()` and a monotonically increasing
// counter to obtain actual length. Function returns dimension length. // counter to obtain actual length. Function returns dimension length.
unsigned ProtoConverter::resizeDimension( unsigned ProtoConverter::resizeDimension(
bool _isStatic, bool _isStatic,
@ -413,7 +413,7 @@ unsigned ProtoConverter::resizeDimension(
length = _arrayLen; length = _arrayLen;
else else
{ {
length = getArrayLengthFromFuzz(_arrayLen, getNextCounter()); length = getDynArrayLengthFromFuzz(_arrayLen, getNextCounter());
// If local var, new T(l); // If local var, new T(l);
// Else, l; // Else, l;
@ -438,8 +438,10 @@ unsigned ProtoConverter::resizeDimension(
addVarDef(lhs, rhs); addVarDef(lhs, rhs);
} }
// if (c.length != l) // Add checks on array length pseudo randomly
checkResizeOp(_param, length); if (addCheck(getNextCounter()))
// if (c.length != l)
checkResizeOp(_param, length);
return length; return length;
} }
@ -455,12 +457,19 @@ void ProtoConverter::resizeHelper(
// (depth-first) recurse otherwise. // (depth-first) recurse otherwise.
if (_arrInfoVec.empty()) if (_arrInfoVec.empty())
{ {
// expression name is _var // We are at the leaf node now.
// value is a value of base type // To ensure we do not create a very large test case
std::string value = getValueByBaseType(_x); // especially for multidimensional dynamic arrays,
// add assignment and check // we create a checked assignment pseudo randomly.
DataType dataType = getDataTypeByBaseType(_x); if (addCheck(getNextCounter()))
addCheckedVarDef(dataType, _varName, _paramName, value); {
// expression name is _var
// value is a value of base type
std::string value = getValueByBaseType(_x);
// add assignment and check
DataType dataType = getDataTypeByBaseType(_x);
addCheckedVarDef(dataType, _varName, _paramName, value);
}
} }
else else
{ {

View File

@ -334,14 +334,27 @@ private:
return toHex(maskUnsignedInt(_counter, _numMaskNibbles), HexPrefix::Add); return toHex(maskUnsignedInt(_counter, _numMaskNibbles), HexPrefix::Add);
} }
static unsigned getArrayLengthFromFuzz(unsigned _fuzz, unsigned _counter = 0) static unsigned getDynArrayLengthFromFuzz(unsigned _fuzz, unsigned _counter)
{ {
return ((_fuzz + _counter) % s_maxArrayLength) + 1; return ((_fuzz + _counter) % s_maxDynamicArrayLength) + 1;
}
static unsigned getStaticArrayLengthFromFuzz(unsigned _fuzz)
{
return (_fuzz % s_maxStaticArrayLength) + 1;
} }
static std::pair<bool, unsigned> arrayDimInfoAsPair(ArrayDimensionInfo const& _x) static std::pair<bool, unsigned> arrayDimInfoAsPair(ArrayDimensionInfo const& _x)
{ {
return std::make_pair(_x.is_static(), getArrayLengthFromFuzz(_x.length())); return std::make_pair(
_x.is_static(),
getStaticArrayLengthFromFuzz(_x.length())
);
}
static bool addCheck(unsigned _counter)
{
return (_counter % s_arrayCheckFrequency == 0);
} }
/// Contains the test program /// Contains the test program
@ -360,8 +373,12 @@ private:
unsigned m_varCounter; unsigned m_varCounter;
/// Monotonically increasing return value for error reporting /// Monotonically increasing return value for error reporting
unsigned m_returnValue; unsigned m_returnValue;
static unsigned constexpr s_maxArrayLength = 2; static unsigned constexpr s_maxStaticArrayLength = 7;
static unsigned constexpr s_maxArrayDimensions = 10; static unsigned constexpr s_maxDynamicArrayLength = 5;
static unsigned constexpr s_maxArrayDimensions = 21;
/// Add check only if counter returned by getNextCounter()
/// is divisible by s_arrayCheckFrequency
static unsigned constexpr s_arrayCheckFrequency = 11;
/// Prefixes for declared and parameterized variable names /// Prefixes for declared and parameterized variable names
static auto constexpr s_varNamePrefix = "x_"; static auto constexpr s_varNamePrefix = "x_";
static auto constexpr s_paramNamePrefix = "c_"; static auto constexpr s_paramNamePrefix = "c_";