bdcs 0.1.0 → 0.1.1
raw patch · 17 files changed
+278/−246 lines, 17 files
Files
- ChangeLog.md +10/−0
- Dockerfile.build +4/−4
- Dockerfile.integration-test +1/−1
- README.md +2/−5
- bdcs.cabal +1/−1
- entrypoint-integration-test.sh +7/−0
- src/BDCS/DB.hs +21/−1
- src/BDCS/Depclose.hs +22/−7
- src/BDCS/Groups.hs +6/−2
- src/BDCS/Projects.hs +9/−1
- src/tests/BDCS/DepcloseSpec.hs +34/−22
- src/tests/BDCS/GroupsSpec.hs +7/−1
- src/tools/depsolve.hs +2/−2
- tests/test_depsolve.sh +38/−40
- tests/test_export.sh +75/−121
- tests/test_import.sh +27/−27
- tests/test_tmpfiles.sh +12/−11
ChangeLog.md view
@@ -1,3 +1,13 @@+## 0.1.1++* Add a new projects function that returns a list of all projects.+* Projects is now an instance of FromJSON and ToJSON.+* Fix running cabal commands under Docker.+* Move where the epoch appears in the output of groupIdToNevra.+* Add depcloseGroupIds for dependency solving from a list of IDs.+* Add depcloseNames for dependency solving from a list of package names.+* Rename depclose to depcloseNEVRAs to make its function clearer.+ ## 0.1.0 * Initial release.
Dockerfile.build view
@@ -26,7 +26,7 @@ WORKDIR /bdcs/ RUN hlint .-RUN cabal configure --enable-tests --enable-coverage --prefix=/usr/local-RUN cabal build-RUN cabal test --show-details=always-RUN cabal install --prefix=/usr/local+RUN cabal configure --enable-tests --enable-coverage --prefix=/usr/local && \+ cabal build && \+ cabal test --show-details=always && \+ cabal install --prefix=/usr/local
Dockerfile.integration-test view
@@ -1,7 +1,7 @@ FROM welder/bdcs-build-img:latest MAINTAINER Alexander Todorov <atodorov@redhat.com> -RUN dnf -y install wget diffutils && dnf clean all+RUN dnf -y install wget diffutils beakerlib COPY schema.sql / COPY entrypoint-integration-test.sh /usr/local/bin/entrypoint-integration-test.sh
README.md view
@@ -20,12 +20,11 @@ is the $PWD/Packages directory. Then run: ```-$ cd src $ cabal sandbox init $ cabal install --dependencies-only --enable-tests $ cabal build-$ sqlite3 metadata.db < ../schema.sql-$ for f in ${PWD}/Packages/*rpm; do dist/build/import/import metadata.db cs.repo file://${f}; done+$ sqlite3 metadata.db < schema.sql+$ for f in ${PWD}/Packages/*rpm; do dist/build/bdcs-import/bdcs-import metadata.db cs.repo file://${f}; done ``` Running with docker@@ -85,7 +84,6 @@ Executing unit tests ==================== - $ cd src/ $ cabal sandbox init $ cabal install --dependencies-only --enable-tests $ cabal test@@ -98,7 +96,6 @@ Produce code coverage report ============================ - $ cd src/ $ cabal sandbox init $ cabal install --enable-tests --enable-coverage $ cabal test
bdcs.cabal view
@@ -1,5 +1,5 @@ name: bdcs-version: 0.1.0+version: 0.1.1 synopsis: Tools for managing a content store of software packages description: This module provides a library and various tools for managing a content store and metadata database. These store the contents of software packages that make up a
entrypoint-integration-test.sh view
@@ -5,9 +5,16 @@ cd /bdcs/ ./tests/test_tmpfiles.sh+grep RESULT_STRING=PASS /var/tmp/beakerlib-*/TestResults || exit 1+ ./tests/test_import.sh+grep RESULT_STRING=PASS /var/tmp/beakerlib-*/TestResults || exit 1+ ./tests/test_export.sh+grep RESULT_STRING=PASS /var/tmp/beakerlib-*/TestResults || exit 1+ ./tests/test_depsolve.sh+grep RESULT_STRING=PASS /var/tmp/beakerlib-*/TestResults || exit 1 # collect coverage data from unit tests and binaries mkdir ./dist/hpc/vanilla/tix/bdcs-tmpfiles/
src/BDCS/DB.hs view
@@ -7,6 +7,7 @@ {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} @@ -29,9 +30,10 @@ import Control.Monad.Logger(NoLoggingT) import Control.Monad.Trans.Resource(MonadBaseControl, ResourceT) import qualified Data.Aeson as Aeson+import Data.Aeson((.:), (.=)) import Data.ByteString(ByteString) import Data.Int(Int64)-import Data.Maybe(fromJust, listToMaybe)+import Data.Maybe(fromJust, fromMaybe, listToMaybe) import qualified Data.Text as T import Data.Time(UTCTime) import Database.Esqueleto(Esqueleto, Entity, Key, PersistEntity, PersistField, SqlBackend, SqlPersistT, ToBackendKey, Value,@@ -184,6 +186,24 @@ script_id ScriptsId deriving Eq Show |]++-- Implement JSON functions for Projects+instance Aeson.ToJSON Projects where+ toJSON Projects{..} = Aeson.object [+ "name" .= projectsName+ , "summary" .= projectsSummary+ , "description" .= projectsDescription+ , "homepage" .= fromMaybe "" projectsHomepage+ , "upstream_vcs" .= projectsUpstream_vcs ]++instance Aeson.FromJSON Projects where+ parseJSON = Aeson.withObject "Projects" $ \o -> do+ projectsName <- o .: "name"+ projectsSummary <- o .: "summary"+ projectsDescription <- o .: "description"+ projectsHomepage <- o .: "homepage"+ projectsUpstream_vcs <- o .: "upstream_vcs"+ return Projects{..} instance Aeson.ToJSON KeyVal where toJSON kv = let
src/BDCS/Depclose.hs view
@@ -16,7 +16,9 @@ -- Collect all the dependencies for a package, but do not solve them. module BDCS.Depclose(DepFormula,- depclose)+ depcloseGroupIds,+ depcloseNEVRAs,+ depcloseNames) where import Codec.RPM.Version(DepRequirement(..), EVR(..), parseDepRequirement, satisfies)@@ -34,7 +36,7 @@ import BDCS.Depsolve(Formula(..)) import BDCS.DB import BDCS.Files(pathToGroupId)-import BDCS.Groups(getGroupId, getRequirementsForGroup)+import BDCS.Groups(getGroupId, getRequirementsForGroup, nameToGroupIds) import BDCS.GroupKeyValue(getGroupsByKeyVal, getKeyValuesForGroup, getValueForGroup) import BDCS.KeyType import qualified BDCS.ReqType as RT@@ -59,6 +61,22 @@ type DepFormula = Formula (Key Groups) -- | Given a path to a mddb, a list of architectures, and a list of RPMS, return a formula describing the dependencies+-- See depcloseGroupIds for further details+depcloseNEVRAs :: (MonadError String m, MonadIO m) => [T.Text] -> [T.Text] -> SqlPersistT m DepFormula+depcloseNEVRAs arches nevras = do+ -- Convert each NEVRA into a group ID.+ groupIds <- mapM getGroupId nevras+ depcloseGroupIds arches groupIds++-- | Given a path to a mddb, a list of architectures, and a list of package names, return a formula describing the dependencies+-- See depcloseGroupIds for further details+depcloseNames :: (MonadError String m, MonadIO m) => [T.Text] -> [T.Text] -> SqlPersistT m DepFormula+depcloseNames arches names = do+ -- Convert each package name into a group ID.+ groupIds <- concatMapM nameToGroupIds names+ depcloseGroupIds arches groupIds++-- | Given a path to a mddb, a list of architectures, and a list of Group Ids, return a formula describing the dependencies -- The general idea is, given a list of packages to depclose, convert each to a group id, and for each id: -- - gather the conflict and obsolete information, find matching group ids, express as Not conflict/obsolete-id -- - gather the requirement expressions, for each:@@ -71,11 +89,8 @@ -- Everything is run in a state with two components: a Map from groupid to expression to act as a cache, -- and a Set containing the group ids that are part of the current branch of the dependency tree in order -- to detect and ignore loops.-depclose :: (MonadError String m, MonadIO m) => [T.Text] -> [T.Text] -> SqlPersistT m DepFormula-depclose arches nevras = do- -- Convert each NEVRA into a group ID.- groupIds <- mapM getGroupId nevras-+depcloseGroupIds :: (MonadError String m, MonadIO m) => [T.Text] -> [Key Groups] -> SqlPersistT m DepFormula+depcloseGroupIds arches groupIds = do -- resolve each group id into a DepFormula -- Use foldM to pass the parents set from resolving one group into the next group, so we -- don't depclose things already depclosed from a previous group ID.
src/BDCS/Groups.hs view
@@ -38,7 +38,7 @@ import Data.Bifunctor(bimap) import Data.Conduit((.|), Conduit, Source) import qualified Data.Conduit.List as CL-import Data.Maybe(isNothing, fromJust, fromMaybe)+import Data.Maybe(isNothing, fromJust) import qualified Data.Text as T import Database.Esqueleto hiding (isNothing) @@ -120,7 +120,11 @@ if isNothing n || isNothing v || isNothing r || isNothing a then return Nothing- else return $ Just $ T.concat [fromMaybe "" e, fromJust n, "-", fromJust v, "-", fromJust r, ".", fromJust a]+ else return $ Just $ T.concat [fromJust n, "-", epoch e, fromJust v, "-", fromJust r, ".", fromJust a]+ where+ epoch :: Maybe T.Text -> T.Text+ epoch (Just e) = e `T.append` ":"+ epoch Nothing = "" getRequirementsForGroup :: MonadIO m => Key Groups -> RT.ReqContext -> SqlPersistT m [Requirements] getRequirementsForGroup groupId context = do
src/BDCS/Projects.hs view
@@ -17,7 +17,8 @@ module BDCS.Projects(findProject, getProject,- insertProject)+ insertProject,+ projects) where import Control.Monad.IO.Class(MonadIO)@@ -25,6 +26,13 @@ import Database.Esqueleto import BDCS.DB++projects :: MonadIO m => SqlPersistT m [Projects]+projects = do+ vals <- select $ from $ \project -> do+ orderBy [asc (project ^. ProjectsName)]+ return project+ return $ map entityVal vals findProject :: MonadIO m => T.Text -> SqlPersistT m (Maybe (Key Projects)) findProject name = firstKeyResult $
src/tests/BDCS/DepcloseSpec.hs view
@@ -31,7 +31,7 @@ import Test.Hspec import BDCS.DB(Files(..), GroupFiles(..), Groups(..))-import BDCS.Depclose(depclose)+import BDCS.Depclose(depcloseNEVRAs, depcloseNames) import BDCS.Depsolve(Formula(..)) import BDCS.GroupKeyValue(insertGroupKeyValue) import BDCS.KeyType(KeyType(..))@@ -47,69 +47,75 @@ let singleton_req = And [Atom (toSqlKey 1)] let solution_1 = Right $ And [singleton_req] it "depclose, singleton" $- withDeps (depclose arches ["singleton-1.0-1.x86_64"]) >>= (`shouldBe` solution_1)+ withDeps (depcloseNEVRAs arches ["singleton-1.0-1.x86_64"]) >>= (`shouldBe` solution_1) let simple_req = And [Atom (toSqlKey 2), Or [singleton_req]] let solution_2 = Right $ And [simple_req]- it "depclose, simple" $- withDeps (depclose arches ["simple-1.0-1.x86_64"]) >>= (`shouldBe` solution_2)+ it "depclose, simple NEVRA" $+ withDeps (depcloseNEVRAs arches ["simple-1.0-1.x86_64"]) >>= (`shouldBe` solution_2) + it "depclose, simple name" $+ withDeps (depcloseNames arches ["simple"]) >>= (`shouldBe` solution_2)+ let simple_chain_req = And [Atom (toSqlKey 3), Or [simple_req]] let solution_3 = Right $ And [simple_chain_req] it "depclose, simple-chain" $- withDeps (depclose arches ["simple-chain-1.0-1.x86_64"]) >>= (`shouldBe` solution_3)+ withDeps (depcloseNEVRAs arches ["simple-chain-1.0-1.x86_64"]) >>= (`shouldBe` solution_3) let provides_file_req = And [Atom (toSqlKey 4)] let needs_file_req = And [Atom (toSqlKey 5), Or [provides_file_req]] let solution_5 = Right $ And [needs_file_req] it "depclose, needs-file" $- withDeps (depclose arches ["needs-file-1.0-1.x86_64"]) >>= (`shouldBe` solution_5)+ withDeps (depcloseNEVRAs arches ["needs-file-1.0-1.x86_64"]) >>= (`shouldBe` solution_5) let conflicts_req = And [Atom (toSqlKey 6), Not (toSqlKey 1)] let solution_6 = Right $ And [conflicts_req] it "depclose, conflicts" $- withDeps (depclose arches ["conflicts-1.0-1.x86_64"]) >>= (`shouldBe` solution_6)+ withDeps (depcloseNEVRAs arches ["conflicts-1.0-1.x86_64"]) >>= (`shouldBe` solution_6) let obsolete_req = And [Atom (toSqlKey 7), Not (toSqlKey 1)] let solution_7 = Right $ And [obsolete_req] it "depclose, obsoletes" $- withDeps (depclose arches ["obsoletes-1.0-1.x86_64"]) >>= (`shouldBe` solution_7)+ withDeps (depcloseNEVRAs arches ["obsoletes-1.0-1.x86_64"]) >>= (`shouldBe` solution_7) let high_version_req = And [Atom (toSqlKey 10)] let need_version_req = And [Atom (toSqlKey 11), Or [high_version_req]] let solution_11 = Right $ And [need_version_req] it "depclose, versioned requirement" $- withDeps (depclose arches ["needs-version-1.0-1.x86_64"]) >>= (`shouldBe` solution_11)+ withDeps (depcloseNEVRAs arches ["needs-version-1.0-1.x86_64"]) >>= (`shouldBe` solution_11) let obsolete_version_req = And [Atom (toSqlKey 12), Not (toSqlKey 9)] let solution_12 = Right $ And [obsolete_version_req] it "depclose, versioned obsolete" $- withDeps (depclose arches ["obsoletes-version-1.0-1.x86_64"]) >>= (`shouldBe` solution_12)+ withDeps (depcloseNEVRAs arches ["obsoletes-version-1.0-1.x86_64"]) >>= (`shouldBe` solution_12) let loop_1_req = And [Atom (toSqlKey 14), Or [And [Atom (toSqlKey 15)]]] let solution_15 = Right $ And [loop_1_req] it "depclose, dependency cycle" $- withDeps (depclose arches ["loop-1-1.0-1.x86_64"]) >>= (`shouldBe` solution_15)+ withDeps (depcloseNEVRAs arches ["loop-1-1.0-1.x86_64"]) >>= (`shouldBe` solution_15) let choice_1_req = And [Atom (toSqlKey 17)] let choice_2_req = And [Atom (toSqlKey 18)] let choices_req = And [Atom (toSqlKey 16), Or [choice_1_req, choice_2_req]] let solution_16 = Right $ And [choices_req] it "depclose, multiple providers" $- withDeps (depclose arches ["choices-1.0-1.x86_64"]) >>= (`shouldBe` solution_16)+ withDeps (depcloseNEVRAs arches ["choices-1.0-1.x86_64"]) >>= (`shouldBe` solution_16) let solution_double = Right $ And [needs_file_req, singleton_req]- it "depclose, two things" $- withDeps (depclose arches ["singleton-1.0-1.x86_64", "needs-file-1.0-1.x86_64"]) >>= (`shouldBe` solution_double)+ it "depclose, two things NEVRAs" $+ withDeps (depcloseNEVRAs arches ["singleton-1.0-1.x86_64", "needs-file-1.0-1.x86_64"]) >>= (`shouldBe` solution_double) + it "depclose, two things names" $+ withDeps (depcloseNames arches ["singleton", "needs-file"]) >>= (`shouldBe` solution_double)+ it "depclose, no such requirement" $- withDeps (depclose arches ["no-such-requirement-1.0-1.x86_64"]) >>= (`shouldBe` Left "Unable to resolve requirement: DepRequirement \"does-not-exist\" Nothing")+ withDeps (depcloseNEVRAs arches ["no-such-requirement-1.0-1.x86_64"]) >>= (`shouldBe` Left "Unable to resolve requirement: DepRequirement \"does-not-exist\" Nothing") it "depclose, missing provides data" $- withDeps (depclose arches ["broken-conflicts-1.0-1.x86_64"]) >>= (`shouldBe` Left "Invalid key/val data")+ withDeps (depcloseNEVRAs arches ["broken-conflicts-1.0-1.x86_64"]) >>= (`shouldBe` Left "Invalid key/val data") it "depclose, no such package" $- withDeps (depclose arches ["does-not-exist-1.0-1.x86_64"]) >>= (`shouldBe` Left "No such group does-not-exist-1.0-1.x86_64")+ withDeps (depcloseNEVRAs arches ["does-not-exist-1.0-1.x86_64"]) >>= (`shouldBe` Left "No such group does-not-exist-1.0-1.x86_64") -- run tests with (mostly) real data -- this is more a demonstration of what's wrong with depclose than anything@@ -166,9 +172,12 @@ Or [ncurses_req], Or [glibc_req]] let bash_solution = Right $ And [bash_req]- it "depclose bash" $- withRealDeps (depclose arches ["bash-4.2.46-12.el7.x86_64"]) >>= (`shouldBe` bash_solution)+ it "depclose bash NEVRA" $+ withRealDeps (depcloseNEVRAs arches ["bash-4.2.46-12.el7.x86_64"]) >>= (`shouldBe` bash_solution) + it "depclose bash name" $+ withRealDeps (depcloseNames arches ["bash"]) >>= (`shouldBe` bash_solution)+ let glibc_req_2 = And [Atom (toSqlKey 1000), Or [nss_softokn_freebl_req], Or [glibc_common_req]]@@ -177,7 +186,7 @@ Or [glibc_req, glibc_req_2]] let bash_solution_2 = Right $ And [bash_req_2] it "depclose bash, two glibcs" $- withGlibcUpgrade (depclose arches ["bash-4.2.46-12.el7.x86_64"]) >>= (`shouldBe` bash_solution_2)+ withGlibcUpgrade (depcloseNEVRAs arches ["bash-4.2.46-12.el7.x86_64"]) >>= (`shouldBe` bash_solution_2) -- tar requirements, minus requirements already pulled in by bash (glibc, libselinux) let libattr_req = And [Atom (toSqlKey 16)]@@ -186,8 +195,11 @@ let tar_with_bash_req = And [Atom (toSqlKey 14), Or [libacl_req]] let tar_with_bash_solution = Right $ And [tar_with_bash_req, bash_req]- it "depclose bash and tar at the same time" $- withRealDeps (depclose arches ["bash-4.2.46-12.el7.x86_64", "tar-2:1.26-29.el7.x86_64"]) >>= (`shouldBe` tar_with_bash_solution)+ it "depclose bash and tar NEVRAs at the same time" $+ withRealDeps (depcloseNEVRAs arches ["bash-4.2.46-12.el7.x86_64", "tar-2:1.26-29.el7.x86_64"]) >>= (`shouldBe` tar_with_bash_solution)++ it "depclose bash and tar names at the same time" $+ withRealDeps (depcloseNames arches ["bash", "tar"]) >>= (`shouldBe` tar_with_bash_solution) where arches :: [T.Text] arches = ["x86_64"]
src/tests/BDCS/GroupsSpec.hs view
@@ -20,7 +20,7 @@ where import BDCS.DB(Groups(..))-import BDCS.Groups(nevraToGroupId)+import BDCS.Groups(groupIdToNevra, nevraToGroupId) import BDCS.GroupKeyValue(insertGroupKeyValue) import BDCS.KeyType(KeyType(..)) @@ -63,6 +63,12 @@ it "nevraToGroupId, wrong arch" $ withNevras (nevraToGroupId ("hasEpoch", Just "7", "1.0", "1.el7", "i686")) >>= (`shouldBe` Nothing)++ it "groupIdToNevra, has epoch" $+ withNevras (groupIdToNevra $ toSqlKey 1) >>= (`shouldBe` Just "hasEpoch-7:1.0-1.el7.x86_64")++ it "groupIdToNevra, no epoch" $+ withNevras (groupIdToNevra $ toSqlKey 2) >>= (`shouldBe` Just "noEpoch-1.0-1.el7.x86_64") where addNevras :: MonadIO m => SqlPersistT m ()
src/tools/depsolve.hs view
@@ -23,7 +23,7 @@ import System.Exit(exitFailure) import BDCS.DB(checkAndRunSqlite)-import BDCS.Depclose(depclose)+import BDCS.Depclose(depcloseNEVRAs) import BDCS.Depsolve(formulaToCNF, solveCNF) import BDCS.Groups(groupIdToNevra) import BDCS.Utils.Monad(mapMaybeM)@@ -34,7 +34,7 @@ runCommand db things = do let things' = map T.pack things result <- runExceptT $ checkAndRunSqlite (T.pack db) $ do- formula <- depclose ["x86_64"] things'+ formula <- depcloseNEVRAs ["x86_64"] things' solution <- solveCNF (formulaToCNF formula) -- solveCNF returns a list of (groupId, bool) assignments. Discard the False ones,
tests/test_depsolve.sh view
@@ -1,54 +1,52 @@ #!/bin/bash # Note: execute from the project root directory -set -x+. /usr/share/beakerlib/beakerlib.sh || exit 1 BDCS="./dist/build/bdcs/bdcs"--# when executed without parameters shows usage-if [[ `$BDCS depsolve` != "Usage: depsolve metadata.db NEVRA [NEVRA ...]" ]]; then- exit 1-fi--# when executed with non-existing DB returns non-zero-$BDCS depsolve /tmp/none.db httpd-if [[ $? == 0 ]]; then- echo "FAIL: Return code is zero"- exit 1-fi--### Prepare for testing depsolve against recipes- METADATA_DB="metadata.db" CS_REPO="/tmp/depsolve.repo"-sqlite3 $METADATA_DB < ../schema.sql -DNF_ROOT=`mktemp -d /tmp/dnf.root.XXXXXX`-DNF_DOWNLOAD=`mktemp -d /tmp/dnf.download.XXXXXX`+rlJournalStart+ rlPhaseStartSetup+ rlRun "sqlite3 $METADATA_DB < ../schema.sql"+ DNF_ROOT=`mktemp -d /tmp/dnf.root.XXXXXX`+ DNF_DOWNLOAD=`mktemp -d /tmp/dnf.download.XXXXXX`+ rlPhaseEnd -# first depsolve via dnf and download all the RPMs-sudo dnf install -y --nogpgcheck --releasever=26 --downloadonly --downloaddir=$DNF_DOWNLOAD --installroot=$DNF_ROOT httpd+ rlPhaseStartTest "When executed without parameters shows usage"+ output=`$BDCS depsolve`+ rlAssertEquals "Usage header is as expected" "$output" "Usage: depsolve metadata.db NEVRA [NEVRA ...]"+ rlPhaseEnd -# then import all RPMs-for F in $DNF_DOWNLOAD/*.rpm; do- $BDCS import $METADATA_DB $CS_REPO file://$F-done+ rlPhaseStartTest "When executed with non-existing DB returns non-zero"+ $BDCS depsolve /tmp/none.db httpd+ rlAssertNotEquals "Return code must be non-zero" $? 0+ rlPhaseEnd -# figure out the exact NEVRA for the httpd package-HTTPD_NEVRA=`find $DNF_DOWNLOAD -type f -name "httpd-2*.rpm" | cut -f4 -d/ | sed 's/\.rpm//'`+ rlPhaseStartTest "Depsolve sanity"+ rlLogInfo "Depsolve and download all the RPMs for httpd via DNF"+ rlRun "sudo dnf install -y --nogpgcheck --releasever=26 --downloadonly --downloaddir=$DNF_DOWNLOAD --installroot=$DNF_ROOT httpd" + rlLogInfo "Import all downloaded RPMs"+ for F in $DNF_DOWNLOAD/*.rpm; do+ rlRun -c -t "$BDCS import $METADATA_DB $CS_REPO file://$F"+ done -# when called with correct parameters-# then output contains input nevra-# and the return code is 0-OUTPUT=`$BDCS depsolve $METADATA_DB $HTTPD_NEVRA`-if [[ $? != 0 ]]; then- echo "FAIL: Return code is not zero"- exit 1-fi+ # figure out the exact NEVRA for the httpd package+ HTTPD_NEVRA=`find $DNF_DOWNLOAD -type f -name "httpd-2*.rpm" | cut -f4 -d/ | sed 's/\.rpm//'` -echo "$OUTPUT" | grep $HTTPD_NEVRA-if [ $? != 0 ]; then- echo "FAIL: httpd not included in depsolved list"- exit 1-fi+ # when called with correct parameters+ # then output contains input nevra+ # and the return code is 0+ OUTPUT=`$BDCS depsolve $METADATA_DB $HTTPD_NEVRA`+ rlAssert0 "depsolve return code must be zero" $?++ echo "$OUTPUT" | grep $HTTPD_NEVRA+ rlAssert0 "httpd included in depsolved list" $?+ rlPhaseEnd++ rlPhaseStartCleanup+ rm -rf $METADATA_DB $CS_REPO $DNF_ROOT $DNF_DOWNLOAD+ rlPhaseEnd+rlJournalEnd
tests/test_export.sh view
@@ -1,9 +1,12 @@ #!/bin/bash # Note: execute from the project root directory -set -x+. /usr/share/beakerlib/beakerlib.sh || exit 1 BDCS="./dist/build/bdcs/bdcs"+CS_REPO="./export.repo"+METADATA_DB="./export_metadata.db"+EXPORT_DIR="./exported-content.d/" function compare_with_rpm() { # Verify that contents of an exported directory have the same files as if@@ -15,180 +18,131 @@ RPM_CHROOT=`mktemp -d /tmp/rpm-chroot.XXXXXX` # install the RPMs with rpm- sudo rpm -Uhv --root $RPM_CHROOT --nodeps --noscripts $RPMS- if [[ $? != 0 ]]; then- echo "ERROR: rpm exit code should be zero"- exit 1- fi+ rlRun "sudo rpm -Uhv --root $RPM_CHROOT --nodeps --noscripts $RPMS" for BASE_FILE in `find $RPM_CHROOT -type f`; do ### skip some files because the rpm -Uhv will produce ### different content for them and cause the test to fail if [[ "$BASE_FILE" == */etc/shadow ]]; then- echo "INFO: skipping $BASE_FILE ..."+ rlLogInfo "skipping $BASE_FILE ..." continue fi if [[ "$BASE_FILE" == */etc/gshadow ]]; then- echo "INFO: skipping $BASE_FILE ..."+ rlLogInfo "skipping $BASE_FILE ..." continue fi if [[ "$BASE_FILE" == */etc/passwd ]]; then- echo "INFO: skipping $BASE_FILE ..."+ rlLogInfo "skipping $BASE_FILE ..." continue fi if [[ "$BASE_FILE" == */etc/group ]]; then- echo "INFO: skipping $BASE_FILE ..."+ rlLogInfo "skipping $BASE_FILE ..." continue fi if [[ "$BASE_FILE" == */var/lib/rpm/* ]]; then- echo "INFO: skipping $BASE_FILE ..."+ rlLogInfo "skipping $BASE_FILE ..." continue fi if [[ "$BASE_FILE" == *.pyc ]]; then- echo "INFO: skipping $BASE_FILE ..."+ rlLogInfo "skipping $BASE_FILE ..." continue fi - echo "INFO: examining $BASE_FILE ..."- EXPECTED_FILE=`echo $BASE_FILE | sed "s|$RPM_CHROOT|$EXPORT_DIR|" | tr -s '/'`+ rlLogInfo "examining $BASE_FILE ..." - if [[ ! -f "$EXPECTED_FILE" ]]; then- echo "ERROR: $EXPECTED_FILE doesn't exist"- exit 1- fi+ EXPECTED_FILE=`echo $BASE_FILE | sed "s|$RPM_CHROOT|$EXPORT_DIR|" | tr -s '/'`+ rlAssertExists "$EXPECTED_FILE" BASE_SHA256=`sha256sum $BASE_FILE | cut -f1 -d' '` EXPECTED_SHA256=`sha256sum $EXPECTED_FILE | cut -f1 -d' '` if [[ $BASE_SHA256 != $EXPECTED_SHA256 ]]; then- echo "ERROR: $BASE_SHA256($BASE_FILE) != $EXPECTED_SHA256($EXPECTED_FILE)"- diff -u $BASE_FILE $EXPECTED_FILE- exit 1+ rlLogError "$BASE_SHA256($BASE_FILE) != $EXPECTED_SHA256($EXPECTED_FILE)"+ rlRun "diff -u $BASE_FILE $EXPECTED_FILE"+ rlFail fi done sudo rm -rf $RPM_CHROOT } --# when executed without parameters shows usage-if [[ `$BDCS export | head -n 2 | tail -n 1` != "Usage: export metadata.db repo dest thing [thing ...]" ]]; then- exit 1-fi--############################################################-### Prepare for testing export functionality--CS_REPO="./export.repo"-METADATA_DB="./export_metadata.db"-EXPORT_DIR="./exported-content.d/"--sqlite3 $METADATA_DB < ../schema.sql--# filesystem package is required by the exporter-wget http://mirror.centos.org/centos/7/os/x86_64/Packages/filesystem-3.2-21.el7.x86_64.rpm && \- $BDCS import $METADATA_DB $CS_REPO file://`pwd`/filesystem-3.2-21.el7.x86_64.rpm-# setup package is required since 5834760-wget http://mirror.centos.org/centos/7/os/x86_64/Packages/setup-2.8.71-7.el7.noarch.rpm && \- $BDCS import $METADATA_DB $CS_REPO file://`pwd`/setup-2.8.71-7.el7.noarch.rpm--############################################################-## When exporting a non-existing package-## Then returns an error--OUTPUT=`sudo $BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 NON-EXISTING`-if [[ $? == 0 ]]; then- echo "ERROR: On error exit code should not be zero"- exit 1-fi--if [[ "$OUTPUT" != '"No such group NON-EXISTING"' ]]; then- echo "ERROR: Error output doesn't match"- exit 1-fi--sudo rm -rf $EXPORT_DIR--############################################################-## When exporting existing package-## Then exported contents match what's inside the RPM package+rlJournalStart+ rlPhaseStartSetup+ rlRun "sqlite3 $METADATA_DB < ../schema.sql"+ # filesystem package is required by the exporter+ rlRun -t -c "wget http://mirror.centos.org/centos/7/os/x86_64/Packages/filesystem-3.2-21.el7.x86_64.rpm"+ rlRun "$BDCS import $METADATA_DB $CS_REPO file://`pwd`/filesystem-3.2-21.el7.x86_64.rpm" -wget http://mirror.centos.org/centos/7/os/x86_64/Packages/yum-rhn-plugin-2.0.1-9.el7.noarch.rpm && \- $BDCS import $METADATA_DB $CS_REPO file://`pwd`/yum-rhn-plugin-2.0.1-9.el7.noarch.rpm+ # setup package is required since 5834760+ rlRun -t -c "wget http://mirror.centos.org/centos/7/os/x86_64/Packages/setup-2.8.71-7.el7.noarch.rpm"+ rlRun "$BDCS import $METADATA_DB $CS_REPO file://`pwd`/setup-2.8.71-7.el7.noarch.rpm" -sudo $BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch yum-rhn-plugin-2.0.1-9.el7.noarch-if [[ $? != 0 ]]; then- echo "ERROR: Exit code should be zero"- exit 1-fi+ rlRun -t -c "wget http://mirror.centos.org/centos/7/os/x86_64/Packages/yum-rhn-plugin-2.0.1-9.el7.noarch.rpm"+ rlRun "$BDCS import $METADATA_DB $CS_REPO file://`pwd`/yum-rhn-plugin-2.0.1-9.el7.noarch.rpm" -compare_with_rpm $EXPORT_DIR filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm yum-rhn-plugin-2.0.1-9.el7.noarch.rpm-sudo rm -rf $EXPORT_DIR+ # these two packages both provide /usr/lib64/libcmpiCppImpl.so+ # normally libcmpiCppImpl0 lives in the @conflicts group+ rlRun -t -c "wget http://mirror.centos.org/centos/7/os/x86_64/Packages/tog-pegasus-libs-2.14.1-5.el7.x86_64.rpm"+ rlRun "$BDCS import $METADATA_DB $CS_REPO file://`pwd`/tog-pegasus-libs-2.14.1-5.el7.x86_64.rpm"+ rlRun -t -c "wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libcmpiCppImpl0-2.0.3-5.el7.x86_64.rpm"+ rlRun "$BDCS import $METADATA_DB $CS_REPO file://`pwd`/libcmpiCppImpl0-2.0.3-5.el7.x86_64.rpm"+ rlPhaseEnd -############################################################-## When exporting existing package into .tar image-## Then untarred contents match the contents of RPM+ rlPhaseStartTest "when executed without parameters shows usage"+ OUTPUT=`$BDCS export | head -n 2 | tail -n 1`+ rlAssertEquals "Usage header as expected" "$OUTPUT" "Usage: export metadata.db repo dest thing [thing ...]"+ rlPhaseEnd -sudo $BDCS export $METADATA_DB $CS_REPO exported.tar filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch yum-rhn-plugin-2.0.1-9.el7.noarch-if [[ $? != 0 ]]; then- echo "ERROR: Exit code should be zero"- exit 1-fi+ rlPhaseStartTest "When exporting a non-existing package returns an error"+ OUTPUT=`sudo $BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 NON-EXISTING`+ rlAssertNotEquals "On error exit code should not be zero" $? 0+ rlAssertEquals "On error output is as expected" "$OUTPUT" '"No such group NON-EXISTING"' -mkdir tar_contents && pushd tar_contents/ && tar xvf ../exported.tar && popd-compare_with_rpm tar_contents/ filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm yum-rhn-plugin-2.0.1-9.el7.noarch.rpm-sudo rm -rf tar_contents/ exported.tar+ sudo rm -rf $EXPORT_DIR+ rlPhaseEnd -############################################################-## When exporting two conflicting packages-## And they conflict on a symlink-## Then (since 5834760) the first symlink to be exported wins--# in libcmpiCppImpl0:-# libcmpiCppImpl.so and libcmpiCppImpl.so.0 are symlinks to libcmpiCppImpl.so.0.0.0--# in tog-pegasus-libs:-# libcmpiCppImpl.so is a symlink to libcmpiCppImpl.so.1--# the conflicting file is the libcmpiCppImpl.so symlink+ rlPhaseStartTest "When exporting existing package exported contents match what's inside the RPM"+ rlRun "sudo $BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch yum-rhn-plugin-2.0.1-9.el7.noarch"+ compare_with_rpm $EXPORT_DIR filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm yum-rhn-plugin-2.0.1-9.el7.noarch.rpm+ sudo rm -rf $EXPORT_DIR+ rlPhaseEnd + rlPhaseStartTest "When exporting existing package into .tar image untarred contents match the contents of RPM"+ rlRun "sudo $BDCS export $METADATA_DB $CS_REPO exported.tar filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch yum-rhn-plugin-2.0.1-9.el7.noarch" -# these two packages both provide /usr/lib64/libcmpiCppImpl.so-# normally libcmpiCppImpl0 lives in the @conflicts group-wget http://mirror.centos.org/centos/7/os/x86_64/Packages/tog-pegasus-libs-2.14.1-5.el7.x86_64.rpm && \- $BDCS import $METADATA_DB $CS_REPO file://`pwd`/tog-pegasus-libs-2.14.1-5.el7.x86_64.rpm-wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libcmpiCppImpl0-2.0.3-5.el7.x86_64.rpm && \- $BDCS import $METADATA_DB $CS_REPO file://`pwd`/libcmpiCppImpl0-2.0.3-5.el7.x86_64.rpm+ mkdir tar_contents && pushd tar_contents/ && tar xvf ../exported.tar && popd+ compare_with_rpm tar_contents/ filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm yum-rhn-plugin-2.0.1-9.el7.noarch.rpm+ sudo rm -rf tar_contents/ exported.tar+ rlPhaseEnd -# first libcmpiCppImpl0, second tog-pegasus-libs-sudo $BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch libcmpiCppImpl0-2.0.3-5.el7.x86_64 tog-pegasus-libs-2:2.14.1-5.el7.x86_64 2>&1-if [[ $? != 0 ]]; then- echo "ERROR: Exit code should be zero"- exit 1-fi+ rlPhaseStartTest "When exporting two conflicting packages on a symlink the first symlink to be exported wins"+ # in libcmpiCppImpl0:+ # libcmpiCppImpl.so and libcmpiCppImpl.so.0 are symlinks to libcmpiCppImpl.so.0.0.0 -# conflict is in tog-pegasus-libs which is the second package in the list-# make sure libcmpiCppImpl0 wins-compare_with_rpm $EXPORT_DIR filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm libcmpiCppImpl0-2.0.3-5.el7.x86_64.rpm-sudo rm -rf $EXPORT_DIR+ # in tog-pegasus-libs:+ # libcmpiCppImpl.so is a symlink to libcmpiCppImpl.so.1 + # first libcmpiCppImpl0, second tog-pegasus-libs+ rlRun "$BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch libcmpiCppImpl0-2.0.3-5.el7.x86_64 tog-pegasus-libs-2:2.14.1-5.el7.x86_64 2>&1"+ # conflict is in tog-pegasus-libs which is the second package in the list+ # make sure libcmpiCppImpl0 wins+ compare_with_rpm $EXPORT_DIR filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm libcmpiCppImpl0-2.0.3-5.el7.x86_64.rpm+ sudo rm -rf $EXPORT_DIR -# first tog-pegasus-libs, second libcmpiCppImpl0-sudo $BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch tog-pegasus-libs-2:2.14.1-5.el7.x86_64 libcmpiCppImpl0-2.0.3-5.el7.x86_64-if [[ $? != 0 ]]; then- echo "ERROR: Exit code should be zero"- exit 1-fi+ # first tog-pegasus-libs, second libcmpiCppImpl0+ rlRun "sudo $BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch tog-pegasus-libs-2:2.14.1-5.el7.x86_64 libcmpiCppImpl0-2.0.3-5.el7.x86_64" -# conflict is in libcmpiCppImpl0 which is the second package in the list-# make sure tog-pegasus wins-compare_with_rpm $EXPORT_DIR filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm tog-pegasus-libs-2.14.1-5.el7.x86_64.rpm-sudo rm -rf $EXPORT_DIR+ # conflict is in libcmpiCppImpl0 which is the second package in the list+ # make sure tog-pegasus wins+ compare_with_rpm $EXPORT_DIR filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm tog-pegasus-libs-2.14.1-5.el7.x86_64.rpm+ sudo rm -rf $EXPORT_DIR+ rlPhaseEnd+rlJournalEnd
tests/test_import.sh view
@@ -1,37 +1,37 @@ #!/bin/bash # Note: execute from the project root directory -set -x+. /usr/share/beakerlib/beakerlib.sh || exit 1 BDCS="./dist/build/bdcs/bdcs"--# when executed without parameters shows usage-if [[ `$BDCS import | head -n 2 | tail -n 1` != "Usage: import output.db repo thing [thing ...]" ]]; then- exit 1-fi- METADATA_DB="./import_metadata.db"-sqlite3 $METADATA_DB < ../schema.sql CENTOS_REPO="centos.repo" -### test that we can import a single RPM from local disk-wget http://mirror.centos.org/centos/7/os/x86_64/Packages/setup-2.8.71-7.el7.noarch.rpm && \- $BDCS import $METADATA_DB $CENTOS_REPO file://`pwd`/setup-2.8.71-7.el7.noarch.rpm-if [ $? -ne 0 ]; then- echo "ERROR: importing from local disk failed"- exit 1-fi -### test that we can import a single RPM from HTTPS URL-$BDCS import $METADATA_DB $CENTOS_REPO https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/a/abc-1.01-9.hg20160905.el7.x86_64.rpm-if [ $? -ne 0 ]; then- echo "ERROR: importing from HTTPS URL failed"- exit 1-fi+rlJournalStart+ rlPhaseStartSetup+ rlRun "sqlite3 $METADATA_DB < ../schema.sql"+ rlPhaseEnd -### test that we can import entire repository from HTTPS URL-$BDCS import $METADATA_DB $CENTOS_REPO https://s3.amazonaws.com/weldr/https-import-repo/-if [ $? -ne 0 ]; then- echo "ERROR: importing from HTTPS REPO failed"- exit 1-fi+ rlPhaseStartTest "When executed without parameters shows usage"+ output=`$BDCS import | head -n 2 | tail -n 1`+ rlAssertEquals "Usage header as expected" "$output" "Usage: import output.db repo thing [thing ...]"+ rlPhaseEnd++ rlPhaseStartTest "Can import a single RPM from local disk"+ rlRun -t -c "wget http://mirror.centos.org/centos/7/os/x86_64/Packages/setup-2.8.71-7.el7.noarch.rpm"+ rlRun -t -c "$BDCS import $METADATA_DB $CENTOS_REPO file://`pwd`/setup-2.8.71-7.el7.noarch.rpm"+ rlPhaseEnd++ rlPhaseStartTest "Can import a single RPM from HTTPS URL"+ rlRun -t -c "$BDCS import $METADATA_DB $CENTOS_REPO https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/a/abc-1.01-9.hg20160905.el7.x86_64.rpm"+ rlPhaseEnd++ rlPhaseStartTest "Can import entire repository from HTTPS URL"+ rlRun -t -c "$BDCS import $METADATA_DB $CENTOS_REPO https://s3.amazonaws.com/weldr/https-import-repo/"+ rlPhaseEnd++ rlPhaseStartCleanup+ rm -rf $CENTOS_REPO $METADATA_DB *.rpm+ rlPhaseEnd+rlJournalEnd
tests/test_tmpfiles.sh view
@@ -1,21 +1,22 @@ #!/bin/bash # Note: execute from the project root directory -set -x+. /usr/share/beakerlib/beakerlib.sh || exit 1 CMD="./dist/build/bdcs-tmpfiles/bdcs-tmpfiles" CFG="./data/tmpfiles-default.conf" TMPDIR="./test-tmpfiles-$$" -err_cleanup() {- rm -rf "$TMPDIR"- exit 1-}--$CMD $CFG $TMPDIR || err_cleanup+rlJournalStart+ rlPhaseStartTest+ rlRun -t -c "$CMD $CFG $TMPDIR" -[ -d "$TMPDIR" ] || err_cleanup-[ -e "$TMPDIR/var/run" ] || err_cleanup-[ -d "$TMPDIR/usr/lib/debug/usr/lib64" ] || err_cleanup+ rlAssertExists "$TMPDIR"+ rlAssertExists "$TMPDIR/var/run"+ rlAssertExists "$TMPDIR/usr/lib/debug/usr/lib64"+ rlPhaseEnd -rm -rf "$TMPDIR"+ rlPhaseStartCleanup+ rm -rf $TMPDIR+ rlPhaseEnd+rlJournalEnd