diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..af78130 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,31 @@ +name: Unit tests + +env: + # This should match the default python_version build arg + PYTHON_VERSION: 3.8 + TOX_ENV: py38 + +on: + push: + branches: + - "*" + pull_request: + types: [opened, reopened] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python 3.x + uses: actions/setup-python@v1 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install tox + run: pip install tox + + - name: Run tests + run: tox -e ${{ env.TOX_ENV }} \ No newline at end of file diff --git a/blazarclient/command.py b/blazarclient/command.py index bc2eca4..927d1bb 100644 --- a/blazarclient/command.py +++ b/blazarclient/command.py @@ -329,7 +329,9 @@ def get_data(self, parsed_args): res_id = parsed_args.id resource_manager = getattr(blazar_client, self.resource) - data = resource_manager.get(res_id, detail=body['detail']) + data = resource_manager.get(res_id) + if body.get('detail'): + data.update(resource_manager.additional_details(res_id)) self.format_output_data(data) return list(zip(*sorted(data.items()))) diff --git a/blazarclient/tests/v1/shell_commands/test_leases.py b/blazarclient/tests/v1/shell_commands/test_leases.py index cdf1e8d..79b20b4 100644 --- a/blazarclient/tests/v1/shell_commands/test_leases.py +++ b/blazarclient/tests/v1/shell_commands/test_leases.py @@ -334,12 +334,33 @@ def test_show_lease(self): ] mock.seal(lease_manager) - args = argparse.Namespace(id=FIRST_LEASE) + args = argparse.Namespace(id=FIRST_LEASE, detail=False) expected = [('id',), (FIRST_LEASE,)] self.assertEqual(show_lease.get_data(args), expected) lease_manager.get.assert_called_once_with(FIRST_LEASE) + def test_show_lease_with_allocations(self): + show_lease, lease_manager = self.create_show_command() + lease_manager.get.return_value = {'id': FIRST_LEASE} + lease_manager.additional_details.return_value = { + 'hosts': [], + 'networks': [], + 'devices': [] + } + lease_manager.list.return_value = [ + {'id': FIRST_LEASE, 'name': 'first-lease'}, + {'id': SECOND_LEASE, 'name': 'second-lease'}, + ] + mock.seal(lease_manager) + + args = argparse.Namespace(id=FIRST_LEASE, detail=True) + expected = [('devices', 'hosts', 'id', 'networks',), ('', '', FIRST_LEASE, '',)] + + self.assertEqual(show_lease.get_data(args), expected) + lease_manager.get.assert_called_once_with(FIRST_LEASE) + lease_manager.additional_details.assert_called_once_with(FIRST_LEASE) + def test_show_lease_by_name(self): show_lease, lease_manager = self.create_show_command() lease_manager.list.return_value = [ @@ -349,13 +370,40 @@ def test_show_lease_by_name(self): lease_manager.get.return_value = {'id': SECOND_LEASE} mock.seal(lease_manager) - args = argparse.Namespace(id='second-lease') + args = argparse.Namespace(id='second-lease', detail=False) expected = [('id',), (SECOND_LEASE,)] self.assertEqual(show_lease.get_data(args), expected) lease_manager.list.assert_called_once_with() lease_manager.get.assert_called_once_with(SECOND_LEASE) + def test_show_lease_by_name_with_allocations(self): + show_lease, lease_manager = self.create_show_command() + lease_manager.list.return_value = [ + {'id': FIRST_LEASE, 'name': 'first-lease'}, + {'id': SECOND_LEASE, 'name': 'second-lease'}, + ] + lease_manager.get.return_value = {'id': SECOND_LEASE} + host1 = {'id': '101', 'hypervisor_hostname': 'host-1'} + lease_manager.additional_details.return_value = { + 'hosts': [host1], + 'networks': [], + 'devices': [] + } + import json + d = json.dumps(host1, indent=4) + mock.seal(lease_manager) + args = argparse.Namespace(id='second-lease', detail=True) + expected = [ + ('devices', 'hosts', 'id', 'networks',), + ('', d, SECOND_LEASE, '',) + ] + + self.assertEqual(show_lease.get_data(args), expected) + lease_manager.list.assert_called_once_with() + lease_manager.get.assert_called_once_with(SECOND_LEASE) + lease_manager.additional_details.assert_called_once_with(SECOND_LEASE) + class DeleteLeaseTestCase(tests.TestCase): diff --git a/blazarclient/v1/leases.py b/blazarclient/v1/leases.py index 1db10ad..791713e 100644 --- a/blazarclient/v1/leases.py +++ b/blazarclient/v1/leases.py @@ -39,17 +39,6 @@ def get(self, lease_id, detail=False): condition. """ resp, body = self.request_manager.get('/leases/%s' % lease_id) - if detail and body['lease']: - with ThreadPoolExecutor() as executor: - # Submit the calls - h_future = executor.submit(self.hosts_in_lease, lease_id) - n_future = executor.submit(self.networks_in_lease, lease_id) - d_future = executor.submit(self.devices_in_lease, lease_id) - - # Retrieve the results - body['lease']['hosts'] = h_future.result() - body['lease']['networks'] = n_future.result() - body['lease']['devices'] = d_future.result() return body['lease'] def update(self, lease_id, name=None, prolong_for=None, reduce_by=None, @@ -107,6 +96,20 @@ def list(self, sort_by=None): leases = sorted(leases, key=lambda l: l[sort_by]) return leases + def additional_details(self, lease_id): + allocations = {} + with ThreadPoolExecutor() as executor: + # Submit the calls + h_future = executor.submit(self.hosts_in_lease, lease_id) + n_future = executor.submit(self.networks_in_lease, lease_id) + d_future = executor.submit(self.devices_in_lease, lease_id) + + # Retrieve the results + allocations['hosts'] = h_future.result() + allocations['networks'] = n_future.result() + allocations['devices'] = d_future.result() + return allocations + def hosts_in_lease(self, lease_id): """List all hosts in lease""" resp, body = self.request_manager.get(f'/leases/{lease_id}/hosts')