@@ -697,3 +697,202 @@ def test_arch_no_reboot_when_current(self):
697697
698698 host .refresh_from_db ()
699699 self .assertFalse (host .reboot_required )
700+
701+
702+ @override_settings (
703+ CELERY_TASK_ALWAYS_EAGER = True ,
704+ CACHES = {'default' : {'BACKEND' : 'django.core.cache.backends.locmem.LocMemCache' }}
705+ )
706+ class KernelPriorityTests (TestCase ):
707+ """Tests for kernel update priority filtering (backports)."""
708+
709+ def setUp (self ):
710+ self .m_arch = MachineArchitecture .objects .create (name = 'x86_64' )
711+ self .domain = Domain .objects .create (name = 'example.com' )
712+ self .os_release = OSRelease .objects .create (
713+ name = 'Debian 12' , codename = 'bookworm'
714+ )
715+ self .os_variant = OSVariant .objects .create (
716+ name = 'Debian GNU/Linux 12' , osrelease = self .os_release
717+ )
718+ self .pkg_arch = PackageArchitecture .objects .create (name = 'amd64' )
719+
720+ # installed kernel (from main repo)
721+ self .img_43_name = PackageName .objects .create (
722+ name = 'linux-image-6.1.0-43-amd64'
723+ )
724+ self .img_43 = Package .objects .create (
725+ name = self .img_43_name , arch = self .pkg_arch , epoch = '' ,
726+ version = '6.1.162-1' , release = '' , packagetype = 'D'
727+ )
728+
729+ # backports kernel (newer version)
730+ self .img_bp_name = PackageName .objects .create (
731+ name = 'linux-image-6.12.73+deb13-amd64'
732+ )
733+ self .img_bp = Package .objects .create (
734+ name = self .img_bp_name , arch = self .pkg_arch , epoch = '' ,
735+ version = '6.12.73-1' , release = '' , packagetype = 'D'
736+ )
737+
738+ # main repo (high priority)
739+ self .main_repo = Repository .objects .create (
740+ name = 'bookworm' , repotype = 'D' , arch = self .m_arch ,
741+ )
742+ self .main_mirror = Mirror .objects .create (
743+ repo = self .main_repo ,
744+ url = 'http://deb.debian.org/debian' ,
745+ )
746+ self .main_mirror .packages .add (self .img_43 )
747+
748+ # backports repo (low priority)
749+ self .bp_repo = Repository .objects .create (
750+ name = 'bookworm-backports' , repotype = 'D' , arch = self .m_arch ,
751+ )
752+ self .bp_mirror = Mirror .objects .create (
753+ repo = self .bp_repo ,
754+ url = 'http://deb.debian.org/debian-backports' ,
755+ )
756+ self .bp_mirror .packages .add (self .img_bp )
757+
758+ def _create_host (self , main_priority , bp_priority , host_repos_only = True ):
759+ host = Host .objects .create (
760+ hostname = 'debian.example.com' ,
761+ ipaddress = '192.168.1.80' ,
762+ osvariant = self .os_variant ,
763+ kernel = '6.1.0-43-amd64' ,
764+ arch = self .m_arch ,
765+ domain = self .domain ,
766+ lastreport = timezone .now (),
767+ host_repos_only = host_repos_only ,
768+ )
769+ host .packages .set ([self .img_43 ])
770+ HostRepo .objects .create (
771+ host = host , repo = self .main_repo ,
772+ enabled = True , priority = main_priority ,
773+ )
774+ HostRepo .objects .create (
775+ host = host , repo = self .bp_repo ,
776+ enabled = True , priority = bp_priority ,
777+ )
778+ return host
779+
780+ def test_deb_backports_lower_priority_no_update (self ):
781+ """DEB: backports kernel with lower priority should NOT be flagged."""
782+ host = self ._create_host (main_priority = 500 , bp_priority = 100 )
783+ repo_packages = Package .objects .filter (
784+ mirror__in = [self .main_mirror , self .bp_mirror ]
785+ )
786+ kernel_packages = host .packages .filter (
787+ name__name__startswith = 'linux-image-'
788+ )
789+
790+ host .find_kernel_updates (kernel_packages , repo_packages )
791+
792+ self .assertEqual (host .updates .count (), 0 )
793+
794+ def test_deb_backports_equal_priority_shows_update (self ):
795+ """DEB: backports kernel with equal priority SHOULD be flagged."""
796+ host = self ._create_host (main_priority = 500 , bp_priority = 500 )
797+ repo_packages = Package .objects .filter (
798+ mirror__in = [self .main_mirror , self .bp_mirror ]
799+ )
800+ kernel_packages = host .packages .filter (
801+ name__name__startswith = 'linux-image-'
802+ )
803+
804+ host .find_kernel_updates (kernel_packages , repo_packages )
805+
806+ self .assertEqual (host .updates .count (), 1 )
807+
808+ def test_deb_priority_zero_no_filtering (self ):
809+ """DEB: priority 0 (unset) means no filtering — backward compat."""
810+ host = self ._create_host (main_priority = 0 , bp_priority = 0 )
811+ repo_packages = Package .objects .filter (
812+ mirror__in = [self .main_mirror , self .bp_mirror ]
813+ )
814+ kernel_packages = host .packages .filter (
815+ name__name__startswith = 'linux-image-'
816+ )
817+
818+ host .find_kernel_updates (kernel_packages , repo_packages )
819+
820+ self .assertEqual (host .updates .count (), 1 )
821+
822+ def test_deb_host_repos_only_false_no_filtering (self ):
823+ """DEB: host_repos_only=False skips priority filtering entirely."""
824+ host = self ._create_host (
825+ main_priority = 500 , bp_priority = 100 , host_repos_only = False ,
826+ )
827+ repo_packages = Package .objects .filter (
828+ mirror__in = [self .main_mirror , self .bp_mirror ]
829+ )
830+ kernel_packages = host .packages .filter (
831+ name__name__startswith = 'linux-image-'
832+ )
833+
834+ host .find_kernel_updates (kernel_packages , repo_packages )
835+
836+ self .assertEqual (host .updates .count (), 1 )
837+
838+ def test_rpm_backports_lower_priority_no_update (self ):
839+ """RPM: kernel from lower-priority repo should NOT be flagged."""
840+ rpm_arch = PackageArchitecture .objects .create (name = 'x86_64_rpm' )
841+ kernel_name = PackageName .objects .create (name = 'kernel-core' )
842+ installed = Package .objects .create (
843+ name = kernel_name , arch = rpm_arch , epoch = '0' ,
844+ version = '5.14.0' , release = '362.el9' , packagetype = 'R'
845+ )
846+ newer = Package .objects .create (
847+ name = kernel_name , arch = rpm_arch , epoch = '0' ,
848+ version = '5.14.0' , release = '503.el9' , packagetype = 'R'
849+ )
850+
851+ base_repo = Repository .objects .create (
852+ name = 'baseos' , repotype = 'R' , arch = self .m_arch ,
853+ )
854+ base_mirror = Mirror .objects .create (
855+ repo = base_repo , url = 'http://repo.example.com/baseos' ,
856+ )
857+ base_mirror .packages .add (installed )
858+
859+ extra_repo = Repository .objects .create (
860+ name = 'extras' , repotype = 'R' , arch = self .m_arch ,
861+ )
862+ extra_mirror = Mirror .objects .create (
863+ repo = extra_repo , url = 'http://repo.example.com/extras' ,
864+ )
865+ extra_mirror .packages .add (newer )
866+
867+ os_release = OSRelease .objects .create (
868+ name = 'Rocky Linux 9' , codename = 'rl9'
869+ )
870+ os_variant = OSVariant .objects .create (
871+ name = 'Rocky Linux 9.4' , osrelease = os_release
872+ )
873+ host = Host .objects .create (
874+ hostname = 'rocky.example.com' ,
875+ ipaddress = '192.168.1.90' ,
876+ osvariant = os_variant ,
877+ kernel = '5.14.0-362.el9' ,
878+ arch = self .m_arch ,
879+ domain = self .domain ,
880+ lastreport = timezone .now (),
881+ host_repos_only = True ,
882+ )
883+ host .packages .set ([installed ])
884+ HostRepo .objects .create (
885+ host = host , repo = base_repo , enabled = True , priority = 500 ,
886+ )
887+ HostRepo .objects .create (
888+ host = host , repo = extra_repo , enabled = True , priority = 100 ,
889+ )
890+
891+ repo_packages = Package .objects .filter (
892+ mirror__in = [base_mirror , extra_mirror ]
893+ )
894+ kernel_packages = host .packages .filter (name = kernel_name )
895+
896+ host .find_kernel_updates (kernel_packages , repo_packages )
897+
898+ self .assertEqual (host .updates .count (), 0 )
0 commit comments