<commit_before>#include "Conformance.h"

#include "vector/Reference.h"
#include "vector/Intrinsic.h"
#include "vector/Aliased.h"

#include "Platform.h"

#include <cstdio>
#include <cmath>

////////////////////////////////////////////////////////////////////////////////
//! Macro for defining a conformance test.
#define TEST(NAME)                                                              \
template<typename M, typename V, typename S>                                    \
struct NAME##T {                                                                \
    static constexpr const char* name = #NAME;                                  \
    bool operator()() const;                                                    \
};                                                                              \
template<typename M, typename V, typename S>                                    \
inline bool NAME##T<M, V, S>::operator()() const

//------------------------------------------------------------------------------
TEST(testComparison) {
    V a(1.0f, 2.0f, 3.0f, 4.0f);
    V b(1.0f, 1.0f, 2.0f, 3.0f);

    if (a != a) {
        return false;
    }
    if (!(a == a)) {
        return false;
    }
    if (a == b) {
        return false;
    }
    if (!(a != b)) {
        return false;
    }
    return true;
}

//------------------------------------------------------------------------------
TEST(testElements) {
    V a(1.0f, 2.0f, 3.0f, 4.0f);
    V b(1.0f, 1.0f, 2.0f, 3.0f);

    if (a[0] != S(1.0f)) {
        return false;
    }
    if (a[1] != S(2.0f)) {
        return false;
    }
    if (a[2] != S(3.0f)) {
        return false;
    }
    if (a[3] != S(4.0f)) {
        return false;
    }

    b[0] = -1.0f;
    if (b != V(-1.0f, 1.0f, 2.0f, 3.0f)) {
        return false;
    }

    b[1] = -2.0f;
    if (b != V(-1.0f, -2.0f, 2.0f, 3.0f)) {
        return false;
    }

    b[2] = -3.0f;
    if (b != V(-1.0f, -2.0f, -3.0f, 3.0f)) {
        return false;
    }

    b[3] = -4.0f;
    if (b != V(-1.0f, -2.0f, -3.0f, -4.0f)) {
        return false;
    }

    return true;
}

//------------------------------------------------------------------------------
TEST(testAlgebraic) {
    V a(1.0f, 2.0f, 3.0f, 4.0f);
    V b(2.0f, 3.0f, 4.0f, 5.0f);
    S c = 0.5f;
    S d = 3.0f;

    if (a + b != V(3.0f, 5.0f, 7.0f, 9.0f)) {
        return false;
    }

    if (a - b != V(-1.0f, -1.0f, -1.0f, -1.0f)) {
        return false;
    }

    if (a * c != V(0.5f, 1.0f, 1.5f, 2.0f)) {
        return false;
    }

    if (a / c != V(2.0f, 4.0f, 6.0f, 8.0f)) {
        return false;
    }

    if (c * (a + b) != c * a + c * b) {
        return false;
    }

    if ((c + d) * a != c * a + d * a) {
        return false;
    }

    return true;
}

//------------------------------------------------------------------------------
TEST(testLength) {
    V a(1.0f, 2.0f, 3.0f, 4.0f);
    V b(2.0f, 3.0f, 4.0f, 5.0f);

    if (a.LengthSqr() != (1.0f + 4.0f + 9.0f + 16.0f)) {
        return false;
    }
    if (a.Length() != std::sqrt(1.0f + 4.0f + 9.0f + 16.0f)) {
        return false;
    }

    S lerr = a.Length() / a.LengthFast();
    // Maximum relative error of rsqrtps is less than 1.5*2^-12
    if (1.0f - 3e4f > lerr || lerr > 1.0f + 3e-4f) {
        return false;
    }

    S asqr = a.Normalize().LengthSqr();
    if (1.0f - 1e-6f > asqr || asqr > 1.0f + 1e-6f) {
        return false;
    }

    S bsqr = b.NormalizeFast().LengthSqr();
    // Maximum relative error of rsqrtps is less than 1.5*2^-12
    if (1.0f - 3e-4f > bsqr || bsqr > 1.0f + 3e-4f) {
        return false;
    }

    return true;
}

//------------------------------------------------------------------------------
TEST(testDotProduct) {
    V a(1.0f, 2.0f, 3.0f, 4.0f);
    V b(2.0f, 3.0f, 4.0f, 5.0f);

    if (a * b != (2.0f + 6.0f + 12.0f + 20.0f)) {
        return false;
    }
    return true;
}

//------------------------------------------------------------------------------
TEST(testCrossProduct) {
    V a(2.0f, 0.0f, 0.0f, 0.0f);
    V b(0.0f, 3.0f, 0.0f, 0.0f);

    if (a % b != V(0.0f, 0.0f, 6.0f, 0.0f)) {
        return false;
    }

    if (a % b + b % a != V(0.0f, 0.0f, 0.0f, 0.0f)) {
        return false;
    }
    return true;
}

//------------------------------------------------------------------------------
TEST(testMatrixScalarProduct) {
    M A = {
        1.f, 2.f, 3.f, 4.f,
        2.f, 3.f, 4.f, 3.f,
        3.f, 4.f, 3.f, 2.f,
        4.f, 3.f, 2.f, 1.f,
    };

    M B = {
        2.f, 4.f, 6.f, 8.f,
        4.f, 6.f, 8.f, 6.f,
        6.f, 8.f, 6.f, 4.f,
        8.f, 6.f, 4.f, 2.f,
    };

    M C = A * 2.f;

    if (C != B) {
        return false;
    }

    M D = B / 2.0f;

    if (D != A) {
        return false;
    }

    return true;
}

//------------------------------------------------------------------------------
TEST(testMatrixVectorProduct) {
    M I = {
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
        0.f, 0.f, 1.f, 0.f,
        0.f, 0.f, 0.f, 1.f,
    };

    V x = {
        1.f, 2.f, 3.f, 4.f,
    };

    if (I * x != x) {
        return false;
    }

    M A = {
        0.f, 0.f, 0.f, 1.f,
        0.f, 0.f, 1.f, 0.f,
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
    };

    V y = {
        4.f, 3.f, 1.f, 2.f,
    };

    if (A * x != y) {
        return false;
    }

    if (A * x + A * y != A * (x + y)) {
        return false;
    }

    S z = 0.5f;

    if (A * (x * z) != (A * x) * z) {
        return false;
    }

    return true;
}

//------------------------------------------------------------------------------
TEST(testMatrixMatrixProduct) {
    M A = {
        1.f, 2.f, 3.f, 4.f,
        2.f, 3.f, 4.f, 3.f,
        3.f, 4.f, 3.f, 2.f,
        4.f, 3.f, 2.f, 1.f,
    };

    M B = {
        0.f, 0.f, 0.f, 1.f,
        0.f, 0.f, 1.f, 0.f,
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
    };

    M C = {
        3.f, 4.f, 2.f, 1.f,
        4.f, 3.f, 3.f, 2.f,
        3.f, 2.f, 4.f, 3.f,
        2.f, 1.f, 3.f, 4.f,
    };

    if (A * B != C) {
        return false;
    }

    V x = {
        1.f, 2.f, 3.f, 4.f,
    };

    if ((B * A) * x != B * (A * x)) {
        return false;
    }

    return true;
}

//------------------------------------------------------------------------------
TEST(testMatrixTranspose) {
    M A = {
        1.f, 2.f, 3.f, 4.f,
        2.f, 3.f, 4.f, 5.f,
        3.f, 4.f, 5.f, 6.f,
        4.f, 5.f, 6.f, 7.f,
    };

    M At = {
        1.f, 2.f, 3.f, 4.f,
        2.f, 3.f, 4.f, 5.f,
        3.f, 4.f, 5.f, 6.f,
        4.f, 5.f, 6.f, 7.f,
    };

    M B = {
        3.f, 4.f, 2.f, 1.f,
        4.f, 3.f, 3.f, 2.f,
        3.f, 2.f, 4.f, 3.f,
        2.f, 1.f, 3.f, 4.f,
    };

    if (A.Transpose() != At) {
        return false;
    }

    if (A.Transpose().Transpose() != A) {
        return false;
    }

    if (A.Transpose() * B.Transpose() != (B * A).Transpose()) {
        return false;
    }

    return true;
}

////////////////////////////////////////////////////////////////////////////////
//! Helper function for executing conformance tests on each implementation.
template<template<typename, typename, typename> class Func>
bool testFunc() {
    constexpr char const* result_strings[] = {
        "failed", "ok",
    };

    bool b0 = Func<reference::Matrix, reference::Vector, reference::Scalar>()();
    bool b1 = Func<intrinsic::Matrix, intrinsic::Vector, intrinsic::Scalar>()();
    bool b2 = Func<aliased::Matrix, aliased::Vector, aliased::Scalar>()();

    // Print results
    printf_s("  %-24s %-15s %-15s %-15s\n",
             Func<reference::Matrix, reference::Vector, reference::Scalar>::name,
             result_strings[b0],
             result_strings[b1],
             result_strings[b2]);

    return b0 && b1 && b2;
}

//------------------------------------------------------------------------------
bool testComparison() {
    return testFunc<testComparisonT>();
}

bool testElements() {
    return testFunc<testElementsT>();
}

bool testAlgebraic() {
    return testFunc<testAlgebraicT>();
}

bool testLength() {
    return testFunc<testLengthT>();
}

bool testDotProduct() {
    return testFunc<testDotProductT>();
}

bool testCrossProduct() {
    return testFunc<testCrossProductT>();
}

bool testMatrixProduct() {
    bool b1 = testFunc<testMatrixScalarProductT>();
    bool b2 = testFunc<testMatrixVectorProductT>();
    bool b3 = testFunc<testMatrixMatrixProductT>();
    return b1 && b2 && b3;
}

bool testMatrixTranspose() {
    return testFunc<testMatrixTransposeT>();
}
<commit_msg>Refactor conformance tests using EXPECT_ macros<commit_after>#include "Conformance.h"

#include "vector/Reference.h"
#include "vector/Intrinsic.h"
#include "vector/Aliased.h"

#include "Platform.h"

#include <cstdio>
#include <cmath>

////////////////////////////////////////////////////////////////////////////////
//! Macro for defining a conformance test.
#define TEST(NAME)                                                              \
template<typename M, typename V, typename S>                                    \
struct NAME##T {                                                                \
    static constexpr const char* name = #NAME;                                  \
    void operator()() const;                                                    \
};                                                                              \
template<typename M, typename V, typename S>                                    \
inline void NAME##T<M, V, S>::operator()() const

//------------------------------------------------------------------------------
struct TestFailure {};

//------------------------------------------------------------------------------
#define EXPECT_TRUE(expr)                                                       \
    if (!(expr)) { throw TestFailure{}; }

//------------------------------------------------------------------------------
#define EXPECT_FALSE(expr)                                                      \
    if ((expr)) { throw TestFailure{}; }

//------------------------------------------------------------------------------
#define _EXPECT_OP(lhs, op, rhs) EXPECT_TRUE((lhs) op (rhs))

//------------------------------------------------------------------------------
#define EXPECT_EQ(lhs, rhs) _EXPECT_OP(lhs, ==, rhs)
#define EXPECT_NE(lhs, rhs) _EXPECT_OP(lhs, !=, rhs)

//------------------------------------------------------------------------------
#define EXPECT_EQ_EPS(lhs, rhs, eps) {                                          \
    auto del = lhs - rhs;                                                       \
    EXPECT_TRUE(-eps < del && del < eps);                                       \
}

//------------------------------------------------------------------------------
#define EXPECT_NE_EPS(lhs, rhs, eps) {                                          \
    auto del = lhs - rhs;                                                       \
    EXPECT_TRUE(del < -eps || eps < del);                                       \
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

//------------------------------------------------------------------------------
TEST(testComparison) {
    V a(1.0f, 2.0f, 3.0f, 4.0f);
    V b(1.0f, 1.0f, 2.0f, 3.0f);

    EXPECT_TRUE(a == a);
    EXPECT_FALSE(a != a);
    EXPECT_FALSE(a == b);
    EXPECT_TRUE(a != b);
}

//------------------------------------------------------------------------------
TEST(testElements) {
    V a(1.0f, 2.0f, 3.0f, 4.0f);
    V b(1.0f, 1.0f, 2.0f, 3.0f);

    EXPECT_EQ(a[0], S(1.0f));
    EXPECT_EQ(a[1], S(2.0f));
    EXPECT_EQ(a[2], S(3.0f));
    EXPECT_EQ(a[3], S(4.0f));

    b[0] = -1.0f;
    EXPECT_EQ(b, V(-1.0f, 1.0f, 2.0f, 3.0f));
    b[1] = -2.0f;
    EXPECT_EQ(b, V(-1.0f, -2.0f, 2.0f, 3.0f));
    b[2] = -3.0f;
    EXPECT_EQ(b, V(-1.0f, -2.0f, -3.0f, 3.0f));
    b[3] = -4.0f;
    EXPECT_EQ(b, V(-1.0f, -2.0f, -3.0f, -4.0f));
}

//------------------------------------------------------------------------------
TEST(testAlgebraic) {
    V a(1.0f, 2.0f, 3.0f, 4.0f);
    V b(2.0f, 3.0f, 4.0f, 5.0f);
    S c = 0.5f;
    S d = 3.0f;

    EXPECT_EQ(a + b, V(3.0f, 5.0f, 7.0f, 9.0f));
    EXPECT_EQ(a - b, V(-1.0f, -1.0f, -1.0f, -1.0f));
    EXPECT_EQ(a * c, V(0.5f, 1.0f, 1.5f, 2.0f));
    EXPECT_EQ(a / c, V(2.0f, 4.0f, 6.0f, 8.0f));
    EXPECT_EQ(c * (a + b), c * a + c * b);
    EXPECT_EQ((c + d) * a, c * a + d * a);
}

//------------------------------------------------------------------------------
TEST(testLength) {
    V a(1.0f, 2.0f, 3.0f, 4.0f);
    V b(2.0f, 3.0f, 4.0f, 5.0f);

    EXPECT_EQ(a.LengthSqr(), 1.0f + 4.0f + 9.0f + 16.0f);
    EXPECT_EQ(a.Length(), std::sqrt(1.0f + 4.0f + 9.0f + 16.0f));

    S lerr = a.Length() / a.LengthFast();
    // Maximum relative error of rsqrtps is less than 1.5*2^-12
    EXPECT_EQ_EPS(lerr, 1.0f, 3e-4f);

    S asqr = a.Normalize().LengthSqr();
    EXPECT_EQ_EPS(asqr, 1.0f, 1e-6f);

    S bsqr = b.NormalizeFast().LengthSqr();
    // Maximum relative error of rsqrtps is less than 1.5*2^-12
    EXPECT_EQ_EPS(bsqr, 1.0f, 3e-4f);
}

//------------------------------------------------------------------------------
TEST(testDotProduct) {
    V a(1.0f, 2.0f, 3.0f, 4.0f);
    V b(2.0f, 3.0f, 4.0f, 5.0f);

    EXPECT_EQ(a * b, 2.0f + 6.0f + 12.0f + 20.0f);
}

//------------------------------------------------------------------------------
TEST(testCrossProduct) {
    V a(2.0f, 0.0f, 0.0f, 0.0f);
    V b(0.0f, 3.0f, 0.0f, 0.0f);

    EXPECT_EQ(a % b, V(0.0f, 0.0f, 6.0f, 0.0f));
    EXPECT_EQ(a % b + b % a, V(0.0f, 0.0f, 0.0f, 0.0f));
}

//------------------------------------------------------------------------------
TEST(testMatrixScalarProduct) {
    M A = {
        1.f, 2.f, 3.f, 4.f,
        2.f, 3.f, 4.f, 3.f,
        3.f, 4.f, 3.f, 2.f,
        4.f, 3.f, 2.f, 1.f,
    };

    M B = {
        2.f, 4.f, 6.f, 8.f,
        4.f, 6.f, 8.f, 6.f,
        6.f, 8.f, 6.f, 4.f,
        8.f, 6.f, 4.f, 2.f,
    };

    M C = A * 2.f;
    EXPECT_EQ(C, B);

    M D = B / 2.0f;
    EXPECT_EQ(D, A);
}

//------------------------------------------------------------------------------
TEST(testMatrixVectorProduct) {
    M I = {
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
        0.f, 0.f, 1.f, 0.f,
        0.f, 0.f, 0.f, 1.f,
    };

    V x = {
        1.f, 2.f, 3.f, 4.f,
    };

    M A = {
        0.f, 0.f, 0.f, 1.f,
        0.f, 0.f, 1.f, 0.f,
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
    };

    V y = {
        4.f, 3.f, 1.f, 2.f,
    };

    S z = 0.5f;

    EXPECT_EQ(I * x, x);
    EXPECT_EQ(A * x, y);
    EXPECT_EQ(A * x + A * y, A * (x + y));
    EXPECT_EQ(A * (x * z), (A * x) * z);
}

//------------------------------------------------------------------------------
TEST(testMatrixMatrixProduct) {
    M A = {
        1.f, 2.f, 3.f, 4.f,
        2.f, 3.f, 4.f, 3.f,
        3.f, 4.f, 3.f, 2.f,
        4.f, 3.f, 2.f, 1.f,
    };

    M B = {
        0.f, 0.f, 0.f, 1.f,
        0.f, 0.f, 1.f, 0.f,
        1.f, 0.f, 0.f, 0.f,
        0.f, 1.f, 0.f, 0.f,
    };

    M C = {
        3.f, 4.f, 2.f, 1.f,
        4.f, 3.f, 3.f, 2.f,
        3.f, 2.f, 4.f, 3.f,
        2.f, 1.f, 3.f, 4.f,
    };

    V x = {
        1.f, 2.f, 3.f, 4.f,
    };

    EXPECT_EQ(A * B, C);
    EXPECT_EQ((B * A) * x, B * (A * x));
}

//------------------------------------------------------------------------------
TEST(testMatrixTranspose) {
    M A = {
        1.f, 2.f, 3.f, 4.f,
        2.f, 3.f, 4.f, 5.f,
        3.f, 4.f, 5.f, 6.f,
        4.f, 5.f, 6.f, 7.f,
    };

    M At = {
        1.f, 2.f, 3.f, 4.f,
        2.f, 3.f, 4.f, 5.f,
        3.f, 4.f, 5.f, 6.f,
        4.f, 5.f, 6.f, 7.f,
    };

    M B = {
        3.f, 4.f, 2.f, 1.f,
        4.f, 3.f, 3.f, 2.f,
        3.f, 2.f, 4.f, 3.f,
        2.f, 1.f, 3.f, 4.f,
    };

    EXPECT_EQ(A.Transpose(), At);
    EXPECT_EQ(A.Transpose().Transpose(), A);
    EXPECT_EQ(A.Transpose() * B.Transpose(), (B * A).Transpose());
}

////////////////////////////////////////////////////////////////////////////////
//! Helper function for executing a conformance test for one implementation.
template<typename Func>
bool testFuncImpl() {
    try {
        Func()();
        return true;
    }
    catch (TestFailure const&)
    {
        return false;
    }
}

////////////////////////////////////////////////////////////////////////////////
//! Helper function for executing conformance tests on each implementation.
template<template<typename, typename, typename> class Func>
bool testFunc() {
    constexpr char const* result_strings[] = {
        "failed", "ok",
    };

    bool b0 = testFuncImpl<Func<reference::Matrix, reference::Vector, reference::Scalar>>();
    bool b1 = testFuncImpl<Func<intrinsic::Matrix, intrinsic::Vector, intrinsic::Scalar>>();
    bool b2 = testFuncImpl<Func<aliased::Matrix, aliased::Vector, aliased::Scalar>>();

    // Print results
    printf_s("  %-24s %-15s %-15s %-15s\n",
             Func<reference::Matrix, reference::Vector, reference::Scalar>::name,
             result_strings[b0],
             result_strings[b1],
             result_strings[b2]);

    return b0 && b1 && b2;
}

//------------------------------------------------------------------------------
bool testComparison() {
    return testFunc<testComparisonT>();
}

bool testElements() {
    return testFunc<testElementsT>();
}

bool testAlgebraic() {
    return testFunc<testAlgebraicT>();
}

bool testLength() {
    return testFunc<testLengthT>();
}

bool testDotProduct() {
    return testFunc<testDotProductT>();
}

bool testCrossProduct() {
    return testFunc<testCrossProductT>();
}

bool testMatrixProduct() {
    bool b1 = testFunc<testMatrixScalarProductT>();
    bool b2 = testFunc<testMatrixVectorProductT>();
    bool b3 = testFunc<testMatrixMatrixProductT>();
    return b1 && b2 && b3;
}

bool testMatrixTranspose() {
    return testFunc<testMatrixTransposeT>();
}
<|endoftext|>


<commit_before>// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chainparams.h>
#include <compressor.h>
#include <core_io.h>
#include <core_memusage.h>
#include <policy/policy.h>
#include <pubkey.h>
#include <script/descriptor.h>
#include <script/script.h>
#include <script/sign.h>
#include <script/signingprovider.h>
#include <script/standard.h>
#include <streams.h>
#include <test/fuzz/fuzz.h>
#include <univalue.h>
#include <util/memory.h>

void initialize()
{
    // Fuzzers using pubkey must hold an ECCVerifyHandle.
    static const auto verify_handle = MakeUnique<ECCVerifyHandle>();

    SelectParams(CBaseChainParams::REGTEST);
}

void test_one_input(const std::vector<uint8_t>& buffer)
{
    const CScript script(buffer.begin(), buffer.end());

    std::vector<unsigned char> compressed;
    if (CompressScript(script, compressed)) {
        const unsigned int size = compressed[0];
        compressed.erase(compressed.begin());
        assert(size >= 0 && size <= 5);
        CScript decompressed_script;
        const bool ok = DecompressScript(decompressed_script, size, compressed);
        assert(ok);
        assert(script == decompressed_script);
    }

    for (unsigned int size = 0; size < 6; ++size) {
        std::vector<unsigned char> vch(GetSpecialScriptSize(size), 0x00);
        vch.insert(vch.end(), buffer.begin(), buffer.end());
        CScript decompressed_script;
        (void)DecompressScript(decompressed_script, size, vch);
    }

    CTxDestination address;
    (void)ExtractDestination(script, address);

    txnouttype type_ret;
    std::vector<CTxDestination> addresses;
    int required_ret;
    (void)ExtractDestinations(script, type_ret, addresses, required_ret);

    (void)GetScriptForWitness(script);

    const FlatSigningProvider signing_provider;
    (void)InferDescriptor(script, signing_provider);

    (void)IsSegWitOutput(signing_provider, script);

    (void)IsSolvable(signing_provider, script);

    txnouttype which_type;
    (void)IsStandard(script, which_type);

    (void)RecursiveDynamicUsage(script);

    std::vector<std::vector<unsigned char>> solutions;
    (void)Solver(script, solutions);

    (void)script.HasValidOps();
    (void)script.IsPayToScriptHash();
    (void)script.IsPayToWitnessScriptHash();
    (void)script.IsPushOnly();
    (void)script.IsUnspendable();
    (void)script.GetSigOpCount(/* fAccurate= */ false);

    (void)FormatScript(script);
    (void)ScriptToAsmStr(script, false);
    (void)ScriptToAsmStr(script, true);

    UniValue o1(UniValue::VOBJ);
    ScriptPubKeyToUniv(script, o1, true);
    UniValue o2(UniValue::VOBJ);
    ScriptPubKeyToUniv(script, o2, false);
    UniValue o3(UniValue::VOBJ);
    ScriptToUniv(script, o3, true);
    UniValue o4(UniValue::VOBJ);
    ScriptToUniv(script, o4, false);
}
<commit_msg>tests: Remove unit test from fuzzing harness<commit_after>// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chainparams.h>
#include <compressor.h>
#include <core_io.h>
#include <core_memusage.h>
#include <policy/policy.h>
#include <pubkey.h>
#include <script/descriptor.h>
#include <script/script.h>
#include <script/sign.h>
#include <script/signingprovider.h>
#include <script/standard.h>
#include <streams.h>
#include <test/fuzz/fuzz.h>
#include <univalue.h>
#include <util/memory.h>

void initialize()
{
    // Fuzzers using pubkey must hold an ECCVerifyHandle.
    static const auto verify_handle = MakeUnique<ECCVerifyHandle>();

    SelectParams(CBaseChainParams::REGTEST);
}

void test_one_input(const std::vector<uint8_t>& buffer)
{
    const CScript script(buffer.begin(), buffer.end());

    std::vector<unsigned char> compressed;
    if (CompressScript(script, compressed)) {
        const unsigned int size = compressed[0];
        compressed.erase(compressed.begin());
        assert(size >= 0 && size <= 5);
        CScript decompressed_script;
        const bool ok = DecompressScript(decompressed_script, size, compressed);
        assert(ok);
        assert(script == decompressed_script);
    }

    CTxDestination address;
    (void)ExtractDestination(script, address);

    txnouttype type_ret;
    std::vector<CTxDestination> addresses;
    int required_ret;
    (void)ExtractDestinations(script, type_ret, addresses, required_ret);

    (void)GetScriptForWitness(script);

    const FlatSigningProvider signing_provider;
    (void)InferDescriptor(script, signing_provider);

    (void)IsSegWitOutput(signing_provider, script);

    (void)IsSolvable(signing_provider, script);

    txnouttype which_type;
    (void)IsStandard(script, which_type);

    (void)RecursiveDynamicUsage(script);

    std::vector<std::vector<unsigned char>> solutions;
    (void)Solver(script, solutions);

    (void)script.HasValidOps();
    (void)script.IsPayToScriptHash();
    (void)script.IsPayToWitnessScriptHash();
    (void)script.IsPushOnly();
    (void)script.IsUnspendable();
    (void)script.GetSigOpCount(/* fAccurate= */ false);

    (void)FormatScript(script);
    (void)ScriptToAsmStr(script, false);
    (void)ScriptToAsmStr(script, true);

    UniValue o1(UniValue::VOBJ);
    ScriptPubKeyToUniv(script, o1, true);
    UniValue o2(UniValue::VOBJ);
    ScriptPubKeyToUniv(script, o2, false);
    UniValue o3(UniValue::VOBJ);
    ScriptToUniv(script, o3, true);
    UniValue o4(UniValue::VOBJ);
    ScriptToUniv(script, o4, false);
}
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <string>
#include <fstream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <limits>
#include <stdexcept>
#include <cfloat>
#include <arrayfire.h>
#include <af/dim4.hpp>
#include <af/array.h>

typedef unsigned char  uchar;
typedef unsigned int   uint;
typedef unsigned short ushort;

template<typename inType, typename outType, typename FileElementType>
void readTests(const std::string &FileName, std::vector<af::dim4> &inputDims,
                std::vector<std::vector<inType> >   &testInputs,
                std::vector<std::vector<outType> > &testOutputs)
{
    using std::vector;

    std::ifstream testFile(FileName.c_str());
    if(testFile.good()) {
        unsigned inputCount;
        testFile >> inputCount;
        for(unsigned i=0; i<inputCount; i++) {
            af::dim4 temp(1);
            testFile >> temp;
            inputDims.push_back(temp);
        }

        unsigned testCount;
        testFile >> testCount;
        testOutputs.resize(testCount);

        vector<unsigned> testSizes(testCount);
        for(unsigned i = 0; i < testCount; i++) {
            testFile >> testSizes[i];
        }

        testInputs.resize(inputCount,vector<inType>(0));
        for(unsigned k=0; k<inputCount; k++) {
            unsigned nElems = inputDims[k].elements();
            testInputs[k].resize(nElems);
            FileElementType tmp;
            for(unsigned i = 0; i < nElems; i++) {
                testFile >> tmp;
                testInputs[k][i] = tmp;
            }
        }

        testOutputs.resize(testCount, vector<outType>(0));
        for(unsigned i = 0; i < testCount; i++) {
            testOutputs[i].resize(testSizes[i]);
            FileElementType tmp;
            for(unsigned j = 0; j < testSizes[i]; j++) {
                testFile >> tmp;
                testOutputs[i][j] = tmp;
            }
        }
    }
    else {
        FAIL() << "TEST FILE NOT FOUND";
    }
}

template<typename inType, typename outType>
void readTestsFromFile(const std::string &FileName, std::vector<af::dim4> &inputDims,
                std::vector<std::vector<inType> >  &testInputs,
                std::vector<std::vector<outType> > &testOutputs)
{
    using std::vector;

    std::ifstream testFile(FileName.c_str());
    if(testFile.good()) {
        unsigned inputCount;
        testFile >> inputCount;
        for(unsigned i=0; i<inputCount; i++) {
            af::dim4 temp(1);
            testFile >> temp;
            inputDims.push_back(temp);
        }

        unsigned testCount;
        testFile >> testCount;
        testOutputs.resize(testCount);

        vector<unsigned> testSizes(testCount);
        for(unsigned i = 0; i < testCount; i++) {
            testFile >> testSizes[i];
        }

        testInputs.resize(inputCount,vector<inType>(0));
        for(unsigned k=0; k<inputCount; k++) {
            unsigned nElems = inputDims[k].elements();
            testInputs[k].resize(nElems);
            inType tmp;
            for(unsigned i = 0; i < nElems; i++) {
                testFile >> tmp;
                testInputs[k][i] = tmp;
            }
        }

        testOutputs.resize(testCount, vector<outType>(0));
        for(unsigned i = 0; i < testCount; i++) {
            testOutputs[i].resize(testSizes[i]);
            outType tmp;
            for(unsigned j = 0; j < testSizes[i]; j++) {
                testFile >> tmp;
                testOutputs[i][j] = tmp;
            }
        }
    }
    else {
        FAIL() << "TEST FILE NOT FOUND";
    }
}

void readImageTests(const std::string        &pFileName,
                    std::vector<af::dim4>    &pInputDims,
                    std::vector<std::string> &pTestInputs,
                    std::vector<dim_t>    &pTestOutSizes,
                    std::vector<std::string> &pTestOutputs)
{
    using std::vector;

    std::ifstream testFile(pFileName.c_str());
    if(testFile.good()) {
        unsigned inputCount;
        testFile >> inputCount;
        for(unsigned i=0; i<inputCount; i++) {
            af::dim4 temp(1);
            testFile >> temp;
            pInputDims.push_back(temp);
        }

        unsigned testCount;
        testFile >> testCount;
        pTestOutputs.resize(testCount);

        pTestOutSizes.resize(testCount);
        for(unsigned i = 0; i < testCount; i++) {
            testFile >> pTestOutSizes[i];
        }

        pTestInputs.resize(inputCount, "");
        for(unsigned k=0; k<inputCount; k++) {
            std::string temp = "";
            while(std::getline(testFile, temp)) {
                if (temp!="")
                    break;
            }
            if (temp=="")
                throw std::runtime_error("Test file might not be per format, please check.");
            pTestInputs[k] = temp;
        }

        pTestOutputs.resize(testCount, "");
        for(unsigned i = 0; i < testCount; i++) {
            std::string temp = "";
            while(std::getline(testFile, temp)) {
                if (temp!="")
                    break;
            }
            if (temp=="")
                throw std::runtime_error("Test file might not be per format, please check.");
            pTestOutputs[i] = temp;
        }
    }
    else {
        FAIL() << "TEST FILE NOT FOUND";
    }
}

template<typename outType>
void readImageTests(const std::string                 &pFileName,
                    std::vector<af::dim4>             &pInputDims,
                    std::vector<std::string>          &pTestInputs,
                    std::vector<std::vector<outType> > &pTestOutputs)
{
    using std::vector;

    std::ifstream testFile(pFileName.c_str());
    if(testFile.good()) {
        unsigned inputCount;
        testFile >> inputCount;
        for(unsigned i=0; i<inputCount; i++) {
            af::dim4 temp(1);
            testFile >> temp;
            pInputDims.push_back(temp);
        }

        unsigned testCount;
        testFile >> testCount;
        pTestOutputs.resize(testCount);

        vector<unsigned> testSizes(testCount);
        for(unsigned i = 0; i < testCount; i++) {
            testFile >> testSizes[i];
        }

        pTestInputs.resize(inputCount, "");
        for(unsigned k=0; k<inputCount; k++) {
            std::string temp = "";
            while(std::getline(testFile, temp)) {
                if (temp!="")
                    break;
            }
            if (temp=="")
                throw std::runtime_error("Test file might not be per format, please check.");
            pTestInputs[k] = temp;
        }

        pTestOutputs.resize(testCount, vector<outType>(0));
        for(unsigned i = 0; i < testCount; i++) {
            pTestOutputs[i].resize(testSizes[i]);
            outType tmp;
            for(unsigned j = 0; j < testSizes[i]; j++) {
                testFile >> tmp;
                pTestOutputs[i][j] = tmp;
            }
        }
    }
    else {
        FAIL() << "TEST FILE NOT FOUND";
    }
}

template<typename descType>
void readImageFeaturesDescriptors(const std::string                  &pFileName,
                                  std::vector<af::dim4>              &pInputDims,
                                  std::vector<std::string>           &pTestInputs,
                                  std::vector<std::vector<float> >    &pTestFeats,
                                  std::vector<std::vector<descType> > &pTestDescs)
{
    using std::vector;

    std::ifstream testFile(pFileName.c_str());
    if(testFile.good()) {
        unsigned inputCount;
        testFile >> inputCount;
        for(unsigned i=0; i<inputCount; i++) {
            af::dim4 temp(1);
            testFile >> temp;
            pInputDims.push_back(temp);
        }

        unsigned attrCount, featCount, descLen;
        testFile >> featCount;
        testFile >> attrCount;
        testFile >> descLen;
        pTestFeats.resize(attrCount);

        pTestInputs.resize(inputCount, "");
        for(unsigned k=0; k<inputCount; k++) {
            std::string temp = "";
            while(std::getline(testFile, temp)) {
                if (temp!="")
                    break;
            }
            if (temp=="")
                throw std::runtime_error("Test file might not be per format, please check.");
            pTestInputs[k] = temp;
        }

        pTestFeats.resize(attrCount, vector<float>(0));
        for(unsigned i = 0; i < attrCount; i++) {
            pTestFeats[i].resize(featCount);
            float tmp;
            for(unsigned j = 0; j < featCount; j++) {
                testFile >> tmp;
                pTestFeats[i][j] = tmp;
            }
        }

        pTestDescs.resize(featCount, vector<descType>(0));
        for(unsigned i = 0; i < featCount; i++) {
            pTestDescs[i].resize(descLen);
            descType tmp;
            for(unsigned j = 0; j < descLen; j++) {
                testFile >> tmp;
                pTestDescs[i][j] = tmp;
            }
        }
    }
    else {
        FAIL() << "TEST FILE NOT FOUND";
    }
}

/**
 * Below is not a pair wise comparition method, rather
 * it computes the accumulated error of the computed
 * output and gold output.
 *
 * The cut off is decided based on root mean square
 * deviation from cpu result
 *
 * For images, the maximum possible error will happen if all
 * the observed values are zeros and all the predicted values
 * are 255's. In such case, the value of NRMSD will be 1.0
 * Similarly, we can deduce that 0.0 will be the minimum
 * value of NRMSD. Hence, the range of RMSD is [0,255] for image inputs.
 */
template<typename T>
bool compareArraysRMSD(dim_t data_size, T *gold, T *data, double tolerance)
{
    double accum  = 0.0;
    double maxion = FLT_MAX;//(double)std::numeric_limits<T>::lowest();
    double minion = FLT_MAX;//(double)std::numeric_limits<T>::max();

    for(dim_t i=0;i<data_size;i++)
    {
        double dTemp = (double)data[i];
        double gTemp = (double)gold[i];
        double diff  = gTemp-dTemp;
        double err   = std::abs(diff) > 1.0e-4 ? diff : 0.0f;
        accum  += std::pow(err,2.0);
        maxion  = std::max(maxion, dTemp);
        minion  = std::min(minion, dTemp);
    }
    accum      /= data_size;
    double NRMSD = std::sqrt(accum)/(maxion-minion);

    std::cout<<"NRMSD = "<<NRMSD<<std::endl;
    if (NRMSD > tolerance)
        return false;

    return true;
}

template<typename T, typename Other>
struct is_same_type{
    static const bool value = false;
};

template<typename T>
struct is_same_type<T, T> {
    static const bool value = true;
};

template<bool, typename T, typename O>
struct cond_type;

template<typename T, typename Other>
struct cond_type<true, T, Other> {
    typedef T type;
};

template<typename T, typename Other>
struct cond_type<false, T, Other> {
    typedef Other type;
};

template<typename T>
double real(T val) { return (double)val; }
template<>
double real<af::cdouble>(af::cdouble val) { return real(val); }
template<>
double real<af::cfloat> (af::cfloat val) { return real(val); }

template<typename T>
double imag(T val) { return (double)val; }
template<>
double imag<af::cdouble>(af::cdouble val) { return imag(val); }
template<>
double imag<af::cfloat> (af::cfloat val) { return imag(val); }

template<typename T>
bool noDoubleTests()
{
    bool isTypeDouble = is_same_type<T, double>::value || is_same_type<T, af::cdouble>::value;

    int dev = af::getDevice();
    bool isDoubleSupported = af::isDoubleAvailable(dev);

    return ((isTypeDouble && !isDoubleSupported) ? true : false);
}

// TODO: perform conversion on device for CUDA and OpenCL
template<typename T>
af_err conv_image(af_array *out, af_array in)
{
    af_array outArray;

    dim_t d0, d1, d2, d3;
    af_get_dims(&d0, &d1, &d2, &d3, in);
    af::dim4 idims(d0, d1, d2, d3);

    dim_t nElems = 0;
    af_get_elements(&nElems, in);

    float *in_data = new float[nElems];
    af_get_data_ptr(in_data, in);

    T *out_data = new T[nElems];

    for (int i = 0; i < (int)nElems; i++)
        out_data[i] = (T)in_data[i];

    af_create_array(&outArray, out_data, idims.ndims(), idims.get(), (af_dtype) af::dtype_traits<T>::af_type);

    std::swap(*out, outArray);

    delete [] in_data;
    delete [] out_data;

    return AF_SUCCESS;
}

template<typename T>
af::array cpu_randu(const af::dim4 dims)
{
    typedef typename af::dtype_traits<T>::base_type BT;

    bool isTypeCplx = is_same_type<T, af::cfloat>::value || is_same_type<T, af::cdouble>::value;
    bool isTypeFloat = is_same_type<BT, float>::value || is_same_type<BT, double>::value;

    dim_t elements = (isTypeCplx ? 2 : 1) * dims.elements();

    std::vector<BT> out(elements);
    for(int i = 0; i < (int)elements; i++) {
        out[i] = isTypeFloat ? (BT)(rand())/RAND_MAX : rand() % 100;
    }

    return af::array(dims, (T *)&out[0]);
}
<commit_msg>Add function to check Image IO availability<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <string>
#include <fstream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <limits>
#include <stdexcept>
#include <cfloat>
#include <arrayfire.h>
#include <af/dim4.hpp>
#include <af/array.h>

typedef unsigned char  uchar;
typedef unsigned int   uint;
typedef unsigned short ushort;

template<typename inType, typename outType, typename FileElementType>
void readTests(const std::string &FileName, std::vector<af::dim4> &inputDims,
                std::vector<std::vector<inType> >   &testInputs,
                std::vector<std::vector<outType> > &testOutputs)
{
    using std::vector;

    std::ifstream testFile(FileName.c_str());
    if(testFile.good()) {
        unsigned inputCount;
        testFile >> inputCount;
        for(unsigned i=0; i<inputCount; i++) {
            af::dim4 temp(1);
            testFile >> temp;
            inputDims.push_back(temp);
        }

        unsigned testCount;
        testFile >> testCount;
        testOutputs.resize(testCount);

        vector<unsigned> testSizes(testCount);
        for(unsigned i = 0; i < testCount; i++) {
            testFile >> testSizes[i];
        }

        testInputs.resize(inputCount,vector<inType>(0));
        for(unsigned k=0; k<inputCount; k++) {
            unsigned nElems = inputDims[k].elements();
            testInputs[k].resize(nElems);
            FileElementType tmp;
            for(unsigned i = 0; i < nElems; i++) {
                testFile >> tmp;
                testInputs[k][i] = tmp;
            }
        }

        testOutputs.resize(testCount, vector<outType>(0));
        for(unsigned i = 0; i < testCount; i++) {
            testOutputs[i].resize(testSizes[i]);
            FileElementType tmp;
            for(unsigned j = 0; j < testSizes[i]; j++) {
                testFile >> tmp;
                testOutputs[i][j] = tmp;
            }
        }
    }
    else {
        FAIL() << "TEST FILE NOT FOUND";
    }
}

