Skip to content

Commit

Permalink
tests: Add some integration tests for DBus
Browse files Browse the repository at this point in the history
This tests can be executed as autopkgtests. They cover netplan get, set
and apply.

There is a copy of test_dbus_config_get() in the file
integration/regressions.py that can be dropped once we adapt the
netplan.io package to run the new test set.
  • Loading branch information
daniloegea committed Mar 2, 2023
1 parent bb78759 commit a62e140
Show file tree
Hide file tree
Showing 2 changed files with 268 additions and 0 deletions.
214 changes: 214 additions & 0 deletions tests/integration/dbus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
#!/usr/bin/python3
#
# Integration tests for netplan-dbus
#
# These need to be run in a VM and do change the system
# configuration.
#
# Copyright (C) 2018-2023 Canonical, Ltd.
# Author: Mathieu Trudel-Lapierre <[email protected]>
# Author: Lukas Märdian <[email protected]>
# Author: Danilo Egea Gondolfo <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import json
import os
import signal
import sys
import subprocess
import unittest

from base import IntegrationTestsBase

BUSCTL_CONFIG = [
'busctl',
'-j',
'call',
'--system',
'io.netplan.Netplan',
'/io/netplan/Netplan',
'io.netplan.Netplan',
'Config'
]

BUSCTL_CONFIG_GET = [
'busctl',
'-j',
'call',
'--system',
'io.netplan.Netplan',
'PLACEHOLDER',
'io.netplan.Netplan.Config',
'Get'
]

BUSCTL_CONFIG_APPLY = [
'busctl',
'-j',
'call',
'--system',
'io.netplan.Netplan',
'PLACEHOLDER',
'io.netplan.Netplan.Config',
'Apply'
]


class _CommonTests():

def setUp(self):
super().setUp()

# If netplan-dbus is already running let's terminate it to
# be sure the process is not from a binary from an old package
# (before the installation of the one being tested)
cmd = ['ps', '-C', 'netplan-dbus', '-o', 'pid=']
out = subprocess.run(cmd, capture_output=True, universal_newlines=True)
if out.returncode == 0:
pid = out.stdout.strip()
os.kill(int(pid), signal.SIGTERM)

def test_dbus_config_get(self):
NETPLAN_YAML = '''network:
version: 2
ethernets:
%(nic)s:
dhcp4: true
'''

with open(self.config, 'w') as f:
f.write(NETPLAN_YAML % {'nic': self.dev_e_client})

out = subprocess.run(BUSCTL_CONFIG, capture_output=True, universal_newlines=True)

self.assertEqual(out.returncode, 0, msg=f"Busctl Config() failed with error: {out.stderr}")

out_dict = json.loads(out.stdout)
config_path = out_dict.get('data')[0]
self.assertNotEqual(config_path, "", msg="Got an empty response from DBUS")

# The path has the following format: /io/netplan/Netplan/config/WM6X01
BUSCTL_CONFIG_GET[5] = config_path

# Retrieving the config
out = subprocess.run(BUSCTL_CONFIG_GET, capture_output=True, universal_newlines=True)
self.assertEqual(out.returncode, 0, msg=f"Busctl Get() failed with error: {out.stderr}")

out_dict = json.loads(out.stdout)
netplan_data = out_dict.get('data')[0]

self.assertNotEqual(netplan_data, "", msg="Got an empty response from DBUS")
self.assertEqual(netplan_data, NETPLAN_YAML % {'nic': self.dev_e_client},
msg="The original YAML is different from the one returned by DBUS")

def test_dbus_config_set(self):
BUSCTL_CONFIG_SET = [
'busctl',
'-j',
'call',
'--system',
'io.netplan.Netplan',
'PLACEHOLDER',
'io.netplan.Netplan.Config',
'Set',
'ss',
'ethernets.%(nic)s.dhcp4=false' % {'nic': self.dev_e_client},
'',
]

NETPLAN_YAML_BEFORE = '''network:
version: 2
ethernets:
%(nic)s:
dhcp4: true
'''

NETPLAN_YAML_AFTER = '''network:
version: 2
ethernets:
%(nic)s:
dhcp4: false
'''
with open(self.config, 'w') as f:
f.write(NETPLAN_YAML_BEFORE % {'nic': self.dev_e_client})

out = subprocess.run(BUSCTL_CONFIG, capture_output=True, universal_newlines=True)
self.assertEqual(out.returncode, 0, msg=f"Busctl Config() failed with error: {out.stderr}")

out_dict = json.loads(out.stdout)
config_path = out_dict.get('data')[0]

self.assertNotEqual(config_path, "", msg="Got an empty response from DBUS")

# The path has the following format: /io/netplan/Netplan/config/WM6X01
BUSCTL_CONFIG_GET[5] = config_path
BUSCTL_CONFIG_SET[5] = config_path

