diff --git a/test/Tests.cpp b/test/Tests.cpp
new file mode 100755
index 0000000..5f3dd6f
--- /dev/null
+++ b/test/Tests.cpp
@@ -0,0 +1,978 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+
+#define LOG_TAG "ArmnnDriverTests"
+#define BOOST_TEST_MODULE armnn_driver_tests
+#include <boost/test/unit_test.hpp>
+#include <log/log.h>
+
+#include "../ArmnnDriver.hpp"
+#include "../SystemPropertiesUtils.hpp"
+
+#include "OperationsUtils.h"
+
+#include <condition_variable>
+
+namespace android
+{
+namespace hardware
+{
+namespace neuralnetworks
+{
+namespace V1_0
+{
+
+std::ostream& operator<<(std::ostream& os, ErrorStatus stat)
+{
+   return os << static_cast<int>(stat);
+}
+
+}
+}
+}
+}
+
+BOOST_AUTO_TEST_SUITE(DriverTests)
+
+using namespace armnn_driver;
+using namespace android::nn;
+using namespace android;
+
+BOOST_AUTO_TEST_CASE(Init)
+{
+    // Making the driver object on the stack causes a weird libc error, so make it on the heap instead
+    auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
+
+    DeviceStatus status = driver->getStatus();
+    // Note double-parentheses to avoid compile error from Boost trying to printf the DeviceStatus
+    BOOST_TEST((status == DeviceStatus::AVAILABLE));
+}
+
+BOOST_AUTO_TEST_CASE(TestCapabilities)
+{
+    // Making the driver object on the stack causes a weird libc error, so make it on the heap instead
+    auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
+
+    ErrorStatus error;
+    Capabilities cap;
+
+    ArmnnDriver::getCapabilities_cb cb = [&](ErrorStatus status, const Capabilities& capabilities)
+    {
+        error = status;
+        cap = capabilities;
+    };
+
+    driver->getCapabilities(cb);
+
+    BOOST_TEST((int)error == (int)ErrorStatus::NONE);
+    BOOST_TEST(cap.float32Performance.execTime > 0.f);
+    BOOST_TEST(cap.float32Performance.powerUsage > 0.f);
+    BOOST_TEST(cap.quantized8Performance.execTime > 0.f);
+    BOOST_TEST(cap.quantized8Performance.powerUsage > 0.f);
+}
+
+BOOST_AUTO_TEST_CASE(SystemProperties)
+{
+    // Test default value
+    {
+        auto p = __system_property_find("thisDoesNotExist");
+        BOOST_TEST((p == nullptr));
+
+        int defaultValue = ParseSystemProperty("thisDoesNotExist", -4);
+        BOOST_TEST((defaultValue == -4));
+    }
+
+    //  Test default value from bad data type
+    {
+        __system_property_set("thisIsNotFloat", "notfloat");
+        float defaultValue = ParseSystemProperty("thisIsNotFloat", 0.1f);
+        BOOST_TEST((defaultValue == 0.1f));
+    }
+
+    // Test fetching bool values
+    {
+        __system_property_set("myTestBool", "1");
+        bool b = ParseSystemProperty("myTestBool", false);
+        BOOST_TEST((b == true));
+    }
+    {
+        __system_property_set("myTestBool", "0");
+        bool b = ParseSystemProperty("myTestBool", true);
+        BOOST_TEST((b == false));
+    }
+
+    // Test fetching int
+    {
+        __system_property_set("myTestInt", "567");
+        int i = ParseSystemProperty("myTestInt", 890);
+        BOOST_TEST((i==567));
+    }
+
+    // Test fetching float
+    {
+        __system_property_set("myTestFloat", "1.2f");
+        float f = ParseSystemProperty("myTestFloat", 3.4f);
+        BOOST_TEST((f==1.2f));
+    }
+}
+
+// The following are helpers for writing unit tests for the driver
+namespace
+{
+
+struct ExecutionCallback : public IExecutionCallback
+{
+    ExecutionCallback()
+        : mNotified(false)
+    {
+    }
+
+    Return<void> notify(ErrorStatus status) override
+    {
+        (void)status;
+        ALOGI("ExecutionCallback::notify invoked");
+        std::lock_guard<std::mutex> executionLock(mMutex);
+        mNotified = true;
+        mCondition.notify_one();
+        return Void();
+    }
+
+    /// wait until the callback has notified us that it is done
+    Return<void> wait()
+    {
+        ALOGI("ExecutionCallback::wait invoked");
+        std::unique_lock<std::mutex> executionLock(mMutex);
+        while (!mNotified)
+        {
+            mCondition.wait(executionLock);
+        }
+        mNotified = false;
+        return Void();
+    }
+
+private:
+    // use a mutex and a condition variable to wait for asynchronous callbacks
+    std::mutex mMutex;
+    std::condition_variable mCondition;
+    // and a flag, in case we are notified before the wait call
+    bool mNotified;
+};
+
+class PreparedModelCallback : public IPreparedModelCallback
+{
+public:
+    PreparedModelCallback()
+    {
+    }
+
+    ~PreparedModelCallback() override
+    {
+    }
+
+    Return<void> notify(ErrorStatus status, const sp<IPreparedModel>& preparedModel) override
+    {
+        m_ErrorStatus = status;
+        m_PreparedModel = preparedModel;
+        return Void();
+    }
+
+    ErrorStatus GetErrorStatus()
+    {
+        return m_ErrorStatus;
+    }
+
+    sp<IPreparedModel> GetPreparedModel()
+    {
+        return m_PreparedModel;
+    }
+
+
+private:
+    ErrorStatus        m_ErrorStatus;
+    sp<IPreparedModel> m_PreparedModel;
+};
+
+
+
+// lifted from common/Utils.cpp
+hidl_memory allocateSharedMemory(int64_t size)
+{
+    hidl_memory memory;
+
+    const std::string& type      = "ashmem";
+    android::sp<IAllocator>     allocator = IAllocator::getService(type);
+    allocator->allocate(size, [&](bool success, const hidl_memory& mem) {
+        if (!success)
+        {
+            ALOGE("unable to allocate %li bytes of %s", size, type.c_str());
+        }
+        else
+        {
+            memory = mem;
+        }
+    });
+
+    return memory;
+}
+
+
+android::sp<IMemory> AddPoolAndGetData(uint32_t size, Request& request)
+{
+    hidl_memory pool;
+
+    android::sp<IAllocator> allocator = IAllocator::getService("ashmem");
+    allocator->allocate(sizeof(float) * size, [&](bool success, const hidl_memory& mem) {
+        BOOST_TEST(success);
+        pool = mem;
+    });
+
+    request.pools.resize(request.pools.size() + 1);
+    request.pools[request.pools.size() - 1] = pool;
+
+    android::sp<IMemory> mapped = mapMemory(pool);
+    mapped->update();
+    return mapped;
+}
+
+void AddPoolAndSetData(uint32_t size, Request& request, float* data)
+{
+    android::sp<IMemory> memory = AddPoolAndGetData(size, request);
+
+    float* dst = static_cast<float*>(static_cast<void*>(memory->getPointer()));
+
+    memcpy(dst, data, size * sizeof(float));
+}
+
+void AddOperand(Model& model, const Operand& op)
+{
+    model.operands.resize(model.operands.size() + 1);
+    model.operands[model.operands.size() - 1] = op;
+}
+
+void AddIntOperand(Model& model, int32_t value)
+{
+    DataLocation location = {};
+    location.offset = model.operandValues.size();
+    location.length = sizeof(int32_t);
+
+    Operand op    = {};
+    op.type = OperandType::INT32;
+    op.dimensions = hidl_vec<uint32_t>{};
+    op.lifetime   = OperandLifeTime::CONSTANT_COPY;
+    op.location   = location;
+
+    model.operandValues.resize(model.operandValues.size() + location.length);
+    *reinterpret_cast<int32_t*>(&model.operandValues[location.offset]) = value;
+
+    AddOperand(model, op);
+}
+
+template<typename T>
+OperandType TypeToOperandType();
+
+template<>
+OperandType TypeToOperandType<float>()
+{
+    return OperandType::TENSOR_FLOAT32;
+};
+
+template<>
+OperandType TypeToOperandType<int32_t>()
+{
+    return OperandType::TENSOR_INT32;
+};
+
+
+
+template<typename T>
+void AddTensorOperand(Model& model, hidl_vec<uint32_t> dimensions, T* values)
+{
+    uint32_t totalElements = 1;
+    for (uint32_t dim : dimensions)
+    {
+        totalElements *= dim;
+    }
+
+    DataLocation location = {};
+    location.offset = model.operandValues.size();
+    location.length = totalElements * sizeof(T);
+
+    Operand op    = {};
+    op.type       = TypeToOperandType<T>();
+    op.dimensions = dimensions;
+    op.lifetime   = OperandLifeTime::CONSTANT_COPY;
+    op.location   = location;
+
+    model.operandValues.resize(model.operandValues.size() + location.length);
+    for (uint32_t i = 0; i < totalElements; i++)
+    {
+        *(reinterpret_cast<T*>(&model.operandValues[location.offset]) + i) = values[i];
+    }
+
+    AddOperand(model, op);
+}
+
+void AddInputOperand(Model& model, hidl_vec<uint32_t> dimensions)
+{
+    Operand op    = {};
+    op.type       = OperandType::TENSOR_FLOAT32;
+    op.dimensions = dimensions;
+    op.lifetime   = OperandLifeTime::MODEL_INPUT;
+
+    AddOperand(model, op);
+
+    model.inputIndexes.resize(model.inputIndexes.size() + 1);
+    model.inputIndexes[model.inputIndexes.size() - 1] = model.operands.size() - 1;
+}
+
+void AddOutputOperand(Model& model, hidl_vec<uint32_t> dimensions)
+{
+    Operand op = {};
+    op.type       = OperandType::TENSOR_FLOAT32;
+    op.dimensions = dimensions;
+    op.lifetime   = OperandLifeTime::MODEL_OUTPUT;
+
+    AddOperand(model, op);
+
+    model.outputIndexes.resize(model.outputIndexes.size() + 1);
+    model.outputIndexes[model.outputIndexes.size() - 1] = model.operands.size() - 1;
+}
+
+android::sp<IPreparedModel> PrepareModel(const Model& model, ArmnnDriver& driver)
+{
+
+    sp<PreparedModelCallback> cb(new PreparedModelCallback());
+    driver.prepareModel(model, cb);
+
+    BOOST_TEST((cb->GetErrorStatus() == ErrorStatus::NONE));
+    BOOST_TEST((cb->GetPreparedModel() != nullptr));
+
+    return cb->GetPreparedModel();
+}
+
+void Execute(android::sp<IPreparedModel> preparedModel, const Request& request)
+{
+    sp<ExecutionCallback> cb(new ExecutionCallback());
+    BOOST_TEST(preparedModel->execute(request, cb) == ErrorStatus::NONE);
+    ALOGI("Execute: waiting for callback to be invoked");
+    cb->wait();
+}
+
+sp<ExecutionCallback> ExecuteNoWait(android::sp<IPreparedModel> preparedModel, const Request& request)
+{
+    sp<ExecutionCallback> cb(new ExecutionCallback());
+    BOOST_TEST(preparedModel->execute(request, cb) == ErrorStatus::NONE);
+    ALOGI("ExecuteNoWait: returning callback object");
+    return cb;
+}
+}
+
+// Add our own test here since we fail the fc tests which Google supplies (because of non-const weights)
+BOOST_AUTO_TEST_CASE(FullyConnected)
+{
+    // this should ideally replicate fully_connected_float.model.cpp
+    // but that uses slightly weird dimensions which I don't think we need to support for now
+
+    auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
+    Model model = {};
+
+    // add operands
+    int32_t actValue      = 0;
+    float   weightValue[] = {2, 4, 1};
+    float   biasValue[]   = {4};
+
+    AddInputOperand(model, hidl_vec<uint32_t>{1, 3});
+    AddTensorOperand(model, hidl_vec<uint32_t>{1, 3}, weightValue);
+    AddTensorOperand(model, hidl_vec<uint32_t>{1}, biasValue);
+    AddIntOperand(model, actValue);
+    AddOutputOperand(model, hidl_vec<uint32_t>{1, 1});
+
+    // make the fully connected operation
+    model.operations.resize(1);
+    model.operations[0].type = OperationType::FULLY_CONNECTED;
+    model.operations[0].inputs  = hidl_vec<uint32_t>{0, 1, 2, 3};
+    model.operations[0].outputs = hidl_vec<uint32_t>{4};
+
+    // make the prepared model
+    android::sp<IPreparedModel> preparedModel = PrepareModel(model, *driver);
+
+    // construct the request
+    DataLocation inloc = {};
+    inloc.poolIndex = 0;
+    inloc.offset    = 0;
+    inloc.length    = 3 * sizeof(float);
+    RequestArgument input = {};
+    input.location = inloc;
+    input.dimensions = hidl_vec<uint32_t>{};
+
+    DataLocation outloc = {};
+    outloc.poolIndex = 1;
+    outloc.offset    = 0;
+    outloc.length    = 1 * sizeof(float);
+    RequestArgument output = {};
+    output.location  = outloc;
+    output.dimensions = hidl_vec<uint32_t>{};
+
+    Request request = {};
+    request.inputs  = hidl_vec<RequestArgument>{input};
+    request.outputs = hidl_vec<RequestArgument>{output};
+
+    // set the input data (matching source test)
+    float indata[] = {2, 32, 16};
+    AddPoolAndSetData(3, request, indata);
+
+    // add memory for the output
+    android::sp<IMemory> outMemory = AddPoolAndGetData(1, request);
+    float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
+
+    // run the execution
+    Execute(preparedModel, request);
+
+    // check the result
+    BOOST_TEST(outdata[0] == 152);
+}
+
+// Add our own test for concurrent execution
+// The main point of this test is to check that multiple requests can be
+// executed without waiting for the callback from previous execution.
+// The operations performed are not significant.
+BOOST_AUTO_TEST_CASE(ConcurrentExecute)
+{
+    ALOGI("ConcurrentExecute: entry");
+
+    auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
+    Model model = {};
+
+    // add operands
+    int32_t actValue      = 0;
+    float   weightValue[] = {2, 4, 1};
+    float   biasValue[]   = {4};
+
+    AddInputOperand(model, hidl_vec<uint32_t>{1, 3});
+    AddTensorOperand(model, hidl_vec<uint32_t>{1, 3}, weightValue);
+    AddTensorOperand(model, hidl_vec<uint32_t>{1}, biasValue);
+    AddIntOperand(model, actValue);
+    AddOutputOperand(model, hidl_vec<uint32_t>{1, 1});
+
+    // make the fully connected operation
+    model.operations.resize(1);
+    model.operations[0].type = OperationType::FULLY_CONNECTED;
+    model.operations[0].inputs  = hidl_vec<uint32_t>{0, 1, 2, 3};
+    model.operations[0].outputs = hidl_vec<uint32_t>{4};
+
+    // make the prepared models
+    const size_t maxRequests = 5;
+    android::sp<IPreparedModel> preparedModels[maxRequests];
+    for (size_t i = 0; i < maxRequests; ++i)
+    {
+        preparedModels[i] = PrepareModel(model, *driver);
+    }
+
+    // construct the request data
+    DataLocation inloc = {};
+    inloc.poolIndex = 0;
+    inloc.offset    = 0;
+    inloc.length    = 3 * sizeof(float);
+    RequestArgument input = {};
+    input.location = inloc;
+    input.dimensions = hidl_vec<uint32_t>{};
+
+    DataLocation outloc = {};
+    outloc.poolIndex = 1;
+    outloc.offset    = 0;
+    outloc.length    = 1 * sizeof(float);
+    RequestArgument output = {};
+    output.location  = outloc;
+    output.dimensions = hidl_vec<uint32_t>{};
+
+    // build the requests
+    Request requests[maxRequests];
+    android::sp<IMemory> outMemory[maxRequests];
+    float* outdata[maxRequests];
+    for (size_t i = 0; i < maxRequests; ++i)
+    {
+        requests[i].inputs  = hidl_vec<RequestArgument>{input};
+        requests[i].outputs = hidl_vec<RequestArgument>{output};
+        // set the input data (matching source test)
+        float indata[] = {2, 32, 16};
+        AddPoolAndSetData(3, requests[i], indata);
+        // add memory for the output
+        outMemory[i] = AddPoolAndGetData(1, requests[i]);
+        outdata[i] = static_cast<float*>(static_cast<void*>(outMemory[i]->getPointer()));
+    }
+
+    // invoke the execution of the requests
+    ALOGI("ConcurrentExecute: executing requests");
+    sp<ExecutionCallback> cb[maxRequests];
+    for (size_t i = 0; i < maxRequests; ++i)
+    {
+        cb[i] = ExecuteNoWait(preparedModels[i], requests[i]);
+    }
+
+    // wait for the requests to complete
+    ALOGI("ConcurrentExecute: waiting for callbacks");
+    for (size_t i = 0; i < maxRequests; ++i)
+    {
+        cb[i]->wait();
+    }
+
+    // check the results
+    ALOGI("ConcurrentExecute: validating results");
+    for (size_t i = 0; i < maxRequests; ++i)
+    {
+        BOOST_TEST(outdata[i][0] == 152);
+    }
+    ALOGI("ConcurrentExecute: exit");
+}
+
+BOOST_AUTO_TEST_CASE(GetSupportedOperations)
+{
+    auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
+
+    ErrorStatus error;
+    std::vector<bool> sup;
+
+    ArmnnDriver::getSupportedOperations_cb cb = [&](ErrorStatus status, const std::vector<bool>& supported)
+    {
+        error = status;
+        sup = supported;
+    };
+
+    Model model1 = {};
+
+    // add operands
+    int32_t actValue      = 0;
+    float   weightValue[] = {2, 4, 1};
+    float   biasValue[]   = {4};
+
+    AddInputOperand(model1, hidl_vec<uint32_t>{1, 3});
+    AddTensorOperand(model1, hidl_vec<uint32_t>{1, 3}, weightValue);
+    AddTensorOperand(model1, hidl_vec<uint32_t>{1}, biasValue);
+    AddIntOperand(model1, actValue);
+    AddOutputOperand(model1, hidl_vec<uint32_t>{1, 1});
+
+    // make a correct fully connected operation
+    model1.operations.resize(2);
+    model1.operations[0].type = OperationType::FULLY_CONNECTED;
+    model1.operations[0].inputs  = hidl_vec<uint32_t>{0, 1, 2, 3};
+    model1.operations[0].outputs = hidl_vec<uint32_t>{4};
+
+    // make an incorrect fully connected operation
+    AddIntOperand(model1, actValue);
+    AddOutputOperand(model1, hidl_vec<uint32_t>{1, 1});
+    model1.operations[1].type = OperationType::FULLY_CONNECTED;
+    model1.operations[1].inputs = hidl_vec<uint32_t>{4};
+    model1.operations[1].outputs = hidl_vec<uint32_t>{5};
+
+    driver->getSupportedOperations(model1, cb);
+    BOOST_TEST((int)error == (int)ErrorStatus::NONE);
+    BOOST_TEST(sup[0] == true);
+    BOOST_TEST(sup[1] == false);
+
+    // Broadcast add/mul are not supported
+    Model model2 = {};
+
+    AddInputOperand(model2, hidl_vec<uint32_t>{1, 1, 3, 4});
+    AddInputOperand(model2, hidl_vec<uint32_t>{4});
+    AddOutputOperand(model2, hidl_vec<uint32_t>{1, 1, 3, 4});
+    AddOutputOperand(model2, hidl_vec<uint32_t>{1, 1, 3, 4});
+
+    model2.operations.resize(2);
+
+    model2.operations[0].type = OperationType::ADD;
+    model2.operations[0].inputs = hidl_vec<uint32_t>{0,1};
+    model2.operations[0].outputs = hidl_vec<uint32_t>{2};
+
+    model2.operations[1].type = OperationType::MUL;
+    model2.operations[1].inputs = hidl_vec<uint32_t>{0,1};
+    model2.operations[1].outputs = hidl_vec<uint32_t>{3};
+
+    driver->getSupportedOperations(model2, cb);
+    BOOST_TEST((int)error == (int)ErrorStatus::NONE);
+    BOOST_TEST(sup[0] == false);
+    BOOST_TEST(sup[1] == false);
+
+    Model model3 = {};
+
+    // Add unsupported operation, should return no error but we don't support it
+    AddInputOperand(model3, hidl_vec<uint32_t>{1, 1, 1, 8});
+    AddIntOperand(model3, 2);
+    AddOutputOperand(model3, hidl_vec<uint32_t>{1, 2, 2, 2});
+    model3.operations.resize(1);
+    model3.operations[0].type = OperationType::DEPTH_TO_SPACE;
+    model1.operations[0].inputs = hidl_vec<uint32_t>{0, 1};
+    model3.operations[0].outputs = hidl_vec<uint32_t>{2};
+
+    driver->getSupportedOperations(model3, cb);
+    BOOST_TEST((int)error == (int)ErrorStatus::NONE);
+    BOOST_TEST(sup[0] == false);
+
+    // Add invalid operation
+    Model model4 = {};
+    AddIntOperand(model4, 0);
+    model4.operations.resize(1);
+    model4.operations[0].type = static_cast<OperationType>(100);
+    model4.operations[0].outputs = hidl_vec<uint32_t>{0};
+
+    driver->getSupportedOperations(model4, cb);
+    BOOST_TEST((int)error == (int)ErrorStatus::INVALID_ARGUMENT);
+}
+
+// The purpose of this test is to ensure that when encountering an unsupported operation
+//      it is skipped and getSupportedOperations() continues (rather than failing and stopping).
+//      As per IVGCVSW-710.
+BOOST_AUTO_TEST_CASE(UnsupportedLayerContinueOnFailure)
+{
+    auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
+
+    ErrorStatus error;
+    std::vector<bool> sup;
+
+    ArmnnDriver::getSupportedOperations_cb cb = [&](ErrorStatus status, const std::vector<bool>& supported)
+    {
+        error = status;
+        sup = supported;
+    };
+
+    Model model = {};
+
+    // operands
+    int32_t actValue      = 0;
+    float   weightValue[] = {2, 4, 1};
+    float   biasValue[]   = {4};
+
+    // broadcast add is unsupported at the time of writing this test, but any unsupported layer will do
+    AddInputOperand(model, hidl_vec<uint32_t>{1, 1, 3, 4});
+    AddInputOperand(model, hidl_vec<uint32_t>{4});
+    AddOutputOperand(model, hidl_vec<uint32_t>{1, 1, 3, 4});
+
+    // fully connected
+    AddInputOperand(model, hidl_vec<uint32_t>{1, 3});
+    AddTensorOperand(model, hidl_vec<uint32_t>{1, 3}, weightValue);
+    AddTensorOperand(model, hidl_vec<uint32_t>{1}, biasValue);
+    AddIntOperand(model, actValue);
+    AddOutputOperand(model, hidl_vec<uint32_t>{1, 1});
+
+    // broadcast mul is unsupported
+    AddOutputOperand(model, hidl_vec<uint32_t>{1, 1, 3, 4});
+
+    model.operations.resize(3);
+
+    // unsupported
+    model.operations[0].type = OperationType::ADD;
+    model.operations[0].inputs = hidl_vec<uint32_t>{0,1};
+    model.operations[0].outputs = hidl_vec<uint32_t>{2};
+
+    // supported
+    model.operations[1].type = OperationType::FULLY_CONNECTED;
+    model.operations[1].inputs  = hidl_vec<uint32_t>{3, 4, 5, 6};
+    model.operations[1].outputs = hidl_vec<uint32_t>{7};
+
+    // unsupported
+    model.operations[2].type = OperationType::MUL;
+    model.operations[2].inputs = hidl_vec<uint32_t>{0,1};
+    model.operations[2].outputs = hidl_vec<uint32_t>{8};
+
+    // we are testing that the unsupported layers return false and the test continues
+    //      rather than failing and stopping.
+    driver->getSupportedOperations(model, cb);
+    BOOST_TEST((int)error == (int)ErrorStatus::NONE);
+    BOOST_TEST(sup[0] == false);
+    BOOST_TEST(sup[1] == true);
+    BOOST_TEST(sup[2] == false);
+}
+
+// The purpose of this test is to ensure that when encountering an failure
+//      during mem pool mapping we properly report an error to the framework via a callback
+BOOST_AUTO_TEST_CASE(ModelToINetworkConverterMemPoolFail)
+{
+    auto driver = std::make_unique<ArmnnDriver>(armnn::Compute::CpuRef);
+
+    ErrorStatus error;
+    std::vector<bool> sup;
+
+    ArmnnDriver::getSupportedOperations_cb cb = [&](ErrorStatus status, const std::vector<bool>& supported)
+    {
+        error = status;
+        sup = supported;
+    };
+
+    Model model = {};
+
+    model.pools = hidl_vec<hidl_memory>{hidl_memory("Unsuported hidl memory type", nullptr, 0)};
+
+    //memory pool mapping should fail, we should report an error
+    driver->getSupportedOperations(model, cb);
+    BOOST_TEST((int)error == (int)ErrorStatus::GENERAL_FAILURE);
+}
+
+namespace
+{
+
+void PaddingTestImpl(android::nn::PaddingScheme paddingScheme)
+{
+    auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
+    Model model  = {};
+
+    uint32_t outSize = paddingScheme == kPaddingSame ? 2 : 1;
+
+    // add operands
+    float weightValue[] = {1, -1, 0, 1};
+    float biasValue[]   = {0};
+
+    AddInputOperand(model, hidl_vec<uint32_t>{1, 2, 3, 1});
+    AddTensorOperand(model, hidl_vec<uint32_t>{1, 2, 2, 1}, weightValue);
+    AddTensorOperand(model, hidl_vec<uint32_t>{1}, biasValue);
+    AddIntOperand(model, (int32_t)paddingScheme); // padding
+    AddIntOperand(model, 2); // stride x
+    AddIntOperand(model, 2); // stride y
+    AddIntOperand(model, 0); // no activation
+    AddOutputOperand(model, hidl_vec<uint32_t>{1, 1, outSize, 1});
+
+    // make the convolution operation
+    model.operations.resize(1);
+    model.operations[0].type = OperationType::CONV_2D;
+    model.operations[0].inputs  = hidl_vec<uint32_t>{0, 1, 2, 3, 4, 5, 6};
+    model.operations[0].outputs = hidl_vec<uint32_t>{7};
+
+    // make the prepared model
+    android::sp<IPreparedModel> preparedModel = PrepareModel(model, *driver);
+
+    // construct the request
+    DataLocation inloc    = {};
+    inloc.poolIndex       = 0;
+    inloc.offset          = 0;
+    inloc.length          = 6 * sizeof(float);
+    RequestArgument input = {};
+    input.location        = inloc;
+    input.dimensions      = hidl_vec<uint32_t>{};
+
+    DataLocation outloc    = {};
+    outloc.poolIndex       = 1;
+    outloc.offset          = 0;
+    outloc.length          = outSize * sizeof(float);
+    RequestArgument output = {};
+    output.location        = outloc;
+    output.dimensions      = hidl_vec<uint32_t>{};
+
+    Request request = {};
+    request.inputs  = hidl_vec<RequestArgument>{input};
+    request.outputs = hidl_vec<RequestArgument>{output};
+
+
+    // set the input data (matching source test)
+    float indata[] = {4, 1, 0, 3, -1, 2};
+    AddPoolAndSetData(6, request, indata);
+
+    // add memory for the output
+    android::sp<IMemory> outMemory = AddPoolAndGetData(outSize, request);
+    float*               outdata   = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
+
+    // run the execution
+    Execute(preparedModel, request);
+
+    // check the result
+    if (paddingScheme == kPaddingValid)
+    {
+        BOOST_TEST(outdata[0] == 2);
+    }
+    else if (paddingScheme == kPaddingSame)
+    {
+        BOOST_TEST(outdata[0] == 2);
+        BOOST_TEST(outdata[1] == 0);
+    }
+    else
+    {
+        BOOST_TEST(false);
+    }
+}
+
+}
+
+BOOST_AUTO_TEST_CASE(ConvValidPadding)
+{
+    PaddingTestImpl(kPaddingValid);
+}
+
+BOOST_AUTO_TEST_CASE(ConvSamePadding)
+{
+    PaddingTestImpl(kPaddingSame);
+}
+
+BOOST_AUTO_TEST_CASE(TestFullyConnected4dInput)
+{
+    auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
+
+    ErrorStatus error;
+    std::vector<bool> sup;
+
+    ArmnnDriver::getSupportedOperations_cb cb = [&](ErrorStatus status, const std::vector<bool>& supported)
+        {
+            error = status;
+            sup = supported;
+        };
+
+    Model model = {};
+
+    // operands
+    int32_t actValue      = 0;
+    float   weightValue[] = {1, 0, 0, 0, 0, 0, 0, 0,
+                             0, 1, 0, 0, 0, 0, 0, 0,
+                             0, 0, 1, 0, 0, 0, 0, 0,
+                             0, 0, 0, 1, 0, 0, 0, 0,
+                             0, 0, 0, 0, 1, 0, 0, 0,
+                             0, 0, 0, 0, 0, 1, 0, 0,
+                             0, 0, 0, 0, 0, 0, 1, 0,
+                             0, 0, 0, 0, 0, 0, 0, 1}; //identity
+    float   biasValue[]   = {0, 0, 0, 0, 0, 0, 0, 0};
+
+    // fully connected operation
+    AddInputOperand(model, hidl_vec<uint32_t>{1, 1, 1, 8});
+    AddTensorOperand(model, hidl_vec<uint32_t>{8, 8}, weightValue);
+    AddTensorOperand(model, hidl_vec<uint32_t>{8}, biasValue);
+    AddIntOperand(model, actValue);
+    AddOutputOperand(model, hidl_vec<uint32_t>{1, 8});
+
+    model.operations.resize(1);
+
+    model.operations[0].type = OperationType::FULLY_CONNECTED;
+    model.operations[0].inputs  = hidl_vec<uint32_t>{0,1,2,3};
+    model.operations[0].outputs = hidl_vec<uint32_t>{4};
+
+    // make the prepared model
+    android::sp<IPreparedModel> preparedModel = PrepareModel(model, *driver);
+
+
+    // construct the request
+    DataLocation inloc = {};
+    inloc.poolIndex = 0;
+    inloc.offset    = 0;
+    inloc.length    = 8 * sizeof(float);
+    RequestArgument input = {};
+    input.location = inloc;
+    input.dimensions = hidl_vec<uint32_t>{};
+
+    DataLocation outloc = {};
+    outloc.poolIndex = 1;
+    outloc.offset    = 0;
+    outloc.length    = 8 * sizeof(float);
+    RequestArgument output = {};
+    output.location  = outloc;
+    output.dimensions = hidl_vec<uint32_t>{};
+
+    Request request = {};
+    request.inputs  = hidl_vec<RequestArgument>{input};
+    request.outputs = hidl_vec<RequestArgument>{output};
+
+    // set the input data
+    float indata[] = {1,2,3,4,5,6,7,8};
+    AddPoolAndSetData(8, request, indata);
+
+    // add memory for the output
+    android::sp<IMemory> outMemory = AddPoolAndGetData(8, request);
+    float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
+
+    // run the execution
+    Execute(preparedModel, request);
+
+    // check the result
+    BOOST_TEST(outdata[0] == 1);
+    BOOST_TEST(outdata[1] == 2);
+    BOOST_TEST(outdata[2] == 3);
+    BOOST_TEST(outdata[3] == 4);
+    BOOST_TEST(outdata[4] == 5);
+    BOOST_TEST(outdata[5] == 6);
+    BOOST_TEST(outdata[6] == 7);
+    BOOST_TEST(outdata[7] == 8);
+}
+
+BOOST_AUTO_TEST_CASE(TestFullyConnected4dInputReshape)
+{
+    auto driver = std::make_unique<ArmnnDriver>(DriverOptions(armnn::Compute::CpuRef));
+
+    ErrorStatus error;
+    std::vector<bool> sup;
+
+    ArmnnDriver::getSupportedOperations_cb cb = [&](ErrorStatus status, const std::vector<bool>& supported)
+        {
+            error = status;
+            sup = supported;
+        };
+
+    Model model = {};
+
+    // operands
+    int32_t actValue      = 0;
+    float   weightValue[] = {1, 0, 0, 0, 0, 0, 0, 0,
+                             0, 1, 0, 0, 0, 0, 0, 0,
+                             0, 0, 1, 0, 0, 0, 0, 0,
+                             0, 0, 0, 1, 0, 0, 0, 0,
+                             0, 0, 0, 0, 1, 0, 0, 0,
+                             0, 0, 0, 0, 0, 1, 0, 0,
+                             0, 0, 0, 0, 0, 0, 1, 0,
+                             0, 0, 0, 0, 0, 0, 0, 1}; //identity
+    float   biasValue[]   = {0, 0, 0, 0, 0, 0, 0, 0};
+
+    // fully connected operation
+    AddInputOperand(model, hidl_vec<uint32_t>{1, 2, 2, 2});
+    AddTensorOperand(model, hidl_vec<uint32_t>{8, 8}, weightValue);
+    AddTensorOperand(model, hidl_vec<uint32_t>{8}, biasValue);
+    AddIntOperand(model, actValue);
+    AddOutputOperand(model, hidl_vec<uint32_t>{1, 8});
+
+    model.operations.resize(1);
+
+    model.operations[0].type = OperationType::FULLY_CONNECTED;
+    model.operations[0].inputs  = hidl_vec<uint32_t>{0,1,2,3};
+    model.operations[0].outputs = hidl_vec<uint32_t>{4};
+
+    // make the prepared model
+    android::sp<IPreparedModel> preparedModel = PrepareModel(model, *driver);
+
+
+    // construct the request
+    DataLocation inloc = {};
+    inloc.poolIndex = 0;
+    inloc.offset    = 0;
+    inloc.length    = 8 * sizeof(float);
+    RequestArgument input = {};
+    input.location = inloc;
+    input.dimensions = hidl_vec<uint32_t>{};
+
+    DataLocation outloc = {};
+    outloc.poolIndex = 1;
+    outloc.offset    = 0;
+    outloc.length    = 8 * sizeof(float);
+    RequestArgument output = {};
+    output.location  = outloc;
+    output.dimensions = hidl_vec<uint32_t>{};
+
+    Request request = {};
+    request.inputs  = hidl_vec<RequestArgument>{input};
+    request.outputs = hidl_vec<RequestArgument>{output};
+
+    // set the input data
+    float indata[] = {1,2,3,4,5,6,7,8};
+    AddPoolAndSetData(8, request, indata);
+
+    // add memory for the output
+    android::sp<IMemory> outMemory = AddPoolAndGetData(8, request);
+    float* outdata = static_cast<float*>(static_cast<void*>(outMemory->getPointer()));
+
+    // run the execution
+    Execute(preparedModel, request);
+
+    // check the result
+    BOOST_TEST(outdata[0] == 1);
+    BOOST_TEST(outdata[1] == 2);
+    BOOST_TEST(outdata[2] == 3);
+    BOOST_TEST(outdata[3] == 4);
+    BOOST_TEST(outdata[4] == 5);
+    BOOST_TEST(outdata[5] == 6);
+    BOOST_TEST(outdata[6] == 7);
+    BOOST_TEST(outdata[7] == 8);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
