Commit d4c1275a authored by Christos Stavrakakis's avatar Christos Stavrakakis
Browse files

Merge branch 'master' into devel-0.11

Conflicts:
	snf-cyclades-gtools/synnefo/ganeti/eventd.py
parents e5668c79 315b11a0
......@@ -529,6 +529,20 @@ domain (for all services). ``ASTAKOS_BASEURL`` is the astakos home page.
For the ``ASTAKOS_RECAPTCHA_PUBLIC_KEY`` and ``ASTAKOS_RECAPTCHA_PRIVATE_KEY``
go to https://www.google.com/recaptcha/admin/create and create your own pair.
Then edit ``/etc/synnefo/20-snf-astakos-app-cloudbar.conf`` :
.. code-block:: console
CLOUDBAR_LOCATION = 'https://node1.example.com/static/im/cloudbar/'
CLOUDBAR_SERVICES_URL = 'https://node1.example.com/im/get_services'
CLOUDBAR_MENU_URL = 'https://node1.example.com/im/get_menu'
Those settings have to do with the black cloudbar endpoints and will be described
in more detail later on in this guide. For now, just edit the domain to point at
node1 which is where we have installed Astakos.
If you are an advanced user and want to use the Shibboleth Authentication method,
read the relative :ref:`section <shibboleth-auth>`.
......@@ -876,7 +890,11 @@ node1 and node2. You can do this by running on *both* nodes:
.. code-block:: console
# apt-get install snf-image-host
# apt-get install snf-image-host snf-pithos-backend
snf-image also needs the `snf-pithos-backend <snf-pithos-backend>`, to be able to
handle image files stored on Pithos+. This is why, we also install it on *all*
VM-capable Ganeti nodes.
Now, you need to download and save the corresponding helper package. Please see
`here <https://code.grnet.gr/projects/snf-image/files>`_ for the latest package. Let's
......@@ -1380,8 +1398,6 @@ This will install the following:
* ``snf-ganeti-eventd`` (daemon to publish Ganeti related messages on RabbitMQ)
* ``snf-ganeti-hook`` (all necessary hooks under ``/etc/ganeti/hooks``)
* ``snf-progress-monitor`` (used by ``snf-image`` to publish progress messages)
* ``kvm-vif-bridge`` (installed under ``/etc/ganeti`` to connect Ganeti with
NFDHCPD)
Configure ``snf-cyclades-gtools``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......@@ -1392,9 +1408,7 @@ that need it:
.. code-block:: console
RABBIT_HOST = "node1.example.com:5672"
RABBIT_USERNAME = "synnefo"
RABBIT_PASSWORD = "example_rabbitmq_passw0rd"
AMQP_HOSTS=["amqp://synnefo:example_rabbitmq_passw0rd@node1.example.com:5672"]
The above variables should reflect your :ref:`Message Queue setup
<rabbitmq-setup>`. This file should be editted in all Ganeti nodes.
......@@ -1554,9 +1568,7 @@ Edit ``/etc/synnefo/20-snf-cyclades-app-queues.conf``:
.. code-block:: console
RABBIT_HOST = "node1.example.com:5672"
RABBIT_USERNAME = "synnefo"
RABBIT_PASSWORD = "example_rabbitmq_passw0rd"
AMQP_HOSTS=["amqp://synnefo:example_rabbitmq_passw0rd@node1.example.com:5672"]
The above settings denote the Message Queue. Those settings should have the same
values as in ``/etc/synnefo/10-snf-cyclades-gtools-backend.conf`` file, and
......
# Copyright 2011-2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
class ArgBasedSingletonMeta(type):
"""Implement the Singleton pattern with a twist.
Implement the Singleton pattern with a twist:
The uniqueness on the object is based on the class name,
plus the argument list (args and kwargs).
Unique objects are store in the '_singles' class attribute.
A distinct _singles object is used per subclass.
"""
def __call__(cls, *args, **kwargs):
kwlist = str([(k, kwargs[k]) for k in sorted(kwargs.keys())])
distinct = str((cls, args, kwlist))
# Allocate a new _singles attribute per subclass
if not hasattr(cls, "_singles_cls") or cls != cls._singles_cls:
cls._singles = {}
cls._singles_cls = cls
if distinct not in cls._singles:
obj = super(ArgBasedSingletonMeta, cls).__call__(*args, **kwargs)
cls._singles[distinct] = obj
ret = cls._singles[distinct]
return ret
class ArgBasedSingleton(object):
__metaclass__ = ArgBasedSingletonMeta
#!/usr/bin/env python
#
# -*- coding: utf-8 -*-
#
# Copyright 2011 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
#
#
"""Unit Tests for the Singleton classes in synnefo.common.singleton
Provides unit tests for the code implementing Singleton
classes in the synnefo.common.singleton module.
"""
import unittest
from synnefo.lib.singleton import ArgBasedSingleton
class SubClassOne(ArgBasedSingleton):
name = None
def __init__(self, name):
self.name = name
class SubClassTwo(ArgBasedSingleton):
name = None
def __init__(self, name):
self.name = name
class SubClassThree(SubClassTwo):
name2 = None
def __init__(self, name):
self.name2 = name
class SubClassKwArgs(ArgBasedSingleton):
name = None
def __init__(self, onearg, **kwargs):
self.name = onearg
for x in kwargs:
setattr(self, x, kwargs[x])
class SubClassNoReinit(ArgBasedSingleton):
initialized = None
def __init__(self, *args, **kwargs):
if self.initialized:
raise Exception("__init__ called twice!")
self.initialized = True
class ArgBasedSingletonTestCase(unittest.TestCase):
def test_same_object(self):
o1 = ArgBasedSingleton()
o2 = ArgBasedSingleton()
self.assertTrue(o1 is o2)
class MyMeta(ArgBasedSingletonMeta):
def __call__(cls, *args, **kw):
return super(MyMeta, cls).__call__(*args, **kw)
class BaseClass(object):
__metaclass__ = MyMeta
def ret5(self):
return 5
class SubClassMultiple(BaseClass, ArgBasedSingleton):
name = None
def __init__(self, name):
name = name
class SubClassTestCase(unittest.TestCase):
def test_same_object(self):
o1 = SubClassOne('one')
o2 = SubClassOne('two')
o1a = SubClassOne('one')
self.assertEqual(o1.name, 'one')
self.assertEqual(o2.name, 'two')
self.assertEqual(o1a.name, 'one')
self.assertFalse(o1 is o2)
self.assertTrue(o1 is o1a)
def test_different_classes(self):
o1 = SubClassOne('one')
o2 = SubClassTwo('one')
self.assertEqual(o1.name, 'one')
self.assertEqual(o2.name, 'one')
self.assertFalse(o1 is o2)
class SubClassKwArgsTestCase(unittest.TestCase):
def test_init_signature(self):
self.assertRaises(TypeError, SubClassKwArgs, 'one', 'two')
def test_distinct_kwargs(self):
o1 = SubClassKwArgs('one', a=1)
o2 = SubClassKwArgs('two')
o1a = SubClassKwArgs('one', a=2)
o1b = SubClassKwArgs('one', a=1)
o1c = SubClassKwArgs('one', a=1, b=2)
o1d = SubClassKwArgs('one', b=2, a=1)
self.assertEqual(o1.a, 1)
self.assertEqual(o1a.a, 2)
self.assertEqual(o1b.a, 1)
self.assertRaises(AttributeError, getattr, o2, 'a')
self.assertFalse(o1 is o2)
self.assertFalse(o1 is o1a)
self.assertTrue(o1 is o1b)
self.assertTrue(o1c is o1d)
class SubClassDistinctDicts(unittest.TestCase):
def test_distinct_storage_per_subclass(self):
o1 = SubClassOne('one')
o2 = SubClassTwo('one')
o1a = SubClassOne('two')
o2a = SubClassTwo('two')
self.assertEqual(o1.name, 'one')
self.assertEqual(o2.name, 'one')
self.assertEqual(o1a.name, 'two')
self.assertEqual(o2a.name, 'two')
self.assertTrue(o1._singles is o1a._singles)
self.assertTrue(o2._singles is o2a._singles)
self.assertFalse(o1._singles is o2._singles)
self.assertFalse(o1a._singles is o2a._singles)
class SubClassThreeTestCase(unittest.TestCase):
def test_singleton_inheritance(self):
o1 = SubClassThree('one')
o2 = SubClassThree('two')
o1a = SubClassThree('one')
self.assertEquals(o1.name2, 'one')
self.assertEquals(o2.name2, 'two')
self.assertEquals(o1a.name2, 'one')
self.assertTrue(o1 is o1a)
self.assertFalse(o1 is o2)
class SubClassMultipleTestCase(unittest.TestCase):
def test_multiple_inheritance(self):
o1 = SubClassMultiple('one')
o2 = SubClassMultiple('two')
o1a = SubClassMultiple('one')
self.assertEquals(o1.ret5(), 5)
self.assertEquals(o2.ret5(), 5)
self.assertEquals(o1a.ret5(), 5)
self.assertTrue(o1 is o1a)
self.assertFalse(o1 is o2)
class SubClassNoReinitTestCase(unittest.TestCase):
def test_no_reinit(self):
o1 = SubClassNoReinit('one')
o2 = SubClassNoReinit('one')
self.assertTrue(o1 is o2)
if __name__ == '__main__':
unittest.main()
......@@ -4,8 +4,44 @@ README
snf-burnin is an integration testing tool for a running Synnefo deployment.
It runs test scenarios from the following categories:
*Authentication
*Images
*Flavors
*Servers
*Networking
- Authentication
- Images
- Flavors
- Servers
- Networking
======
Usage
======
Example:
--------
snf-burnin --api=API_URL --token=TOKEN --image-id=IMAGE-ID --log-folder=LOG_FOLDER
For more options:
------------------
snf-burnin --help
==========
Log files
==========
In each run, snf-burnin stores log files in the folder defined in the --log-folder parameter (default is /var/log/burnin) under the folder with the timestamp of the snf-burnin-run and the image used for it. The name prefixes of the log files are:
- details: Showing the complete log of snf-burnin run.
- error: Showing the testcases that encountered a runtime error.
- failed: Showing the testcases that encountered a failure.
Example scripts
-----------------
Under /snf-tools/conf/ you can find example scripts for automating snf-burnin testing using cron.
- **snf-burnin-run.sh** runs snf-burnin with the given parameters, deletes stale instances (servers, networks) from old runs and delete logs older than a week. It aborts if snf-burnin runs for longer than expected.
- **Usage**: ./snf-burnin-run.sh TOKEN IMAGE-ID LOG_FOLDER
- **snf-burnin-output.sh** checks for failed snf-burnin tests the last 30 minutes in a given log folder. Exit status is 0 if no failures where encountered, else exit status is 1.
- **Usage**: ./snf-burnin-output.sh LOG_FOLDER
\ No newline at end of file
#! /bin/bash
#Example script to check current status.
#Checks for testcases that failed the last 30 minutes in a given folder.
#Usage: ./check-burnin-output.sh LOG_FOLDER
curr=$(date -d "30 minutes ago" +%Y%m%d%H%M%S)
for dir in ${1}/* ; do
d=`basename $dir`
if (($d>$curr)); then
if find "$dir"/* -type f -size +0 | grep failed >/dev/null; then
echo snf-burnin encountered a testcase failure. See log for details...
exit 1
fi
echo No testcase failure encountered...
exit 0
fi
done
\ No newline at end of file
#! /bin/bash
#Example script for an snf-burnin cronjob.
#Starts an a snf-burnin test, deletes stale instances and archives old logs.
#It aborts if snf-burnin runs for longer than expected.
#Usage: ./snf-burnin-run.sh TOKEN IMAGE-ID LOG-FOLDER
timeout --foreground 25m snf-burnin --token="$1" --image-id="$2" --action-timeout 120 --log-folder "$3"
snf-burnin --token="$1" --delete-stale
#Delete old folders
old=$(date -d "1 week ago" +%Y%m%d%H%M%S)
for dir in ${3}/* ; do
d=`basename $dir`
(($d<$old)) && rm -r "$dir"
done
#! /bin/bash
#Example script for an snf-burnin cronjob
#Usage snf-burnin.cron.example TOKEN IMAGE-ID LOG-FOLDER
snf-burnin --token="$1" --delete-stale
snf-burnin --token="$1" --image-id="$2" --action-timeout 120 --log-folder "$3"
#Delete old folders
old=$(date -d "30 minutes ago" +%Y%m%d%H%M%S)
for dir in ${3}/* ; do
d=`basename $dir`
(($d<$old)) && rm -r "$dir"
done
#Check for failed testcases
curr=$(date -d "30 minutes ago" +%Y%m%d%H%M%S)
for dir in ${3}/* ; do
d=`basename $dir`
if (($d>$curr)); then
if find "$dir"/* -type f -size +0 | grep failed >/dev/null; then
echo snf-burnin encountered a test failure. See log for details...
exit 1
fi
echo No testcase failure encountered
exit 0
fi
done
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment