File: //home/arjun/python-apt/tests/test_aptsources.py
#!/usr/bin/python3
import copy
import os
import tempfile
import unittest
import apt_pkg
import testcommon
import aptsources.distro
import aptsources.sourceslist
class TestAptSources(testcommon.TestCase):
def setUp(self):
testcommon.TestCase.setUp(self)
if apt_pkg.config["APT::Architecture"] not in ("i386", "amd64"):
apt_pkg.config.set("APT::Architecture", "i386")
apt_pkg.config.set("Dir::Etc", os.getcwd())
apt_pkg.config.set("Dir::Etc::sourceparts", tempfile.mkdtemp())
if os.path.exists("./build/data/templates"):
self.templates = os.path.abspath("./build/data/templates")
elif os.path.exists("../build/data/templates"):
self.templates = os.path.abspath("../build/data/templates")
else:
self.templates = "/usr/share/python-apt/templates/"
def tearDown(self):
aptsources.distro._OSRelease.OS_RELEASE_FILE = (
aptsources.distro._OSRelease.DEFAULT_OS_RELEASE_FILE
)
if "LSB_ETC_LSB_RELEASE" in os.environ:
del os.environ["LSB_ETC_LSB_RELEASE"]
def testIsMirror(self):
"""aptsources: Test mirror detection."""
yes = aptsources.sourceslist.is_mirror(
"http://archive.ubuntu.com", "http://de.archive.ubuntu.com"
)
no = aptsources.sourceslist.is_mirror(
"http://archive.ubuntu.com", "http://ftp.debian.org"
)
self.assertTrue(yes)
self.assertFalse(no)
def testSourcesListReading(self):
"""aptsources: Test sources.list parsing."""
apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list")
sources = aptsources.sourceslist.SourcesList(True, self.templates)
self.assertEqual(len(sources.list), 10)
# test load
sources.list = []
sources.load("data/aptsources/sources.list")
self.assertEqual(len(sources.list), 10)
def testSourcesListReading_deb822(self):
"""aptsources: Test sources.list parsing."""
apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d")
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
self.assertEqual(len(sources.list), 5)
# test load
sources.list = []
sources.load("data/aptsources/sources.list.d/main.sources")
self.assertEqual(len(sources.list), 5)
for entry in sources.list:
self.assertFalse(entry.invalid)
self.assertFalse(entry.disabled)
self.assertEqual(entry.types, ["deb"])
self.assertEqual(entry.type, "deb")
self.assertEqual(entry.uris, ["http://de.archive.ubuntu.com/ubuntu/"])
self.assertEqual(entry.uri, "http://de.archive.ubuntu.com/ubuntu/")
self.assertEqual(sources.list[0].comps, ["main"])
self.assertEqual(sources.list[1].comps, ["restricted"])
self.assertEqual(sources.list[2].comps, ["universe"])
self.assertEqual(sources.list[3].comps, ["main"])
self.assertEqual(sources.list[4].comps, ["main"])
for entry in sources.list[:-1]:
self.assertIsNone(entry.trusted)
self.assertTrue(sources.list[-1].trusted)
for entry in sources.list[:-2]:
self.assertEqual(entry.architectures, [])
self.assertEqual(entry.suites, ["edgy"])
self.assertEqual(entry.dist, "edgy")
for entry in sources.list[-2:]:
self.assertEqual(entry.suites, ["natty"])
self.assertEqual(entry.dist, "natty")
self.assertEqual(entry.architectures, ["amd64", "i386"])
def testSourcesListWriting_deb822(self):
"""aptsources: Test sources.list parsing."""
apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d")
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
with tempfile.TemporaryDirectory() as tmpdir:
for entry in sources.list:
entry.file = os.path.join(tmpdir, os.path.basename(entry.file))
sources.save()
maxDiff = self.maxDiff
self.maxDiff = None
for file in os.listdir("data/aptsources/sources.list.d"):
with open(os.path.join("data/aptsources/sources.list.d", file)) as a:
with open(os.path.join(tmpdir, file)) as b:
self.assertEqual(a.read(), b.read(), f"file {file}")
self.maxDiff = maxDiff
def testSourcesListAdding(self):
"""aptsources: Test additions to sources.list"""
apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list")
sources = aptsources.sourceslist.SourcesList(True, self.templates)
# test to add something that is already there (main)
before = copy.deepcopy(sources)
sources.add("deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["main"])
self.assertTrue(sources.list == before.list)
# test to add something that is already there (restricted)
before = copy.deepcopy(sources)
sources.add(
"deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["restricted"]
)
self.assertTrue(sources.list == before.list)
before = copy.deepcopy(sources)
sources.add(
"deb",
"http://de.archive.ubuntu.com/ubuntu/",
"natty",
["main"],
architectures=["amd64", "i386"],
)
self.assertTrue(sources.list == before.list)
# test to add something new: multiverse
sources.add(
"deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["multiverse"]
)
found = False
for entry in sources:
if (
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "edgy"
and "multiverse" in entry.comps
):
found = True
break
self.assertTrue(found)
# add a new natty entry without architecture specification
sources.add(
"deb", "http://de.archive.ubuntu.com/ubuntu/", "natty", ["multiverse"]
)
found = False
for entry in sources:
if (
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "natty"
and entry.architectures == []
and "multiverse" in entry.comps
):
found = True
break
self.assertTrue(found)
# Add universe to existing multi-arch line
sources.add(
"deb",
"http://de.archive.ubuntu.com/ubuntu/",
"natty",
["universe"],
architectures=["i386", "amd64"],
)
found = False
for entry in sources:
if (
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "natty"
and set(entry.architectures) == {"amd64", "i386"}
and set(entry.comps) == {"main", "universe"}
):
found = True
break
self.assertTrue(found)
# test to add something new: multiverse *and*
# something that is already there
before = copy.deepcopy(sources)
sources.add(
"deb",
"http://de.archive.ubuntu.com/ubuntu/",
"edgy",
["universe", "something"],
)
found_universe = 0
found_something = 0
for entry in sources:
if (
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "edgy"
):
for c in entry.comps:
if c == "universe":
found_universe += 1
if c == "something":
found_something += 1
# print "\n".join([s.str() for s in sources])
self.assertEqual(found_something, 1)
self.assertEqual(found_universe, 1)
def testSourcesListAdding_deb822(self):
"""aptsources: Test additions to sources.list"""
apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d")
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
# test to add something that is already there (main)
before = copy.deepcopy(sources)
sources.add("deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["main"])
self.assertEqual(sources.list, before.list)
# test to add something that is already there (restricted)
before = copy.deepcopy(sources)
sources.add(
"deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["restricted"]
)
self.assertTrue(sources.list == before.list)
before = copy.deepcopy(sources)
sources.add(
"deb",
"http://de.archive.ubuntu.com/ubuntu/",
"natty",
["main"],
architectures=["amd64", "i386"],
)
self.assertEqual(
[e.str() for e in sources.list], [e.str() for e in before.list]
)
# test to add something new: multiverse
sources.add(
"deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["multiverse"]
)
found = False
for entry in sources:
if (
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "edgy"
and "multiverse" in entry.comps
):
found = True
break
self.assertTrue(found)
# add a new natty entry without architecture specification
sources.add(
"deb", "http://de.archive.ubuntu.com/ubuntu/", "natty", ["multiverse"]
)
found = False
for entry in sources:
if (
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "natty"
and entry.architectures == []
and "multiverse" in entry.comps
):
found = True
break
self.assertTrue(found)
# Add universe to existing multi-arch line
sources.add(
"deb",
"http://de.archive.ubuntu.com/ubuntu/",
"natty",
["universe"],
architectures=["i386", "amd64"],
)
found = False
for entry in sources:
if (
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "natty"
and set(entry.architectures) == {"amd64", "i386"}
and set(entry.comps) == {"main", "universe"}
):
found = True
break
self.assertTrue(found)
# test to add something new: multiverse *and*
# something that is already there
before = copy.deepcopy(sources)
sources.add(
"deb",
"http://de.archive.ubuntu.com/ubuntu/",
"edgy",
["universe", "something"],
)
found_universe = 0
found_something = 0
for entry in sources:
if (
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "edgy"
):
for c in entry.comps:
if c == "universe":
found_universe += 1
if c == "something":
found_something += 1
# print "\n".join([s.str() for s in sources])
self.assertEqual(found_something, 1)
self.assertEqual(found_universe, 1)
def testAddingWithComment_deb822(self):
apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d")
self._commonTestAddingWithComment()
def testAddingWithComment_short(self):
apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list")
self._commonTestAddingWithComment()
def _commonTestAddingWithComment(self):
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
# test to add something that is already there (main); loses comment
before = copy.deepcopy(sources)
sources.add(
"deb",
"http://de.archive.ubuntu.com/ubuntu/",
"edgy",
["main"],
comment="this will be lost",
)
self.assertTrue(sources.list == before.list)
for entry in sources:
self.assertNotEqual(entry.comment, "this will be lost")
# test to add component to existing entry: multiverse; loses comment
sources.add(
"deb",
"http://de.archive.ubuntu.com/ubuntu/",
"edgy",
["multiverse"],
comment="this will be lost",
)
for entry in sources:
self.assertNotEqual(entry.comment, "this will be lost")
before = copy.deepcopy(sources)
# test to add entirely new entry; retains comment
sources.add(
"deb-src",
"http://de.archive.ubuntu.com/ubuntu/",
"edgy",
["main"],
comment="this will appear",
file=sources.list[0].file, # make sure we test the deb822 code path
)
self.assertNotEqual(sources.list, before.list)
self.assertEqual(len(sources.list), len(before.list) + 1)
found = False
for entry in sources:
if (
entry.type == "deb-src"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "edgy"
and entry.comment == "this will appear"
and "main" in entry.comps
):
found = True
break
self.assertTrue(found)
def testInsertion_deb822(self):
apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d")
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
# test to insert something that is already there (universe); does not
# move existing entry (remains at index 2)
before = copy.deepcopy(sources)
sources.add(
"deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["universe"], pos=0
)
self.assertTrue(sources.list == before.list)
entry = list(sources)[2]
self.assertEqual(entry.type, "deb")
self.assertEqual(entry.uri, "http://de.archive.ubuntu.com/ubuntu/")
self.assertEqual(entry.dist, "edgy")
self.assertIn("universe", entry.comps)
# test add component to existing entry: multiverse; does not move
# entry to which it is appended (remains at index 0)
sources.add(
"deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["multiverse"], pos=2
)
entry = list(sources)[0]
self.assertTrue(
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "edgy"
and {"main", "multiverse"} <= set(entry.comps)
)
# test to add entirely new entry; inserted at 0
sources.add(
"deb-src", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["main"], pos=0
)
entry = list(sources)[0]
self.assertTrue(
entry.type == "deb-src"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "edgy"
and "main" in entry.comps
)
def testInsertion(self):
apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list")
sources = aptsources.sourceslist.SourcesList(True, self.templates)
# test to insert something that is already there (universe); does not
# move existing entry (remains at index 2)
before = copy.deepcopy(sources)
sources.add(
"deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["universe"], pos=0
)
self.assertTrue(sources.list == before.list)
entry = list(sources)[5]
self.assertTrue(
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "edgy"
and "universe" in entry.comps
)
# test add component to existing entry: multiverse; does not move
# entry to which it is appended (remains at index 0)
sources.add(
"deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["multiverse"], pos=2
)
entry = list(sources)[1]
self.assertTrue(
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "edgy"
and {"main", "multiverse"} <= set(entry.comps)
)
# test to add entirely new entry; inserted at 0
sources.add(
"deb-src", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["main"], pos=0
)
entry = list(sources)[0]
self.assertTrue(
entry.type == "deb-src"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and entry.dist == "edgy"
and "main" in entry.comps
)
def testDuplication_short(self):
apt_pkg.config.set(
"Dir::Etc::sourcelist", "data/aptsources/sources.list.testDuplication"
)
return self.commonTestDuplication()
def testDuplication_deb822(self):
apt_pkg.config.set(
"Dir::Etc::sourceparts", "data/aptsources/sources.list.d.testDuplication"
)
return self.commonTestDuplication()
def commonTestDuplication(self):
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
test_url = "http://ppa.launchpad.net/me/myproject/ubuntu"
# test to add something that is already there (enabled)
before = copy.deepcopy(sources)
sources.add("deb", test_url, "xenial", ["main"])
self.assertEqual(sources.list, before.list)
# test to add something that is already there (disabled)
sources.add("# deb-src", test_url, "xenial", ["main"])
self.assertEqual(sources.list, before.list)
# test to enable something that is already there
sources.add("deb-src", test_url, "xenial", ["main"])
found = False
self.assertEqual(len(sources.list), 2)
for entry in sources:
if (
entry.type == "deb-src"
and not entry.disabled
and entry.uri == test_url
and entry.dist == "xenial"
and entry.architectures == []
and entry.comps == ["main"]
):
found = True
break
self.assertTrue(found)
def testMatcher_short(self):
"""aptsources: Test matcher"""
apt_pkg.config.set(
"Dir::Etc::sourcelist", "data/aptsources/" "sources.list.testDistribution"
)
return self.commonTestMatcher()
def testMatcher_deb822(self):
"""aptsources: Test matcher"""
apt_pkg.config.set(
"Dir::Etc::sourceparts",
"data/aptsources/" "sources.list.d.testDistribution",
)
return self.commonTestMatcher()
def commonTestMatcher(self):
"""aptsources: Test matcher"""
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
distro = aptsources.distro.get_distro(
id="Ubuntu",
codename="bionic",
description="Ubuntu 18.04 LTS",
release="18.04",
)
distro.get_sources(sources)
# test if all suits of the current distro were detected correctly
self.assertNotEqual(sources.list, [])
for s in sources:
if not s.template:
self.fail("source entry '%s' has no matcher" % s)
# Hack in a check for splitting of fields here.
if sources.list[-1].file.endswith(".sources"):
self.assertEqual(
sources.list[-1].uris, ["cdrom:[Ubuntu 8.04 _Hardy Heron_]"]
)
self.assertEqual(sources.list[-1].uri, "cdrom:[Ubuntu 8.04 _Hardy Heron_]")
def testMultiArch(self):
"""aptsources: Test multi-arch parsing"""
apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list")
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
assert not sources.list[8].invalid
assert sources.list[8].type == "deb"
assert sources.list[8].architectures == ["amd64", "i386"]
assert sources.list[8].uri == "http://de.archive.ubuntu.com/ubuntu/"
assert sources.list[8].dist == "natty"
assert sources.list[8].comps == ["main"]
assert sources.list[8].line.strip() == str(sources.list[8])
assert sources.list[8].trusted is None
def testMultiArch_deb822(self):
"""aptsources: Test multi-arch parsing"""
apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d")
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
assert not sources.list[3].invalid
assert sources.list[3].type == "deb"
assert sources.list[3].architectures == ["amd64", "i386"]
assert sources.list[3].uri == "http://de.archive.ubuntu.com/ubuntu/"
assert sources.list[3].dist == "natty"
assert sources.list[3].comps == ["main"]
self.assertEqual(sources.list[3].line.strip(), str(sources.list[3]))
self.assertIsNone(sources.list[3].trusted)
def testMultipleOptions(self):
"""aptsources: Test multi-arch parsing"""
apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list")
sources = aptsources.sourceslist.SourcesList(True, self.templates)
assert sources.list[9].invalid is False
assert sources.list[9].type == "deb"
assert sources.list[9].architectures == ["amd64", "i386"]
self.assertEqual(sources.list[9].uri, "http://de.archive.ubuntu.com/ubuntu/")
assert sources.list[9].dist == "natty"
assert sources.list[9].comps == ["main"]
assert sources.list[9].trusted
assert sources.list[9].line.strip() == str(sources.list[9])
def testMultipleOptions_deb822(self):
"""aptsources: Test multi-arch parsing"""
apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d")
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
assert sources.list[4].invalid is False
assert sources.list[4].type == "deb"
assert sources.list[4].architectures == ["amd64", "i386"]
self.assertEqual(sources.list[4].uri, "http://de.archive.ubuntu.com/ubuntu/")
assert sources.list[4].dist == "natty"
assert sources.list[4].comps == ["main"]
assert sources.list[4].trusted
assert sources.list[4].line.strip() == str(sources.list[4])
def test_enable_component(self):
target = "./data/aptsources/sources.list.enable_comps"
line = "deb http://archive.ubuntu.com/ubuntu lucid main\n"
with open(target, "w") as target_file:
target_file.write(line)
apt_pkg.config.set("Dir::Etc::sourcelist", target)
sources = aptsources.sourceslist.SourcesList(True, self.templates)
distro = aptsources.distro.get_distro(
id="Ubuntu", codename="lucid", release="10.04", description="Ubuntu 10.04"
)
# and get the sources
distro.get_sources(sources)
# test enable_component
comp = "multiverse"
distro.enable_component(comp)
comps = set()
for entry in sources:
comps = comps.union(set(entry.comps))
self.assertTrue("multiverse" in comps)
self.assertTrue("universe" in comps)
def test_enable_component_deb822(self):
target = (
apt_pkg.config.find_dir("dir::etc::sourceparts") + "enable_comps.sources"
)
line = "Types: deb\nURIs: http://archive.ubuntu.com/ubuntu\nSuites: lucid\nComponents: main\n"
with open(target, "w") as target_file:
target_file.write(line)
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
distro = aptsources.distro.get_distro(
id="Ubuntu", codename="lucid", release="10.04", description="Ubuntu 10.04"
)
# and get the sources
distro.get_sources(sources)
# test enable_component
comp = "multiverse"
distro.enable_component(comp)
comps = set()
for entry in sources:
comps = comps.union(set(entry.comps))
self.assertTrue("multiverse" in comps)
self.assertTrue("universe" in comps)
def test_enable_component_deb822_multi(self):
apt_pkg.config.set("Dir::Etc::sourcelist", "/dev/null")
target = (
apt_pkg.config.find_dir("dir::etc::sourceparts") + "enable_comps.sources"
)
line = "Types: deb\nURIs: http://archive.ubuntu.com/ubuntu\nSuites: lucid lucid-updates\nComponents: main\n"
with open(target, "w") as target_file:
target_file.write(line)
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
distro = aptsources.distro.get_distro(
id="Ubuntu", codename="lucid", release="10.04", description="Ubuntu 10.04"
)
# and get the sources
distro.get_sources(sources)
self.assertEqual(len(distro.main_sources), 1)
self.assertEqual(len(sources.list), 1)
# test enable_component
comp = "multiverse"
distro.enable_component(comp)
self.assertEqual(len(sources.list), 2) # split into two
self.assertEqual(
"Types: deb\n"
"URIs: http://archive.ubuntu.com/ubuntu\n"
"Suites: lucid\n"
"Components: main multiverse universe",
str(sources.list[0]),
)
self.assertEqual(
"Types: deb\n"
"URIs: http://archive.ubuntu.com/ubuntu\n"
"Suites: lucid-updates\n"
"Components: main multiverse universe",
str(sources.list[1]),
)
comps = set()
for entry in sources:
comps = comps.union(set(entry.comps))
self.assertTrue("multiverse" in comps)
self.assertTrue("universe" in comps)
sources.save()
self.assertEqual(
"Types: deb\n"
"URIs: http://archive.ubuntu.com/ubuntu\n"
"Suites: lucid lucid-updates\n"
"Components: main multiverse universe",
str(sources.list[0]),
)
def test_enable_component_deb822_multi_mixed_origin(self):
apt_pkg.config.set("Dir::Etc::sourcelist", "/dev/null")
target = (
apt_pkg.config.find_dir("dir::etc::sourceparts") + "enable_comps.sources"
)
line = "Types: deb\nURIs: http://archive.ubuntu.com/ubuntu http://example.com/\nSuites: lucid\nComponents: main\n"
with open(target, "w") as target_file:
target_file.write(line)
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
distro = aptsources.distro.get_distro(
id="Ubuntu", codename="lucid", release="10.04", description="Ubuntu 10.04"
)
# and get the sources
distro.get_sources(sources)
self.assertEqual(len(distro.main_sources), 2)
self.assertEqual(len(sources.list), 1)
# test enable_component
comp = "multiverse"
distro.enable_component(comp)
self.assertEqual(len(sources.list), 2) # split into two
self.assertEqual(
"Types: deb\n"
"URIs: http://archive.ubuntu.com/ubuntu\n"
"Suites: lucid\n"
"Components: main multiverse universe",
str(sources.list[0]),
)
self.assertEqual(
"Types: deb\n"
"URIs: http://example.com/\n"
"Suites: lucid\n"
"Components: main",
str(sources.list[1]),
)
sources.save()
self.assertEqual(
"Types: deb\n"
"URIs: http://archive.ubuntu.com/ubuntu\n"
"Suites: lucid\n"
"Components: main multiverse universe",
str(sources.list[0]),
)
self.assertEqual(
"Types: deb\n"
"URIs: http://example.com/\n"
"Suites: lucid\n"
"Components: main",
str(sources.list[1]),
)
def test_enable_component_deb822_multi_mixed_ultimate(self):
apt_pkg.config.set("Dir::Etc::sourcelist", "/dev/null")
target = (
apt_pkg.config.find_dir("dir::etc::sourceparts") + "enable_comps.sources"
)
line = "Types: deb deb-src\nURIs: http://archive.ubuntu.com/ubuntu http://example.com/\nSuites: lucid lucid-updates notalucid\nComponents: main\n"
with open(target, "w") as target_file:
target_file.write(line)
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
distro = aptsources.distro.get_distro(
id="Ubuntu", codename="lucid", release="10.04", description="Ubuntu 10.04"
)
# and get the sources
distro.get_sources(sources)
self.assertEqual(len(distro.main_sources), 1)
self.assertEqual(len(sources.list), 1)
self.assertEqual(len(sources.exploded_list()), 12)
# test enable_component
comp = "multiverse"
distro.enable_component(comp)
self.assertEqual(len(sources.list), 12) # split into two
expected = []
for typ in "deb", "deb-src":
for uri in "http://archive.ubuntu.com/ubuntu", "http://example.com/":
for suite in "lucid", "lucid-updates", "notalucid":
comps = "main multiverse universe"
# unofficial source ends up without enablement
if uri == "http://example.com/" or suite == "notalucid":
comps = "main"
expected.append(
f"Types: {typ}\n"
f"URIs: {uri}\n"
f"Suites: {suite}\n"
f"Components: {comps}"
)
self.maxDiff = None
self.assertEqual(expected, list(map(str, sources.list)))
sources.save()
expected = [
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu\n"
"Suites: lucid lucid-updates\n"
"Components: main multiverse universe",
# unofficial suite
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu http://example.com/\n"
"Suites: notalucid\n"
"Components: main",
# unofficial mirror, FIXME: We'd rather merge the notalucid into here
"Types: deb deb-src\n"
"URIs: http://example.com/\n"
"Suites: lucid lucid-updates\n"
"Components: main",
]
self.maxDiff = None
self.assertEqual(expected, list(map(str, sources.list)))
def test_deb822_explode(self):
apt_pkg.config.set("Dir::Etc::sourcelist", "/dev/null")
target = (
apt_pkg.config.find_dir("dir::etc::sourceparts") + "enable_comps.sources"
)
line = "Types: deb\nURIs: http://archive.ubuntu.com/ubuntu\nSuites: lucid\nComponents: main\n"
with open(target, "w") as target_file:
target_file.write(line)
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
self.assertEqual(len(sources.list), 1)
self.assertEqual(len(sources.exploded_list()), 1)
self.assertIsInstance(
sources.exploded_list()[0], aptsources.sourceslist.Deb822SourceEntry
)
sources.list[0].suites += ["fakesuite"]
self.assertEqual(len(sources.list), 1)
self.assertEqual(len(sources.exploded_list()), 2)
self.assertIsInstance(
sources.exploded_list()[0], aptsources.sourceslist.ExplodedDeb822SourceEntry
)
self.assertIsInstance(
sources.exploded_list()[1], aptsources.sourceslist.ExplodedDeb822SourceEntry
)
self.assertEqual(sources.list[0].suites, ["lucid", "fakesuite"])
sources.remove(sources.exploded_list()[1])
self.assertEqual(len(sources.list), 1)
self.assertEqual(len(sources.exploded_list()), 1)
self.assertEqual(sources.list[0].suites, ["lucid"])
sources.list[0].types += ["deb-src"]
self.assertEqual(len(sources.list), 1)
self.assertEqual(len(sources.exploded_list()), 2)
self.assertIsInstance(
sources.exploded_list()[0], aptsources.sourceslist.ExplodedDeb822SourceEntry
)
self.assertIsInstance(
sources.exploded_list()[1], aptsources.sourceslist.ExplodedDeb822SourceEntry
)
self.assertEqual(sources.list[0].types, ["deb", "deb-src"])
sources.remove(sources.exploded_list()[1])
self.assertEqual(len(sources.list), 1)
self.assertEqual(len(sources.exploded_list()), 1)
self.assertEqual(sources.list[0].types, ["deb"])
sources.list[0].uris += ["http://example.com"]
self.assertEqual(len(sources.list), 1)
self.assertEqual(len(sources.exploded_list()), 2)
self.assertIsInstance(
sources.exploded_list()[0], aptsources.sourceslist.ExplodedDeb822SourceEntry
)
self.assertIsInstance(
sources.exploded_list()[1], aptsources.sourceslist.ExplodedDeb822SourceEntry
)
self.assertEqual(
sources.list[0].uris,
["http://archive.ubuntu.com/ubuntu", "http://example.com"],
)
sources.remove(sources.exploded_list()[1])
self.assertEqual(len(sources.list), 1)
self.assertEqual(len(sources.exploded_list()), 1)
self.assertEqual(sources.list[0].uris, ["http://archive.ubuntu.com/ubuntu"])
# test setting attributes
sources.list[0].uris += ["http://example.com"]
with self.assertRaises(AttributeError):
sources.exploded_list()[0].types = ["does not work"]
with self.assertRaises(AttributeError):
sources.exploded_list()[0].uris = ["does not work"]
with self.assertRaises(AttributeError):
sources.exploded_list()[0].suites = ["does not work"]
with self.assertRaises(AttributeError):
sources.exploded_list()[0].doesnotexist = ["does not work"]
# test overriding
sources.exploded_list()[0].type = "faketype"
self.assertEqual(sources.list[0].type, "faketype")
self.assertEqual(sources.list[1].type, "deb")
sources.exploded_list()[0].type = "deb"
self.assertEqual(sources.list[0].type, "deb")
self.assertEqual(sources.list[1].type, "deb")
sources.save()
self.assertEqual(len(sources.list), 1)
def testDistribution_short(self):
"""aptsources: Test distribution detection."""
apt_pkg.config.set(
"Dir::Etc::sourcelist", "data/aptsources/" "sources.list.testDistribution"
)
return self.commonTestDistribution()
def testDistribution_deb822(self):
"""aptsources: Test distribution detection."""
apt_pkg.config.set(
"Dir::Etc::sourceparts",
"data/aptsources/" "sources.list.d.testDistribution",
)
return self.commonTestDistribution()
def commonTestDistribution(self):
"""aptsources: Test distribution detection."""
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
distro = aptsources.distro.get_distro(
id="Ubuntu",
codename="bionic",
description="Ubuntu 18.04 LTS",
release="18.04",
)
distro.get_sources(sources)
# test if all suits of the current distro were detected correctly
dist_templates = set()
for s in sources:
if s.template:
dist_templates.add(s.template.name)
# print dist_templates
for d in (
"hardy",
"hardy-security",
"hardy-updates",
"intrepid",
"hardy-backports",
):
self.assertTrue(d in dist_templates)
# test enable
comp = "restricted"
distro.enable_component(comp)
found = {}
for entry in sources:
if (
entry.type == "deb"
and entry.uri == "http://de.archive.ubuntu.com/ubuntu/"
and "edgy" in entry.dist
):
for c in entry.comps:
if c == comp:
if entry.dist not in found:
found[entry.dist] = 0
found[entry.dist] += 1
# print "".join([s.str() for s in sources])
for key in found:
self.assertEqual(found[key], 1)
# add a not-already available component
comp = "multiverse"
distro.enable_component(comp)
found = {}
for entry in sources:
if entry.type == "deb" and entry.template and entry.template.name == "edgy":
for c in entry.comps:
if c == comp:
if entry.dist not in found.has_key:
found[entry.dist] = 0
found[entry.dist] += 1
# print "".join([s.str() for s in sources])
for key in found:
self.assertEqual(found[key], 1)
@unittest.skip("lsb-release test broken when it was added")
def test_os_release_distribution(self):
"""os-release file can be read and is_like is populated accordingly"""
os.environ["LSB_ETC_LSB_RELEASE"] = os.path.abspath(
"./data/aptsources/lsb-release"
)
aptsources.distro._OSRelease.OS_RELEASE_FILE = os.path.abspath(
"./data/aptsources/os-release"
)
distro = aptsources.distro.get_distro()
# Everything but is_like comes from lsb_release, see TODO in
# get_distro.
self.assertEqual("Ubuntu", distro.id)
self.assertEqual("xenial", distro.codename)
self.assertEqual("Ubuntu 16.04.1 LTS", distro.description)
self.assertEqual("16.04", distro.release)
self.assertEqual(["ubuntu", "debian"], distro.is_like)
def test_enable_disabled_short(self):
"""LP: #1042916: Test enabling disabled entry."""
apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list")
return self.common_test_enable_disabled()
def test_enable_disabled_deb822(self):
"""LP: #1042916: Test enabling disabled entry."""
apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d")
return self.common_test_enable_disabled()
def common_test_enable_disabled(self):
"""LP: #1042916: Test enabling disabled entry."""
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
disabled = sources.add(
"deb",
"http://fi.archive.ubuntu.com/ubuntu/",
"precise",
["main"],
file=sources.list[0].file, # if we use deb822, enable deb822
)
disabled.set_enabled(False)
enabled = sources.add(
"deb",
"http://fi.archive.ubuntu.com/ubuntu/",
"precise",
["main"],
file=sources.list[0].file, # if we use deb822, enable deb822
)
self.assertEqual(disabled, enabled)
self.assertFalse(disabled.disabled)
def test_duplicate_uri_with_trailing_slash_short(self):
"""Test replacing entry with same uri except trailing slash"""
apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list")
return self.common_test_duplicate_uri_with_trailing_slash()
def test_duplicate_uri_with_trailing_slash_deb822(self):
"""Test replacing entry with same uri except trailing slash"""
apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d")
return self.common_test_duplicate_uri_with_trailing_slash()
def common_test_duplicate_uri_with_trailing_slash(self):
"""Test replacing entry with same uri except trailing slash"""
sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True)
line_wslash = "deb http://rslash.ubuntu.com/ubuntu/ precise main"
line_woslash = "deb http://rslash.ubuntu.com/ubuntu precise main"
entry_wslash = aptsources.sourceslist.SourceEntry(line_wslash)
entry_woslash = aptsources.sourceslist.SourceEntry(line_woslash)
self.assertEqual(entry_wslash, entry_woslash)
count = len(sources.list)
sourceslist_wslash = sources.add(
entry_wslash.type, entry_wslash.uri, entry_wslash.dist, entry_wslash.comps
)
self.assertEqual(count + 1, len(sources.list))
count = len(sources.list)
sourceslist_woslash = sources.add(
entry_woslash.type,
entry_woslash.uri,
entry_woslash.dist,
entry_woslash.comps,
)
self.assertEqual(count, len(sources.list))
self.assertEqual(sourceslist_wslash, sourceslist_woslash)
def test_deb822_distro_enable_disable_component(self):
"""Test enabling and disabling a component in the distro sources.
This ensures reasonable behavior when enabling and then disabling a component"""
with tempfile.NamedTemporaryFile("w", suffix=".sources") as file:
file.write(
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
)
file.flush()
apt_pkg.config.set("Dir::Etc::sourcelist", file.name)
sources = aptsources.sourceslist.SourcesList(
True, self.templates, deb822=True
)
distro = aptsources.distro.get_distro(
id="Ubuntu",
codename="noble",
description="Ubuntu 24.04 LTS",
release="24.04",
)
self.assertEqual(len(sources.list), 2)
distro.get_sources(sources)
distro.enable_component("multiverse")
sources.save()
with open(file.name) as readonly:
self.maxDiff = None
self.assertEqual(
readonly.read(),
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/\n"
"Suites: noble noble-updates\n"
"Components: main universe multiverse\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe multiverse\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
# Disable it again
# FIXME: The child entries will no longer be valid at this point, so we have to call
# get_sources(), but it's not clear whether this should be considered a bug -
# there may have been other changes rendering entries no longer valid that distro
# is holding on to.
distro.get_sources(sources)
distro.disable_component("multiverse")
sources.save()
with open(file.name) as readonly:
self.maxDiff = None
self.assertEqual(
readonly.read(),
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
# Disable universe as well
distro.get_sources(sources)
distro.disable_component("universe")
sources.save()
with open(file.name) as readonly:
self.maxDiff = None
self.assertEqual(
readonly.read(),
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/\n"
"Suites: noble noble-updates\n"
"Components: main\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
def test_deb822_distro_enable_disable_component_mixed_origin(self):
"""Test enabling and disabling a component in the distro sources, with mixed origin
Here we ensure that we still get idempotent behavior of disable after enable even if the
entry we were modifying also had a non-official repository in it."""
with tempfile.NamedTemporaryFile("w", suffix=".sources") as file:
file.write(
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
)
file.flush()
apt_pkg.config.set("Dir::Etc::sourcelist", file.name)
sources = aptsources.sourceslist.SourcesList(
True, self.templates, deb822=True
)
distro = aptsources.distro.get_distro(
id="Ubuntu",
codename="noble",
description="Ubuntu 24.04 LTS",
release="24.04",
)
self.assertEqual(len(sources.list), 2)
distro.get_sources(sources)
distro.enable_component("multiverse")
sources.save()
with open(file.name) as readonly:
self.maxDiff = None
self.assertEqual(
readonly.read(),
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/\n"
"Suites: noble noble-updates\n"
"Components: main universe multiverse\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe multiverse\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
# Disable it again
# FIXME: The child entries will no longer be valid at this point, so we have to call
# get_sources(), but it's not clear whether this should be considered a bug -
# there may have been other changes rendering entries no longer valid that distro
# is holding on to.
distro.get_sources(sources)
distro.disable_component("multiverse")
sources.save()
with open(file.name) as readonly:
self.maxDiff = None
self.assertEqual(
readonly.read(),
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
# Disable universe too. The behaviour here is interesting: Distro only disables
# universe for the official source, so we end up with the non-official source split out.
distro.get_sources(sources)
distro.disable_component("universe")
sources.save()
with open(file.name) as readonly:
self.maxDiff = None
self.assertEqual(
readonly.read(),
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/\n"
"Suites: noble noble-updates\n"
"Components: main\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# main archive\n" # note it keeps the comment on the split out child
"Types: deb deb-src\n"
"URIs: http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
def test_deb822_distro_enable_disable_child_source_mixed_origins(self):
"""Test enabling and disabling a child source (proposed) in the distro sources, with mixed origin
Here we ensure that we still get idempotent behavior of disable after enable even if the
entry we were modifying also had a non-official repository in it."""
with tempfile.NamedTemporaryFile("w", suffix=".sources") as file:
file.write(
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
)
file.flush()
apt_pkg.config.set("Dir::Etc::sourcelist", file.name)
sources = aptsources.sourceslist.SourcesList(
True, self.templates, deb822=True
)
distro = aptsources.distro.get_distro(
id="Ubuntu",
codename="noble",
description="Ubuntu 24.04 LTS",
release="24.04",
)
self.assertEqual(len(sources.list), 2)
distro.get_sources(sources)
distro.get_source_code = True
distro.add_source(dist="noble-proposed")
# FIXME: Component ordering is not stable right now
for entry in sources.list:
entry.comps = sorted(entry.comps)
sources.save()
with open(file.name) as readonly:
self.maxDiff = None
# FIXME: In an optimal world it would look like this
self.assertNotEqual(
readonly.read(),
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/\n"
"Suites: noble noble-updates noble-proposed\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
with open(file.name) as readonly:
self.maxDiff = None
# Sadly our merge algorithm does not always produce optimal merges, because it merges the unofficial entry first
self.assertEqual(
readonly.read(),
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/\n"
"Suites: noble-proposed\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
# Disable it again
# FIXME: The child entries will no longer be valid at this point, so we have to call
# get_sources(), but it's not clear whether this should be considered a bug -
# there may have been other changes rendering entries no longer valid that distro
# is holding on to.
distro.get_sources(sources)
for child in distro.child_sources + distro.source_code_sources:
if child.dist.endswith("proposed"):
sources.remove(child)
sources.save()
with open(file.name) as readonly:
self.maxDiff = None
self.assertEqual(
readonly.read(),
"# main archive\n"
"Types: deb deb-src\n"
"URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb deb-src\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
def test_deb822_distro_enable_disable_child_source_mixed_origins_no_source_code(
self,
):
"""Test enabling and disabling a child source (proposed) in the distro sources, with mixed origin
Here we ensure that we still get idempotent behavior of disable after enable even if the
entry we were modifying also had a non-official repository in it."""
with tempfile.NamedTemporaryFile("w", suffix=".sources") as file:
file.write(
"# main archive\n"
"Types: deb\n"
"URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
)
file.flush()
apt_pkg.config.set("Dir::Etc::sourcelist", file.name)
sources = aptsources.sourceslist.SourcesList(
True, self.templates, deb822=True
)
distro = aptsources.distro.get_distro(
id="Ubuntu",
codename="noble",
description="Ubuntu 24.04 LTS",
release="24.04",
)
self.assertEqual(len(sources.list), 2)
distro.get_sources(sources)
self.assertEqual(
[(s.type, s.uri, s.dist, s.comps) for s in distro.main_sources]
+ ["separator"]
+ [(s.type, s.uri, s.dist, s.comps) for s in distro.child_sources],
[
(
"deb",
"http://archive.ubuntu.com/ubuntu/",
"noble",
["main", "universe"],
),
"separator",
(
"deb",
"http://archive.ubuntu.com/ubuntu/",
"noble-updates",
["main", "universe"],
),
(
"deb",
"http://security.ubuntu.com/ubuntu/",
"noble-security",
["main", "universe"],
),
],
)
distro.add_source(dist="noble-proposed")
# FIXME: Component ordering is not stable right now
for entry in sources.list:
entry.comps = sorted(entry.comps)
sources.save()
with open(file.name) as readonly:
self.maxDiff = None
# FIXME: In an optimal world it would look like this
self.assertNotEqual(
readonly.read(),
"# main archive\n"
"Types: deb\n"
"URIs: http://archive.ubuntu.com/ubuntu/\n"
"Suites: noble noble-updates noble-proposed\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# main archive\n"
"Types: deb\n"
"URIs: http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
with open(file.name) as readonly:
self.maxDiff = None
# Sadly our merge algorithm does not always produce optimal merges, because it merges the unofficial entry first
self.assertEqual(
readonly.read(),
"# main archive\n"
"Types: deb\n"
"URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"Types: deb\n"
"URIs: http://archive.ubuntu.com/ubuntu/\n"
"Suites: noble-proposed\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
# Disable it again
# FIXME: The child entries will no longer be valid at this point, so we have to call
# get_sources(), but it's not clear whether this should be considered a bug -
# there may have been other changes rendering entries no longer valid that distro
# is holding on to.
distro.get_sources(sources)
for child in distro.child_sources + distro.source_code_sources:
if child.dist.endswith("proposed"):
sources.remove(child)
sources.save()
with open(file.name) as readonly:
self.maxDiff = None
self.assertEqual(
readonly.read(),
"# main archive\n"
"Types: deb\n"
"URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n"
"Suites: noble noble-updates\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n"
"\n"
"# security\n"
"Types: deb\n"
"URIs: http://security.ubuntu.com/ubuntu/\n"
"Suites: noble-security\n"
"Components: main universe\n"
"Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n",
)
if __name__ == "__main__":
os.chdir(os.path.dirname(__file__))
unittest.main()