template<typename inType, typename outType>
void readTestsFromFile(const std::string &FileName, std::vector<af::dim4> &inputDims,
                std::vector<std::vector<inType> >  &testInputs,
                std::vector<std::vector<outType> > &testOutputs)
{
    using std::vector;

    std::ifstream testFile(FileName.c_str());
    if(testFile.good()) {
        unsigned inputCount;
        testFile >> inputCount;
        for(unsigned i=0; i<inputCount; i++) {
            af::dim4 temp(1);
            testFile >> temp;
            inputDims.push_back(temp);
        }

        unsigned testCount;
        testFile >> testCount;
        testOutputs.resize(testCount);

        vector<unsigned> testSizes(testCount);
        for(unsigned i = 0; i < testCount; i++) {
            testFile >> testSizes[i];
        }

        testInputs.resize(inputCount,vector<inType>(0));
        for(unsigned k=0; k<inputCount; k++) {
            unsigned nElems = inputDims[k].elements();
            testInputs[k].resize(nElems);
            inType tmp;
            for(unsigned i = 0; i < nElems; i++) {
                testFile >> tmp;
                testInputs[k][i] = tmp;
            }
        }

        testOutputs.resize(testCount, vector<outType>(0));
        for(unsigned i = 0; i < testCount; i++) {
            testOutputs[i].resize(testSizes[i]);
            outType tmp;
            for(unsigned j = 0; j < testSizes[i]; j++) {
                testFile >> tmp;
                testOutputs[i][j] = tmp;
            }
        }
    }
    else {
        FAIL() << "TEST FILE NOT FOUND";
    }
}

void readImageTests(const std::string        &pFileName,
                    std::vector<af::dim4>    &pInputDims,
                    std::vector<std::string> &pTestInputs,
                    std::vector<dim_t>    &pTestOutSizes,
                    std::vector<std::string> &pTestOutputs)
{
    using std::vector;

    std::ifstream testFile(pFileName.c_str());
    if(testFile.good()) {
        unsigned inputCount;
        testFile >> inputCount;
        for(unsigned i=0; i<inputCount; i++) {
            af::dim4 temp(1);
            testFile >> temp;
            pInputDims.push_back(temp);
        }

        unsigned testCount;
        testFile >> testCount;
        pTestOutputs.resize(testCount);

        pTestOutSizes.resize(testCount);
        for(unsigned i = 0; i < testCount; i++) {
            testFile >> pTestOutSizes[i];
        }

        pTestInputs.resize(inputCount, "");
        for(unsigned k=0; k<inputCount; k++) {
            std::string temp = "";
            while(std::getline(testFile, temp)) {
                if (temp!="")
                    break;
            }
            if (temp=="")
                throw std::runtime_error("Test file might not be per format, please check.");
            pTestInputs[k] = temp;
        }

        pTestOutputs.resize(testCount, "");
        for(unsigned i = 0; i < testCount; i++) {
            std::string temp = "";
            while(std::getline(testFile, temp)) {
                if (temp!="")
                    break;
            }
            if (temp=="")
                throw std::runtime_error("Test file might not be per format, please check.");
            pTestOutputs[i] = temp;
        }
    }
    else {
        FAIL() << "TEST FILE NOT FOUND";
    }
}

template<typename outType>
void readImageTests(const std::string                 &pFileName,
                    std::vector<af::dim4>             &pInputDims,
                    std::vector<std::string>          &pTestInputs,
                    std::vector<std::vector<outType> > &pTestOutputs)
{
    using std::vector;

    std::ifstream testFile(pFileName.c_str());
    if(testFile.good()) {
        unsigned inputCount;
        testFile >> inputCount;
        for(unsigned i=0; i<inputCount; i++) {
            af::dim4 temp(1);
            testFile >> temp;
            pInputDims.push_back(temp);
        }

        unsigned testCount;
        testFile >> testCount;
        pTestOutputs.resize(testCount);

        vector<unsigned> testSizes(testCount);
        for(unsigned i = 0; i < testCount; i++) {
            testFile >> testSizes[i];
        }

        pTestInputs.resize(inputCount, "");
        for(unsigned k=0; k<inputCount; k++) {
            std::string temp = "";
            while(std::getline(testFile, temp)) {
                if (temp!="")
                    break;
            }
            if (temp=="")
                throw std::runtime_error("Test file might not be per format, please check.");
            pTestInputs[k] = temp;
        }

        pTestOutputs.resize(testCount, vector<outType>(0));
        for(unsigned i = 0; i < testCount; i++) {
            pTestOutputs[i].resize(testSizes[i]);
            outType tmp;
            for(unsigned j = 0; j < testSizes[i]; j++) {
                testFile >> tmp;
                pTestOutputs[i][j] = tmp;
            }
        }
    }
    else {
        FAIL() << "TEST FILE NOT FOUND";
    }
}

template<typename descType>
void readImageFeaturesDescriptors(const std::string                  &pFileName,
                                  std::vector<af::dim4>              &pInputDims,
                                  std::vector<std::string>           &pTestInputs,
                                  std::vector<std::vector<float> >    &pTestFeats,
                                  std::vector<std::vector<descType> > &pTestDescs)
{
    using std::vector;

    std::ifstream testFile(pFileName.c_str());
    if(testFile.good()) {
        unsigned inputCount;
        testFile >> inputCount;
        for(unsigned i=0; i<inputCount; i++) {
            af::dim4 temp(1);
            testFile >> temp;
            pInputDims.push_back(temp);
        }

        unsigned attrCount, featCount, descLen;
        testFile >> featCount;
        testFile >> attrCount;
        testFile >> descLen;
        pTestFeats.resize(attrCount);

        pTestInputs.resize(inputCount, "");
        for(unsigned k=0; k<inputCount; k++) {
            std::string temp = "";
            while(std::getline(testFile, temp)) {
                if (temp!="")
                    break;
            }
            if (temp=="")
                throw std::runtime_error("Test file might not be per format, please check.");
            pTestInputs[k] = temp;
        }

        pTestFeats.resize(attrCount, vector<float>(0));
        for(unsigned i = 0; i < attrCount; i++) {
            pTestFeats[i].resize(featCount);
            float tmp;
            for(unsigned j = 0; j < featCount; j++) {
                testFile >> tmp;
                pTestFeats[i][j] = tmp;
            }
        }

        pTestDescs.resize(featCount, vector<descType>(0));
        for(unsigned i = 0; i < featCount; i++) {
            pTestDescs[i].resize(descLen);
            descType tmp;
            for(unsigned j = 0; j < descLen; j++) {
                testFile >> tmp;
                pTestDescs[i][j] = tmp;
            }
        }
    }
    else {
        FAIL() << "TEST FILE NOT FOUND";
    }
}

/**
 * Below is not a pair wise comparition method, rather
 * it computes the accumulated error of the computed
 * output and gold output.
 *
 * The cut off is decided based on root mean square
 * deviation from cpu result
 *
 * For images, the maximum possible error will happen if all
 * the observed values are zeros and all the predicted values
 * are 255's. In such case, the value of NRMSD will be 1.0
 * Similarly, we can deduce that 0.0 will be the minimum
 * value of NRMSD. Hence, the range of RMSD is [0,255] for image inputs.
 */
template<typename T>
bool compareArraysRMSD(dim_t data_size, T *gold, T *data, double tolerance)
{
    double accum  = 0.0;
    double maxion = FLT_MAX;//(double)std::numeric_limits<T>::lowest();
    double minion = FLT_MAX;//(double)std::numeric_limits<T>::max();

    for(dim_t i=0;i<data_size;i++)
    {
        double dTemp = (double)data[i];
        double gTemp = (double)gold[i];
        double diff  = gTemp-dTemp;
        double err   = std::abs(diff) > 1.0e-4 ? diff : 0.0f;
        accum  += std::pow(err,2.0);
        maxion  = std::max(maxion, dTemp);
        minion  = std::min(minion, dTemp);
    }
    accum      /= data_size;
    double NRMSD = std::sqrt(accum)/(maxion-minion);

    std::cout<<"NRMSD = "<<NRMSD<<std::endl;
    if (NRMSD > tolerance)
        return false;

    return true;
}

template<typename T, typename Other>
struct is_same_type{
    static const bool value = false;
};

template<typename T>
struct is_same_type<T, T> {
    static const bool value = true;
};

template<bool, typename T, typename O>
struct cond_type;

template<typename T, typename Other>
struct cond_type<true, T, Other> {
    typedef T type;
};

template<typename T, typename Other>
struct cond_type<false, T, Other> {
    typedef Other type;
};

template<typename T>
double real(T val) { return (double)val; }
template<>
double real<af::cdouble>(af::cdouble val) { return real(val); }
template<>
double real<af::cfloat> (af::cfloat val) { return real(val); }

template<typename T>
double imag(T val) { return (double)val; }
template<>
double imag<af::cdouble>(af::cdouble val) { return imag(val); }
template<>
double imag<af::cfloat> (af::cfloat val) { return imag(val); }

template<typename T>
bool noDoubleTests()
{
    bool isTypeDouble = is_same_type<T, double>::value || is_same_type<T, af::cdouble>::value;

    int dev = af::getDevice();
    bool isDoubleSupported = af::isDoubleAvailable(dev);

    return ((isTypeDouble && !isDoubleSupported) ? true : false);
}

bool noImageIOTests()
{
    af_array arr = 0;
    const af_err err = af_load_image(&arr, TEST_DIR"/imageio/color_small.png", true);

    if(arr != 0) af_release_array(arr);

    if(err == AF_ERR_NOT_CONFIGURED)
        return true;    // Yes, disable test
    else
        return false;   // No, let test continue
}

// TODO: perform conversion on device for CUDA and OpenCL
template<typename T>
af_err conv_image(af_array *out, af_array in)
{
    af_array outArray;

    dim_t d0, d1, d2, d3;
    af_get_dims(&d0, &d1, &d2, &d3, in);
    af::dim4 idims(d0, d1, d2, d3);

    dim_t nElems = 0;
    af_get_elements(&nElems, in);

    float *in_data = new float[nElems];
    af_get_data_ptr(in_data, in);

    T *out_data = new T[nElems];

    for (int i = 0; i < (int)nElems; i++)
        out_data[i] = (T)in_data[i];

    af_create_array(&outArray, out_data, idims.ndims(), idims.get(), (af_dtype) af::dtype_traits<T>::af_type);

    std::swap(*out, outArray);

    delete [] in_data;
    delete [] out_data;

    return AF_SUCCESS;
}

template<typename T>
af::array cpu_randu(const af::dim4 dims)
{
    typedef typename af::dtype_traits<T>::base_type BT;

    bool isTypeCplx = is_same_type<T, af::cfloat>::value || is_same_type<T, af::cdouble>::value;
    bool isTypeFloat = is_same_type<BT, float>::value || is_same_type<BT, double>::value;

    dim_t elements = (isTypeCplx ? 2 : 1) * dims.elements();

    std::vector<BT> out(elements);
    for(int i = 0; i < (int)elements; i++) {
        out[i] = isTypeFloat ? (BT)(rand())/RAND_MAX : rand() % 100;
    }

    return af::array(dims, (T *)&out[0]);
}
<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) <2015> <Stephan Gatzka>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE fetch

#include <boost/test/unit_test.hpp>

#include "json/cJSON.h"
#include "peer.h"
#include "router.h"
#include "state.h"
#include "table.h"

enum event {
	UNKNOWN_EVENT,
	ADD_EVENT,
	CHANGE_EVENT,
	REMOVE_EVENT
};

static char send_buffer[100000];

static struct peer *fetch_peer_1;
static bool message_for_wrong_peer;

static enum event fetch_peer_1_event;

static cJSON *parse_send_buffer(void)
{
	char *read_ptr = send_buffer;
	const char *end_parse;
	cJSON *root = cJSON_ParseWithOpts(read_ptr, &end_parse, 0);
	return root;
}

static enum event get_event_from_json(cJSON *json)
{
	cJSON *params = cJSON_GetObjectItem(json, "params");
	if (params == NULL) return UNKNOWN_EVENT;
	cJSON *event = cJSON_GetObjectItem(params, "event");
	if (event == NULL) return UNKNOWN_EVENT;
	if (event->type != cJSON_String) return UNKNOWN_EVENT;
	if (strcmp(event->valuestring, "add") == 0) return ADD_EVENT;
	if (strcmp(event->valuestring, "change") == 0) return CHANGE_EVENT;
	if (strcmp(event->valuestring, "remove") == 0) return REMOVE_EVENT;
	return UNKNOWN_EVENT;
}

extern "C" {
	int send_message(struct peer *p, const char *rendered, size_t len)
	{
		memcpy(send_buffer, rendered, len);
		if (p == fetch_peer_1) {
			cJSON *fetch_event = parse_send_buffer();
			fetch_peer_1_event = get_event_from_json(fetch_event);
			cJSON_Delete(fetch_event);
		} else {
			message_for_wrong_peer = true;
		}
		return 0;
	}

	int add_io(struct peer *p)
	{
		(void)p;
		return 0;
	}

	void remove_io(const struct peer *p)
	{
		(void)p;
		return;
	}

	void remove_all_methods_from_peer(struct peer *p)
	{
		(void)p;
	}
}

struct F {
	F()
	{
		state_hashtable_create();
		p = alloc_peer(-1);
		fetch_peer_1 = alloc_peer(-1);
		message_for_wrong_peer = false;
		fetch_peer_1_event = UNKNOWN_EVENT;
	}
	~F()
	{
		free_peer(fetch_peer_1);
		free_peer(p);
		state_hashtable_delete();
	}

	struct peer *p;
};

static struct state_or_method *get_state(const char *path)
{
	return (struct state_or_method *)state_table_get(path);
}

static cJSON *create_fetch_params(const char *path_equals_string, const char *path_startsWith_string, const char *path_endsWith_string, const char *path_contains, int ignore_case)
{
	cJSON *root = cJSON_CreateObject();
	BOOST_REQUIRE(root != NULL);
	cJSON_AddStringToObject(root, "id", "fetch_id_1");
	cJSON *path = cJSON_CreateObject();
	BOOST_REQUIRE(path != NULL);
	cJSON_AddItemToObject(root, "path", path);
	if (strlen(path_equals_string)) {
		cJSON_AddStringToObject(path, "equals", path_equals_string);
	}

	if (strlen(path_startsWith_string)) {
		cJSON_AddStringToObject(path, "startsWith", path_startsWith_string);
	}

	if (strlen(path_endsWith_string)) {
		cJSON_AddStringToObject(path, "endsWith", path_endsWith_string);
	}

	if (strlen(path_contains)) {
		cJSON_AddStringToObject(path, "contains", path_contains);
	}

	if (ignore_case) {
		cJSON_AddBoolToObject(root, "caseInsensitive", 1);
	}

	return root;
}

BOOST_FIXTURE_TEST_CASE(fetch_matchers, F)
{
	const char *path = "foo/bar";
	const char *path_upper = "FOO/BAR";
	const char *path_startsWith = "foo";
	const char *path_endsWith = "bar";
	const char *path_contains = "oo/ba";

	int state_value = 12345;

	{
		cJSON *value = cJSON_CreateNumber(state_value);

		cJSON *error = add_state_or_method_to_peer(p, path, value);
		BOOST_CHECK(error == NULL);

		cJSON_Delete(value);
	}

	struct state_or_method *s = get_state(path);
	BOOST_CHECK(s->value->valueint == state_value);
	{
		/// is to fail because fetch is case sensitive
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path_upper, "", "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == UNKNOWN_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path, "", "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", path_startsWith, "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", "", path_endsWith, "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", "", "", path_contains, 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}
}

BOOST_FIXTURE_TEST_CASE(fetch_matchers_ignoring_case, F)
{
	const char *path = "foo/bar";
	const char *path_upper = "FOO/BAR";
	const char *path_startsWith = "FOO";
	const char *path_endsWith = "BAR";
	const char *path_contains = "OO/BA";

	int state_value = 12345;

	{
		cJSON *value = cJSON_CreateNumber(state_value);

		cJSON *error = add_state_or_method_to_peer(p, path, value);
		BOOST_CHECK(error == NULL);
		cJSON_Delete(value);
	}

	struct state_or_method *s = get_state(path);
	BOOST_CHECK(s->value->valueint == state_value);

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path_upper, "", "", "", 1);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", path_startsWith, "", "", 1);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", "", path_endsWith, "", 1);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", "", "", path_contains, 1);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}
}

BOOST_FIXTURE_TEST_CASE(fetch_and_change_and_remove, F)
{
	const char *path = "foo/bar";

	int state_value = 12345;

	{
		/// does not fetch anything because nothing does match
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path, "", "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == UNKNOWN_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		cJSON *value = cJSON_CreateNumber(state_value);

		cJSON *error = add_state_or_method_to_peer(p, path, value);
		BOOST_CHECK(error == NULL);

		cJSON_Delete(value);
	}

	struct state_or_method *s = get_state(path);
	BOOST_CHECK(s->value->valueint == state_value);

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path, "", "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);

		cJSON *new_value = cJSON_CreateNumber(4321);
		error = change_state(p, path, new_value);
		BOOST_REQUIRE(error == NULL);
		cJSON_Delete(new_value);

		BOOST_CHECK(fetch_peer_1_event == CHANGE_EVENT);

		BOOST_CHECK(!message_for_wrong_peer);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		/// fetch removal of state
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path, "", "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		remove_state_or_method_from_peer(p, path);

		BOOST_CHECK(fetch_peer_1_event == REMOVE_EVENT);
		cJSON_Delete(params);
	}
}
<commit_msg>Test unfetch.<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) <2015> <Stephan Gatzka>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE fetch

#include <boost/test/unit_test.hpp>

#include "json/cJSON.h"
#include "peer.h"
#include "router.h"
#include "state.h"
#include "table.h"

enum event {
	UNKNOWN_EVENT,
	ADD_EVENT,
	CHANGE_EVENT,
	REMOVE_EVENT
};

static char send_buffer[100000];

static struct peer *fetch_peer_1;
static bool message_for_wrong_peer;

static enum event fetch_peer_1_event;

static cJSON *parse_send_buffer(void)
{
	char *read_ptr = send_buffer;
	const char *end_parse;
	cJSON *root = cJSON_ParseWithOpts(read_ptr, &end_parse, 0);
	return root;
}

static enum event get_event_from_json(cJSON *json)
{
	cJSON *params = cJSON_GetObjectItem(json, "params");
	if (params == NULL) return UNKNOWN_EVENT;
	cJSON *event = cJSON_GetObjectItem(params, "event");
	if (event == NULL) return UNKNOWN_EVENT;
	if (event->type != cJSON_String) return UNKNOWN_EVENT;
	if (strcmp(event->valuestring, "add") == 0) return ADD_EVENT;
	if (strcmp(event->valuestring, "change") == 0) return CHANGE_EVENT;
	if (strcmp(event->valuestring, "remove") == 0) return REMOVE_EVENT;
	return UNKNOWN_EVENT;
}

extern "C" {
	int send_message(struct peer *p, const char *rendered, size_t len)
	{
		memcpy(send_buffer, rendered, len);
		if (p == fetch_peer_1) {
			cJSON *fetch_event = parse_send_buffer();
			fetch_peer_1_event = get_event_from_json(fetch_event);
			cJSON_Delete(fetch_event);
		} else {
			message_for_wrong_peer = true;
		}
		return 0;
	}

	int add_io(struct peer *p)
	{
		(void)p;
		return 0;
	}

	void remove_io(const struct peer *p)
	{
		(void)p;
		return;
	}

	void remove_all_methods_from_peer(struct peer *p)
	{
		(void)p;
	}
}

struct F {
	F()
	{
		state_hashtable_create();
		p = alloc_peer(-1);
		fetch_peer_1 = alloc_peer(-1);
		message_for_wrong_peer = false;
		fetch_peer_1_event = UNKNOWN_EVENT;
	}
	~F()
	{
		free_peer(fetch_peer_1);
		free_peer(p);
		state_hashtable_delete();
	}

	struct peer *p;
};

static struct state_or_method *get_state(const char *path)
{
	return (struct state_or_method *)state_table_get(path);
}

