Build ceilometer 2015.1.0 (stable/kilo)
[openstack-build/ceilometer-build.git] / tests / runtests.sh
1 #!/bin/bash
2
3 set -eux
4
5 package_to_test=${1}
6 RES=0
7
8 mysql_pass="admin"
9 token=$(openssl rand -hex 10)
10 auth_string="--os-auth-url http://127.0.0.1:35357 --os-token ${token} --os-endpoint http://127.0.0.1:35357/v2.0/"
11 ceilometer_auth_string="--os-username ceilometer --os-password ceilometer --os-tenant-name ceilometer --os-auth-url http://127.0.0.1:35357/v2.0"
12 ceilometer_service=
13
14 keystone_log_file="/var/log/keystone/keystone.log"
15 ceilometer_log_dir="/var/log/ceilometer"
16 mongodb_log="/var/log/mongodb/mongodb.log"
17
18 if [[ `cat /etc/*-release | head -n 1 | awk '{print $1}'` =~ Ubuntu ]]; then
19    os="ubuntu"
20    packages_list="python-pip curl"
21    command_to_install="apt-get install -y --force-yes"
22    keystone_package="keystone"
23    keystone_service="keystone"
24    mysql_service="mysql"
25    mongodb_service="mongodb"
26    ceilometer_packages_and_services=(
27       ceilometer-agent-central
28       ceilometer-agent-compute
29       ceilometer-collector
30       ceilometer-agent-notification
31       ceilometer-polling
32       ceilometer-api
33       ceilometer-alarm-notifier
34       ceilometer-alarm-evaluator
35    )
36 else
37    echo "Disable tests for Centos"
38    exit 0
39    os="centos"
40    packages_list="python-pip curl"
41    command_to_install="yum install -y"
42    keystone_package="openstack-keystone"
43    keystone_service="openstack-keystone"
44    mysql_service="mysqld"
45    mongodb_service="mongod"
46    ceilometer_packages_and_services=(
47       openstack-ceilometer-central
48       openstack-ceilometer-compute
49       openstack-ceilometer-collector
50       openstack-ceilometer-notification
51       openstack-ceilometer-polling
52       openstack-ceilometer-api
53       openstack-ceilometer-alarm
54    )
55 fi
56
57 ceilometer_binaries=(
58    ceilometer-agent-central
59    ceilometer-agent-compute
60    ceilometer-collector
61    ceilometer-agent-notification
62    ceilometer-polling
63    ceilometer-api
64    ceilometer-alarm-notifier
65    ceilometer-alarm-evaluator
66    ceilometer-dbsync
67    ceilometer-expirer
68    ceilometer-rootwrap
69    ceilometer-send-sample
70 )
71
72 config_files=(
73    api_paste.ini
74    ceilometer.conf
75    deprecated_pipeline.yaml
76    event_definitions.yaml
77    event_pipeline.yaml
78    gabbi_pipeline.yaml
79    pipeline.yaml
80    policy.json
81    rootwrap.conf
82 )
83
84 list_commands=(
85    alarm-list
86    event-list
87    meter-list
88    resource-list
89    sample-list
90 )
91
92 install_packages() {
93    ${command_to_install} $@
94 }
95
96 prepare_vm() {
97    install_packages ${packages_list}
98 }
99
100 install_and_setup_keystone() {
101    install_packages ${keystone_package}
102    service ${keystone_service} stop
103
104    cat > /etc/keystone/keystone.conf << EOF
105 [DEFAULT]
106 admin_token=${token}
107 log_file=${keystone_log_file}
108 rabbit_password = guest
109 rabbit_hosts = 127.0.0.1
110 notification_driver = messaging
111 notification_topics = notifications
112 [database]
113 connection=mysql://keystone:keystone@localhost/keystone
114 [token]
115 provider=keystone.token.providers.uuid.Provider
116 EOF
117    [ -d "/var/log/keystone/" ] || mkdir /var/log/keystone/
118    touch ${keystone_log_file}
119    chown -R keystone:keystone /var/log/keystone/
120    chown -R keystone:keystone /etc/keystone
121
122    keystone-manage db_sync
123    service ${keystone_service} restart
124    sleep 5
125
126    if [ -z "$(curl -s http://localhost:5000/ | grep '^{"versions":')" ]; then
127       cat ${keystone_log_file}
128       exit_on_error 1 "Failed to get to keystone API.\nTests failed because of keystone problem"
129    fi
130 }
131
132 install_and_setup_mysql() {
133    echo "mysql-server mysql-server/root_password select ${mysql_pass}" | debconf-set-selections
134    echo "mysql-server mysql-server/root_password_again select ${mysql_pass}" | debconf-set-selections
135    ${command_to_install} mysql-server-5.6 mysql-client-core-5.6 python-mysqldb
136
137    service ${mysql_service} restart
138    sleep 5
139
140    if [ -z "$(service ${mysql_service} status | grep "start/running" )" ]; then
141       exit_on_error 1 "Mysql service has failed to start"
142    fi
143
144    mysql -uroot -p${mysql_pass} -Bse "drop database if exists keystone"
145    mysql -uroot -p${mysql_pass} -Bse "create database keystone"
146    mysql -uroot -p${mysql_pass} -Bse "GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'keystone'"
147    mysql -uroot -p${mysql_pass} -Bse "flush privileges"
148 }
149
150 install_and_setup_rabbit() {
151    install_packages rabbitmq-server
152    echo "127.0.10.1 $(hostname)" >> /etc/hosts
153    service rabbitmq-server restart
154    sleep 5
155
156    if [ ! -z "$(service rabbitmq-server status | grep "Error: unable to connect to node")" ]; then
157       cat /var/log/rabbitmq/startup_log
158       cat /var/log/rabbitmq/startup_err
159
160       exit_on_error 1 "DB sync command has failures"
161    fi
162 }
163
164 ceilometer_configuration() {
165    cat > /etc/ceilometer/ceilometer.conf << EOF
166 [DEFAULT]
167 api_paste_config = /etc/ceilometer/api_paste.ini
168 policy_file = /etc/ceilometer/policy.json
169 debug = True
170 verbose = True
171 log_dir = ${ceilometer_log_dir}
172 rpc_backend = ceilometer.openstack.common.rpc.impl_kombu
173 auth_strategy = keystone
174 rabbit_password = guest
175 rabbit_hosts = 127.0.0.1
176
177 [keystone_authtoken]
178 auth_host = 127.0.0.1
179 auth_port = 35357
180 auth_protocol = http
181 admin_tenant_name = ceilometer
182 admin_user = ceilometer
183 admin_password = ceilometer
184 auth_url=http://127.0.0.1:35357/v2.0
185
186 [database]
187 connection=mongodb://127.0.0.1/ceilometer
188
189 [notification]
190 store_events = True
191 EOF
192    [ -e /etc/default/ceilometer-polling ] && rm -f /etc/default/ceilometer-polling
193    echo "DAEMON_ARGS=\"--polling-namespaces=central\"" > /etc/default/ceilometer-polling
194
195    [ -d "${ceilometer_log_dir}" ] || mkdir ${ceilometer_log_dir}
196    chown -R ceilometer:ceilometer ${ceilometer_log_dir}
197    chown -R ceilometer:ceilometer /etc/ceilometer
198
199    ceilometer-dbsync --config-file /etc/ceilometer/ceilometer.conf
200    if [ "$?" -ne '0' ]; then
201       cat ${ceilometer_log_dir}/ceilometer-dbsync.log
202       exit_on_error 1 "DB sync command has failures"
203    fi
204
205    keystone ${auth_string} user-create --name ceilometer --pass ceilometer
206    keystone ${auth_string} tenant-create --name ceilometer
207    keystone ${auth_string} role-create --name=admin
208    keystone ${auth_string} user-role-add --user ceilometer --role admin --tenant ceilometer
209    ceilometer_service=$(keystone ${auth_string} service-create --name=ceilometer\
210  --type=metering --description="ceilometer" | grep id | awk -F '|' '{print $3}' | tr -d ' ')
211    keystone ${auth_string} endpoint-create --region RegionOne --service-id=${ceilometer_service}\
212  --publicurl=http://127.0.0.1:8777/ --internalurl=http://127.0.0.1:8777/ --adminurl=http://127.0.0.1:8777/
213 }
214
215 install_and_setup_mongo() {
216    install_packages "mongodb mongodb-clients"
217    cat > /etc/mongodb.conf << EOF
218 logappend=true
219 bind_ip = 127.0.0.1
220 port = 27017
221 dbpath=/var/lib/mongo
222 pidfilepath = /var/run/mongodb/mongodb.pid
223 journal = true
224 logpath = ${mongodb_log}
225 setParameter = logLevel=1
226 EOF
227    [ -d "/var/log/mongo" ] || mkdir /var/log/mongo
228    [ -d "/var/lib/mongo" ] || mkdir /var/lib/mongo
229    [ -d "/var/run/mongodb" ] || mkdir /var/run/mongodb
230    chown -R mongodb:mongodb /var/log/mongo /var/lib/mongo /var/run/mongodb /etc/mongodb.conf
231
232    service ${mongodb_service} restart
233    sleep 5
234
235    if [ -z "$(service ${mongodb_service} status | grep "start/running")" ]; then
236       cat ${mongodb_log}
237       exit_on_error 1 "Mongo service has failed to start"
238    fi
239
240    try=0
241    while [ ${try} -le '5' ]; do
242       mongo --host 127.0.0.1 --eval "db.getSiblingDB('admin')"
243       if [ "$?" -ne '0' ]; then
244          try=$((try + 1))
245          sleep 5
246       else
247          break
248       fi
249    done
250    if [ "${try}" -ge '5' ]; then
251       exit_on_error 1 "Mongo shell is not available. Mongo work is broken"
252    fi
253 }
254
255 send_fake_instance_notification() {
256    pip install pika==0.9.8
257    echo '#!/usr/bin/env python
258 import pika
259 connection = pika.BlockingConnection(pika.ConnectionParameters(host="127.0.0.1"))
260 channel = connection.channel()
261 channel.queue_declare(queue="notifications.info")
262 test=r'"'"'{"event_type": "compute.instance.update", "_unique_id": "fake", "payload": {"ephemeral_gb": 0, "instance_id": "fake", "user_id": "fake", "root_gb": 0, "tenant_id": "fake", "memory_mb": 64, "vcpus": 1}, "priority": "INFO"}'"'"'
263 channel.basic_publish(exchange="nova", routing_key="notifications.info",
264                       properties=pika.BasicProperties(priority=0, delivery_mode=2, headers="", content_encoding="utf-8", content_type="application/json"),
265                       body=test)
266 print " [x] Message was sent!"
267 connection.close()' > $(pwd)/send.py
268    python $(pwd)/send.py
269 }
270
271 exit_on_error() {
272    # $1 - responce code
273    # $2 - message
274    if [ "${1}" -ne '0' ]; then
275       echo -e "${2}"
276       RES=${1}
277       exit ${RES}
278    fi
279 }
280
281 found=false
282 for i in ${ceilometer_packages_and_services[@]}; do
283    if [ "${i}" == "${package_to_test}" ]; then
284       found=true
285    fi
286 done
287
288 if ${found}; then
289    echo "Test for package ${package_to_test} will be run with ceilometer-common package"
290    RES=0
291 fi
292
293 case ${package_to_test} in
294    ceilometer-common|openstack-ceilometer-common)
295       prepare_vm
296       install_packages "${ceilometer_packages_and_services[@]}"
297       install_and_setup_rabbit
298       install_and_setup_mysql
299       install_and_setup_keystone
300       install_and_setup_mongo
301       ceilometer_configuration
302
303       for binary in ${ceilometer_binaries[@]}; do
304          if [ ! -f "/usr/bin/${binary}" ]; then
305             exit_on_error 1 "Ceilometer binary ${binary} is missed"
306          fi
307       done
308
309       for config in ${config_files[@]}; do
310          if [ ! -f "/etc/ceilometer/${config}" ]; then
311             exit_on_error 1 "Ceilometer configuration file ${config} is missed"
312          fi
313       done
314
315       for service in ${ceilometer_packages_and_services[@]}; do
316          service ${service} restart
317          sleep 5
318          if [ -z "$(service ${service} status | grep "start/running")" ]; then
319             cat /var/log/ceilometer/${service}.log
320             exit_on_error 1 "Service ${service} has failed to start"
321          fi
322       done
323
324       repsonce=$(curl "http://localhost:8777" | grep "Authentication required")
325       if [ -z "$repsonce" ]; then
326          exit_on_error 1 "Ceilometer api doesn't work.\n No one process is listening on 8777 port"
327       fi
328
329       for Command in ${list_commands[@]}; do
330          ceilometer ${ceilometer_auth_string} ${Command}
331          if [ "$?" -ne '0' ]; then
332              exit_on_error 1 "Command ${Command} has failed"
333          fi
334       done
335
336       # Keystone notifications
337       if [ -z "$(ceilometer ${ceilometer_auth_string} meter-list | grep identity)" ]; then
338          exit_on_error 1 "Keystone notifications don't work"
339       fi
340
341       # Instance notification
342       send_fake_instance_notification
343       resource_id=$(ceilometer ${ceilometer_auth_string} resource-list | grep fake)
344       if [ -z ${resource_id} ]; then
345          exit_on_error 1 "Notification is not received"
346       fi
347
348       # Events
349       if [ -z "$(ceilometer ${ceilometer_auth_string} event-list | grep fake)" ]; then
350          exit_on_error 1 "Events wasn't created"
351       fi
352
353       # Alarming
354       ceilometer -dv ${ceilometer_auth_string} alarm-threshold-create --name cpu_high --description 'instance running hot' \
355  --meter-name cpu_util  --threshold 70.0 --comparison-operator gt  --statistic avg \
356  --period 600 --evaluation-periods 3 --alarm-action 'log://' --query resource_id="${resource_id}"
357
358       if [ "$?" -ne '0' -a -z "$(ceilometer ${ceilometer_auth_string} alarm-list | grep cpu_high)" ]; then
359          exit_on_error 1 "Alarm creation has failed"
360       fi
361
362       # Samples
363       ceilometer -dv ${ceilometer_auth_string} sample-create -m fake_sample --meter-type gauge --meter-unit '%' --sample-volume 100 -r "fake"
364
365       if [ "$?" -ne '0' -a -z "$(ceilometer ${ceilometer_auth_string} sample-list | grep fake_sample)" ]; then
366          exit_on_error 1 "Sample creation has failed"
367       fi
368    ;;
369    ceilometer-agent-ipmi|openstack-ceilometer-ipmi)
370       # Ceilometer-agent-ipmi is not included in common testing
371       # because it is not used in Fuel now
372       if [ ! -f "/usr/bin/ceilometer-agent-ipmi" ]; then
373          exit_on_error 1 "Ceilometer ipmi binary is missed"
374       fi
375    ;;
376    python-ceilometer)
377       python -c 'import ceilometer'
378       if [ $? -ne '0' ]; then
379          exit_on_error 1 "Couldn't import module 'ceilometer'"
380       fi
381       if [ -z "$(which ceilometer)" ]; then
382          exit_on_error 1 "Can't find command 'ceilometer'"
383       fi
384    ;;
385    *)
386       if ! ${found}; then
387          echo "Test not defined. Please create test for package ${package_to_test}"
388       fi
389    ;;
390 esac
391
392 exit ${RES}