packages feed

bdcs 0.1.0 → 0.1.1

raw patch · 17 files changed

+278/−246 lines, 17 files

Files

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