static cJSON *create_fetch_params(const char *path_equals_string, const char *path_startsWith_string, const char *path_endsWith_string, const char *path_contains, int ignore_case)
{
	cJSON *root = cJSON_CreateObject();
	BOOST_REQUIRE(root != NULL);
	cJSON_AddStringToObject(root, "id", "fetch_id_1");
	cJSON *path = cJSON_CreateObject();
	BOOST_REQUIRE(path != NULL);
	cJSON_AddItemToObject(root, "path", path);
	if (strlen(path_equals_string)) {
		cJSON_AddStringToObject(path, "equals", path_equals_string);
	}

	if (strlen(path_startsWith_string)) {
		cJSON_AddStringToObject(path, "startsWith", path_startsWith_string);
	}

	if (strlen(path_endsWith_string)) {
		cJSON_AddStringToObject(path, "endsWith", path_endsWith_string);
	}

	if (strlen(path_contains)) {
		cJSON_AddStringToObject(path, "contains", path_contains);
	}

	if (ignore_case) {
		cJSON_AddBoolToObject(root, "caseInsensitive", 1);
	}

	return root;
}

static cJSON *create_unfetch_params()
{
	cJSON *root = cJSON_CreateObject();
	BOOST_REQUIRE(root != NULL);
	cJSON_AddStringToObject(root, "id", "fetch_id_1");

	return root;
}

BOOST_FIXTURE_TEST_CASE(fetch_matchers, F)
{
	const char *path = "foo/bar";
	const char *path_upper = "FOO/BAR";
	const char *path_startsWith = "foo";
	const char *path_endsWith = "bar";
	const char *path_contains = "oo/ba";

	int state_value = 12345;

	{
		cJSON *value = cJSON_CreateNumber(state_value);

		cJSON *error = add_state_or_method_to_peer(p, path, value);
		BOOST_CHECK(error == NULL);

		cJSON_Delete(value);
	}

	struct state_or_method *s = get_state(path);
	BOOST_CHECK(s->value->valueint == state_value);
	{
		/// is to fail because fetch is case sensitive
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path_upper, "", "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == UNKNOWN_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path, "", "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", path_startsWith, "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", "", path_endsWith, "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", "", "", path_contains, 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}
}

BOOST_FIXTURE_TEST_CASE(fetch_matchers_ignoring_case, F)
{
	const char *path = "foo/bar";
	const char *path_upper = "FOO/BAR";
	const char *path_startsWith = "FOO";
	const char *path_endsWith = "BAR";
	const char *path_contains = "OO/BA";

	int state_value = 12345;

	{
		cJSON *value = cJSON_CreateNumber(state_value);

		cJSON *error = add_state_or_method_to_peer(p, path, value);
		BOOST_CHECK(error == NULL);
		cJSON_Delete(value);
	}

	struct state_or_method *s = get_state(path);
	BOOST_CHECK(s->value->valueint == state_value);

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path_upper, "", "", "", 1);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", path_startsWith, "", "", 1);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", "", path_endsWith, "", 1);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params("", "", "", path_contains, 1);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}
}

BOOST_FIXTURE_TEST_CASE(fetch_and_change_and_remove, F)
{
	const char *path = "foo/bar";

	int state_value = 12345;

	{
		/// does not fetch anything because nothing does match
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path, "", "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == UNKNOWN_EVENT);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		cJSON *value = cJSON_CreateNumber(state_value);

		cJSON *error = add_state_or_method_to_peer(p, path, value);
		BOOST_CHECK(error == NULL);

		cJSON_Delete(value);
	}

	struct state_or_method *s = get_state(path);
	BOOST_CHECK(s->value->valueint == state_value);

	{
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path, "", "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		BOOST_CHECK(fetch_peer_1_event == ADD_EVENT);

		cJSON *new_value = cJSON_CreateNumber(4321);
		error = change_state(p, path, new_value);
		BOOST_REQUIRE(error == NULL);
		cJSON_Delete(new_value);

		BOOST_CHECK(fetch_peer_1_event == CHANGE_EVENT);

		BOOST_CHECK(!message_for_wrong_peer);
		remove_all_fetchers_from_peer(fetch_peer_1);
		cJSON_Delete(params);
	}

	{
		/// fetch removal of state
		struct fetch *f = NULL;
		cJSON *params = create_fetch_params(path, "", "", "", 0);
		cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
		BOOST_REQUIRE(error == NULL);
		error = add_fetch_to_states(f);
		BOOST_REQUIRE(error == NULL);

		remove_state_or_method_from_peer(p, path);

		BOOST_CHECK(fetch_peer_1_event == REMOVE_EVENT);
		cJSON_Delete(params);
	}
}

BOOST_FIXTURE_TEST_CASE(fetch_and_unfetch, F)
{
	struct fetch *f = NULL;
	cJSON *params = create_fetch_params("", "", "", "", 0);
	cJSON *error = add_fetch_to_peer(fetch_peer_1, params, &f);
	BOOST_REQUIRE(error == NULL);
	cJSON_Delete(params);

	params = create_unfetch_params();
	error = remove_fetch_from_peer(fetch_peer_1, params);
	BOOST_REQUIRE(error == NULL);
	cJSON_Delete(params);
}
<|endoftext|>


<commit_before>#include <boost/test/unit_test.hpp>
#include "../src/MLGrid.hpp"
#include "../src/GridStorageAccessInterface.hpp"
#include "../src/GridStorageAccess.hpp"
#include "../src/GridStorageFacade.hpp"

using namespace envire::maps;
class PatchBase
{
    public:
        PatchBase(double m, double ma) : min(m), max(ma)
        {
        }

        double min;
        double max;

        double getMiddle() const
        {
            return min + (max - min) / 2.0;
        }

    bool operator<(const PatchBase &other) const{
        return  getMiddle() < other.getMiddle();
    }

    double getMin() const {
        return min;
    };

    double getMax() const {
        return max;
    };

    virtual void test()
    {
        std::cout << "Base class " << std::endl;
    };
};

class Patch : public PatchBase
{
public:
    Patch() : PatchBase(0,0)
    {
    };

    Patch(double m, double ma) : PatchBase(m, ma)
    {
    };

    virtual void test()
    {
        std::cout << "Derived Class " << std::endl;
    };

    double someValue;
};

BOOST_AUTO_TEST_CASE(test_levelAccess)
{
    Patch p;

    PatchBase b = p;

    p.test();

    b.test();

    LevelList<Patch> list;

    LevelListAccess<PatchBase> *access = new LevelListAccessImpl<Patch, PatchBase>(&list);

    delete access;

}

BOOST_AUTO_TEST_CASE(test_levelAccess2)
{
    DerivableLevelList<Patch, PatchBase> list;

    std::cout << "SuperClass " << std::endl;

    list.begin();

    std::cout << "BaseClass " << std::endl;
    DerivableLevelList<PatchBase> *listBase = &list;

    listBase->begin();

//     LevelListAccess<PatchBase> *access = new LevelListAccessImpl<Patch, PatchBase>(&list);

}

BOOST_AUTO_TEST_CASE(test_mapAccess)
{
    GridMap<Patch> map;

    GridStorageAccessInterface<PatchBase> *test = new GridStorageAccess<Patch, PatchBase>(&map);

    GridMap<PatchBase, GridStorageFacade<PatchBase> > test2(map, GridStorageFacade<PatchBase>(test));

}

BOOST_AUTO_TEST_CASE(test_mapAccess2)
{
    GridMap<DerivableLevelList<Patch, PatchBase> > map(Vector2ui(5,5), Eigen::Vector2d(0.5,0.5), DerivableLevelList<Patch, PatchBase>());

    GridStorageAccessInterface<DerivableLevelList<PatchBase, PatchBase> > *test = new GridStorageAccess<DerivableLevelList<Patch, PatchBase>, DerivableLevelList<PatchBase, PatchBase> >(&map);

    GridMap<DerivableLevelList<PatchBase, PatchBase>, GridStorageFacade<DerivableLevelList<PatchBase, PatchBase> > > test2(map, GridStorageFacade<DerivableLevelList<PatchBase, PatchBase> >(test));

    Patch p(38, 50);
    Patch p2(55, 80);

    map.at(2,2).insert(p2);
    map.at(2,2).insert(p);

    BOOST_CHECK_EQUAL(map.at(2,2).size(), 2);

    {
    auto it = map.at(2,2).begin();

    BOOST_CHECK_EQUAL(it->getMin(), 38);
    it++;
    BOOST_CHECK_EQUAL(it->getMin(), 55);
    }

    BOOST_CHECK_EQUAL(test2.at(2,2).size(), 2);

    {
    auto it = test2.at(2,2).begin();

    BOOST_CHECK_EQUAL(it->getMin(), 38);
    it++;
    BOOST_CHECK_EQUAL(it->getMin(), 55);
    }

}

BOOST_AUTO_TEST_CASE(test_base_class)
{

    MLGrid<PatchBase> grid(Vector2ui(5,5), Eigen::Vector2d(0.5,0.5));

    PatchBase p(38, 50);
    PatchBase p2(55, 80);

    grid.at(2,2).insert(p2);
    grid.at(2,2).insert(p);

    BOOST_CHECK_EQUAL(grid.at(2,2).size(), 2);

    {
    auto it = grid.at(2,2).begin();

    BOOST_CHECK_EQUAL(it->getMin(), 38);
    it++;
    BOOST_CHECK_EQUAL(it->getMin(), 55);
    }
//     for(const Patch &p : grid.at(2,2))
//         std::cout << "Bar is " << p.getMin() << std::endl;

//     Eigen::Vector3d pos;
//     grid.fromGrid(Index(2,2), pos);
//
//     std::cout << "From" << pos.transpose() << std::endl;

    {
    Eigen::AlignedBox3f box(Eigen::Vector3f(0.5, .5, 49),Eigen::Vector3f(2.0, 2.0, 60));
    MLGrid<PatchBase>::MLView view = grid.intersectCuboid(box);

//     std::cout << "Subview Size : " << view.getNumCells().transpose() << std::endl;
//     for(size_t x = 0; x < view.getNumCells().x(); x++)
//     {
//         for(size_t y = 0; y < view.getNumCells().y(); y++)
//         {
//             for(const Patch *p : view.at(x,y))
//                 std::cout << "X " << x << " Y " << y << " Bar is " << p->getMin() << std::endl;
//         }
//     }
//
    BOOST_CHECK_EQUAL(view.at(1,1).size(), 2);
    auto it = view.at(1,1).begin();

    BOOST_CHECK_EQUAL((*it)->getMin(), 38);
    it++;
    BOOST_CHECK_EQUAL((*it)->getMin(), 55);
    }

    {
    Eigen::AlignedBox3f box(Eigen::Vector3f(0.5, .5, 37),Eigen::Vector3f(2.0, 2.0, 38));
    MLGrid<PatchBase>::MLView view = grid.intersectCuboid(box);

    BOOST_CHECK_EQUAL(view.at(1,1).size(), 1);
    auto it = view.at(1,1).begin();

    BOOST_CHECK_EQUAL((*it)->getMin(), 38);
    }

    {
    Eigen::AlignedBox3f box(Eigen::Vector3f(0.5, .5, 80),Eigen::Vector3f(2.0, 2.0, 105));
    MLGrid<PatchBase>::MLView view = grid.intersectCuboid(box);

    BOOST_CHECK_EQUAL(view.at(1,1).size(), 1);
    auto it = view.at(1,1).begin();

    BOOST_CHECK_EQUAL((*it)->getMin(), 55);
    }
}

