Commit 6df837c Ticket 49086 - public api compatability test for SDN changes.

5 files Authored and Committed by firstyear 2 months ago
Ticket 49086 - public api compatability test for SDN changes.

Bug Description:  In order to resolve the SDN premangaling issue, we need to
assert that as we change the pblock and operation code we do not violate our
api behaviours.

Fix Description:  This adds a set of initial tests to assert the behaviours of
the plugin v3 api via the pblock, and partially via the internal operation
api. With this set of tests, changes to the pblock structures and pointers can
be asserted to "behave the same way", which means we will keep the public api
working for existing plugins.

https://fedorahosted.org/389/ticket/49086

Author: wibrown

Review by: mreynolds (Thanks!)

    
 1 @@ -1843,10 +1843,14 @@
 2   
 3   test_slapd_SOURCES = test/main.c \
 4   »       »       »       »       »       test/libslapd/test.c \
 5 - »       »       »       »       »       test/libslapd/pblock/analytics.c
 6 + »       »       »       »       »       test/libslapd/pblock/analytics.c \
 7 + »       »       »       »       »       test/libslapd/pblock/v3_compat.c \
 8 + »       »       »       »       »       test/libslapd/operation/v3_compat.c
 9   test_slapd_LDADD = libslapd.la
10   test_slapd_LDFLAGS = $(AM_CPPFLAGS) $(CMOCKA_LINKS)
11 - test_slapd_CPPFLAGS = $(AM_CPPFLAGS) @nspr_inc@
12 + ### WARNING: Slap.h needs cert.h, which requires the -I/lib/ldaputil!!!
13 + ### WARNING: Slap.h pulls ssl.h, which requires nss!!!!
14 + test_slapd_CPPFLAGS = $(AM_CPPFLAGS) @nspr_inc@ @nss_inc@ -I$(srcdir)/include/ldaputil
15   
16   
17   
 1 @@ -0,0 +1,53 @@
 2 + /** BEGIN COPYRIGHT BLOCK
 3 +  * Copyright (C) 2017 Red Hat, Inc.
 4 +  * All rights reserved.
 5 +  *
 6 +  * License: GPL (version 3 or any later version).
 7 +  * See LICENSE for details.
 8 +  * END COPYRIGHT BLOCK **/
 9 + 
