1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
// Copyright (C) 2022-2024 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef GENERIC_CONFIG_BACKEND_DHCP6_H
#define GENERIC_CONFIG_BACKEND_DHCP6_H

#include <database/database_connection.h>
#include <dhcpsrv/config_backend_dhcp6_mgr.h>
#include <dhcpsrv/testutils/generic_backend_unittest.h>

namespace isc {
namespace dhcp {
namespace test {

/// @brief Generic test fixture class for testing DHCPv6
/// config backend operations.
class GenericConfigBackendDHCPv6Test : public GenericBackendTest {
public:
    /// @brief Constructor.
    GenericConfigBackendDHCPv6Test()
        : test_subnets_(), test_networks_(), test_option_defs_(),
          test_options_(), test_client_classes_(), test_servers_(), cbptr_() {
    }

    /// @brief Destructor.
    virtual ~GenericConfigBackendDHCPv6Test() {};<--- Destructor in derived class

    /// @brief Prepares the class for a test.
    ///
    /// Invoked by gtest prior test entry, we create the
    /// appropriate schema and create a basic host manager to
    /// wipe out any prior instance
    virtual void SetUp();

    /// @brief Pre-test exit clean up
    ///
    /// Invoked by gtest upon test exit, we destroy the schema
    /// we created.
    virtual void TearDown();

    /// @brief Abstract method for destroying the back end specific schema
    virtual void destroySchema() = 0;

    /// @brief Abstract method for creating the back end specific schema
    virtual void createSchema() = 0;

    /// @brief Abstract method which returns the back end specific connection
    /// string
    virtual std::string validConnectionString() = 0;

    /// @brief Abstract method which instantiates an instance of a
    /// DHCPv6 configuration back end.
    ///
    /// @params Connection parameters describing the back end to create.
    /// @return Pointer to the newly created back end instance.
    virtual ConfigBackendDHCPv6Ptr backendFactory(db::DatabaseConnection::ParameterMap&
                                                  params) = 0;

    /// @brief Counts rows in a selected table in the back end database.
    ///
    /// This method can be used to verify that some configuration elements were
    /// deleted from a selected table as a result of cascade delete or a trigger.
    /// For example, deleting a subnet should trigger deletion of its address
    /// pools and options. By counting the rows on each table we can determine
    /// whether the deletion took place on all tables for which it was expected.
    ///
    /// @param table Table name.
    /// @return Number of rows in the specified table.
    virtual size_t countRows(const std::string& table) const = 0;

    /// @brief Creates several servers used in tests.
    void initTestServers();

    /// @brief Creates several subnets used in tests.
    void initTestSubnets();

    /// @brief Creates several subnets used in tests.
    void initTestSharedNetworks();

    /// @brief Creates several option definitions used in tests.
    void initTestOptionDefs();

    /// @brief Creates several DHCP options used in tests.
    void initTestOptions();

    /// @brief Creates several client classes used in tests.
    void initTestClientClasses();

    /// @brief Tests that a backend of the given type can be instantiated.
    ///
    /// @param  expected_type type of the back end created (i.e. "mysql",
    /// "postgresql").
    void getTypeTest(const std::string& expected_type);

    /// @brief Verifies that a backend on the localhost can be instantiated.
    void getHostTest();

    /// @brief Verifies that a backend on the localhost port 0 can be instantiated.
    void getPortTest();

    /// @brief Retrieves the most recent audit entries.
    ///
    /// Allowed server selectors: ALL, ONE.
    /// Not allowed server selectors: ANY, UNASSIGNED, MULTIPLE.
    ///
    /// @param server_selector Server selector.
    /// @param modification_time Timestamp being a lower limit for the returned
    /// result set, i.e. entries later than specified time are returned.
    /// @param modification_id Identifier being a lower limit for the returned
    /// result set, used when two (or more) entries have the same
    /// modification_time.
    /// @return Collection of audit entries.
    virtual db::AuditEntryCollection
    getRecentAuditEntries(const db::ServerSelector& server_selector,<--- Function in derived class
                          const boost::posix_time::ptime& modification_time,
                          const uint64_t& modification_id) const;

    /// @brief This test verifies that the server can be added, updated and deleted.
    void createUpdateDeleteServerTest();

    /// @brief This test verifies that it is possible to retrieve all servers from the
    /// database and then delete all of them.
    void getAndDeleteAllServersTest();

    /// @brief This test verifies that the global parameter can be added, updated and
    /// deleted.
    void createUpdateDeleteGlobalParameter6Test();

    /// @brief This test verifies that it is possible to differentiate between the
    /// global parameters by server tag and that the value specified for the
    /// particular server overrides the value specified for all servers.
    void globalParameters6WithServerTagsTest();

    /// @brief This test verifies that all global parameters can be retrieved and deleted.
    void getAllGlobalParameters6Test();

