summaryrefslogtreecommitdiff
path: root/yarns
diff options
context:
space:
mode:
Diffstat (limited to 'yarns')
-rw-r--r--yarns/building.yarn2
-rw-r--r--yarns/deployment.yarn9
-rw-r--r--yarns/implementations.yarn192
-rw-r--r--yarns/regression.yarn2
-rw-r--r--yarns/splitting.yarn129
5 files changed, 325 insertions, 9 deletions
diff --git a/yarns/building.yarn b/yarns/building.yarn
index 5b6b29a0..cc45df65 100644
--- a/yarns/building.yarn
+++ b/yarns/building.yarn
@@ -6,4 +6,4 @@ Morph Building Tests
AND a git server
WHEN the user checks out the system branch called master
AND the user creates an uncommitted system morphology called base-system for our architecture in system branch master
- THEN morph build the system base-system of the branch master of the repo test:morphs
+ THEN morph build the system base-system of the branch master
diff --git a/yarns/deployment.yarn b/yarns/deployment.yarn
index 35f933b7..855ecc52 100644
--- a/yarns/deployment.yarn
+++ b/yarns/deployment.yarn
@@ -8,3 +8,12 @@ Morph Deployment Tests
AND the user attempts to deploy the system test-system in branch master
THEN morph failed
AND the deploy error message includes the string "morph deploy is only supported for cluster morphologies"
+
+ SCENARIO deploying a cluster morphology
+ GIVEN a workspace
+ AND a git server
+ WHEN the user checks out the system branch called master
+ GIVEN a cluster called test-cluster for deploying only the test-system system as type tar in system branch master
+ WHEN the user builds the system test-system in branch master
+ AND the user attempts to deploy the cluster test-cluster in branch master with options system.location=test.tar
+ THEN morph succeeded
diff --git a/yarns/implementations.yarn b/yarns/implementations.yarn
index 0fad95be..5b9b39df 100644
--- a/yarns/implementations.yarn
+++ b/yarns/implementations.yarn
@@ -30,6 +30,14 @@ we can test it later in a THEN step.
0) die "Morph should have failed, but didn't. Unexpected success!" ;;
esac
+ IMPLEMENTS THEN morph succeeded
+ case $(cat "$DATADIR/morph-exit") in
+ 0) echo "Morph succeeded!"
+ ;;
+ *) die "Morph should have succeeded, but didn't. Unexpected failure!"
+ ;;
+ esac
+
We need to check that a workspace creation worked. This requires the
directory to exist, and its `.morph` subdirectory to exist, and nothing
else.
@@ -96,10 +104,142 @@ another to hold a chunk.
mkdir "$DATADIR/gits/test-chunk"
- cat << EOF > "$DATADIR/gits/test-chunk/test-chunk.morph"
+ # To verify that chunk splitting works, we have a chunk that installs
+ # dummy files in all the places that different kinds of files are
+ # usually installed. e.g. executables in `/bin` and `/usr/bin`
+
+ cat << 'EOF' > "$DATADIR/gits/test-chunk/test-chunk.morph"
name: test-chunk
kind: chunk
- build-system: dummy
+ build-system: manual
+
+ # `install-commands` is a list of shell commands to run. Commands
+ # may be on multiple lines, and indeed anything programmatic will
+ # benefit from doing so. Arguably we could have just one command,
+ # but it's split into multiple so that morph can inform us which
+ # command failed without us having to include a lot of status
+ # information in the command and look at the error message.
+
+ install-commands:
+
+ # It's important that we can test whether executables get
+ # installed, so we install an empty script into `/usr/bin/test` and
+ # `/usr/sbin/test`.
+
+ # `install -D` will create the leading components for us, and install
+ # defaults to creating the file with its executable bit set.
+
+ # `install` needs a source file to install, but since we only care
+ # that the file exists, rather than its contents, we can use /dev/null
+ # as the source.
+
+ - |
+ for bindir in bin sbin; do
+ install -D /dev/null "$DESTDIR/$PREFIX/$bindir/test"
+ done
+
+ # We need shared libraries too, sometimes they're libraries to support
+ # the executables that a chunk provides, sometimes for other chunks.
+
+ # Libraries can be found in a variety of places, hence why we install
+ # them into lib, lib32 and lib64.
+
+ # Shared libraries' file names start with lib and end with `.so`
+ # for shared-object, with version numbers optionally suffixed.
+
+ - |
+ for libdir in lib lib32 lib64; do
+ dirpath="$DESTDIR/$PREFIX/$libdir"
+ install -D /dev/null "$dirpath/libtest.so"
+ ln -s libtest.so "$dirpath/libtest.so.0"
+ ln -s libtest.so.0 "$dirpath/libtest.so.0.0"
+ ln -s libtest.so.0.0 "$dirpath/libtest.so.0.0.0"
+ done
+
+ # Shared objects aren't the only kind of library, some executable
+ # binaries count as libraries, such as git's plumbing commands.
+
+ # In some distributions they go into /lib, in others, and the default
+ # autotools configuration, they go into /libexec.
+
+ - |
+ install -D /dev/null "$DESTDIR/$PREFIX/libexec/test-bin"
+
+ # As well as run-time libraries, there's development files. For C
+ # this is headers, which describe the API of the libraries, which
+ # then use the shared objects, and other files which are needed
+ # to build the executables, but aren't needed to run them, such as
+ # static libraries.
+
+ # Header files go into `include` and end with `.h`. They are not
+ # executable, so the install command changes the permissions with the
+ # `-m` option.
+
+ - |
+ install -D -m 644 /dev/null "$DESTDIR/$PREFIX/include/test.h"
+
+ # `pkg-config` is a standard way to locate libraries and get the
+ # compiler flags needed to build with the library. It's also used
+ # for other configuration for packages that don't install binaries,
+ # so as well as being found in `lib/pkgconfig`, it can be found in
+ # `share/pkgconfig`, so we install dummy files to both.
+
+ - |
+ for pkgdir in lib lib32 lib64 share; do
+ install -D -m 644 /dev/null \
+ "$DESTDIR/$PREFIX/$pkgdir/pkgconfig/test.pc"
+ done
+
+ # Static libraries can be used to build static binaries, which don't
+ # require their dependencies to be installed. They are typically in
+ # the form of `.a` archive and `.la` libtool archives.
+
+ - |
+ for libdir in lib lib32 lib64; do
+ for libname in libtest.a libtest.la; do
+ install -D -m 644 /dev/null "$DESTDIR/$PREFIX/$libdir/$libname"
+ done
+ done
+
+ # Packages may also install documentation, this comes in a variety
+ # of formats, but info pages, man pages and html documentation are
+ # the most common.
+
+ - |
+ for docfile in info/test.info.gz man/man3/test.3.gz doc/test/doc.html; do
+ install -D -m 644 /dev/null "$DESTDIR/$PREFIX/share/$docfile"
+ done
+
+ # Locale covers translations, timezones, keyboard layouts etc. in
+ # all manner of strange file formats and locations.
+
+ # Locale provides various translations for specific messages.
+
+ - |
+ install -D -m 644 /dev/null \
+ "$DESTDIR/$PREFIX/share/locale/en_GB/LC_MESSAGES/test.mo"
+
+ # Internationalisation (i18n) includes character maps and other data
+ # such as currency.
+
+ - |
+ for localefile in i18n/locales/en_GB charmaps/UTF-8.gz; do
+ install -D -m 644 /dev/null "$DESTDIR/$PREFIX/share/$localefile"
+ done
+
+ # Timezones are another kind of localisation.
+
+ - |
+ install -D -m 644 /dev/null "$DESTDIR/$PREFIX/share/zoneinfo/UTC"
+
+ # We also need a catch rule for everything that doesn't fit into
+ # the above categories, so to test that, we create some files that
+ # don't belong in one.
+
+ - |
+ for cfgfile in test.conf README; do
+ install -D -m 644 /dev/null "$DESTDIR/$PREFIX/etc/test.d/$cfgfile"
+ done
EOF
run_in "$DATADIR/gits/test-chunk" git init .
@@ -524,11 +664,40 @@ Implementation sections for cross-bootstraping
Implementation sections for deployment
======================================
- IMPLEMENTS WHEN the user (attempts to deploy|deploys) the (system|cluster) (\S+) in branch (\S+)
+Defaults are set in the cluster morphology, so we can deploy without
+setting any extra parameters, but we also need to be able to override
+them, so they can be added to the end of the implements section.
+
+ IMPLEMENTS WHEN the user (attempts to deploy|deploys) the (system|cluster) (\S+) in branch (\S+)( with options (.*))?
cd "$DATADIR/workspace/$MATCH_4"
- set build "$MATCH_3"
+ set -- deploy "$MATCH_3"
+ if [ "$MATCH_5" != '' ]; then
+ # eval used so word splitting in the text is preserved
+ eval set -- '"$@"' $MATCH_6
+ fi
if [ $MATCH_1 == "deploys" ]; then run_morph "$@"
- else attempt_morph deploy "$MATCH_3"; fi
+ else attempt_morph "$@"; fi
+
+To successfully deploy systems, we need a cluster morphology. Since the
+common case is to just have one system, we generate a stub morphology
+with only the minimal information.
+
+ IMPLEMENTS GIVEN a cluster called (\S+) for deploying only the (\S+) system as type (\S+) in system branch (\S+)
+ name="$MATCH_1"
+ system="$MATCH_2"
+ type="$MATCH_3"
+ branch="$MATCH_4"
+ cat << EOF > "$DATADIR/workspace/$branch/test:morphs/$name.morph"
+ name: $name
+ kind: cluster
+ systems:
+ - morph: $system
+ repo: test:morphs
+ ref: $branch
+ deploy:
+ system:
+ type: $type
+ EOF
Implementations sections for reading error messages
===================================================
@@ -616,6 +785,15 @@ variables in `$DATADIR/env`. We treat the value as a format string for
Implementations for building systems
------------------------------------
- IMPLEMENTS THEN morph build the system (\S+) of the (branch|tag) (\S+) of the repo (\S+)
- cd "$DATADIR/workspace/$MATCH_3/$MATCH_4"
+ IMPLEMENTS THEN morph build the system (\S+) of the (branch|tag) (\S+)
+ cd "$DATADIR/workspace/$MATCH_3"
run_morph build "$MATCH_1"
+
+Implementations for tarball inspection
+--------------------------------------
+
+ IMPLEMENTS THEN tarball (\S+) contains (.*)
+ tar -tf "$DATADIR/$MATCH_1" | grep -Fe "$MATCH_2"
+
+ IMPLEMENTS THEN tarball (\S+) doesn't contain (.*)
+ ! tar -tf "$DATADIR/$MATCH_1" | grep -Fe "$MATCH_2"
diff --git a/yarns/regression.yarn b/yarns/regression.yarn
index eae01343..49c663ec 100644
--- a/yarns/regression.yarn
+++ b/yarns/regression.yarn
@@ -10,7 +10,7 @@ Testing if we can build after checking out from a tag.
GIVEN a workspace
AND a git server
WHEN the user checks out the system tag called test-tag
- THEN morph build the system test-system of the tag test-tag of the repo test:morphs
+ THEN morph build the system test-system of the tag test-tag
Running `morph branch` when the branch directory exists doesn't
diff --git a/yarns/splitting.yarn b/yarns/splitting.yarn
new file mode 100644
index 00000000..e3324190
--- /dev/null
+++ b/yarns/splitting.yarn
@@ -0,0 +1,129 @@
+Artifact splitting tests
+========================
+
+ SCENARIO building a system with morphologies that have splitting rules
+ GIVEN a workspace
+ AND a git server
+
+ AND chunk test-chunk includes the default splitting rules
+ AND stratum test-stratum includes the default splitting rules
+ AND system test-system includes the default splitting rules
+
+ WHEN the user checks out the system branch called master
+ THEN morph build the system test-system of the branch master
+
+
+
+ SCENARIO building a system only using runtime strata
+ GIVEN a workspace
+ AND a git server
+ AND system test-system only uses test-stratum-runtime from test-stratum
+ WHEN the user checks out the system branch called master
+ GIVEN a cluster called test-cluster for deploying only the test-system system as type tar in system branch master
+ WHEN the user builds the system test-system in branch master
+ AND the user attempts to deploy the cluster test-cluster in branch master with options system.location="$DATADIR/test.tar"
+ THEN tarball test.tar contains bin/test
+ AND tarball test.tar contains lib/libtest.so
+ AND tarball test.tar doesn't contain lib/libtest.a
+ AND tarball test.tar doesn't contain man/man3/test.3.gz
+
+Implementations
+---------------
+
+ IMPLEMENTS GIVEN chunk (\S+) includes the default splitting rules
+ # Append default products rules
+ cat <<EOF >>"$DATADIR/gits/$MATCH_1/$MATCH_1.morph"
+ products:
+ - artifact: $MATCH_1-bins
+ include: [ "(usr/)?s?bin/.*" ]
+ - artifact: $MATCH_1-libs
+ include:
+ - (usr/)?lib(32|64)?/lib[^/]*\.so(\.\d+)*
+ - (usr/)?libexec/.*
+ - artifact: $MATCH_1-devel
+ include:
+ - (usr/)?include/.*
+ - (usr/)?lib(32|64)?/lib.*\.a
+ - (usr/)?lib(32|64)?/lib.*\.la
+ - (usr/)?(lib(32|64)?|share)/pkgconfig/.*\.pc
+ - artifact: $MATCH_1-doc
+ include:
+ - (usr/)?share/doc/.*
+ - (usr/)?share/man/.*
+ - (usr/)?share/info/.*
+ - artifact: $MATCH_1-locale
+ include:
+ - (usr/)?share/locale/.*
+ - (usr/)?share/i18n/.*
+ - (usr/)?share/zoneinfo/.*
+ - artifact: $MATCH_1-misc
+ include: [ .* ]
+ EOF
+ run_in "$DATADIR/gits/$MATCH_1" git add "$MATCH_1.morph"
+ run_in "$DATADIR/gits/$MATCH_1" git commit -m 'Add default splitting rules'
+
+ IMPLEMENTS GIVEN stratum (\S+) includes the default splitting rules
+ # Append default products rules
+ cat <<EOF >"$DATADIR/gits/morphs/$MATCH_1.morph"
+ name: $MATCH_1
+ kind: stratum
+ products:
+ - artifact: $MATCH_1-devel
+ include:
+ - .*-devel
+ - .*-debug
+ - .*-doc
+ - artifact: $MATCH_1-runtime
+ include:
+ - .*-bins
+ - .*-libs
+ - .*-locale
+ - .*-misc
+ - .*
+ chunks:
+ - name: test-chunk
+ repo: test:test-chunk
+ ref: master
+ morph: test-chunk
+ build-mode: test
+ build-depends: []
+ artifacts:
+ test-chunk-bins: $MATCH_1-runtime
+ test-chunk-libs: $MATCH_1-runtime
+ test-chunk-locale: $MATCH_1-runtime
+ test-chunk-misc: $MATCH_1-runtime
+ test-chunk-devel: $MATCH_1-devel
+ test-chunk-doc: $MATCH_1-devel
+ EOF
+ run_in "$DATADIR/gits/morphs" git add "$MATCH_1.morph"
+ run_in "$DATADIR/gits/morphs" git commit -m 'Add default splitting rules'
+
+ IMPLEMENTS GIVEN system (\S+) includes the default splitting rules
+ cat << EOF > "$DATADIR/gits/morphs/$MATCH_1.morph"
+ name: $MATCH_1
+ kind: system
+ arch: $(run_morph print-architecture)
+ strata:
+ - name: test-stratum
+ repo: test:morphs
+ ref: master
+ morph: test-stratum
+ artifacts:
+ - test-stratum-runtime
+ - test-stratum-devel
+ EOF
+ run_in "$DATADIR/gits/morphs" git add "$MATCH_1.morph"
+ run_in "$DATADIR/gits/morphs" git commit -m 'Add default splitting rules'
+
+ IMPLEMENTS GIVEN system (\S+) only uses (\S+) from (\S+)
+ python -c 'import sys, yaml
+ with open(sys.argv[1], "r") as f:
+ d = yaml.load(f)
+ for spec in d["strata"]:
+ if spec["name"] == sys.argv[3]:
+ spec["artifacts"] = [sys.argv[2]]
+ with open(sys.argv[1], "w") as f:
+ yaml.dump(d, f)
+ ' "$DATADIR/gits/morphs/$MATCH_1.morph" "$MATCH_2" "$MATCH_3"
+ run_in "$DATADIR/gits/morphs" git add "$MATCH_1.morph"
+ run_in "$DATADIR/gits/morphs" git commit -m "Make $MATCH_1 only use $MATCH_2"