Skip to content

Commit 7c20baa

Browse files
authored
Merge pull request #568 from pjbreaux/bugfix.test_policy_11_5_4
Fixing functional test issues in test/functional/tm/ltm/test_policy.py
2 parents 874299c + c8e058e commit 7c20baa

5 files changed

Lines changed: 103 additions & 81 deletions

File tree

conftest.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from f5.bigip import BigIP
1717
from f5.bigip import ManagementRoot
18+
from f5.utils.testutils.registrytools import register_device
1819
import mock
1920
import pytest
2021
import requests
@@ -53,41 +54,41 @@ def json(self):
5354
monkeypatch.setattr('f5.bigip.iControlRESTSession', fakesessionclass)
5455

5556

56-
@pytest.fixture
57+
@pytest.fixture(scope='session')
5758
def opt_bigip(request):
5859
return request.config.getoption("--bigip")
5960

6061

61-
@pytest.fixture
62+
@pytest.fixture(scope='session')
6263
def opt_username(request):
6364
return request.config.getoption("--username")
6465

6566

66-
@pytest.fixture
67+
@pytest.fixture(scope='session')
6768
def opt_password(request):
6869
return request.config.getoption("--password")
6970

7071

71-
@pytest.fixture
72+
@pytest.fixture(scope='session')
7273
def opt_port(request):
7374
return request.config.getoption("--port")
7475

7576

76-
@pytest.fixture
77+
@pytest.fixture(scope='session')
7778
def bigip(opt_bigip, opt_username, opt_password, opt_port, scope="module"):
7879
'''bigip fixture'''
7980
b = BigIP(opt_bigip, opt_username, opt_password, port=opt_port)
8081
return b
8182

8283

83-
@pytest.fixture
84+
@pytest.fixture(scope='module')
8485
def mgmt_root(opt_bigip, opt_username, opt_password, opt_port, scope="module"):
8586
'''bigip fixture'''
8687
m = ManagementRoot(opt_bigip, opt_username, opt_password, port=opt_port)
8788
return m
8889

8990

90-
@pytest.fixture
91+
@pytest.fixture(scope='session')
9192
def opt_release(request):
9293
return request.config.getoption("--release")
9394

@@ -153,3 +154,22 @@ def deleter():
153154
request.addfinalizer(deleter)
154155
return pool_registry, members_registry
155156
return _setup_boilerplate
157+
158+
159+
@pytest.fixture(scope='module')
160+
def setup_device_snapshot(request, mgmt_root):
161+
'''Snapshot the device to manage objects created by tests.
162+
163+
Snapshot the device before a test runs and after, then remove objects
164+
that persist after suite runs.
165+
'''
166+
167+
before_snapshot = register_device(mgmt_root)
168+
169+
def teardown():
170+
after_snapshot = register_device(mgmt_root)
171+
diff = set(after_snapshot) - set(before_snapshot)
172+
for item in diff:
173+
after_snapshot[item].delete()
174+
request.addfinalizer(teardown)
175+
return before_snapshot

f5/bigip/resource.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,30 @@ def _produce_instance(self, response):
568568
new_instance._activate_URI(new_instance.selfLink)
569569
return new_instance
570570

571+
def _reduce_boolean_pair(self, config_dict, key1, key2):
572+
'''Ensure only one key with a boolean value is present in dict.
573+
574+
:param config_dict: dict -- dictionary of config or kwargs
575+
:param key1: string -- first key name
576+
:param key2: string -- second key name
577+
:raises: BooleansToReduceHaveSameValue
578+
'''
579+
580+
if key1 in config_dict and key2 in config_dict \
581+
and config_dict[key1] == config_dict[key2]:
582+
msg = 'Boolean pair, %s and %s, have same value: %s. If both ' \
583+
'are given to this method, they cannot be the same, as this ' \
584+
'method cannot decide which one should be True.' \
585+
% (key1, key2, config_dict[key1])
586+
raise BooleansToReduceHaveSameValue(msg)
587+
elif key1 in config_dict and not config_dict[key1]:
588+
config_dict[key2] = True
589+
config_dict.pop(key1)
590+
elif key2 in config_dict and not config_dict[key2]:
591+
config_dict[key1] = True
592+
config_dict.pop(key2)
593+
return config_dict
594+
571595