<commit_msg>add test to mlgrid<commit_after>#include <boost/test/unit_test.hpp>
#include "../src/MLGrid.hpp"
#include "../src/GridStorageAccessInterface.hpp"
#include "../src/GridStorageAccess.hpp"
#include "../src/GridStorageFacade.hpp"

using namespace envire::maps;
class PatchBase
{
    public:
        PatchBase(double m, double ma) : min(m), max(ma)
        {
        }

        double min;
        double max;

        double getMiddle() const
        {
            return min + (max - min) / 2.0;
        }

    bool operator<(const PatchBase &other) const{
        return  getMiddle() < other.getMiddle();
    }

    double getMin() const {
        return min;
    };

    double getMax() const {
        return max;
    };

    virtual void test()
    {
        std::cout << "Base class " << std::endl;
    };
};

class Patch : public PatchBase
{
public:
    Patch() : PatchBase(0,0)
    {
    };

    Patch(double m, double ma) : PatchBase(m, ma)
    {
    };

    virtual void test()
    {
        std::cout << "Derived Class " << std::endl;
    };

    double someValue;
};

BOOST_AUTO_TEST_CASE(test_levelAccess)
{
    Patch p;

    PatchBase b = p;

    p.test();

    b.test();

    LevelList<Patch> list;

    LevelListAccess<PatchBase> *access = new LevelListAccessImpl<Patch, PatchBase>(&list);

    delete access;

}

BOOST_AUTO_TEST_CASE(test_levelAccess2)
{
    DerivableLevelList<Patch, PatchBase> list;

    std::cout << "SuperClass " << std::endl;

    list.begin();

    std::cout << "BaseClass " << std::endl;
    DerivableLevelList<PatchBase> *listBase = &list;

    listBase->begin();

//     LevelListAccess<PatchBase> *access = new LevelListAccessImpl<Patch, PatchBase>(&list);

}

BOOST_AUTO_TEST_CASE(test_mapAccess)
{
    GridMap<Patch> map;

    GridStorageAccessInterface<PatchBase> *test = new GridStorageAccess<Patch, PatchBase>(&map);

    GridMap<PatchBase, GridStorageFacade<PatchBase> > test2(map, GridStorageFacade<PatchBase>(test));
}

BOOST_AUTO_TEST_CASE(test_map_access3)
{

    GridMap<Patch> map(Vector2ui(2,2), Eigen::Vector2d(1,1), Patch(0,0));
    map.at(0,0) = Patch(0, 0);
    map.at(0,1) = Patch(0, 1);
    map.at(1,0) = Patch(1, 0);
    map.at(1,1) = Patch(1, 1);

    map.at(0,0).test();
    map.at(0,1).test();

    for (auto it = map.begin(); it != map.end(); ++it)
    {
        std::cout << it->getMin() << " " << it->getMax() << std::endl;
    }

    GridStorageAccessInterface<PatchBase> *test = new GridStorageAccess<Patch, PatchBase>(&map);

    GridMap<PatchBase, GridStorageFacade<PatchBase> > test2(map, GridStorageFacade<PatchBase>(test));

    test2.at(0,0).test();
    test2.at(0,1).test();

    for (auto it = test2.begin(); it != test2.end(); ++it)
    {
        std::cout << it->getMin() << " " << it->getMax() << std::endl;
    }
}

#include <ctime>

BOOST_AUTO_TEST_CASE(test_map_access_time)
{
    GridMap<Patch> map(Vector2ui(1000,1000), Eigen::Vector2d(1,1), Patch(0,0));

    clock_t begin = clock();
    for (unsigned int x = 0; x < 1000; ++x)
    {
        for (unsigned int y = 0; y < 1000; ++y)
        {
            map.at(x, y).getMin();
        }
    }
    clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    std::cout << "map: " << elapsed_secs << std::endl;

    begin = clock();
    for (auto it = map.begin(); it != map.end(); ++it)
    {
        it->getMin();
    }
    end = clock();

    elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    std::cout << "map: " << elapsed_secs << std::endl;

    GridStorageAccessInterface<PatchBase> *test = new GridStorageAccess<Patch, PatchBase>(&map);
    GridMap<PatchBase, GridStorageFacade<PatchBase> > test2(map, GridStorageFacade<PatchBase>(test));

    begin = clock();
    for (unsigned int x = 0; x < 1000; ++x)
    {
        for (unsigned int y = 0; y < 1000; ++y)
        {
            test2.at(x, y).getMin();
        }
    }
    end = clock();

    elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    std::cout << "test2: " << elapsed_secs << std::endl;

    auto it_2 = test2.begin();

    begin = clock();
    for (auto it = test2.begin(); it != test2.end(); ++it)
    {
        it->getMin();
    }
    end = clock();

    elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    std::cout << "test2: " << elapsed_secs << std::endl;
}

BOOST_AUTO_TEST_CASE(test_mapAccess2)
{
    GridMap<DerivableLevelList<Patch, PatchBase> > map(Vector2ui(5,5), Eigen::Vector2d(0.5,0.5), DerivableLevelList<Patch, PatchBase>());

    GridStorageAccessInterface<DerivableLevelList<PatchBase, PatchBase> > *test = new GridStorageAccess<DerivableLevelList<Patch, PatchBase>, DerivableLevelList<PatchBase, PatchBase> >(&map);

    GridMap<DerivableLevelList<PatchBase, PatchBase>, GridStorageFacade<DerivableLevelList<PatchBase, PatchBase> > > test2(map, GridStorageFacade<DerivableLevelList<PatchBase, PatchBase> >(test));

    Patch p(38, 50);
    Patch p2(55, 80);

    map.at(2,2).insert(p2);
    map.at(2,2).insert(p);

    BOOST_CHECK_EQUAL(map.at(2,2).size(), 2);

    {
    auto it = map.at(2,2).begin();

    BOOST_CHECK_EQUAL(it->getMin(), 38);
    it++;
    BOOST_CHECK_EQUAL(it->getMin(), 55);
    }

    BOOST_CHECK_EQUAL(test2.at(2,2).size(), 2);

    {
    auto it = test2.at(2,2).begin();

    BOOST_CHECK_EQUAL(it->getMin(), 38);
    it++;
    BOOST_CHECK_EQUAL(it->getMin(), 55);
    }

}

BOOST_AUTO_TEST_CASE(test_base_class)
{

    MLGrid<PatchBase> grid(Vector2ui(5,5), Eigen::Vector2d(0.5,0.5));

    PatchBase p(38, 50);
    PatchBase p2(55, 80);

    grid.at(2,2).insert(p2);
    grid.at(2,2).insert(p);

    BOOST_CHECK_EQUAL(grid.at(2,2).size(), 2);

    {
    auto it = grid.at(2,2).begin();

    BOOST_CHECK_EQUAL(it->getMin(), 38);
    it++;
    BOOST_CHECK_EQUAL(it->getMin(), 55);
    }
//     for(const Patch &p : grid.at(2,2))
//         std::cout << "Bar is " << p.getMin() << std::endl;

//     Eigen::Vector3d pos;
//     grid.fromGrid(Index(2,2), pos);
//
//     std::cout << "From" << pos.transpose() << std::endl;

    {
    Eigen::AlignedBox3f box(Eigen::Vector3f(0.5, .5, 49),Eigen::Vector3f(2.0, 2.0, 60));
    MLGrid<PatchBase>::MLView view = grid.intersectCuboid(box);

//     std::cout << "Subview Size : " << view.getNumCells().transpose() << std::endl;
//     for(size_t x = 0; x < view.getNumCells().x(); x++)
//     {
//         for(size_t y = 0; y < view.getNumCells().y(); y++)
//         {
//             for(const Patch *p : view.at(x,y))
//                 std::cout << "X " << x << " Y " << y << " Bar is " << p->getMin() << std::endl;
//         }
//     }
//
    BOOST_CHECK_EQUAL(view.at(1,1).size(), 2);
    auto it = view.at(1,1).begin();

    BOOST_CHECK_EQUAL((*it)->getMin(), 38);
    it++;
    BOOST_CHECK_EQUAL((*it)->getMin(), 55);
    }

    {
    Eigen::AlignedBox3f box(Eigen::Vector3f(0.5, .5, 37),Eigen::Vector3f(2.0, 2.0, 38));
    MLGrid<PatchBase>::MLView view = grid.intersectCuboid(box);

    BOOST_CHECK_EQUAL(view.at(1,1).size(), 1);
    auto it = view.at(1,1).begin();

    BOOST_CHECK_EQUAL((*it)->getMin(), 38);
    }

    {
    Eigen::AlignedBox3f box(Eigen::Vector3f(0.5, .5, 80),Eigen::Vector3f(2.0, 2.0, 105));
    MLGrid<PatchBase>::MLView view = grid.intersectCuboid(box);

    BOOST_CHECK_EQUAL(view.at(1,1).size(), 1);
    auto it = view.at(1,1).begin();

    BOOST_CHECK_EQUAL((*it)->getMin(), 55);
    }
}

<|endoftext|>