Browse Source
new: charm can now declare relations
new: charm can now declare relations
A relation can be 'recommended', 'required', 'optional'. It can also auto-pair.hostresources
Valentin Lab
6 years ago
4 changed files with 1224 additions and 77 deletions
-
511bin/compose-core
-
57test/base
-
533test/relations
-
200test/uses
@ -0,0 +1,533 @@ |
|||
#!/usr/bin/env bash-shlib |
|||
# -*- mode: shell-script -*- |
|||
|
|||
include shunit |
|||
|
|||
depends sed grep git mkdir readlink |
|||
|
|||
export -f matches |
|||
export grep |
|||
|
|||
tmp=/tmp |
|||
tprog="../bin/compose-core" |
|||
tprog=$(readlink -f $tprog) |
|||
|
|||
|
|||
export PATH=".:$PATH" |
|||
short_tprog=$(basename "$tprog") |
|||
|
|||
|
|||
## |
|||
## Convenience function |
|||
## |
|||
|
|||
init_test() { |
|||
test_tmpdir=$(mktemp -d -t tmp.XXXXXXXXXX) |
|||
cd "$test_tmpdir" |
|||
export CACHEDIR="$test_tmpdir/.cache" |
|||
export VARDIR="$test_tmpdir/.var" |
|||
mkdir -p "$CACHEDIR" |
|||
} |
|||
|
|||
|
|||
|
|||
tear_test() { |
|||
rm -rf "$test_tmpdir" |
|||
} |
|||
|
|||
|
|||
## |
|||
## Tests |
|||
## |
|||
|
|||
|
|||
function test_all_relations_simple { |
|||
|
|||
init_test |
|||
|
|||
export DISABLE_SYSTEM_CONFIG_FILE=true |
|||
|
|||
assert_list <<EOF |
|||
|
|||
### Testing simple case |
|||
|
|||
## -- simple case with only one service with one relation, no uses/provides |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/{www,mysql} |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
EOF2 |
|||
|
|||
touch $test_tmpdir/mysql/metadata.yml |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
www: |
|||
charm: www |
|||
relations: |
|||
mysql-db: |
|||
mysql: |
|||
label: value |
|||
EOF2 |
|||
|
|||
. "$tprog" |
|||
|
|||
_setup_state_dir |
|||
COMPOSE_YML_FILE=$test_tmpdir/compose.yml |
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www mysql | tr '\0' '\n') || exit 3 |
|||
expected="www |
|||
mysql-db |
|||
mysql |
|||
label: value |
|||
|
|||
True" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
## -- simple case, 1 uses, already present |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/{www,mysql} |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
uses: |
|||
mysql-db: |
|||
constraint: optional |
|||
default-options: |
|||
label: from-default-options |
|||
label2: from-default-options |
|||
EOF2 |
|||
|
|||
touch $test_tmpdir/mysql/metadata.yml |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
www: |
|||
charm: www |
|||
relations: |
|||
mysql-db: |
|||
mysql: |
|||
label: value |
|||
EOF2 |
|||
|
|||
. "$tprog" |
|||
|
|||
_setup_state_dir |
|||
COMPOSE_YML_FILE=$test_tmpdir/compose.yml |
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www mysql | tr '\0' '\n') || exit 3 |
|||
expected="www |
|||
mysql-db |
|||
mysql |
|||
label: value |
|||
label2: from-default-options |
|||
True" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo --- OUT: >&2 |
|||
echo "\$out" >&2 |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
## -- simple case, 1 uses, optional, not present |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/{www,mysql} |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
uses: |
|||
mysql-db: |
|||
constraint: optional |
|||
default-options: |
|||
label: from-default-options |
|||
label2: from-default-options |
|||
EOF2 |
|||
|
|||
touch $test_tmpdir/mysql/metadata.yml |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
www: |
|||
charm: www |
|||
EOF2 |
|||
|
|||
. "$tprog" |
|||
|
|||
_setup_state_dir |
|||
COMPOSE_YML_FILE=$test_tmpdir/compose.yml |
|||
|
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www mysql 2>&1 >/dev/null) || exit 3 |
|||
expected="" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www mysql | tr '\0' '\n') || exit 3 |
|||
expected="" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
## -- simple case, 1 uses, optional with solves, not present |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/{www,mysql} |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
uses: |
|||
mysql-db: |
|||
constraint: optional |
|||
solves: |
|||
missing-feature: foo |
|||
default-options: |
|||
label: from-default-options |
|||
label2: from-default-options |
|||
EOF2 |
|||
|
|||
touch $test_tmpdir/mysql/metadata.yml |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
www: |
|||
charm: www |
|||
EOF2 |
|||
|
|||
. "$tprog" |
|||
|
|||
_setup_state_dir |
|||
COMPOSE_YML_FILE=$test_tmpdir/compose.yml |
|||
|
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www mysql 2>&1 >/dev/null) || exit 3 |
|||
expected="Notice" |
|||
|
|||
[[ "\$out" == *"\$expected"* ]] || { |
|||
echo "doesn't contain: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
## -- simple case, 1 uses, auto-pair, present |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/{www,mysql} |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
uses: |
|||
mysql-db: |
|||
constraint: optional |
|||
auto: pair |
|||
default-options: |
|||
label: from-default-options |
|||
label2: from-default-options |
|||
EOF2 |
|||
|
|||
touch $test_tmpdir/mysql/metadata.yml |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
www: |
|||
charm: www |
|||
relations: |
|||
mysql-db: |
|||
mysql: |
|||
label: value |
|||
EOF2 |
|||
|
|||
. "$tprog" |
|||
|
|||
_setup_state_dir |
|||
COMPOSE_YML_FILE=$test_tmpdir/compose.yml |
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www mysql | tr '\0' '\n') || exit 3 |
|||
expected="www |
|||
mysql-db |
|||
mysql |
|||
label: value |
|||
label2: from-default-options |
|||
True" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
|
|||
## -- simple case, 1 uses, auto-pair, not present, no provider |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/{www,mysql} |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
uses: |
|||
mysql-db: |
|||
constraint: optional |
|||
auto: pair |
|||
default-options: |
|||
label: from-default-options |
|||
label2: from-default-options |
|||
EOF2 |
|||
|
|||
touch $test_tmpdir/mysql/metadata.yml |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
www: |
|||
charm: www |
|||
EOF2 |
|||
|
|||
. "$tprog" |
|||
|
|||
_setup_state_dir |
|||
COMPOSE_YML_FILE=$test_tmpdir/compose.yml |
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www mysql | tr '\0' '\n') || exit 3 |
|||
expected="" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
## -- simple case, 1 uses, auto-pair, not present, 1 provider |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/{www,mysql} |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
uses: |
|||
mysql-db: |
|||
constraint: optional |
|||
auto: pair |
|||
default-options: |
|||
label: from-default-options |
|||
label2: from-default-options |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/mysql/metadata.yml |
|||
provides: |
|||
mysql-db: |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
www: |
|||
charm: www |
|||
EOF2 |
|||
|
|||
. "$tprog" |
|||
|
|||
_setup_state_dir |
|||
COMPOSE_YML_FILE=$test_tmpdir/compose.yml |
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www mysql | tr '\0' '\n') || exit 3 |
|||
expected="www |
|||
mysql-db |
|||
mysql |
|||
label: from-default-options |
|||
label2: from-default-options |
|||
True" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "--- EXPECTED" >&2 |
|||
echo "\$expected" >&2 |
|||
echo "--- OUT" >&2 |
|||
echo "\$out" >&2 |
|||
|
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
## -- simple case, 1 uses, auto-pair, not present, 2 providers |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/{www,mysql,mysql2} |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
uses: |
|||
mysql-db: |
|||
constraint: optional |
|||
auto: pair |
|||
default-options: |
|||
label: from-default-options |
|||
label2: from-default-options |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/mysql/metadata.yml |
|||
provides: |
|||
mysql-db: |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/mysql2/metadata.yml |
|||
provides: |
|||
mysql-db: |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
www: |
|||
charm: www |
|||
EOF2 |
|||
|
|||
. "$tprog" |
|||
|
|||
_setup_state_dir |
|||
COMPOSE_YML_FILE=$test_tmpdir/compose.yml |
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www mysql mysql2 2>&1 >/dev/null) || exit 3 |
|||
|
|||
expected="> 1" |
|||
|
|||
[[ "\$out" == *"\$expected"* ]] || { |
|||
echo "doesn't contain: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
# Remember, it is cached |
|||
out=\$(set -o pipefail |
|||
get_all_relations www mysql mysql2 | tr '\0' '\n') || exit 3 |
|||
expected="" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
EOF |
|||
|
|||
tear_test |
|||
} |
|||
|
|||
|
|||
|
|||
function test_all_relations_missing { |
|||
|
|||
init_test |
|||
|
|||
export DISABLE_SYSTEM_CONFIG_FILE=true |
|||
|
|||
assert_list <<EOF |
|||
|
|||
### Testing missing services at first call |
|||
|
|||
## -- 1 service, connection to another, no use/provide |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/{www,mysql} |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/mysql/metadata.yml |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
www: |
|||
relations: |
|||
mysql-db: mysql |
|||
EOF2 |
|||
|
|||
. "$tprog" |
|||
|
|||
_setup_state_dir |
|||
COMPOSE_YML_FILE=$test_tmpdir/compose.yml |
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www | tr '\0' '\n') || exit 3 |
|||
expected="www |
|||
mysql-db |
|||
mysql |
|||
|
|||
True" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "OUT:" >&2 |
|||
echo "\$out" >&2 |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
## -- 1 service, connection to another that auto-pair with first |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/{www,mysql} |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
provides: |
|||
www-proxy: |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/mysql/metadata.yml |
|||
uses: |
|||
www-proxy: |
|||
constraint: optional |
|||
auto: pair |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
www: |
|||
relations: |
|||
mysql-db: mysql |
|||
EOF2 |
|||
|
|||
. "$tprog" |
|||
|
|||
_setup_state_dir |
|||
COMPOSE_YML_FILE=$test_tmpdir/compose.yml |
|||
|
|||
out=\$(set -o pipefail |
|||
get_all_relations www | tr '\0' '\n') || exit 3 |
|||
expected="\ |
|||
www |
|||
mysql-db |
|||
mysql |
|||
|
|||
True |
|||
mysql |
|||
www-proxy |
|||
www |
|||
|
|||
True" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "DIFF:" >&2 |
|||
diff -u <(echo "\$expected") <(echo "\$out") >&2 |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
EOF |
|||
|
|||
tear_test |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
continue_on_error="0" testbench $* |
@ -0,0 +1,200 @@ |
|||
#!/usr/bin/env bash-shlib |
|||
# -*- mode: shell-script -*- |
|||
|
|||
include shunit |
|||
|
|||
depends sed grep git mkdir readlink |
|||
|
|||
export -f matches |
|||
export grep |
|||
|
|||
tmp=/tmp |
|||
tprog="../bin/compose-core" |
|||
tprog=$(readlink -f $tprog) |
|||
|
|||
|
|||
export PATH=".:$PATH" |
|||
short_tprog=$(basename "$tprog") |
|||
|
|||
|
|||
## |
|||
## Convenience function |
|||
## |
|||
|
|||
init_test() { |
|||
test_tmpdir=$(mktemp -d -t tmp.XXXXXXXXXX) |
|||
cd "$test_tmpdir" |
|||
export CACHEDIR="$test_tmpdir/.cache" |
|||
export VARDIR="$test_tmpdir/.var" |
|||
mkdir -p "$CACHEDIR" |
|||
} |
|||
|
|||
|
|||
|
|||
tear_test() { |
|||
rm -rf "$test_tmpdir" |
|||
} |
|||
|
|||
|
|||
## |
|||
## Tests |
|||
## |
|||
|
|||
|
|||
function test_uses { |
|||
|
|||
init_test |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/www/actions |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
docker-image: bar ## required as we want relation to know the base image |
|||
uses: |
|||
myrelation: myrelationdef |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
web_site: |
|||
charm: www |
|||
EOF2 |
|||
|
|||
export DISABLE_SYSTEM_CONFIG_FILE=true |
|||
|
|||
assert_list <<EOF |
|||
|
|||
### Testing _get_services_uses |
|||
|
|||
## -- simple case with only one service with one relation |
|||
|
|||
cd "$test_tmpdir" |
|||
. "$tprog" || exit 1 |
|||
|
|||
_setup_state_dir |
|||
|
|||
|
|||
out=\$(_get_services_uses web_site | tr '\0' ':') |
|||
expected="web_site:myrelation:myrelationdef:" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
## -- service not defined in compose, but has charm |
|||
|
|||
cd "$test_tmpdir" |
|||
. "$tprog" || exit 1 |
|||
|
|||
_setup_state_dir |
|||
|
|||
out=\$(_get_services_uses www | tr '\0' ':') || exit 2 |
|||
expected="www:myrelation:myrelationdef:" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
## -- service not defined in compose, nor has charm should fail |
|||
|
|||
cd "$test_tmpdir" |
|||
. "$tprog" || exit 1 |
|||
|
|||
_setup_state_dir |
|||
|
|||
_get_services_uses xxx || exit 0 |
|||
|
|||
echo "Expected it to fail" |
|||
exit 1 |
|||
|
|||
EOF |
|||
|
|||
tear_test |
|||
} |
|||
|
|||
|
|||
function test_provides { |
|||
|
|||
init_test |
|||
|
|||
export CHARM_STORE=$test_tmpdir |
|||
mkdir -p $test_tmpdir/www/actions |
|||
cat <<EOF2 > $test_tmpdir/www/metadata.yml |
|||
docker-image: bar ## required as we want relation to know the base image |
|||
provides: |
|||
myrelation: myrelationdef |
|||
EOF2 |
|||
|
|||
cat <<EOF2 > $test_tmpdir/compose.yml |
|||
web_site: |
|||
charm: www |
|||
EOF2 |
|||
|
|||
export DISABLE_SYSTEM_CONFIG_FILE=true |
|||
|
|||
assert_list <<EOF |
|||
|
|||
### Testing _get_services_provides |
|||
|
|||
## -- simple case with only one service with one relation |
|||
|
|||
cd "$test_tmpdir" |
|||
. "$tprog" || exit 1 |
|||
|
|||
_setup_state_dir |
|||
|
|||
|
|||
out=\$(_get_services_provides web_site | tr '\0' ':') |
|||
expected="web_site:myrelation:myrelationdef:" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
## -- service not defined in compose, but has charm |
|||
|
|||
cd "$test_tmpdir" |
|||
. "$tprog" || exit 1 |
|||
|
|||
_setup_state_dir |
|||
|
|||
|
|||
out=\$(_get_services_provides www | tr '\0' ':') |
|||
expected="www:myrelation:myrelationdef:" |
|||
|
|||
[[ "\$out" == "\$expected" ]] || { |
|||
echo "doesn't end with: \$expected" >&2 |
|||
echo "\$out" |
|||
exit 1 |
|||
} |
|||
|
|||
|
|||
## -- service not defined in compose, nor has charm should fail |
|||
|
|||
cd "$test_tmpdir" |
|||
. "$tprog" || exit 1 |
|||
|
|||
_setup_state_dir |
|||
|
|||
out=\$(set -o pipefail |
|||
_get_provides_uses xxx | tr '\0' :) || exit 0 |
|||
|
|||
echo "Expected it to fail" |
|||
exit 1 |
|||
|
|||
|
|||
EOF |
|||
|
|||
tear_test |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
continue_on_error="0" testbench $* |
Write
Preview
Loading…
Cancel
Save
Reference in new issue