summaryrefslogtreecommitdiff
path: root/yarns/implementations.yarn
diff options
context:
space:
mode:
Diffstat (limited to 'yarns/implementations.yarn')
-rw-r--r--yarns/implementations.yarn356
1 files changed, 356 insertions, 0 deletions
diff --git a/yarns/implementations.yarn b/yarns/implementations.yarn
new file mode 100644
index 00000000..6c0ef6e2
--- /dev/null
+++ b/yarns/implementations.yarn
@@ -0,0 +1,356 @@
+IMPLEMENTS implementations
+==========================
+
+Implementation sections for workspaces
+--------------------------------------
+
+We'll use `$DATADIR/workspace` as the workspace directory that is used.
+
+ IMPLEMENTS GIVEN no workspace
+ true
+
+ IMPLEMENTS GIVEN an empty workspace directory
+ mkdir "$DATADIR/workspace"
+
+ IMPLEMENTS GIVEN a non-empty workspace directory
+ mkdir "$DATADIR/workspace"
+ touch "$DATADIR/workspace/random-file"
+
+We run `morph init` in two different ways: either the simple way,
+letting yarn catch errors, or in a way that catches the error so
+we can test it later in a THEN step.
+
+ IMPLEMENTS WHEN morph initialises a workspace
+ run_morph init "$DATADIR/workspace"
+
+ IMPLEMENTS WHEN morph attempts to initialise a workspace
+ attempt_morph init "$DATADIR/workspace"
+
+ IMPLEMENTS THEN morph failed
+ case $(cat "$DATADIR/morph-exit") in
+ 0) die "Morph should have failed, but didn't. Unexpected success!" ;;
+ 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.
+
+ IMPLEMENTS THEN an empty workspace exists
+ is_dir "$DATADIR/workspace"
+ is_dir "$DATADIR/workspace/.morph"
+ assert_equal $(ls -A "$DATADIR/workspace" | wc -l) 1
+
+Tests for things other than `morph init` just want to have a workspace
+created.
+
+ IMPLEMENTS GIVEN a workspace
+ run_morph init "$DATADIR/workspace"
+
+Implementation sections related to a simulated Trove
+----------------------------------------------------
+
+Morph needs access to a Trove, i.e., a git server, in order to do certain
+kinds of stuff. We simulate this by creating a set of git repositories
+locally, which we'll tell Morph to access using `file:` URLs. Specifically,
+we'll create a repository to hold system and stratum morphologies, and
+another to hold a chunk.
+
+ IMPLEMENTS GIVEN a git server
+
+ # Create a directory for all the git repositories.
+ mkdir "$DATADIR/gits"
+
+ # Create a repo for the system and stratum morphologies.
+
+ mkdir "$DATADIR/gits/morphs"
+
+ cat << EOF > "$DATADIR/gits/morphs/test-system.morph"
+ name: test-system
+ kind: system
+ strata:
+ - name: test-stratum
+ repo: test:morphs
+ ref: master
+ morph: test-stratum
+ EOF
+
+ cat << EOF > "$DATADIR/gits/morphs/test-stratum.morph"
+ name: test-stratum
+ kind: stratum
+ chunks:
+ - name: test-chunk
+ repo: test:test-chunk
+ ref: master
+ morph: test-chunk
+ EOF
+
+ run_in "$DATADIR/gits/morphs" git init .
+ run_in "$DATADIR/gits/morphs" git add .
+ run_in "$DATADIR/gits/morphs" git commit -m Initial.
+
+ # Create the chunk repository.
+
+ mkdir "$DATADIR/gits/test-chunk"
+
+ cat << EOF > "$DATADIR/gits/test-chunk/test-chunk.morph"
+ name: test-chunk
+ kind: chunk
+ build-system: dummy
+ EOF
+
+ run_in "$DATADIR/gits/test-chunk" git init .
+ run_in "$DATADIR/gits/test-chunk" git add .
+ run_in "$DATADIR/gits/test-chunk" git commit -m Initial.
+
+ # Create the Morph configuration file so we can access the repos
+ # using test:foo URL aliases.
+
+ cat << EOF > "$DATADIR/morph.conf"
+ [config]
+ repo-alias = test=file://$DATADIR/gits/%s#file://$DATADIR/gits/%s
+ EOF
+
+Implementation sections for system branch operations
+----------------------------------------------------
+
+Checkout out an existing system branch. We parameterise this so the
+same phrase can be used to check out any system branch.
+
+ IMPLEMENTS WHEN checking out the (\S+) system branch
+ cd "$DATADIR/workspace"
+ run_morph checkout test:morphs "$MATCH_1"
+
+Attempt to check out a system branch, and remember if it failed.
+
+ IMPLEMENTS WHEN morph attempts to check out system branch (\S+)
+ cd "$DATADIR/workspace"
+ attempt_morph checkout "$MATCH_1"
+
+We also need to verify that a system branch has been checked out.
+
+ IMPLEMENTS THEN the system branch (\S+) is checked out
+ is_dir "$DATADIR/workspace/$MATCH_1/test:morphs"
+ is_file "$DATADIR/workspace/$MATCH_1/test:morphs/test-system.morph"
+ is_file "$DATADIR/workspace/$MATCH_1/test:morphs/test-stratum.morph"
+
+We can create a new branch, off master.
+
+ IMPLEMENTS WHEN creating system branch (\S+)
+ cd "$DATADIR/workspace"
+ run_morph branch test:morphs "$MATCH_1"
+
+We can create a new branch, off another system branch.
+
+ IMPLEMENTS WHEN creating system branch (\S+), based on (\S+)
+ cd "$DATADIR/workspace"
+ run_morph branch test:morphs "$MATCH_1" "$MATCH_2"
+
+Pushing all changes in a system branch checkout to the git server.
+
+ IMPLEMENTS WHEN pushing system branch (\S+) to git server
+ # FIXME: For now, this is just the morphs checkout.
+ run_in "$DATADIR/workspace/$MATCH_1/test:morphs" git push origin HEAD
+
+Report workspace path.
+
+ IMPLEMENTS WHEN morph reports workspace in (\S+)
+ cd "$DATADIR/workspace/$MATCH_1"
+ run_morph workspace > "$DATADIR/workspace-reported"
+
+ IMPLEMENTS THEN workspace is reported correctly
+ assert_equal $(cat "$DATADIR/workspace-reported") "$DATADIR/workspace"
+
+ IMPLEMENTS WHEN morph attempts to report workspace
+ cd "$DATADIR"
+ attempt_morph workspace
+
+Report system branch name:
+
+ IMPLEMENTS WHEN reporting system branch in (\S+)
+ cd "$DATADIR/workspace/$MATCH_1"
+ run_morph show-system-branch > "$DATADIR/system-branch.reported"
+
+ IMPLEMENTS THEN system branch is reported as (.*)
+ echo "$MATCH_1" > "$DATADIR/system-branch.actual"
+ diff -u "$DATADIR/system-branch.actual" "$DATADIR/system-branch.reported"
+
+ IMPLEMENTS WHEN attempting to report system branch in (.*)
+ cd "$DATADIR/workspace/$MATCH_1"
+ attempt_morph show-system-branch
+
+Report system branch root repository.
+
+ IMPLEMENTS WHEN reporting system branch root repository in (.*)
+ cd "$DATADIR/workspace/$MATCH_1"
+ run_morph show-branch-root > "$DATADIR/branch-root.reported"
+
+ IMPLEMENTS THEN root repository is reported as (.*)
+ echo "$MATCH_1" > "$DATADIR/branch-root.actual"
+ diff -u "$DATADIR/branch-root.actual" "$DATADIR/branch-root.reported"
+
+ IMPLEMENTS WHEN attempting to report system branch root repository in (.*)
+ cd "$DATADIR/workspace/$MATCH_1"
+ attempt_morph show-branch-root
+
+Editing morphologies with `morph edit`.
+
+ IMPLEMENTS THEN in branch (\S+), system (\S+) refs (\S+) in (\S+)
+ "$SRCDIR/scripts/yaml-extract" \
+ "$DATADIR/workspace/$MATCH_1/test:morphs/$MATCH_2.morph" \
+ strata name="$MATCH_3" ref > "$DATADIR/ref.actual"
+ echo "$MATCH_4" > "$DATADIR/ref.wanted"
+ diff -u "$DATADIR/ref.wanted" "$DATADIR/ref.actual"
+
+ IMPLEMENTS THEN in branch (\S+), stratum (\S+) refs (\S+) in (\S+)
+ "$SRCDIR/scripts/yaml-extract" \
+ "$DATADIR/workspace/$MATCH_1/test:morphs/$MATCH_2.morph" \
+ chunks name="$MATCH_3" ref > "$DATADIR/ref.actual"
+ echo "$MATCH_4" > "$DATADIR/ref.wanted"
+ diff -u "$DATADIR/ref.wanted" "$DATADIR/ref.actual"
+
+ IMPLEMENTS WHEN editing stratum (\S+) in system (\S+) in branch (\S+)
+ cd "$DATADIR/workspace/$MATCH_3/test:morphs"
+ run_morph edit "$MATCH_2" "$MATCH_1"
+
+ IMPLEMENTS WHEN editing chunk (\S+) in (\S+) in (\S+) in branch (\S+)
+ cd "$DATADIR/workspace/$MATCH_4/test:morphs"
+ run_morph edit "$MATCH_3" "$MATCH_2" "$MATCH_1"
+
+ IMPLEMENTS THEN edited chunk (\S+) has git branch (\S+)
+ ls -l "$DATADIR/workspace/$MATCH_2"
+ cd "$DATADIR/workspace/$MATCH_2/$MATCH_1"
+ git branch | awk '$1 == "*" { print $2 }' > "$DATADIR/git-branch.actual"
+ echo "$MATCH_2" > "$DATADIR/git-branch.wanted"
+ diff -u "$DATADIR/git-branch.wanted" "$DATADIR/git-branch.actual"
+
+Reporting status of checked out repositories:
+
+ IMPLEMENTS THEN morph reports no outstanding changes in (\S+)
+ cd "$DATADIR/workspace/$MATCH_1"
+ run_morph status > "$DATADIR/morph.stdout"
+ grep '^No repos have outstanding changes.' "$DATADIR/morph.stdout"
+
+ IMPLEMENTS THEN morph reports changes in (\S+) in (\S+) only
+ cd "$DATADIR/workspace/$MATCH_1"
+ run_morph status > "$DATADIR/morph.stdout"
+
+ # morph status is expected to produce records like this:
+ # On branch GITBRANCH, root baserock:baserock/morphs
+ # GITREPO: uncommitted changes
+ # We check thet GITREPO matches $MATCH_2.
+
+ awk '/: uncommitted changes$/ { print substr($1,1,length($1)-1) }' \
+ "$DATADIR/morph.stdout" > "$DATADIR/changed.actual"
+ echo "$MATCH_2" > "$DATADIR/changed.wanted"
+ diff -u "$DATADIR/changed.wanted" "$DATADIR/changed.actual"
+
+ IMPLEMENTS THEN morph reports changes in (\S+) in (\S+) and (\S+)
+ cd "$DATADIR/workspace/$MATCH_1"
+ run_morph status > "$DATADIR/morph.stdout"
+ echo "status morph.stdout:"
+ cat "$DATADIR/morph.stdout"
+ awk '/: uncommitted changes$/ { print substr($1,1,length($1)-1) }' \
+ "$DATADIR/morph.stdout" | sort > "$DATADIR/changed.actual"
+ (echo "$MATCH_2"; echo "$MATCH_3") | sort > "$DATADIR/changed.wanted"
+ diff -u "$DATADIR/changed.wanted" "$DATADIR/changed.actual"
+
+ IMPLEMENTS WHEN creating file (\S+) in (\S+) in branch (\S+)
+ touch "$DATADIR/workspace/$MATCH_3/$MATCH_2/$MATCH_1"
+
+ IMPLEMENTS WHEN adding file (\S+) in (\S+) in branch (\S+) to git
+ cd "$DATADIR/workspace/$MATCH_3/$MATCH_2"
+ git add "$MATCH_1"
+
+ IMPLEMENTS WHEN committing changes in (\S+) in branch (\S+)
+ cd "$DATADIR/workspace/$MATCH_2/$MATCH_1"
+ git commit -a -m test-commit
+
+Running shell command in each checked out repository:
+
+ IMPLEMENTS WHEN running shell command in each repo in (\S+)
+ cd "$DATADIR/workspace/$MATCH_1"
+ run_morph foreach -- pwd > "$DATADIR/morph.stdout"
+
+ IMPLEMENTS THEN morph ran command in (\S+) in (\S+)
+ grep -Fx "$MATCH_1" "$DATADIR/morph.stdout"
+ grep -Fx "$DATADIR/workspace/$MATCH_2/$MATCH_1" "$DATADIR/morph.stdout"
+
+Petrification and unpetrification:
+
+ IMPLEMENTS WHEN remembering all refs in (\S+)
+ cd "$DATADIR/workspace/$MATCH_1/test:morphs"
+ list_refs *.morph > "$DATADIR/refs.remembered"
+
+ IMPLEMENTS THEN (\S+) refs are as remembered
+ cd "$DATADIR/workspace/$MATCH_1/test:morphs"
+
+ # FIXME: petrify/unpetrify doesn't work quite right at this time:
+ # petrify can change a ref to a stratum to point at the system
+ # branch, but does it without adding an unpetrify-ref, and so
+ # unpetrify doesn't undo the change. We ignore this bug for the
+ # time being, in order to make the test suite pass. When the
+ # petrification code has been cleaned up to not be so hairy,
+ # we'll fix the test and the code.
+ #
+ # We would like to verify the result like this:
+ #
+ # list_refs *.morph > "$DATADIR/refs.now"
+ # diff -u "$DATADIR/refs.remembered" "$DATADIR/refs.now"
+ #
+ # However, due to the bug, we have to do it in a more complicated
+ # manner.
+
+ list_refs *.morph |
+ while read filename ref
+ do
+ orig=$(awk -v "f=$filename" '$1 == f { print $2 }' \
+ "$DATADIR/refs.remembered")
+ if [ "$orig" != "$ref" ] && [ "$ref" != "$MATCH_1" ]
+ then
+ die "Un-petrified ref: $filename $ref (should be $orig)"
+ fi
+ done
+
+ IMPLEMENTS WHEN petrifying (\S+)
+ cd "$DATADIR/workspace/$MATCH_1/test:morphs"
+ run_morph petrify
+
+ IMPLEMENTS WHEN unpetrifying (\S+)
+ cd "$DATADIR/workspace/$MATCH_1/test:morphs"
+ run_morph unpetrify
+
+ IMPLEMENTS THEN (\S+) is petrified
+ cd "$DATADIR/workspace/$MATCH_1/test:morphs"
+ assert_morphologies_are_petrified "$MATCH_1" *.morph
+
+ IMPLEMENTS THEN (\S+) is not petrified
+ cd "$DATADIR/workspace/$MATCH_1/test:morphs"
+ ! assert_morphologies_are_petrified "$MATCH_1" *.morph
+
+Tagging.
+
+ IMPLEMENTS WHEN tagging system branch (\S+) as (\S+)
+ cd "$DATADIR/workspace/$MATCH_1/test:morphs"
+ run_morph tag "$MATCH_2" -- -m "testing morph tagging"
+
+ IMPLEMENTS WHEN attempting to tag system branch (\S+) as (\S+)
+ cd "$DATADIR/workspace/$MATCH_1/test:morphs"
+ attempt_morph tag "$MATCH_2" -- -m "testing morph tagging"
+
+ IMPLEMENTS THEN morph tag (\S+) in (\S+) is an annotated git tag
+ cd "$DATADIR/workspace/$MATCH_2/test:morphs"
+ if git show "$MATCH_1" | head -n1 | grep -v '^tag '
+ then
+ die "git tag $MATCH_1 is not an annotated tag"
+ fi
+
+ IMPLEMENTS THEN morph tag (\S+) in (\S+) refers to a petrified commit
+ cd "$DATADIR/workspace/$MATCH_2/test:morphs"
+ git ls-tree "$MATCH_1" |
+ awk '$NF ~ /\.morph$/ { print $NF }' |
+ while read x
+ do
+ git cat-file blob "$MATCH_1:$x" > temptemptemp
+ assert_morphologies_are_petrified "$MATCH_1" temptemptemp
+ done
+