/** * Copyright (C) Mellanox Technologies Ltd. 2001-2014. ALL RIGHTS RESERVED. * * See file LICENSE for terms. */ #include extern "C" { #include } class test_class : public ucs::test { }; typedef struct { int field1; } base_t; UCS_CLASS_DECLARE(base_t, int); typedef struct { base_t super; int field2; } derived_t; UCS_CLASS_DECLARE(derived_t, int, int); typedef struct { base_t super; int field2; } derived2_t; UCS_CLASS_DECLARE(derived2_t, int, int); static int base_init_count = 0; static int derived_init_count = 0; /* Base impl */ UCS_CLASS_INIT_FUNC(base_t, int param) { if (param < 0) { return UCS_ERR_INVALID_PARAM; } self->field1 = param; ++base_init_count; return UCS_OK; } UCS_CLASS_CLEANUP_FUNC(base_t) { --base_init_count; } UCS_CLASS_DEFINE(base_t, void); /* Derived impl */ UCS_CLASS_INIT_FUNC(derived_t, int param1, int param2) { UCS_CLASS_CALL_SUPER_INIT(base_t, param1); if (param2 < 0) { return UCS_ERR_INVALID_PARAM; } self->field2 = param2; ++derived_init_count; return UCS_OK; } UCS_CLASS_CLEANUP_FUNC(derived_t) { --derived_init_count; } UCS_CLASS_DEFINE(derived_t, base_t); UCS_CLASS_DEFINE_NEW_FUNC(derived_t, derived_t, int, int); UCS_CLASS_DEFINE_DELETE_FUNC(derived_t, derived_t); /* Derived2 impl */ UCS_CLASS_INIT_FUNC(derived2_t, int param1, int param2) { if (param2 < 0) { return UCS_ERR_INVALID_PARAM; } UCS_CLASS_CALL_SUPER_INIT(base_t, param1); self->field2 = param2; ++derived_init_count; return UCS_OK; } UCS_CLASS_CLEANUP_FUNC(derived2_t) { --derived_init_count; } UCS_CLASS_DEFINE(derived2_t, base_t); UCS_TEST_F(test_class, basic) { derived_t *derived; ucs_status_t status; ASSERT_EQ(0, base_init_count); ASSERT_EQ(0, derived_init_count); status = UCS_CLASS_NEW(derived_t, &derived, 1, 2); ASSERT_UCS_OK(status); /* coverity[uninit_use] */ EXPECT_EQ(2, derived->field2); EXPECT_EQ(1, derived->super.field1); EXPECT_EQ(1, base_init_count); EXPECT_EQ(1, derived_init_count); UCS_CLASS_DELETE(derived_t, derived); EXPECT_EQ(0, base_init_count); EXPECT_EQ(0, derived_init_count); } UCS_TEST_F(test_class, create_destroy) { derived_t *derived; ucs_status_t status; ASSERT_EQ(0, base_init_count); ASSERT_EQ(0, derived_init_count); status = UCS_CLASS_NEW_FUNC_NAME(derived_t)(1, 2, &derived); ASSERT_UCS_OK(status); EXPECT_EQ(2, derived->field2); EXPECT_EQ(1, derived->super.field1); EXPECT_EQ(1, base_init_count); EXPECT_EQ(1, derived_init_count); UCS_CLASS_DELETE_FUNC_NAME(derived_t)(derived); EXPECT_EQ(0, base_init_count); EXPECT_EQ(0, derived_init_count); } UCS_TEST_F(test_class, failure) { derived_t *derived; ucs_status_t status; ASSERT_EQ(0, base_init_count); ASSERT_EQ(0, derived_init_count); /* Should fail on base */ derived = NULL; status = UCS_CLASS_NEW(derived_t, &derived, -1, 2); /* coverity[leaked_storage] */ ASSERT_EQ(UCS_ERR_INVALID_PARAM, status); ASSERT_TRUE(NULL == derived); /* Should be properly cleaned up */ EXPECT_EQ(0, base_init_count); EXPECT_EQ(0, derived_init_count); /* Should fail on derived */ derived = NULL; status = UCS_CLASS_NEW(derived_t, &derived, 1, -2); /* coverity[leaked_storage] */ ASSERT_EQ(UCS_ERR_INVALID_PARAM, status); ASSERT_TRUE(NULL == derived); /* Should be properly cleaned up */ EXPECT_EQ(0, base_init_count); EXPECT_EQ(0, derived_init_count); } UCS_TEST_F(test_class, failure2) { derived2_t *derived; ucs_status_t status; ASSERT_EQ(0, base_init_count); ASSERT_EQ(0, derived_init_count); /* Should fail on base */ derived = NULL; status = UCS_CLASS_NEW(derived2_t, &derived, -1, 2); /* coverity[leaked_storage] */ ASSERT_EQ(UCS_ERR_INVALID_PARAM, status); ASSERT_TRUE(NULL == derived); /* Should be properly cleaned up */ EXPECT_EQ(0, base_init_count); EXPECT_EQ(0, derived_init_count); /* Should fail on derived */ derived = NULL; status = UCS_CLASS_NEW(derived2_t, &derived, 1, -2); /* coverity[leaked_storage] */ ASSERT_EQ(UCS_ERR_INVALID_PARAM, status); ASSERT_TRUE(NULL == derived); /* Should be properly cleaned up */ EXPECT_EQ(0, base_init_count); EXPECT_EQ(0, derived_init_count); }