7179642aea
The housekeeper GET will run the job with readonly mode The PUT command will run it with readonly=False (unless it is globally configured as readonlyi, which will cause a failure) Change-Id: Ifcac0bbe6f447ae431c75f66f3c7f8682c9e9408
157 lines
5.9 KiB
Python
157 lines
5.9 KiB
Python
# Copyright 2018 VMware, Inc.
|
|
# All Rights Reserved
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import mock
|
|
from neutron.tests import base
|
|
from neutron_lib import exceptions as n_exc
|
|
|
|
from vmware_nsx.plugins.common.housekeeper import base_job
|
|
from vmware_nsx.plugins.common.housekeeper import housekeeper
|
|
|
|
|
|
class TestJob1(base_job.BaseJob):
|
|
def __init__(self, global_readonly, readonly_jobs):
|
|
super(TestJob1, self).__init__(global_readonly, readonly_jobs)
|
|
|
|
def get_name(self):
|
|
return 'test_job1'
|
|
|
|
def get_project_plugin(self, plugin):
|
|
return 'Dummy'
|
|
|
|
def get_description(self):
|
|
return 'test'
|
|
|
|
def run(self, context, readonly=False):
|
|
pass
|
|
|
|
|
|
class TestJob2(TestJob1):
|
|
def get_name(self):
|
|
return 'test_job2'
|
|
|
|
|
|
class TestHousekeeper(base.BaseTestCase):
|
|
|
|
def setUp(self):
|
|
self.jobs = ['test_job1', 'test_job2']
|
|
self.readonly_jobs = ['test_job1']
|
|
self.readonly = False
|
|
self.housekeeper = housekeeper.NsxHousekeeper(
|
|
hk_ns='stevedore.test.extension',
|
|
hk_jobs=self.jobs,
|
|
hk_readonly=self.readonly,
|
|
hk_readonly_jobs=self.readonly_jobs)
|
|
|
|
self.job1 = TestJob1(self.readonly, self.readonly_jobs)
|
|
self.job2 = TestJob2(self.readonly, self.readonly_jobs)
|
|
self.housekeeper.jobs = {'test_job1': self.job1,
|
|
'test_job2': self.job2}
|
|
self.context = mock.Mock()
|
|
self.context.session = mock.Mock()
|
|
|
|
super(TestHousekeeper, self).setUp()
|
|
|
|
def test_run_job_readonly(self):
|
|
with mock.patch.object(self.job1, 'run') as run1,\
|
|
mock.patch.object(self.job2, 'run') as run2:
|
|
self.housekeeper.run(self.context, 'test_job1', readonly=True)
|
|
run1.assert_called_with(mock.ANY, readonly=True)
|
|
|
|
self.housekeeper.run(self.context, 'test_job2', readonly=True)
|
|
run2.assert_called_with(mock.ANY, readonly=True)
|
|
|
|
def test_run_job_readwrite(self):
|
|
with mock.patch.object(self.job1, 'run') as run1,\
|
|
mock.patch.object(self.job2, 'run') as run2:
|
|
# job1 is configured as a readonly job so this should fail
|
|
self.assertRaises(
|
|
n_exc.ObjectNotFound,
|
|
self.housekeeper.run, self.context, 'test_job1',
|
|
readonly=False)
|
|
self.assertFalse(run1.called)
|
|
|
|
# job2 should run
|
|
self.housekeeper.run(self.context, 'test_job2', readonly=False)
|
|
run2.assert_called_with(mock.ANY, readonly=False)
|
|
|
|
def test_run_all_readonly(self):
|
|
with mock.patch.object(self.job1, 'run') as run1,\
|
|
mock.patch.object(self.job2, 'run') as run2:
|
|
self.housekeeper.run(self.context, 'all', readonly=True)
|
|
run1.assert_called_with(mock.ANY, readonly=True)
|
|
run2.assert_called_with(mock.ANY, readonly=True)
|
|
|
|
def test_run_all_readwrite(self):
|
|
with mock.patch.object(self.job1, 'run') as run1,\
|
|
mock.patch.object(self.job2, 'run') as run2:
|
|
self.housekeeper.run(self.context, 'all', readonly=False)
|
|
# job1 is configured as a readonly job so it was not called
|
|
self.assertFalse(run1.called)
|
|
# job2 should run
|
|
run2.assert_called_with(mock.ANY, readonly=False)
|
|
|
|
|
|
class TestHousekeeperReadOnly(TestHousekeeper):
|
|
|
|
def setUp(self):
|
|
super(TestHousekeeperReadOnly, self).setUp()
|
|
self.housekeeper.global_readonly = True
|
|
|
|
def test_run_job_readonly(self):
|
|
with mock.patch.object(self.job1, 'run') as run1,\
|
|
mock.patch.object(self.job2, 'run') as run2:
|
|
self.housekeeper.run(self.context, 'test_job1', readonly=True)
|
|
run1.assert_called_with(mock.ANY, readonly=True)
|
|
|
|
self.housekeeper.run(self.context, 'test_job2', readonly=True)
|
|
run2.assert_called_with(mock.ANY, readonly=True)
|
|
|
|
def test_run_job_readwrite(self):
|
|
with mock.patch.object(self.job1, 'run') as run1,\
|
|
mock.patch.object(self.job2, 'run') as run2:
|
|
|
|
# job1 is configured as a readonly job so this should fail
|
|
self.assertRaises(
|
|
n_exc.ObjectNotFound,
|
|
self.housekeeper.run, self.context, 'test_job1',
|
|
readonly=False)
|
|
self.assertFalse(run1.called)
|
|
|
|
# global readonly flag so job2 should also fail
|
|
self.assertRaises(
|
|
n_exc.ObjectNotFound,
|
|
self.housekeeper.run, self.context, 'test_job2',
|
|
readonly=False)
|
|
self.assertFalse(run2.called)
|
|
|
|
def test_run_all_readonly(self):
|
|
with mock.patch.object(self.job1, 'run') as run1,\
|
|
mock.patch.object(self.job2, 'run') as run2:
|
|
self.housekeeper.run(self.context, 'all', readonly=True)
|
|
run1.assert_called_with(mock.ANY, readonly=True)
|
|
run2.assert_called_with(mock.ANY, readonly=True)
|
|
|
|
def test_run_all_readwrite(self):
|
|
with mock.patch.object(self.job1, 'run') as run1,\
|
|
mock.patch.object(self.job2, 'run') as run2:
|
|
# global readonly flag so 'all' should fail
|
|
self.assertRaises(
|
|
n_exc.ObjectNotFound,
|
|
self.housekeeper.run, self.context, 'all',
|
|
readonly=False)
|
|
self.assertFalse(run1.called)
|
|
self.assertFalse(run2.called)
|