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
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff