ae0aee3456443786443697afa881229cf098d337
[samba.git] / python / samba / tests / kcc / kcc_utils.py
1 # Unix SMB/CIFS implementation. Tests for samba.kcc.kcc_utils.
2 # Copyright (C) Andrew Bartlett 2015
3 #
4 # Written by Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19
20 """Tests for samba.kcc.kcc_utils"""
21 import samba
22 import samba.tests
23 from samba.kcc.kcc_utils import *
24 from samba.credentials import Credentials
25 from samba.auth import system_session
26 from samba.samdb import SamDB
27 from samba.tests import delete_force
28
29
30 class ScheduleTests(samba.tests.TestCase):
31
32     def test_new_connection_schedule(self):
33         schedule = new_connection_schedule()
34         self.assertIsInstance(schedule, drsblobs.schedule)
35         self.assertEquals(schedule.size, 188)
36         self.assertEquals(len(schedule.dataArray[0].slots), 168)
37
38
39 # OK, this is pathetic, but the rest of it looks really hard, with the
40 # classes all intertwingled with each other and the samdb. That is to say:
41 # XXX later.
42
43 class SiteCoverageTests(samba.tests.TestCase):
44
45     def setUp(self):
46         self.prefix = "kcc_"
47         self.lp = samba.tests.env_loadparm()
48
49         self.sites = {}
50         self.site_links = {}
51
52         self.creds = Credentials()
53         self.creds.guess(self.lp)
54         self.session = system_session()
55
56         self.samdb = SamDB(session_info=self.session,
57                            credentials=self.creds,
58                            lp=self.lp)
59
60     def tearDown(self):
61         self.samdb.transaction_start()
62
63         for site in self.sites:
64             delete_force(self.samdb, site, controls=['tree_delete:1'])
65
66         for site_link in self.site_links:
67             delete_force(self.samdb, site_link)
68
69         self.samdb.transaction_commit()
70
71     def _add_server(self, name, site):
72         dn = "CN={},CN=Servers,{}".format(name, site)
73         self.samdb.add({
74             "dn": dn,
75             "objectClass": "server",
76             "serverReference": self.samdb.domain_dn()
77         })
78         return dn
79
80     def _add_site(self, name):
81         dn = "CN={},CN=Sites,{}".format(
82             name, self.samdb.get_config_basedn()
83         )
84         self.samdb.add({
85             "dn": dn,
86             "objectClass": "site"
87         })
88         self.samdb.add({
89             "dn": "CN=Servers," + dn,
90             "objectClass": ["serversContainer"]
91         })
92
93         self.sites[dn] = name
94         return dn, name.lower()
95
96     def _add_site_link(self, name, links=[], cost=100):
97         dn = "CN={},CN=IP,CN=Inter-Site Transports,CN=Sites,{}".format(
98             name, self.samdb.get_config_basedn()
99         )
100         self.samdb.add({
101             "dn": dn,
102             "objectClass": "siteLink",
103             "cost": str(cost),
104             "siteList": links
105         })
106         self.site_links[dn] = name
107         return dn
108
109     def test_single_site_link_same_dc_count(self):
110         self.samdb.transaction_start()
111         site1, name1 = self._add_site(self.prefix + "ABCD")
112         site2, name2 = self._add_site(self.prefix + "BCDE")
113
114         uncovered_dn, uncovered = self._add_site(self.prefix + "uncovered")
115
116         self._add_server(self.prefix + "ABCD" + '1', site1)
117         self._add_server(self.prefix + "BCDE" + '1', site2)
118
119         self._add_site_link(self.prefix + "link",
120                             [site1, site2, uncovered_dn])
121         self.samdb.transaction_commit()
122
123         to_cover = uncovered_sites_to_cover(self.samdb, name1)
124         to_cover.sort()
125
126         self.assertEqual([uncovered], to_cover)
127
128         to_cover = uncovered_sites_to_cover(self.samdb, name2)
129         to_cover.sort()
130
131         self.assertEqual([], to_cover)
132
133     def test_single_site_link_different_dc_count(self):
134         self.samdb.transaction_start()
135         site1, name1 = self._add_site(self.prefix + "ABCD")
136         site2, name2 = self._add_site(self.prefix + "BCDE")
137
138         uncovered_dn, uncovered = self._add_site(self.prefix + "uncovered")
139
140         self._add_server(self.prefix + "ABCD" + '1', site1)
141         self._add_server(self.prefix + "ABCD" + '2', site1)
142         self._add_server(self.prefix + "BCDE" + '1', site2)
143         self._add_server(self.prefix + "BCDE" + '2', site2)
144         self._add_server(self.prefix + "BCDE" + '3', site2)
145
146         self._add_site_link(self.prefix + "link",
147                             [site1, site2, uncovered_dn])
148         self.samdb.transaction_commit()
149
150         to_cover = uncovered_sites_to_cover(self.samdb, name1)
151         to_cover.sort()
152
153         self.assertEqual([], to_cover)
154
155         to_cover = uncovered_sites_to_cover(self.samdb, name2)
156         to_cover.sort()
157
158         self.assertEqual([uncovered], to_cover)
159
160     def test_two_site_links_same_cost(self):
161         self.samdb.transaction_start()
162         site1, name1 = self._add_site(self.prefix + "ABCD")
163         site2, name2 = self._add_site(self.prefix + "BCDE")
164
165         uncovered_dn, uncovered = self._add_site(self.prefix + "uncovered")
166
167         self._add_server(self.prefix + "ABCD" + '1', site1)
168         self._add_server(self.prefix + "ABCD" + '2', site1)
169         self._add_server(self.prefix + "BCDE" + '1', site2)
170         self._add_server(self.prefix + "BCDE" + '2', site2)
171         self._add_server(self.prefix + "BCDE" + '3', site2)
172
173         self._add_site_link(self.prefix + "link1",
174                             [site1, uncovered_dn])
175         self._add_site_link(self.prefix + "link2",
176                             [site2, uncovered_dn])
177         self.samdb.transaction_commit()
178
179         to_cover = uncovered_sites_to_cover(self.samdb, name1)
180         to_cover.sort()
181
182         self.assertEqual([uncovered], to_cover)
183
184         to_cover = uncovered_sites_to_cover(self.samdb, name2)
185         to_cover.sort()
186
187         self.assertEqual([uncovered], to_cover)
188
189     def test_two_site_links_different_costs(self):
190         self.samdb.transaction_start()
191         site1, name1 = self._add_site(self.prefix + "ABCD")
192         site2, name2 = self._add_site(self.prefix + "BCDE")
193
194         uncovered_dn, uncovered = self._add_site(self.prefix + "uncovered")
195
196         self._add_server(self.prefix + "ABCD" + '1', site1)
197         self._add_server(self.prefix + "BCDE" + '1', site2)
198         self._add_server(self.prefix + "BCDE" + '2', site2)
199
200         self._add_site_link(self.prefix + "link1",
201                             [site1, uncovered_dn],
202                             cost=50)
203         self._add_site_link(self.prefix + "link2",
204                             [site2, uncovered_dn],
205                             cost=75)
206         self.samdb.transaction_commit()
207
208         to_cover = uncovered_sites_to_cover(self.samdb, name1)
209         to_cover.sort()
210
211         self.assertEqual([uncovered], to_cover)
212
213         to_cover = uncovered_sites_to_cover(self.samdb, name2)
214         to_cover.sort()
215
216         self.assertEqual([], to_cover)
217
218     def test_three_site_links_different_costs(self):
219         self.samdb.transaction_start()
220         site1, name1 = self._add_site(self.prefix + "ABCD")
221         site2, name2 = self._add_site(self.prefix + "BCDE")
222         site3, name3 = self._add_site(self.prefix + "CDEF")
223
224         uncovered_dn, uncovered = self._add_site(self.prefix + "uncovered")
225
226         self._add_server(self.prefix + "ABCD" + '1', site1)
227         self._add_server(self.prefix + "BCDE" + '1', site2)
228         self._add_server(self.prefix + "CDEF" + '1', site3)
229         self._add_server(self.prefix + "CDEF" + '2', site3)
230
231         self._add_site_link(self.prefix + "link1",
232                             [site1, uncovered_dn],
233                             cost=50)
234         self._add_site_link(self.prefix + "link2",
235                             [site2, uncovered_dn],
236                             cost=75)
237         self._add_site_link(self.prefix + "link3",
238                             [site3, uncovered_dn],
239                             cost=60)
240         self.samdb.transaction_commit()
241
242         to_cover = uncovered_sites_to_cover(self.samdb, name1)
243         to_cover.sort()
244
245         self.assertEqual([uncovered], to_cover)
246
247         to_cover = uncovered_sites_to_cover(self.samdb, name2)
248         to_cover.sort()
249
250         self.assertEqual([], to_cover)
251
252         to_cover = uncovered_sites_to_cover(self.samdb, name3)
253         to_cover.sort()
254
255         self.assertEqual([], to_cover)
256
257     def test_three_site_links_different_costs(self):
258         self.samdb.transaction_start()
259         site1, name1 = self._add_site(self.prefix + "ABCD")
260         site2, name2 = self._add_site(self.prefix + "BCDE")
261         site3, name3 = self._add_site(self.prefix + "CDEF")
262
263         uncovered_dn, uncovered = self._add_site(self.prefix + "uncovered")
264
265         self._add_server(self.prefix + "ABCD" + '1', site1)
266         self._add_server(self.prefix + "BCDE" + '1', site2)
267         self._add_server(self.prefix + "CDEF" + '1', site3)
268         self._add_server(self.prefix + "CDEF" + '2', site3)
269
270         self._add_site_link(self.prefix + "link1",
271                             [site1, uncovered_dn],
272                             cost=50)
273         self._add_site_link(self.prefix + "link2",
274                             [site2, uncovered_dn],
275                             cost=75)
276         self._add_site_link(self.prefix + "link3",
277                             [site3, uncovered_dn],
278                             cost=50)
279         self.samdb.transaction_commit()
280
281         to_cover = uncovered_sites_to_cover(self.samdb, name1)
282         to_cover.sort()
283
284         self.assertEqual([uncovered], to_cover)
285
286         to_cover = uncovered_sites_to_cover(self.samdb, name2)
287         to_cover.sort()
288
289         self.assertEqual([], to_cover)
290
291         to_cover = uncovered_sites_to_cover(self.samdb, name3)
292         to_cover.sort()
293
294         self.assertEqual([uncovered], to_cover)
295
296     def test_complex_setup_with_multiple_uncovered_sites(self):
297         self.samdb.transaction_start()
298         site1, name1 = self._add_site(self.prefix + "ABCD")
299         site2, name2 = self._add_site(self.prefix + "BCDE")
300         site3, name3 = self._add_site(self.prefix + "CDEF")
301
302         site4, name4 = self._add_site(self.prefix + "1234")
303         site5, name5 = self._add_site(self.prefix + "2345")
304         site6, name6 = self._add_site(self.prefix + "3456")
305
306         uncovered_dn1, uncovered1 = self._add_site(self.prefix + "uncovered1")
307         uncovered_dn2, uncovered2 = self._add_site(self.prefix + "uncovered2")
308         uncovered_dn3, uncovered3 = self._add_site(self.prefix + "uncovered3")
309
310         # Site Link Cluster 1 - Server List
311         self._add_server(self.prefix + "ABCD" + '1', site1)
312
313         self._add_server(self.prefix + "BCDE" + '1', site2)
314         self._add_server(self.prefix + "BCDE" + '2', site2)
315
316         self._add_server(self.prefix + "CDEF" + '1', site3)
317         self._add_server(self.prefix + "CDEF" + '2', site3)
318         self._add_server(self.prefix + "CDEF" + '3', site3)
319
320         # Site Link Cluster 2 - Server List
321         self._add_server(self.prefix + "1234" + '1', site4)
322         self._add_server(self.prefix + "1234" + '2', site4)
323
324         self._add_server(self.prefix + "2345" + '1', site5)
325         self._add_server(self.prefix + "2345" + '2', site5)
326
327         self._add_server(self.prefix + "3456" + '1', site6)
328
329         # Join to Uncovered1 (preference to site link cluster 1)
330         self._add_site_link(self.prefix + "link1A",
331                             [site1, site2, site3, uncovered_dn1],
332                             cost=49)
333         self._add_site_link(self.prefix + "link2A",
334                             [site4, site5, site6, uncovered_dn1],
335                             cost=50)
336
337         # Join to Uncovered2 (no preferene on site links)
338         self._add_site_link(self.prefix + "link1B",
339                             [site1, site2, site3, uncovered_dn2],
340                             cost=50)
341         self._add_site_link(self.prefix + "link2B",
342                             [site4, site5, site6, uncovered_dn2],
343                             cost=50)
344
345         # Join to Uncovered3 (preference to site link cluster 2)
346         self._add_site_link(self.prefix + "link1C",
347                             [site1, site2, site3, uncovered_dn3],
348                             cost=50)
349         self._add_site_link(self.prefix + "link2C",
350                             [site4, site5, site6, uncovered_dn3],
351                             cost=49)
352
353         self.samdb.transaction_commit()
354
355         to_cover = uncovered_sites_to_cover(self.samdb, name1)
356         to_cover.sort()
357
358         self.assertEqual([], to_cover)
359
360         to_cover = uncovered_sites_to_cover(self.samdb, name2)
361         to_cover.sort()
362
363         self.assertEqual([], to_cover)
364
365         to_cover = uncovered_sites_to_cover(self.samdb, name3)
366         to_cover.sort()
367
368         self.assertEqual([uncovered1, uncovered2], to_cover)
369
370         to_cover = uncovered_sites_to_cover(self.samdb, name4)
371         to_cover.sort()
372
373         self.assertEqual([uncovered2, uncovered3], to_cover)
374
375         to_cover = uncovered_sites_to_cover(self.samdb, name5)
376         to_cover.sort()
377
378         self.assertEqual([], to_cover)
379
380         to_cover = uncovered_sites_to_cover(self.samdb, name6)
381         to_cover.sort()
382
383         self.assertEqual([], to_cover)
384
385         for to_check in [uncovered1, uncovered2, uncovered3]:
386             to_cover = uncovered_sites_to_cover(self.samdb, to_check)
387             to_cover.sort()
388
389             self.assertEqual([], to_cover)