|
- #pragma once
-
- #include "asserts.h"
- #include <vector>
-
- /**
- * Utility class that counts up in binary using an array of ints to hold the bits.
- *
- */
- class BitCounter
- {
- public:
- void reset(int size)
- {
- done = false;
- state.resize(size);
- for (int i = 0; i < size; ++i) {
- state[i] = 0;
- }
- }
- bool atMax() const
- {
- for (size_t i = 0; i < state.size(); ++i) {
- if (state[i] == 0) {
- return false;
- }
- }
- return true;
- }
- bool isDone() const
- {
- return done;
- }
- void next()
- {
- if (atMax()) {
- done = true;
- return;
- }
- state[0]++;
- for (size_t i = 0; i < state.size(); ++i) {
- if (state[i] > 1) {
- state[i] = 0;
- ++state[i + 1];
- }
- }
-
- }
-
- template <typename Q>
- void setState(std::vector<Q>& testSignal, const std::vector< std::pair<float, float>>* signalLimits)
- {
- for (int i = (int) state.size() - 1; i >= 0; --i) {
- float min = -10.f;
- float max = 10.f;
- if (signalLimits) { // here we want to clip these to the possible values of params
- min = (*signalLimits)[i].first;
- max = (*signalLimits)[i].second;
-
- assertNE(min, max);
- assertGT(max, min);
- }
- testSignal[i].value = state[i] > 0 ? max : min;
- }
- }
-
-
- void dump(const char * label)
- {
- printf("State (%s): ", label);
- for (int i = (int) state.size() - 1; i >= 0; --i) {
- printf("%d ", state[i]);
- }
- printf("\n");
- }
- private:
- std::vector<int> state;
- bool done;
-
- };
-
-
- /**
- * Tests a composite by feeding all the inputs and parameters (in every possible permutation)
- * with extreme inputs. Asserts that the output stays in a semi-sane range.
- * Typically this test will fail by triggering an assert in some distant code.
- */
- template <typename T>
- class ExtremeTester
- {
- public:
-
- static void test(T& dut,
- const std::vector< std::pair<float, float>>& paramLimits,
- bool checkOutput,
- const char * testName)
- {
- printf("extreme test starting for %s. %s ....\n", testName, checkOutput ? "test output" : "");
- const int numInputs = dut.NUM_INPUTS;
- const int numParams = dut.NUM_PARAMS;
- const int numOutputs = dut.NUM_OUTPUTS;
- assert(numInputs < 20);
- assertEQ(paramLimits.size(), numParams);
-
- const std::vector< std::pair<float, float>> * nullLimits = nullptr;
- BitCounter inputState;
- BitCounter paramsState;
- for (inputState.reset(numInputs); !inputState.isDone(); inputState.next()) {
- inputState.setState(dut.inputs, nullLimits);
- for (paramsState.reset(numParams); !paramsState.isDone(); paramsState.next()) {
- paramsState.setState(dut.params, ¶mLimits);
- for (int i = 0; i < 100; ++i) {
- dut.step();
- for (int j = 0; j < numOutputs; ++j) {
- const float out = dut.outputs[j].value;
- if (checkOutput) {
- assertGE(out, -150);
- assertLE(out, 150);
- }
- }
- }
- }
- }
- printf("extreme test done\n");
- }
- };
|