# Changing the configuration
out = subprocess.run(BUSCTL_CONFIG_SET, capture_output=True, universal_newlines=True)
self.assertEqual(out.returncode, 0, msg=f"Busctl Set() failed with error: {out.stderr}")

out_dict = json.loads(out.stdout)
self.assertEqual(out_dict.get('data')[0], True, msg="Set command failed")

# Retrieving the configuration
out = subprocess.run(BUSCTL_CONFIG_GET, capture_output=True, universal_newlines=True)
self.assertEqual(out.returncode, 0, msg=f"Busctl Get() failed with error: {out.stderr}")

out_dict = json.loads(out.stdout)
netplan_data = out_dict.get('data')[0]

self.assertNotEqual(netplan_data, "", msg="Got an empty response from DBUS")
self.assertEqual(NETPLAN_YAML_AFTER % {'nic': self.dev_e_client},
netplan_data, msg="The final YAML is different than expected")

def test_dbus_config_apply(self):
NETPLAN_YAML = '''network:
version: 2
bridges:
br1234:
dhcp4: false
'''

self.addCleanup(subprocess.call, ['ip', 'link', 'delete', 'br1234'], stderr=subprocess.DEVNULL)

with open(self.config, 'w') as f:
f.write(NETPLAN_YAML)

out = subprocess.run(BUSCTL_CONFIG, capture_output=True, universal_newlines=True)
self.assertEqual(out.returncode, 0, msg=f"Busctl Config() failed with error: {out.stderr}")

out_dict = json.loads(out.stdout)
config_path = out_dict.get('data')[0]

self.assertNotEqual(config_path, "", msg="Got an empty response from DBUS")

# The path has the following format: /io/netplan/Netplan/config/WM6X01
BUSCTL_CONFIG_APPLY[5] = config_path

# Applying the configuration
out = subprocess.run(BUSCTL_CONFIG_APPLY, capture_output=True, universal_newlines=True)
self.assertEqual(out.returncode, 0, msg=f"Busctl Apply() failed with error: {out.stderr}")

out_dict = json.loads(out.stdout)
self.assertEqual(out_dict.get('data')[0], True, msg="Apply command failed")

self.assert_iface('br1234')


class TestNetworkd(IntegrationTestsBase, _CommonTests):
pass


unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))
54 changes: 54 additions & 0 deletions tests/integration/regressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import json
import os
import sys
import signal
Expand Down Expand Up @@ -145,4 +146,57 @@ class TestNetworkManager(IntegrationTestsBase, _CommonTests):
backend = 'NetworkManager'


class TestDbus(IntegrationTestsBase):
# This test can be dropped when tests/integration/dbus.py is
# integrated as an autopkgtest in the Debian package
def test_dbus_config_get_lp1997467(self):

NETPLAN_YAML = '''network:
version: 2
ethernets:
%(nic)s:
dhcp4: true
'''
BUSCTL_CONFIG = [
'busctl', '-j', 'call', '--system',
'io.netplan.Netplan', '/io/netplan/Netplan',
'io.netplan.Netplan', 'Config']

BUSCTL_CONFIG_GET = [
'busctl', '-j', 'call', '--system',
'io.netplan.Netplan', 'PLACEHOLDER',
'io.netplan.Netplan.Config', 'Get']

# Terminates netplan-dbus if it is running already
cmd = ['ps', '-C', 'netplan-dbus', '-o', 'pid=']
out = subprocess.run(cmd, capture_output=True, universal_newlines=True)
if out.returncode == 0:
pid = out.stdout.strip()
os.kill(int(pid), signal.SIGTERM)

with open(self.config, 'w') as f:
f.write(NETPLAN_YAML % {'nic': self.dev_e_client})

out = subprocess.run(BUSCTL_CONFIG, capture_output=True, universal_newlines=True)
self.assertEqual(out.returncode, 0, msg=f"Busctl Config() failed with error: {out.stderr}")

out_dict = json.loads(out.stdout)
config_path = out_dict.get('data')[0]
self.assertNotEqual(config_path, "", msg="Got an empty response from DBUS")

# The path has the following format: /io/netplan/Netplan/config/WM6X01
BUSCTL_CONFIG_GET[5] = config_path

# Retrieving the config
out = subprocess.run(BUSCTL_CONFIG_GET, capture_output=True, universal_newlines=True)
self.assertEqual(out.returncode, 0, msg=f"Busctl Get() failed with error: {out.stderr}")

out_dict = json.loads(out.stdout)
netplan_data = out_dict.get('data')[0]

self.assertNotEqual(netplan_data, "", msg="Got an empty response from DBUS")
self.assertEqual(netplan_data, NETPLAN_YAML % {'nic': self.dev_e_client},
msg="The original YAML is different from the one returned by DBUS")


unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))

0 comments on commit a62e140

Please sign in to comment.