@@ -1466,14 +1466,16 @@ class TestAutoUpdates(NoSubManCase):
14661466
14671467 def setUp (self ):
14681468 super ().setUp ()
1469- # not implemented for apt yet, only dnf
1470- self .supported_backend = "dnf" in self .backend
1469+ self .supported_backend = "dnf" in self .backend or self .backend == "apt"
14711470 if self .backend == "dnf5" :
14721471 self .timer_unit = "dnf5-automatic"
14731472 self .config = "/etc/dnf/dnf5-plugins/automatic.conf"
14741473 elif self .backend == "dnf4" :
14751474 self .timer_unit = "dnf-automatic-install"
14761475 self .config = "/etc/dnf/automatic.conf"
1476+ elif self .backend == "apt" :
1477+ self .timer_unit = "apt-daily-upgrade"
1478+ self .config = "/etc/apt/apt.conf.d/52unattended-upgrades-cockpit"
14771479
14781480 def closeSettings (self , browser : testlib .Browser ) -> None :
14791481 browser .click ("#automatic-updates-dialog button:contains('Save changes')" )
@@ -1524,9 +1526,34 @@ class TestAutoUpdates(NoSubManCase):
15241526 else :
15251527 self .assertNotIn ("ExecStartPost" , out )
15261528
1529+ def assertTimerApt (hour : str | None , dow : str | None ) -> None :
1530+ out = m .execute (f"systemctl --no-legend list-timers { self .timer_unit } .timer" )
1531+ if hour :
1532+ # don't test the minutes, due to RandomizedDelaySec=60m
1533+ self .assertRegex (out , f" { hour } :" )
1534+ else :
1535+ self .assertEqual (out , "" )
1536+ if dow :
1537+ self .assertRegex (out , r"^%s\s" % dow )
1538+ else :
1539+ # "every day" should not have a "LEFT" time > 1 day
1540+ self .assertNotIn (" day" , out )
1541+
1542+ # service should not run right away
1543+ self .assertEqual (m .execute (f"systemctl is-active { self .timer_unit } .service || true" ).strip (), "inactive" )
1544+
1545+ # automatic reboots should be enabled whenever timer is enabled
1546+ out = m .execute ("apt-config dump | grep 'Unattended-Upgrade::Automatic-Reboot \" true\" ;' || true" )
1547+ if hour :
1548+ self .assertIn ("Reboot" , out )
1549+ else :
1550+ self .assertNotIn ("Reboot" , out )
1551+
15271552 def assertTimer (hour : str | None , dow : str | None = None ) -> None :
15281553 if "dnf" in self .backend :
15291554 assertTimerDnf (hour , dow )
1555+ elif self .backend == "apt" :
1556+ assertTimerApt (hour , dow )
15301557 else :
15311558 raise NotImplementedError (self .backend )
15321559
@@ -1540,9 +1567,29 @@ class TestAutoUpdates(NoSubManCase):
15401567
15411568 self .assertIn (match , m .execute (f"grep upgrade_type { self .config } " ))
15421569
1570+ def assertTypeApt (type_ : str ) -> None :
1571+ stored_patterns = m .execute (f"grep origin= { self .config } " )
1572+ all_updates_pattern = '"origin=*";'
1573+
1574+ if type_ == "all" :
1575+ self .assertIn (all_updates_pattern , stored_patterns )
1576+ elif type_ == "security" :
1577+ self .assertNotIn (all_updates_pattern , stored_patterns )
1578+ else :
1579+ raise ValueError (type_ )
1580+
1581+ stable_pattern = "origin=Debian,codename=${distro_codename},label=Debian"
1582+ security_pattern = "origin=Debian,codename=${distro_codename}-security,label=Debian-Security"
1583+ security_alt_pattern = "origin=Debian,codename=${distro_codename},label=Debian-Security"
1584+ self .assertIn (stable_pattern , stored_patterns )
1585+ self .assertIn (security_pattern , stored_patterns )
1586+ self .assertIn (security_alt_pattern , stored_patterns )
1587+
15431588 def assertType (type_ : str ) -> None :
15441589 if "dnf" in self .backend :
15451590 assertTypeDnf (type_ )
1591+ elif self .backend == "apt" :
1592+ assertTypeApt (type_ )
15461593 else :
15471594 raise NotImplementedError (self .backend )
15481595
@@ -1620,7 +1667,7 @@ class TestAutoUpdates(NoSubManCase):
16201667 b .wait_in_text ("#autoupdates-settings" , "Disabled" )
16211668 assertTimer (None )
16221669
1623- if "dnf" in self .backend :
1670+ if "dnf" in self .backend or self . backend == "apt" :
16241671 b .click ("#autoupdates-settings button:contains('Edit')" )
16251672 b .wait_visible ("#automatic-updates-dialog" )
16261673 b .click ("#all-updates" )
@@ -1775,7 +1822,7 @@ class TestAutoUpdatesInstall(NoSubManCase):
17751822 b .wait_visible (".pf-v6-c-empty-state__title:contains('Update was successful')" )
17761823 b .click ("#ignore" )
17771824
1778- if "dnf" in self .backend :
1825+ if "dnf" in self .backend or self . backend == "apt" :
17791826 b .wait_in_text ("#autoupdates-settings" , "Not set up" )
17801827 b .wait_not_present ("#settings .pf-v6-c-alert" )
17811828 b .click ("#autoupdates-settings button:contains('Enable')" )
@@ -1822,6 +1869,21 @@ WantedBy=basic.target
18221869 elif self .backend == 'apt' :
18231870 m .execute ("dpkg -P unattended-upgrades" )
18241871
1872+ self .createPackage ('unattended-upgrades' , '1' , '1' , content = {
1873+ '/etc/apt/apt.conf.d/20auto-upgrades' : (
1874+ 'APT::Periodic::Update-Package-Lists "1";\n '
1875+ 'APT::Periodic::Unattended-Upgrade "1";\n '
1876+ ),
1877+ '/etc/apt/apt.conf.d/50unattended-upgrades' : (
1878+ 'Unattended-Upgrade::Origins-Pattern {\n '
1879+ '// Some Dummy Entries:\n '
1880+ ' "origin=Debian,codename=${distro_codename},label=Debian";\n '
1881+ ' "origin=Debian,codename=${distro_codename},label=Debian-Security";\n '
1882+ ' "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";\n '
1883+ '};\n '
1884+ ),
1885+ })
1886+
18251887 self .enableRepo ()
18261888
18271889 self .login_and_go ('/updates' )
0 commit comments