    /// @brief This test verifies that modified global parameters can be retrieved.
    void getModifiedGlobalParameters6Test();

    /// @brief Test that the NullKeyError message is correctly updated.
    void nullKeyErrorTest();

    /// @brief Test that createUpdateSubnet6 throws appropriate exceptions for various
    /// server selectors.
    void createUpdateSubnet6SelectorsTest();

    /// @brief Test that subnet can be inserted, fetched, updated and then fetched again.
    void getSubnet6Test();

    /// @brief Test that getSubnet6 by ID throws appropriate exceptions for various server
    /// selectors.
    void getSubnet6byIdSelectorsTest();

    /// @brief Test that the information about unspecified optional parameters gets
    /// propagated to the database.
    void getSubnet6WithOptionalUnspecifiedTest();

    /// @brief Test that subnet can be associated with a shared network.
    void getSubnet6SharedNetworkTest();

    /// @brief Test that subnet can be fetched by prefix.
    void getSubnet6ByPrefixTest();

    /// @brief Test that getSubnet6 by prefix throws appropriate exceptions for various server
    /// selectors.
    void getSubnet6byPrefixSelectorsTest();

    /// @brief Test that all subnets can be fetched and then deleted.
    void getAllSubnets6Test();

    /// @brief Test that getAllSubnets6 throws appropriate exceptions for various
    /// server selectors.
    void getAllSubnets6SelectorsTest();

    /// @brief Test that subnets with different server associations are returned.
    void getAllSubnets6WithServerTagsTest();

    /// @brief Test that getModifiedSubnets6 throws appropriate exceptions for various
    /// server selectors.
    void getModifiedSubnets6SelectorsTest();

    /// @brief Test that selected subnet can be deleted.
    void deleteSubnet6Test();

    /// @brief Test that deleteSubnet6 by ID throws appropriate exceptions for various
    /// server selectors.
    void deleteSubnet6ByIdSelectorsTest();

    /// @brief Test that deleteSubnet6 by prefix throws appropriate exceptions for various
    /// server selectors.
    void deleteSubnet6ByPrefixSelectorsTest();

    /// @brief Test that deleteAllSubnets6 throws appropriate exceptions for various
    /// server selectors.
    void deleteAllSubnets6SelectorsTest();

    /// @brief Test that it is possible to retrieve and delete orphaned subnet.
    void unassignedSubnet6Test();

    /// @brief Test that subnets modified after given time can be fetched.
    void getModifiedSubnets6Test();

    /// @brief Test that lifetimes in subnets are handled as expected.
    void subnetLifetimeTest();

    /// @brief Test that subnets belonging to a shared network can be retrieved.
    void getSharedNetworkSubnets6Test();

    /// @brief Test that pools are properly updated as a result a subnet update.
    void subnetUpdatePoolsTest();

    /// @brief Test that deleting a subnet triggers deletion of the options associated
    /// with the subnet and pools.
    void subnetOptionsTest();

    /// @brief Test that shared network can be inserted, fetched, updated and then
    /// fetched again.
    void getSharedNetwork6Test();

    /// @brief Test that getSharedNetwork6 throws appropriate exceptions for various
    /// server selectors.
    void getSharedNetwork6SelectorsTest();

    /// @brief Test that shared network may be created and updated and the server tags
    /// are properly assigned to it.
    void createUpdateSharedNetwork6Test();

    /// @brief Test that createUpdateSharedNetwork6 throws appropriate exceptions for various
    /// server selectors.
    void createUpdateSharedNetwork6SelectorsTest();

    /// @brief Test that the information about unspecified optional parameters gets
    /// propagated to the database.
    void getSharedNetwork6WithOptionalUnspecifiedTest();

    /// @brief Test that deleteSharedNetworkSubnets6 with not ANY selector throw.
    void deleteSharedNetworkSubnets6Test();

    /// @brief Test that all shared networks can be fetched.
    void getAllSharedNetworks6Test();

    /// @brief Test that getAllSharedNetworks6 throws appropriate exceptions for various
    /// server selectors.
    void getAllSharedNetworks6SelectorsTest();

    /// @brief Test that shared networks with different server associations are returned.
    void getAllSharedNetworks6WithServerTagsTest();

    /// @brief Test that shared networks modified after given time can be fetched.
    void getModifiedSharedNetworks6Test();

    /// @brief Test that getModifiedSharedNetworks6 throws appropriate exceptions for various
    /// server selectors.
    void getModifiedSharedNetworks6SelectorsTest();

    /// @brief Test that selected shared network can be deleted.
    void deleteSharedNetwork6Test();

    /// @brief Test that deleteSharedNetwork6 throws appropriate exceptions for various
    /// server selectors.
    void deleteSharedNetwork6SelectorsTest();

    /// @brief Test that deleteAllSharedNetworks6 throws appropriate exceptions for various
    /// server selectors.
    void deleteAllSharedNetworks6SelectorsTest();