10 + #include "../../test_slapd.h"
11 + 
12 + /* This is somewhat internal to the server! Thus the slap.h */
13 + /* WARNING: Slap.h needs cert.h, which requires the -I/lib/ldaputil!!! */
14 + /* It also pulls in nspr! Bad! */
15 + 
16 + #include <slap.h>
17 + 
18 + /*
19 +  * Assert that the compatability requirements of the plugin V3 pblock API
20 +  * are upheld.
21 +  *
22 +  * This is for checking the operation type maintains a correct interface.
23 +  */
24 + 
25 + void
26 + test_libslapd_operation_v3c_target_spec(void **state __attribute__((unused))) {
27 +     /* Will we need to test PB / op interactions? */
28 +     /* Test the operation of the target spec is maintained. */
29 +     Slapi_Operation *op = slapi_operation_new(SLAPI_OP_FLAG_INTERNAL);
30 +     Slapi_DN *test_a_sdn = slapi_sdn_new_dn_byval("cn=a,cn=test");
31 +     Slapi_DN *a_sdn = NULL;
32 +     Slapi_DN *b_sdn = NULL;
33 + 
34 +     /* Create an SDN */
35 +     /* Set it. */
36 +     operation_set_target_spec(op, test_a_sdn);
37 +     /* Assert the pointers are different because target_spec DUPS */
38 +     a_sdn = operation_get_target_spec(op);
39 +     assert_ptr_not_equal(a_sdn, test_a_sdn);
40 +     assert_int_equal(slapi_sdn_compare(a_sdn, test_a_sdn), 0);
41 + 
42 +     /* Set a new SDN */
43 +     operation_set_target_spec_str(op, "cn=b,cn=test");
44 +     /* Assert the old SDN is there, as we don't free on set */
45 +     b_sdn = operation_get_target_spec(op);
46 +     assert_ptr_not_equal(b_sdn, a_sdn);
47 +     assert_ptr_not_equal(b_sdn, test_a_sdn);
48 +     assert_int_not_equal(slapi_sdn_compare(a_sdn, b_sdn), 0);
49 + 
50 +     /* free everything */
51 +     slapi_sdn_free(&test_a_sdn);
52 +     slapi_sdn_free(&a_sdn);
53 +     slapi_sdn_free(&b_sdn);
54 + }
  1 @@ -0,0 +1,204 @@
  2 + /** BEGIN COPYRIGHT BLOCK
  3 +  * Copyright (C) 2017 Red Hat, Inc.
  4 +  * All rights reserved.
  5 +  *
  6 +  * License: GPL (version 3 or any later version).
  7 +  * See LICENSE for details.
  8 +  * END COPYRIGHT BLOCK **/
  9 + 
 10 + #include "../../test_slapd.h"
 11 + #include <string.h>
 12 + 
 13 + /*
 14 +  * Assert that the compatability requirements of the plugin V3 pblock API
 15 +  * are upheld.
 16 +  *
 17 +  * This will be critical in the migration to V4 so that refactors can guarantee
 18 +  * we are not altering code behaviours.
 19 +  */
 20 + 
 21 + 
 22 + void
 23 + test_libslapd_pblock_v3c_target_dn(void **state __attribute__((unused))) {
 24 +     /* Create a pblock */
 25 +     Slapi_PBlock *pb = slapi_pblock_new();
 26 +     Slapi_Operation *op = slapi_operation_new(SLAPI_OP_FLAG_INTERNAL);
 27 +     slapi_pblock_init(pb);
 28 + 
 29 +     char *dn = NULL;
 30 +     char *test_dn = "cn=Directory Manager";
 31 +     Slapi_DN *sdn = NULL;
 32 + 
 33 +     /* SLAPI_TARGET_DN */
 34 +     /* Check that with no operation we get -1 */
 35 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn), -1);
 36 +     assert_int_equal(slapi_pblock_set(pb, SLAPI_TARGET_DN, &dn), -1);
 37 + 
 38 +     /* Add the operation */
 39 +     assert_int_equal(slapi_pblock_set(pb, SLAPI_OPERATION, op), 0);
 40 + 
 41 +     /* Check that with a null target_address we get NULL */
 42 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn), 0);
 43 +     assert_null(dn);
 44 + 
 45 +     /* Set a DN */
 46 +     assert_int_equal(slapi_pblock_set(pb, SLAPI_TARGET_DN, test_dn), 0);
 47 +     /* Check it was set */
 48 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn), 0);
 49 +     assert_int_equal(strcmp(dn, test_dn), 0);
 50 +     /* Check that TARGET_SDN is not null now  */
 51 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn), 0);
 52 +     assert_non_null(sdn);
 53 + 
 54 +     /* Assert we did not influence ORIGINAL_TARGET_DN or UNIQUEID */
 55 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &dn), 0);
 56 +     assert_null(dn);
 57 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_TARGET_UNIQUEID, &dn), 0);
 58 +     assert_null(dn);
 59 + 
 60 +     /* A property we cannot easily test is that setting a new DN frees the
 61 +      * OLD sdn. But, we can test in SDN that setting via SDN does NOT free.
 62 +      *
 63 +      * The only effective way to test this would be to crash sadly.
 64 +      */
 65 + 
 66 +     /* It works! */
 67 +     slapi_pblock_destroy(pb);
 68 + }
 69 + 
 70 + 
 71 + void
 72 + test_libslapd_pblock_v3c_target_sdn(void **state __attribute__((unused))) {
 73 +     /* SLAPI_TARGET_SDN */
 74 +     Slapi_PBlock *pb = slapi_pblock_new();
 75 +     Slapi_Operation *op = slapi_operation_new(SLAPI_OP_FLAG_INTERNAL);
 76 +     slapi_pblock_init(pb);
 77 + 
 78 +     char *dn = NULL;
 79 +     Slapi_DN *sdn = NULL;
 80 +     Slapi_DN *test_a_sdn = NULL;
 81 +     Slapi_DN *test_b_sdn = NULL;
 82 + 
 83 +     /* Check our aliases - once we assert these are the same
 84 +      * we can then extend to say that these behaviours hold for all these
 85 +      * pblock aliases.
 86 +      */
 87 +     assert_int_equal(SLAPI_TARGET_SDN, SLAPI_ADD_TARGET_SDN);
 88 +     assert_int_equal(SLAPI_TARGET_SDN, SLAPI_BIND_TARGET_SDN);
 89 +     assert_int_equal(SLAPI_TARGET_SDN, SLAPI_COMPARE_TARGET_SDN);
 90 +     assert_int_equal(SLAPI_TARGET_SDN, SLAPI_DELETE_TARGET_SDN);
 91 +     assert_int_equal(SLAPI_TARGET_SDN, SLAPI_MODIFY_TARGET_SDN);
 92 +     assert_int_equal(SLAPI_TARGET_SDN, SLAPI_MODRDN_TARGET_SDN);
 93 +     assert_int_equal(SLAPI_TARGET_SDN, SLAPI_SEARCH_TARGET_SDN);
 94 + 
 95 +     /* Check that with no operation we get -1 */
 96 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn), -1);
 97 +     assert_int_equal(slapi_pblock_set(pb, SLAPI_TARGET_SDN, sdn), -1);
 98 +     /* Add the operation */
 99 +     assert_int_equal(slapi_pblock_set(pb, SLAPI_OPERATION, op), 0);