572596
class OrganizingCollection(ResourceBase):
573597
"""Base class for objects that collect resources under them.
@@ -762,30 +786,6 @@ def _activate_URI(self, selfLinkuri):
762786
'creation_uri_frag': frag,
763787
'allowed_lazy_attributes': attrs})
764788

765-
def _reduce_boolean_pair(self, config_dict, key1, key2):
766-
'''Ensure only one key with a boolean value is present in dict.
767-
768-
:param config_dict: dict -- dictionary of config or kwargs
769-
:param key1: string -- first key name
770-
:param key2: string -- second key name
771-
:raises: BooleansToReduceHaveSameValue
772-
'''
773-
774-
if key1 in config_dict and key2 in config_dict \
775-
and config_dict[key1] == config_dict[key2]:
776-
msg = 'Boolean pair, %s and %s, have same value: %s. If both ' \
777-
'are given to this method, they cannot be the same, as this ' \
778-
'method cannot decide which one should be True.' \
779-
% (key1, key2, config_dict[key1])
780-
raise BooleansToReduceHaveSameValue(msg)
781-
elif key1 in config_dict and not config_dict[key1]:
782-
config_dict[key2] = True
783-
config_dict.pop(key1)
784-
elif key2 in config_dict and not config_dict[key2]:
785-
config_dict[key1] = True
786-
config_dict.pop(key2)
787-
return config_dict
788-
789789
def _create(self, **kwargs):
790790
"""wrapped by `create` override that in subclasses to customize"""
791791
if 'uri' in self._meta_data:

f5/bigip/tm/sys/failover.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@
2828

2929
from f5.bigip.mixins import CommandExecutionMixin
3030
from f5.bigip.resource import UnnamedResource
31-
from f5.sdk_exception import F5SDKError
32-
33-
34-
class InvalidParameterValue(F5SDKError):
35-
pass
3631

3732

3833
class Failover(UnnamedResource, CommandExecutionMixin):
@@ -95,14 +90,7 @@ def exec_cmd(self, command, **kwargs):
9590
:: raises InvalidParameterValue
9691
"""
9792

98-
if 'online' in kwargs and 'offline' in kwargs:
99-
if kwargs['online'] is True and kwargs['offline'] is True or \
100-
kwargs['online'] is False and kwargs['offline'] is False:
101-
error = 'Both parameters cannot have the same value' \
102-
'Currently they are: online={} offline={}'.format(
103-
kwargs['online'], kwargs['offline'])
104-
raise InvalidParameterValue(error)
105-
93+
kwargs = self._reduce_boolean_pair(kwargs, 'online', 'offline')
10694
if 'offline' in kwargs:
10795
self._meta_data['exclusive_attributes'].append(
10896
('offline', 'standby'))

test/functional/tm/ltm/test_policy.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,12 @@
2020
TESTDESCRIPTION = "TESTDESCRIPTION"
2121

2222

23-
def delete_resource(resources):
24-
for resource in resources.get_collection():
25-
system_policy_obj_name = ['_sys_CEC_SSL_client_policy',
26-
'_sys_CEC_SSL_server_policy',
27-
'_sys_CEC_video_policy']
28-
if resource.name not in system_policy_obj_name:
29-
resource.delete()
30-
31-
3223
@pytest.fixture
33-
def setup(request, bigip):
34-
pc1 = bigip.ltm.policys
35-
delete_resource(pc1)
24+
def setup(request, setup_device_snapshot):
25+
return setup_device_snapshot
3626

3727

3828
def setup_policy_test(request, bigip, partition, name, strategy="first-match"):
39-
def teardown():
40-
delete_resource(pc1)
41-
request.addfinalizer(teardown)
4229
pc1 = bigip.ltm.policys
4330
policy1 = pc1.policy.create(
4431
name=name, partition=partition, strategy=strategy)
@@ -70,10 +57,9 @@ def test_rules_refresh_update_load(self, setup, request, bigip):
7057
test_pol1 = rulespc.policy.load(partition='Common',
7158
name='_sys_CEC_video_policy')
7259
rules_s1 = test_pol1.rules_s
73-
rules1 = rules_s1.rules.load(name='youporn_web_1')
60+
rules1 = rules_s1.rules.load(name='cnn_web_1')
7461
r1actions = rules1.actions_s.actions.load(name="1")
7562
assert r1actions.kind == r1actions._meta_data['required_json_kind']
76-
delete_resource(rulespc)
7763

7864

7965
class TestRulesAndConditions(object):
@@ -82,8 +68,7 @@ def test_rules_refresh_update_load(self, setup, request, bigip):
8268
test_pol1 = rulespc.policy.load(partition='Common',
8369
name='_sys_CEC_video_policy')
8470
rules_s1 = test_pol1.rules_s
85-
rules1 = rules_s1.rules.load(name='youporn_web_1')
71+
rules1 = rules_s1.rules.load(name='cnn_web_1')
8672
r1conditions = rules1.conditions_s.conditions.load(name="1")
8773
assert r1conditions.kind ==\
8874
r1conditions._meta_data['required_json_kind']
89-
delete_resource(rulespc)

