#
# 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
# 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
#
#
#
from . import testutils
if __name__ == "__main__":
import pkg5unittest
import errno
import os
import re
import shutil
import six
import stat
import sys
import tempfile
import unittest
"""Tests for the pkgmogrify publication tool."""
pkgcontents = """\
# directories
# dependencies
depend fmri=SUNWfontconfig@2.7.1-$(BUILDID) type=require
depend fmri=SUNWfreetype2@2.3.9-$(BUILDID) type=require
depend fmri=SUNWlibms@0.5.11-$(BUILDID) type=require
$(i386_ONLY)depend fmri=SUNWxorg-mesa@7.4.4-$(BUILDID) type=require
file NOHASH elfarch=i386 elfbits=32 group=bin mode=0755 \
link path=usr/X11/lib/libXdmcp.so target=./libXdmcp.so.6
link path=usr/X11/lib/libXevie.so target=./libXevie.so.1
link path=usr/X11/lib/libXext.so target=./libXext.so.0
link path=usr/X11/lib/libXfixes.so target=./libXfixes.so.1
link path=usr/X11/lib/libXinerama.so target=./libXinerama.so.1
"""
pkgcontents2 = """\
set name=bugs value=12345 value=54321 value=13524
set name=justonebug value=12345
file NOHASH path="'/usr/bin/quotedpath'" moo=cowssayit
set name=pkg.summary value="Doo wah diddy"
legacy pkg=SUNWwombat version=3
"""
pkgcontents3 = """\
$(sparc_ONLY)file NOHASH path=kernel/drv/sparc_only1 reboot-needed=true
$(sparc_ONLY)file NOHASH path=kernel/drv/sparc_only2 reboot-needed=true
"""
# Give names to simple transforms. These transforms can use <include>
# by referring to the named transforms using the %()s construct.
transforms = {
"X11->Y11": "<transform file link dir -> edit path X11 Y11>",
"drop xkbprint": "<transform file path='.*xkbprint.*' -> drop>",
"drop mode=0755": "<transform file -> delete mode 0755> ",
"empty": "<transform file >",
"empty edit": "<transform file -> edit bar >",
"2include": "<include {X11->Y11}>\n<include {X11mode}>",
"include 9": "<include {include 5}>",
"include 5": "<include {empty}>",
"add bobcat": "<transform file -> add bobcat 1>",
"print ouch": '<transform file bobcat=1 -> print "ouch" >',
"abort on bobcat": "<transform file bobcat=1 -> abort >",
"exit7 on bobcat": "<transform file bobcat=1 -> exit 7>",
"exit6 on bobcat": "<transform file bobcat=1 -> exit 6 found a bobcat>",
"fmrival": "<transform set name=pkg.fmri -> print test of \"%(value)\" ... or is it?>",
"fmrinoval": "<transform set name=pkg.fmri -> print test of \"%(valuee)\" ... or is it?>",
"fmrisaved": "<transform set name=pkg.fmri -> print test of \"%(valuee;notfound=noprint)\" ... or is it?>",
"fmriqsaved": "<transform set name=pkg.fmri -> print test of \"%(valuee;notfound=\"got quotes\")\" ... or is it?>",
"fmrinotsaved": "<transform set name=pkg.fmri -> print test of \"%(value;notfound=noprint)\" ... or is it?>",
"list": "<transform set name=bugs -> print test of listval \"%(value)\">",
"listsep": "<transform set name=bugs -> print test of listval \"%(value;sep=\",\")\">",
"listsufpresep": "<transform set name=bugs -> print test of listval \"%(value;sep=\", \";prefix=\"bug='\";suffix=\"'\")\">",
"nolistsufpre": "<transform set name=justonebug -> print test of \"%(value;prefix=\"bug='\";suffix=\"'\")\">",
"emitblank": "<transform set name=pkg.fmri -> emit>",
"emitcomment": "<transform set name=pkg.fmri -> emit # comment>",
"emitaction": "<transform set name=pkg.fmri -> emit depend type=incorporate fmri=%(value)>",
"synthetic": "<transform file path=usr/bin/foo -> print %(pkg.manifest.filename) %(pkg.manifest.lineno)>",
"synthetic2": "<transform file path=usr/bin/foo -> print %(action.hash) %(action.key) %(action.name)>",
"synthetic3": "<transform file -> print %(action.hash)>",
"synthetic4": "<transform set -> print %(action.hash)>",
"synthetic5": "<transform set -> print %(action.hash;notfound=something)>",
"pkgmatch": "<transform pkg -> default $(MYATTR) false>",
"pkggen": "<transform pkg $(MYATTR)=false -> emit depend fmri=consolidation type=require>",
"rbneeded": "<transform file reboot-needed=true -> emit set name=magic value=true>",
"brdefault": "<transform depend fmri=__TBD path=([^/]*)/([^/]*)/ mode=0(.)55 -> default pkg.debug.depend.path %<1>/%<2>>",
"brdefault2": "<transform depend fmri=__TBD mode=0(.)55 path=([^/]*)/([^/]*)/ -> default pkg.debug.depend.path %<2>/%<3>>",
"brdefault3": "<transform depend fmri=__TBD mode=0(.)55 path=([^/]*)/([^/]*)/ -> default pkg.debug.depend.path %<2>/%<4>>",
"brdefault3a": "<transform depend fmri=__TBD mode=0(.)55 path=([^/]*)/([^/]*)/ -> default pkg.debug.depend.path %<2>/%<0>>",
"brweirdquote": "<transform file moo=(.*) path='\\'.*/([^/]*)\\'' -> default refs %<1>,%<2>>",
"bredit": "<transform file path=usr/share/locale/([^/]+).* -> edit path .*/([^/]*\\.mo) another/place/for/locales/%<1>/\\\\1>",
"edit1": "<transform file path=usr/(share|lib)/locale.* -> edit path usr/(lib|share)/locale place/\\\\1/langs>",
"doublequote": "<transform legacy -> default name %{{pkg.summary}}>",
"delete-with-no-operand": "<transform file -> delete >",
"backreference-no-object": "<transform file path=(local/)?usr/* -> default refs %<1>>",
"backreference-empty-string": "<transform file path=usr/bin/foo(.*)-> emit file path=usr/sbin/foo%<1>>"
}
basic_defines = {
"i386_ONLY": "#",
"BUILDID": 0.126
}
# Map the transform names to path names
xformpaths = dict((
))
# Now that we have path names, we can use the expandos in the
# transform contents to embed those pathnames, and write the
# transform files out.
if defines is None:
"-D {0}={1}".format(k, v)
])
if output:
"""Count how many lines in the output of the previously run
command match the regular expression 'regex'. If 'path' is
specified, the contents of that file are searched."""
if path is not None:
else:
c = sum((
))
return c
"""Assert that the regular expression 'regex' matches in the
output of the previously run command. If 'path' is specified,
the contents of that file are searched. If 'count' is greater
than zero, then the number of lines which match must equal that
number."""
if count > 0:
"{0} matches for '{1}' found, {2} expected".format(
"""Assert that the regular expression 'regex' is not found in
the output of the previously run command. If 'path' is
specified, the contents of that file are searched."""
"""Basic and nested macro substitution. Allow a macro to
comment out a manifest line."""
sources = [ source_file ]
# Lines commented out by macros remain in the output.
# nested macros
# stdin only
"""The -O option: output goes to a file rather than stdout."""
sources = [ source_file ]
# stdin and source file combined
# Make sure that the line really got dropped, not just changed
# unrecognizably.
# Basic attribute editing.
# Ensure that modifying an attribute used as matching criteria
# by a later transform means that the later transform is not
# invoked.
# Make sure that the -I flag works, with files specified on the
# commandline as well as ones <include>d by others.
# Ensure that modifying an attribute used as matching criteria
# by an earlier transform doesn't prevent the earlier transform
# from being invoked.
# If NOHASH is omitted from the original manifest, check that it
# gets added.
"""Test various error conditions."""
# Bad argument
# Bad transform
exit=1)
# file not found XXX this fails because of a bad transform
# nested tranform error XXX this fails because of a bad transform
# Wombats!
"""Test for graceful exit with no output on abort."""
# Add an abort transform that's expected to trigger. This
# should cover the "exit gracefully" part of abort.
# Make sure neither output nor print file was created.
# Trigger an exit transform with a specific exit code.
# Make sure neither output nor print file was created.
# Trigger an exit transform with a specific exit code and
# message.
"""Test for print output to specified file."""
# Generate output for each file action, and count resulting
# lines in print file to be sure it matches our expectations.
"""Test to make sure we can handle leading macros, preserve comments"""
"""Test the generation of new actions."""
# The emit operation can emit a blank line ...
# ... or a comment ...
# ... or an action ...
# Recursive transforms shouldn't blow up.
exit=1)
# Emitted actions shouldn't be duplicated, modulo a macro
# prefix.
del defines["i386_ONLY"]
"""Test the use of action attributes."""
expect = "^test of \"{0}\" ... or is it\?$"
# Simple %() replacement
# We should exit with an error and exit code 1 when the %()
# replacement fails because of a missing attribute.
exit=1)
# When the attribute is missing but a notfound token is present,
# we should see that value show up.
# If the notfound value has quotes, the quoted value should show
# up, and the quotes dropped.
# When a notfound value is present, but the original attribute
# is also present, the notfound value should be ignored.
# Basic list-valued attribute
# List-valued attribute with a separator
# List-valued attribute with a prefix, suffix, and separator
"bug='13524'\"$")
# Singly-valued attribute with a prefix and suffix
# Synthetic attributes
# Synthetic attributes
# The "action.hash" attribute shouldn't cause a problem when a
# file action doesn't specify the hash in the manifest.
# The "action.hash" attribute shouldn't explode when an action
# which doesn't have one tries to use it.
exit=1)
# The "action.hash" attribute can have a "notfound" value.
"""Test the use of package attributes."""
# Simple valued
'the rest$')
# List valued
# Match on package attributes, and generate temporary ones
# If we don't match, don't generate
"""Test the use of backreferences to the matching portion of the
transform."""
# Basic test of backreferences, using the default operation.
# Same operation, but reorder the match criteria (and the
# references to match) to show that the reference numbers are
# based on the literal order of the match criteria, rather than
# some internal storage mechanism.
# A reference to a group that doesn't exist should die
# gracefully.
exit=1)
# A reference to group 0 should die gracefully.
exit=1)
# A backreference may very well be used as part of an attribute
# name. Make sure that the "default" operation takes the fully
# substituted attribute name into account.
# Quoting in a match attribute may not agree with the quoting
# that actions use, confusing the mechanism we use to ensure
# backreference numbers refer to the right groups. Make sure
# we don't tip over, but show that we didn't get the backrefs
# right. The right solution for this is probably to have a
# mode for fromstr() that returns a list rather than a dict.
# XXX # self.assertMatch("refs=cowssayit,quotedpath")
# A "set" operation with a backreference works.
# An "add" operation with a backreference works.
# This is the "normal" kind of backreferencing, only available
# for the "edit" operation, where a \1 in the replacement string
# refers to a group in the regex string, all on the operation
# side of the transform.
# An "edit" operation with a backreference in the replacement
# value works. This one also uses the \1-style backreference.
# An "edit" operation with a backreference in the matching
# expression works.
# A backreference to an unmatched group is an error.
# A backreference to an empty string should work.
if __name__ == "__main__":