diff --git a/ase/tests/test_api_c_ase.cpp b/ase/tests/test_api_c_ase.cpp new file mode 100644 index 0000000..baf45c3 --- /dev/null +++ b/ase/tests/test_api_c_ase.cpp @@ -0,0 +1,153 @@ +// Copyright(c) 2019, Intel Corporation +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Intel Corporation nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +extern "C" { +#include +#include +#include +#include +#include "types_int.h" +#include "ase_common.h" +#include "wsid_list_int.h" +#include "props.h" + +fpga_result prop_check_and_lock(struct _fpga_properties *prop); +fpga_result handle_check_and_lock(struct _fpga_handle *handle); +fpga_result event_handle_check_and_lock(struct _fpga_event_handle *eh); +} + +#include "gtest/gtest.h" +#include "test_system.h" +#include "ase.h" + +/** +* @test ase_common_01 +* +* @brief When the property's magic is invalid and libopae-ase-c is loaded: +* prop_check_and_lock() function should return FPGA_INVALID_PARAM +* +*/ +TEST(sim_sw_ase, ase_common_01) { + struct _fpga_properties prop; + + prop.lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + prop.magic = FPGA_PROPERTY_MAGIC; + EXPECT_EQ(FPGA_OK, prop_check_and_lock(&prop)); + + prop.magic = 0xFFFFFFFF; + EXPECT_EQ(FPGA_INVALID_PARAM, prop_check_and_lock(&prop)); + + +} + +/** +* @test ase_common_02 +* +* @brief When the FPGA handle's magic is invalid and libopae-ase-c is loaded: +* prop_check_and_lock() function should return FPGA_INVALID_PARAM +* +*/ +TEST(sim_sw_ase, ase_common_02) { + struct _fpga_handle handle; + + handle.magic = 0xFFFFFFFF; + handle.lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + EXPECT_EQ(FPGA_INVALID_PARAM, handle_check_and_lock(&handle)); +} + +/** +* @test ase_common_03 +* +* @brief When the event handle's magic is invalid and libopae-ase-c is loaded: +* prop_check_and_lock() function should return FPGA_INVALID_PARAM +* +*/ +TEST(sim_sw_ase, ase_common_03) { + struct _fpga_event_handle ehandle; + + ehandle.magic = 0xFFFFFFFF; + ehandle.lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + EXPECT_EQ(FPGA_INVALID_PARAM, event_handle_check_and_lock(&ehandle)); +} + +/** + * @test fpga_version + * + * @brief When the parameter fpga_version* to fpgaGetOPAECVersion() is nullptr, + * the function returns FPGA_INVALID_PARAM. + * If the parameter fpga_version* to fpgaGetOPAECVersion() is valid, + * the function returns FPGA_OK. + * When the parameter version_str* to fpgaGetOPAECVersionString() is nullptr, + * the function returns FPGA_INVALID_PARAM. + * When the parameter build_str* to fpgaGetOPAECBuildString() is nullptr, + * the function returns FPGA_INVALID_PARAM. + */ +TEST(open_c_ase, fpga_version) { + EXPECT_EQ(FPGA_INVALID_PARAM, fpgaGetOPAECVersion(nullptr)); + fpga_version version; + EXPECT_EQ(FPGA_OK, fpgaGetOPAECVersion(&version)); + + EXPECT_EQ(FPGA_INVALID_PARAM, fpgaGetOPAECVersionString(nullptr, 10)); + EXPECT_EQ(FPGA_INVALID_PARAM, fpgaGetOPAECBuildString(nullptr, 10)); +} + +/** + * @test ase_wsid_1 + * + * @brief When the parameter n_hash_buckets is zero or greater than 16384, + * the function returns NULL. + */ +TEST(open_c_ase, ase_wsid_1) { + EXPECT_EQ(NULL, wsid_tracker_init(0)); + EXPECT_EQ(NULL, wsid_tracker_init(NUM_WSID_TRACKER_BUCKETS+1)); + +} + +/** +* @test ase_wsid_2 +* +* @brief When memory allocation function ase_malloc failed, +* wsid_tracker_init() function should return NULL and +* wsid_add() returns false +* +*/ +using namespace opae::testing; +TEST(sim_sw_ase, ase_wsid_2) { + test_system *system_; + system_ = test_system::instance(); + system_->initialize(); + + // Invalidate the memory allocation . + system_->invalidate_malloc(0, "wsid_tracker_init"); + system_->invalidate_malloc(0, "ase_malloc"); + EXPECT_EQ(wsid_tracker_init(1000), (struct wsid_tracker*)NULL); + + system_->finalize(); +} + + + + diff --git a/ase/tests/test_enum_c_ase.cpp b/ase/tests/test_enum_c_ase.cpp new file mode 100644 index 0000000..bffc296 --- /dev/null +++ b/ase/tests/test_enum_c_ase.cpp @@ -0,0 +1,393 @@ +// Copyright(c) 2019, Intel Corporation +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Intel Corporation nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +extern "C" { +#include +#include +#include +#include "types_int.h" +#include "props.h" + +void api_guid_to_fpga(uint64_t guidh, uint64_t guidl, uint8_t *guid); +bool matches_filters(const fpga_properties *filter, uint32_t num_filter, + fpga_token *token, uint64_t *j); +} + +#include +#include +#include +#include "gtest/gtest.h" +#include "ase.h" + +// ASE ID +#define ASE_TOKEN_MAGIC 0x46504741544f4b40 + +static const fpga_guid ASE_GUID = { + 0xd8, 0x42, 0x4d, 0xc4, 0xa4, 0xa3, 0xc4, 0x13, 0xf8,0x9e, + 0x43, 0x36, 0x83, 0xf9, 0x04, 0x0b +}; + +static const fpga_guid FPGA_FME_GUID = { + 0xbf, 0xaf, 0x2a, 0xe9, 0x4a, 0x52, 0x46, 0xe3, 0x82, 0xfe, + 0x38, 0xf0, 0xf9, 0xe1, 0x77, 0x64 +}; + +inline void token_for_fme(struct _fpga_token* tok_) +{ + std::copy(&FPGA_FME_GUID[0], &FPGA_FME_GUID[16], tok_->accelerator_id); + tok_->magic = ASE_TOKEN_MAGIC; + tok_->ase_objtype = FPGA_DEVICE; +} + +inline void token_for_afu0(struct _fpga_token* tok_) +{ + std::copy(&ASE_GUID[0], &ASE_GUID[16], tok_->accelerator_id); + tok_->magic = ASE_TOKEN_MAGIC; + tok_->ase_objtype = FPGA_ACCELERATOR; +} + +fpga_guid known_guid = {0xc5, 0x14, 0x92, 0x82, 0xe3, 0x4f, 0x11, 0xe6, + 0x8e, 0x3a, 0x13, 0xcc, 0x9d, 0x38, 0xca, 0x28}; + +class enum_c_ase_p : public testing::Test { + protected: + enum_c_ase_p() : tok(nullptr) {} + + virtual void SetUp() override { + token_for_afu0(&tok_); + tok = &tok_; + + filter_ = nullptr; + ASSERT_EQ(ase_fpgaGetProperties(nullptr, &filter_), FPGA_OK); + } + + virtual void TearDown() override { + if (filter_ != nullptr) { + EXPECT_EQ(fpgaDestroyProperties(&filter_), FPGA_OK); + } + } + + fpga_properties filter_; + struct _fpga_token tok_; + fpga_token tok; +}; + +/** + * @test nullfilter + * + * @brief When the fpga_properties *parameter to fpgaEnumerate is nullptr + * and the number of filter is bigger than zero, the + * function returns FPGA_INVALID_PARAM. + */ +TEST_F(enum_c_ase_p, nullfilter) { + uint32_t matches = 0; + EXPECT_EQ(ase_fpgaEnumerate(nullptr, 1, &tok, 1, &matches), + FPGA_INVALID_PARAM); +} + +/** + * @test nullmatches + * + * @brief When the uint32_t *num_matches parameter to fpgaEnumerate is nullptr, the + * function returns FPGA_INVALID_PARAM. + * If the fpga_properties *filters parameter is not null, but the num_filters + * is zero, the function returns FPGA_INVALID_PARAM. + */ +TEST_F(enum_c_ase_p, nullmatches) { + uint32_t matches = 0; + EXPECT_EQ(ase_fpgaEnumerate(&filter_, 1, &tok, 1, NULL), + FPGA_INVALID_PARAM); + EXPECT_EQ( + ase_fpgaEnumerate(&filter_, 0, &tok, 1, &matches), + FPGA_INVALID_PARAM); +} + +/** + * @test nulltokens + * + * @brief When the fpga_token* parameter to fpgaEnumerate is nullptr with nonzero + * number of tokens, the function returns FPGA_INVALID_PARAM. + * + */ +TEST_F(enum_c_ase_p, nulltokens) { + uint32_t matches = 0; + EXPECT_EQ(ase_fpgaEnumerate(&filter_, 0, NULL, 1, &matches), + FPGA_INVALID_PARAM); +} + +/** + * @test api_guid_to_fpga + * + * @brief Test internal function api_guid_to_fpga in enum.c, + * api_guid_to_fpga returns the expected guid. + * + */ +TEST(enum_c_ase, api_guid_to_fpga) { + fpga_guid guid; + uint8_t *guid_; + uint64_t guidh = 0x4041424344454647; + uint64_t guidl = 0x3031323334353637;; + api_guid_to_fpga(guidh, guidl, guid); + guid_ = (uint8_t*)guid; + for (int i=0; i<8; i++) + EXPECT_EQ(guid_[i], (0x40 + i)); + for (int i=0; i<8; i++) + EXPECT_EQ(guid_[i+8], (0x30 + i)); +} + +/** + * @test matches_filters_1 + * + * @brief Test internal function matches_filters(), the function returns + * true if the property field of FPGA_PROPERTY_FUNCTION is valid. + */ +TEST_F(enum_c_ase_p, matches_filters_1) { + uint64_t j = 0; + struct _fpga_properties* _prop = (struct _fpga_properties*)filter_; + + // Set the property valid field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_FUNCTION); + _prop->function = 0xAE; + + EXPECT_EQ(matches_filters(&filter_, 1, &tok, &j), true); +} + +/** + * @test matches_filters_2 + * + * @brief Test internal function matches_filters(), the function returns + * true if the property field of FPGA_PROPERTY_DEVICE is valid. + */ +TEST_F(enum_c_ase_p, matches_filters_2) { + uint64_t j = 0; + struct _fpga_properties* _prop = (struct _fpga_properties*)filter_; + + SET_FIELD_VALID(_prop, FPGA_PROPERTY_DEVICE); + _prop->device = 0xAE; + + EXPECT_EQ(matches_filters(&filter_, 1, &tok, &j), true); +} + +/** + * @test matches_filters_3 + * + * @brief Test internal function matches_filters(), the function returns + * true if the property field valid_fields is zero. + */ +TEST_F(enum_c_ase_p, matches_filters_3) { + uint64_t j = 0; + struct _fpga_properties* _prop = (struct _fpga_properties*)filter_; + + _prop->valid_fields = 0; + EXPECT_EQ(matches_filters(&filter_, 1, &tok, &j), true); +} + +/** + * @test matches_filters_4 + * + * @brief Test internal function matches_filters(), the function returns + * false if the property field of FPGA_PROPERTY_PARENT is set but the + * _prop->parent is NULL. + */ +TEST_F(enum_c_ase_p, matches_filters_4) { + uint64_t j = 0; + struct _fpga_properties* _prop = (struct _fpga_properties*)filter_; + + SET_FIELD_VALID(_prop, FPGA_PROPERTY_PARENT); + _prop->parent = NULL; + + EXPECT_EQ(matches_filters(&filter_, 1, &tok, &j), false); +} + +/** + * @test matches_filters_5 + * + * @brief Test internal function matches_filters(), the function returns + * false the property field of FPGA_PROPERTY_PARENT is set but the + * but the _prop->parent is not a valid token. + */ +TEST_F(enum_c_ase_p, matches_filters_5) { + uint64_t j = 0; + struct _fpga_token tok1_; + fpga_token tok_dev_; + tok_dev_ = &tok1_; + token_for_afu0(&tok1_); + + struct _fpga_properties* _prop = (struct _fpga_properties*)filter_; + + SET_FIELD_VALID(_prop, FPGA_PROPERTY_PARENT); + _prop->parent = tok_dev_; + + EXPECT_EQ(matches_filters(&filter_, 1, &tok, &j), false); +} + +/** + * @test matches_filters_6 + * + * @brief Test internal function matches_filters(), the function returns + * false if the property's object ID is not valid. + */ +TEST_F(enum_c_ase_p, matches_filters_6) { + uint64_t j = 0; + struct _fpga_token tok1_; + fpga_token tok_dev_; + + tok_dev_ = &tok1_; + token_for_fme(&tok1_); + + struct _fpga_properties* _prop = (struct _fpga_properties*)filter_; + + SET_FIELD_VALID(_prop, FPGA_PROPERTY_PARENT); + _prop->parent = tok_dev_; + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJECTID); + _prop->object_id = ASE_OBJID + 1; + + EXPECT_EQ(matches_filters(&filter_, 1, &tok, &j), false); +} + +/** + * @test matches_filters_7 + * + * @brief Test internal function matches_filters(), the function returns + * false if the object type is not ACCELERATOR type. + */ +TEST_F(enum_c_ase_p, matches_filters_7) { + uint64_t j = 0; + struct _fpga_token tok1_; + fpga_token tok_dev_; + + tok_dev_ = &tok1_; + token_for_fme(&tok1_); + + struct _fpga_properties* _prop = (struct _fpga_properties*)filter_; + + SET_FIELD_VALID(_prop, FPGA_PROPERTY_PARENT); + _prop->parent = tok_dev_; + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJECTID); + _prop->object_id = ASE_OBJID; + + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_DEVICE; + + EXPECT_EQ(matches_filters(&filter_, 1, &tok, &j), false); +} + +/** + * @test matches_filters_8 + * + * @brief Test internal function matches_filters(), the function returns + * false if the guid doesn't match. + */ +TEST_F(enum_c_ase_p, matches_filters_8) { + uint64_t j = 0; + struct _fpga_token tok1_; + fpga_token tok_dev_; + + tok_dev_ = &tok1_; + token_for_fme(&tok1_); + + struct _fpga_properties* _prop = (struct _fpga_properties*)filter_; + + SET_FIELD_VALID(_prop, FPGA_PROPERTY_PARENT); + _prop->parent = tok_dev_; + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJECTID); + _prop->object_id = ASE_OBJID; + + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_GUID); + _prop->objtype = FPGA_ACCELERATOR; + + // set the guid to a known value + std::copy(&known_guid[0], &known_guid[16], _prop->guid); + + EXPECT_EQ(matches_filters(&filter_, 1, &tok, &j), false); +} + +/** + * @test matches_filters_9 + * + * @brief Test internal function matches_filters(), the function returns + * true if the guid id matches. + */ +TEST_F(enum_c_ase_p, matches_filters_9) { + uint64_t j = 0; + struct _fpga_token tok1_; + fpga_token tok_dev_; + + token_for_fme(&tok1_); + tok_dev_ = &tok1_; + + struct _fpga_properties* _prop = (struct _fpga_properties*)filter_; + + SET_FIELD_VALID(_prop, FPGA_PROPERTY_PARENT); + _prop->parent = tok_dev_; + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJECTID); + _prop->object_id = ASE_OBJID; + + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_GUID); + _prop->objtype = FPGA_ACCELERATOR; + + std::copy(&ASE_GUID[0], &ASE_GUID[16], _prop->guid); + + EXPECT_EQ(matches_filters(&filter_, 1, &tok, &j), true); +} + +/** + * @test matches_filters_10 + * + * @brief Test internal function matches_filters(), the function returns + * true if the filter is nullptr. + */ +TEST_F(enum_c_ase_p, matches_filters_10) { + uint64_t j = 0; + fpga_properties * filter = nullptr; + + EXPECT_EQ(matches_filters(filter, 1, &tok, &j), true); +} + +/** + * @test matches_filters_11 + * + * @brief Test internal function matches_filters(), the function returns + * true if the num_filter is zero. + */ +TEST_F(enum_c_ase_p, matches_filters_11) { + uint64_t j = 0; + EXPECT_EQ(matches_filters(&filter_, 0, &tok, &j), true); +} + +/** + * @test destroy_token_1 + * + * @brief Test fpgaDestroyToken, if the token is nullptr + * the function returns FPGA_INVALID_PARAM. + */ +TEST(enum_c_ase, destroy_token_1) { + EXPECT_EQ(ase_fpgaDestroyToken(nullptr), FPGA_INVALID_PARAM); + fpga_token token = nullptr; + EXPECT_EQ(ase_fpgaDestroyToken(&token), FPGA_INVALID_PARAM); +} diff --git a/ase/tests/test_mmio_c_ase.cpp b/ase/tests/test_mmio_c_ase.cpp new file mode 100644 index 0000000..c232a60 --- /dev/null +++ b/ase/tests/test_mmio_c_ase.cpp @@ -0,0 +1,219 @@ +// Copyright(c) 2019, Intel Corporation +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Intel Corporation nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +extern "C" { +#include +#include +#include +#include "types_int.h" + +} + +#include "gtest/gtest.h" +#include "ase.h" + +#define MMIO_AFU_OFFSET (256*1024) +#define FPGA_HANDLE_MAGIC 0x46504741484e444c +extern uint64_t *mmio_afu_vbase; + +/** + * @test nullhandle + * + * @brief When the fpga_handle parameter is nullptr, the + * function returns FPGA_INVALID_PARAM. + */ +TEST(mmio_c_ase, nullhandle) { + uint32_t value = 0; + uint64_t value2 = 0; + uint64_t value512[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint64_t *addr = nullptr; + EXPECT_EQ(ase_fpgaWriteMMIO32(nullptr, 1, 0x4, 0xff), + FPGA_INVALID_PARAM); + + EXPECT_EQ(ase_fpgaReadMMIO32(nullptr, 1, 0x4, &value), + FPGA_INVALID_PARAM); + + EXPECT_EQ(ase_fpgaWriteMMIO64(nullptr, 1, 0x4, 0xff), + FPGA_INVALID_PARAM); + + EXPECT_EQ(ase_fpgaReadMMIO64(nullptr, 1, 0x4, &value2), + FPGA_INVALID_PARAM); + + EXPECT_EQ(ase_fpgaWriteMMIO512(nullptr, 1, 0x40, value512), + FPGA_INVALID_PARAM); + + EXPECT_EQ(ase_fpgaMapMMIO(nullptr, 1, &addr), + FPGA_INVALID_PARAM); + + EXPECT_EQ(ase_fpgaUnmapMMIO(nullptr, 1), + FPGA_INVALID_PARAM); + + EXPECT_EQ(ase_fpgaReset(nullptr), + FPGA_INVALID_PARAM); +} + +/** + * @test mmio_afu_vbase_null + * + * @brief If mmio_afu_vbase is nullptr, this test returns FFPGA_NOT_FOUND. + */ +TEST(mmio_c_ase, mmio_afu_vbase_null) { + uint32_t value = 0; + uint64_t value2 = 0; + uint64_t value512[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + + struct _fpga_handle handle_; + fpga_handle accel_ = &handle_; + + handle_.fpgaMMIO_is_mapped = 0; + mmio_afu_vbase = nullptr; + EXPECT_EQ(ase_fpgaWriteMMIO32(accel_, 1, 0x4, 0xff), + FPGA_NOT_FOUND); + EXPECT_EQ(ase_fpgaReadMMIO32(accel_, 1, 0x4, &value), + FPGA_NOT_FOUND); + EXPECT_EQ(ase_fpgaWriteMMIO64(accel_, 1, 0x4, 0xff), + FPGA_NOT_FOUND); + EXPECT_EQ(ase_fpgaReadMMIO64(accel_, 1, 0x4, &value2), + FPGA_NOT_FOUND); + EXPECT_EQ(ase_fpgaWriteMMIO512(accel_, 1, 0x40, value512), + FPGA_NOT_FOUND); +} + +/** + * @test offset_misaligned + * + * @brief If the offset to MMIO functions is not 4 or 8 bytes aligned + * it will return FPGA_INVALID_PARAM + */ +TEST(mmio_c_ase, offset_misaligned) { + uint32_t value = 0; + uint64_t value2 = 0; + uint64_t value512[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint64_t mmio_data[16]; + + struct _fpga_handle handle_; + fpga_handle accel_ = &handle_; + + handle_.fpgaMMIO_is_mapped = 0; + mmio_afu_vbase = mmio_data; + EXPECT_EQ(ase_fpgaWriteMMIO32(accel_, 1, 0x3, 0xff), + FPGA_INVALID_PARAM); + EXPECT_EQ(ase_fpgaReadMMIO32(accel_, 1, 0x3, &value), + FPGA_INVALID_PARAM); + EXPECT_EQ(ase_fpgaWriteMMIO64(accel_, 1, 0x3, 0xff), + FPGA_INVALID_PARAM); + EXPECT_EQ(ase_fpgaReadMMIO64(accel_, 1, 0x3, &value2), + FPGA_INVALID_PARAM); + EXPECT_EQ(ase_fpgaWriteMMIO512(accel_, 1, 0x3, value512), + FPGA_INVALID_PARAM); +} + +/** + * @test offset_overflow + * + * @brief If the offset to MMIO functions is bigger than the MMIO_AFU_OFFSET + * it will return FPGA_INVALID_PARAM + */ +TEST(mmio_c_ase, offset_overflow) { + uint32_t value = 0; + uint64_t value2 = 0; + uint64_t value512[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint64_t mmio_data[16]; + + struct _fpga_handle handle_; + fpga_handle accel_ = &handle_; + + handle_.fpgaMMIO_is_mapped = 0; + mmio_afu_vbase = mmio_data; + EXPECT_EQ(ase_fpgaWriteMMIO32(accel_, 1, MMIO_AFU_OFFSET + 4, 0xff), + FPGA_INVALID_PARAM); + EXPECT_EQ(ase_fpgaReadMMIO32(accel_, 1, MMIO_AFU_OFFSET + 4, &value), + FPGA_INVALID_PARAM); + EXPECT_EQ(ase_fpgaWriteMMIO64(accel_, 1, MMIO_AFU_OFFSET + 4, 0xff), + FPGA_INVALID_PARAM); + EXPECT_EQ(ase_fpgaReadMMIO64(accel_, 1, MMIO_AFU_OFFSET + 4, &value2), + FPGA_INVALID_PARAM); + EXPECT_EQ(ase_fpgaWriteMMIO512(accel_, 1, MMIO_AFU_OFFSET + 64, value512), + FPGA_INVALID_PARAM); +} + +/** + * @test mmio_nullptr + * + * @brief If mmio_ptr parameter to fpgaMapMMIO() is nullptr, this test + * returns FFPGA_OK; if a non-null pointer is passed, fpgaMapMMIO + * returns FPGA_NOT_SUPPORTED. + */ +TEST(mmio_c_ase, mmio_nullptr) { + uint64_t value = 0; + uint64_t *addr = &value; + + struct _fpga_handle handle_; + fpga_handle accel_ = &handle_; + + handle_.fpgaMMIO_is_mapped = 0; + EXPECT_EQ(ase_fpgaMapMMIO(accel_, 1, &addr), FPGA_NOT_SUPPORTED); + EXPECT_EQ(ase_fpgaMapMMIO(accel_, 1, nullptr), FPGA_OK); +} + +/** + * @test invalid_handle + * + * @brief If fpga_hanle's magic is invalid, fpgaUnmapMMIO returns FPGA_INVALID_PARAM + * If fpga_hanle's magic is valid, fpgaUnmapMMIO returns FPGA_OK. + * If the fpgaMMIO_is_mapped is false, fpgaUnmapMMIO returns FPGA_INVALID_PARAM. + */ +TEST(mmio_c_ase, invalid_handle) { + struct _fpga_handle handle_; + handle_.magic = 0xFFFFFFFF; + fpga_handle accel_ = &handle_; + + EXPECT_EQ(ase_fpgaUnmapMMIO(accel_, 1), FPGA_INVALID_PARAM); + + handle_.magic = FPGA_HANDLE_MAGIC; + handle_.fpgaMMIO_is_mapped = true; + EXPECT_EQ(ase_fpgaUnmapMMIO(accel_, 1), FPGA_OK); + + handle_.fpgaMMIO_is_mapped = false; + EXPECT_EQ(ase_fpgaUnmapMMIO(accel_, 1), FPGA_INVALID_PARAM); +} + +/** + * @test reset + * + * @brief If fpga_hanle is nullptr, fpgaReset returns FPGA_INVALID_PARAM + * If fpga_hanle's magic is invalid, fpgaReset returns FPGA_INVALID_PARAM. + */ +TEST(mmio_c_ase, reset) { + struct _fpga_handle handle_; + handle_.magic = 0xFFFFFFFF; + fpga_handle accel_ = &handle_; + + EXPECT_EQ(ase_fpgaReset(nullptr), FPGA_INVALID_PARAM); + + EXPECT_EQ(ase_fpgaReset(accel_), FPGA_INVALID_PARAM); +} + diff --git a/ase/tests/test_open_c_ase.cpp b/ase/tests/test_open_c_ase.cpp new file mode 100644 index 0000000..6317ca6 --- /dev/null +++ b/ase/tests/test_open_c_ase.cpp @@ -0,0 +1,168 @@ +// Copyright(c) 2019, Intel Corporation +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Intel Corporation nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +extern "C" { +#include +#include +#include +#include "types_int.h" +fpga_result ase_fpgaOpen(fpga_token token, fpga_handle *handle, int flags); +fpga_result ase_fpgaClose(fpga_handle handle); +} + +#include +#include +#include +#include +#include +#include +#include "gtest/gtest.h" +#include "test_system.h" + +using namespace opae::testing; + +// ASE ID +#define ASE_TOKEN_MAGIC 0x46504741544f4b40 +static const fpga_guid ASE_GUID = { + 0xd8, 0x42, 0x4d, 0xc4, 0xa4, 0xa3, 0xc4, 0x13, 0xf8,0x9e, + 0x43, 0x36, 0x83, 0xf9, 0x04, 0x0b +}; + +inline void token_for_afu0(struct _fpga_token* tok_) +{ + memcpy(tok_->accelerator_id,ASE_GUID, sizeof(fpga_guid)); + tok_->magic = ASE_TOKEN_MAGIC; + tok_->ase_objtype=FPGA_ACCELERATOR; +} + +class open_c_ase_p : public testing::Test { + protected: + open_c_ase_p() : tok(nullptr) {} + + virtual void SetUp() override { + system_ = test_system::instance(); + system_->initialize(); + + tok = &tok_; + token_for_afu0(&tok_); + accel_ = nullptr; + } + + virtual void TearDown() override { + if (accel_) { + EXPECT_EQ(ase_fpgaClose(accel_), FPGA_OK); + accel_ = nullptr; + } + system_->finalize(); + } + + struct _fpga_token tok_; + fpga_token tok; + fpga_handle accel_; + test_system *system_; +}; + +/** + * @test ase_open_01 + * + * @brief When the fpga_handle * parameter to fpgaOpen is nullptr, the + * function returns FPGA_INVALID_PARAM. + */ +TEST_F(open_c_ase_p, ase_open_01) { + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaOpen(tok, nullptr, 0)); +} + +/** + * @test ase_open_02 + * + * @brief When the fpga_token parameter to fpgaOpen is nullptr, the + * function returns FPGA_INVALID_PARAM. + */ +TEST_F(open_c_ase_p, ase_open_02) { + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaOpen(nullptr, &accel_, 0)); +} + +/** + * @test ase_open_03 + * + * @brief When the flags parameter to fpgaOpen is invalid, the + * function returns FPGA_INVALID_PARAM. + * + */ +TEST_F(open_c_ase_p, ase_open_03) { + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaOpen(tok, &accel_, 42)); +} + +/** + * @test ase_open_04 + * + * @brief When the token magic is invalid, + * fpgaOpen returns FPGA_INVALID_PARAM. + * + */ +TEST_F(open_c_ase_p, ase_open_04) { + struct _fpga_token *token_= (struct _fpga_token *)tok; + token_->magic = 0xFFFFFFFF; + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaOpen(tok, &accel_, 42)); +} + +/** +* @test ase_open_05 +* @brief When the fpga_handle is nullptr, +* fpgaOpen returns FPGA_INVALID_PARAM +* +*/ +TEST(sim_sw_ase, ase_open_05) { + struct _fpga_token _token; + fpga_token token = (fpga_token)&_token; + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaOpen(token, nullptr, 0)); +} + +/** + * @test mallocfails + * + * @brief When the malloc function called by fpgaOpen() failed, the function returns + * FPGA_INVALID_PARAM. + */ +TEST_F(open_c_ase_p, mallocfails) { + // Invalidate the allocation of the wrapped handle. + system_->invalidate_malloc(0, "ase_malloc"); + ASSERT_EQ(ase_fpgaOpen(tok, &accel_, 0), FPGA_NO_MEMORY); + EXPECT_EQ(accel_, nullptr); +} + +/** + * @test close_nullhandle + * + * @brief When the nullptr parameter is passed to fpgaClose(), the function returns + * FPGA_INVALID_PARAM. + */ +TEST(open_c_ase, close_nullhandle) { + EXPECT_EQ(ase_fpgaClose(nullptr), FPGA_INVALID_PARAM); +} + + diff --git a/ase/tests/test_props_c_ase.cpp b/ase/tests/test_props_c_ase.cpp new file mode 100644 index 0000000..046d270 --- /dev/null +++ b/ase/tests/test_props_c_ase.cpp @@ -0,0 +1,3362 @@ +// Copyright(c) 2017-2019, Intel Corporation +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Intel Corporation nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include + +#include +#include +#include "types_int.h" +#include +#include "props.h" + +#include "gtest/gtest.h" +#include "test_system.h" + +using namespace opae::testing; + +// ASE ID +#define ASE_TOKEN_MAGIC 0x46504741544f4b40 + +static const fpga_guid FPGA_FME_GUID = { + 0xbf, 0xaf, 0x2a, 0xe9, 0x4a, 0x52, 0x46, 0xe3, 0x82, 0xfe, + 0x38, 0xf0, 0xf9, 0xe1, 0x77, 0x64 +}; +static const fpga_guid ASE_GUID = { + 0xd8, 0x42, 0x4d, 0xc4, 0xa4, 0xa3, 0xc4, 0x13, 0xf8,0x9e, + 0x43, 0x36, 0x83, 0xf9, 0x04, 0x0b +}; +fpga_guid known_guid = {0xc5, 0x14, 0x92, 0x82, 0xe3, 0x4f, 0x11, 0xe6, + 0x8e, 0x3a, 0x13, 0xcc, 0x9d, 0x38, 0xca, 0x28}; + +inline void token_for_fme(struct _fpga_token* tok_) +{ + memcpy(tok_->accelerator_id,FPGA_FME_GUID, sizeof(fpga_guid)); + tok_->magic = ASE_TOKEN_MAGIC; + tok_->ase_objtype=FPGA_DEVICE; +} + +inline void token_for_afu0(struct _fpga_token* tok_) +{ + memcpy(tok_->accelerator_id,ASE_GUID, sizeof(fpga_guid)); + tok_->magic = ASE_TOKEN_MAGIC; + tok_->ase_objtype=FPGA_ACCELERATOR; +} + +class properties_c_ase_p : public testing::Test{ + protected: + properties_c_ase_p() + : tok_dev_(nullptr), + tok_accel_(nullptr) {} + + virtual void SetUp() override { + system_ = test_system::instance(); + system_->initialize(); + + tok_accel_ = &tok_; + token_for_afu0(&tok_); + tok_dev_ = &tok1_; + token_for_fme(&tok1_); + filter_ = nullptr; + accel_ = nullptr; + ASSERT_EQ(fpgaGetProperties(nullptr, &filter_), FPGA_OK); + ASSERT_EQ(fpgaPropertiesSetObjectType(filter_, FPGA_ACCELERATOR), FPGA_OK); + } + + virtual void TearDown() override { + EXPECT_EQ(fpgaDestroyProperties(&filter_), FPGA_OK); + system_->finalize(); + } + + struct _fpga_token tok_, tok1_; + fpga_token tok_dev_; + fpga_token tok_accel_; + fpga_properties filter_; + fpga_handle accel_; + test_system* system_; +}; + +/** + * @test property_01 + * @brief Tests: fpgaClearProperties + * @details Given a non-null fpga_properties* object
+ * Then the return value is FPGA_OK
+ * And the field in the token object is set to the known value
+ * */ +TEST_F(properties_c_ase_p, property_01) { + fpga_properties prop = nullptr; + + ASSERT_EQ(fpgaGetProperties(NULL, &prop), FPGA_OK); + EXPECT_EQ(fpgaPropertiesSetObjectType(prop, FPGA_DEVICE), FPGA_OK); + EXPECT_EQ(fpgaClearProperties(prop), FPGA_OK); + EXPECT_EQ(fpgaDestroyProperties(&prop), FPGA_OK); +} + +/** + * @test get_parent02 + * @brief Tests: fpgaPropertiesGetParent + * @details Given a non-null fpga_properties* object
+ * And it does NOT have the parent field set
+ * When I call fpgaPropertiesGetParent with a pointer to a token + * object
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_parent02) { + fpga_properties prop = nullptr; + + ASSERT_EQ(fpgaGetProperties(NULL, &prop), FPGA_OK); + + struct _fpga_properties* prop_ = (struct _fpga_properties*)prop; + fpga_token tok = nullptr; + + // make sure the FPGA_PROPERTY_PARENT bit is zero + EXPECT_EQ((prop_->valid_fields >> FPGA_PROPERTY_PARENT) & 1, 0); + + EXPECT_EQ(fpgaPropertiesGetParent(prop_, &tok), FPGA_NOT_FOUND); + EXPECT_EQ(tok, nullptr); + + EXPECT_EQ(fpgaDestroyProperties(&prop), FPGA_OK); +} + +/** + * @test set_parent01 + * @brief Tests: fpgaPropertiesSetParent + * @details Given a non-null fpga_properties* object
+ * And a fpga_token* object with a known value
+ * When I call fpgaPropertiesSetParent with the property and the + * token
+ * Then the parent object in the properties object is the token
+ */ +TEST_F(properties_c_ase_p, set_parent01) { + fpga_properties prop = nullptr; + fpga_token parent = nullptr; + + ASSERT_EQ(fpgaGetProperties(NULL, &prop), FPGA_OK); + EXPECT_EQ(fpgaPropertiesSetObjectType(prop, FPGA_DEVICE), FPGA_OK); + EXPECT_EQ(fpgaClearProperties(prop), FPGA_OK); + + // now get the parent token from the prop structure + EXPECT_EQ(fpgaPropertiesSetParent(prop, tok_dev_), FPGA_OK); + // now get the parent token from the prop structure + EXPECT_EQ(fpgaPropertiesGetParent(prop, &parent), FPGA_OK); + // GetParent clones the token so compare object_id of the two + fpga_properties p1 = nullptr, p2 = nullptr; + ASSERT_EQ(fpgaGetProperties(tok_dev_, &p1), FPGA_OK); + ASSERT_EQ(fpgaGetProperties(parent, &p2), FPGA_OK); + EXPECT_EQ(((_fpga_properties*)p1)->object_id, + ((_fpga_properties*)p2)->object_id); + + EXPECT_EQ(fpgaDestroyProperties(&p1), FPGA_OK); + EXPECT_EQ(fpgaDestroyProperties(&p2), FPGA_OK); + EXPECT_EQ(fpgaDestroyProperties(&prop), FPGA_OK); + EXPECT_EQ(fpgaDestroyToken(&parent), FPGA_OK); +} + +/** + * @test set_parent02 + * @brief Tests: fpgaPropertiesSetParent + * @details When setting the parent token in a properties object
+ * that has a wrapped parent token resulting from fpgaGetProperties[FromParent]
+ * or fpgaUpdateProperties,
+ * fpgaPropertiesSetParent will free the token wrapper.
+ */ +TEST_F(properties_c_ase_p, set_parent02) { + fpga_properties prop = nullptr; + // The accelerator token will have a parent token set. + ASSERT_EQ(fpgaGetProperties(tok_accel_, &prop), FPGA_OK); + // When this parent is set explicitly, the parent token wrapper is freed. + EXPECT_EQ(fpgaPropertiesSetParent(prop, tok_dev_), FPGA_OK); + EXPECT_EQ(fpgaDestroyProperties(&prop), FPGA_OK); +} + +/** + * @test from_handle01 + * @brief Tests: fpgaGetPropertiesFromHandle + * @details When the input handle is NULL
+ * fpgaGetPropertiesFromHandle returns FPGA_INVALID_PARAM.
+ */ +TEST_F(properties_c_ase_p, from_handle01) { + fpga_properties prop = nullptr; + EXPECT_EQ(fpgaGetPropertiesFromHandle(accel_, &prop), FPGA_INVALID_PARAM); +} + +/** + * @test from_handle02 + * @brief Tests: fpgaGetPropertiesFromHandle + * @details When the input handle is valid
+ * fpgaGetPropertiesFromHandle returns FPGA_OK.
+ */ +TEST_F(properties_c_ase_p, from_handle02) { + fpga_properties prop = nullptr; + struct _fpga_handle handle; + handle.token = tok_accel_; + accel_ = &handle; + EXPECT_EQ(fpgaGetPropertiesFromHandle(accel_, &prop), FPGA_OK); + EXPECT_EQ(fpgaDestroyProperties(&prop), FPGA_OK); +} + +/** + * @test from_token03 + * @brief Tests: fpgaGetProperties + * @details When the input token is valid
+ * and the call is successful,
+ * fpgaGetProperties returns FPGA_OK.
+ */ +TEST_F(properties_c_ase_p, from_token03) { + fpga_properties prop = nullptr; + EXPECT_EQ(fpgaGetProperties(tok_accel_, &prop), FPGA_OK); + EXPECT_EQ(fpgaDestroyProperties(&prop), FPGA_OK); +} + +/** + * @test update01 + * @brief Tests: fpgaUpdateProperties + * @details When the input properties object has a parent token set,
+ * fpgaUpdateProperties re-uses the wrapper object.
+ * If a subsequent call to fpgaUpdateProperties results in a properites
+ * object without a parent token,
+ * then the wrapper object is freed.
+ */ +TEST_F(properties_c_ase_p, update01) { + fpga_properties props = nullptr; + ASSERT_EQ(fpgaGetProperties(NULL, &props), FPGA_OK); + EXPECT_EQ(fpgaUpdateProperties(tok_accel_, props), FPGA_OK); + // The output properties for the accelerator will have a parent token. + + // Updating the properties again (accelerator) + EXPECT_EQ(fpgaUpdateProperties(tok_accel_, props), FPGA_OK); + + // Updating the properties for a device token will not result in + // a parent token. + EXPECT_EQ(fpgaUpdateProperties(tok_dev_, props), FPGA_OK); + + EXPECT_EQ(fpgaDestroyProperties(&props), FPGA_OK); +} + +/** + * @test update02 + * @brief Tests: fpgaUpdateProperties + * @details When the input properties object has a parent token set,
+ * + * If a subsequent call to fpgaUpdateProperties results in a properites
+ * object without a parent token,
+ * then the wrapper object is freed.
+ */ +TEST_F(properties_c_ase_p, update02) { + fpga_properties props = nullptr; + ASSERT_EQ(fpgaGetProperties(NULL, &props), FPGA_OK); + EXPECT_EQ(fpgaUpdateProperties(NULL, props), FPGA_INVALID_PARAM); + + struct _fpga_properties *prop_ = (struct _fpga_properties *)props; + prop_->magic = 0xFFFFFFFF; + EXPECT_EQ(fpgaUpdateProperties(tok_accel_, props), FPGA_INVALID_PARAM); + + struct _fpga_token *token_ = (struct _fpga_token *)tok_accel_; + token_->magic = 0xFFFFFFFF; + EXPECT_EQ(fpgaUpdateProperties(tok_accel_, props), FPGA_INVALID_PARAM); + + EXPECT_EQ(fpgaDestroyProperties(&props), FPGA_OK); +} + +/** + * @test get_parent_null_props + * @brief Tests: fpgaPropertiesGetParent + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetParent with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ **/ +TEST(properties, get_parent_null_props) { + fpga_properties prop = NULL; + + fpga_token token; + fpga_result result = fpgaPropertiesGetParent(prop, &token); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_parent_null_token + * @brief Tests: fpgaPropertiesSetParent + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetParent with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_parent_null_token) { + fpga_properties prop = NULL; + + // Call the API to set the token on the property + fpga_token token = nullptr; + fpga_result result = fpgaPropertiesSetParent(prop, &token); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test create + * @brief Tests: fpgaGetProperties + * @details Given a null fpga_properties object
+ * When I call fpgaGetProperties with the object
+ * Then the return value is FPGA_OK
+ * And the fpga_properties object is non-null
+ */ +TEST_F(properties_c_ase_p, create) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_EQ(NULL, ((struct _fpga_properties*)prop)->parent); + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(result, FPGA_OK); +} + +/** + * @test destroy01 + * @brief Tests: fpgaDestroyProperties + * @details Given a non-null fpga_properties object
+ * When I call fpgaDestroyProperties with that object
+ * Then the result is FPGA_OK
+ * And that object is null
+ */ +TEST_F(properties_c_ase_p, destroy01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(FPGA_OK, result); + ASSERT_EQ(NULL, prop); +} + +/** + * @test destroy02 + * @brief Tests: fpgaDestroyProperties + * @details Given a null fpga_properties object
+ * When I call fpgaDestroyProperties with that object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, destroy02) { + fpga_properties prop = NULL; + + fpga_result result = fpgaDestroyProperties(&prop); + ASSERT_EQ(FPGA_INVALID_PARAM, result); + ASSERT_EQ(NULL, prop); +} + +/** + * @test clear01 + * @brief Tests: fpgaClearProperties + * @details Given a non-null fpga_properties object
+ * When I call fpgaClearProperties with the object
+ * Then the result is FPGA_OK
+ * And the properties object is cleared
+ */ +TEST_F(properties_c_ase_p, clear01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the bus field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_BUS); + _prop->bus = 0xAB; + + result = fpgaClearProperties(prop); + EXPECT_EQ(FPGA_OK, result); + EXPECT_EQ(_prop, prop); + EXPECT_EQ(0, _prop->valid_fields); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(FPGA_OK, result); + ASSERT_EQ(NULL, prop); +} + +/** + * @test clear02 + * @brief Tests: fpgaClearProperties + * @details Given a null fpga_properties object
+ * When I call fpgaClearProperties with the object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, clear02) { + fpga_properties prop = NULL; + + fpga_result result = fpgaClearProperties(prop); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test get_object_type01 + * @brief Tests: fpgaPropertiesGetObjectType + * @details Given a non-null fpga_properties* object
+ * And it has the objtype field set
+ * And its objtype field is a known value
+ * When I call fpgaPropertiesGetObjectType with a pointer to an + * fpga_objtype
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_object_type01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_DEVICE; + + // now get the parent token from the prop structure + fpga_objtype objtype; + result = fpgaPropertiesGetObjectType(prop, &objtype); + EXPECT_EQ(result, FPGA_OK); + // Assert it is set to what we set it to above + EXPECT_EQ(FPGA_DEVICE, objtype); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_object_type02 + * @brief Tests: fpgaPropertiesGetObjectType + * @details Given a non-null fpga_properties* object
+ * And it does NOT have the objtype field set
+ * When I call fpgaPropertiesGetObjectType with a pointer to an + * fpga_objtype
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_object_type02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // make sure the FPGA_PROPERTY_OBJTYPE bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_OBJTYPE) & 1, 0); + + fpga_objtype objtype; + result = fpgaPropertiesGetObjectType(prop, &objtype); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_object_type01 + * @brief Tests: fpgaPropertiesSetObjectType + * @details Given a non-null fpga_properties* object
+ * And a fpga_objtype object set to a known value
+ * When I call fpgaPropertiesSetObjectType with the properties + object + * and the objtype
+ * Then the objtype in the properties object is the known value
+ */ +TEST_F(properties_c_ase_p, set_object_type01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + fpga_objtype objtype = FPGA_DEVICE; + result = fpgaPropertiesSetObjectType(prop, objtype); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + EXPECT_EQ(result, FPGA_OK); + // Assert it is set to what we set it to above + EXPECT_EQ(FPGA_DEVICE, _prop->objtype); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_object_type03 + * @brief Tests: fpgaPropertiesGetObjectType + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetObjectType with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_object_type03) { + fpga_properties prop = NULL; + + fpga_objtype objtype; + fpga_result result = fpgaPropertiesGetObjectType(prop, &objtype); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_object_type02 + * @brief Tests: fpgaPropertiesSetObjectType + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetObjectType with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_object_type02) { + fpga_properties prop = NULL; + + // Call the API to set the objtype on the property + fpga_objtype objtype = FPGA_DEVICE; + fpga_result result = fpgaPropertiesSetObjectType(prop, objtype); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +// * Segment field tests *// +/** + * @test get_segment01 + * @brief Tests: fpgaPropertiesGetSegment + * @details Given a non-null fpga_properties* object
+ * And it has the bus field set
+ * And it is set to a known value
+ * When I call fpgaPropertiesGetSegment with a pointer to an + integer
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ */ +TEST_F(properties_c_ase_p, get_segment01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the segment field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_SEGMENT); + _prop->segment = 0xc001; + + // now get the segment number using the API + uint16_t segment = 0; + result = fpgaPropertiesGetSegment(prop, &segment); + EXPECT_EQ(result, FPGA_OK); + // Assert it is set to what we set it to above + // (Get the subfield manually) + EXPECT_EQ(0xc001, segment); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_segment02 + * @brief Tests: fpgaPropertiesGetSegment + * @details Given a non-null fpga_properties* object
+ * And it does NOT have the bus field set
+ * When I call fpgaPropertiesGetSegment with a pointer to an + integer
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_segment02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // make sure the FPGA_PROPERTY_SEGMENT bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_SEGMENT) & 1, 0); + + uint16_t segment; + result = fpgaPropertiesGetSegment(prop, &segment); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_segment01 + * @brief Tests: fpgaPropertiesSetSegment + * @details Given a non-null fpga_properties* object
+ * And segment variable set to a known value
+ * When I call fpgaPropertiesSetSegment with the properties object + and + * the segment variable
+ * Then the segment field in the properties object is the known + value
+ */ +TEST_F(properties_c_ase_p, set_segment01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + uint16_t segment = 0xc001; + // make sure the FPGA_PROPERTY_SEGMENT bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_SEGMENT) & 1, 0); + // Call the API to set the segment on the property + result = fpgaPropertiesSetSegment(prop, segment); + + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_SEGMENT bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_SEGMENT) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0xc001, _prop->segment); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_segment03 + * @brief Tests: fpgaPropertiesGetSegment + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetSegment with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_segment03) { + fpga_properties prop = NULL; + + uint16_t segment; + fpga_result result = fpgaPropertiesGetSegment(prop, &segment); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_segment02 + * @brief Tests: fpgaPropertiesSetSegment + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetSegment with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_segment02) { + fpga_properties prop = NULL; + + // Call the API to set the segment on the property + fpga_result result = fpgaPropertiesSetSegment(prop, 0xc001); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +// * Bus field tests *// +/** + * @test get_bus01 + * @brief Tests: fpgaPropertiesGetBus + * @details Given a non-null fpga_properties* object
+ * And it has the bus field set
+ * And it is set to a known value
+ * When I call fpgaPropertiesGetBus with a pointer to an integer
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_bus01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_BUS); + _prop->bus = 0xAE; + + // now get the bus number using the API + uint8_t bus; + result = fpgaPropertiesGetBus(prop, &bus); + EXPECT_EQ(result, FPGA_OK); + // Assert it is set to what we set it to above + // (Get the subfield manually) + EXPECT_EQ(0xAE, bus); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_bus02 + * @brief Tests: fpgaPropertiesGetBus + * @details Given a non-null fpga_properties* object
+ * And it does NOT have the bus field set
+ * When I call fpgaPropertiesGetBus with a pointer to an integer
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_bus02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // make sure the FPGA_PROPERTY_BUS bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_BUS) & 1, 0); + + uint8_t bus; + result = fpgaPropertiesGetBus(prop, &bus); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_bus01 + * @brief Tests: fpgaPropertiesSetBus + * @details Given a non-null fpga_properties* object
+ * And bus variable set to a known value
+ * When I call fpgaPropertiesSetBus with the properties object and + * the bus variable
+ * Then the bus field in the properties object is the known + value
+ */ +TEST_F(properties_c_ase_p, set_bus01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + uint8_t bus = 0xAE; + // make sure the FPGA_PROPERTY_BUS bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_BUS) & 1, 0); + // Call the API to set the bus on the property + result = fpgaPropertiesSetBus(prop, bus); + + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_BUS bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_BUS) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0xAE, _prop->bus); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_bus03 + * @brief Tests: fpgaPropertiesGetBus + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetBus with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_bus03) { + fpga_properties prop = NULL; + + uint8_t bus; + fpga_result result = fpgaPropertiesGetBus(prop, &bus); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_bus02 + * @brief Tests: fpgaPropertiesSetBus + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetBus with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_bus02) { + fpga_properties prop = NULL; + + // Call the API to set the objtype on the property + fpga_result result = fpgaPropertiesSetBus(prop, 0); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +// * Device field tests *// +/** + * @test get_device01 + * @brief Tests: fpgaPropertiesGetDevice + * @details Given a non-null fpga_properties* object
+ * And it has the device field set
+ * And it is set to a known value
+ * When I call fpgaPropertiesGetDevice with a pointer to an + * integer
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_device01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_DEVICE); + _prop->device = 0xAE; + + // now get the device number using the API + uint8_t device; + result = fpgaPropertiesGetDevice(prop, &device); + EXPECT_EQ(result, FPGA_OK); + // Assert it is set to what we set it to above + // (Get the subfield manually) + EXPECT_EQ(0xAE, device); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_device02 + * @brief Tests: fpgaPropertiesGetDevice + * @details Given a non-null fpga_properties* object
+ * And it does NOT have the device field set
+ * When I call fpgaPropertiesGetDevice with a pointer to an + * integer
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_device02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // make sure the FPGA_PROPERTY_DEVICE bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_DEVICE) & 1, 0); + + uint8_t device; + result = fpgaPropertiesGetDevice(prop, &device); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_device01 + * @brief Tests: fpgaPropertiesSetDevice + * @details Given a non-null fpga_properties* object
+ * And device variable set to a known value
+ * When I call fpgaPropertiesSetDevice with the properties object + * and the device variable
+ * Then the device field in the properties object is the known + * value
+ */ +TEST_F(properties_c_ase_p, set_device01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + uint8_t device = 0x1f; // max of 32 devices + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // make sure the FPGA_PROPERTY_DEVICE bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_DEVICE) & 1, 0); + + // Call the API to set the device on the property + result = fpgaPropertiesSetDevice(prop, device); + + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_DEVICE bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_DEVICE) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0x1f, _prop->device); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_device03 + * @brief Tests: fpgaPropertiesGetDevice + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetDevice with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_device03) { + fpga_properties prop = NULL; + + uint8_t device; + fpga_result result = fpgaPropertiesGetDevice(prop, &device); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_device02 + * @brief Tests: fpgaPropertiesSetDevice + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetDevice with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_device02) { + fpga_properties prop = NULL; + + // Call the API to set the objtype on the property + fpga_result result = fpgaPropertiesSetDevice(prop, 0); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +// * Function field tests *// +/** + * @test get_function01 + * @brief Tests: fpgaPropertiesGetFunction + * @details Given a non-null fpga_properties* object
+ * And it has the function field set
+ * And it is set to a known value
+ * When I call fpgaPropertiesGetFunction with a pointer to an + * integer
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_function01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_FUNCTION); + _prop->function = 0xAE; + + // now get the function number using the API + uint8_t function; + result = fpgaPropertiesGetFunction(prop, &function); + EXPECT_EQ(result, FPGA_OK); + // Assert it is set to what we set it to above + // (Get the subfield manually) + EXPECT_EQ(0xAE, function); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_function02 + * @brief Tests: fpgaPropertiesGetFunction + * @details Given a non-null fpga_properties* object
+ * And it does NOT have the function field set
+ * When I call fpgaPropertiesGetFunction with a pointer to an + * integer
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_function02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // make sure the FPGA_PROPERTY_FUNCTION bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_FUNCTION) & 1, 0); + + uint8_t function; + result = fpgaPropertiesGetFunction(prop, &function); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_function01 + * @brief Tests: fpgaPropertiesSetFunction + * @details Given a non-null fpga_properties* object
+ * And function variable set to a known value
+ * When I call fpgaPropertiesSetFunction with the properties object + * and the function variable
+ * Then the function field in the properties object is the known + * value
+ */ +TEST_F(properties_c_ase_p, set_function01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + uint8_t function = 7; // max of 8 functions + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // make sure the FPGA_PROPERTY_FUNCTION bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_FUNCTION) & 1, 0); + + // Call the API to set the function on the property + result = fpgaPropertiesSetFunction(prop, function); + + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_FUNCTION bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_FUNCTION) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(7, _prop->function); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_function03 + * @brief Tests: fpgaPropertiesGetFunction + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetFunction with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_function03) { + fpga_properties prop = NULL; + + uint8_t function; + fpga_result result = fpgaPropertiesGetFunction(prop, &function); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_function02 + * @brief Tests: fpgaPropertiesSetFunction + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetFunction with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_function02) { + fpga_properties prop = NULL; + + // Call the API to set the objtype on the property + fpga_result result = fpgaPropertiesSetFunction(prop, 0); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_function03 + * @brief Tests: fpgaPropertiesSetFunction + * @details When fpgaPropertiesSetFunction is called with an invalid
+ * PCIe function number,
+ * Then the result is FPGA_INVALID_PARAM.
+ */ +TEST_F(properties_c_ase_p, set_function03) { + // Call the API to set the objtype on the property + EXPECT_EQ(fpgaPropertiesSetFunction(filter_, 8), FPGA_INVALID_PARAM); +} + +// * SocketID field tests *// +/** + * @test get_socket_id01 + * @brief Tests: fpgaPropertiesGetSocketID + * @details Given a non-null fpga_properties* object
+ * And it has the socket_id field set
+ * And it is set to a known value
+ * When I call fpgaPropertiesGetSocketID with a pointer to an + * integer
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_socket_id01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_SOCKETID); + _prop->socket_id = 0xAE; + + // now get the socket_id number using the API + uint8_t socket_id; + result = fpgaPropertiesGetSocketID(prop, &socket_id); + EXPECT_EQ(result, FPGA_OK); + // Assert it is set to what we set it to above + // (Get the subfield manually) + EXPECT_EQ(0xAE, socket_id); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_socket_id02 + * @brief Tests: fpgaPropertiesGetSocketID + * @details Given a non-null fpga_properties* object
+ * And it does NOT have the socket_id field set
+ * When I call fpgaPropertiesGetSocketID with a pointer to an + * integer
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_socket_id02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // make sure the FPGA_PROPERTY_SOCKETID bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_SOCKETID) & 1, 0); + + uint8_t socket_id; + result = fpgaPropertiesGetSocketID(prop, &socket_id); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_socket_id01 + * @brief Tests: fpgaPropertiesSetSocketID + * @details Given a non-null fpga_properties* object
+ * And socket_id variable set to a known value
+ * When I call fpgaPropertiesSetSocketID with the properties object + * and the socket_id variable
+ * Then the socket_id field in the properties object is the known + * value
+ */ +TEST_F(properties_c_ase_p, set_socket_id01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + uint8_t socket_id = 0xAE; + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // make sure the FPGA_PROPERTY_SOCKETID bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_SOCKETID) & 1, 0); + + // Call the API to set the socket_id on the property + result = fpgaPropertiesSetSocketID(prop, socket_id); + + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_SOCKETID bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_SOCKETID) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0xAE, _prop->socket_id); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_socket_id03 + * @brief Tests: fpgaPropertiesGetSocketID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetSocketID with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_socket_id03) { + fpga_properties prop = NULL; + + uint8_t socket_id; + fpga_result result = fpgaPropertiesGetSocketID(prop, &socket_id); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_socket_id02 + * @brief Tests: fpgaPropertiesSetSocketID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetSocketID with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_socket_id02) { + fpga_properties prop = NULL; + + // Call the API to set the objtype on the property + fpga_result result = fpgaPropertiesSetSocketID(prop, 0); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** fpga.num_slots field tests **/ +/** + * @test get_num_slots01 + * @brief Tests: fpgaPropertiesGetNumSlots + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA + * And it has the num_slots field set to a known value
+ * When I call fpgaPropertiesGetNumSlots with a pointer to an + integer + * variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_num_slots01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_NUM_SLOTS); + + // set the object type field + _prop->objtype = FPGA_DEVICE; + + // set the num_slots to a known value + _prop->u.fpga.num_slots = 0xCAFE; + + // now get the num_slots from the prop structure + uint32_t num_slots; + result = fpgaPropertiesGetNumSlots(prop, &num_slots); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + + // assert it is set to what we set it to above + EXPECT_EQ(0xCAFE, num_slots); + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_num_slots02 + * @brief Tests: fpgaPropertiesGetNumSlots + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA + * When I call fpgaPropertiesGetNumSlots with a pointer to an + integer + * variable
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST_F(properties_c_ase_p, get_num_slots02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field to a different type + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_ACCELERATOR; + + // now get the num_slots from the prop structure + uint32_t num_slots; + result = fpgaPropertiesGetNumSlots(prop, &num_slots); + EXPECT_EQ(FPGA_INVALID_PARAM, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_num_slots03 + * @brief Tests: fpgaPropertiesGetNumSlots + * @details Given a non-null fpga_properties* object
+ * And its type is FPGA_DEVICE + * And it does NOT have the num_slots field set
+ * When I call fpgaPropertiesGetNumSlots with the property object + * and a pointer to bool variable
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_num_slots03) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + + // make sure the FPGA_PROPERTY_NUM_SLOTS bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_NUM_SLOTS) & 1, 0); + + uint32_t num_slots; + result = fpgaPropertiesGetNumSlots(prop, &num_slots); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_num_slots01 + * @brief Tests: fpgaPropertiesSetNumSlots + * @details Given a non-null fpga_properties* object
+ * And its object type is of type FPGA
+ * And an integer variable set to a known value
+ * When I call fpgaPropertiesSetNumSlots with the properties object + * and the integer variable
+ * Then the return value is FPGA_OK + * And the num_slots in the properties object is the known value
+ */ +TEST_F(properties_c_ase_p, set_num_slots01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + // set the object type field + _prop->objtype = FPGA_DEVICE; + + // make sure the FPGA_PROPERTY_NUM_SLOTS bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_NUM_SLOTS) & 1, 0); + + uint32_t num_slots = 0xCAFE; + // Call the API to set the token on the property + result = fpgaPropertiesSetNumSlots(prop, num_slots); + + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_NUM_SLOTS bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_NUM_SLOTS) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0xCAFE, _prop->u.fpga.num_slots); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_num_slots02 + * @brief Tests: fpgaPropertiesSetNumSlots + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA_DEVICE
+ * When I call fpgaPropertiesSetNumSlots with the properties object + * and a num_slots variable
+ * Then the return value is FPGA_INVALID_PARAM + */ +TEST_F(properties_c_ase_p, set_num_slots02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + + // Call the API to set the token on the property + result = fpgaPropertiesSetNumSlots(prop, 0); + + EXPECT_EQ(result, FPGA_INVALID_PARAM); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_num_slots04 + * @brief Tests: fpgaPropertiesGetNumSlots + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetNumSlots with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_num_slots04) { + fpga_properties prop = NULL; + + uint32_t num_slots; + fpga_result result = fpgaPropertiesGetNumSlots(prop, &num_slots); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_num_slots03 + * @brief Tests: fpgaPropertiesSetNumSlots + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetNumSlots with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_num_slots03) { + fpga_properties prop = NULL; + + // Call the API to set the num_slots on the property + fpga_result result = fpgaPropertiesSetNumSlots(prop, 0); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** fpga.bbs_id field tests **/ +/** + * @test get_bbs_id01 + * @brief Tests: fpgaPropertiesGetBBSID + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA + * And it has the bbs_id field set to a known value
+ * When I call fpgaPropertiesGetBBSID with a pointer to an integer + * variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_bbs_id01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_BBSID); + + // set the object type field + _prop->objtype = FPGA_DEVICE; + + // set the bbs_id to a known value + _prop->u.fpga.bbs_id = 0xCAFE; + + // now get the bbs_id from the prop structure + uint64_t bbs_id; + result = fpgaPropertiesGetBBSID(prop, &bbs_id); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + + // assert it is set to what we set it to above + EXPECT_EQ(0xCAFE, bbs_id); + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_bbs_id02 + * @brief Tests: fpgaPropertiesGetBBSID + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA + * When I call fpgaPropertiesGetBBSID with a pointer to an integer + * variable
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST_F(properties_c_ase_p, get_bbs_id02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field to a different type + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_ACCELERATOR; + + // now get the bbs_id from the prop structure + uint64_t bbs_id; + result = fpgaPropertiesGetBBSID(prop, &bbs_id); + EXPECT_EQ(FPGA_INVALID_PARAM, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_bbs_id03 + * @brief Tests: fpgaPropertiesGetBBSID + * @details Given a non-null fpga_properties* object
+ * And its type is FPGA_DEVICE + * And it does NOT have the bbs_id field set
+ * When I call fpgaPropertiesGetBBSID with the property object + * and a pointer to bool variable
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_bbs_id03) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + + // make sure the FPGA_PROPERTY_BBSID bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_BBSID) & 1, 0); + + uint64_t bbs_id; + result = fpgaPropertiesGetBBSID(prop, &bbs_id); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_bbs_id01 + * @brief Tests: fpgaPropertiesSetBBSID + * @details Given a non-null fpga_properties* object
+ * And its object type is of type FPGA
+ * And an integer variable set to a known value
+ * When I call fpgaPropertiesSetBBSID with the properties object + * and the integer variable
+ * Then the return value is FPGA_OK + * And the bbs_id in the properties object is the known value
+ */ +TEST_F(properties_c_ase_p, set_bbs_id01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + // set the object type field + _prop->objtype = FPGA_DEVICE; + + // make sure the FPGA_PROPERTY_BBSID bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_BBSID) & 1, 0); + + uint64_t bbs_id = 0xCAFE; + // Call the API to set the token on the property + result = fpgaPropertiesSetBBSID(prop, bbs_id); + EXPECT_EQ(result, FPGA_OK); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_bbs_id02 + * @brief Tests: fpgaPropertiesSetBBSID + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA_DEVICE
+ * When I call fpgaPropertiesSetBBSID with the properties object + * and a bbs_id variable
+ * Then the return value is FPGA_INVALID_PARAM
+ */ +TEST_F(properties_c_ase_p, set_bbs_id02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_ACCELERATOR; + + // Call the API to set the token on the property + result = fpgaPropertiesSetBBSID(prop, 0); + + EXPECT_EQ(result, FPGA_INVALID_PARAM); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_bbs_id04 + * @brief Tests: fpgaPropertiesGetBBSID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetBBSID with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_bbs_id04) { + fpga_properties prop = NULL; + + uint64_t bbs_id; + fpga_result result = fpgaPropertiesGetBBSID(prop, &bbs_id); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_bbs_id03 + * @brief Tests: fpgaPropertiesSetBBSID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetBBSID with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_bbs_id03) { + fpga_properties prop = NULL; + + // Call the API to set the bbs_id on the property + fpga_result result = fpgaPropertiesSetBBSID(prop, 0); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** fpga.bbs_version field tests **/ +/** + * @test get_bbs_version01 + * @brief Tests: fpgaPropertiesGetBBSVersion + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA + * And it has the bbs_version field set to a known value
+ * When I call fpgaPropertiesGetBBSVersion with a pointer to an + * fpga_version variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_bbs_version01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_BBSVERSION); + + // set the object type field + _prop->objtype = FPGA_DEVICE; + + // set the bbs_version to a known value + fpga_version v = {1, 2, 3}; + _prop->u.fpga.bbs_version = v; + + // now get the bbs_version from the prop structure + fpga_version bbs_version; + result = fpgaPropertiesGetBBSVersion(prop, &bbs_version); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + +// assert it is set to what we set it to above +#ifndef BUILD_ASE + EXPECT_EQ(0, memcmp(&v, &bbs_version, sizeof(fpga_version))); +#endif + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_bbs_version02 + * @brief Tests: fpgaPropertiesGetBBSVersion + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA + * When I call fpgaPropertiesGetBBSVersion with a pointer to an + * fpga_version variable
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST_F(properties_c_ase_p, get_bbs_version02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field to a different type + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_ACCELERATOR; + + // now get the bbs_version from the prop structure + fpga_version bbs_version; + result = fpgaPropertiesGetBBSVersion(prop, &bbs_version); + EXPECT_EQ(FPGA_INVALID_PARAM, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_bbs_version03 + * @brief Tests: fpgaPropertiesGetBBSVersion + * @details Given a non-null fpga_properties* object
+ * And its type is FPGA_DEVICE + * And it does NOT have the bbs_version field set
+ * When I call fpgaPropertiesGetBBSVersion with the property object + * and a pointer to an fpga_version variable
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_bbs_version03) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + + // make sure the FPGA_PROPERTY_BBSVERSION bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_BBSVERSION) & 1, 0); + + fpga_version bbs_version; + result = fpgaPropertiesGetBBSVersion(prop, &bbs_version); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_bbs_version01 + * @brief Tests: fpgaPropertiesSetBBSVersion + * @details Given a non-null fpga_properties* object
+ * And its object type is of type FPGA
+ * And an fpga_version variable set to a known value
+ * When I call fpgaPropertiesSetBBSVersion with the properties + object + * and the fpga_version variable
+ * Then the return value is FPGA_OK + * And the bbs_version in the properties object is the known + value
+ */ +TEST_F(properties_c_ase_p, set_bbs_version01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + // set the object type field + _prop->objtype = FPGA_DEVICE; + + fpga_version bbs_version = {1, 2, 3}; + + // make sure the FPGA_PROPERTY_BBSVERSION bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_BBSVERSION) & 1, 0); + + // Call the API to set the bbs version on the property + result = fpgaPropertiesSetBBSVersion(prop, bbs_version); + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_BBSVERSION bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_BBSVERSION) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0, memcmp(&bbs_version, &(_prop->u.fpga.bbs_version), + sizeof(fpga_version))); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_bbs_version02 + * @brief Tests: fpgaPropertiesSetBBSVersion + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA_DEVICE
+ * When I call fpgaPropertiesSetBBSVersion with the properties + object + * and a bbs_version variable
+ * Then the return value is FPGA_INVALID_PARAM + */ +TEST_F(properties_c_ase_p, set_bbs_version02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_ACCELERATOR; + + // Call the API to set the token on the property + fpga_version v = {0, 0, 0}; + result = fpgaPropertiesSetBBSVersion(prop, v); + + EXPECT_EQ(result, FPGA_INVALID_PARAM); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_bbs_version04 + * @brief Tests: fpgaPropertiesGetBBSVersion + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetBBSVersion with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_bbs_version04) { + fpga_properties prop = NULL; + + fpga_version bbs_version; + fpga_result result = fpgaPropertiesGetBBSVersion(prop, &bbs_version); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_bbs_version03 + * @brief Tests: fpgaPropertiesSetBBSVersion + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetBBSVersion with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_bbs_version03) { + fpga_properties prop = NULL; + + // Call the API to set the bbs_version on the property + fpga_version v = {0, 0, 0}; + fpga_result result = fpgaPropertiesSetBBSVersion(prop, v); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test fpga_clone_properties01 + * @brief Tests: fpgaClonePoperties + * @details Given a fpga_properties object cloned with + fpgaCloneProperties
+ * When I call fpgaDestroyProperties with the cloned object
+ * Then the result is FPGA_OK
+ * And the properties object is destroyed appropriately
+ */ +TEST_F(properties_c_ase_p, fpga_clone_properties01) { + fpga_properties prop = NULL; + fpga_properties clone = NULL; + uint8_t s1 = 0xEF, s2 = 0; + ASSERT_EQ(FPGA_OK, fpgaGetProperties(NULL, &prop)); + EXPECT_EQ(FPGA_OK, fpgaPropertiesSetSocketID(prop, s1)); + ASSERT_EQ(FPGA_OK, fpgaCloneProperties(prop, &clone)); + EXPECT_EQ(FPGA_OK, fpgaPropertiesGetSocketID(clone, &s2)); + EXPECT_EQ(s1, s2); + ASSERT_EQ(FPGA_OK, fpgaDestroyProperties(&clone)); + ASSERT_EQ(FPGA_OK, fpgaDestroyProperties(&prop)); + ASSERT_EQ(FPGA_INVALID_PARAM, fpgaCloneProperties(NULL, &clone)); +} + +/** + * @test set_model01 + * @brief Tests: fpgaPropertiesSetModel + * @details fpgaPropertiesSetModel is not currently supported. + * + */ +TEST(properties, set_model01) { + EXPECT_EQ(FPGA_NOT_SUPPORTED, fpgaPropertiesSetModel(NULL, 0)); +} + +/** + * @test get_model01 + * @brief Tests: fpgaPropertiesGetModel + * @details fpgaPropertiesGetModel is not currently supported. + * + */ +TEST(properties, get_model01) { + EXPECT_EQ(FPGA_NOT_SUPPORTED, fpgaPropertiesGetModel(NULL, NULL)); +} + +/** + * @test get_lms01 + * @brief Tests: fpgaPropertiesGetLocalMemorySize + * @details fpgaPropertiesGetLocalMemorySize is not currently supported. + * + */ +TEST(properties, get_lms01) { + EXPECT_EQ(FPGA_NOT_SUPPORTED, fpgaPropertiesGetLocalMemorySize(NULL, NULL)); +} + +/** + * @test set_lms01 + * @brief Tests: fpgaPropertiesSetLocalMemorySize + * @details fpgaPropertiesSetLocalMemorySize is not currently supported. + * + */ +TEST(properties, set_lms01) { + EXPECT_EQ(FPGA_NOT_SUPPORTED, fpgaPropertiesSetLocalMemorySize(NULL, 0)); +} + +/** + * @test set_capabilities01 + * @brief Tests: fpgaPropertiesSetCapabilities + * @details fpgaPropertiesSetCapabilities is not currently supported. + * + */ +TEST(properties, set_capabilities01) { + EXPECT_EQ(FPGA_NOT_SUPPORTED, fpgaPropertiesSetCapabilities(NULL, 0)); +} + +/** + * @test get_capabilities01 + * @brief Tests: fpgaPropertiesGetCapabilities + * @details fpgaPropertiesGetCapabilities is not currently supported. + * + */ +TEST(properties, get_capabilities01) { + EXPECT_EQ(FPGA_NOT_SUPPORTED, fpgaPropertiesGetCapabilities(NULL, NULL)); +} + +/** (afu | accelerator).guid field tests **/ +/** + * @test get_guid01 + * @brief Tests: fpgaPropertiesGetGUID + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR + * And it has the guid field set to a known value
+ * When I call fpgaPropertiesGetGUID with a pointer to an + * guid variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_guid01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_GUID); + + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + std::copy(&known_guid[0], &known_guid[16], _prop->guid); + + // now get the guid from the prop structure + fpga_guid guid; + result = fpgaPropertiesGetGUID(prop, &guid); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + + // assert it is set to what we set it to above + EXPECT_EQ(0, memcmp(guid, known_guid, 16)); + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_guid02 + * @brief Tests: fpgaPropertiesGetGUID + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR + * And it has the guid field set to a known value
+ * When I call fpgaPropertiesGetGUID with a pointer to an + * guid variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_guid02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_GUID); + + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + + // set the guid to a known value + std::copy(&known_guid[0], &known_guid[16], _prop->guid); + + // now get the guid from the prop structure + fpga_guid guid = {0}; + result = fpgaPropertiesGetGUID(prop, &guid); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + + // assert it is set to what we set it to above + EXPECT_EQ(0, memcmp(guid, known_guid, 16)); + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_guid03 + * @brief Tests: fpgaPropertiesGetGUID + * @details Given a non-null fpga_properties* object
+ * And its type is FPGA_DEVICE
+ * And it does NOT have the guid field set
+ * When I call fpgaPropertiesGetGUID with the property + * object and a pointer to an integer variable
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_guid03) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type to FPGA_DEVICE + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_DEVICE; + + // make sure the FPGA_PROPERTY_GUID bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_GUID) & 1, 0); + + fpga_guid guid; + result = fpgaPropertiesGetGUID(prop, &guid); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_guid04 + * @brief Tests: fpgaPropertiesGetGUID + * @details Given a non-null fpga_properties* object
+ * And its type is FPGA_ACCELERATOR
+ * And it does NOT have the guid field set
+ * When I call fpgaPropertiesGetGUID with the property + * object and a pointer to an integer variable
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_guid04) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type to FPGA_ACCELERATOR + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_ACCELERATOR; + + // make sure the FPGA_PROPERTY_GUID bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_GUID) & 1, 0); + + fpga_guid guid; + result = fpgaPropertiesGetGUID(prop, &guid); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_guid05 + * @brief Tests: fpgaPropertiesGetGUID + * @details Given a non-null fpga_properties* object
+ * And its type is FPGA_ACCELERATOR
+ * And it does NOT have the guid field set
+ * When I call fpgaPropertiesGetGUID with the property + * object and a pointer to an integer variable
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_guid05) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type to FPGA_ACCELERATOR + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_ACCELERATOR; + + // make sure the FPGA_PROPERTY_GUID bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_GUID) & 1, 0); + + fpga_guid guid; + result = fpgaPropertiesGetGUID(prop, &guid); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_guid01 + * @brief Tests: fpgaPropertiesSetGUID + * @details Given a non-null fpga_properties* object
+ * And its object type is of type FPGA_ACCELERATOR
+ * And an integer variable set to a known value
+ * When I call fpgaPropertiesSetGUID with the properties + * object and the integer variable
+ * Then the return value is FPGA_OK + * And the guid in the properties object is the known + * value
+ */ +TEST_F(properties_c_ase_p, set_guid01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + + // make sure the FPGA_PROPERTY_GUID bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_GUID) & 1, 0); + fpga_guid guid; + std::copy(&known_guid[0], &known_guid[16], guid); + // Call the API to set the token on the property + result = fpgaPropertiesSetGUID(prop, guid); + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_GUID bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_GUID) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0, memcmp(guid, _prop->guid, 16)); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_guid02 + * @brief Tests: fpgaPropertiesSetGUID + * @details Given a non-null fpga_properties* object
+ * And its object type is of type FPGA_ACCELERATOR
+ * And an integer variable set to a known value
+ * When I call fpgaPropertiesSetGUID with the properties + * object and the integer variable
+ * Then the return value is FPGA_OK + * And the guid in the properties object is the known + * value
+ */ +TEST_F(properties_c_ase_p, set_guid02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + + // make sure the FPGA_PROPERTY_GUID bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_GUID) & 1, 0); + + fpga_guid guid; + std::copy(&known_guid[0], &known_guid[16], guid); + // Call the API to set the token on the property + result = fpgaPropertiesSetGUID(prop, guid); + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_GUID bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_GUID) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0, memcmp(guid, _prop->guid, 16)); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_guid03 + * @brief Tests: fpgaPropertiesSetGUID + * @details Given a non-null fpga_properties* object
+ * And its object type is of type FPGA_DEVICE
+ * And an integer variable set to a known value
+ * When I call fpgaPropertiesSetGUID with the properties + * object and the integer variable
+ * Then the return value is FPGA_OK + * And the guid in the properties object is the known + * value
+ */ +TEST_F(properties_c_ase_p, set_guid03) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + // set the object type field + _prop->objtype = FPGA_DEVICE; + + // make sure the FPGA_PROPERTY_GUID bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_GUID) & 1, 0); + fpga_guid guid; + std::copy(&known_guid[0], &known_guid[16], guid); + // Call the API to set the token on the property + result = fpgaPropertiesSetGUID(prop, guid); + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_GUID bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_GUID) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0, memcmp(guid, _prop->guid, 16)); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_guid06 + * @brief Tests: fpgaPropertiesGetGUID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetGUID with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_guid06) { + fpga_properties prop = NULL; + + fpga_guid guid; + fpga_result result = fpgaPropertiesGetGUID(prop, &guid); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test get_guid07 + * @brief Tests: fpgaPropertiesGetGUID + * @details Given a non-null fpga_properties* object
+ * When I call fpgaPropertiesGetGUID with a null guid parameter
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST_F(properties_c_ase_p, get_guid07) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + result = fpgaPropertiesGetGUID(prop, NULL); + EXPECT_EQ(FPGA_INVALID_PARAM, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(FPGA_OK, result); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_guid04 + * @brief Tests: fpgaPropertiesSetGUID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetGUID with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_guid04) { + fpga_properties prop = NULL; + fpga_guid guid; + // Call the API to set the guid on the property + fpga_result result = fpgaPropertiesSetGUID(prop, guid); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** accelerator.mmio_spaces field tests **/ +/** + * @test get_num_mmio01 + * @brief Tests: fpgaPropertiesGetNumMMIO + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR + * And it has the mmio_spaces field set to a known value
+ * When I call fpgaPropertiesGetNumMMIO with a pointer to an + * integer variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_num_mmio01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_NUM_MMIO); + + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + // set the slot mmio_spaces to a known value + _prop->u.accelerator.num_mmio = 0xAE; + + // now get the mmio_spaces from the prop structure + uint32_t mmio_spaces; + result = fpgaPropertiesGetNumMMIO(prop, &mmio_spaces); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + + // assert it is set to what we set it to above + EXPECT_EQ(0xAE, mmio_spaces); + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_num_mmio02 + * @brief Tests: fpgaPropertiesGetNumMMIO + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA_ACCELERATOR
+ * When I call fpgaPropertiesGetNumMMIO with a pointer to an + * integer variable
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST_F(properties_c_ase_p, get_num_mmio02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field to a different type + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_DEVICE; + + // now get the mmio_spaces from the prop structure + uint32_t mmio_spaces; + result = fpgaPropertiesGetNumMMIO(prop, &mmio_spaces); + EXPECT_EQ(FPGA_INVALID_PARAM, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_num_mmio03 + * @brief Tests: fpgaPropertiesGetNumMMIO + * @details Given a non-null fpga_properties* object
+ * And its type is FPGA_ACCELERATOR
+ * And it does NOT have the mmio_spaces field set
+ * When I call fpgaPropertiesGetNumMMIO with the property + * object and a pointer to an integer variable
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_num_mmio03) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type to FPGA_AFU + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_ACCELERATOR; + + // make sure the FPGA_PROPERTY_NUM_MMIO bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_NUM_MMIO) & 1, 0); + + uint32_t mmio_spaces; + result = fpgaPropertiesGetNumMMIO(prop, &mmio_spaces); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_num_mmio01 + * @brief Tests: fpgaPropertiesSetNumMMIO + * @details Given a non-null fpga_properties* object
+ * And its object type is of type FPGA_ACCELERATOR
+ * When I call fpgaPropertiesSetNumMMIO with the properties + * object and a known value for mmio_spaces parameter
+ * Then the return value is FPGA_OK
+ * And the mmio_spaces in the properties object is the known + * value
+ */ +TEST_F(properties_c_ase_p, set_num_mmio01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + + // make sure the FPGA_PROPERTY_NUM_MMIO bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_NUM_MMIO) & 1, 0); + + // Call the API to set the number of afus + result = fpgaPropertiesSetNumMMIO(prop, 0xAE); + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_NUM_MMIO bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_NUM_MMIO) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0xAE, _prop->u.accelerator.num_mmio); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_num_mmio02 + * @brief Tests: fpgaPropertiesSetNumMMIO + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA_ACCELERATOR
+ * When I call fpgaPropertiesSetNumMMIO with the properties + * object
+ * Then the return value is FPGA_INVALID_PARAM + */ +TEST_F(properties_c_ase_p, set_num_mmio02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_DEVICE; + + // Call the API to set the slot mmio_spaces + result = fpgaPropertiesSetNumMMIO(prop, 0); + + EXPECT_EQ(result, FPGA_INVALID_PARAM); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_num_mmio04 + * @brief Tests: fpgaPropertiesGetNumMMIO + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetNumMMIO with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_num_mmio04) { + fpga_properties prop = NULL; + + uint32_t mmio_spaces; + fpga_result result = fpgaPropertiesGetNumMMIO(prop, &mmio_spaces); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_num_mmio03 + * @brief Tests: fpgaPropertiesSetNumMMIO + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetNumMMIO with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_num_mmio03) { + fpga_properties prop = NULL; + // Call the API to set the mmio_spaces on the property + fpga_result result = fpgaPropertiesSetNumMMIO(prop, 0); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** accelerator.state field tests **/ +/** + * @test get_accelerator_state01 + * @brief Tests: fpgaPropertiesGetAcceleratorState + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR + * And it has the state field set to a known value
+ * When I call fpgaPropertiesGetAcceleratorState with a pointer to + an + * fpga_accelerator_state variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_accelerator_state01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of accelerators fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_ACCELERATOR_STATE); + + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + // set the accelerator state to a known value + _prop->u.accelerator.state = FPGA_ACCELERATOR_UNASSIGNED; + + // now get the state from the prop structure + fpga_accelerator_state state; + result = fpgaPropertiesGetAcceleratorState(prop, &state); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + + // assert it is set to what we set it to above + EXPECT_EQ(FPGA_ACCELERATOR_UNASSIGNED, state); + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_accelerator_state02 + * @brief Tests: fpgaPropertiesGetAcceleratorState + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA_ACCELERATOR
+ * When I call fpgaPropertiesGetAcceleratorState with a pointer to + an + * fpga_accelerator_state variable
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST_F(properties_c_ase_p, get_accelerator_state02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field to a different type + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_DEVICE; + + // now get the state from the prop structure + fpga_accelerator_state state; + result = fpgaPropertiesGetAcceleratorState(prop, &state); + EXPECT_EQ(FPGA_INVALID_PARAM, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_accelerator_state03 + * @brief Tests: fpgaPropertiesGetAcceleratorState + * @details Given a non-null fpga_properties* object
+ * And its type is FPGA_ACCELERATOR
+ * And it does NOT have the state field set
+ * When I call fpgaPropertiesGetAcceleratorState with the property + * object and a pointer to an integer variable
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_accelerator_state03) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type to FPGA_DEVICE + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_ACCELERATOR; + + // make sure the FPGA_PROPERTY_ACCELERATOR_STATE bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_ACCELERATOR_STATE) & 1, 0); + + fpga_accelerator_state state; + result = fpgaPropertiesGetAcceleratorState(prop, &state); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_accelerator_state01 + * @brief Tests: fpgaPropertiesSetAcceleratorState + * @details Given a non-null fpga_properties* object
+ * And its object type is of type FPGA_ACCELERATOR
+ * When I call fpgaPropertiesSetAcceleratorState with the properties + * object and a known accelerator state variable
+ * Then the return value is FPGA_OK + * And the state in the properties object is the known + * value
+ */ +TEST_F(properties_c_ase_p, set_accelerator_state01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of accelerators fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + + // make sure the FPGA_PROPERTY_ACCELERATOR_STATE bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_ACCELERATOR_STATE) & 1, 0); + + // Call the API to set the token on the property + result = fpgaPropertiesSetAcceleratorState(prop, FPGA_ACCELERATOR_UNASSIGNED); + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_ACCELERATOR_STATE bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_ACCELERATOR_STATE) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(FPGA_ACCELERATOR_UNASSIGNED, _prop->u.accelerator.state); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_accelerator_state02 + * @brief Tests: fpgaPropertiesSetAcceleratorState + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA_ACCELERATOR
+ * When I call fpgaPropertiesSetAcceleratorState with the properties + * object and a state variable
+ * Then the return value is FPGA_INVALID_PARAM + */ +TEST_F(properties_c_ase_p, set_accelerator_state02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_DEVICE; + + // Call the API to set the accelerator state + fpga_accelerator_state state = FPGA_ACCELERATOR_ASSIGNED; + result = fpgaPropertiesSetAcceleratorState(prop, state); + + EXPECT_EQ(result, FPGA_INVALID_PARAM); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_accelerator_state04 + * @brief Tests: fpgaPropertiesGetAcceleratorState + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetAcceleratorState with the null + * object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_accelerator_state04) { + fpga_properties prop = NULL; + + fpga_accelerator_state state; + fpga_result result = fpgaPropertiesGetAcceleratorState(prop, &state); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test get_accelerator_state05 + * @brief Tests: fpgaPropertiesGetAcceleratorState + * @details Given a non-null fpga_properties* object
+ * When I call fpgaPropertiesGetAcceleratorState with a null state + * pointer
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST_F(properties_c_ase_p, get_accelerator_state05) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + result = fpgaPropertiesGetAcceleratorState(prop, NULL); + EXPECT_EQ(FPGA_INVALID_PARAM, result); + EXPECT_EQ(fpgaDestroyProperties(&prop), FPGA_OK); +} + +/** + * @test set_accelerator_state03 + * @brief Tests: fpgaPropertiesSetAcceleratorState + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetAcceleratorState with the null + * object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_accelerator_state03) { + fpga_properties prop = NULL; + // Call the API to set the state on the property + fpga_result result = + fpgaPropertiesSetAcceleratorState(prop, FPGA_ACCELERATOR_UNASSIGNED); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** accelerator.num_interrupts field tests **/ +/** + * @test get_num_interrupts01 + * @brief Tests: fpgaPropertiesGetNumInterrupts + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR
+ * And it has the num_interrupts field set to a known value
+ * When I call fpgaPropertiesGetNumInterrupts with a pointer to an + * integer variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_num_interrupts01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_NUM_INTERRUPTS); + + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + // set the slot num_interrupts to a known value + _prop->u.accelerator.num_interrupts = 0xAE; + + // now get the num_interrupts from the prop structure + uint32_t num_interrupts; + result = fpgaPropertiesGetNumInterrupts(prop, &num_interrupts); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + + // assert it is set to what we set it to above + EXPECT_EQ(0xAE, num_interrupts); + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_num_interrupts02 + * @brief Tests: fpgaPropertiesGetNumInterrupts + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA_ACCELERATOR
+ * When I call fpgaPropertiesGetNumInterrupts with a pointer to an + * integer variable
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST_F(properties_c_ase_p, get_num_interrupts02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field to a different type + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_DEVICE; + + // now get the num_interrupts from the prop structure + uint32_t num_interrupts; + result = fpgaPropertiesGetNumInterrupts(prop, &num_interrupts); + EXPECT_EQ(FPGA_INVALID_PARAM, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_num_interrupts03 + * @brief Tests: fpgaPropertiesGetNumInterrupts + * @details Given a non-null fpga_properties* object
+ * And its type is FPGA_ACCELERATOR
+ * And it does NOT have the num_interrupts field set
+ * When I call fpgaPropertiesGetNumInterrupts with the property + * object and a pointer to an integer variable
+ * Then the return value is FPGA_NOT_FOUND
+ * */ +TEST_F(properties_c_ase_p, get_num_interrupts03) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_TRUE(NULL != prop); + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + // set the object type to FPGA_AFU + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_ACCELERATOR; + + // make sure the FPGA_PROPERTY_NUM_INTERRUPTS bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_NUM_INTERRUPTS) & 1, 0); + + uint32_t num_interrupts; + result = fpgaPropertiesGetNumInterrupts(prop, &num_interrupts); + EXPECT_EQ(FPGA_NOT_FOUND, result); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_num_interrupts01 + * @brief Tests: fpgaPropertiesSetNumInterrupts + * @details Given a non-null fpga_properties* object
+ * And its object type is of type FPGA_ACCELERATOR
+ * When I call fpgaPropertiesSetNumInterrupts with the properties + * object and a known value for num_interrupts parameter
+ * Then the return value is FPGA_OK
+ * And the num_interrupts in the properties object is the known + * value
+ */ +TEST_F(properties_c_ase_p, set_num_interrupts01) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + + // make sure the FPGA_PROPERTY_NUM_INTERRUPTS bit is zero + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_NUM_INTERRUPTS) & 1, 0); + + // Call the API to set the number of afus + result = fpgaPropertiesSetNumInterrupts(prop, 0xAE); + EXPECT_EQ(result, FPGA_OK); + + // make sure the FPGA_PROPERTY_NUM_INTERRUPTS bit is one + EXPECT_EQ((_prop->valid_fields >> FPGA_PROPERTY_NUM_INTERRUPTS) & 1, 1); + + // Assert it is set to what we set it to above + EXPECT_EQ(0xAE, _prop->u.accelerator.num_interrupts); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test set_num_interrupts02 + * @brief Tests: fpgaPropertiesSetNumInterrupts + * @details Given a non-null fpga_properties* object
+ * And its object type is NOT of type FPGA_ACCELERATOR
+ * When I call fpgaPropertiesSetNumInterrupts with the properties + * object
+ * Then the return value is FPGA_INVALID_PARAM + */ +TEST_F(properties_c_ase_p, set_num_interrupts02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type field + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + _prop->objtype = FPGA_DEVICE; + + // Call the API to set the slot num_interrupts + result = fpgaPropertiesSetNumInterrupts(prop, 0); + + EXPECT_EQ(result, FPGA_INVALID_PARAM); + + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_num_interrupts04 + * @brief Tests: fpgaPropertiesGetNumInterrupts + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetNumInterrupts with the null + object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_num_interrupts04) { + fpga_properties prop = NULL; + + uint32_t num_interrupts; + fpga_result result = fpgaPropertiesGetNumInterrupts(prop, &num_interrupts); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_num_interrupts03 + * @brief Tests: fpgaPropertiesSetNumInterrupts + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetNumInterrupts with the null + object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_num_interrupts03) { + fpga_properties prop = NULL; + // Call the API to set the num_interrupts on the property + fpga_result result = fpgaPropertiesSetNumInterrupts(prop, 0); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test prop_213 + * @brief Tests: fpgaGetProperties + * @details When creating a properties object
+ * Then the internal magic should be set to FPGA_PROPERTY_MAGIC
+ */ +TEST_F(properties_c_ase_p, prop_213) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + EXPECT_EQ(FPGA_OK, result); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + EXPECT_EQ(FPGA_PROPERTY_MAGIC, _prop->magic); + EXPECT_EQ(fpgaDestroyProperties(&prop), FPGA_OK); +} + +/** + * @test prop_214 + * @brief Tests: fpgaGetProperties + * @details When creating a properties object with a null properties + * argument
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, prop_214) { + fpga_result result = FPGA_OK; + ASSERT_NO_THROW(result = fpgaGetProperties(NULL, NULL)); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test get_vendor_id01 + * @brief Tests: fpgaPropertiesGetVendorID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetVendorID with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_vendor_id01) { + fpga_properties prop = NULL; + + uint16_t vendor_id; + fpga_result result = fpgaPropertiesGetVendorID(prop, &vendor_id); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_vendor_id01 + * @brief Tests: fpgaPropertiesSetVendorID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetVendorID with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_vendor_id01) { + fpga_properties prop = NULL; + // Call the API to set the vendor_id on the property + fpga_result result = fpgaPropertiesSetVendorID(prop, 0); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test get_vendor_id02 + * @brief Tests: fpgaPropertiesGetVendorID + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR
+ * And it has the vendor_id field set to a known value
+ * When I call fpgaPropertiesGetVendorID with a pointer to an + * 16-bit integer variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_vendor_id02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_VENDORID); + + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + // set the slot num_interrupts to a known value + _prop->vendor_id = 0x8087; + + // now get the num_interrupts from the prop structure + uint16_t vendor_id; + result = fpgaPropertiesGetVendorID(prop, &vendor_id); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + + // assert it is set to what we set it to above + EXPECT_EQ(0x8087, vendor_id); + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_vendor_id03 + * @brief Tests: fpgaPropertiesGetVendorID + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR
+ * But the vendor_id field is not set,
+ * When I call fpgaPropertiesGetVendorID with a pointer to an + * 16-bit integer variable
+ * Then the return value is FPGA_NOT_FOUND.
+ */ +TEST_F(properties_c_ase_p, get_vendor_id03) { + uint16_t vendor = 0; + EXPECT_EQ(fpgaPropertiesGetVendorID(filter_, &vendor), FPGA_NOT_FOUND); +} + +/** + * @test get_device_id01 + * @brief Tests: fpgaPropertiesGetDeviceID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetDeviceID with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_device_id01) { + fpga_properties prop = NULL; + + uint16_t device_id; + fpga_result result = fpgaPropertiesGetDeviceID(prop, &device_id); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +TEST(properties, set_device_id01) { + fpga_properties prop = NULL; + // Call the API to set the device_id on the property + fpga_result result = fpgaPropertiesSetDeviceID(prop, 0); + + EXPECT_EQ(FPGA_NOT_SUPPORTED, result); +} + +/** + * @test get_device_id02 + * @brief Tests: fpgaPropertiesGetDeviceID + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR
+ * And it has the device_id field set to a known value
+ * When I call fpgaPropertiesGetDeviceID with a pointer to an + * 16-bit integer variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_device_id02) { + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and number of slots fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_DEVICEID); + + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + // set the slot num_interrupts to a known value + _prop->device_id = 0xAFFE; + + // now get the num_interrupts from the prop structure + uint16_t device_id; + result = fpgaPropertiesGetDeviceID(prop, &device_id); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + + // assert it is set to what we set it to above + EXPECT_EQ(0xAFFE, device_id); + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_device_id03 + * @brief Tests: fpgaPropertiesGetDeviceID + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR
+ * But the device_id field is not set,
+ * When I call fpgaPropertiesGetDeviceID with a pointer to an + * 16-bit integer variable
+ * Then the return value is FPGA_NOT_FOUND.
+ */ +TEST_F(properties_c_ase_p, get_device_id03) { + uint16_t devid = 0; + EXPECT_EQ(fpgaPropertiesGetDeviceID(filter_, &devid), FPGA_NOT_FOUND); +} + +/** + * @test get_object_id01 + * @brief Tests: fpgaPropertiesGetObjectID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesGetObjectID with the null object
+ * Then the return value is FPGA_INVALID_PARAM
+ * */ +TEST(properties, get_object_id01) { + fpga_properties prop = NULL; + + uint64_t object_id; + fpga_result result = fpgaPropertiesGetObjectID(prop, &object_id); + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test set_object_id01 + * @brief Tests: fpgaPropertiesSetObjectID + * @details Given a null fpga_properties* object
+ * When I call fpgaPropertiesSetObjectID with the null object
+ * Then the result is FPGA_INVALID_PARAM
+ */ +TEST(properties, set_object_id01) { + fpga_properties prop = NULL; + // Call the API to set the object_id on the property + fpga_result result = fpgaPropertiesSetObjectID(prop, 0); + + EXPECT_EQ(FPGA_INVALID_PARAM, result); +} + +/** + * @test get_object_id02 + * @brief Tests: fpgaPropertiesGetObjectID + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR
+ * And it has the object_id field set to a known value
+ * When I call fpgaPropertiesGetObjectID with a pointer to an + * 64-bit integer variable
+ * Then the return value is FPGA_OK
+ * And the output value is the known value
+ * */ +TEST_F(properties_c_ase_p, get_object_id02) { + uint64_t object_id = 0x8000000000000000UL; + fpga_properties prop = NULL; + fpga_result result = fpgaGetProperties(NULL, &prop); + + ASSERT_EQ(result, FPGA_OK); + ASSERT_FALSE(NULL == prop); + + struct _fpga_properties* _prop = (struct _fpga_properties*)prop; + + // set the object type and object ID fields as valid + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJTYPE); + SET_FIELD_VALID(_prop, FPGA_PROPERTY_OBJECTID); + + // set the object type field + _prop->objtype = FPGA_ACCELERATOR; + // set the object ID to a known value + _prop->object_id = object_id; + + // now get the object ID from the prop structure + uint64_t tmp_object_id = 0; + result = fpgaPropertiesGetObjectID(prop, &tmp_object_id); + + // assert the result was ok + EXPECT_EQ(FPGA_OK, result); + + // assert it is set to what we set it to above + EXPECT_EQ(object_id, tmp_object_id); + + // now delete the properties object + result = fpgaDestroyProperties(&prop); + ASSERT_EQ(NULL, prop); +} + +/** + * @test get_object_id03 + * @brief Tests: fpgaPropertiesGetObjectID + * @details Given a non-null fpga_properties* object
+ * And its object type is FPGA_ACCELERATOR
+ * But it has no object_id field set,
+ * When I call fpgaPropertiesGetObjectID with a pointer to an + * 64-bit integer variable
+ * Then the return value is FPGA_NOT_FOUND.
+ */ +TEST_F(properties_c_ase_p, get_object_id03) { + uint64_t objid = 0; + EXPECT_EQ(fpgaPropertiesGetObjectID(filter_, &objid), FPGA_NOT_FOUND); +} + +/** + * @test fpga_destroy_properties01 + * @brief Tests: fpgaDestroyProperties + * @details When the fpga_properties* object
+ * to fpgaDestroyProperties is NULL
+ * Then the function returns FPGA_INVALID_PARAM
+ * + */ +TEST(properties, fpga_destroy_properties01) { + EXPECT_EQ(FPGA_INVALID_PARAM, fpgaDestroyProperties(NULL)); +} + +TEST_F(properties_c_ase_p, get_num_errors01) +{ + fpga_properties prop = nullptr; + fpga_result result = fpgaGetProperties(NULL, &prop); + EXPECT_EQ(result, FPGA_OK); + auto _prop = (_fpga_properties*)prop; + SET_FIELD_VALID(_prop, FPGA_PROPERTY_NUM_ERRORS); + + uint32_t num_errors = 0; + // now get the parent token from the prop structure + EXPECT_EQ(fpgaPropertiesGetNumErrors(prop, &num_errors), FPGA_OK); + EXPECT_EQ(fpgaDestroyProperties(&prop), FPGA_OK); +} + +/** + * @test get_num_errors02 + * @brief Tests: fpgaPropertiesGetNumErrors + * @details When the number of errors field is not set
+ * in the properties object,
+ * Then fpgaPropertiesGetNumErrors returns FPGA_NOT_FOUND.
+ * + */ +TEST_F(properties_c_ase_p, get_num_errors02) { + uint32_t errors = 0; + EXPECT_EQ(fpgaPropertiesGetNumErrors(filter_, &errors), FPGA_OK); +} + +/** + * @test from_token02 + * @brief Tests: fpgaGetProperties + * @details When the input token is valid
+ * and the call to opae_allocate_wrapped_token() fails,
+ * fpgaGetProperties returns FPGA_NO_MEMORY
+ */ +TEST_F(properties_c_ase_p, from_token) { + fpga_properties props = nullptr; + // Invalidate the allocation of the wrapped token. + system_->invalidate_malloc(0, "ase_malloc"); + EXPECT_EQ(fpgaGetProperties(tok_accel_, &props), FPGA_NO_MEMORY); +} + +/** + * @test update03 + * @brief Tests: fpgaUpdateProperties + * @details When the resulting properties object has a parent token set,
+ * but malloc fails during wrapper allocation,
+ * fpgaUpdateProperties returns FPGA_NO_MEMORY.
+ */ +TEST_F(properties_c_ase_p, update03) { + fpga_properties props = nullptr; + ASSERT_EQ(fpgaGetProperties(NULL, &props), FPGA_OK); + EXPECT_EQ(fpgaDestroyProperties(&props), FPGA_OK); +} + +/** + * @test fpga_clone_properties02 + * @brief Tests: fpgaCloneProperties + * @details When calloc fails to allocate the new properties object,
+ * fpgaClonePropeties returns FPGA_EXCEPTION.
+ */ +TEST_F(properties_c_ase_p, fpga_clone_properties02) { + fpga_properties clone = NULL; + system_->invalidate_malloc(0, "ase_malloc"); + ASSERT_EQ(fpgaCloneProperties(filter_, &clone), FPGA_NO_MEMORY); +} + +/** + * @test fpga_clone_properties03 + * @brief Tests: fpgaCloneProperties + * @details When property's magic is invalid,
+ * fpgaClonePropeties returns FPGA_INVALID_PARAM.
+ */ +TEST_F(properties_c_ase_p, fpga_clone_properties03) { + fpga_properties src = NULL; + fpga_properties clone = NULL; + + ASSERT_EQ(fpgaGetProperties(nullptr, &src), FPGA_OK); + struct _fpga_properties * src_ = (struct _fpga_properties *)src; + src_->magic = 0xFFFFFFFF; + ASSERT_EQ(fpgaCloneProperties(src, &clone), FPGA_INVALID_PARAM); + EXPECT_EQ(fpgaDestroyProperties(&src), FPGA_OK); +} diff --git a/ase/tests/test_sw_c_ase.cpp b/ase/tests/test_sw_c_ase.cpp new file mode 100644 index 0000000..3b6d9a8 --- /dev/null +++ b/ase/tests/test_sw_c_ase.cpp @@ -0,0 +1,585 @@ +// Copyright(c) 2019, Intel Corporation +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Intel Corporation nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +extern "C" { +#include +#include +#include +#include "types_int.h" +#include "ase_common.h" +#include "ase_host_memory.h" + +int ase_pt_length_to_level(uint64_t length); +ase_host_memory_status membus_op_status(uint64_t va, uint64_t pa); +const char *fpgaErrStr(fpga_result e); +} + +#include "gtest/gtest.h" +#include "test_system.h" +#include "ase.h" + +#define ASE_UNIT +#define FPGA_EVENT_INVALID 0x64 +#define ESBADFMT -1 +#define ESFMTTYP -2 + +#define KB 1024 +#define MB (1024 * KB) +#define GB (1024UL * MB) + +using namespace opae::testing; + +typedef struct mmio_s { + // MMIO Mutex Lock, initilize it here + pthread_mutex_t mmio_port_lock; + + struct buffer_t *mmio_region; // CSR map storage + + // MMIO Read response watcher + int glbl_mmio_tid; // MMIO Tid + + pthread_t mmio_watch_tid; // Tracker thread Id + mmio_t *mmio_rsp_pkt; // MMIO Response packet handoff control +} MMIO_S; +extern MMIO_S io_s; + +/** +* @test ase_rm_sp +* +* @brief When the parameters are valid and libopae-ase-c is loaded: +* remove_spaces() function should remove all the whilte space +* +*/ +TEST(sim_sw_ase, ase_rm_sp) { + char str1[128] = " This is a test string with spaces"; + char *str2 = NULL; + + remove_spaces(str1); + EXPECT_STREQ("Thisisateststringwithspaces", str1); + + remove_spaces(str2); +} + +/** +* @test ase_rm_tab +* +* @brief When the parameters are valid and libopae-ase-c is loaded: +* remove_tabs() function should remove all the tabs +* +*/ +TEST(sim_sw_ase, ase_rm_tab) { + char str1[128] = " This is a test string with tabs "; + char *str2 = NULL; + + remove_tabs(str1); + EXPECT_STREQ("This is a test string with tabs", str1); + + remove_tabs(str2); +} + +/** +* @test ase_ops_01 +* +* @brief When the parameters are valid and libopae-ase-c is loaded: +* ase_buffer_oneline(struct buffer_t *) function should be called +* +*/ +TEST(sim_sw_ase, ase_ops_01) { + struct buffer_t b1, b2; + b1.valid = ASE_BUFFER_VALID; + b2.valid = ASE_BUFFER_INVALID; + + ase_buffer_oneline(&b1); + ase_buffer_oneline(&b2); +} + +/** +* @test ase_mallocafail +* +* @brief When ase_malloc() failed, ase_malloc(size_t) function should +* return NULL +* +*/ +TEST(sim_sw_ase, ase_mallocafail) { + test_system *system_; + system_ = test_system::instance(); + system_->initialize(); + + // Invalidate the memory allocation. + system_->invalidate_malloc(0, "ase_malloc"); + EXPECT_EQ(ase_malloc(100), (char*)NULL); + system_->finalize(); +} + +/** +* @test ase_str_01 +* +* @brief When the parameters are valid and libopae-ase-c is loaded: +* sscanf_s_ii() function should read from a string +* +*/ +TEST(sim_sw_ase, ase_str_01) { + char str1[128] = "Read two integers 345 234"; + char format[128] = "Read two integers %d %d"; + int a, b; + + sscanf_s_ii(str1, format, &a, &b); + EXPECT_EQ(a, 345); + EXPECT_EQ(b, 234); +} + +/** +* @test ase_str_02 +* +* @brief When the parameters are valid and libopae-ase-c is loaded: +* parse_format() function should parse the format of a string +* +*/ +TEST(sim_sw_ase, ase_str_02) { + char format[128]; + char pformatList[32]; + int numformat = 0; + + pformatList[0] = '\0'; + strcpy(format, "Read null %\0"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %%"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %#"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %0"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %-"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read % "); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %+"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %4.2h"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %04.3h"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %04.5l"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %04c"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %04L"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %04c"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %04j"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %04z"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %04t"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %c"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %d"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %d"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %i"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %o"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %4ho"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %u"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %04x"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %04X"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %e"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %f"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %5.2f"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %g"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %a"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %s"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %p"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %n"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(1, numformat); + + pformatList[0] = '\0'; + strcpy(format, "Read %m"); + numformat = parse_format(format, pformatList, 4); + EXPECT_EQ(0, numformat); +} + +/** +* @test ase_str_03 +* +* @brief When the parameters are valid and libopae-ase-c is loaded: +* fscanf_s_i() function should read an integer from a file +* +*/ +TEST(sim_sw_ase, ase_str_03) { + int a = 0; + int b = 2018; + FILE *fp = fopen("str_test.txt", "w+"); + fprintf(fp, "%d ", b); + + rewind(fp); + fscanf_s_i(fp, "%d", &a); + EXPECT_EQ(2018, a); + + fclose(fp); + EXPECT_EQ(unlink("str_test.txt"), 0); +} + +/** +* @test ase_buffer_01 +* @brief Tests: fpgaPrepareBuffer and fpgaReleaseBuffer +* fpgaGetIOAddress +* @details Buffer functions returns FPGA_INVALID_PARAM for +*..........invalid input +*/ +TEST(sim_sw_ase, ase_buffer_01) { + uint64_t* buf_addr; + uint64_t wsid = 1; + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaPrepareBuffer(NULL, 0, (void**)&buf_addr, &wsid, 0)); + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaReleaseBuffer(NULL, 0x10001)); + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaGetIOAddress(NULL, 0x10001, NULL)); +} + +/** +* @test ase_com_01 +* @brief Tests: fpgaErrStr +* +* @details This function returns different message for +* different errors +*/ +TEST(sim_sw_ase, ase_com_01) { + // NULL Handle + EXPECT_STREQ("success", fpgaErrStr(FPGA_OK)); + EXPECT_STREQ("invalid parameter", fpgaErrStr(FPGA_INVALID_PARAM)); + EXPECT_STREQ("resource busy", fpgaErrStr(FPGA_BUSY)); + EXPECT_STREQ("exception", fpgaErrStr(FPGA_EXCEPTION)); + EXPECT_STREQ("not found", fpgaErrStr(FPGA_NOT_FOUND)); + EXPECT_STREQ("no memory", fpgaErrStr(FPGA_NO_MEMORY)); + EXPECT_STREQ("not supported", fpgaErrStr(FPGA_NOT_SUPPORTED)); + EXPECT_STREQ("no driver available", fpgaErrStr(FPGA_NO_DRIVER)); + EXPECT_STREQ("insufficient privileges", fpgaErrStr(FPGA_NO_ACCESS)); +} + +/** +* @test ase_err_01 +* @brief Tests: fpgaReadError fpgaClearError fpgaClearAllErrors +* fpgaGetErrorInfo +* @details These functions returns FPGA_NOT_SUPPORTED +* +*/ +TEST(sim_sw_ase, ase_err_01) { + struct _fpga_token _token; + fpga_token t = &_token; + + // NULL Handle + EXPECT_EQ(FPGA_NOT_SUPPORTED, ase_fpgaReadError(t, 0, NULL)); + EXPECT_EQ(FPGA_NOT_SUPPORTED, ase_fpgaClearError(t, 0)); + EXPECT_EQ(FPGA_NOT_SUPPORTED, ase_fpgaClearAllErrors(t)); + EXPECT_EQ(FPGA_NOT_SUPPORTED, ase_fpgaGetErrorInfo(t, 0, NULL)); +} + +/** +* @test ase_eve_01 +* @brief Tests: fpgaCreateEventHandle fpgaDestroyEventHandle +* fpgaRegisterEvent fpgaUnregisterEvent +* @details These functions returns FPGA_INVALID_PARAM or FPGA_NOT_SUPPORTED +* +*/ +TEST(sim_sw_ase, ase_eve_01) { + int fd; + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaCreateEventHandle(NULL)); + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaDestroyEventHandle(NULL)); + fpga_event_handle handle = NULL; + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaDestroyEventHandle(&handle)); + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaGetOSObjectFromEventHandle(NULL, &fd)); + EXPECT_EQ(FPGA_NOT_SUPPORTED, ase_fpgaRegisterEvent(NULL, (fpga_event_type)FPGA_EVENT_INVALID, NULL, 1)); + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaRegisterEvent(NULL, FPGA_EVENT_INTERRUPT, NULL, MAX_USR_INTRS)); + EXPECT_EQ(FPGA_NOT_SUPPORTED, ase_fpgaUnregisterEvent(NULL, (fpga_event_type)FPGA_EVENT_INVALID, NULL)); +} + +/** +* @test ase_mmio_01 +* @brief Tests: fpgaWriteMMIO32 fpgaReadMMIO32 fpgaWriteMMIO64 +* fpgaReadMMIO64 fpgaWriteMMIO512 fpgaMapMMIO fpgaUnmapMMIO +* @details These functions returns FPGA_NOT_SUPPORTED +* +*/ +TEST(sim_sw_ase, ase_mmio_01) { + struct _fpga_handle _handle; + uint32_t value; + uint64_t value1; + uint64_t value512[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + _handle.fpgaMMIO_is_mapped = 0; + fpga_handle handle = &_handle; + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaWriteMMIO32(NULL, 0, 0x10, 0)); + EXPECT_EQ(FPGA_NOT_FOUND, ase_fpgaWriteMMIO32(handle, 0, 0x10, 0)); + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaReadMMIO32(NULL, 0, 0x10, &value)); + EXPECT_EQ(FPGA_NOT_FOUND, ase_fpgaReadMMIO32(handle, 0, 0x10, &value)); + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaWriteMMIO64(NULL, 0, 0x10, 0)); + EXPECT_EQ(FPGA_NOT_FOUND, ase_fpgaWriteMMIO64(handle, 0, 0x10, 0)); + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaReadMMIO64(NULL, 0, 0x10, &value1)); + EXPECT_EQ(FPGA_NOT_FOUND, ase_fpgaReadMMIO64(handle, 0, 0x10, &value1)); + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaWriteMMIO512(NULL, 0, 0x40, value512)); + EXPECT_EQ(FPGA_NOT_FOUND, ase_fpgaWriteMMIO512(handle, 0, 0x40, value512)); + + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaMapMMIO(NULL, 0, NULL)); + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaUnmapMMIO(NULL, 0)); + _handle.magic = FPGA_HANDLE_MAGIC; + EXPECT_EQ(FPGA_OK, ase_fpgaUnmapMMIO(handle, 0)); + _handle.magic = FPGA_HANDLE_MAGIC - 1; + EXPECT_EQ(FPGA_INVALID_PARAM, ase_fpgaUnmapMMIO(handle, 0)); +} + +/** +* @test ase_err_021 +* +* @brief When the parameters are valid and libopae-ase-c is loaded: +* ase_error_report() function should print out the errors +* +*/ +TEST(sim_sw_ase, ase_err_02) { + + ase_error_report("ase_init", 1, ASE_USR_CAPCM_NOINIT); + ase_error_report("ase_init", 1, ASE_OS_MQUEUE_ERR); + ase_error_report("ase_malloc", 1, ASE_OS_SHM_ERR); + ase_error_report("ase_buffer_alloc", 1, ASE_OS_FOPEN_ERR); + ase_error_report("ase_buffer_alloc", 1, ASE_OS_MEMMAP_ERR); + ase_error_report("ase_init", 1, ASE_OS_MQTXRX_ERR); + ase_error_report("ase_init", 1, ASE_OS_MALLOC_ERR); + ase_error_report("ase_init", 1, ASE_IPCKILL_CATERR); + ase_error_report("ase_init", 1, 100); +} + +/** +* @test ase_app_01 +* +* @brief When the parameters are valid and libopae-ase-c is loaded: +* failure_cleanup(const char *) function should be called +* +*/ +TEST(sim_sw_ase, ase_app_01) { + FILE *file = fopen("app_test.txt", "w"); + fprintf(file, "%d\n", getpid() + 1); + fclose(file); + + remove_existing_lock_file("app_test.txt"); + + file = fopen("app_test2.txt", "w"); + fprintf(file, "%s\n", "abab"); + fclose(file); + + remove_existing_lock_file("app_test2.txt"); + EXPECT_EQ(unlink("app_test2.txt"), 0); +} + +/** +* @test ase_app_02 +* +* @brief When the parameters are nullptr, +* is_directory function returns 0; +* +*/ +TEST(sim_sw_ase, ase_app_02) { + EXPECT_EQ(0, is_directory(nullptr)); +} + +/** +* @test ase_app_03 +* +* @brief When the parameters of va 0x1000000000000 is bigger than 48 bit address, +* ase_host_memory_va_to_pa() raise a signal +* +*/ +TEST(sim_sw_ase, ase_app_03) { + ASSERT_EXIT(ase_host_memory_pin(nullptr, nullptr, 0), ::testing::KilledBySignal(SIGSEGV), ""); + ASSERT_EXIT(ase_host_memory_va_to_pa(0x1000000000000, 48), ::testing::KilledBySignal(SIGABRT),""); + ASSERT_EXIT(ase_host_memory_pa_to_va(0x1000000000000, true), ::testing::KilledBySignal(SIGABRT),""); + + EXPECT_EQ(2, ase_pt_length_to_level(GB)); + EXPECT_EQ(-1, ase_pt_length_to_level(3*1024*1024)); +} + +/** +* @test ase_app_04 +* +* @brief When the parameter offset to mmio_write/read() functions is invalid, +* it raises a signal +* +*/ +TEST(sim_sw_ase, ase_app_04) { + uint32_t val32; + uint64_t val64; + ASSERT_EXIT(mmio_write32(-4, 48), ::testing::KilledBySignal(SIGABRT),""); + ASSERT_EXIT(mmio_read32(-4, &val32), ::testing::KilledBySignal(SIGABRT),""); + ASSERT_EXIT(mmio_write64(-4, 48), ::testing::KilledBySignal(SIGABRT),""); + ASSERT_EXIT(mmio_read64(-4, &val64), ::testing::KilledBySignal(SIGABRT),""); +} + +/** +* @test ase_app_05 +* +* @brief When the parameter of pa to membus_op_status() is invalid, +* it returns HOST_MEM_STATUS_ILLEGAL +* When the parameter of va to membus_op_status() is zero +* it returns HOST_MEM_STATUS_ILLEGAL +* +*/ +TEST(sim_sw_ase, ase_app_05) { + EXPECT_EQ(HOST_MEM_STATUS_ILLEGAL, membus_op_status(0x100, 0104)); + EXPECT_EQ(HOST_MEM_STATUS_NOT_PINNED, membus_op_status(0x0, 0100)); +} + +/** +* @test ase_app_06 +* +* @brief When the parameter of pa to membus_op_status() is invalid, +* it returns HOST_MEM_STATUS_ILLEGAL +* When the parameter of va to membus_op_status() is zero +* it returns HOST_MEM_STATUS_ILLEGAL +* +*/ +TEST(sim_sw_ase, ase_app_06) { + EXPECT_EQ(HOST_MEM_STATUS_ILLEGAL, membus_op_status(0x100, 0104)); + EXPECT_EQ(HOST_MEM_STATUS_NOT_PINNED, membus_op_status(0x0, 0100)); +} + +