test/functional/tm/sys/test_failover.py

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,36 @@
1313
# limitations under the License.
1414
#
1515

16-
from f5.bigip.tm.sys.failover import InvalidParameterValue
16+
from f5.bigip.resource import BooleansToReduceHaveSameValue
17+
from f5.multi_device.utils import get_device_info
18+
from f5.multi_device.utils import pollster
1719
from pprint import pprint as pp
1820

1921
import pytest
20-
import time
22+
23+
24+
def get_activation_state(device):
25+
'''Get the activation state for a device.'''
26+
27+
device_name = get_device_info(device).name
28+
act = device.tm.cm.devices.device.load(
29+
name=device_name,
30+
partition='Common'
31+
)
32+
return act.failoverState
33+
34+
35+
def check_device_state_as_expected(device, expected_state):
36+
assert get_activation_state(device).lower() == expected_state.lower()
37+
38+
39+
@pytest.fixture
40+
def teardown_device_failover_state(request, mgmt_root):
41+
def teardown():
42+
if get_activation_state(mgmt_root).lower() != 'active':
43+
f = mgmt_root.tm.sys.failover
44+
f.exec_cmd('run', utilCmdArgs='online')
45+
request.addfinalizer(teardown)
2146

2247

2348
class TestFailover(object):
@@ -47,41 +72,45 @@ def test_toggle_standby(self, bigip):
4772
assert f.command == u"run"
4873
pp('************')
4974
f.refresh()
75+
pp('after refresh')
5076
pp(f.raw)
5177
assert 'Failover active' in f.apiRawValues['apiAnonymous']
5278

5379
def test_attribute_values(self, bigip):
5480
fl = bigip.sys.failover
5581
# Testing both conditions
56-
with pytest.raises(InvalidParameterValue):
82+
with pytest.raises(BooleansToReduceHaveSameValue) as ex1:
5783
fl.exec_cmd('run', online=True, offline=True)
58-
with pytest.raises(InvalidParameterValue):
84+
assert 'online and offline, have same value: True' \
85+
in ex1.value.message
86+
with pytest.raises(BooleansToReduceHaveSameValue) as ex2:
5987
fl.exec_cmd('run', online=False, offline=False)
88+
assert 'online and offline, have same value: False' \
89+
in ex2.value.message
6090

61-
def test_exec_cmd(self, bigip):
62-
fl = bigip.sys.failover.load()
63-
f = bigip.sys.failover
91+
def test_exec_cmd(self, mgmt_root, teardown_device_failover_state):
92+
fl = mgmt_root.tm.sys.failover.load()
93+
f = mgmt_root.tm.sys.failover
6494
f.exec_cmd('run', offline=True)
65-
time.sleep(4)
95+
get_activation_state(mgmt_root)
96+
pollster(check_device_state_as_expected)(mgmt_root, 'forced-offline')
6697
fl.refresh()
98+
pp(fl.raw)
6799
assert 'Failover forced_offline' in fl.apiRawValues['apiAnonymous']
68100
f.exec_cmd('run', offline=False, online=True)
69-
# We need this 2 sec delay as sometimes the status does not change
70-
# straight away, causing the assertion to fail.
71-
time.sleep(2)
101+
pollster(check_device_state_as_expected)(mgmt_root, 'active')
72102
fl.refresh()
103+
pp(fl.raw)
73104
assert 'Failover active' in fl.apiRawValues['apiAnonymous']
74105

75-
def test_exec_cmd_cmdargs(self, bigip):
76-
fl = bigip.sys.failover.load()
77-
f = bigip.sys.failover
106+
def test_exec_cmd_cmdargs(self, mgmt_root, teardown_device_failover_state):
107+
fl = mgmt_root.tm.sys.failover.load()
108+
f = mgmt_root.tm.sys.failover
78109
f.exec_cmd('run', utilCmdArgs='offline')
79-
time.sleep(4)
110+
pollster(check_device_state_as_expected)(mgmt_root, 'forced-offline')
80111
fl.refresh()
81112
assert 'Failover forced_offline' in fl.apiRawValues['apiAnonymous']
82113
f.exec_cmd('run', utilCmdArgs='online')
83-
# We need this 2 sec delay as sometimes the status does not change
84-
# straight away, causing the assertion to fail.
85-
time.sleep(2)
114+
pollster(check_device_state_as_expected)(mgmt_root, 'active')
86115
fl.refresh()
87116
assert 'Failover active' in fl.apiRawValues['apiAnonymous']

0 commit comments

Comments
 (0)