summaryrefslogtreecommitdiff
path: root/yarns/implementations.yarn
diff options
context:
space:
mode:
authorLars Wirzenius <lars.wirzenius@codethink.co.uk>2013-07-29 14:15:11 +0000
committerLars Wirzenius <lars.wirzenius@codethink.co.uk>2013-07-30 17:10:08 +0000
commitfac47acd5ab8e3410929e8c36ceaa4ecf070de10 (patch)
treea880bdeeffc2d62804b97e85551132319258dae9 /yarns/implementations.yarn
parentb36072a5af5947e5dbb73395d821f1a57e0ef773 (diff)
downloadmorph-fac47acd5ab8e3410929e8c36ceaa4ecf070de10.tar.gz
Add scenario (yarn) tests for most of branching and merging
These scenarios test the basics of most of the subcommands the branch and merge plugin provides. They don't purport to be complete, but give some indication that things work, and form a basis upon which further things can be built. Yarn also isn't included in a Baserock release yet, so we need to keep the cmdtests until Baserock 10 has been released. The existing cmdtest tests are not modified by this: they are left intact, until they can analysed in detail for things to be added to the scenarios. After that, the cmdtest tests will start to go away. Merging is not covered by these tests: it is not clear how merge should work, and the current code is known to do the wrong thing in many cases. Scenarios for merge will be added later. Building is also not covered. Testing builds well needs some additional, careful thinking, and that isn't ready for this patch series. It will be added later.
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
+