12130 install/update operations should always refresh publisher metadata (when allowed)
4419 misleading error message when pkg not found because refresh failed
10976 operations should report when refresh failed if appropriate
#!/usr/bin/python
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
import testutils
if __name__ == "__main__":
testutils.setup_environment("../../../proto")
import os
import pkg.catalog as catalog
import pkg.fmri as fmri
import pkg.portable as portable
import re
import shutil
import time
import unittest
import urllib
from stat import *
class TestPkgInstallBasics(testutils.SingleDepotTestCase):
# Only start/stop the depot once (instead of for every test)
persistent_depot = True
foo10 = """
open [email protected],5.11-0
close """
foo11 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=/lib
add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1 timestamp="20080731T024051Z"
add signature pkg.sig_bit1=sig_bit_val1 pkg.sig_bit2=sig_bit_val2
close """
foo11_timestamp = 1217472051
foo12 = """
open [email protected],5.11-0
add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
close """
afoo10 = """
open a/[email protected],5.11-0
close """
boring10 = """
open [email protected],5.11-0
close """
boring11 = """
open [email protected],5.11-0
close """
bar10 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
add dir mode=0755 owner=root group=bin path=/bin
add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
close """
bar11 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
add dir mode=0755 owner=root group=bin path=/bin
add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
close """
xfoo10 = """
open [email protected],5.11-0
close """
xbar10 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
add dir mode=0755 owner=root group=bin path=/bin
add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
close """
xbar11 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
add dir mode=0755 owner=root group=bin path=/bin
add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
close """
bar12 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
add dir mode=0755 owner=root group=bin path=/bin
add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
close """
baz10 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
add dir mode=0755 owner=root group=bin path=/bin
add file /tmp/baz mode=0555 owner=root group=bin path=/bin/baz
close """
deep10 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
add dir mode=0755 owner=root group=bin path=/bin
add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
close """
xdeep10 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
add dir mode=0755 owner=root group=bin path=/bin
add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
close """
ydeep10 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
add dir mode=0755 owner=root group=bin path=/bin
add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
close """
a6018_1 = """
open [email protected],5.11-0
close """
a6018_2 = """
open [email protected],5.11-0
close """
b6018_1 = """
open [email protected],5.11-0
add depend type=optional fmri=a6018@1
close """
misc_files = [ "/tmp/libc.so.1", "/tmp/cat", "/tmp/baz" ]
def setUp(self):
testutils.SingleDepotTestCase.setUp(self)
for p in self.misc_files:
f = open(p, "w")
# write the name of the file into the file, so that
# all files have differing contents
f.write(p)
f.close
self.debug("wrote %s" % p)
def tearDown(self):
testutils.SingleDepotTestCase.tearDown(self)
for p in self.misc_files:
os.remove(p)
def test_cli(self):
"""Test bad cli options"""
durl = self.dc.get_depot_url()
self.image_create(durl)
self.pkg("-@", exit=2)
self.pkg("-s status", exit=2)
self.pkg("-R status", exit=2)
self.pkg("install -@ foo", exit=2)
self.pkg("install -vq foo", exit=2)
self.pkg("install", exit=2)
self.pkg("install [email protected]", exit=1)
self.pkg("install pkg:/[email protected]", exit=1)
def test_basics_1(self):
""" Send empty package [email protected], install and uninstall """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo10)
self.image_create(durl)
self.pkg("list -a")
self.pkg("list", exit=1)
self.pkg("install foo")
self.pkg("list")
self.pkg("verify")
self.pkg("uninstall foo")
self.pkg("verify")
def test_basics_2(self):
""" Send package [email protected], containing a directory and a file,
install, search, and uninstall. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo10)
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.pkg("list -a")
self.pkg("install foo")
self.pkg("verify")
self.pkg("list")
self.pkg("search -l /lib/libc.so.1")
self.pkg("search -r /lib/libc.so.1")
self.pkg("search -l blah", exit=1)
self.pkg("search -r blah", exit=1)
# check to make sure timestamp was set to correct value
libc_path = os.path.join(self.get_img_path(), "lib/libc.so.1")
stat = os.stat(libc_path)
assert (stat[ST_MTIME] == self.foo11_timestamp)
# check that verify finds changes
now = time.time()
os.utime(libc_path, (now, now))
self.pkg("verify", exit=1)
self.pkg("uninstall foo")
self.pkg("verify")
self.pkg("list -a")
self.pkg("verify")
def test_basics_3(self):
""" Install [email protected], upgrade to [email protected], uninstall. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo10)
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.pkg("install [email protected]")
self.pkg("list [email protected]")
self.pkg("list [email protected]", exit=1)
self.pkg("install [email protected]")
self.pkg("list [email protected]")
self.pkg("list [email protected]", exit=1)
self.pkg("list foo@1")
self.pkg("verify")
self.pkg("uninstall foo")
self.pkg("list -a")
self.pkg("verify")
def test_basics_4(self):
""" Add [email protected], dependent on [email protected], install, uninstall. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo10)
self.pkgsend_bulk(durl, self.foo11)
self.pkgsend_bulk(durl, self.bar10)
self.image_create(durl)
self.pkg("list -a")
self.pkg("install [email protected]")
self.pkg("list")
self.pkg("verify")
self.pkg("uninstall -v bar foo")
# foo and bar should not be installed at this point
self.pkg("list bar", exit=1)
self.pkg("list foo", exit=1)
self.pkg("verify")
def test_basics_5(self):
""" Add [email protected], install [email protected]. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.xbar11)
self.image_create(durl)
self.pkg("install [email protected]", exit=1)
def test_basics_6(self):
""" Install [email protected], upgrade to [email protected].
Boring should be left alone, while
foo gets upgraded as needed"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.bar10)
self.pkgsend_bulk(durl, self.bar11)
self.pkgsend_bulk(durl, self.foo10)
self.pkgsend_bulk(durl, self.foo11)
self.pkgsend_bulk(durl, self.foo12)
self.pkgsend_bulk(durl, self.boring10)
self.pkgsend_bulk(durl, self.boring11)
self.image_create(durl)
self.pkg("install [email protected] [email protected] [email protected]")
self.pkg("list")
self.pkg("list [email protected] [email protected] [email protected]")
self.pkg("install -v [email protected]") # upgrade bar
self.pkg("list")
self.pkg("list [email protected] [email protected] [email protected]")
def test_image_upgrade(self):
""" Send package [email protected], dependent on [email protected]. Install [email protected].
List all packages. Upgrade image. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo10)
self.pkgsend_bulk(durl, self.foo11)
self.pkgsend_bulk(durl, self.bar10)
self.image_create(durl)
self.pkg("install [email protected]")
self.pkgsend_bulk(durl, self.foo12)
self.pkgsend_bulk(durl, self.bar11)
self.pkg("refresh")
self.pkg("contents -H")
self.pkg("list")
self.pkg("refresh")
self.pkg("list")
self.pkg("verify")
self.pkg("image-update -v")
self.pkg("verify")
self.pkg("list [email protected]")
self.pkg("list [email protected]")
self.pkg("uninstall bar foo")
self.pkg("verify")
def test_recursive_uninstall(self):
"""Install [email protected], dependent on [email protected], uninstall foo recursively."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo10)
self.pkgsend_bulk(durl, self.foo11)
self.pkgsend_bulk(durl, self.bar10)
self.image_create(durl)
self.pkg("install [email protected]")
# Here's the real part of the regression test;
# at this point foo and bar are installed, and
# bar depends on foo. foo and bar should both
# be removed by this action.
self.pkg("uninstall -vr foo")
self.pkg("list bar", exit=1)
self.pkg("list foo", exit=1)
def test_nonrecursive_dependent_uninstall(self):
"""Trying to remove a package that's a dependency of another
package should fail if the uninstall isn't recursive."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo10)
self.pkgsend_bulk(durl, self.bar10)
self.image_create(durl)
self.pkg("install [email protected]")
self.pkg("uninstall -v foo", exit=1)
self.pkg("list bar")
self.pkg("list foo")
def test_bug_1338(self):
""" Add [email protected], dependent on [email protected], install [email protected]. """
durl = self.dc.get_depot_url()
self.pkg("list -a")
self.pkgsend_bulk(durl, self.bar11)
self.image_create(durl)
self.pkg("install [email protected]", exit=1)
def test_bug_1338_2(self):
""" Add [email protected], dependent on [email protected], and [email protected], dependent
on [email protected], install [email protected] and [email protected]. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.bar11)
self.pkgsend_bulk(durl, self.baz10)
self.image_create(durl)
self.pkg("list -a")
self.pkg("install [email protected] [email protected]")
def test_bug_1338_3(self):
""" Add [email protected], [email protected]. [email protected] depends on [email protected] which
depends on [email protected], install [email protected]. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.xbar10)
self.pkgsend_bulk(durl, self.xdeep10)
self.image_create(durl)
self.pkg("install [email protected]", exit=1)
def test_bug_1338_4(self):
""" Add [email protected]. [email protected] depends on [email protected] which depends
on [email protected], install [email protected]. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.ydeep10)
self.image_create(durl)
self.pkg("install [email protected]", exit=1)
def test_bug_2795(self):
""" Try to install two versions of the same package """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.pkgsend_bulk(durl, self.foo12)
self.image_create(durl)
self.pkg("install [email protected] [email protected]", exit=1)
def test_bug_6018(self):
""" From original comment in bug report:
Consider a repository that contains:
a@1 and a@2
b@1 that contains an optional dependency on package a@1
If a@1 and b@1 are installed in an image, the "pkg image-update" command
produces the following output:
$ pkg image-update
No updates available for this image.
However, "pkg install a@2" works.
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.a6018_1)
self.pkgsend_bulk(durl, self.a6018_2)
self.pkgsend_bulk(durl, self.b6018_1)
self.image_create(durl)
self.pkg("install b6018@1 a6018@1")
self.pkg("image-update")
self.pkg("list b6018@1 a6018@2")
def test_install_matching(self):
""" Try to [un]install packages matching a pattern """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo10)
self.pkgsend_bulk(durl, self.bar10)
self.pkgsend_bulk(durl, self.baz10)
self.image_create(durl)
# don't specify versions here; we have many
# different versions of foo, bar & baz in repo
# when entire class is run w/ one repo instance.
# first case should fail since multiple patterns
# match the same pacakge
self.pkg("install 'ba*' 'b*'", exit=1)
self.pkg("install 'ba*'", exit=0)
self.pkg("list foo", exit=0)
self.pkg("list bar", exit=0)
self.pkg("list baz", exit=0)
self.pkg("uninstall 'b*' 'f*'")
def test_bug_3770(self):
""" Try to install two versions of the same package """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dc.stop()
self.pkg("install [email protected]", exit=1)
self.dc.start()
def test_bug_9929(self):
"""Make sure that we can uninstall/install a package that
already has its contents on disk."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.pkg("install foo")
self.dc.stop()
self.pkg("uninstall foo")
lr_path = os.path.join(self.img_path, "var","pkg","publisher",
"test", "last_refreshed")
os.unlink(lr_path)
self.pkg("install --no-refresh foo")
self.dc.start()
class TestPkgInstallAmbiguousPatterns(testutils.SingleDepotTestCase):
# An "ambiguous" package name pattern is one which, because of the
# pattern matching rules, might refer to more than one package. This
# may be as obvious as the pattern "SUNW*", but also like the pattern
# "foo", where "foo" and "a/foo" both exist in the catalog.
afoo10 = """
open a/[email protected],5.11-0
close """
bfoo10 = """
open b/[email protected],5.11-0
close """
bar10 = """
open [email protected],5.11-0
close """
foo10 = """
open [email protected],5.11-0
close """
foo11 = """
open [email protected],5.11-0
close """
anotherfoo11 = """
open another/[email protected],5.11-0
close """
depender10 = """
open [email protected],5.11-0
add depend type=require [email protected]
close """
depender11 = """
open [email protected],5.11-0
add depend type=require [email protected]
close """
def test_bug_4204(self):
"""Don't stack trace when printing a PlanCreationException with
"multiple_matches" populated (on uninstall)."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.afoo10)
self.pkgsend_bulk(durl, self.bfoo10)
self.pkgsend_bulk(durl, self.bar10)
self.image_create(durl)
self.pkg("install foo", exit=1)
self.pkg("install a/foo b/foo", exit=0)
self.pkg("list")
self.pkg("uninstall foo", exit=1)
self.pkg("uninstall a/foo b/foo", exit=0)
def test_bug_6874(self):
"""Don't stack trace when printing a PlanCreationException with
"multiple_matches" populated (on install and image-update)."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.afoo10)
self.pkgsend_bulk(durl, self.bfoo10)
self.image_create(durl)
self.pkg("install foo", exit=1)
def test_ambiguous_pattern_install(self):
"""An image-update should never get confused about an existing
package being part of an ambiguous set of package names."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo10)
self.image_create(durl)
self.pkg("install foo")
self.pkgsend_bulk(durl, self.anotherfoo11)
self.pkg("refresh")
self.pkg("image-update -v", exit=4)
def test_ambiguous_pattern_depend(self):
"""A dependency on a package should pull in an exact name
match."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.depender10)
self.pkgsend_bulk(durl, self.foo10)
self.image_create(durl)
self.pkg("install depender")
self.pkgsend_bulk(durl, self.foo11)
self.pkgsend_bulk(durl, self.anotherfoo11)
self.pkgsend_bulk(durl, self.depender11)
self.pkg("refresh")
self.pkg("install depender")
# Make sure that we didn't get other/foo from the dependency.
self.pkg("list another/foo", exit=1)
def test_non_ambiguous_fragment(self):
"""We should be able to refer to a package by its "basename", if
that component is unique."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.anotherfoo11)
self.image_create(durl)
# Right now, this is not exact, but still unambiguous
self.pkg("install foo")
# Create ambiguity
self.pkgsend_bulk(durl, self.foo11)
self.pkg("refresh")
# This is unambiguous, should succeed
self.pkg("install pkg:/foo")
# This is now ambiguous, should fail
self.pkg("install foo", exit=1)
class TestPkgInstallCircularDependencies(testutils.SingleDepotTestCase):
# Only start/stop the depot once (instead of for every test)
persistent_depot = True
pkg10 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/pkg2
close
"""
pkg20 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/pkg3
close
"""
pkg30 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/pkg1
close
"""
pkg11 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
close
"""
pkg21 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
close
"""
pkg31 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
close
"""
def test_unanchored_circular_dependencies(self):
""" check to make sure we can install
circular dependencies w/o versions
"""
# Send 1.0 versions of packages.
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.pkg10)
self.pkgsend_bulk(durl, self.pkg20)
self.pkgsend_bulk(durl, self.pkg30)
self.image_create(durl)
self.pkg("install pkg1")
self.pkg("list")
self.pkg("verify -v")
def test_anchored_circular_dependencies(self):
""" check to make sure we can install
circular dependencies w/ versions
"""
# Send 1.0 versions of packages.
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.pkg11)
self.pkgsend_bulk(durl, self.pkg21)
self.pkgsend_bulk(durl, self.pkg31)
self.image_create(durl)
self.pkg("install pkg1")
self.pkg("list")
self.pkg("verify -v")
class TestPkgInstallUpgrade(testutils.SingleDepotTestCase):
# Only start/stop the depot once (instead of for every test)
persistent_depot = True
incorp10 = """
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
"""
incorp20 = """
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
"""
incorp30 = """
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
close
"""
incorpA = """
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
"""
incorpB = """
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
"""
iridium10 = """
open [email protected],5.11-0
add depend fmri=pkg:/[email protected] type=require
close
"""
amber10 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=/lib
add dir mode=0755 owner=root group=bin path=/etc
add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
add link path=/lib/libc.symlink target=/lib/libc.so.1
add hardlink path=/lib/libc.hardlink target=/lib/libc.so.1
add file /tmp/amber1 mode=0444 owner=root group=bin path=/etc/amber1
add file /tmp/amber2 mode=0444 owner=root group=bin path=/etc/amber2
add license /tmp/copyright1 license=copyright
close
"""
brass10 = """
open [email protected],5.11-0
add depend fmri=pkg:/bronze type=require
close
"""
bronze10 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=/usr
add dir mode=0755 owner=root group=bin path=/usr/bin
add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
add link path=/usr/bin/jsh target=./sh
add hardlink path=/lib/libc.bronze target=/lib/libc.so.1
add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
add file /tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
add depend fmri=pkg:/[email protected] type=require
add license /tmp/copyright2 license=copyright
close
"""
amber20 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=/usr
add dir mode=0755 owner=root group=bin path=/usr/bin
add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
add link path=/lib/libc.symlink target=/lib/libc.so.1
add hardlink path=/lib/libc.amber target=/lib/libc.bronze
add hardlink path=/lib/libc.hardlink target=/lib/libc.so.1
add file /tmp/amber1 mode=0444 owner=root group=bin path=/etc/amber1
add file /tmp/amber2 mode=0444 owner=root group=bin path=/etc/bronze2
add depend fmri=pkg:/[email protected] type=require
add license /tmp/copyright2 license=copyright
close
"""
bronze20 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=/etc
add dir mode=0755 owner=root group=bin path=/lib
add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.bronze
add link path=/usr/bin/jsh target=./sh
add hardlink path=/lib/libc.bronze2.0.hardlink target=/lib/libc.so.1
add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/amber2
add license /tmp/copyright3 license=copyright
add file /tmp/bronzeA2 mode=0444 owner=root group=bin path=/A1/B2/C3/D4/E5/F6/bronzeA2
add depend fmri=pkg:/[email protected] type=require
close
"""
bronze30 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=/etc
add dir mode=0755 owner=root group=bin path=/lib
add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.bronze
add link path=/usr/bin/jsh target=./sh
add hardlink path=/lib/libc.bronze2.0.hardlink target=/lib/libc.so.1
add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/amber2
add license /tmp/copyright3 license=copyright
add file /tmp/bronzeA2 mode=0444 owner=root group=bin path=/A1/B2/C3/D4/E5/F6/bronzeA2
add depend fmri=pkg:/[email protected] type=require
close
"""
gold10 = """
open [email protected],5.11-0
add file /tmp/config1 mode=0644 owner=root group=bin path=etc/config1 preserve=true
close
"""
gold20 = """
open [email protected],5.11-0
add file /tmp/config2 mode=0644 owner=root group=bin path=etc/config2 original_name="gold:etc/config1" preserve=true
close
"""
gold30 = """
open [email protected],5.11-0
close
"""
silver10 = """
open [email protected],5.11-0
close
"""
silver20 = """
open [email protected],5.11-0
add file /tmp/config2 mode=0644 owner=root group=bin path=etc/config1 original_name="gold:etc/config1" preserve=true
close
"""
silver30 = """
open [email protected],5.11-0
add file /tmp/config2 mode=0644 owner=root group=bin path=etc/config2 original_name="gold:etc/config1" preserve=true
close
"""
iron10 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=etc
add file /tmp/config1 mode=0644 owner=root group=bin path=etc/foo
add hardlink path=etc/foo.link target=foo
close
"""
iron20 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=etc
add file /tmp/config2 mode=0644 owner=root group=bin path=etc/foo
add hardlink path=etc/foo.link target=foo
close
"""
concorp10 = """
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
"""
dricon1 = """
open dricon@1
add dir path=/tmp mode=755 owner=root group=root
add dir path=/etc mode=755 owner=root group=root
add file /tmp/dricon_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
add file /tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
close
"""
dricon2 = """
open dricon@2
add dir path=/tmp mode=755 owner=root group=root
add dir path=/etc mode=755 owner=root group=root
add file /tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
add file /tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
add driver name=zigit alias=pci8086,1234
close
"""
dricon3 = """
open dricon@3
add dir path=/tmp mode=755 owner=root group=root
add dir path=/etc mode=755 owner=root group=root
add file /tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
add file /tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
add driver name=zigit alias=pci8086,1234
add driver name=figit alias=pci8086,1234
close
"""
dripol1 = """
open dripol@1
add dir path=/tmp mode=755 owner=root group=root
add dir path=/etc mode=755 owner=root group=root
add dir path=/etc/security mode=755 owner=root group=root
add file /tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
add file /tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
add file /tmp/dripol1_dp path=/etc/security/device_policy mode=644 owner=root group=sys preserve=true
add driver name=frigit policy="read_priv_set=net_rawaccess write_priv_set=net_rawaccess"
close
"""
dripol2 = """
open dripol@2
add dir path=/tmp mode=755 owner=root group=root
add dir path=/etc mode=755 owner=root group=root
add dir path=/etc/security mode=755 owner=root group=root
add file /tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
add file /tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
add file /tmp/dripol1_dp path=/etc/security/device_policy mode=644 owner=root group=sys preserve=true
add driver name=frigit
close
"""
liveroot10 = """
open [email protected]
add dir path=/etc mode=755 owner=root group=root
add file /tmp/liveroot1 path=/etc/liveroot mode=644 owner=root group=sys reboot-needed=true
close
"""
liveroot20 = """
open [email protected]
add dir path=/etc mode=755 owner=root group=root
add file /tmp/liveroot2 path=/etc/liveroot mode=644 owner=root group=sys reboot-needed=true
close
"""
misc_files = [
"/tmp/amber1", "/tmp/amber2", "/tmp/bronzeA1", "/tmp/bronzeA2",
"/tmp/bronze1", "/tmp/bronze2",
"/tmp/copyright1", "/tmp/copyright2",
"/tmp/copyright3", "/tmp/copyright4",
"/tmp/libc.so.1", "/tmp/sh", "/tmp/config1", "/tmp/config2",
"/tmp/dricon_da", "/tmp/dricon2_da", "/tmp/dricon_n2m",
"/tmp/dripol1_dp", "/tmp/liveroot1", "/tmp/liveroot2"
]
misc_files_contents = {
"/tmp/dricon_da": """\
wigit "pci8086,1234"
wigit "pci8086,4321"
# someother "pci8086,1234"
foobar "pci8086,9999"
""",
"/tmp/dricon2_da": """\
zigit "pci8086,1234"
wigit "pci8086,4321"
# someother "pci8086,1234"
foobar "pci8086,9999"
""",
"/tmp/dricon_n2m": """\
wigit 1
foobar 2
""",
"/tmp/dripol1_dp": """\
* read_priv_set=none write_priv_set=none
"""
}
def setUp(self):
testutils.SingleDepotTestCase.setUp(self)
for p in self.misc_files:
f = open(p, "w")
# If no contents are specified, write the name of the
# file into the file, so that all files have differing
# contents
f.write(self.misc_files_contents.get(p, p))
f.close()
self.debug("wrote %s" % p)
def tearDown(self):
testutils.SingleDepotTestCase.tearDown(self)
for p in self.misc_files:
os.remove(p)
def test_incorp_install(self):
"""Make sure we don't round up packages we specify on
install"""
durl = self.dc.get_depot_url()
first_bronze = self.pkgsend_bulk(durl, self.bronze20)
self.pkgsend_bulk(durl, self.incorp20)
self.pkgsend_bulk(durl, self.amber10)
self.pkgsend_bulk(durl, self.bronze10)
self.pkgsend_bulk(durl, self.amber20)
self.pkgsend_bulk(durl, self.bronze20)
# create image
self.image_create(durl)
# install incorp2
self.pkg("install [email protected]")
# try to install version 1
self.pkg("install [email protected]", exit=1)
# install earliest version [email protected]
self.pkg("install %s" % first_bronze[0])
self.pkg("list -v %s" % first_bronze[0])
self.pkg("install [email protected]")
def test_upgrade1(self):
""" Upgrade torture test.
Send package [email protected], bronze1.0; install bronze1.0, which
should cause amber to also install.
Send 2.0 versions of packages which contains a lot of
complex transactions between amber and bronze, then do
an image-update, and try to check the results.
"""
# Send 1.0 versions of packages.
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.incorp10)
self.pkgsend_bulk(durl, self.amber10)
self.pkgsend_bulk(durl, self.bronze10)
#
# In version 2.0, several things happen:
#
# Amber and Bronze swap a file with each other in both directions.
# The dependency flips over (Amber now depends on Bronze)
# Amber and Bronze swap ownership of various directories.
#
# Bronze's 1.0 hardlink to amber's libc goes away and is replaced
# with a file of the same name. Amber hardlinks to that.
#
self.pkgsend_bulk(durl, self.incorp20)
self.pkgsend_bulk(durl, self.amber20)
self.pkgsend_bulk(durl, self.bronze20)
# create image and install version 1
self.image_create(durl)
self.pkg("install [email protected]")
self.pkg("install bronze")
self.pkg("list [email protected] [email protected]")
self.pkg("verify -v")
# demonstrate that [email protected] prevents package movement
self.pkg("install [email protected] [email protected]", exit=1)
# Now image-update to get new versions of amber and bronze
self.pkg("image-update")
# Try to verify that it worked.
self.pkg("list [email protected] [email protected]")
self.pkg("verify -v")
# make sure old implicit directories for bronzeA1 were removed
self.assert_(not os.path.isdir(os.path.join(self.get_img_path(), "A")))
# Remove packages
self.pkg("uninstall amber bronze")
self.pkg("verify -v")
# make sure all directories are gone save /var in test image
self.assert_(os.listdir(self.get_img_path()) == ["var"])
def test_upgrade2(self):
""" test incorporations:
1) install files that conflict w/ existing incorps
2) install package w/ dependencies that violate incorps
3) install incorp that violates existing incorp
4) install incorp that would force package backwards
"""
# Send all pkgs
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.incorp10)
self.pkgsend_bulk(durl, self.incorp20)
self.pkgsend_bulk(durl, self.incorp30)
self.pkgsend_bulk(durl, self.iridium10)
self.pkgsend_bulk(durl, self.concorp10)
self.pkgsend_bulk(durl, self.amber10)
self.pkgsend_bulk(durl, self.amber20)
self.pkgsend_bulk(durl, self.bronze10)
self.pkgsend_bulk(durl, self.bronze20)
self.pkgsend_bulk(durl, self.bronze30)
self.pkgsend_bulk(durl, self.brass10)
self.image_create(durl)
self.pkg("install [email protected]")
# install files that conflict w/ existing incorps
self.pkg("install [email protected]", exit=1)
# install package w/ dependencies that violate incorps
self.pkg("install [email protected]", exit=1)
# install package w/ unspecified dependency that pulls
# in bronze
self.pkg("install brass")
self.pkg("verify [email protected] [email protected]")
# attempt to install conflicting incorporation
self.pkg("install [email protected]", exit=1)
# attempt to force downgrade of package w/ older incorp
self.pkg("install [email protected]")
self.pkg("uninstall [email protected]")
self.pkg("install [email protected]", exit=1)
# upgrade pkg that loses incorp. deps. in new version
self.pkg("install [email protected]")
self.pkg("image-update")
self.pkg("list [email protected]")
def test_upgrade3(self):
""" test for editable files moving between packages or locations or both"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.silver10)
self.pkgsend_bulk(durl, self.silver20)
self.pkgsend_bulk(durl, self.silver30)
self.pkgsend_bulk(durl, self.gold10)
self.pkgsend_bulk(durl, self.gold20)
self.pkgsend_bulk(durl, self.gold30)
self.image_create(durl)
# first test - move an editable file between packages
self.pkg("install [email protected] [email protected]")
self.pkg("verify -v")
# modify config file
str = "this file has been modified 1"
file_path = "etc/config1"
self.file_append(file_path, str)
# make sure /etc/config1 contains correct string
self.file_contains(file_path, str)
# update packages
self.pkg("install [email protected] [email protected]")
self.pkg("verify -v")
# make sure /etc/config1 contains still correct string
self.file_contains(file_path, str)
self.pkg("uninstall silver gold")
# test file moving within package
self.pkg("install [email protected]")
self.pkg("verify -v")
# modify config file
str = "this file has been modified test 2"
file_path = "etc/config1"
self.file_append(file_path, str)
self.pkg("install [email protected]")
self.pkg("verify -v")
# make sure /etc/config2 contains correct string
file_path = "etc/config2"
self.file_contains(file_path, str)
self.pkg("uninstall gold")
self.pkg("verify -v")
# test movement in filesystem and across packages
self.pkg("install [email protected] [email protected]")
self.pkg("verify -v")
# modify config file
file_path = "etc/config1"
str = "this file has been modified test 3"
self.file_append(file_path, str)
self.file_contains(file_path, str)
self.pkg("install [email protected] [email protected]")
self.pkg("verify -v")
# make sure /etc/config2 now contains correct string
file_path = "etc/config2"
self.file_contains(file_path, str)
def test_upgrade4(self):
""" test to make sure hardlinks are correctly restored when file they point to is updated """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.iron10)
self.pkgsend_bulk(durl, self.iron20)
self.image_create(durl)
self.pkg("install [email protected]")
self.pkg("verify -v")
self.pkg("install [email protected]")
self.pkg("verify -v")
def test_upgrade_liveroot(self):
""" test to make sure upgrade of package fails if on live root
and reboot is needed"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.liveroot10)
self.pkgsend_bulk(durl, self.liveroot20)
self.image_create(durl)
self.pkg("--debug simulate_live_root=True install [email protected]")
self.pkg("verify -v")
self.pkg("--debug simulate_live_root=True install [email protected]", exit=5)
self.pkg("--debug simulate_live_root=True uninstall liveroot", exit=5)
# "break" liveroot@1
self.file_append("etc/liveroot", "this file has been changed")
self.pkg("--debug simulate_live_root=True fix liveroot", exit=5)
def test_upgrade_driver_conflicts(self):
"""Test to make sure driver_aliases conflicts don't cause
add_drv to fail."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.dricon1)
self.pkgsend_bulk(durl, self.dricon2)
self.pkgsend_bulk(durl, self.dricon3)
self.image_create(durl)
self.pkg("list -afv")
self.pkg("install dricon@1")
# This one should comment out the wigit entry in driver_aliases
self.pkg("install dricon@2")
da_contents = file(os.path.join(self.get_img_path(),
"etc/driver_aliases")).readlines()
self.assert_("# pkg(5): wigit \"pci8086,1234\"\n" in da_contents)
self.assert_("wigit \"pci8086,1234\"\n" not in da_contents)
self.assert_("wigit \"pci8086,4321\"\n" in da_contents)
self.assert_("zigit \"pci8086,1234\"\n" in da_contents)
# This one should fail
self.pkg("install dricon@3", exit=1)
def test_driver_policy_removal(self):
"""Test for bug #9568 - that removing a policy for a
driver where there is no minor node associated with it,
works successfully.
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.dripol1)
self.pkgsend_bulk(durl, self.dripol2)
self.image_create(durl)
self.pkg("list -afv")
# Should install the frigit driver with a policy.
self.pkg("install dripol@1")
# Check that there is a policy entry for this
# device in /etc/security/device_policy
dp_contents = file(os.path.join(self.get_img_path(),
"etc/security/device_policy")).readlines()
self.assert_("frigit:*\tread_priv_set=net_rawaccess\twrite_priv_set=net_rawaccess\n" in dp_contents)
# Should reinstall the frigit driver without a policy.
self.pkg("install dripol@2")
# Check that there is no longer a policy entry for this
# device in /etc/security/device_policy
dp_contents = file(os.path.join(self.get_img_path(),
"etc/security/device_policy")).readlines()
self.assert_("frigit:*\tread_priv_set=net_rawaccess\twrite_priv_set=net_rawaccess\n" not in dp_contents)
def file_append(self, path, string):
file_path = os.path.join(self.get_img_path(), path)
f = file(file_path, "a+")
f.write("\n%s\n" % string)
f.close
def file_contains(self, path, string):
file_path = os.path.join(self.get_img_path(), path)
f = file(file_path)
for line in f:
if string in line:
f.close()
break
else:
f.close()
self.assert_(False, "File %s does not contain %s" % (path, string))
class TestPkgInstallActions(testutils.SingleDepotTestCase):
# Only start/stop the depot once (instead of for every test)
persistent_depot = True
ftpusers_data = \
"""# ident "@(#)ftpusers 1.6 06/11/21 SMI"
#
# List of users denied access to the FTP server, see ftpusers(4).
#
root
bin
sys
adm
"""
group_data = \
"""root::0:
other::1:root
bin::2:root,daemon
sys::3:root,bin,adm
adm::4:root,daemon
"""
passwd_data = \
"""root:x:0:0::/root:/usr/bin/bash
daemon:x:1:1::/:
bin:x:2:2::/usr/bin:
sys:x:3:3::/:
adm:x:4:4:Admin:/var/adm:
"""
shadow_data = \
"""root:9EIfTNBp9elws:13817::::::
daemon:NP:6445::::::
bin:NP:6445::::::
sys:NP:6445::::::
adm:NP:6445::::::
"""
cat_data = " "
foo10 = """
open [email protected],5.11-0
close """
only_attr10 = """
open [email protected],5.11-0
add set name=foo value=bar
close """
only_depend10 = """
open [email protected],5.11-0
add depend type=require [email protected],5.11-0
close """
only_directory10 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=/bin
close """
only_driver10 = """
open [email protected],5.11-0
add driver name=zerg devlink="type=ddi_pseudo;name=zerg\\t\D"
close """
only_group10 = """
open [email protected],5.11-0
add group groupname=Kermit gid=28
close """
only_group_file10 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=Kermit path=/export/home/Kermit
close """
only_hardlink10 = """
open [email protected],5.11-0
add hardlink path=/cat.hardlink target=/cat
close """
only_legacy10 = """
open [email protected],5.11-0
add legacy arch=i386 category=system desc="GNU make - A utility used to build software (gmake) 3.81" hotline="Please contact your local service provider" name="gmake - GNU make" pkg=SUNWgmake vendor="Sun Microsystems, Inc." version=11.11.0,REV=2008.04.29.02.08
close """
only_link10 = """
open [email protected],5.11-0
add link path=/link target=/tmp/cat
close """
only_user10 = """
open [email protected],5.11-0
add user username=Kermit group=adm home-dir=/export/home/Kermit
close """
only_user_file10 = """
open [email protected],5.11-0
add dir mode=0755 owner=Kermit group=adm path=/export/home/Kermit
close """
empty_data = ""
misc_files = [ "empty", "ftpusers", "group", "passwd", "shadow", "cat" ]
testdata_dir = None
pkg_name_valid_chars = {
"never": " `~!@#$%^&*()=[{]}\\|;:\",<>?",
"always": "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
"after-first": "_/-.+",
"at-end": "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-.+",
}
def setUp(self):
testutils.SingleDepotTestCase.setUp(self)
tp = self.get_test_prefix()
self.testdata_dir = os.path.join(tp, "testdata")
os.mkdir(self.testdata_dir)
self.only_file10 = """
open [email protected],5.11-0
add file """ + self.testdata_dir + """/cat mode=0555 owner=root group=bin path=/cat
close """
self.only_license10 = """
open [email protected],5.11-0
add license """ + self.testdata_dir + """/cat license=copyright
close """
self.basics0 = """
open [email protected],5.11-0
add file """ + self.testdata_dir + """/passwd mode=0644 owner=root group=sys path=etc/passwd preserve=true
add file """ + self.testdata_dir + """/shadow mode=0400 owner=root group=sys path=etc/shadow preserve=true
add file """ + self.testdata_dir + """/group mode=0644 owner=root group=sys path=etc/group preserve=true
add file """ + self.testdata_dir + """/ftpusers mode=0644 owner=root group=sys path=etc/ftpd/ftpusers preserve=true
add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=etc/name_to_major preserve=true
add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=etc/driver_aliases preserve=true
add dir mode=0755 owner=root group=sys path=etc
add dir mode=0755 owner=root group=sys path=etc/ftpd
close """
self.basics1 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=lib
add dir mode=0755 owner=root group=sys path=var
add dir mode=0755 owner=root group=sys path=var/svc
add dir mode=0755 owner=root group=sys path=var/svc/manifest
add dir mode=0755 owner=root group=bin path=usr
add dir mode=0755 owner=root group=bin path=usr/local
close """
self.grouptest = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=Kermit path=/usr/Kermit
add file """ + self.testdata_dir + """/empty mode=0755 owner=root group=Kermit path=/usr/local/bin/do_group_nothing
add group groupname=lp gid=8
add group groupname=staff gid=10
add group groupname=Kermit
add depend fmri=pkg:/[email protected] type=require
close """
self.usertest10 = """
open [email protected],5.11-0
add dir mode=0755 owner=Kermit group=Kermit path=/export/home/Kermit
add file """ + self.testdata_dir + """/empty mode=0755 owner=Kermit group=Kermit path=/usr/local/bin/do_user_nothing
add depend fmri=pkg:/[email protected] type=require
add user username=Kermit group=Kermit home-dir=/export/home/Kermit group-list=lp group-list=staff
add depend fmri=pkg:/[email protected] type=require
add depend fmri=pkg:/[email protected] type=require
close """
self.usertest11 = """
open [email protected],5.11-0
add dir mode=0755 owner=Kermit group=Kermit path=/export/home/Kermit
add file """ + self.testdata_dir + """/empty mode=0755 owner=Kermit group=Kermit path=/usr/local/bin/do_user_nothing
add depend fmri=pkg:/[email protected] type=require
add user username=Kermit group=Kermit home-dir=/export/home/Kermit group-list=lp group-list=staff group-list=root ftpuser=false
add depend fmri=pkg:/[email protected] type=require
add depend fmri=pkg:/[email protected] type=require
close """
self.ugidtest = """
open [email protected],5.11-0
add user username=dummy group=root
add group groupname=dummy
close """
self.silver10 = """
open [email protected],5.11-0
add file """ + self.testdata_dir + """/empty mode=0755 owner=root group=root path=/usr/local/bin/silver
add depend fmri=pkg:/[email protected] type=require
add depend fmri=pkg:/[email protected] type=require
close """
self.silver20 = """
open [email protected],5.11-0
add file """ + self.testdata_dir + """/empty mode=0755 owner=Kermit group=Kermit path=/usr/local/bin/silver
add user username=Kermit group=Kermit home-dir=/export/home/Kermit group-list=lp group-list=staff
add depend fmri=pkg:/[email protected] type=require
add depend fmri=pkg:/[email protected] type=require
add depend fmri=pkg:/[email protected] type=require
close """
self.devicebase = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=root path=/tmp
add dir mode=0755 owner=root group=root path=/etc
add dir mode=0755 owner=root group=root path=/etc/security
add file """ + self.testdata_dir + """/empty mode=0600 owner=root group=root path=/etc/devlink.tab preserve=true
add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/etc/name_to_major preserve=true
add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/etc/driver_aliases preserve=true
add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/etc/driver_classes preserve=true
add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/etc/minor_perm preserve=true
add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=root path=/etc/security/device_policy preserve=true
add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/etc/security/extra_privs preserve=true
close
"""
self.devlink10 = """
open [email protected],5.11-0
add driver name=zerg devlink="type=ddi_pseudo;name=zerg\\t\D"
add driver name=borg devlink="type=ddi_pseudo;name=borg\\t\D" devlink="type=ddi_pseudo;name=warg\\t\D"
add depend type=require fmri=devicebase
close
"""
self.devlink20 = """
open [email protected],5.11-0
add driver name=zerg devlink="type=ddi_pseudo;name=zerg2\\t\D" devlink="type=ddi_pseudo;name=zorg\\t\D"
add driver name=borg devlink="type=ddi_pseudo;name=borg\\t\D" devlink="type=ddi_pseudo;name=zork\\t\D"
add depend type=require fmri=devicebase
close
"""
self.badhardlink1 = """
open [email protected],5.11-0
add hardlink path=foo target=bar
close
"""
self.badhardlink2 = """
open [email protected],5.11-0
add file """ + self.testdata_dir + """/cat mode=0555 owner=root group=bin path=/etc/motd
add hardlink path=foo target=/etc/motd
close
"""
self.dirshouldbelink = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=foo
add link path=foo target=bar
close
"""
for f in self.misc_files:
filename = os.path.join(self.testdata_dir, f)
file_handle = open(filename, 'wb')
try:
file_handle.write(eval("self.%s_data" % f))
finally:
file_handle.close()
def tearDown(self):
testutils.SingleDepotTestCase.tearDown(self)
if self.testdata_dir:
shutil.rmtree(self.testdata_dir)
def test_basics_0(self):
"""Send basic infrastructure, install and uninstall."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.basics0)
self.pkgsend_bulk(durl, self.basics1)
self.image_create(durl)
self.pkg("list -a")
self.pkg("list", exit=1)
self.pkg("install basics")
self.pkg("install basics1")
self.pkg("list")
self.pkg("verify")
self.pkg("uninstall basics basics1")
self.pkg("verify")
def test_grouptest(self):
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.basics0)
self.pkgsend_bulk(durl, self.basics1)
self.pkgsend_bulk(durl, self.grouptest)
self.image_create(durl)
self.pkg("install basics")
self.pkg("install basics1")
self.pkg("install grouptest")
self.pkg("verify")
self.pkg("uninstall grouptest")
self.pkg("verify")
def test_usertest(self):
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.basics0)
self.pkgsend_bulk(durl, self.basics1)
self.pkgsend_bulk(durl, self.grouptest)
self.pkgsend_bulk(durl, self.usertest10)
self.image_create(durl)
self.pkg("install basics")
self.pkg("install basics1")
self.pkg("install usertest")
self.pkg("verify")
self.pkg("contents -m usertest")
self.pkgsend_bulk(durl, self.usertest11)
self.pkg("refresh")
self.pkg("install usertest")
self.pkg("verify")
self.pkg("contents -m usertest")
self.pkg("uninstall usertest")
self.pkg("verify")
def test_minugid(self):
"""Ensure that an unspecified uid/gid results in the first
unused."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.ugidtest)
self.image_create(durl)
os.mkdir(os.path.join(self.get_img_path(), "etc"))
os.mkdir(os.path.join(self.get_img_path(), "etc/ftpd"))
for f in self.misc_files:
dir = "etc"
if f == "ftpusers":
dir = "etc/ftpd"
filename = os.path.join(self.get_img_path(), dir, f)
file_handle = open(filename, 'wb')
exec("%s_path = \"%s\"" % (f, filename))
try:
file_handle.write(eval("self.%s_data" % f))
finally:
file_handle.close()
self.pkg("install ugidtest")
passwd_file = file(passwd_path)
for line in passwd_file:
if line.startswith("dummy"):
self.assert_(line.startswith("dummy:x:5:"))
passwd_file.close()
group_file = file(group_path)
for line in group_file:
if line.startswith("dummy"):
self.assert_(line.startswith("dummy::5:"))
group_file.close()
def test_upgrade_with_user(self):
"""Ensure that we can add a user and change file ownership to
that user in the same delta (mysql tripped over this early on
in IPS development)."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.basics0)
self.pkgsend_bulk(durl, self.basics1)
self.pkgsend_bulk(durl, self.silver10)
self.pkgsend_bulk(durl, self.silver20)
self.pkgsend_bulk(durl, self.grouptest)
self.image_create(durl)
self.pkg("install [email protected]")
self.pkg("install [email protected]")
self.pkg("install [email protected]")
self.pkg("list [email protected]")
self.pkg("verify -v")
self.pkg("install [email protected]")
self.pkg("verify -v")
def test_invalid_open(self):
"""Send a invalid package definition (invalid fmri); expect
failure."""
durl = self.dc.get_depot_url()
for char in self.pkg_name_valid_chars["never"]:
invalid_name = "invalid%[email protected],5.11-0" % char
self.pkgsend(durl, "open '%s'" % invalid_name, exit=1)
for char in self.pkg_name_valid_chars["after-first"]:
invalid_name = "%[email protected],5.11-0" % char
if char == "-":
cmd = "open -- '%s'" % invalid_name
else:
cmd = "open '%s'" % invalid_name
self.pkgsend(durl, cmd, exit=1)
invalid_name = "invalid/%[email protected],5.11-0" % char
cmd = "open '%s'" % invalid_name
self.pkgsend(durl, cmd, exit=1)
def test_valid_open(self):
"""Send a invalid package definition (valid fmri); expect
success."""
durl = self.dc.get_depot_url()
for char in self.pkg_name_valid_chars["always"]:
valid_name = "%svalid%s/%spkg%[email protected],5.11-0" % (char,
char, char, char)
self.pkgsend(durl, "open '%s'" % valid_name)
self.pkgsend(durl, "close -A")
for char in self.pkg_name_valid_chars["after-first"]:
valid_name = "v%salid%[email protected],5.11-0" % (char, char)
self.pkgsend(durl, "open '%s'" % valid_name)
self.pkgsend(durl, "close -A")
for char in self.pkg_name_valid_chars["at-end"]:
valid_name = "validpkg%[email protected],5.11-0" % char
self.pkgsend(durl, "open '%s'" % valid_name)
self.pkgsend(durl, "close -A")
def test_devlink(self):
# driver actions are not valid except on OpenSolaris
if portable.util.get_canonical_os_name() != "sunos":
return
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.devicebase)
self.pkgsend_bulk(durl, self.devlink10)
self.pkgsend_bulk(durl, self.devlink20)
self.image_create(durl)
def readfile():
dlf = file(os.path.join(self.get_img_path(),
"etc/devlink.tab"))
dllines = dlf.readlines()
dlf.close()
return dllines
def writefile(dllines):
dlf = file(os.path.join(self.get_img_path(),
"etc/devlink.tab"), "w")
dlf.writelines(dllines)
dlf.close()
def assertContents(dllines, contents):
actual = re.findall("name=([^\t;]*)",
"\n".join(dllines), re.M)
self.assert_(set(actual) == set(contents))
# Install
self.pkg("install [email protected]")
self.pkg("verify -v")
dllines = readfile()
# Verify that three entries got added
self.assert_(len(dllines) == 3)
# Verify that the tab character got written correctly
self.assert_(dllines[0].find("\t") > 0)
# Upgrade
self.pkg("install [email protected]")
self.pkg("verify -v")
dllines = readfile()
# Verify that there are four entries now
self.assert_(len(dllines) == 4)
# Verify they are what they should be
assertContents(dllines, ["zerg2", "zorg", "borg", "zork"])
# Remove
self.pkg("uninstall devlinktest")
self.pkg("verify -v")
# Install again
self.pkg("install [email protected]")
# Diddle with it
dllines = readfile()
for i, line in enumerate(dllines):
if line.find("zerg") != -1:
dllines[i] = "type=ddi_pseudo;name=zippy\t\D\n"
writefile(dllines)
# Upgrade
self.pkg("install [email protected]")
# Verify that we spewed a message on upgrade
self.assert_(self.output.find("not found") != -1)
self.assert_(self.output.find("name=zerg") != -1)
# Verify the new set
dllines = readfile()
self.assert_(len(dllines) == 5)
assertContents(dllines,
["zerg2", "zorg", "borg", "zork", "zippy"])
self.pkg("uninstall devlinktest")
# Null out the "zippy" entry
writefile([])
# Install again
self.pkg("install [email protected]")
# Diddle with it
dllines = readfile()
for i, line in enumerate(dllines):
if line.find("zerg") != -1:
dllines[i] = "type=ddi_pseudo;name=zippy\t\D\n"
writefile(dllines)
# Remove
self.pkg("uninstall devlinktest")
# Verify that we spewed a message on removal
self.assert_(self.output.find("not found") != -1)
self.assert_(self.output.find("name=zerg") != -1)
# Verify that the one left behind was the one we overwrote.
dllines = readfile()
self.assert_(len(dllines) == 1)
assertContents(dllines, ["zippy"])
# Null out the "zippy" entry, but add the "zerg" entry
writefile(["type=ddi_pseudo;name=zerg\t\D\n"])
# Install ... again
self.pkg("install [email protected]")
# Make sure we didn't get a second zerg line
dllines = readfile()
self.failUnless(len(dllines) == 3, msg=dllines)
assertContents(dllines, ["zerg", "borg", "warg"])
# Now for the same test on upgrade
dllines.append("type=ddi_pseudo;name=zorg\t\D\n")
writefile(dllines)
self.pkg("install [email protected]")
dllines = readfile()
self.failUnless(len(dllines) == 4, msg=dllines)
assertContents(dllines, ["zerg2", "zorg", "borg", "zork"])
def test_uninstall_without_perms(self):
"""Test for bug 4569"""
durl = self.dc.get_depot_url()
pkg_list = [self.foo10, self.only_attr10, self.only_depend10,
self.only_directory10, self.only_file10,
self.only_group10, self.only_hardlink10, self.only_legacy10,
self.only_license10, self.only_link10, self.only_user10]
# driver actions are not valid except on OpenSolaris
if portable.util.get_canonical_os_name() == 'sunos':
pkg_list += [self.only_driver10]
self.pkgsend_bulk(durl, "".join(pkg_list) + self.devicebase + \
self.basics0 + self.basics1)
self.image_create(durl)
name_pat = re.compile("^\s+open\s+(\S+)\@.*$")
def __manually_check_deps(name, install=True, exit=0):
cmd = "install --no-refresh"
if not install:
cmd = "uninstall"
if name == "only_depend" and not install:
self.pkg("uninstall foo", exit=exit)
elif name == "only_driver":
self.pkg("%s devicebase" % cmd, exit=exit)
elif name == "only_group":
self.pkg("%s basics" % cmd, exit=exit)
elif name == "only_hardlink":
self.pkg("%s only_file" % cmd, exit=exit)
elif name == "only_user":
if install:
self.pkg("%s basics" % cmd, exit=exit)
self.pkg("%s only_group" % cmd, exit=exit)
else:
self.pkg("%s only_group" % cmd, exit=exit)
self.pkg("%s basics" % cmd, exit=exit)
for p in pkg_list:
name_mat = name_pat.match(p.splitlines()[1])
pname = name_mat.group(1)
__manually_check_deps(pname, exit=[0,4])
self.pkg("install --no-refresh %s" % pname,
su_wrap=True, exit=1)
self.pkg("install %s" % pname, su_wrap=True,
exit=1)
self.pkg("install --no-refresh %s" % pname)
self.pkg("uninstall %s" % pname, su_wrap=True,
exit=1)
self.pkg("uninstall %s" % pname)
__manually_check_deps(pname, install=False)
for p in pkg_list:
name_mat = name_pat.match(p.splitlines()[1])
pname = name_mat.group(1)
__manually_check_deps(pname, exit=[0,4])
self.pkg("install --no-refresh %s" % pname)
for p in pkg_list:
self.pkgsend_bulk(durl, p)
self.pkgsend_bulk(durl, self.devicebase + self.basics0 + \
self.basics1)
self.pkg("image-update --no-refresh", su_wrap=True, exit=4)
self.pkg("refresh")
self.pkg("image-update", su_wrap=True, exit=1)
# Should fail since user doesn't have permission to refresh
# publisher metadata.
self.pkg("refresh --full", su_wrap=True, exit=1)
self.pkg("refresh --full")
self.pkg("image-update --no-refresh", su_wrap=True,
exit=1)
self.pkg("image-update")
def test_bug_3222(self):
""" Verify that a timestamp of '0' for a passwd file will not
cause further package operations to fail. This can happen
when there are time synchronization issues within a virtual
environment or in other cases. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.basics0)
self.pkgsend_bulk(durl, self.only_user10)
self.pkgsend_bulk(durl, self.only_user_file10)
self.pkgsend_bulk(durl, self.only_group10)
self.pkgsend_bulk(durl, self.only_group_file10)
self.pkgsend_bulk(durl, self.grouptest)
self.pkgsend_bulk(durl, self.usertest10)
self.image_create(durl)
fname = os.path.join(self.get_img_path(), "etc", "passwd")
self.pkg("install basics")
# This should work regardless of whether a user is installed
# at the same time as the file in a package, or if the user is
# installed first and then files owned by that user are
# installed.
plists = [["grouptest", "usertest"],
["only_user", "only_user_file"],
["only_group", "only_group_file"]]
for plist in plists:
for pname in plist:
os.utime(fname, (0, 0))
self.pkg("install %s" % pname)
self.pkg("verify")
for pname in reversed(plist):
os.utime(fname, (0, 0))
self.pkg("uninstall %s" % pname)
self.pkg("verify")
def test_bad_hardlinks(self):
"""A couple of bogus hard link target tests."""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.badhardlink1)
self.pkgsend_bulk(durl, self.badhardlink2)
self.image_create(durl)
# A package which tries to install a hard link to a target that
# doesn't exist shouldn't stack trace, but exit sanely.
self.pkg("install badhardlink1", exit=1)
# A package which tries to install a hard link to a target
# specified as an absolute path should install that link
# relative to the image root.
self.pkg("install badhardlink2")
ino1 = os.stat(os.path.join(self.get_img_path(), "foo")).st_ino
ino2 = os.stat(os.path.join(self.get_img_path(), "etc/motd")).st_ino
self.assert_(ino1 == ino2)
def test_bad_links(self):
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.dirshouldbelink)
self.image_create(durl)
self.pkg("install dirshouldbelink", exit=1)
class TestDependencies(testutils.SingleDepotTestCase):
# Only start/stop the depot once (instead of for every test)
persistent_depot = True
pkg10 = """
open [email protected],5.11-0
add depend type=optional fmri=pkg:/pkg2
close
"""
pkg20 = """
open [email protected],5.11-0
close
"""
pkg11 = """
open [email protected],5.11-0
add depend type=optional fmri=pkg:/[email protected]
close
"""
pkg21 = """
open [email protected],5.11-0
close
"""
pkg30 = """
open [email protected],5.11-0
add depend type=require fmri=pkg:/[email protected]
close
"""
pkg40 = """
open [email protected],5.11-0
add depend type=exclude fmri=pkg:/[email protected]
close
"""
pkg50 = """
open [email protected],5.11-0
add depend type=exclude fmri=pkg:/[email protected]
add depend type=require fmri=pkg:/[email protected]
close
"""
pkg505 = """
open [email protected],5.11-0
add depend type=exclude fmri=pkg:/[email protected]
add depend type=require fmri=pkg:/[email protected]
close
"""
pkg51 = """
open [email protected],5.11-0
add depend type=exclude fmri=pkg:/[email protected]
add depend type=exclude fmri=pkg:/pkg2
add depend type=require fmri=pkg:/[email protected]
close
"""
pkg60 = """
open [email protected],5.11-0
add depend type=exclude fmri=pkg:/[email protected]
close
"""
pkg61 = """
open [email protected],5.11-0
close
"""
leaf_template = """
open pkg%s%s@%s,5.11-0
add depend type=require fmri=pkg:/%s_incorp
close
"""
leaf_expansion = [
("A","_0", "1.0", "A"),
("A","_1", "1.0", "A"),
("A","_2", "1.0", "A"),
("A","_3", "1.0", "A"),
("B","_0", "1.0", "B"),
("B","_1", "1.0", "B"),
("B","_2", "1.0", "B"),
("B","_3", "1.0", "B"),
("A","_0", "1.1", "A"),
("A","_1", "1.1", "A"),
("A","_2", "1.1", "A"),
("A","_3", "1.1", "A"),
("B","_0", "1.1", "B"),
("B","_1", "1.1", "B"),
("B","_2", "1.1", "B"),
("B","_3", "1.1", "B")
]
incorps = [ """
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
""",
"""
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
""",
"""
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
""",
"""
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
""",
"""
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
""",
"""
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
add depend type=incorporate fmri=pkg:/[email protected]
close
"""]
bug_7394_incorp = """
open [email protected],5.11-0
add depend type=incorporate fmri=pkg:/[email protected]
close
"""
def setUp(self):
testutils.SingleDepotTestCase.setUp(self)
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.pkg10)
self.pkgsend_bulk(durl, self.pkg20)
self.pkgsend_bulk(durl, self.pkg11)
self.pkgsend_bulk(durl, self.pkg21)
self.pkgsend_bulk(durl, self.pkg30)
self.pkgsend_bulk(durl, self.pkg40)
self.pkgsend_bulk(durl, self.pkg50)
self.pkgsend_bulk(durl, self.pkg505)
self.pkgsend_bulk(durl, self.pkg51)
self.pkgsend_bulk(durl, self.pkg60)
self.pkgsend_bulk(durl, self.pkg61)
self.pkgsend_bulk(durl, self.bug_7394_incorp)
for t in self.leaf_expansion:
self.pkgsend_bulk(durl, self.leaf_template % t)
for i in self.incorps:
self.pkgsend_bulk(durl, i)
def test_require_dependencies(self):
""" exercise require dependencies"""
durl = self.dc.get_depot_url()
self.image_create(durl)
self.pkg("install [email protected]")
self.pkg("verify [email protected]")
self.pkg("install [email protected]")
self.pkg("verify [email protected] [email protected]")
def test_exclude_dependencies(self):
""" exercise exclude dependencies """
durl = self.dc.get_depot_url()
self.image_create(durl)
# install pkg w/ exclude dep.
self.pkg("install [email protected]")
self.pkg("verify [email protected]")
# install pkg that is allowed by dep
self.pkg("install [email protected]")
self.pkg("verify [email protected]")
# try to install disallowed pkg
self.pkg("install [email protected]", exit=1)
self.pkg("uninstall '*'")
# install pkg
self.pkg("install [email protected]")
# try to install pkg exclude dep on already
# installed pkg
self.pkg("install [email protected]", exit=1)
self.pkg("uninstall '*'")
# install a package w/ both exclude
# and require dependencies
self.pkg("install pkg5")
self.pkg("verify [email protected] [email protected] ")
self.pkg("uninstall '*'")
# pick pkg to install that fits constraint
# of already installed pkg
self.pkg("install pkg2")
self.pkg("install pkg5")
self.pkg("verify [email protected] [email protected] pkg2")
self.pkg("uninstall '*'")
# install a package that requires updating
# existing package to avoid exclude
# dependency
self.pkg("install [email protected]")
self.pkg("install [email protected]")
self.pkg("verify [email protected] [email protected]")
self.pkg("uninstall '*'")
# try to install two incompatible pkgs
self.pkg("install [email protected] [email protected]", exit=1)
def test_optional_dependencies(self):
""" check to make sure that optional dependencies are enforced
"""
durl = self.dc.get_depot_url()
self.image_create(durl)
self.pkg("install [email protected]")
# pkg2 is optional, it should not have been installed
self.pkg("list pkg2", exit=1)
self.pkg("install [email protected]")
# this should install [email protected] and upgrade pkg2 to [email protected]
self.pkg("install pkg1")
self.pkg("list [email protected]")
self.pkg("uninstall pkg2")
self.pkg("list pkg2", exit=1)
# this should not install [email protected] because of the optional
# dependency in pkg1
self.pkg("list [email protected]")
self.pkg("install [email protected]", exit=1)
def test_incorporation_dependencies(self):
""" shake out incorporation dependencies """
durl = self.dc.get_depot_url()
self.image_create(durl)
self.pkg("list -a") # help w/ debugging
# simple pkg requiring controlling incorp
# should control pkgA_1 as well
self.pkg("install -v [email protected] pkgA_1")
self.pkg("list")
self.pkg("verify [email protected] [email protected] [email protected]")
self.pkg("image-update -v")
self.pkg("list [email protected] [email protected] [email protected]")
self.pkg("uninstall '*'")
# try nested incorporations
self.pkg("install -v [email protected] pkgA_0 pkgB_0")
self.pkg("list")
self.pkg("list [email protected] [email protected] [email protected] [email protected] [email protected]")
# try to break incorporation
self.pkg("install -v [email protected]", exit=1) # fixed by [email protected]
# try image update
self.pkg("image-update -v")
self.pkg("list [email protected] [email protected] [email protected] [email protected] [email protected]")
self.pkg("uninstall '*'")
# what happens when incorporation specified
# a package that isn't in the catalog
self.pkg("install bug_7394_incorp")
self.pkg("install pkg1", exit=1)
class TestMultipleDepots(testutils.ManyDepotTestCase):
# Only start/stop the depot once (instead of for every test)
persistent_depot = True
foo10 = """
open [email protected],5.11-0
close"""
bar10 = """
open [email protected],5.11-0
close"""
moo10 = """
open [email protected],5.11-0
close"""
quux10 = """
open [email protected],5.11-0
add depend type=optional [email protected]
close"""
baz10 = """
open [email protected],5.11-0
add depend type=require [email protected]
close"""
corge10 = """
open [email protected],5.11-0
close"""
optional10 = """
open [email protected],5.11-0
close"""
upgrade_p10 = """
open [email protected],5.11-0
close"""
upgrade_p11 = """
open [email protected],5.11-0
close"""
upgrade_np10 = """
open [email protected],5.11-0
close"""
upgrade_np11 = """
open [email protected],5.11-0
close"""
incorp_p10 = """
open [email protected],5.11-0
add depend type=incorporate [email protected]
close"""
incorp_p11 = """
open [email protected],5.11-0
add depend type=incorporate [email protected]
close"""
incorp_np10 = """
open [email protected],5.11-0
add depend type=incorporate [email protected]
close"""
incorp_np11 = """
open [email protected],5.11-0
add depend type=incorporate [email protected]
close"""
def setUp(self):
""" Start four depots.
depot 1 gets foo and moo, depot 2 gets foo and bar,
depot 3 is empty, depot 4 gets [email protected]
depot1 is mapped to publisher test1 (preferred)
depot2 is mapped to publisher test2
depot3 is not mapped during setUp
depot4 is not mapped during setUp"""
# Two depots are intentionally started for test2.
testutils.ManyDepotTestCase.setUp(self, ["test1", "test2",
"test3", "test2"])
durl1 = self.dcs[1].get_depot_url()
self.pkgsend_bulk(durl1, self.foo10 + self.moo10 + \
self.quux10 + self.optional10 + self.upgrade_p10 + \
self.upgrade_np11 + self.incorp_p10 + self.incorp_p11 + \
self.incorp_np10 + self.incorp_np11 + self.baz10 + \
self.corge10)
durl2 = self.dcs[2].get_depot_url()
self.pkgsend_bulk(durl2, self.foo10 + self.bar10 + \
self.upgrade_p11 + self.upgrade_np10 + self.corge10)
durl4 = self.dcs[4].get_depot_url()
self.pkgsend_bulk(durl4, self.upgrade_np11)
# Create image and hence primary publisher
self.image_create(durl1, prefix="test1")
# Create second publisher using depot #2
self.pkg("set-publisher -O " + durl2 + " test2")
def tearDown(self):
testutils.ManyDepotTestCase.tearDown(self)
def test_01_basics(self):
self.pkg("list -a")
# Install and uninstall moo (which is unique to depot 1)
self.pkg("install moo")
self.pkg("list")
self.pkg("uninstall moo")
# Install and uninstall bar (which is unique to depot 2)
self.pkg("install bar")
self.pkg("list")
self.pkg("uninstall bar")
# Install and uninstall foo (which is in both depots)
# In this case, we should select foo from depot 1, since
# it is preferred.
self.pkg("install foo")
self.pkg("list pkg://test1/foo")
self.pkg("uninstall foo")
def test_02_basics(self):
""" Test install from an explicit preferred publisher """
self.pkg("install pkg://test1/foo")
self.pkg("list foo")
self.pkg("list pkg://test1/foo")
self.pkg("uninstall foo")
def test_03_basics(self):
""" Test install from an explicit non-preferred publisher """
self.pkg("install pkg://test2/foo")
self.pkg("list foo")
self.pkg("list pkg://test2/foo")
self.pkg("uninstall foo")
def test_04_upgrade_preferred_to_non_preferred(self):
"""Install a package from the preferred publisher, and then
upgrade it, failing to implicitly switching to a non-preferred
publisher and then managing it explicitly"""
self.pkg("list -a upgrade-p")
self.pkg("install [email protected]")
self.pkg("install [email protected]", exit=1)
self.pkg("install pkg://test2/[email protected]")
self.pkg("uninstall upgrade-p")
def test_05_upgrade_non_preferred_to_preferred(self):
"""Install a package from a non-preferred publisher, and then
try to upgrade it, failing to implicitly switchto the preferred
publisher and then succeed doing it explicitly."""
self.pkg("list -a upgrade-np")
self.pkg("install [email protected]")
self.pkg("install [email protected]", exit=1)
self.pkg("install pkg://test1/[email protected]")
self.pkg("uninstall upgrade-np")
def test_06_upgrade_preferred_to_non_preferred_incorporated(self):
"""Install a package from the preferred publisher, and then
upgrade it, failing to implicitly switching to a non-preferred
publisher, when the package is constrained by an
incorporation, and then succeed when doing so explicitly"""
self.pkg("list -a upgrade-p incorp-p")
self.pkg("install [email protected]")
self.pkg("install upgrade-p")
self.pkg("install [email protected]", exit=1)
self.pkg("install [email protected] pkg://test2/[email protected]")
self.pkg("list [email protected]")
self.pkg("uninstall '*'")
def test_07_upgrade_non_preferred_to_preferred_incorporated(self):
"""Install a package from the preferred publisher, and then
upgrade it, implicitly switching to a non-preferred
publisher, when the package is constrained by an
incorporation."""
self.pkg("list", exit=1)
self.pkg("list -a upgrade-np incorp-np")
self.pkg("install [email protected]")
self.pkg("install upgrade-np", exit=1)
self.pkg("uninstall '*'")
def test_08_install_repository_access(self):
"""Verify that packages can still be installed from a repository
even when any of the other repositories are not reachable and
--no-refresh is used."""
# Change the second publisher to point to an unreachable URI.
self.pkg("set-publisher --no-refresh -O http://test.invalid7 test2")
# Verify that no packages are installed.
self.pkg("list", exit=1)
# Verify moo can not be installed (as only depot1 has it) since
# test2 cannot be reached (and needs a refresh).
self.pkg("install moo", exit=1)
# Verify moo can be installed (as only depot1 has it) even though
# test2 cannot be reached (and needs a refresh) if --no-refresh
# is used.
self.pkg("install --no-refresh moo")
self.pkg("uninstall moo")
# Reset the test2 publisher.
durl2 = self.dcs[2].get_depot_url()
self.pkg("set-publisher -O %s test2" % durl2)
# Install v1.0 of upgrade-np from test2 to prepare for
# image-update.
self.pkg("install [email protected]")
# Set test1 to point to an unreachable URI.
self.pkg("set-publisher --no-refresh -O http://test.invalid7 test1")
# Set test2 so that upgrade-np has a new version available
# even though test1's repository is not accessible.
durl4 = self.dcs[4].get_depot_url()
self.pkg("set-publisher -O %s test2" % durl4)
# Verify image-update does not work since test1 is unreachable
# even though [email protected] is available from test2.
self.pkg("image-update", exit=1)
# Verify image-update works even though test1 is unreachable
# since [email protected] is available from test2 if --no-refresh
# is used.
self.pkg("image-update --no-refresh")
# Now reset everything for the next test.
self.pkg("uninstall upgrade-np")
durl1 = self.dcs[1].get_depot_url()
self.pkg("set-publisher --no-refresh -O %s test1" % durl1)
self.pkg("set-publisher -O %s test2" % durl2)
def test_09_uninstall_from_wrong_publisher(self):
"""Install a package from a publisher and try to remove it
using a different publisher name; this should fail."""
self.pkg("install foo")
self.pkg("uninstall pkg://test2/foo", exit=1)
# Check to make sure that uninstalling using the explicit
# publisher works
self.pkg("uninstall pkg://test1/foo")
def test_10_install_after_publisher_removal(self):
"""Install a package from a publisher that has an optional
dependency; then change the preferred publisher and remove the
original publisher and then verify that installing the package
again succeeds since it is essentially a no-op."""
self.pkg("install [email protected]")
self.pkg("set-publisher -P test2")
self.pkg("unset-publisher test1")
self.pkg("list")
# Attempting to install an already installed package should
# be a no-op even if the corresponding publisher no longer
# exists.
self.pkg("install [email protected]", exit=4)
# Image update should work if we don't see the optional dependency
self.pkg("image-update", exit=4)
# Add back the installed package's publisher, but using a
# a repository with an empty catalog. After that, attempt to
# install the package again, which should succeed even though
# the fmri is no longer in the publisher's catalog.
self.pkg("set-publisher -O %s test1" % \
self.dcs[3].get_depot_url())
self.pkg("install [email protected]", exit=4)
self.pkg("info [email protected]")
self.pkg("unset-publisher test1")
# Add a new publisher, using the installed package publisher's
# repository and add back the installed package's publisher, but
# using a repository with an empty catalog. After that, attempt
# to install the package again, which should succeed even though
# the package's installed publisher is known, but doesn't have
# the package's fmri in its catalog, but the package's fmri is
# in a different publisher's catalog.
self.pkg("set-publisher -O %s test3" % \
self.dcs[1].get_depot_url())
self.pkg("set-publisher -O %s test1" % \
self.dcs[3].get_depot_url())
self.pkg("install [email protected]", exit=4)
self.pkg("unset-publisher test1")
self.pkg("unset-publisher test3")
# Add a new publisher, using the installed package publisher's
# repository. After that, attempt to install the package again,
# which should succeed even though the fmri is only in a
# different publisher's catalog.
self.pkg("set-publisher -O %s test3" % \
self.dcs[1].get_depot_url())
self.pkg("install [email protected]", exit=4)
self.pkg("unset-publisher test3")
# Change the image metadata back to where it was, in preparation
# for subsequent tests.
self.pkg("set-publisher -O %s -P test1" % \
self.dcs[1].get_depot_url())
# Remove the installed packages.
self.pkg("uninstall quux")
def test_11_uninstall_after_preferred_publisher_change(self):
"""Install a package from the preferred publisher, change the
preferred publisher, and attempt to remove the package."""
self.pkg("install [email protected]")
self.pkg("set-publisher -P test2")
self.pkg("uninstall foo")
# Change the image metadata back to where it was, in preparation
# for the next test.
self.pkg("set-publisher -P test1")
def test_12_uninstall_after_publisher_removal(self):
"""Install a package from the preferred publisher, remove the
preferred publisher, and then evaluate whether an uninstall
would succeed regardless of whether its publisher still exists
or another publisher has the same fmri in its catalog."""
self.pkg("install [email protected]")
self.pkg("set-publisher -P test2")
self.pkg("unset-publisher test1")
# Attempting to uninstall should work even if the corresponding
# publisher no longer exists.
self.pkg("uninstall -nv foo")
# Add back the installed package's publisher, but using a
# a repository with an empty catalog. After that, attempt to
# uninstall the package again, which should succeed even though
# the fmri is no longer in the publisher's catalog.
self.pkg("set-publisher -O %s test1" % \
self.dcs[3].get_depot_url())
self.pkg("uninstall -nv foo")
self.pkg("unset-publisher test1")
# Add a new publisher, using the installed package publisher's
# repository; then add back the installed package's publisher
# using a repository with an empty catalog. After that, attempt
# to uninstall the package again, which should succeed even
# though the package's installed publisher is known, but doesn't
# have the package's fmri in its catalog, but the package's fmri
# is in a different publisher's catalog.
self.pkg("set-publisher -O %s test3" % \
self.dcs[1].get_depot_url())
self.pkg("set-publisher -O %s test1" % \
self.dcs[3].get_depot_url())
self.pkg("uninstall -nv foo")
self.pkg("unset-publisher test1")
self.pkg("unset-publisher test3")
# Add a new publisher, using the installed package publisher's
# repository. After that, attempt to uninstall the package
# again, which should succeed even though the fmri is only in a
# different publisher's catalog.
self.pkg("set-publisher -O %s test3" % \
self.dcs[1].get_depot_url())
self.pkg("uninstall -nv foo")
self.pkg("unset-publisher test3")
# Finally, actually remove the package.
self.pkg("uninstall -v foo")
# Change the image metadata back to where it was, in preparation
# for subsequent tests.
self.pkg("set-publisher -O %s -P test1" % \
self.dcs[1].get_depot_url())
def test_13_non_preferred_multimatch(self):
"""Verify that when multiple non-preferred publishers offer the
same package that the expected install behaviour occurs."""
self.pkg("set-publisher -P -O %s test3" % \
self.dcs[3].get_depot_url())
# make sure we look here first; tests rely on that
self.pkg("set-publisher --search-before=test2 test1")
self.pkg("publisher")
# First, verify that installing a package from a non-preferred
# publisher will cause its dependencies to be installed from the
# same publisher if the preferred publisher does not offer them.
self.pkg("list -a")
self.pkg("install pkg://test1/baz")
self.pkg("list")
self.pkg("info baz | grep test1")
self.pkg("info corge | grep test1")
self.pkg("uninstall -r corge")
# Next, verify that naming the specific publishers for a package
# and all of its dependencies will install the package from the
# specified sources instead of the same publisher the package is a
# dependency of.
self.pkg("install pkg://test1/baz pkg://test2/corge")
self.pkg("info baz | grep test1")
self.pkg("info corge | grep test2")
self.pkg("uninstall -r corge")
# Finally, cleanup for the next test.
self.pkg("set-publisher -P test1")
self.pkg("unset-publisher test3")
def test_14_nonsticky_publisher(self):
"""Test various aspects of the stick/non-sticky
behavior of publishers"""
# For ease of debugging
self.pkg("list -a")
# install from non-preferred repo explicitly
self.pkg("install pkg://test2/[email protected]")
# Demonstrate that perferred publisher is not
# acceptable, since test2 is sticky by default
self.pkg("install [email protected]", exit=1) # not right repo
# Check that we can proceed once test2 is not sticky
self.pkg("set-publisher --non-sticky test2")
self.pkg("install [email protected]") # should work now
# Restore to pristine
self.pkg("set-publisher --sticky test2")
self.pkg("uninstall upgrade-np")
# Repeat the test w/ preferred
self.pkg("install upgrade-p")
self.pkg("set-publisher -P test2")
self.pkg("install [email protected]", exit=1) #orig pub is sticky
self.pkg("set-publisher --non-sticky test1") #not anymore
self.pkg("install [email protected]")
self.pkg("set-publisher -P --sticky test1") # restore
self.pkg("uninstall '*'")
# Check that search order can be overridden w/ explicit
# version specification...
self.pkg("install upgrade-p")
self.pkg("install [email protected]", exit=1)
self.pkg("set-publisher --non-sticky test1")
self.pkg("install [email protected]") # find match later on
self.pkg("set-publisher --sticky test1")
self.pkg("uninstall '*'")
def test_15_nonsticky_update(self):
"""Test to make sure image-update follows the same
publisher selection mechanisms as pkg install"""
# try image-update
self.pkg("install pkg://test2/[email protected]")
self.pkg("image-update", exit=4)
self.pkg("list [email protected]")
self.pkg("set-publisher --non-sticky test2")
self.pkg("publisher")
self.pkg("list -a upgrade-np")
self.pkg("image-update")
self.pkg("list [email protected]")
self.pkg("set-publisher --sticky test2")
self.pkg("uninstall '*'")
def test_16_disabled_nonsticky(self):
"""Test to make sure disabled publishers are
automatically made non-sticky, and after
being enabled keep their previous value
of stickiness"""
# For ease of debugging
self.pkg("list -a")
# install from non-preferred repo explicitly
self.pkg("install pkg://test2/[email protected]")
# Demonstrate that perferred publisher is not
# acceptable, since test2 is sticky by default
self.pkg("install [email protected]", exit=1) # not right repo
# Disable test2 and then we should be able to proceed
self.pkg("set-publisher --disable test2")
self.pkg("install [email protected]")
self.pkg("publisher")
self.pkg("set-publisher --enable test2")
self.pkg("publisher")
self.pkg("publisher | egrep sticky", exit=1 )
class TestImageCreateCorruptImage(testutils.SingleDepotTestCaseCorruptImage):
"""
If a new essential directory is added to the format of an image it will
be necessary to update this test suite. To update this test suite,
decide in what ways it is necessary to corrupt the image (removing the
new directory or file, or removing the some or all of contents of the
new directory for example). Make the necessary changes in
testutils.SingleDepotTestCaseCorruptImage to allow the needed
corruptions, then add new tests to the suite below. Be sure to add
tests for both Full and User images, and perhaps Partial images if
situations are found where these behave differently than Full or User
images.
"""
# Only start/stop the depot once (instead of for every test)
persistent_depot = True
foo11 = """
open [email protected],5.11-0
add dir mode=0755 owner=root group=bin path=/lib
add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
close """
misc_files = [ "/tmp/libc.so.1" ]
PREFIX = "unset PKG_IMAGE; cd %s"
def setUp(self):
testutils.SingleDepotTestCaseCorruptImage.setUp(self)
for p in self.misc_files:
f = open(p, "w")
# write the name of the file into the file, so that
# all files have differing contents
f.write(p)
f.close()
self.debug("wrote %s" % p)
def tearDown(self):
testutils.SingleDepotTestCaseCorruptImage.tearDown(self)
for p in self.misc_files:
os.remove(p)
def pkg(self, command, exit=0, comment=""):
testutils.SingleDepotTestCaseCorruptImage.pkg(self, command,
exit=exit, comment=comment, prefix=self.PREFIX % self.dir)
# For each test:
# A good image is created at $basedir/image
# A corrupted image is created at $basedir/image/bad (called bad_dir
# in subsequent notes) in verious ways
# The $basedir/image/bad/final directory is created and PKG_IMAGE
# is set to that dirctory.
# Tests simulating a corrupted Full Image
def test_empty_var_pkg(self):
""" Creates an empty bad_dir. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["publisher", "cfg_cache", "file", "pkg", "index"]),
["var/pkg"])
self.pkg("install [email protected]")
def test_var_pkg_missing_publisher(self):
""" Creates bad_dir with only the publisher and known/state
dir missing. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["publisher_absent", "known_absent"]),
["var/pkg"])
self.pkg("install [email protected]")
def test_var_pkg_missing_cfg_cache(self):
""" Creates bad_dir with only the cfg_cache file missing. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["cfg_cache_absent"]), ["var/pkg"])
self.pkg("install [email protected]")
def test_var_pkg_missing_file(self):
""" Creating bad_dir with only the file dir missing. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["file_absent"]), ["var/pkg"])
self.pkg("install [email protected]")
def test_var_pkg_missing_pkg(self):
""" Creates bad_dir with only the pkg dir missing. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl, set(["pkg_absent"]),
["var/pkg"])
self.pkg("install [email protected]")
def test_var_pkg_missing_index(self):
""" Creates bad_dir with only the index dir missing. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl, set(["index_absent"]),
["var/pkg"])
self.pkg("install [email protected]")
def test_var_pkg_missing_publisher_empty(self):
""" Creates bad_dir with all dirs and files present, but
with an empty publisher and state/known dir.
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["publisher_empty", "known_empty"]), ["var/pkg"])
# This is expected to fail because it will see an empty
# publisher directory and not rebuild the files as needed
self.pkg("install --no-refresh [email protected]", exit=1)
self.pkg("install [email protected]")
def test_var_pkg_missing_publisher_empty_hit_then_refreshed_then_hit(
self):
""" Creates bad_dir with all dirs and files present, but with an
with an empty publisher and state/known dir. This is to ensure
that refresh will work, and that an install after the refresh
also works.
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["publisher_empty", "known_empty"]), ["var/pkg"])
self.pkg("install --no-refresh [email protected]", exit=1)
self.pkg("refresh")
self.pkg("install [email protected]")
def test_var_pkg_left_alone(self):
""" Sanity check to ensure that the code for creating
a bad_dir creates a good copy other than what's specified
to be wrong. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl, set(), ["var/pkg"])
self.pkg("install [email protected]")
# Tests simulating a corrupted User Image
# These tests are duplicates of those above but instead of creating
# a corrupt full image, they create a corrupt User image.
def test_empty_ospkg(self):
""" Creates a corrupted image at bad_dir by creating empty
bad_dir. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["publisher", "cfg_cache", "file", "pkg", "index"]),
[".org.opensolaris,pkg"])
self.pkg("install [email protected]")
def test_ospkg_missing_publisher(self):
""" Creates a corrupted image at bad_dir by creating bad_dir
with only the publisher and known/state dir missing. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["publisher_absent", "known_absent"]),
[".org.opensolaris,pkg"])
self.pkg("install [email protected]")
def test_ospkg_missing_cfg_cache(self):
""" Creates a corrupted image at bad_dir by creating
bad_dir with only the cfg_cache file missing. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["cfg_cache_absent"]), [".org.opensolaris,pkg"])
self.pkg("install [email protected]")
def test_ospkg_missing_file(self):
""" Creates a corrupted image at bad_dir by creating
bad_dir with only the file dir missing. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl, set(["file_absent"]),
[".org.opensolaris,pkg"])
self.pkg("install [email protected]")
def test_ospkg_missing_pkg(self):
""" Creates a corrupted image at bad_dir by creating
bad_dir with only the pkg dir missing. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl, set(["pkg_absent"]),
[".org.opensolaris,pkg"])
self.pkg("install [email protected]")
def test_ospkg_missing_index(self):
""" Creates a corrupted image at bad_dir by creating
bad_dir with only the index dir missing. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl, set(["index_absent"]),
[".org.opensolaris,pkg"])
self.pkg("install [email protected]")
def test_ospkg_missing_publisher_empty(self):
""" Creates a corrupted image at bad_dir by creating bad_dir
with all dirs and files present, but with an empty publisher
and known/state dir. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["publisher_empty", "known_empty"]),
[".org.opensolaris,pkg"])
self.pkg("install --no-refresh [email protected]", exit=1)
def test_ospkg_missing_publisher_empty_hit_then_refreshed_then_hit(self):
""" Creates bad_dir with all dirs and files present, but with
an empty publisher and known/state dir. This is to ensure that
refresh will work, and that an install after the refresh also
works.
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["publisher_empty", "known_empty"]),
[".org.opensolaris,pkg"])
self.pkg("install --no-refresh [email protected]", exit=1)
self.pkg("refresh")
self.pkg("install [email protected]")
def test_ospkg_left_alone(self):
""" Sanity check to ensure that the code for creating
a bad_dir creates a good copy other than what's specified
to be wrong. """
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl, set(),
[".org.opensolaris,pkg"])
self.pkg("install [email protected]")
# Tests for checking what happens when two images are installed side by side.
def test_var_pkg_missing_cfg_cache_ospkg_also_missing_alongside(self):
""" Each bad_dir is missing a cfg_cache
These 3 tests do nothing currently because trying to install an
image next to an existing image in not currently possible. The
test cases remain against the day that such an arrangement is
possible.
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["cfg_cache_absent"]), [".org.opensolaris,pkg"])
self.dir = self.corrupt_image_create(durl,
set(["cfg_cache_absent"]), ["var/pkg"], destroy=False)
self.pkg("install [email protected]")
def test_var_pkg_ospkg_missing_cfg_cache_alongside(self):
""" Complete Full image besides a User image missing cfg_cache
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl, set(), ["var/pkg"])
self.dir = self.corrupt_image_create(durl,
set(["cfg_cache_absent"]), [".org.opensolaris,pkg"],
destroy=False)
self.pkg("install [email protected]")
def test_var_pkg_missing_cfg_cache_ospkg_alongside(self):
""" Complete User image besides a Full image missing cfg_cache
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, self.foo11)
self.image_create(durl)
self.dir = self.corrupt_image_create(durl,
set(["cfg_cache_absent"]), ["var/pkg"])
self.dir = self.corrupt_image_create(durl, set(),
[".org.opensolaris,pkg"], destroy=False)
self.pkg("install [email protected]")
class TestPkgInstallObsolete(testutils.SingleDepotTestCase):
"""Test cases for obsolete packages."""
persistent_depot = True
def setUp(self):
testutils.SingleDepotTestCase.setUp(self)
def test_basic(self):
foo1 = """
open foo@1
add dir path=usr mode=0755 owner=root group=root
close
"""
# Obsolete packages can have metadata
foo2 = """
open foo@2
add set name=pkg.obsolete value=true
add set name=pkg.summary value="A test package"
close
"""
fbar = """
open fbar@1
add depend type=require fmri=foo@2
close
"""
qbar = """
open qbar@1
add depend type=require fmri=qux@2
close
"""
qux1 = """
open qux@1
add dir path=usr mode=0755 owner=root group=root
close
"""
qux2 = """
open qux@2
add set name=pkg.renamed value=true
add depend type=require fmri=foo@1
close
"""
fred1 = """
open fred@1
add depend type=require fmri=foo
close
"""
fred2 = """
open fred@2
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, foo1)
self.pkgsend_bulk(durl, foo2)
self.pkgsend_bulk(durl, fbar)
self.pkgsend_bulk(durl, qbar)
self.pkgsend_bulk(durl, qux1)
self.pkgsend_bulk(durl, qux2)
self.pkgsend_bulk(durl, fred1)
self.image_create(durl)
# First install the non-obsolete version of foo
self.pkg("install foo@1")
self.pkg("list foo@1")
# Now install the obsolete version, and ensure it disappears (5)
self.pkg("install foo")
self.pkg("list foo", exit=1)
# Explicitly installing an obsolete package succeeds, but
# results in nothing on the system. (1)
self.pkg("install foo@2", exit=4)
self.pkg("list foo", exit=1)
# Installing a package with a dependency on an obsolete package
# fails. (2)
self.pkg("install fbar", exit=1)
# Installing a package with a dependency on a renamed package
# succeeds, leaving the first package and the renamed package on
# the system, as well as the empty, pre-renamed package. (3)
self.pkg("install qbar")
self.pkg("list qbar")
self.pkg("list foo@1")
self.pkg("list qux | grep -- --r--")
self.pkg("uninstall '*'") #clean up for next test
# A simple rename test: First install the pre-renamed version of
# qux. Then install the renamed version, and see that the new
# package is installed, and the renamed package is installed,
# but marked renamed. (4)
self.pkg("install qux@1")
self.pkg("install qux")
self.pkg("list foo@1")
self.pkg("list qux | grep -- --r--")
self.pkg("uninstall '*'") #clean up for next test
# Install a package that's going to be obsoleted and a package
# that depends on it. Update the package to its obsolete
# version and see that it fails. (6, sorta)
self.pkg("install foo@1 fred@1")
self.pkg("install foo@2", exit=1)
# now add a version of fred that doesn't require foo, and
# show that update works
self.pkgsend_bulk(durl, fred2)
self.pkg("refresh")
self.pkg("install foo@2")
def test_basic_7a(self):
"""Upgrade a package to a version with a dependency on a renamed
package. A => A' (-> Br (-> C))"""
t7ap1_1 = """
open t7ap1@1
close
"""
t7ap1_2 = """
open t7ap1@2
add depend type=require fmri=t7ap2
close
"""
t7ap2_1 = """
open t7ap2@1
add set name=pkg.renamed value=true
add depend type=require fmri=t7ap3
close
"""
t7ap3_1 = """
open t7ap3@1
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t7ap1_1)
self.image_create(durl)
self.pkg("install t7ap1")
self.pkgsend_bulk(durl, t7ap1_2)
self.pkgsend_bulk(durl, t7ap2_1)
self.pkgsend_bulk(durl, t7ap3_1)
self.pkg("refresh")
self.pkg("image-update")
self.pkg("list -af")
self.pkg("list t7ap2 | grep -- --r--")
self.pkg("list t7ap3")
def test_basic_7b(self):
"""Upgrade a package to a version with a dependency on a renamed
package. Like 7a except package A starts off depending on B.
A (-> B) => A' (-> Br (-> C))"""
t7bp1_1 = """
open t7bp1@1
add depend type=require fmri=t7bp2
close
"""
t7bp1_2 = """
open t7bp1@2
add depend type=require fmri=t7bp2
close
"""
t7bp2_1 = """
open t7bp2@1
close
"""
t7bp2_2 = """
open t7bp2@1
add set name=pkg.renamed value=true
add depend type=require fmri=t7bp3
close
"""
t7bp3_1 = """
open t7bp3@1
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t7bp1_1)
self.pkgsend_bulk(durl, t7bp2_1)
self.image_create(durl)
self.pkg("install t7bp1")
self.pkgsend_bulk(durl, t7bp1_2)
self.pkgsend_bulk(durl, t7bp2_2)
self.pkgsend_bulk(durl, t7bp3_1)
self.pkg("refresh")
self.pkg("image-update")
self.pkg("list t7bp2 | grep -- --r--")
self.pkg("list t7bp3")
def test_basic_7c(self):
"""Upgrade a package to a version with a dependency on a renamed
package. Like 7b, except package A doesn't change.
A (-> B) => A (-> Br (-> C))"""
t7cp1_1 = """
open t7cp1@1
add depend type=require fmri=t7cp2
close
"""
t7cp2_1 = """
open t7cp2@1
close
"""
t7cp2_2 = """
open t7cp2@2
add set name=pkg.renamed value=true
add depend type=require fmri=t7cp3
close
"""
t7cp3_1 = """
open t7cp3@1
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t7cp1_1)
self.pkgsend_bulk(durl, t7cp2_1)
self.image_create(durl)
self.pkg("install t7cp1")
self.pkgsend_bulk(durl, t7cp2_2)
self.pkgsend_bulk(durl, t7cp3_1)
self.pkg("refresh")
self.pkg("image-update")
self.pkg("list t7cp2 | grep -- --r--")
self.pkg("list t7cp3")
def test_basic_6a(self):
"""Upgrade a package to a version with a dependency on an
obsolete package. This version is unlikely to happen in real
life."""
t6ap1_1 = """
open t6ap1@1
close
"""
t6ap1_2 = """
open t6ap1@2
add depend type=require fmri=t6ap2
close
"""
t6ap2_1 = """
open t6ap2@1
add set name=pkg.obsolete value=true
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t6ap1_1)
self.image_create(durl)
self.pkg("install t6ap1")
self.pkgsend_bulk(durl, t6ap1_2)
self.pkgsend_bulk(durl, t6ap2_1)
self.pkg("refresh")
self.pkg("image-update", exit=4) # does nothing
self.pkg("list t6ap1")
def test_basic_6b(self):
"""Install a package with a dependency, and image-update after
publishing updated packages for both, but where the dependency
has become obsolete."""
t6ap1_1 = """
open t6ap1@1
add depend type=require fmri=t6ap2
close
"""
t6ap1_2 = """
open t6ap1@2
add depend type=require fmri=t6ap2
close
"""
t6ap2_1 = """
open t6ap2@1
close
"""
t6ap2_2 = """
open t6ap2@2
add set name=pkg.obsolete value=true
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t6ap1_1)
self.pkgsend_bulk(durl, t6ap2_1)
self.image_create(durl)
self.pkg("install t6ap1")
self.pkg("list")
self.pkgsend_bulk(durl, t6ap1_2)
self.pkgsend_bulk(durl, t6ap2_2)
self.pkg("refresh")
self.pkg("image-update")
self.pkg("list t6ap1@2 t6ap2@1")
def test_basic_8a(self):
"""Upgrade a package to an obsolete leaf version when another
depends on it."""
t8ap1_1 = """
open t8ap1@1
close
"""
t8ap1_2 = """
open t8ap1@2
add set name=pkg.obsolete value=true
close
"""
t8ap2_1 = """
open t8ap2@1
add depend type=require fmri=t8ap1
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t8ap1_1)
self.pkgsend_bulk(durl, t8ap2_1)
self.image_create(durl)
self.pkg("install t8ap2")
self.pkgsend_bulk(durl, t8ap1_2)
self.pkg("refresh")
self.pkg("image-update", exit=4) # does nothing
self.pkg("list t8ap2@1")
def test_basic_13a(self):
"""Publish an package with a dependency, then publish both as
obsolete, image-update, and see that both packages have gotten
removed."""
t13ap1_1 = """
open t13ap1@1
add depend type=require fmri=t13ap2
close
"""
t13ap1_2 = """
open t13ap1@2
add set name=pkg.obsolete value=true
close
"""
t13ap2_1 = """
open t13ap2@1
close
"""
t13ap2_2 = """
open t13ap2@2
add set name=pkg.obsolete value=true
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t13ap1_1)
self.pkgsend_bulk(durl, t13ap2_1)
self.image_create(durl)
self.pkg("install t13ap1")
self.pkgsend_bulk(durl, t13ap1_2)
self.pkgsend_bulk(durl, t13ap2_2)
self.pkg("refresh")
self.pkg("image-update")
self.pkg("list", exit=1)
def test_basic_11(self):
"""Install a package with an ambiguous name, where only one
match is non-obsolete."""
t11p1 = """
open netbeans@1
add set name=pkg.obsolete value=true
close
"""
t11p2 = """
open developer/netbeans@1
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t11p1)
self.pkgsend_bulk(durl, t11p2)
self.image_create(durl)
self.pkg("install netbeans")
self.pkg("list pkg:/developer/netbeans")
self.pkg("list pkg:/netbeans", exit=1)
def test_basic_11a(self):
"""Install a package using an ambiguous name where
pkg is renamed to another package, but not the
conflicting one"""
t11p1 = """
open netbonze@1
add set name=pkg.renamed value=true
add depend type=require fmri=SUNWnetbonze
close
"""
t11p2 = """
open developer/netbonze@1
close
"""
t11p3 = """
open SUNWnetbonze@1
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t11p1)
self.pkgsend_bulk(durl, t11p2)
self.pkgsend_bulk(durl, t11p3)
self.image_create(durl)
self.pkg("install netbonze", exit=1)
def test_basic_11b(self):
"""Install a package using an ambiguous name where only one
match is non-renamed, and the renamed match is renamed to the
other."""
t11p1 = """
open netbooze@1
close
"""
t11p2 = """
open netbooze@2
add set name=pkg.renamed value=true
add depend type=require fmri=developer/netbooze
close
"""
t11p3 = """
open developer/netbooze@2
close
"""
t11p4 = """
open developer/netbooze@3
add depend type=require fmri=developer/missing
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t11p1)
self.pkgsend_bulk(durl, t11p2)
self.pkgsend_bulk(durl, t11p3)
self.pkgsend_bulk(durl, t11p4)
self.image_create(durl)
self.pkg("install netbooze")
self.pkg("list pkg:/developer/netbooze")
self.pkg("list pkg:/netbooze")
def test_basic_12(self):
"""Upgrade a package across a rename to an ambiguous name."""
t12p1_1 = """
open netbeenz@1
close
"""
t12p1_2 = """
open netbeenz@2
add set name=pkg.renamed value=true
add depend type=require fmri=pkg:/developer/netbeenz
close
"""
t12p2_1 = """
open developer/netbeenz@1
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, t12p1_1)
self.image_create(durl)
self.pkg("install netbeenz")
self.pkgsend_bulk(durl, t12p1_2)
self.pkgsend_bulk(durl, t12p2_1)
self.pkg("refresh")
self.pkg("image-update -v")
self.pkg("list pkg:/developer/netbeenz | grep -- -----")
self.pkg("list pkg:/netbeenz | grep -- --r--")
def test_remove_renamed(self):
"""If a renamed package has nothing depending on it, it should
be removed."""
p1_1 = """
open remrenA@1
close
"""
p1_2 = """
open remrenA@2
add set name=pkg.renamed value=true
add depend type=require fmri=pkg:/remrenB
close
"""
p2_1 = """
open remrenB@1
close
"""
p3_1 = """
open remrenC@1
add depend type=require fmri=pkg:/remrenA
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, p1_1)
self.image_create(durl)
self.pkg("install remrenA")
self.pkgsend_bulk(durl, p1_2)
self.pkgsend_bulk(durl, p2_1)
self.pkgsend_bulk(durl, p3_1)
self.pkg("refresh")
self.pkg("image-update")
self.pkg("list remrenA", exit=1)
# But if there is something depending on the renamed package, it
# can't be removed.
self.pkg("pkg uninstall remrenB")
self.pkg("install remrenA@1 remrenC")
self.pkg("image-update")
self.pkg("list remrenA")
def test_incorp_1(self):
"""We should be able to incorporate an obsolete package."""
p1_1 = """
open inc1p1@1
add depend type=incorporate fmri=inc1p2@1
close
"""
p2_1 = """
open inc1p2@1
add set name=pkg.obsolete value=true
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, p1_1)
self.pkgsend_bulk(durl, p2_1)
self.image_create(durl)
self.pkg("install inc1p1")
self.pkg("install inc1p2", exit=4)
self.pkg("list inc1p2", exit=1)
def test_incorp_2(self):
"""We should be able to continue incorporating a package when it
becomes obsolete on upgrade."""
p1_1 = """
open inc2p1@1
add depend type=incorporate fmri=inc2p2@1
close
"""
p1_2 = """
open inc2p1@2
add depend type=incorporate fmri=inc2p2@2
close
"""
p2_1 = """
open inc2p2@1
close
"""
p2_2 = """
open inc2p2@2
add set name=pkg.obsolete value=true
close
"""
durl = self.dc.get_depot_url()
self.pkgsend_bulk(durl, p1_1)
self.pkgsend_bulk(durl, p2_1)
self.image_create(durl)
self.pkg("install inc2p1 inc2p2")
self.pkgsend_bulk(durl, p1_2)
self.pkgsend_bulk(durl, p2_2)
self.pkg("refresh")
self.pkg("list -afv")
self.pkg("image-update -v")
self.pkg("list inc2p2", exit=1)
class TestPkgInstallMultiObsolete(testutils.ManyDepotTestCase):
"""Tests involving obsolete packages and multiple publishers."""
obs = """
open stem@1
add set name=pkg.obsolete value=true
close
"""
nonobs = """
open stem@1
close
"""
persistent_depot = True
def setUp(self):
testutils.ManyDepotTestCase.setUp(self, ["test1", "test2"])
def test_01(self):
"""If an obsolete package is found in a preferred publisher and
a non-obsolete package of the same name is found in a
non-preferred publisher, pick the preferred pub as usual """
durl1 = self.dcs[1].get_depot_url()
durl2 = self.dcs[2].get_depot_url()
self.pkgsend_bulk(durl1, self.obs)
self.pkgsend_bulk(durl2, self.nonobs)
self.image_create(durl1, prefix="test1")
self.pkg("set-publisher -O " + durl2 + " test2")
self.pkg("list -a")
self.pkg("install stem", exit=4) # noting to do since it's obs
# We should choose the obsolete package, which means nothing
# gets installed.
self.pkg("list", exit=1)
def test_02(self):
"""Same as test_01, but now we have ambiguity in the package
names. While at first blush we might follow the same rule as in
test_01 (choose the preferred publisher), in this case, we can't
figure out which package from the preferred publisher we want,
so the choice already isn't as straightforward, so we choose the
non-obsolete package."""
lobs = """
open some/stem@1
add set name=pkg.obsolete value=true
close
"""
durl1 = self.dcs[1].get_depot_url()
durl2 = self.dcs[2].get_depot_url()
self.pkgsend_bulk(durl1, self.obs + lobs)
self.pkgsend_bulk(durl2, self.nonobs + lobs)
self.image_create(durl1, prefix="test1")
self.pkg("set-publisher -O " + durl2 + " test2")
self.pkg("install stem", exit=1)
if __name__ == "__main__":
unittest.main()