100 + 
101 +     /* Check that with a null target_address we get NULL */
102 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn), 0);
103 +     assert_null(sdn);
104 + 
105 +     /* Create and SDN and set it. */
106 +     test_a_sdn = slapi_sdn_new_dn_byval("cn=a,cn=test");
107 +     test_b_sdn = slapi_sdn_new_dn_byval("cn=b,cn=test");
108 + 
109 +     assert_int_equal(slapi_pblock_set(pb, SLAPI_TARGET_SDN, test_a_sdn), 0);
110 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn), 0);
111 +     /* Assert we get it back, not a dup, the real pointer */
112 +     assert_ptr_equal(test_a_sdn, sdn);
113 +     assert_int_equal(slapi_sdn_compare(sdn, test_a_sdn), 0);
114 + 
115 +     /* Make a new one, and assert we haven't freed the previous. */
116 +     assert_int_equal(slapi_pblock_set(pb, SLAPI_TARGET_SDN, test_b_sdn), 0);
117 +     assert_int_equal(slapi_sdn_compare(sdn, test_a_sdn), 0);
118 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn), 0);
119 +     /* Assert we get it back, not a dup, the real pointer */
120 +     assert_ptr_equal(test_b_sdn, sdn);
121 +     assert_int_equal(slapi_sdn_compare(sdn, test_b_sdn), 0);
122 +     assert_int_not_equal(slapi_sdn_compare(sdn, test_a_sdn), 0);
123 + 
124 +     /* Assert we did not influence ORIGINAL_TARGET_DN or UNIQUEID */
125 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &dn), 0);
126 +     assert_null(dn);
127 +     assert_int_equal(slapi_pblock_get(pb, SLAPI_TARGET_UNIQUEID, &dn), 0);
128 +     assert_null(dn);
129 + 
130 +     /* Free everything ourselves! */
131 +     slapi_sdn_free(&test_a_sdn);
132 +     slapi_sdn_free(&test_b_sdn);
133 + 
134 +     /* It works! */
135 +     slapi_pblock_destroy(pb);
136 + }
137 + 
138 + /* nf here means "no implicit free". For now implies no dup */
139 + void
140 + _test_libslapi_pblock_v3c_generic_nf_char(Slapi_PBlock *pb, int type, int *conflicts) {
141 +     /* We have to accept a valid PB, because some tests require operations etc. */
142 +     char *out = NULL;
143 +     char *test_a_in = slapi_ch_strdup("some awesome value");
144 +     char *test_b_in = slapi_ch_strdup("some other value");
145 + 
146 +     /* Check we start nulled. */
147 +     assert_int_equal(slapi_pblock_get(pb, type, &out), 0);
148 +     assert_null(out);
149 +     /* Now, set a value into the pblock. */
150 +     assert_int_equal(slapi_pblock_set(pb, type, test_a_in), 0);
151 +     assert_int_equal(slapi_pblock_get(pb, type, &out), 0);
152 +     assert_ptr_equal(test_a_in, out);
153 +     assert_int_equal(strcmp(out, test_a_in), 0);
154 + 
155 +     /* Test another value, and does not free a. */
156 +     assert_int_equal(slapi_pblock_set(pb, type, test_b_in), 0);
157 +     assert_int_equal(slapi_pblock_get(pb, type, &out), 0);
158 +     assert_ptr_equal(test_b_in, out);
159 +     assert_int_equal(strcmp(out, test_b_in), 0);
160 +     assert_int_not_equal(strcmp(out, test_a_in), 0);
161 + 
162 +     /* conflicts takes a null terminated array of values that we want to assert we do not influence */
163 +     for (size_t i = 0; conflicts[i] != 0; i++) {
164 +         assert_int_equal(slapi_pblock_get(pb, conflicts[i], &out), 0);
165 +         assert_null(out);
166 +     }
167 + 
168 +     slapi_ch_free_string(&test_a_in);
169 +     slapi_ch_free_string(&test_b_in);
170 + }
171 + 
172 + void
173 + test_libslapd_pblock_v3c_original_target_dn(void **state __attribute__((unused))) {
174 +     /* SLAPI_ORIGINAL_TARGET_DN */
175 +     Slapi_PBlock *pb = slapi_pblock_new();
176 +     Slapi_Operation *op = slapi_operation_new(SLAPI_OP_FLAG_INTERNAL);
177 +     int conflicts[] = {SLAPI_TARGET_UNIQUEID, SLAPI_TARGET_SDN, 0};
178 +     slapi_pblock_init(pb);
179 + 
180 +     /* Add the operation */
181 +     assert_int_equal(slapi_pblock_set(pb, SLAPI_OPERATION, op), 0);
182 +     /* Run the generic char * tests */
183 +     _test_libslapi_pblock_v3c_generic_nf_char(pb, SLAPI_ORIGINAL_TARGET_DN, conflicts);
184 + 
185 +     /* It works! */
186 +     slapi_pblock_destroy(pb);
187 + }
188 + 
189 + void
190 + test_libslapd_pblock_v3c_target_uniqueid(void **state __attribute__((unused))) {
191 +     /* SLAPI_TARGET_UNIQUEID */
192 +     Slapi_PBlock *pb = slapi_pblock_new();
193 +     Slapi_Operation *op = slapi_operation_new(SLAPI_OP_FLAG_INTERNAL);
194 +     int conflicts[] = {SLAPI_ORIGINAL_TARGET_DN, SLAPI_TARGET_SDN, 0};
195 +     slapi_pblock_init(pb);
196 + 
197 +     /* Add the operation */
198 +     assert_int_equal(slapi_pblock_set(pb, SLAPI_OPERATION, op), 0);
199 +     /* Run the generic char * tests */
200 +     _test_libslapi_pblock_v3c_generic_nf_char(pb, SLAPI_TARGET_UNIQUEID, conflicts);
201 + 
202 +     /* It works! */
203 +     slapi_pblock_destroy(pb);
204 + }
205 + 
 1 @@ -19,6 +19,11 @@
 2       const struct CMUnitTest tests[] = {
 3           cmocka_unit_test(test_libslapd_hello),
 4           cmocka_unit_test(test_libslapd_pblock_analytics),
 5 +         cmocka_unit_test(test_libslapd_pblock_v3c_target_dn),
 6 +         cmocka_unit_test(test_libslapd_pblock_v3c_target_sdn),
 7 +         cmocka_unit_test(test_libslapd_pblock_v3c_original_target_dn),
 8 +         cmocka_unit_test(test_libslapd_pblock_v3c_target_uniqueid),
 9 +         cmocka_unit_test(test_libslapd_operation_v3c_target_spec),
10       };
11       return cmocka_run_group_tests(tests, NULL, NULL);
12   }
 1 @@ -28,4 +28,13 @@
 2   /* libslapd-pblock-analytics */
 3   void test_libslapd_pblock_analytics(void **state);
 4   
 5 + /* libslapd-pblock-v3_compat */
 6 + void test_libslapd_pblock_v3c_target_dn(void **state);
 7 + void test_libslapd_pblock_v3c_target_sdn(void **state);
 8 + void test_libslapd_pblock_v3c_original_target_dn(void **state);
 9 + void test_libslapd_pblock_v3c_target_uniqueid(void **state);
10 + 
11 + /* libslapd-operation-v3_compat */
12 + void test_libslapd_operation_v3c_target_spec(void **state);
13 + 
14