Revision 90066780
b/Makefile.am | ||
---|---|---|
106 | 106 |
test/data \ |
107 | 107 |
test/data/ovfdata \ |
108 | 108 |
test/data/ovfdata/other \ |
109 |
test/py \ |
|
109 | 110 |
tools |
110 | 111 |
|
111 | 112 |
ALL_APIDOC_HS_DIRS = \ |
... | ... | |
814 | 815 |
doc/examples/gnt-debug/README \ |
815 | 816 |
doc/examples/gnt-debug/delay0.json \ |
816 | 817 |
doc/examples/gnt-debug/delay50.json \ |
817 |
test/lockperf.py \ |
|
818 |
test/testutils.py \ |
|
819 |
test/mocks.py \ |
|
818 |
test/py/lockperf.py \
|
|
819 |
test/py/testutils.py \
|
|
820 |
test/py/mocks.py \
|
|
820 | 821 |
$(dist_TESTS) \ |
821 | 822 |
$(TEST_FILES) \ |
822 | 823 |
man/footer.rst \ |
... | ... | |
956 | 957 |
test/data/vgreduce-removemissing-2.02.66-ok.txt \ |
957 | 958 |
test/data/vgs-missing-pvs-2.02.02.txt \ |
958 | 959 |
test/data/vgs-missing-pvs-2.02.66.txt \ |
959 |
test/ganeti-cli.test \ |
|
960 |
test/gnt-cli.test \ |
|
961 |
test/import-export_unittest-helper |
|
960 |
test/py/ganeti-cli.test \
|
|
961 |
test/py/gnt-cli.test \
|
|
962 |
test/py/import-export_unittest-helper
|
|
962 | 963 |
|
963 | 964 |
python_tests = \ |
964 | 965 |
doc/examples/rapi_testutils.py \ |
965 |
test/cfgupgrade_unittest.py \ |
|
966 |
test/docs_unittest.py \ |
|
967 |
test/ganeti.asyncnotifier_unittest.py \ |
|
968 |
test/ganeti.backend_unittest-runasroot.py \ |
|
969 |
test/ganeti.backend_unittest.py \ |
|
970 |
test/ganeti.bdev_unittest.py \ |
|
971 |
test/ganeti.cli_unittest.py \ |
|
972 |
test/ganeti.client.gnt_cluster_unittest.py \ |
|
973 |
test/ganeti.client.gnt_instance_unittest.py \ |
|
974 |
test/ganeti.client.gnt_job_unittest.py \ |
|
975 |
test/ganeti.cmdlib_unittest.py \ |
|
976 |
test/ganeti.compat_unittest.py \ |
|
977 |
test/ganeti.confd.client_unittest.py \ |
|
978 |
test/ganeti.config_unittest.py \ |
|
979 |
test/ganeti.constants_unittest.py \ |
|
980 |
test/ganeti.daemon_unittest.py \ |
|
981 |
test/ganeti.errors_unittest.py \ |
|
982 |
test/ganeti.hooks_unittest.py \ |
|
983 |
test/ganeti.ht_unittest.py \ |
|
984 |
test/ganeti.http_unittest.py \ |
|
985 |
test/ganeti.hypervisor.hv_chroot_unittest.py \ |
|
986 |
test/ganeti.hypervisor.hv_fake_unittest.py \ |
|
987 |
test/ganeti.hypervisor.hv_kvm_unittest.py \ |
|
988 |
test/ganeti.hypervisor.hv_lxc_unittest.py \ |
|
989 |
test/ganeti.hypervisor.hv_xen_unittest.py \ |
|
990 |
test/ganeti.hypervisor_unittest.py \ |
|
991 |
test/ganeti.impexpd_unittest.py \ |
|
992 |
test/ganeti.jqueue_unittest.py \ |
|
993 |
test/ganeti.jstore_unittest.py \ |
|
994 |
test/ganeti.locking_unittest.py \ |
|
995 |
test/ganeti.luxi_unittest.py \ |
|
996 |
test/ganeti.masterd.iallocator_unittest.py \ |
|
997 |
test/ganeti.masterd.instance_unittest.py \ |
|
998 |
test/ganeti.mcpu_unittest.py \ |
|
999 |
test/ganeti.netutils_unittest.py \ |
|
1000 |
test/ganeti.objects_unittest.py \ |
|
1001 |
test/ganeti.objectutils_unittest.py \ |
|
1002 |
test/ganeti.opcodes_unittest.py \ |
|
1003 |
test/ganeti.ovf_unittest.py \ |
|
1004 |
test/ganeti.qlang_unittest.py \ |
|
1005 |
test/ganeti.query_unittest.py \ |
|
1006 |
test/ganeti.rapi.baserlib_unittest.py \ |
|
1007 |
test/ganeti.rapi.client_unittest.py \ |
|
1008 |
test/ganeti.rapi.resources_unittest.py \ |
|
1009 |
test/ganeti.rapi.rlib2_unittest.py \ |
|
1010 |
test/ganeti.rapi.testutils_unittest.py \ |
|
1011 |
test/ganeti.rpc_unittest.py \ |
|
1012 |
test/ganeti.runtime_unittest.py \ |
|
1013 |
test/ganeti.serializer_unittest.py \ |
|
1014 |
test/ganeti.server.rapi_unittest.py \ |
|
1015 |
test/ganeti.ssconf_unittest.py \ |
|
1016 |
test/ganeti.ssh_unittest.py \ |
|
1017 |
test/ganeti.storage_unittest.py \ |
|
1018 |
test/ganeti.tools.ensure_dirs_unittest.py \ |
|
1019 |
test/ganeti.tools.node_daemon_setup_unittest.py \ |
|
1020 |
test/ganeti.tools.prepare_node_join_unittest.py \ |
|
1021 |
test/ganeti.uidpool_unittest.py \ |
|
1022 |
test/ganeti.utils.algo_unittest.py \ |
|
1023 |
test/ganeti.utils.filelock_unittest.py \ |
|
1024 |
test/ganeti.utils.hash_unittest.py \ |
|
1025 |
test/ganeti.utils.io_unittest-runasroot.py \ |
|
1026 |
test/ganeti.utils.io_unittest.py \ |
|
1027 |
test/ganeti.utils.log_unittest.py \ |
|
1028 |
test/ganeti.utils.mlock_unittest.py \ |
|
1029 |
test/ganeti.utils.nodesetup_unittest.py \ |
|
1030 |
test/ganeti.utils.process_unittest.py \ |
|
1031 |
test/ganeti.utils.retry_unittest.py \ |
|
1032 |
test/ganeti.utils.text_unittest.py \ |
|
1033 |
test/ganeti.utils.wrapper_unittest.py \ |
|
1034 |
test/ganeti.utils.x509_unittest.py \ |
|
1035 |
test/ganeti.utils_unittest.py \ |
|
1036 |
test/ganeti.vcluster_unittest.py \ |
|
1037 |
test/ganeti.workerpool_unittest.py \ |
|
1038 |
test/pycurl_reset_unittest.py \ |
|
1039 |
test/qa.qa_config_unittest.py \ |
|
1040 |
test/tempfile_fork_unittest.py |
|
966 |
test/py/cfgupgrade_unittest.py \
|
|
967 |
test/py/docs_unittest.py \
|
|
968 |
test/py/ganeti.asyncnotifier_unittest.py \
|
|
969 |
test/py/ganeti.backend_unittest-runasroot.py \
|
|
970 |
test/py/ganeti.backend_unittest.py \
|
|
971 |
test/py/ganeti.bdev_unittest.py \
|
|
972 |
test/py/ganeti.cli_unittest.py \
|
|
973 |
test/py/ganeti.client.gnt_cluster_unittest.py \
|
|
974 |
test/py/ganeti.client.gnt_instance_unittest.py \
|
|
975 |
test/py/ganeti.client.gnt_job_unittest.py \
|
|
976 |
test/py/ganeti.cmdlib_unittest.py \
|
|
977 |
test/py/ganeti.compat_unittest.py \
|
|
978 |
test/py/ganeti.confd.client_unittest.py \
|
|
979 |
test/py/ganeti.config_unittest.py \
|
|
980 |
test/py/ganeti.constants_unittest.py \
|
|
981 |
test/py/ganeti.daemon_unittest.py \
|
|
982 |
test/py/ganeti.errors_unittest.py \
|
|
983 |
test/py/ganeti.hooks_unittest.py \
|
|
984 |
test/py/ganeti.ht_unittest.py \
|
|
985 |
test/py/ganeti.http_unittest.py \
|
|
986 |
test/py/ganeti.hypervisor.hv_chroot_unittest.py \
|
|
987 |
test/py/ganeti.hypervisor.hv_fake_unittest.py \
|
|
988 |
test/py/ganeti.hypervisor.hv_kvm_unittest.py \
|
|
989 |
test/py/ganeti.hypervisor.hv_lxc_unittest.py \
|
|
990 |
test/py/ganeti.hypervisor.hv_xen_unittest.py \
|
|
991 |
test/py/ganeti.hypervisor_unittest.py \
|
|
992 |
test/py/ganeti.impexpd_unittest.py \
|
|
993 |
test/py/ganeti.jqueue_unittest.py \
|
|
994 |
test/py/ganeti.jstore_unittest.py \
|
|
995 |
test/py/ganeti.locking_unittest.py \
|
|
996 |
test/py/ganeti.luxi_unittest.py \
|
|
997 |
test/py/ganeti.masterd.iallocator_unittest.py \
|
|
998 |
test/py/ganeti.masterd.instance_unittest.py \
|
|
999 |
test/py/ganeti.mcpu_unittest.py \
|
|
1000 |
test/py/ganeti.netutils_unittest.py \
|
|
1001 |
test/py/ganeti.objects_unittest.py \
|
|
1002 |
test/py/ganeti.objectutils_unittest.py \
|
|
1003 |
test/py/ganeti.opcodes_unittest.py \
|
|
1004 |
test/py/ganeti.ovf_unittest.py \
|
|
1005 |
test/py/ganeti.qlang_unittest.py \
|
|
1006 |
test/py/ganeti.query_unittest.py \
|
|
1007 |
test/py/ganeti.rapi.baserlib_unittest.py \
|
|
1008 |
test/py/ganeti.rapi.client_unittest.py \
|
|
1009 |
test/py/ganeti.rapi.resources_unittest.py \
|
|
1010 |
test/py/ganeti.rapi.rlib2_unittest.py \
|
|
1011 |
test/py/ganeti.rapi.testutils_unittest.py \
|
|
1012 |
test/py/ganeti.rpc_unittest.py \
|
|
1013 |
test/py/ganeti.runtime_unittest.py \
|
|
1014 |
test/py/ganeti.serializer_unittest.py \
|
|
1015 |
test/py/ganeti.server.rapi_unittest.py \
|
|
1016 |
test/py/ganeti.ssconf_unittest.py \
|
|
1017 |
test/py/ganeti.ssh_unittest.py \
|
|
1018 |
test/py/ganeti.storage_unittest.py \
|
|
1019 |
test/py/ganeti.tools.ensure_dirs_unittest.py \
|
|
1020 |
test/py/ganeti.tools.node_daemon_setup_unittest.py \
|
|
1021 |
test/py/ganeti.tools.prepare_node_join_unittest.py \
|
|
1022 |
test/py/ganeti.uidpool_unittest.py \
|
|
1023 |
test/py/ganeti.utils.algo_unittest.py \
|
|
1024 |
test/py/ganeti.utils.filelock_unittest.py \
|
|
1025 |
test/py/ganeti.utils.hash_unittest.py \
|
|
1026 |
test/py/ganeti.utils.io_unittest-runasroot.py \
|
|
1027 |
test/py/ganeti.utils.io_unittest.py \
|
|
1028 |
test/py/ganeti.utils.log_unittest.py \
|
|
1029 |
test/py/ganeti.utils.mlock_unittest.py \
|
|
1030 |
test/py/ganeti.utils.nodesetup_unittest.py \
|
|
1031 |
test/py/ganeti.utils.process_unittest.py \
|
|
1032 |
test/py/ganeti.utils.retry_unittest.py \
|
|
1033 |
test/py/ganeti.utils.text_unittest.py \
|
|
1034 |
test/py/ganeti.utils.wrapper_unittest.py \
|
|
1035 |
test/py/ganeti.utils.x509_unittest.py \
|
|
1036 |
test/py/ganeti.utils_unittest.py \
|
|
1037 |
test/py/ganeti.vcluster_unittest.py \
|
|
1038 |
test/py/ganeti.workerpool_unittest.py \
|
|
1039 |
test/py/pycurl_reset_unittest.py \
|
|
1040 |
test/py/qa.qa_config_unittest.py \
|
|
1041 |
test/py/tempfile_fork_unittest.py
|
|
1041 | 1042 |
|
1042 | 1043 |
haskell_tests = htest/test |
1043 | 1044 |
|
1044 | 1045 |
dist_TESTS = \ |
1045 |
test/check-cert-expired_unittest.bash \ |
|
1046 |
test/daemon-util_unittest.bash \ |
|
1047 |
test/ganeti-cleaner_unittest.bash \ |
|
1048 |
test/import-export_unittest.bash \ |
|
1049 |
test/cli-test.bash \ |
|
1050 |
test/bash_completion.bash \ |
|
1046 |
test/py/check-cert-expired_unittest.bash \
|
|
1047 |
test/py/daemon-util_unittest.bash \
|
|
1048 |
test/py/ganeti-cleaner_unittest.bash \
|
|
1049 |
test/py/import-export_unittest.bash \
|
|
1050 |
test/py/cli-test.bash \
|
|
1051 |
test/py/bash_completion.bash \
|
|
1051 | 1052 |
$(python_tests) |
1052 | 1053 |
|
1053 | 1054 |
nodist_TESTS = |
... | ... | |
1099 | 1100 |
|
1100 | 1101 |
srclink_files = \ |
1101 | 1102 |
man/footer.rst \ |
1102 |
test/check-cert-expired_unittest.bash \ |
|
1103 |
test/daemon-util_unittest.bash \ |
|
1104 |
test/ganeti-cleaner_unittest.bash \ |
|
1105 |
test/import-export_unittest.bash \ |
|
1106 |
test/cli-test.bash \ |
|
1107 |
test/bash_completion.bash \ |
|
1103 |
test/py/check-cert-expired_unittest.bash \
|
|
1104 |
test/py/daemon-util_unittest.bash \
|
|
1105 |
test/py/ganeti-cleaner_unittest.bash \
|
|
1106 |
test/py/import-export_unittest.bash \
|
|
1107 |
test/py/cli-test.bash \
|
|
1108 |
test/py/bash_completion.bash \
|
|
1108 | 1109 |
htest/offline-test.sh \ |
1109 | 1110 |
htest/cli-tests-defs.sh \ |
1110 | 1111 |
$(all_python_code) \ |
... | ... | |
1145 | 1146 |
$(PYTHON_BOOTSTRAP) \ |
1146 | 1147 |
qa |
1147 | 1148 |
|
1148 |
test/daemon-util_unittest.bash: daemons/daemon-util |
|
1149 |
test/py/daemon-util_unittest.bash: daemons/daemon-util
|
|
1149 | 1150 |
|
1150 |
test/ganeti-cleaner_unittest.bash: daemons/ganeti-cleaner |
|
1151 |
test/py/ganeti-cleaner_unittest.bash: daemons/ganeti-cleaner
|
|
1151 | 1152 |
|
1152 |
test/bash_completion.bash: doc/examples/bash_completion-debug |
|
1153 |
test/py/bash_completion.bash: doc/examples/bash_completion-debug
|
|
1153 | 1154 |
|
1154 | 1155 |
tools/kvm-ifup: tools/kvm-ifup.in $(REPLACE_VARS_SED) |
1155 | 1156 |
sed -f $(REPLACE_VARS_SED) < $< > $@ |
b/autotools/gen-coverage | ||
---|---|---|
1 | 1 |
#!/bin/bash |
2 | 2 |
# |
3 | 3 |
|
4 |
# Copyright (C) 2010, 2011 Google Inc. |
|
4 |
# Copyright (C) 2010, 2011, 2012 Google Inc.
|
|
5 | 5 |
# |
6 | 6 |
# This program is free software; you can redistribute it and/or modify |
7 | 7 |
# it under the terms of the GNU General Public License as published by |
... | ... | |
30 | 30 |
|
31 | 31 |
reportargs=( |
32 | 32 |
'--include=*' |
33 |
'--omit=test/*' |
|
33 |
'--omit=test/py/*'
|
|
34 | 34 |
) |
35 | 35 |
|
36 | 36 |
$COVERAGE erase |
b/doc/devnotes.rst | ||
---|---|---|
176 | 176 |
For Python tests:: |
177 | 177 |
|
178 | 178 |
$ export PYTHONPATH=$PWD |
179 |
$ python ./test/ganeti.%mytest% |
|
179 |
$ python ./test/py/ganeti.%mytest%
|
|
180 | 180 |
|
181 | 181 |
For Haskell tests:: |
182 | 182 |
|
/dev/null | ||
---|---|---|
1 |
#!/bin/bash |
|
2 |
# |
|
3 |
|
|
4 |
# Copyright (C) 2012 Google Inc. |
|
5 |
# |
|
6 |
# This program is free software; you can redistribute it and/or modify |
|
7 |
# it under the terms of the GNU General Public License as published by |
|
8 |
# the Free Software Foundation; either version 2 of the License, or |
|
9 |
# (at your option) any later version. |
|
10 |
# |
|
11 |
# This program is distributed in the hope that it will be useful, but |
|
12 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
# General Public License for more details. |
|
15 |
# |
|
16 |
# You should have received a copy of the GNU General Public License |
|
17 |
# along with this program; if not, write to the Free Software |
|
18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
19 |
# 02110-1301, USA. |
|
20 |
|
|
21 |
set -e -u -o pipefail |
|
22 |
|
|
23 |
# Disable any locales |
|
24 |
export LC_ALL=C |
|
25 |
|
|
26 |
readonly bash_completion=${TOP_BUILDDIR:-.}/doc/examples/bash_completion-debug |
|
27 |
readonly default_wordbreaks=$' \t\n"'\''@><=;|&(:' |
|
28 |
|
|
29 |
err() { |
|
30 |
echo "$@" |
|
31 |
echo 'Aborting' |
|
32 |
exit 1 |
|
33 |
} |
|
34 |
|
|
35 |
contains() { |
|
36 |
local -r needle="$1"; shift |
|
37 |
|
|
38 |
for value; do |
|
39 |
if [[ "$value" = "$needle" ]]; then |
|
40 |
return 0 |
|
41 |
fi |
|
42 |
done |
|
43 |
|
|
44 |
return 1 |
|
45 |
} |
|
46 |
|
|
47 |
# Prepares a subshell for testing bash completion functions |
|
48 |
setup() { |
|
49 |
local -r unused=UNUSED |
|
50 |
|
|
51 |
set +e +u -o pipefail |
|
52 |
|
|
53 |
. $bash_completion |
|
54 |
|
|
55 |
COMP_KEY=$unused |
|
56 |
COMP_LINE=$unused |
|
57 |
COMP_POINT=$unused |
|
58 |
COMP_TYPE=$unused |
|
59 |
COMP_WORDBREAKS="$default_wordbreaks" |
|
60 |
|
|
61 |
GANETI_COMPL_LOG= |
|
62 |
|
|
63 |
unset COMP_CWORD |
|
64 |
unset COMP_WORDS |
|
65 |
} |
|
66 |
|
|
67 |
# Check if default wordbreaks are still valid (this detects cases where Bash |
|
68 |
# were to change its built-in default value) |
|
69 |
# TODO: May need an update for older Bash versions; some didn't include the |
|
70 |
# colon character (':') in COMP_WORDBREAKS |
|
71 |
( |
|
72 |
bashdef=$(env - bash --noprofile --norc -c 'echo -n "$COMP_WORDBREAKS"') |
|
73 |
case "$bashdef" in |
|
74 |
$default_wordbreaks) ;; |
|
75 |
*) |
|
76 |
err 'Bash uses unknown value for COMP_WORDBREAKS' |
|
77 |
;; |
|
78 |
esac |
|
79 |
) |
|
80 |
|
|
81 |
# Check for --help |
|
82 |
for cmd in gnt-{instance,node,group,job}; do |
|
83 |
( |
|
84 |
setup |
|
85 |
COMP_CWORD=2 |
|
86 |
COMP_WORDS=( $cmd list - ) |
|
87 |
_${cmd/-/_} |
|
88 |
contains --help "${COMPREPLY[@]}" || \ |
|
89 |
err "'$cmd list' did not list --help as an option" |
|
90 |
) |
|
91 |
done |
|
92 |
|
|
93 |
# Completing a yes/no option |
|
94 |
( |
|
95 |
setup |
|
96 |
COMP_CWORD=3 |
|
97 |
COMP_WORDS=( gnt-node modify --drained ) |
|
98 |
_gnt_node |
|
99 |
if [[ "${COMPREPLY[*]}" != 'no yes' ]]; then |
|
100 |
err "Completing '${COMP_WORDS[@]}' did not give correct result" |
|
101 |
fi |
|
102 |
) |
|
103 |
|
|
104 |
# Completing a multiple-choice option |
|
105 |
( |
|
106 |
setup |
|
107 |
COMP_CWORD=2 |
|
108 |
COMP_WORDS=( gnt-debug allocator --disk-template=sh foo ) |
|
109 |
_gnt_debug |
|
110 |
if [[ "${COMPREPLY[*]}" != sharedfile ]]; then |
|
111 |
err "Completing '${COMP_WORDS[*]}' did not give correct result" |
|
112 |
fi |
|
113 |
) |
|
114 |
|
|
115 |
# Completing a node name |
|
116 |
( |
|
117 |
setup |
|
118 |
|
|
119 |
# Override built-in function |
|
120 |
_ganeti_nodes() { |
|
121 |
echo aanode1 bbnode2 aanode3 |
|
122 |
} |
|
123 |
|
|
124 |
COMP_CWORD=4 |
|
125 |
COMP_WORDS=( gnt-node modify --drained yes aa ) |
|
126 |
_gnt_node |
|
127 |
if [[ "${COMPREPLY[*]}" != 'aanode1 aanode3' ]]; then |
|
128 |
err 'Completing node names failed' |
|
129 |
fi |
|
130 |
) |
|
131 |
|
|
132 |
# Completing an option when it's not at the end |
|
133 |
( |
|
134 |
setup |
|
135 |
|
|
136 |
# Override built-in function |
|
137 |
_ganeti_instances() { |
|
138 |
echo inst{1..5} |
|
139 |
} |
|
140 |
|
|
141 |
# Completing word in the middle |
|
142 |
COMP_CWORD=2 |
|
143 |
COMP_WORDS=( gnt-instance list --o inst3 inst inst5 ) |
|
144 |
_gnt_node |
|
145 |
contains --output "${COMPREPLY[@]}" || err 'Did not complete parameter' |
|
146 |
) |
|
147 |
|
|
148 |
# Completing an instance name |
|
149 |
( |
|
150 |
setup |
|
151 |
|
|
152 |
# Override built-in function |
|
153 |
_ganeti_instances() { |
|
154 |
echo inst{1..5} |
|
155 |
} |
|
156 |
|
|
157 |
# Completing word in the middle |
|
158 |
COMP_CWORD=5 |
|
159 |
COMP_WORDS=( gnt-instance list -o foobar inst1 inst inst5 ) |
|
160 |
_gnt_instance |
|
161 |
if [[ "${COMPREPLY[*]}" != "$(echo inst{1..5})" ]]; then |
|
162 |
err "Completing '${COMP_WORDS[*]}' did not give correct result" |
|
163 |
fi |
|
164 |
) |
|
165 |
|
|
166 |
# Need to test node expansion with different wordbreak settings |
|
167 |
[[ "$default_wordbreaks" == *:* ]] || \ |
|
168 |
err 'No colon in default wordbreak characters' |
|
169 |
for wb in "$default_wordbreaks" "${default_wordbreaks/:/}"; do |
|
170 |
( |
|
171 |
setup |
|
172 |
|
|
173 |
# Override built-in function |
|
174 |
_ganeti_nodes() { |
|
175 |
echo node{A..C} |
|
176 |
} |
|
177 |
|
|
178 |
COMP_WORDBREAKS="$wb" |
|
179 |
|
|
180 |
# Completing nodes |
|
181 |
COMP_CWORD=3 |
|
182 |
COMP_WORDS=( gnt-instance add -n ) |
|
183 |
_gnt_instance |
|
184 |
if [[ "${COMPREPLY[*]}" != 'nodeA nodeA: nodeB nodeB: nodeC nodeC:' ]]; then |
|
185 |
err 'Got wrong node list' |
|
186 |
fi |
|
187 |
|
|
188 |
COMP_CWORD=3 |
|
189 |
COMP_WORDS=( gnt-instance add -n nodeB ) |
|
190 |
_gnt_instance |
|
191 |
if [[ "${COMPREPLY[*]}" != 'nodeB nodeB:' ]]; then |
|
192 |
err 'Got wrong node list' |
|
193 |
fi |
|
194 |
|
|
195 |
COMP_CWORD=3 |
|
196 |
COMP_WORDS=( gnt-instance add -n nodeC: ) |
|
197 |
_gnt_instance |
|
198 |
if [[ "$COMP_WORDBREAKS" == *:* ]]; then |
|
199 |
expected='nodeA nodeB' |
|
200 |
else |
|
201 |
expected='nodeC:nodeA nodeC:nodeB' |
|
202 |
fi |
|
203 |
if [[ "${COMPREPLY[*]}" != "$expected" ]]; then |
|
204 |
err 'Got wrong node list' |
|
205 |
fi |
|
206 |
) |
|
207 |
done |
|
208 |
|
|
209 |
# Need to test different settings for the extglob shell option |
|
210 |
for opt in -u -s; do |
|
211 |
verify_extglob() { |
|
212 |
if [[ "$(shopt -p extglob)" != "shopt $opt extglob" ]]; then |
|
213 |
err 'The "extglob" shell option has an unexpected value' |
|
214 |
fi |
|
215 |
} |
|
216 |
|
|
217 |
( |
|
218 |
shopt $opt extglob |
|
219 |
|
|
220 |
verify_extglob |
|
221 |
setup |
|
222 |
verify_extglob |
|
223 |
|
|
224 |
# Completing nodes |
|
225 |
COMP_CWORD=4 |
|
226 |
COMP_WORDS=( gnt-instance add --os-type busybox --no-n ) |
|
227 |
_gnt_instance |
|
228 |
if [[ "${COMPREPLY[*]}" != '--no-name-check --no-nics' ]]; then |
|
229 |
err "Completing '${COMP_WORDS[*]}' did not give correct result" |
|
230 |
fi |
|
231 |
verify_extglob |
|
232 |
) |
|
233 |
done |
|
234 |
|
|
235 |
exit 0 |
/dev/null | ||
---|---|---|
1 |
#!/usr/bin/python |
|
2 |
# |
|
3 |
|
|
4 |
# Copyright (C) 2010, 2012 Google Inc. |
|
5 |
# |
|
6 |
# This program is free software; you can redistribute it and/or modify |
|
7 |
# it under the terms of the GNU General Public License as published by |
|
8 |
# the Free Software Foundation; either version 2 of the License, or |
|
9 |
# (at your option) any later version. |
|
10 |
# |
|
11 |
# This program is distributed in the hope that it will be useful, but |
|
12 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
# General Public License for more details. |
|
15 |
# |
|
16 |
# You should have received a copy of the GNU General Public License |
|
17 |
# along with this program; if not, write to the Free Software |
|
18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
19 |
# 02110-1301, USA. |
|
20 |
|
|
21 |
|
|
22 |
"""Script for testing tools/cfgupgrade""" |
|
23 |
|
|
24 |
import os |
|
25 |
import sys |
|
26 |
import unittest |
|
27 |
import shutil |
|
28 |
import tempfile |
|
29 |
import operator |
|
30 |
|
|
31 |
from ganeti import constants |
|
32 |
from ganeti import utils |
|
33 |
from ganeti import errors |
|
34 |
from ganeti import serializer |
|
35 |
from ganeti import netutils |
|
36 |
|
|
37 |
import testutils |
|
38 |
|
|
39 |
|
|
40 |
def _RunUpgrade(path, dry_run, no_verify, ignore_hostname=True): |
|
41 |
cmd = [sys.executable, "%s/tools/cfgupgrade" % testutils.GetSourceDir(), |
|
42 |
"--debug", "--force", "--path=%s" % path, "--confdir=%s" % path] |
|
43 |
|
|
44 |
if ignore_hostname: |
|
45 |
cmd.append("--ignore-hostname") |
|
46 |
if dry_run: |
|
47 |
cmd.append("--dry-run") |
|
48 |
if no_verify: |
|
49 |
cmd.append("--no-verify") |
|
50 |
|
|
51 |
result = utils.RunCmd(cmd, cwd=os.getcwd()) |
|
52 |
if result.failed: |
|
53 |
raise Exception("cfgupgrade failed: %s, output %r" % |
|
54 |
(result.fail_reason, result.output)) |
|
55 |
|
|
56 |
|
|
57 |
class TestCfgupgrade(unittest.TestCase): |
|
58 |
def setUp(self): |
|
59 |
self.tmpdir = tempfile.mkdtemp() |
|
60 |
|
|
61 |
self.config_path = utils.PathJoin(self.tmpdir, "config.data") |
|
62 |
self.noded_cert_path = utils.PathJoin(self.tmpdir, "server.pem") |
|
63 |
self.rapi_cert_path = utils.PathJoin(self.tmpdir, "rapi.pem") |
|
64 |
self.rapi_users_path = utils.PathJoin(self.tmpdir, "rapi", "users") |
|
65 |
self.rapi_users_path_pre24 = utils.PathJoin(self.tmpdir, "rapi_users") |
|
66 |
self.known_hosts_path = utils.PathJoin(self.tmpdir, "known_hosts") |
|
67 |
self.confd_hmac_path = utils.PathJoin(self.tmpdir, "hmac.key") |
|
68 |
self.cds_path = utils.PathJoin(self.tmpdir, "cluster-domain-secret") |
|
69 |
self.ss_master_node_path = utils.PathJoin(self.tmpdir, "ssconf_master_node") |
|
70 |
self.file_storage_paths = utils.PathJoin(self.tmpdir, "file-storage-paths") |
|
71 |
|
|
72 |
def tearDown(self): |
|
73 |
shutil.rmtree(self.tmpdir) |
|
74 |
|
|
75 |
def _LoadConfig(self): |
|
76 |
return serializer.LoadJson(utils.ReadFile(self.config_path)) |
|
77 |
|
|
78 |
def _CreateValidConfigDir(self): |
|
79 |
utils.WriteFile(self.noded_cert_path, data="") |
|
80 |
utils.WriteFile(self.known_hosts_path, data="") |
|
81 |
utils.WriteFile(self.ss_master_node_path, |
|
82 |
data="node.has.another.name.example.net") |
|
83 |
|
|
84 |
def testNoConfigDir(self): |
|
85 |
self.assertFalse(utils.ListVisibleFiles(self.tmpdir)) |
|
86 |
self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True) |
|
87 |
self.assertRaises(Exception, _RunUpgrade, self.tmpdir, True, True) |
|
88 |
|
|
89 |
def testWrongHostname(self): |
|
90 |
self._CreateValidConfigDir() |
|
91 |
|
|
92 |
utils.WriteFile(self.config_path, data=serializer.DumpJson({ |
|
93 |
"version": constants.CONFIG_VERSION, |
|
94 |
"cluster": {}, |
|
95 |
"instances": {}, |
|
96 |
"nodegroups": {}, |
|
97 |
})) |
|
98 |
|
|
99 |
hostname = netutils.GetHostname().name |
|
100 |
assert hostname != utils.ReadOneLineFile(self.ss_master_node_path) |
|
101 |
|
|
102 |
self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True, |
|
103 |
ignore_hostname=False) |
|
104 |
|
|
105 |
def testCorrectHostname(self): |
|
106 |
self._CreateValidConfigDir() |
|
107 |
|
|
108 |
utils.WriteFile(self.config_path, data=serializer.DumpJson({ |
|
109 |
"version": constants.CONFIG_VERSION, |
|
110 |
"cluster": {}, |
|
111 |
"instances": {}, |
|
112 |
"nodegroups": {}, |
|
113 |
})) |
|
114 |
|
|
115 |
utils.WriteFile(self.ss_master_node_path, |
|
116 |
data="%s\n" % netutils.GetHostname().name) |
|
117 |
|
|
118 |
_RunUpgrade(self.tmpdir, False, True, ignore_hostname=False) |
|
119 |
|
|
120 |
def testInconsistentConfig(self): |
|
121 |
self._CreateValidConfigDir() |
|
122 |
# There should be no "config_version" |
|
123 |
cfg = { |
|
124 |
"version": 0, |
|
125 |
"cluster": { |
|
126 |
"config_version": 0, |
|
127 |
}, |
|
128 |
"instances": {}, |
|
129 |
"nodegroups": {}, |
|
130 |
} |
|
131 |
utils.WriteFile(self.config_path, data=serializer.DumpJson(cfg)) |
|
132 |
self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True) |
|
133 |
|
|
134 |
def testInvalidConfig(self): |
|
135 |
self._CreateValidConfigDir() |
|
136 |
# Missing version from config |
|
137 |
utils.WriteFile(self.config_path, data=serializer.DumpJson({})) |
|
138 |
self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True) |
|
139 |
|
|
140 |
def _TestSimpleUpgrade(self, from_version, dry_run, |
|
141 |
file_storage_dir=None, |
|
142 |
shared_file_storage_dir=None): |
|
143 |
cluster = {} |
|
144 |
|
|
145 |
if file_storage_dir: |
|
146 |
cluster["file_storage_dir"] = file_storage_dir |
|
147 |
if shared_file_storage_dir: |
|
148 |
cluster["shared_file_storage_dir"] = shared_file_storage_dir |
|
149 |
|
|
150 |
cfg = { |
|
151 |
"version": from_version, |
|
152 |
"cluster": cluster, |
|
153 |
"instances": {}, |
|
154 |
"nodegroups": {}, |
|
155 |
} |
|
156 |
self._CreateValidConfigDir() |
|
157 |
utils.WriteFile(self.config_path, data=serializer.DumpJson(cfg)) |
|
158 |
|
|
159 |
self.assertFalse(os.path.isfile(self.rapi_cert_path)) |
|
160 |
self.assertFalse(os.path.isfile(self.confd_hmac_path)) |
|
161 |
self.assertFalse(os.path.isfile(self.cds_path)) |
|
162 |
|
|
163 |
_RunUpgrade(self.tmpdir, dry_run, True) |
|
164 |
|
|
165 |
if dry_run: |
|
166 |
expversion = from_version |
|
167 |
checkfn = operator.not_ |
|
168 |
else: |
|
169 |
expversion = constants.CONFIG_VERSION |
|
170 |
checkfn = operator.truth |
|
171 |
|
|
172 |
self.assert_(checkfn(os.path.isfile(self.rapi_cert_path))) |
|
173 |
self.assert_(checkfn(os.path.isfile(self.confd_hmac_path))) |
|
174 |
self.assert_(checkfn(os.path.isfile(self.cds_path))) |
|
175 |
|
|
176 |
newcfg = self._LoadConfig() |
|
177 |
self.assertEqual(newcfg["version"], expversion) |
|
178 |
|
|
179 |
def testRapiUsers(self): |
|
180 |
self.assertFalse(os.path.exists(self.rapi_users_path)) |
|
181 |
self.assertFalse(os.path.exists(self.rapi_users_path_pre24)) |
|
182 |
self.assertFalse(os.path.exists(os.path.dirname(self.rapi_users_path))) |
|
183 |
|
|
184 |
utils.WriteFile(self.rapi_users_path_pre24, data="some user\n") |
|
185 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), False) |
|
186 |
|
|
187 |
self.assertTrue(os.path.isdir(os.path.dirname(self.rapi_users_path))) |
|
188 |
self.assert_(os.path.islink(self.rapi_users_path_pre24)) |
|
189 |
self.assert_(os.path.isfile(self.rapi_users_path)) |
|
190 |
self.assertEqual(os.readlink(self.rapi_users_path_pre24), |
|
191 |
self.rapi_users_path) |
|
192 |
for path in [self.rapi_users_path, self.rapi_users_path_pre24]: |
|
193 |
self.assertEqual(utils.ReadFile(path), "some user\n") |
|
194 |
|
|
195 |
def testRapiUsers24AndAbove(self): |
|
196 |
self.assertFalse(os.path.exists(self.rapi_users_path)) |
|
197 |
self.assertFalse(os.path.exists(self.rapi_users_path_pre24)) |
|
198 |
|
|
199 |
os.mkdir(os.path.dirname(self.rapi_users_path)) |
|
200 |
utils.WriteFile(self.rapi_users_path, data="other user\n") |
|
201 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), False) |
|
202 |
|
|
203 |
self.assert_(os.path.islink(self.rapi_users_path_pre24)) |
|
204 |
self.assert_(os.path.isfile(self.rapi_users_path)) |
|
205 |
self.assertEqual(os.readlink(self.rapi_users_path_pre24), |
|
206 |
self.rapi_users_path) |
|
207 |
for path in [self.rapi_users_path, self.rapi_users_path_pre24]: |
|
208 |
self.assertEqual(utils.ReadFile(path), "other user\n") |
|
209 |
|
|
210 |
def testRapiUsersExistingSymlink(self): |
|
211 |
self.assertFalse(os.path.exists(self.rapi_users_path)) |
|
212 |
self.assertFalse(os.path.exists(self.rapi_users_path_pre24)) |
|
213 |
|
|
214 |
os.mkdir(os.path.dirname(self.rapi_users_path)) |
|
215 |
os.symlink(self.rapi_users_path, self.rapi_users_path_pre24) |
|
216 |
utils.WriteFile(self.rapi_users_path, data="hello world\n") |
|
217 |
|
|
218 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), False) |
|
219 |
|
|
220 |
self.assert_(os.path.isfile(self.rapi_users_path) and |
|
221 |
not os.path.islink(self.rapi_users_path)) |
|
222 |
self.assert_(os.path.islink(self.rapi_users_path_pre24)) |
|
223 |
self.assertEqual(os.readlink(self.rapi_users_path_pre24), |
|
224 |
self.rapi_users_path) |
|
225 |
for path in [self.rapi_users_path, self.rapi_users_path_pre24]: |
|
226 |
self.assertEqual(utils.ReadFile(path), "hello world\n") |
|
227 |
|
|
228 |
def testRapiUsersExistingTarget(self): |
|
229 |
self.assertFalse(os.path.exists(self.rapi_users_path)) |
|
230 |
self.assertFalse(os.path.exists(self.rapi_users_path_pre24)) |
|
231 |
|
|
232 |
os.mkdir(os.path.dirname(self.rapi_users_path)) |
|
233 |
utils.WriteFile(self.rapi_users_path, data="other user\n") |
|
234 |
utils.WriteFile(self.rapi_users_path_pre24, data="hello world\n") |
|
235 |
|
|
236 |
self.assertRaises(Exception, self._TestSimpleUpgrade, |
|
237 |
constants.BuildVersion(2, 2, 0), False) |
|
238 |
|
|
239 |
for path in [self.rapi_users_path, self.rapi_users_path_pre24]: |
|
240 |
self.assert_(os.path.isfile(path) and not os.path.islink(path)) |
|
241 |
self.assertEqual(utils.ReadFile(self.rapi_users_path), "other user\n") |
|
242 |
self.assertEqual(utils.ReadFile(self.rapi_users_path_pre24), |
|
243 |
"hello world\n") |
|
244 |
|
|
245 |
def testRapiUsersDryRun(self): |
|
246 |
self.assertFalse(os.path.exists(self.rapi_users_path)) |
|
247 |
self.assertFalse(os.path.exists(self.rapi_users_path_pre24)) |
|
248 |
|
|
249 |
utils.WriteFile(self.rapi_users_path_pre24, data="some user\n") |
|
250 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), True) |
|
251 |
|
|
252 |
self.assertFalse(os.path.isdir(os.path.dirname(self.rapi_users_path))) |
|
253 |
self.assertTrue(os.path.isfile(self.rapi_users_path_pre24) and |
|
254 |
not os.path.islink(self.rapi_users_path_pre24)) |
|
255 |
self.assertFalse(os.path.exists(self.rapi_users_path)) |
|
256 |
|
|
257 |
def testRapiUsers24AndAboveDryRun(self): |
|
258 |
self.assertFalse(os.path.exists(self.rapi_users_path)) |
|
259 |
self.assertFalse(os.path.exists(self.rapi_users_path_pre24)) |
|
260 |
|
|
261 |
os.mkdir(os.path.dirname(self.rapi_users_path)) |
|
262 |
utils.WriteFile(self.rapi_users_path, data="other user\n") |
|
263 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), True) |
|
264 |
|
|
265 |
self.assertTrue(os.path.isfile(self.rapi_users_path) and |
|
266 |
not os.path.islink(self.rapi_users_path)) |
|
267 |
self.assertFalse(os.path.exists(self.rapi_users_path_pre24)) |
|
268 |
self.assertEqual(utils.ReadFile(self.rapi_users_path), "other user\n") |
|
269 |
|
|
270 |
def testRapiUsersExistingSymlinkDryRun(self): |
|
271 |
self.assertFalse(os.path.exists(self.rapi_users_path)) |
|
272 |
self.assertFalse(os.path.exists(self.rapi_users_path_pre24)) |
|
273 |
|
|
274 |
os.mkdir(os.path.dirname(self.rapi_users_path)) |
|
275 |
os.symlink(self.rapi_users_path, self.rapi_users_path_pre24) |
|
276 |
utils.WriteFile(self.rapi_users_path, data="hello world\n") |
|
277 |
|
|
278 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), True) |
|
279 |
|
|
280 |
self.assertTrue(os.path.islink(self.rapi_users_path_pre24)) |
|
281 |
self.assertTrue(os.path.isfile(self.rapi_users_path) and |
|
282 |
not os.path.islink(self.rapi_users_path)) |
|
283 |
self.assertEqual(os.readlink(self.rapi_users_path_pre24), |
|
284 |
self.rapi_users_path) |
|
285 |
for path in [self.rapi_users_path, self.rapi_users_path_pre24]: |
|
286 |
self.assertEqual(utils.ReadFile(path), "hello world\n") |
|
287 |
|
|
288 |
def testFileStoragePathsDryRun(self): |
|
289 |
self.assertFalse(os.path.exists(self.file_storage_paths)) |
|
290 |
|
|
291 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 6, 0), True, |
|
292 |
file_storage_dir=self.tmpdir, |
|
293 |
shared_file_storage_dir="/tmp") |
|
294 |
|
|
295 |
self.assertFalse(os.path.exists(self.file_storage_paths)) |
|
296 |
|
|
297 |
def testFileStoragePathsBoth(self): |
|
298 |
self.assertFalse(os.path.exists(self.file_storage_paths)) |
|
299 |
|
|
300 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 6, 0), False, |
|
301 |
file_storage_dir=self.tmpdir, |
|
302 |
shared_file_storage_dir="/tmp") |
|
303 |
|
|
304 |
lines = utils.ReadFile(self.file_storage_paths).splitlines() |
|
305 |
self.assertTrue(lines.pop(0).startswith("# ")) |
|
306 |
self.assertTrue(lines.pop(0).startswith("# cfgupgrade")) |
|
307 |
self.assertEqual(lines.pop(0), self.tmpdir) |
|
308 |
self.assertEqual(lines.pop(0), "/tmp") |
|
309 |
self.assertFalse(lines) |
|
310 |
self.assertEqual(os.stat(self.file_storage_paths).st_mode & 0777, |
|
311 |
0600, msg="Wrong permissions") |
|
312 |
|
|
313 |
def testFileStoragePathsSharedOnly(self): |
|
314 |
self.assertFalse(os.path.exists(self.file_storage_paths)) |
|
315 |
|
|
316 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 5, 0), False, |
|
317 |
file_storage_dir=None, |
|
318 |
shared_file_storage_dir=self.tmpdir) |
|
319 |
|
|
320 |
lines = utils.ReadFile(self.file_storage_paths).splitlines() |
|
321 |
self.assertTrue(lines.pop(0).startswith("# ")) |
|
322 |
self.assertTrue(lines.pop(0).startswith("# cfgupgrade")) |
|
323 |
self.assertEqual(lines.pop(0), self.tmpdir) |
|
324 |
self.assertFalse(lines) |
|
325 |
|
|
326 |
def testUpgradeFrom_2_0(self): |
|
327 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 0, 0), False) |
|
328 |
|
|
329 |
def testUpgradeFrom_2_1(self): |
|
330 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 1, 0), False) |
|
331 |
|
|
332 |
def testUpgradeFrom_2_2(self): |
|
333 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), False) |
|
334 |
|
|
335 |
def testUpgradeFrom_2_3(self): |
|
336 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), False) |
|
337 |
|
|
338 |
def testUpgradeFrom_2_4(self): |
|
339 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 4, 0), False) |
|
340 |
|
|
341 |
def testUpgradeFrom_2_5(self): |
|
342 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 5, 0), False) |
|
343 |
|
|
344 |
def testUpgradeFrom_2_6(self): |
|
345 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 6, 0), False) |
|
346 |
|
|
347 |
def testUpgradeCurrent(self): |
|
348 |
self._TestSimpleUpgrade(constants.CONFIG_VERSION, False) |
|
349 |
|
|
350 |
def testUpgradeDryRunFrom_2_0(self): |
|
351 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 0, 0), True) |
|
352 |
|
|
353 |
def testUpgradeDryRunFrom_2_1(self): |
|
354 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 1, 0), True) |
|
355 |
|
|
356 |
def testUpgradeDryRunFrom_2_2(self): |
|
357 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), True) |
|
358 |
|
|
359 |
def testUpgradeDryRunFrom_2_3(self): |
|
360 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), True) |
|
361 |
|
|
362 |
def testUpgradeDryRunFrom_2_4(self): |
|
363 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 4, 0), True) |
|
364 |
|
|
365 |
def testUpgradeDryRunFrom_2_5(self): |
|
366 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 5, 0), True) |
|
367 |
|
|
368 |
def testUpgradeDryRunFrom_2_6(self): |
|
369 |
self._TestSimpleUpgrade(constants.BuildVersion(2, 6, 0), True) |
|
370 |
|
|
371 |
def testUpgradeCurrentDryRun(self): |
|
372 |
self._TestSimpleUpgrade(constants.CONFIG_VERSION, True) |
|
373 |
|
|
374 |
|
|
375 |
if __name__ == "__main__": |
|
376 |
testutils.GanetiTestProgram() |
/dev/null | ||
---|---|---|
1 |
#!/bin/bash |
|
2 |
# |
|
3 |
|
|
4 |
# Copyright (C) 2010 Google Inc. |
|
5 |
# |
|
6 |
# This program is free software; you can redistribute it and/or modify |
|
7 |
# it under the terms of the GNU General Public License as published by |
|
8 |
# the Free Software Foundation; either version 2 of the License, or |
|
9 |
# (at your option) any later version. |
|
10 |
# |
|
11 |
# This program is distributed in the hope that it will be useful, but |
|
12 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
# General Public License for more details. |
|
15 |
# |
|
16 |
# You should have received a copy of the GNU General Public License |
|
17 |
# along with this program; if not, write to the Free Software |
|
18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
19 |
# 02110-1301, USA. |
|
20 |
|
|
21 |
set -e |
|
22 |
set -o pipefail |
|
23 |
|
|
24 |
export PYTHON=${PYTHON:=python} |
|
25 |
|
|
26 |
CCE=tools/check-cert-expired |
|
27 |
|
|
28 |
err() { |
|
29 |
echo "$@" |
|
30 |
echo 'Aborting' |
|
31 |
exit 1 |
|
32 |
} |
|
33 |
|
|
34 |
impexpd_helper() { |
|
35 |
$PYTHON "${TOP_SRCDIR:-.}/test/import-export_unittest-helper" "$@" |
|
36 |
} |
|
37 |
|
|
38 |
$CCE 2>/dev/null && err 'Accepted empty argument list' |
|
39 |
$CCE foo bar 2>/dev/null && err 'Accepted more than one argument' |
|
40 |
$CCE foo bar baz 2>/dev/null && err 'Accepted more than one argument' |
|
41 |
|
|
42 |
tmpdir=$(mktemp -d) |
|
43 |
trap "rm -rf $tmpdir" EXIT |
|
44 |
|
|
45 |
[[ -f "$tmpdir/cert-not" ]] && err 'File existed when it should not' |
|
46 |
$CCE $tmpdir/cert-not 2>/dev/null && err 'Accepted non-existent file' |
|
47 |
|
|
48 |
VALIDITY=1 impexpd_helper $tmpdir/cert-valid gencert |
|
49 |
$CCE $tmpdir/cert-valid 2>/dev/null && \ |
|
50 |
err 'Reported valid certificate as expired' |
|
51 |
|
|
52 |
VALIDITY=-50 impexpd_helper $tmpdir/cert-expired gencert |
|
53 |
$CCE $tmpdir/cert-expired 2>/dev/null || \ |
|
54 |
err 'Reported expired certificate as valid' |
|
55 |
|
|
56 |
echo > $tmpdir/cert-invalid |
|
57 |
$CCE $tmpdir/cert-invalid 2>/dev/null && \ |
|
58 |
err 'Reported invalid certificate as expired' |
|
59 |
|
|
60 |
echo 'Hello World' > $tmpdir/cert-invalid2 |
|
61 |
$CCE $tmpdir/cert-invalid2 2>/dev/null && \ |
|
62 |
err 'Reported invalid certificate as expired' |
|
63 |
|
|
64 |
exit 0 |
/dev/null | ||
---|---|---|
1 |
#!/bin/bash |
|
2 |
|
|
3 |
export SCRIPTS=${TOP_BUILDDIR:-.}/scripts |
|
4 |
export DAEMONS=${TOP_BUILDDIR:-.}/daemons |
|
5 |
|
|
6 |
shelltest $SHELLTESTARGS \ |
|
7 |
${TOP_SRCDIR:-.}/test/{gnt,ganeti}-*.test \ |
|
8 |
-- --hide-successes |
/dev/null | ||
---|---|---|
1 |
#!/bin/bash |
|
2 |
# |
|
3 |
|
|
4 |
# Copyright (C) 2010, 2011 Google Inc. |
|
5 |
# |
|
6 |
# This program is free software; you can redistribute it and/or modify |
|
7 |
# it under the terms of the GNU General Public License as published by |
|
8 |
# the Free Software Foundation; either version 2 of the License, or |
|
9 |
# (at your option) any later version. |
|
10 |
# |
|
11 |
# This program is distributed in the hope that it will be useful, but |
|
12 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
# General Public License for more details. |
|
15 |
# |
|
16 |
# You should have received a copy of the GNU General Public License |
|
17 |
# along with this program; if not, write to the Free Software |
|
18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
19 |
# 02110-1301, USA. |
|
20 |
|
|
21 |
set -e |
|
22 |
|
|
23 |
daemon_util=daemons/daemon-util |
|
24 |
|
|
25 |
err() { |
|
26 |
echo "$@" |
|
27 |
echo 'Aborting' |
|
28 |
exit 1 |
|
29 |
} |
|
30 |
|
|
31 |
if ! grep -q '^ENABLE_CONFD = ' lib/_autoconf.py; then |
|
32 |
err "Please update $0, confd enable feature is missing" |
|
33 |
fi |
|
34 |
|
|
35 |
if grep -q '^ENABLE_CONFD = True' lib/_autoconf.py; then |
|
36 |
DAEMONS="$(echo ganeti-{noded,masterd,rapi,confd})" |
|
37 |
STOPDAEMONS="$(echo ganeti-{confd,rapi,masterd,noded})" |
|
38 |
else |
|
39 |
DAEMONS="$(echo ganeti-{noded,masterd,rapi})" |
|
40 |
STOPDAEMONS="$(echo ganeti-{rapi,masterd,noded})" |
|
41 |
fi |
|
42 |
|
|
43 |
$daemon_util >/dev/null 2>&1 && |
|
44 |
err "daemon-util succeeded without command" |
|
45 |
|
|
46 |
$daemon_util this-is-an-unimplemented-command >/dev/null 2>&1 && |
|
47 |
err "daemon-util accepted unimplemented command" |
|
48 |
|
|
49 |
$daemon_util list_start_daemons >/dev/null 2>&1 && |
|
50 |
err "daemon-util accepted command with underscores" |
|
51 |
|
|
52 |
$daemon_util check-exitcode 0 || |
|
53 |
err "check-exitcode 0 failed" |
|
54 |
|
|
55 |
for i in 1 2 3 4 20 25 33; do |
|
56 |
$daemon_util check-exitcode $i >/dev/null 2>&1 && rc=0 || rc=$? |
|
57 |
test "$rc" == 1 || err "check-exitcode $i didn't return 1" |
|
58 |
done |
|
59 |
|
|
60 |
$daemon_util check-exitcode 11 >/dev/null 2>&1 || |
|
61 |
err "check-exitcode 11 (not master) didn't return 0" |
|
62 |
|
|
63 |
tmp=$(echo $($daemon_util list-start-daemons)) |
|
64 |
test "$tmp" == "$DAEMONS" || |
|
65 |
err "list-start-daemons didn't return correct list of daemons" |
|
66 |
|
|
67 |
tmp=$(echo $($daemon_util list-stop-daemons)) |
|
68 |
test "$tmp" == "$STOPDAEMONS" || |
|
69 |
err "list-stop-daemons didn't return correct list of daemons" |
|
70 |
|
|
71 |
$daemon_util is-daemon-name >/dev/null 2>&1 && |
|
72 |
err "is-daemon-name didn't require daemon name" |
|
73 |
|
|
74 |
for i in '' '.' '..' '-' 'not-a-daemon'; do |
|
75 |
$daemon_util is-daemon-name "$i" >/dev/null 2>&1 && |
|
76 |
err "is-daemon-name thinks '$i' is a daemon name" |
|
77 |
done |
|
78 |
|
|
79 |
for i in $DAEMONS; do |
|
80 |
$daemon_util is-daemon-name $i >/dev/null 2>&1 || |
|
81 |
err "is-daemon-name doesn't think '$i' is a daemon name" |
|
82 |
done |
/dev/null | ||
---|---|---|
1 |
#!/usr/bin/python |
|
2 |
# |
|
3 |
|
|
4 |
# Copyright (C) 2009 Google Inc. |
|
5 |
# |
|
6 |
# This program is free software; you can redistribute it and/or modify |
|
7 |
# it under the terms of the GNU General Public License as published by |
|
8 |
# the Free Software Foundation; either version 2 of the License, or |
|
9 |
# (at your option) any later version. |
|
10 |
# |
|
11 |
# This program is distributed in the hope that it will be useful, but |
|
12 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
# General Public License for more details. |
|
15 |
# |
|
16 |
# You should have received a copy of the GNU General Public License |
|
17 |
# along with this program; if not, write to the Free Software |
|
18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
19 |
# 02110-1301, USA. |
|
20 |
|
|
21 |
|
|
22 |
"""Script for unittesting documentation""" |
|
23 |
|
|
24 |
import unittest |
|
25 |
import re |
|
26 |
import itertools |
|
27 |
import operator |
|
28 |
|
|
29 |
from ganeti import _autoconf |
|
30 |
from ganeti import utils |
|
31 |
from ganeti import cmdlib |
|
32 |
from ganeti import build |
|
33 |
from ganeti import compat |
|
34 |
from ganeti import mcpu |
|
35 |
from ganeti import opcodes |
|
36 |
from ganeti import constants |
|
37 |
from ganeti.rapi import baserlib |
|
38 |
from ganeti.rapi import rlib2 |
|
39 |
from ganeti.rapi import connector |
|
40 |
|
|
41 |
import testutils |
|
42 |
|
|
43 |
|
|
44 |
VALID_URI_RE = re.compile(r"^[-/a-z0-9]*$") |
|
45 |
|
|
46 |
RAPI_OPCODE_EXCLUDE = compat.UniqueFrozenset([ |
|
47 |
# Not yet implemented |
|
48 |
opcodes.OpBackupQuery, |
|
49 |
opcodes.OpBackupRemove, |
|
50 |
opcodes.OpClusterConfigQuery, |
|
51 |
opcodes.OpClusterRepairDiskSizes, |
|
52 |
opcodes.OpClusterVerify, |
|
53 |
opcodes.OpClusterVerifyDisks, |
|
54 |
opcodes.OpInstanceChangeGroup, |
|
55 |
opcodes.OpInstanceMove, |
|
56 |
opcodes.OpNodeQueryvols, |
|
57 |
opcodes.OpOobCommand, |
|
58 |
opcodes.OpTagsSearch, |
|
59 |
opcodes.OpClusterActivateMasterIp, |
|
60 |
opcodes.OpClusterDeactivateMasterIp, |
|
61 |
opcodes.OpExtStorageDiagnose, |
|
62 |
|
|
63 |
# Difficult if not impossible |
|
64 |
opcodes.OpClusterDestroy, |
|
65 |
opcodes.OpClusterPostInit, |
|
66 |
opcodes.OpClusterRename, |
|
67 |
opcodes.OpNodeAdd, |
|
68 |
opcodes.OpNodeRemove, |
|
69 |
|
|
70 |
# Very sensitive in nature |
|
71 |
opcodes.OpRestrictedCommand, |
|
72 |
|
|
73 |
# Helper opcodes (e.g. submitted by LUs) |
|
74 |
opcodes.OpClusterVerifyConfig, |
|
75 |
opcodes.OpClusterVerifyGroup, |
|
76 |
opcodes.OpGroupEvacuate, |
|
77 |
opcodes.OpGroupVerifyDisks, |
|
78 |
|
|
79 |
# Test opcodes |
|
80 |
opcodes.OpTestAllocator, |
|
81 |
opcodes.OpTestDelay, |
|
82 |
opcodes.OpTestDummy, |
|
83 |
opcodes.OpTestJqueue, |
|
84 |
]) |
|
85 |
|
|
86 |
|
|
87 |
def _ReadDocFile(filename): |
|
88 |
return utils.ReadFile("%s/doc/%s" % |
|
89 |
(testutils.GetSourceDir(), filename)) |
|
90 |
|
|
91 |
|
|
92 |
class TestHooksDocs(unittest.TestCase): |
|
93 |
HOOK_PATH_OK = compat.UniqueFrozenset([ |
|
94 |
"master-ip-turnup", |
|
95 |
"master-ip-turndown", |
|
96 |
]) |
|
97 |
|
|
98 |
def test(self): |
|
99 |
"""Check whether all hooks are documented. |
|
100 |
|
|
101 |
""" |
|
102 |
hooksdoc = _ReadDocFile("hooks.rst") |
|
103 |
|
|
104 |
# Reverse mapping from LU to opcode |
|
105 |
lu2opcode = dict((lu, op) |
|
106 |
for (op, lu) in mcpu.Processor.DISPATCH_TABLE.items()) |
|
107 |
assert len(lu2opcode) == len(mcpu.Processor.DISPATCH_TABLE), \ |
|
108 |
"Found duplicate entries" |
|
109 |
|
|
110 |
hooks_paths = frozenset(re.findall("^:directory:\s*(.+)\s*$", hooksdoc, |
|
111 |
re.M)) |
|
112 |
self.assertTrue(self.HOOK_PATH_OK.issubset(hooks_paths), |
|
113 |
msg="Whitelisted path not found in documentation") |
|
114 |
|
|
115 |
raw_hooks_ops = re.findall("^OP_(?!CODE$).+$", hooksdoc, re.M) |
|
116 |
hooks_ops = set() |
|
117 |
duplicate_ops = set() |
|
118 |
for op in raw_hooks_ops: |
|
119 |
if op in hooks_ops: |
|
120 |
duplicate_ops.add(op) |
|
121 |
else: |
|
122 |
hooks_ops.add(op) |
|
123 |
|
|
124 |
self.assertFalse(duplicate_ops, |
|
125 |
msg="Found duplicate opcode documentation: %s" % |
|
126 |
utils.CommaJoin(duplicate_ops)) |
|
127 |
|
|
128 |
seen_paths = set() |
|
129 |
seen_ops = set() |
|
130 |
|
|
131 |
self.assertFalse(duplicate_ops, |
|
132 |
msg="Found duplicated hook documentation: %s" % |
|
133 |
utils.CommaJoin(duplicate_ops)) |
|
134 |
|
|
135 |
for name in dir(cmdlib): |
|
136 |
lucls = getattr(cmdlib, name) |
|
137 |
|
|
138 |
if (isinstance(lucls, type) and |
|
139 |
issubclass(lucls, cmdlib.LogicalUnit) and |
|
140 |
hasattr(lucls, "HPATH")): |
|
141 |
if lucls.HTYPE is None: |
|
142 |
continue |
|
143 |
|
|
144 |
opcls = lu2opcode.get(lucls, None) |
|
145 |
|
|
146 |
if opcls: |
|
147 |
seen_ops.add(opcls.OP_ID) |
|
148 |
self.assertTrue(opcls.OP_ID in hooks_ops, |
|
149 |
msg="Missing hook documentation for %s" % |
|
150 |
opcls.OP_ID) |
|
151 |
self.assertTrue(lucls.HPATH in hooks_paths, |
|
152 |
msg="Missing documentation for hook %s/%s" % |
|
153 |
(lucls.HTYPE, lucls.HPATH)) |
|
154 |
seen_paths.add(lucls.HPATH) |
|
155 |
|
|
156 |
missed_ops = hooks_ops - seen_ops |
|
157 |
missed_paths = hooks_paths - seen_paths - self.HOOK_PATH_OK |
|
158 |
|
|
159 |
self.assertFalse(missed_ops, |
|
160 |
msg="Op documents hook not existing anymore: %s" % |
|
161 |
utils.CommaJoin(missed_ops)) |
|
162 |
|
|
163 |
self.assertFalse(missed_paths, |
|
164 |
msg="Hook path does not exist in opcode: %s" % |
|
165 |
utils.CommaJoin(missed_paths)) |
|
166 |
|
|
167 |
|
|
168 |
class TestRapiDocs(unittest.TestCase): |
|
169 |
def _CheckRapiResource(self, uri, fixup, handler): |
|
170 |
docline = "%s resource." % uri |
|
171 |
self.assertEqual(handler.__doc__.splitlines()[0].strip(), docline, |
|
172 |
msg=("First line of %r's docstring is not %r" % |
|
173 |
(handler, docline))) |
|
174 |
|
|
175 |
# Apply fixes before testing |
|
176 |
for (rx, value) in fixup.items(): |
|
177 |
uri = rx.sub(value, uri) |
|
178 |
|
|
179 |
self.assertTrue(VALID_URI_RE.match(uri), msg="Invalid URI %r" % uri) |
|
180 |
|
|
181 |
def test(self): |
|
182 |
"""Check whether all RAPI resources are documented. |
|
183 |
|
|
184 |
""" |
|
185 |
rapidoc = _ReadDocFile("rapi.rst") |
|
186 |
|
|
187 |
node_name = re.escape("[node_name]") |
|
188 |
instance_name = re.escape("[instance_name]") |
|
189 |
group_name = re.escape("[group_name]") |
|
190 |
network_name = re.escape("[network_name]") |
|
191 |
job_id = re.escape("[job_id]") |
|
192 |
disk_index = re.escape("[disk_index]") |
|
193 |
query_res = re.escape("[resource]") |
|
194 |
|
|
195 |
resources = connector.GetHandlers(node_name, instance_name, |
|
196 |
group_name, network_name, |
|
197 |
job_id, disk_index, query_res) |
|
198 |
|
|
199 |
handler_dups = utils.FindDuplicates(resources.values()) |
|
200 |
self.assertFalse(handler_dups, |
|
201 |
msg=("Resource handlers used more than once: %r" % |
|
202 |
handler_dups)) |
|
203 |
|
|
204 |
uri_check_fixup = { |
|
205 |
re.compile(node_name): "node1examplecom", |
|
206 |
re.compile(instance_name): "inst1examplecom", |
|
207 |
re.compile(group_name): "group4440", |
|
208 |
re.compile(network_name): "network5550", |
|
209 |
re.compile(job_id): "9409", |
|
210 |
re.compile(disk_index): "123", |
|
211 |
re.compile(query_res): "lock", |
|
212 |
} |
|
213 |
|
|
214 |
assert compat.all(VALID_URI_RE.match(value) |
|
215 |
for value in uri_check_fixup.values()), \ |
|
216 |
"Fixup values must be valid URIs, too" |
|
217 |
|
|
218 |
titles = [] |
|
219 |
|
|
220 |
prevline = None |
|
221 |
for line in rapidoc.splitlines(): |
|
222 |
if re.match(r"^\++$", line): |
|
223 |
titles.append(prevline) |
|
224 |
|
|
225 |
prevline = line |
|
226 |
|
|
227 |
prefix_exception = compat.UniqueFrozenset(["/", "/version", "/2"]) |
|
228 |
|
|
229 |
undocumented = [] |
|
230 |
used_uris = [] |
|
231 |
|
|
232 |
for key, handler in resources.iteritems(): |
|
233 |
# Regex objects |
|
234 |
if hasattr(key, "match"): |
|
235 |
self.assert_(key.pattern.startswith("^/2/"), |
|
236 |
msg="Pattern %r does not start with '^/2/'" % key.pattern) |
|
237 |
self.assertEqual(key.pattern[-1], "$") |
|
238 |
|
|
239 |
found = False |
|
240 |
for title in titles: |
|
241 |
if title.startswith("``") and title.endswith("``"): |
|
242 |
uri = title[2:-2] |
|
243 |
if key.match(uri): |
|
244 |
self._CheckRapiResource(uri, uri_check_fixup, handler) |
|
245 |
used_uris.append(uri) |
|
246 |
found = True |
|
247 |
break |
|
248 |
|
|
249 |
if not found: |
|
250 |
# TODO: Find better way of identifying resource |
|
251 |
undocumented.append(key.pattern) |
|
252 |
|
|
253 |
else: |
|
254 |
self.assert_(key.startswith("/2/") or key in prefix_exception, |
|
255 |
msg="Path %r does not start with '/2/'" % key) |
|
256 |
|
|
257 |
if ("``%s``" % key) in titles: |
|
258 |
self._CheckRapiResource(key, {}, handler) |
|
259 |
used_uris.append(key) |
|
260 |
else: |
|
261 |
undocumented.append(key) |
|
262 |
|
|
263 |
self.failIf(undocumented, |
|
264 |
msg=("Missing RAPI resource documentation for %s" % |
|
265 |
utils.CommaJoin(undocumented))) |
|
266 |
|
|
267 |
uri_dups = utils.FindDuplicates(used_uris) |
|
268 |
self.failIf(uri_dups, |
|
269 |
msg=("URIs matched by more than one resource: %s" % |
|
270 |
utils.CommaJoin(uri_dups))) |
|
271 |
|
|
272 |
self._FindRapiMissing(resources.values()) |
|
273 |
self._CheckTagHandlers(resources.values()) |
|
274 |
|
|
275 |
def _FindRapiMissing(self, handlers): |
|
276 |
used = frozenset(itertools.chain(*map(baserlib.GetResourceOpcodes, |
|
277 |
handlers))) |
|
278 |
|
|
279 |
unexpected = used & RAPI_OPCODE_EXCLUDE |
|
280 |
self.assertFalse(unexpected, |
|
281 |
msg=("Found RAPI resources for excluded opcodes: %s" % |
|
282 |
utils.CommaJoin(_GetOpIds(unexpected)))) |
|
283 |
|
|
284 |
missing = (frozenset(opcodes.OP_MAPPING.values()) - used - |
|
285 |
RAPI_OPCODE_EXCLUDE) |
|
286 |
self.assertFalse(missing, |
|
287 |
msg=("Missing RAPI resources for opcodes: %s" % |
|
288 |
utils.CommaJoin(_GetOpIds(missing)))) |
|
289 |
|
|
290 |
def _CheckTagHandlers(self, handlers): |
|
291 |
tag_handlers = filter(lambda x: issubclass(x, rlib2._R_Tags), handlers) |
|
292 |
self.assertEqual(frozenset(map(operator.attrgetter("TAG_LEVEL"), |
|
293 |
tag_handlers)), |
|
294 |
constants.VALID_TAG_TYPES) |
|
295 |
|
|
296 |
|
|
297 |
def _GetOpIds(ops): |
|
298 |
"""Returns C{OP_ID} for all opcodes in passed sequence. |
|
299 |
|
|
300 |
""" |
|
301 |
return sorted(opcls.OP_ID for opcls in ops) |
|
302 |
|
|
303 |
|
|
304 |
class TestManpages(unittest.TestCase): |
|
305 |
"""Manpage tests""" |
|
306 |
|
|
307 |
@staticmethod |
|
308 |
def _ReadManFile(name): |
|
309 |
return utils.ReadFile("%s/man/%s.rst" % |
|
310 |
(testutils.GetSourceDir(), name)) |
|
311 |
|
|
312 |
@staticmethod |
|
313 |
def _LoadScript(name): |
|
314 |
return build.LoadModule("scripts/%s" % name) |
|
315 |
|
|
316 |
def test(self): |
|
317 |
for script in _autoconf.GNT_SCRIPTS: |
|
318 |
self._CheckManpage(script, |
|
319 |
self._ReadManFile(script), |
|
320 |
self._LoadScript(script).commands.keys()) |
|
321 |
|
|
322 |
def _CheckManpage(self, script, mantext, commands): |
|
323 |
missing = [] |
|
324 |
|
|
325 |
for cmd in commands: |
|
326 |
pattern = r"^(\| )?\*\*%s\*\*" % re.escape(cmd) |
|
327 |
if not re.findall(pattern, mantext, re.DOTALL | re.MULTILINE): |
|
328 |
missing.append(cmd) |
|
329 |
|
|
330 |
self.failIf(missing, |
|
331 |
msg=("Manpage for '%s' missing documentation for %s" % |
|
332 |
(script, utils.CommaJoin(missing)))) |
|
333 |
|
|
334 |
|
|
335 |
if __name__ == "__main__": |
|
336 |
testutils.GanetiTestProgram() |
/dev/null | ||
---|---|---|
1 |
#!/bin/bash |
|
2 |
# |
|
3 |
|
|
4 |
# Copyright (C) 2010, 2012 Google Inc. |
|
5 |
# |
|
6 |
# This program is free software; you can redistribute it and/or modify |
|
7 |
# it under the terms of the GNU General Public License as published by |
|
8 |
# the Free Software Foundation; either version 2 of the License, or |
|
9 |
# (at your option) any later version. |
|
10 |
# |
|
11 |
# This program is distributed in the hope that it will be useful, but |
|
12 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 |
# General Public License for more details. |
|
15 |
# |
|
16 |
# You should have received a copy of the GNU General Public License |
|
17 |
# along with this program; if not, write to the Free Software |
|
18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
19 |
# 02110-1301, USA. |
|
20 |
|
|
21 |
set -e -u |
|
22 |
set -o pipefail |
|
23 |
|
|
24 |
export PYTHON=${PYTHON:=python} |
|
25 |
|
|
26 |
GNTC=daemons/ganeti-cleaner |
|
27 |
CCE=tools/check-cert-expired |
|
28 |
|
|
29 |
err() { |
|
30 |
echo "$@" |
|
31 |
echo 'Aborting' |
|
32 |
exit 1 |
|
33 |
} |
|
34 |
|
|
35 |
upto() { |
|
36 |
echo "$(date '+%F %T'):" "$@" '...' |
|
37 |
} |
|
38 |
|
|
39 |
gencert() { |
|
40 |
local path=$1 validity=$2 |
|
41 |
VALIDITY=$validity $PYTHON \ |
|
42 |
${TOP_SRCDIR:-.}/test/import-export_unittest-helper \ |
|
43 |
$path gencert |
|
44 |
} |
|
45 |
|
|
46 |
check_logfiles() { |
|
47 |
local n=$1 p=$2 path |
|
48 |
if [[ "$p" = master ]]; then |
|
49 |
path=$tmpls/log/ganeti/master-cleaner |
|
50 |
else |
|
51 |
path=$tmpls/log/ganeti/cleaner |
|
52 |
fi |
|
53 |
|
|
54 |
test -d $path || \ |
|
55 |
err "Log file directory '$path' not created" |
|
56 |
|
|
57 |
[[ "$(find $path -mindepth 1 | wc -l)" -le "$n" ]] || \ |
|
58 |
err "Found more than $n logfiles" |
|
59 |
} |
|
60 |
|
|
61 |
count_jobs() { |
|
62 |
local n=$1 |
|
63 |
local count=$(find $queuedir -mindepth 1 -type f | wc -l) |
|
64 |
[[ "$count" -eq "$n" ]] || err "Found $count jobs instead of $n" |
|
65 |
} |
|
66 |
|
|
67 |
count_watcher() { |
|
68 |
local suffix="$1" n=$2 |
Also available in: Unified diff