1 /**
2 * Copyright (C) Mellanox Technologies Ltd. 2001-2014.  ALL RIGHTS RESERVED.
3 *
4 * See file LICENSE for terms.
5 */
6 
7 #include <common/test.h>
8 extern "C" {
9 #include <ucs/type/class.h>
10 }
11 
12 class test_class : public ucs::test {
13 };
14 
15 
16 typedef struct base {
17     int            field1;
18 } base_t;
19 UCS_CLASS_DECLARE(base_t, int);
20 
21 typedef struct derived {
22     base_t         super;
23     int            field2;
24 } derived_t;
25 UCS_CLASS_DECLARE(derived_t, int, int);
26 
27 typedef struct derived2 {
28     base_t         super;
29     int            field2;
30 } derived2_t;
31 UCS_CLASS_DECLARE(derived2_t, int, int);
32 
33 static int base_init_count = 0;
34 static int derived_init_count = 0;
35 
36 
37 /* Base impl */
38 
UCS_CLASS_INIT_FUNC(base_t,int param)39 UCS_CLASS_INIT_FUNC(base_t, int param)
40 {
41     if (param < 0) {
42         return UCS_ERR_INVALID_PARAM;
43     }
44     self->field1 = param;
45     ++base_init_count;
46     return UCS_OK;
47 }
48 
UCS_CLASS_CLEANUP_FUNC(base_t)49 UCS_CLASS_CLEANUP_FUNC(base_t)
50 {
51     --base_init_count;
52 }
53 
54 UCS_CLASS_DEFINE(base_t, void);
55 
56 /* Derived impl */
57 
UCS_CLASS_INIT_FUNC(derived_t,int param1,int param2)58 UCS_CLASS_INIT_FUNC(derived_t, int param1, int param2)
59 {
60     UCS_CLASS_CALL_SUPER_INIT(base_t, param1);
61 
62     if (param2 < 0) {
63         return UCS_ERR_INVALID_PARAM;
64     }
65     self->field2 = param2;
66     ++derived_init_count;
67     return UCS_OK;
68 }
69 
UCS_CLASS_CLEANUP_FUNC(derived_t)70 UCS_CLASS_CLEANUP_FUNC(derived_t)
71 {
72     --derived_init_count;
73 }
74 
75 UCS_CLASS_DEFINE(derived_t, base_t);
76 
77 UCS_CLASS_DEFINE_NEW_FUNC(derived_t, derived_t, int, int);
78 UCS_CLASS_DEFINE_DELETE_FUNC(derived_t, derived_t);
79 
80 
81 /* Derived2 impl */
82 
UCS_CLASS_INIT_FUNC(derived2_t,int param1,int param2)83 UCS_CLASS_INIT_FUNC(derived2_t, int param1, int param2)
84 {
85     if (param2 < 0) {
86         return UCS_ERR_INVALID_PARAM;
87     }
88 
89     UCS_CLASS_CALL_SUPER_INIT(base_t, param1);
90 
91     self->field2 = param2;
92     ++derived_init_count;
93     return UCS_OK;
94 }
95 
UCS_CLASS_CLEANUP_FUNC(derived2_t)96 UCS_CLASS_CLEANUP_FUNC(derived2_t)
97 {
98     --derived_init_count;
99 }
100 
101 UCS_CLASS_DEFINE(derived2_t, base_t);
102 
103 
UCS_TEST_F(test_class,basic)104 UCS_TEST_F(test_class, basic) {
105     derived_t *derived;
106     ucs_status_t status;
107 
108     ASSERT_EQ(0, base_init_count);
109     ASSERT_EQ(0, derived_init_count);
110 
111     status = UCS_CLASS_NEW(derived_t, &derived, 1, 2);
112     ASSERT_UCS_OK(status);
113 
114     /* coverity[uninit_use] */
115     EXPECT_EQ(2, derived->field2);
116     EXPECT_EQ(1, derived->super.field1);
117 
118     EXPECT_EQ(1, base_init_count);
119     EXPECT_EQ(1, derived_init_count);
120 
121     UCS_CLASS_DELETE(derived_t, derived);
122 
123     EXPECT_EQ(0, base_init_count);
124     EXPECT_EQ(0, derived_init_count);
125 }
126 
UCS_TEST_F(test_class,create_destroy)127 UCS_TEST_F(test_class, create_destroy) {
128     derived_t *derived;
129     ucs_status_t status;
130 
131     ASSERT_EQ(0, base_init_count);
132     ASSERT_EQ(0, derived_init_count);
133 
134     status = UCS_CLASS_NEW_FUNC_NAME(derived_t)(1, 2, &derived);
135     ASSERT_UCS_OK(status);
136 
137     EXPECT_EQ(2, derived->field2);
138     EXPECT_EQ(1, derived->super.field1);
139 
140     EXPECT_EQ(1, base_init_count);
141     EXPECT_EQ(1, derived_init_count);
142 
143     UCS_CLASS_DELETE_FUNC_NAME(derived_t)(derived);
144 
145     EXPECT_EQ(0, base_init_count);
146     EXPECT_EQ(0, derived_init_count);
147 }
148 
UCS_TEST_F(test_class,failure)149 UCS_TEST_F(test_class, failure) {
150     derived_t *derived;
151     ucs_status_t status;
152 
153     ASSERT_EQ(0, base_init_count);
154     ASSERT_EQ(0, derived_init_count);
155 
156     /* Should fail on base */
157     derived = NULL;
158     status = UCS_CLASS_NEW(derived_t, &derived, -1, 2);
159     /* coverity[leaked_storage] */
160     ASSERT_EQ(UCS_ERR_INVALID_PARAM, status);
161     ASSERT_TRUE(NULL == derived);
162 
163     /* Should be properly cleaned up */
164     EXPECT_EQ(0, base_init_count);
165     EXPECT_EQ(0, derived_init_count);
166 
167     /* Should fail on derived */
168     derived = NULL;
169     status = UCS_CLASS_NEW(derived_t, &derived, 1, -2);
170     /* coverity[leaked_storage] */
171     ASSERT_EQ(UCS_ERR_INVALID_PARAM, status);
172     ASSERT_TRUE(NULL == derived);
173 
174     /* Should be properly cleaned up */
175     EXPECT_EQ(0, base_init_count);
176     EXPECT_EQ(0, derived_init_count);
177 }
178 
UCS_TEST_F(test_class,failure2)179 UCS_TEST_F(test_class, failure2) {
180     derived2_t *derived;
181     ucs_status_t status;
182 
183     ASSERT_EQ(0, base_init_count);
184     ASSERT_EQ(0, derived_init_count);
185 
186     /* Should fail on base */
187     derived = NULL;
188     status = UCS_CLASS_NEW(derived2_t, &derived, -1, 2);
189     /* coverity[leaked_storage] */
190     ASSERT_EQ(UCS_ERR_INVALID_PARAM, status);
191     ASSERT_TRUE(NULL == derived);
192 
193     /* Should be properly cleaned up */
194     EXPECT_EQ(0, base_init_count);
195     EXPECT_EQ(0, derived_init_count);
196 
197     /* Should fail on derived */
198     derived = NULL;
199     status = UCS_CLASS_NEW(derived2_t, &derived, 1, -2);
200     /* coverity[leaked_storage] */
201     ASSERT_EQ(UCS_ERR_INVALID_PARAM, status);
202     ASSERT_TRUE(NULL == derived);
203 
204     /* Should be properly cleaned up */
205     EXPECT_EQ(0, base_init_count);
206     EXPECT_EQ(0, derived_init_count);
207 }
208