    /// @brief Test that it is possible to retrieve and delete orphaned shared network.
    void unassignedSharedNetworkTest();

    /// @brief Test that lifetimes in shared networks are handled as expected.
    void sharedNetworkLifetimeTest();

    /// @brief Test that deleting a shared network triggers deletion of the options
    /// associated with the shared network.
    void sharedNetworkOptionsTest();

    /// @brief Test that option definition can be inserted, fetched, updated and then
    /// fetched again.
    void getOptionDef6Test();

    /// @brief This test verifies that it is possible to differentiate between the
    /// option definitions by server tag and that the option definition
    /// specified for the particular server overrides the definition for
    /// all servers.
    void optionDefs6WithServerTagsTest();

    /// @brief This test verifies that the back end prevents storage
    /// of definitions with invalid data types
    void invalidOptionDefDataType6Test();

    /// @brief This test verifies that it is possible to create options of each
    /// valid data type.
    void allOptionDefDataTypes6Test();

    /// @brief Test that all option definitions can be fetched.
    void getAllOptionDefs6Test();

    /// @brief Test that option definitions modified after given time can be fetched.
    void getModifiedOptionDefs6Test();

    /// @brief This test verifies that global option can be added, updated and deleted.
    void createUpdateDeleteOption6Test();

    /// @brief This test verifies that it is possible to differentiate between the
    /// global options by server tag and that the option specified for the
    /// particular server overrides the value specified for all servers.
    void globalOptions6WithServerTagsTest();

    /// @brief This test verifies that all global options can be retrieved.
    void getAllOptions6Test();

    /// @brief This test verifies that modified global options can be retrieved.
    void getModifiedOptions6Test();

    /// @brief This test verifies that subnet level option can be added, updated and
    /// deleted.
    void createUpdateDeleteSubnetOption6Test();

    /// @brief This test verifies that option can be inserted, updated and deleted
    /// from the pool.
    void createUpdateDeletePoolOption6Test();

    /// @brief This test verifies that option can be inserted, updated and deleted
    /// from the pd pool.
    void createUpdateDeletePdPoolOption6Test();

    /// @brief This test verifies that shared network level option can be added,
    /// updated and deleted.
    void createUpdateDeleteSharedNetworkOption6Test();

    /// @brief This test verifies that option id values in one subnet do
    /// not impact options returned in subsequent subnets when
    /// fetching subnets from the backend.
    void subnetOptionIdOrderTest();

    /// @brief This test verifies that option id values in one shared network do
    /// not impact options returned in subsequent shared networks when
    /// fetching shared networks from the backend.
    void sharedNetworkOptionIdOrderTest();

    /// @brief This test verifies that it is possible to create client classes, update them
    /// and retrieve all classes for a given server.
    void setAndGetAllClientClasses6Test();

    /// @brief This test verifies that a single class can be retrieved from the database.
    void getClientClass6Test();

    /// @brief This test verifies that client class specific DHCP options can be
    /// modified during the class update.
    void createUpdateClientClass6OptionsTest();

    /// @brief This test verifies that modified client classes can be retrieved from the database.
    void getModifiedClientClasses6Test();

    /// @brief This test verifies that a specified client class can be deleted.
    void deleteClientClass6Test();

    /// @brief This test verifies that all client classes can be deleted using
    /// a specified server selector.
    void deleteAllClientClasses6Test();

    /// @brief This test verifies that client class dependencies are tracked when the
    /// classes are added to the database. It verifies that an attempt to update
    /// a class violating the dependencies results in an error.
    void clientClassDependencies6Test();

    /// @brief This test verifies that audit entries can be retrieved from a given
    /// timestamp and id including when two entries can get the same timestamp.
    /// (either it is a common even and this should catch it, or it is a rare
    /// event and it does not matter).
    void multipleAuditEntriesTest();

    /// @brief Holds pointers to subnets used in tests.
    std::vector<Subnet6Ptr> test_subnets_;

    /// @brief Holds pointers to shared networks used in tests.
    std::vector<SharedNetwork6Ptr> test_networks_;

    /// @brief Holds pointers to option definitions used in tests.
    std::vector<OptionDefinitionPtr> test_option_defs_;

    /// @brief Holds pointers to options used in tests.
    std::vector<OptionDescriptorPtr> test_options_;

    /// @brief Holds pointers to classes used in tests.
    std::vector<ClientClassDefPtr> test_client_classes_;

    /// @brief Holds pointers to the servers used in tests.
    std::vector<db::ServerPtr> test_servers_;

    /// @brief Holds pointer to the backend.
    boost::shared_ptr<ConfigBackendDHCPv6> cbptr_;
};

}  // namespace test
}  // namespace dhcp
}  // namespace isc

#endif // GENERIC_CONFIG_BACKEND_DHCP6_H