<commit_before># vim: set expandtab sw=4 ts=4:
#
# Unit tests for tools related functions
#
# Copyright (C) 2014-2016 Dieter Adriaenssens <ruleant@users.sourceforge.net>
#
# This file is part of buildtimetrend/python-lib
# <https://github.com/buildtimetrend/python-lib/>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from builtins import str
from buildtimetrend import tools
from buildtimetrend.tools import nano2sec
from buildtimetrend.tools import check_file
from buildtimetrend.tools import file_is_newer
from buildtimetrend.tools import check_dict
from buildtimetrend.tools import is_dict
from buildtimetrend.tools import keys_in_dict
from buildtimetrend.tools import is_list
from buildtimetrend.tools import is_string
from buildtimetrend.tools import check_num_string
from buildtimetrend.tools import get_repo_slug
from buildtimetrend.settings import Settings
from datetime import datetime
from decimal import Decimal
from dateutil.tz import tzutc
import unittest
from buildtimetrend.test import constants

class TestTools(unittest.TestCase):

    """Unit tests for tools related functions"""

    @classmethod
    def setUpClass(cls):
        """Set up test fixture."""
        cls.project_info = Settings().get_project_info()
        cls.maxDiff = None

    def test_format_timestamp(self):
        """Test format_timestamp()"""
        # test 0 timestamp (epoch)
        self.assertEqual("1970-01-01T00:00:00", tools.format_timestamp(0))

        # test timestamp
        self.assertEqual(
            "2014-07-09T12:38:33", tools.format_timestamp(1404909513)
        )

    def test_split_timestamp(self):
        """Test split_timestamp()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, tools.split_timestamp)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, tools.split_timestamp, None)
        self.assertRaises(TypeError, tools.split_timestamp, "string")

        # test 0 timestamp (epoch)
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH, tools.split_timestamp(0)
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            tools.split_timestamp(nano2sec(constants.TIMESTAMP_NANO_TESTDATE))
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_STARTED,
            tools.split_timestamp(constants.TIMESTAMP_STARTED)
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_FINISHED,
            tools.split_timestamp(nano2sec(constants.TIMESTAMP_NANO_FINISHED))
        )

    def test_split_isotimestamp(self):
        """Test split_isotimestamp()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, tools.split_isotimestamp)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, tools.split_isotimestamp, None)
        self.assertRaises(TypeError, tools.split_isotimestamp, 1234)
        self.assertRaises(ValueError, tools.split_isotimestamp, "string")

        # test 0 timestamp (epoch) in UTC
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            tools.split_isotimestamp("1970-01-01T00:00:00Z")
        )

        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            tools.split_isotimestamp("1970-01-01T00:00:00Z")
        )

        # test 0 timestamp (epoch), without timezone
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH_NOTZ,
            tools.split_isotimestamp("1970-01-01T00:00:00")
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            tools.split_isotimestamp(constants.ISOTIMESTAMP_TESTDATE)
        )

    def test_split_datetime(self):
        """Test split_datetime()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, tools.split_datetime)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, tools.split_datetime, None)
        self.assertRaises(TypeError, tools.split_datetime, "string")

        # test 0 timestamp (epoch) in UTC
        epoch_utc_dt = datetime.utcfromtimestamp(0).replace(tzinfo=tzutc())
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            tools.split_datetime(epoch_utc_dt)
        )

        # test 0 timestamp (epoch), without timezone
        epoch_dt = datetime.utcfromtimestamp(0)
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH_NOTZ,
            tools.split_datetime(epoch_dt)
        )

        # test timestamp
        timestamp_dt = datetime.utcfromtimestamp(constants.TIMESTAMP_TESTDATE)
        timestamp_dt = timestamp_dt.replace(tzinfo=tzutc())

        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            tools.split_datetime(timestamp_dt)
        )

    def test_nano2sec(self):
        """Test nano2sec()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, nano2sec)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, nano2sec, None)
        self.assertRaises(ValueError, nano2sec, "string")

        # test valid parameters
        self.assertEqual(0.0, nano2sec(0))
        self.assertAlmostEqual(
            Decimal(123.456789123), nano2sec(123456789123), 9
        )
        self.assertAlmostEqual(
            Decimal(0.123456789123), nano2sec(123456789.123), 9
        )
        self.assertAlmostEqual(
            Decimal(-123.456789123), nano2sec(-123456789123), 9
        )
        self.assertAlmostEqual(
            Decimal(123.456789123), nano2sec("123456789123"), 9
        )

    def test_check_file(self):
        """Test check_file()"""
        # function should return false when file doesn't exist
        self.assertFalse(check_file('nofile.csv'))
        self.assertFalse(check_file(''))

        # function should throw an error when no filename is set
        self.assertRaises(TypeError, check_file)

        # function should return true if file exists
        self.assertTrue(check_file(constants.TEST_SAMPLE_TIMESTAMP_FILE))

    def test_file_is_newer(self):
        """Test file_is_newer()"""
        NEWER_FILE = 'newer_file.tmp'

        # create a testfile
        with open(NEWER_FILE, 'w') as outfile:
            outfile.write("test")

        # function should return false when any of the files doesn't exist
        self.assertFalse(file_is_newer('nofile.csv', 'nofile.csv'))
        self.assertFalse(
            file_is_newer('nofile.csv', constants.TEST_SAMPLE_TIMESTAMP_FILE)
        )
        self.assertFalse(
            file_is_newer(constants.TEST_SAMPLE_TIMESTAMP_FILE, 'nofile.csv')
        )

        # function should throw an error when no filename is set
        self.assertRaises(TypeError, file_is_newer)
        self.assertRaises(TypeError, file_is_newer, '')
        self.assertRaises(TypeError, file_is_newer, None, '')

        # function should return false if both files
        # were modified at the same time
        self.assertFalse(
            file_is_newer(
                constants.TEST_SAMPLE_TIMESTAMP_FILE,
                constants.TEST_SAMPLE_TIMESTAMP_FILE
            )
        )

        # file 1 is newer than file 2
        self.assertTrue(
            file_is_newer(
                NEWER_FILE,
                constants.TEST_SAMPLE_TIMESTAMP_FILE
            )
        )

        # file 1 is older than file 2
        self.assertFalse(
            file_is_newer(
                constants.TEST_SAMPLE_TIMESTAMP_FILE,
                NEWER_FILE
            )
        )

    def test_is_dict(self):
        """Test is_dict()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, is_dict)

        self.assertFalse(is_dict(None))
        self.assertFalse(is_dict("not_a_dict"))
        self.assertFalse(is_dict(4567))
        self.assertFalse(is_dict(("string", "test")))
        self.assertFalse(is_dict(["string", "test"]))
        self.assertTrue(is_dict({"string": "test"}))

    def test_check_dict(self):
        """Test check_dict()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, check_dict)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            check_dict(None, "name")
        self.assertEqual(
            "param name should be a dictionary", str(cm.exception)
        )

        with self.assertRaises(TypeError) as cm:
            check_dict("string", "string_name")
        self.assertEqual(
            "param string_name should be a dictionary", str(cm.exception)
        )

        # should return true if parameter is a dictionary
        self.assertTrue(check_dict({"string": "test"}, "name"))

        # should return false if parameter is not a list (and name is not set)
        self.assertFalse(check_dict(None))
        self.assertFalse(check_dict("string"))

        # should return true if key is found in dictionary
        self.assertTrue(check_dict({"string": "test"}, "name", "string"))
        self.assertTrue(check_dict(
            {"string": "test", 7: "test"},
            "name",
            list({7, "string"})
        ))

        # should return false if key is not found in dictionary
        self.assertFalse(check_dict(
            {"string": "test"},
            "name",
            list({7})
        ))

    def test_keys_in_dict(self):
        """Test keys_in_dict()"""
        # empty dict and empty key_list should return true
        self.assertTrue(keys_in_dict({}, []))
        self.assertTrue(keys_in_dict({"string": "test"}, []))

        # find 1 key in dict
        self.assertTrue(keys_in_dict({"string": "test"}, "string"))
        self.assertTrue(keys_in_dict({"string": "test", 7: "test"}, "string"))
        self.assertTrue(keys_in_dict({7: "test"}, 7))
        self.assertTrue(keys_in_dict({"string": "test", 7: "test"}, 7))

        # find multiple keys in dict
        self.assertTrue(keys_in_dict(
            {"string": "test", 7: "test"},
            list({7, "string"})
        ))

        # passing something else than a list should return true
        self.assertFalse(keys_in_dict({"string": "test"}, {}))

        # missing keys
        self.assertFalse(keys_in_dict({"string": "test"}, 7))
        self.assertFalse(keys_in_dict({7: "test"}, "string"))
        self.assertFalse(keys_in_dict({"string": "test"}, list({7, "string"})))

    def test_is_list(self):
        """Test is_list()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, is_list)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_list(None, "name")
        self.assertEqual("param name should be a list", str(cm.exception))

        with self.assertRaises(TypeError) as cm:
            is_list("string", "string_name")
        self.assertEqual(
            "param string_name should be a list", str(cm.exception)
        )

        # should return false if parameter is not a list (and name is not set)
        self.assertFalse(is_list(None))
        self.assertFalse(is_list("string"))
        self.assertFalse(is_list(4567))
        self.assertFalse(is_list(("string", "test")))
        self.assertFalse(is_list({"string": "test"}))

        # should return true if parameter is a list
        self.assertTrue(is_list(["string", "test"], "name"))

    def test_is_string(self):
        """Test is_string()"""
        self.assertRaises(TypeError, is_string)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string(None, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string(123, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string({}, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string([], "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        self.assertFalse(is_string(None))
        self.assertFalse(is_string(None, None))

        self.assertTrue(is_string("string", "name"))

    def test_num_string(self):
        """Test check_num_string()"""
        self.assertRaises(TypeError, check_num_string)
        self.assertRaises(TypeError, check_num_string, None)
        self.assertRaises(TypeError, check_num_string, 2.2, "name")
        self.assertRaises(ValueError, check_num_string, "2.2", "name")

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            check_num_string(None, "name")
        self.assertEqual(
            "param name should be a numerical string or an integer",
            str(cm.exception)
        )

        self.assertEqual(0, check_num_string(0, "name"))
        self.assertEqual(1, check_num_string(1, "name"))
        self.assertEqual(-1, check_num_string(-1, "name"))
        self.assertEqual(2, check_num_string(2, "name"))

        self.assertEqual(0, check_num_string("0", "name"))
        self.assertEqual(1, check_num_string("1", "name"))
        self.assertEqual(-1, check_num_string("-1", "name"))
        self.assertEqual(2, check_num_string("2", "name"))

    def test_get_repo_slug(self):
        """Test get_repo_slug()"""
        self.assertEqual(None, get_repo_slug())
        self.assertEqual(None, get_repo_slug("abcd", None))
        self.assertEqual(None, get_repo_slug(None, "efgh"))
        self.assertEqual(None, get_repo_slug(None, None))

        self.assertEqual("abcd/efgh", get_repo_slug("abcd", "efgh"))
        self.assertEqual("Abcd/eFgh", get_repo_slug("Abcd", "eFgh"))
        self.assertEqual("123/456", get_repo_slug(123, 456))
<commit_msg>use namespace for function calls<commit_after># vim: set expandtab sw=4 ts=4:
#
# Unit tests for tools related functions
#
# Copyright (C) 2014-2016 Dieter Adriaenssens <ruleant@users.sourceforge.net>
#
# This file is part of buildtimetrend/python-lib
# <https://github.com/buildtimetrend/python-lib/>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from builtins import str
from buildtimetrend import tools
from buildtimetrend.tools import nano2sec
from buildtimetrend.tools import check_file
from buildtimetrend.tools import file_is_newer
from buildtimetrend.tools import check_dict
from buildtimetrend.tools import keys_in_dict
from buildtimetrend.tools import is_string
from buildtimetrend.tools import check_num_string
from buildtimetrend.tools import get_repo_slug
from buildtimetrend.settings import Settings
from datetime import datetime
from decimal import Decimal
from dateutil.tz import tzutc
import unittest
from buildtimetrend.test import constants

class TestTools(unittest.TestCase):

    """Unit tests for tools related functions"""

    @classmethod
    def setUpClass(cls):
        """Set up test fixture."""
        cls.project_info = Settings().get_project_info()
        cls.maxDiff = None

    def test_format_timestamp(self):
        """Test format_timestamp()"""
        # test 0 timestamp (epoch)
        self.assertEqual("1970-01-01T00:00:00", tools.format_timestamp(0))

        # test timestamp
        self.assertEqual(
            "2014-07-09T12:38:33", tools.format_timestamp(1404909513)
        )

    def test_split_timestamp(self):
        """Test split_timestamp()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, tools.split_timestamp)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, tools.split_timestamp, None)
        self.assertRaises(TypeError, tools.split_timestamp, "string")

        # test 0 timestamp (epoch)
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH, tools.split_timestamp(0)
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            tools.split_timestamp(nano2sec(constants.TIMESTAMP_NANO_TESTDATE))
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_STARTED,
            tools.split_timestamp(constants.TIMESTAMP_STARTED)
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_FINISHED,
            tools.split_timestamp(nano2sec(constants.TIMESTAMP_NANO_FINISHED))
        )

    def test_split_isotimestamp(self):
        """Test split_isotimestamp()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, tools.split_isotimestamp)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, tools.split_isotimestamp, None)
        self.assertRaises(TypeError, tools.split_isotimestamp, 1234)
        self.assertRaises(ValueError, tools.split_isotimestamp, "string")

        # test 0 timestamp (epoch) in UTC
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            tools.split_isotimestamp("1970-01-01T00:00:00Z")
        )

        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            tools.split_isotimestamp("1970-01-01T00:00:00Z")
        )

        # test 0 timestamp (epoch), without timezone
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH_NOTZ,
            tools.split_isotimestamp("1970-01-01T00:00:00")
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            tools.split_isotimestamp(constants.ISOTIMESTAMP_TESTDATE)
        )

    def test_split_datetime(self):
        """Test split_datetime()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, tools.split_datetime)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, tools.split_datetime, None)
        self.assertRaises(TypeError, tools.split_datetime, "string")

        # test 0 timestamp (epoch) in UTC
        epoch_utc_dt = datetime.utcfromtimestamp(0).replace(tzinfo=tzutc())
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            tools.split_datetime(epoch_utc_dt)
        )

        # test 0 timestamp (epoch), without timezone
        epoch_dt = datetime.utcfromtimestamp(0)
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH_NOTZ,
            tools.split_datetime(epoch_dt)
        )

        # test timestamp
        timestamp_dt = datetime.utcfromtimestamp(constants.TIMESTAMP_TESTDATE)
        timestamp_dt = timestamp_dt.replace(tzinfo=tzutc())

        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            tools.split_datetime(timestamp_dt)
        )

    def test_nano2sec(self):
        """Test nano2sec()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, nano2sec)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, nano2sec, None)
        self.assertRaises(ValueError, nano2sec, "string")

        # test valid parameters
        self.assertEqual(0.0, nano2sec(0))
        self.assertAlmostEqual(
            Decimal(123.456789123), nano2sec(123456789123), 9
        )
        self.assertAlmostEqual(
            Decimal(0.123456789123), nano2sec(123456789.123), 9
        )
        self.assertAlmostEqual(
            Decimal(-123.456789123), nano2sec(-123456789123), 9
        )
        self.assertAlmostEqual(
            Decimal(123.456789123), nano2sec("123456789123"), 9
        )

    def test_check_file(self):
        """Test check_file()"""
        # function should return false when file doesn't exist
        self.assertFalse(check_file('nofile.csv'))
        self.assertFalse(check_file(''))

        # function should throw an error when no filename is set
        self.assertRaises(TypeError, check_file)

        # function should return true if file exists
        self.assertTrue(check_file(constants.TEST_SAMPLE_TIMESTAMP_FILE))

    def test_file_is_newer(self):
        """Test file_is_newer()"""
        NEWER_FILE = 'newer_file.tmp'

        # create a testfile
        with open(NEWER_FILE, 'w') as outfile:
            outfile.write("test")

        # function should return false when any of the files doesn't exist
        self.assertFalse(file_is_newer('nofile.csv', 'nofile.csv'))
        self.assertFalse(
            file_is_newer('nofile.csv', constants.TEST_SAMPLE_TIMESTAMP_FILE)
        )
        self.assertFalse(
            file_is_newer(constants.TEST_SAMPLE_TIMESTAMP_FILE, 'nofile.csv')
        )

        # function should throw an error when no filename is set
        self.assertRaises(TypeError, file_is_newer)
        self.assertRaises(TypeError, file_is_newer, '')
        self.assertRaises(TypeError, file_is_newer, None, '')

        # function should return false if both files
        # were modified at the same time
        self.assertFalse(
            file_is_newer(
                constants.TEST_SAMPLE_TIMESTAMP_FILE,
                constants.TEST_SAMPLE_TIMESTAMP_FILE
            )
        )

        # file 1 is newer than file 2
        self.assertTrue(
            file_is_newer(
                NEWER_FILE,
                constants.TEST_SAMPLE_TIMESTAMP_FILE
            )
        )

        # file 1 is older than file 2
        self.assertFalse(
            file_is_newer(
                constants.TEST_SAMPLE_TIMESTAMP_FILE,
                NEWER_FILE
            )
        )

    def test_is_dict(self):
        """Test is_dict()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, tools.is_dict)

        self.assertFalse(tools.is_dict(None))
        self.assertFalse(tools.is_dict("not_a_dict"))
        self.assertFalse(tools.is_dict(4567))
        self.assertFalse(tools.is_dict(("string", "test")))
        self.assertFalse(tools.is_dict(["string", "test"]))
        self.assertTrue(tools.is_dict({"string": "test"}))

    def test_check_dict(self):
        """Test check_dict()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, check_dict)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            check_dict(None, "name")
        self.assertEqual(
            "param name should be a dictionary", str(cm.exception)
        )

        with self.assertRaises(TypeError) as cm:
            check_dict("string", "string_name")
        self.assertEqual(
            "param string_name should be a dictionary", str(cm.exception)
        )

        # should return true if parameter is a dictionary
        self.assertTrue(check_dict({"string": "test"}, "name"))

        # should return false if parameter is not a list (and name is not set)
        self.assertFalse(check_dict(None))
        self.assertFalse(check_dict("string"))

        # should return true if key is found in dictionary
        self.assertTrue(check_dict({"string": "test"}, "name", "string"))
        self.assertTrue(check_dict(
            {"string": "test", 7: "test"},
            "name",
            list({7, "string"})
        ))

        # should return false if key is not found in dictionary
        self.assertFalse(check_dict(
            {"string": "test"},
            "name",
            list({7})
        ))

    def test_keys_in_dict(self):
        """Test keys_in_dict()"""
        # empty dict and empty key_list should return true
        self.assertTrue(keys_in_dict({}, []))
        self.assertTrue(keys_in_dict({"string": "test"}, []))

        # find 1 key in dict
        self.assertTrue(keys_in_dict({"string": "test"}, "string"))
        self.assertTrue(keys_in_dict({"string": "test", 7: "test"}, "string"))
        self.assertTrue(keys_in_dict({7: "test"}, 7))
        self.assertTrue(keys_in_dict({"string": "test", 7: "test"}, 7))

        # find multiple keys in dict
        self.assertTrue(keys_in_dict(
            {"string": "test", 7: "test"},
            list({7, "string"})
        ))

        # passing something else than a list should return true
        self.assertFalse(keys_in_dict({"string": "test"}, {}))

        # missing keys
        self.assertFalse(keys_in_dict({"string": "test"}, 7))
        self.assertFalse(keys_in_dict({7: "test"}, "string"))
        self.assertFalse(keys_in_dict({"string": "test"}, list({7, "string"})))

    def test_is_list(self):
        """Test is_list()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, tools.is_list)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            tools.is_list(None, "name")
        self.assertEqual("param name should be a list", str(cm.exception))

        with self.assertRaises(TypeError) as cm:
            tools.is_list("string", "string_name")
        self.assertEqual(
            "param string_name should be a list", str(cm.exception)
        )

        # should return false if parameter is not a list (and name is not set)
        self.assertFalse(tools.is_list(None))
        self.assertFalse(tools.is_list("string"))
        self.assertFalse(tools.is_list(4567))
        self.assertFalse(tools.is_list(("string", "test")))
        self.assertFalse(tools.is_list({"string": "test"}))

        # should return true if parameter is a list
        self.assertTrue(tools.is_list(["string", "test"], "name"))

    def test_is_string(self):
        """Test is_string()"""
        self.assertRaises(TypeError, is_string)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string(None, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string(123, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string({}, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string([], "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        self.assertFalse(is_string(None))
        self.assertFalse(is_string(None, None))

        self.assertTrue(is_string("string", "name"))

    def test_num_string(self):
        """Test check_num_string()"""
        self.assertRaises(TypeError, check_num_string)
        self.assertRaises(TypeError, check_num_string, None)
        self.assertRaises(TypeError, check_num_string, 2.2, "name")
        self.assertRaises(ValueError, check_num_string, "2.2", "name")

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            check_num_string(None, "name")
        self.assertEqual(
            "param name should be a numerical string or an integer",
            str(cm.exception)
        )

        self.assertEqual(0, check_num_string(0, "name"))
        self.assertEqual(1, check_num_string(1, "name"))
        self.assertEqual(-1, check_num_string(-1, "name"))
        self.assertEqual(2, check_num_string(2, "name"))

        self.assertEqual(0, check_num_string("0", "name"))
        self.assertEqual(1, check_num_string("1", "name"))
        self.assertEqual(-1, check_num_string("-1", "name"))
        self.assertEqual(2, check_num_string("2", "name"))

    def test_get_repo_slug(self):
        """Test get_repo_slug()"""
        self.assertEqual(None, get_repo_slug())
        self.assertEqual(None, get_repo_slug("abcd", None))
        self.assertEqual(None, get_repo_slug(None, "efgh"))
        self.assertEqual(None, get_repo_slug(None, None))

        self.assertEqual("abcd/efgh", get_repo_slug("abcd", "efgh"))
        self.assertEqual("Abcd/eFgh", get_repo_slug("Abcd", "eFgh"))
        self.assertEqual("123/456", get_repo_slug(123, 456))
<|endoftext|>


<commit_before># vim: set expandtab sw=4 ts=4:
#
# Unit tests for Tools
#
# Copyright (C) 2014-2015 Dieter Adriaenssens <ruleant@users.sourceforge.net>
#
# This file is part of buildtimetrend/python-lib
# <https://github.com/buildtimetrend/python-lib/>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from builtins import str
import buildtimetrend
from buildtimetrend.tools import *
from buildtimetrend.settings import Settings
import os
import unittest
import constants

class TestTools(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        """Set up test fixture."""
        cls.project_info = Settings().get_project_info()
        cls.maxDiff = None

    def test_format_timestamp(self):
        # test 0 timestamp (epoch)
        self.assertEqual("1970-01-01T00:00:00", format_timestamp(0))

        # test timestamp
        self.assertEqual("2014-07-09T12:38:33", format_timestamp(1404909513))

    def test_split_timestamp(self):
        # error is thrown when called without parameters
        self.assertRaises(TypeError, split_timestamp)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, split_timestamp, None)
        self.assertRaises(TypeError, split_timestamp, "string")

        # test 0 timestamp (epoch)
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH, split_timestamp(0)
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            split_timestamp(nano2sec(constants.TIMESTAMP_NANO_TESTDATE))
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_STARTED,
            split_timestamp(constants.TIMESTAMP_STARTED)
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_FINISHED,
            split_timestamp(nano2sec(constants.TIMESTAMP_NANO_FINISHED))
        )

    def test_split_isotimestamp(self):
        # error is thrown when called without parameters
        self.assertRaises(TypeError, split_isotimestamp)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, split_isotimestamp, None)
        self.assertRaises(TypeError, split_isotimestamp, 1234)
        self.assertRaises(ValueError, split_isotimestamp, "string")

        # test 0 timestamp (epoch) in UTC
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            split_isotimestamp("1970-01-01T00:00:00Z")
        )

        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            split_isotimestamp("1970-01-01T00:00:00Z")
        )

        # test 0 timestamp (epoch), without timezone
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH_NOTZ,
            split_isotimestamp("1970-01-01T00:00:00")
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            split_isotimestamp(constants.ISOTIMESTAMP_TESTDATE)
        )

    def test_split_datetime(self):
        # error is thrown when called without parameters
        self.assertRaises(TypeError, split_datetime)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, split_datetime, None)
        self.assertRaises(TypeError, split_datetime, "string")

        # test 0 timestamp (epoch) in UTC
        epoch_utc_dt = datetime.utcfromtimestamp(0).replace(tzinfo=tzutc())
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            split_datetime(epoch_utc_dt)
        )

        # test 0 timestamp (epoch), without timezone
        epoch_dt = datetime.utcfromtimestamp(0)
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH_NOTZ,
            split_datetime(epoch_dt)
        )

        # test timestamp
        timestamp_dt = datetime.utcfromtimestamp(constants.TIMESTAMP_TESTDATE)
        timestamp_dt = timestamp_dt.replace(tzinfo=tzutc())

        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            split_datetime(timestamp_dt)
        )

    def test_nano2sec(self):
        # error is thrown when called without parameters
        self.assertRaises(TypeError, nano2sec)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, nano2sec, None)
        self.assertRaises(ValueError, nano2sec, "string")

        # test valid parameters
        self.assertEqual(0.0, nano2sec(0))
        self.assertAlmostEqual(
            Decimal(123.456789123), nano2sec(123456789123), 9
        )
        self.assertAlmostEqual(
            Decimal(0.123456789123), nano2sec(123456789.123), 9
        )
        self.assertAlmostEqual(
            Decimal(-123.456789123), nano2sec(-123456789123), 9
        )
        self.assertAlmostEqual(
            Decimal(123.456789123), nano2sec("123456789123"), 9
        )

    def test_check_file(self):
        # function should return false when file doesn't exist
        self.assertFalse(check_file('nofile.csv'))
        self.assertFalse(check_file(''))

        # function should throw an error when no filename is set
        self.assertRaises(TypeError, check_file)

        # function should return true if file exists
        self.assertTrue(check_file(constants.TEST_SAMPLE_TIMESTAMP_FILE))

    def test_file_is_newer(self):
        NEWER_FILE = 'newer_file.tmp'

        # create a testfile
        with open(NEWER_FILE, 'w') as outfile:
            outfile.write("test")

        # function should return false when any of the files doesn't exist
        self.assertFalse(file_is_newer('nofile.csv', 'nofile.csv'))
        self.assertFalse(
            file_is_newer('nofile.csv', constants.TEST_SAMPLE_TIMESTAMP_FILE)
        )
        self.assertFalse(
            file_is_newer(constants.TEST_SAMPLE_TIMESTAMP_FILE, 'nofile.csv')
        )

        # function should throw an error when no filename is set
        self.assertRaises(TypeError, file_is_newer)
        self.assertRaises(TypeError, file_is_newer, '')
        self.assertRaises(TypeError, file_is_newer, None, '')

        # function should return false if both files
        # were modified at the same time
        self.assertFalse(file_is_newer(
            constants.TEST_SAMPLE_TIMESTAMP_FILE,
            constants.TEST_SAMPLE_TIMESTAMP_FILE)
        )

        # file 1 is newer than file 2
        self.assertTrue(file_is_newer(
            NEWER_FILE,
            constants.TEST_SAMPLE_TIMESTAMP_FILE)
        )

        # file 1 is older than file 2
        self.assertFalse(file_is_newer(
            constants.TEST_SAMPLE_TIMESTAMP_FILE,
            NEWER_FILE)
        )

    def test_is_dict(self):
        # error is thrown when called without parameters
        self.assertRaises(TypeError, is_dict)

        self.assertFalse(is_dict(None))
        self.assertFalse(is_dict("not_a_dict"))
        self.assertTrue(is_dict({"string": "test"}))

    def test_check_dict(self):
        # error is thrown when called without parameters
        self.assertRaises(TypeError, check_dict)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            check_dict(None, "name")
        self.assertEqual(
            "param name should be a dictionary", str(cm.exception)
        )

        with self.assertRaises(TypeError) as cm:
            check_dict("string", "string_name")
        self.assertEqual(
            "param string_name should be a dictionary", str(cm.exception)
        )

        # should return true if parameter is a dictionary
        self.assertTrue(check_dict({"string": "test"}, "name"))

        # should return false if parameter is not a list (and name is not set)
        self.assertFalse(check_dict(None))
        self.assertFalse(check_dict("string"))

        # should return true if key is found in dictionary
        self.assertTrue(check_dict({"string": "test"}, "name", "string"))
        self.assertTrue(check_dict(
            {"string": "test", 7: "test"},
            "name",
            list({7, "string"})
        ))

        # should return false if key is not found in dictionary
        self.assertFalse(check_dict(
            {"string": "test"},
            "name",
            list({7})
        ))

    def test_keys_in_dict(self):
        # empty dict and empty key_list should return true
        self.assertTrue(keys_in_dict({}, []))
        self.assertTrue(keys_in_dict({"string": "test"}, []))

        # find 1 key in dict
        self.assertTrue(keys_in_dict({"string": "test"}, "string"))
        self.assertTrue(keys_in_dict({"string": "test", 7: "test"}, "string"))
        self.assertTrue(keys_in_dict({7: "test"}, 7))
        self.assertTrue(keys_in_dict({"string": "test", 7: "test"}, 7))

        # find multiple keys in dict
        self.assertTrue(keys_in_dict(
            {"string": "test", 7: "test"},
            list({7, "string"})
        ))

        # passing something else than a list should return true
        self.assertFalse(keys_in_dict({"string": "test"}, {}))

        # missing keys
        self.assertFalse(keys_in_dict({"string": "test"}, 7))
        self.assertFalse(keys_in_dict({7: "test"}, "string"))
        self.assertFalse(keys_in_dict({"string": "test"}, list({7, "string"})))

    def test_is_list(self):
        # error is thrown when called without parameters
        self.assertRaises(TypeError, is_list)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_list(None, "name")
        self.assertEqual("param name should be a list", str(cm.exception))

        with self.assertRaises(TypeError) as cm:
            is_list("string", "string_name")
        self.assertEqual(
            "param string_name should be a list", str(cm.exception)
        )

        # should return false if parameter is not a list (and name is not set)
        self.assertFalse(is_list(None))
        self.assertFalse(is_list("string"))

        # should return true if parameter is a list
        self.assertTrue(is_list(["string", "test"], "name"))

    def test_is_string(self):
        self.assertRaises(TypeError, is_string)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string(None, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string(123, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string({}, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string([], "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        self.assertFalse(is_string(None))
        self.assertFalse(is_string(None, None))

        self.assertTrue(is_string("string", "name"))

    def test_num_string(self):
        self.assertRaises(TypeError, check_num_string)
        self.assertRaises(TypeError, check_num_string, None)
        self.assertRaises(TypeError, check_num_string, 2.2, "name")
        self.assertRaises(ValueError, check_num_string, "2.2", "name")

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            check_num_string(None, "name")
        self.assertEqual(
            "param name should be a numerical string or an integer",
            str(cm.exception)
        )

        self.assertEqual(0, check_num_string(0, "name"))
        self.assertEqual(1, check_num_string(1, "name"))
        self.assertEqual(-1, check_num_string(-1, "name"))
        self.assertEqual(2, check_num_string(2, "name"))

        self.assertEqual(0, check_num_string("0", "name"))
        self.assertEqual(1, check_num_string("1", "name"))
        self.assertEqual(-1, check_num_string("-1", "name"))
        self.assertEqual(2, check_num_string("2", "name"))

    def test_get_repo_slug(self):
        self.assertEqual(None, get_repo_slug())
        self.assertEqual(None, get_repo_slug("abcd", None))
        self.assertEqual(None, get_repo_slug(None, "efgh"))
        self.assertEqual(None, get_repo_slug(None, None))

        self.assertEqual("abcd/efgh", get_repo_slug("abcd", "efgh"))
        self.assertEqual("Abcd/eFgh", get_repo_slug("Abcd", "eFgh"))
        self.assertEqual("123/456", get_repo_slug(123, 456))
<commit_msg>add class and function docs<commit_after># vim: set expandtab sw=4 ts=4:
#
# Unit tests for Tools
#
# Copyright (C) 2014-2015 Dieter Adriaenssens <ruleant@users.sourceforge.net>
#
# This file is part of buildtimetrend/python-lib
# <https://github.com/buildtimetrend/python-lib/>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from builtins import str
import buildtimetrend
from buildtimetrend.tools import *
from buildtimetrend.settings import Settings
import os
import unittest
import constants

class TestTools(unittest.TestCase):

    """Unit tests for tools functions"""

    @classmethod
    def setUpClass(cls):
        """Set up test fixture."""
        cls.project_info = Settings().get_project_info()
        cls.maxDiff = None

    def test_format_timestamp(self):
        """Test format_timestamp()"""
        # test 0 timestamp (epoch)
        self.assertEqual("1970-01-01T00:00:00", format_timestamp(0))

        # test timestamp
        self.assertEqual("2014-07-09T12:38:33", format_timestamp(1404909513))

    def test_split_timestamp(self):
        """Test split_timestamp()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, split_timestamp)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, split_timestamp, None)
        self.assertRaises(TypeError, split_timestamp, "string")

        # test 0 timestamp (epoch)
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH, split_timestamp(0)
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            split_timestamp(nano2sec(constants.TIMESTAMP_NANO_TESTDATE))
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_STARTED,
            split_timestamp(constants.TIMESTAMP_STARTED)
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_FINISHED,
            split_timestamp(nano2sec(constants.TIMESTAMP_NANO_FINISHED))
        )

    def test_split_isotimestamp(self):
        """Test split_isotimestamp()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, split_isotimestamp)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, split_isotimestamp, None)
        self.assertRaises(TypeError, split_isotimestamp, 1234)
        self.assertRaises(ValueError, split_isotimestamp, "string")

        # test 0 timestamp (epoch) in UTC
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            split_isotimestamp("1970-01-01T00:00:00Z")
        )

        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            split_isotimestamp("1970-01-01T00:00:00Z")
        )

        # test 0 timestamp (epoch), without timezone
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH_NOTZ,
            split_isotimestamp("1970-01-01T00:00:00")
        )

        # test timestamp
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            split_isotimestamp(constants.ISOTIMESTAMP_TESTDATE)
        )

    def test_split_datetime(self):
        """Test split_datetime()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, split_datetime)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, split_datetime, None)
        self.assertRaises(TypeError, split_datetime, "string")

        # test 0 timestamp (epoch) in UTC
        epoch_utc_dt = datetime.utcfromtimestamp(0).replace(tzinfo=tzutc())
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH,
            split_datetime(epoch_utc_dt)
        )

        # test 0 timestamp (epoch), without timezone
        epoch_dt = datetime.utcfromtimestamp(0)
        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_EPOCH_NOTZ,
            split_datetime(epoch_dt)
        )

        # test timestamp
        timestamp_dt = datetime.utcfromtimestamp(constants.TIMESTAMP_TESTDATE)
        timestamp_dt = timestamp_dt.replace(tzinfo=tzutc())

        self.assertDictEqual(
            constants.SPLIT_TIMESTAMP_TESTDATE,
            split_datetime(timestamp_dt)
        )

    def test_nano2sec(self):
        """Test nano2sec()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, nano2sec)

        # error is thrown when called with an invalid parameter
        self.assertRaises(TypeError, nano2sec, None)
        self.assertRaises(ValueError, nano2sec, "string")

        # test valid parameters
        self.assertEqual(0.0, nano2sec(0))
        self.assertAlmostEqual(
            Decimal(123.456789123), nano2sec(123456789123), 9
        )
        self.assertAlmostEqual(
            Decimal(0.123456789123), nano2sec(123456789.123), 9
        )
        self.assertAlmostEqual(
            Decimal(-123.456789123), nano2sec(-123456789123), 9
        )
        self.assertAlmostEqual(
            Decimal(123.456789123), nano2sec("123456789123"), 9
        )

    def test_check_file(self):
        """Test check_file()"""
        # function should return false when file doesn't exist
        self.assertFalse(check_file('nofile.csv'))
        self.assertFalse(check_file(''))

        # function should throw an error when no filename is set
        self.assertRaises(TypeError, check_file)

        # function should return true if file exists
        self.assertTrue(check_file(constants.TEST_SAMPLE_TIMESTAMP_FILE))

    def test_file_is_newer(self):
        """Test file_is_newer()"""
        NEWER_FILE = 'newer_file.tmp'

        # create a testfile
        with open(NEWER_FILE, 'w') as outfile:
            outfile.write("test")

        # function should return false when any of the files doesn't exist
        self.assertFalse(file_is_newer('nofile.csv', 'nofile.csv'))
        self.assertFalse(
            file_is_newer('nofile.csv', constants.TEST_SAMPLE_TIMESTAMP_FILE)
        )
        self.assertFalse(
            file_is_newer(constants.TEST_SAMPLE_TIMESTAMP_FILE, 'nofile.csv')
        )

        # function should throw an error when no filename is set
        self.assertRaises(TypeError, file_is_newer)
        self.assertRaises(TypeError, file_is_newer, '')
        self.assertRaises(TypeError, file_is_newer, None, '')

        # function should return false if both files
        # were modified at the same time
        self.assertFalse(file_is_newer(
            constants.TEST_SAMPLE_TIMESTAMP_FILE,
            constants.TEST_SAMPLE_TIMESTAMP_FILE)
        )

        # file 1 is newer than file 2
        self.assertTrue(file_is_newer(
            NEWER_FILE,
            constants.TEST_SAMPLE_TIMESTAMP_FILE)
        )

        # file 1 is older than file 2
        self.assertFalse(file_is_newer(
            constants.TEST_SAMPLE_TIMESTAMP_FILE,
            NEWER_FILE)
        )

    def test_is_dict(self):
        """Test is_dict()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, is_dict)

        self.assertFalse(is_dict(None))
        self.assertFalse(is_dict("not_a_dict"))
        self.assertTrue(is_dict({"string": "test"}))

    def test_check_dict(self):
        """Test check_dict()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, check_dict)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            check_dict(None, "name")
        self.assertEqual(
            "param name should be a dictionary", str(cm.exception)
        )

        with self.assertRaises(TypeError) as cm:
            check_dict("string", "string_name")
        self.assertEqual(
            "param string_name should be a dictionary", str(cm.exception)
        )

        # should return true if parameter is a dictionary
        self.assertTrue(check_dict({"string": "test"}, "name"))

        # should return false if parameter is not a list (and name is not set)
        self.assertFalse(check_dict(None))
        self.assertFalse(check_dict("string"))

        # should return true if key is found in dictionary
        self.assertTrue(check_dict({"string": "test"}, "name", "string"))
        self.assertTrue(check_dict(
            {"string": "test", 7: "test"},
            "name",
            list({7, "string"})
        ))

        # should return false if key is not found in dictionary
        self.assertFalse(check_dict(
            {"string": "test"},
            "name",
            list({7})
        ))

    def test_keys_in_dict(self):
        """Test keys_in_dict()"""
        # empty dict and empty key_list should return true
        self.assertTrue(keys_in_dict({}, []))
        self.assertTrue(keys_in_dict({"string": "test"}, []))

        # find 1 key in dict
        self.assertTrue(keys_in_dict({"string": "test"}, "string"))
        self.assertTrue(keys_in_dict({"string": "test", 7: "test"}, "string"))
        self.assertTrue(keys_in_dict({7: "test"}, 7))
        self.assertTrue(keys_in_dict({"string": "test", 7: "test"}, 7))

        # find multiple keys in dict
        self.assertTrue(keys_in_dict(
            {"string": "test", 7: "test"},
            list({7, "string"})
        ))

        # passing something else than a list should return true
        self.assertFalse(keys_in_dict({"string": "test"}, {}))

        # missing keys
        self.assertFalse(keys_in_dict({"string": "test"}, 7))
        self.assertFalse(keys_in_dict({7: "test"}, "string"))
        self.assertFalse(keys_in_dict({"string": "test"}, list({7, "string"})))

    def test_is_list(self):
        """Test is_list()"""
        # error is thrown when called without parameters
        self.assertRaises(TypeError, is_list)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_list(None, "name")
        self.assertEqual("param name should be a list", str(cm.exception))

        with self.assertRaises(TypeError) as cm:
            is_list("string", "string_name")
        self.assertEqual(
            "param string_name should be a list", str(cm.exception)
        )

        # should return false if parameter is not a list (and name is not set)
        self.assertFalse(is_list(None))
        self.assertFalse(is_list("string"))

        # should return true if parameter is a list
        self.assertTrue(is_list(["string", "test"], "name"))

    def test_is_string(self):
        """Test is_string()"""
        self.assertRaises(TypeError, is_string)

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string(None, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string(123, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string({}, "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            is_string([], "name")
        self.assertEqual(
            "param name should be a string",
            str(cm.exception)
        )

        self.assertFalse(is_string(None))
        self.assertFalse(is_string(None, None))

        self.assertTrue(is_string("string", "name"))

    def test_num_string(self):
        """Test check_num_string()"""
        self.assertRaises(TypeError, check_num_string)
        self.assertRaises(TypeError, check_num_string, None)
        self.assertRaises(TypeError, check_num_string, 2.2, "name")
        self.assertRaises(ValueError, check_num_string, "2.2", "name")

        # error is thrown when called with an invalid parameter
        with self.assertRaises(TypeError) as cm:
            check_num_string(None, "name")
        self.assertEqual(
            "param name should be a numerical string or an integer",
            str(cm.exception)
        )

        self.assertEqual(0, check_num_string(0, "name"))
        self.assertEqual(1, check_num_string(1, "name"))
        self.assertEqual(-1, check_num_string(-1, "name"))
        self.assertEqual(2, check_num_string(2, "name"))

        self.assertEqual(0, check_num_string("0", "name"))
        self.assertEqual(1, check_num_string("1", "name"))
        self.assertEqual(-1, check_num_string("-1", "name"))
        self.assertEqual(2, check_num_string("2", "name"))

    def test_get_repo_slug(self):
        """Test get_repo_slug()"""
        self.assertEqual(None, get_repo_slug())
        self.assertEqual(None, get_repo_slug("abcd", None))
        self.assertEqual(None, get_repo_slug(None, "efgh"))
        self.assertEqual(None, get_repo_slug(None, None))

        self.assertEqual("abcd/efgh", get_repo_slug("abcd", "efgh"))
        self.assertEqual("Abcd/eFgh", get_repo_slug("Abcd", "eFgh"))
        self.assertEqual("123/456", get_repo_slug(123, 456))
<|endoftext|>


<commit_before>from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(host='0.0.0.0')
<commit_msg>Very basic websockets-supporting flask app<commit_after># Flask fundamentals
from flask import Flask
app = Flask('toyota')

# Some configuration
app.config['SECRET_KEY'] = 'secret!' # TODO: don't...
app.config['MAX_CONTENT_LENGTH'] = 10 * 1024 # 10KB seems fair

# Websockets
import flask.ext.socketio
socketio = flask.ext.socketio.SocketIO(app)

@app.route("/")
def hello():
    """ The main page...
    """
    return "Hello World!"

if __name__ == "__main__":
    socketio.run(app, host='0.0.0.0')
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

# Copyright (c) 2015 Ericsson AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sys
import time
import random

from calvin.runtime.south.plugins.async import async
from calvin.utilities.calvin_callback import CalvinCB
from calvin.utilities.calvinlogger import get_logger
from calvin.utilities import calvinconfig

_log = get_logger(__name__)
_conf = calvinconfig.get()

class Scheduler(object):

    """docstring for Scheduler"""

    def __init__(self, node, actor_mgr, monitor):
        super(Scheduler, self).__init__()
        self.actor_mgr = actor_mgr
        self.idle = False
        self.done = False
        self.node = node
        self.monitor = monitor
        self._loop_once = None
        self._trigger_set = set()
        self._watchdog = None
        self._watchdog_timeout = 1
        self._maintenance_loop = None
        self._maintenance_delay = _conf.get(None, "maintenance_delay") or 300
        self.actor_pressures = {}

    def run(self):
        async.run_ioloop()

    def stop(self):
        if not self.done:
            async.DelayedCall(0, async.stop_ioloop)
        self.done = True

    def loop_once(self, fire_all=False):
        # We don't know how we got here, so cancel both of these (safe thing to do)
        self._cancel_watchdog()
        self._cancel_schedule()

        # Transfer tokens between actors
        activity = self.monitor.communicate(self)

        # Pick which set of actors to fire, None means EVERY actor
        actors_to_fire = None if fire_all else self._trigger_set
        did_fire, timeout, actor_ids = self.fire_actors(actors_to_fire)

        # Reset the set of potential actors
        self._trigger_set = set()

        # FIXME: This is probably not the correct way to compute activity
        activity = did_fire or activity or timeout

        if activity:
            # Something happened - run again
            self._schedule_actors(actor_ids=actor_ids)
        else:
            # No firings, set a watchdog timeout
            self._watchdog = async.DelayedCall(self._watchdog_timeout, self._watchdog_wakeup)

    def trigger_loop(self, actor_ids=None):
        if actor_ids is None:
            self._schedule_all()
        else:
            self._schedule_actors(actor_ids)

    def _cancel_schedule(self):
        if self._loop_once is not None:
            self._loop_once.cancel()
            self._loop_once = None

    def _cancel_watchdog(self):
        if self._watchdog is not None:
            self._watchdog.cancel()
            self._watchdog = None

    def _watchdog_wakeup(self):
        _log.warning("Watchdog wakeup -- this should not really happen...")
        self._schedule_all()

    def _schedule_all(self):
        # If there is a scheduled loop_once then cancel it since it might be
        # scheduled later, and/or with argument set to False.
        self._cancel_watchdog()
        self._cancel_schedule()
        self._loop_once = async.DelayedCall(0, self.loop_once, True)

    def _schedule_actors(self, actor_ids):
        # Update the set of actors that could possibly fire
        self._trigger_set.update(actor_ids)
        # Schedule loop_once if-and-only-if
        #                    it is not already scheduled
        #                    AND
        #                    the set of actors is non-empty
        if self._loop_once is None and self._trigger_set:
            self._cancel_watchdog()
            self._loop_once = async.DelayedCall(0, self.loop_once)

    def schedule_tunnel(self, backoff_time=0):
        # If backoff_time > 0 don't call UNTIL that time has passed.
        # Doesn't work with current scheduler/monitor, so tunnel::communicate has a workaround
        self._cancel_watchdog()
        self._cancel_schedule()
        self._loop_once = async.DelayedCall(backoff_time, self.loop_once, True)

    def _log_exception_during_fire(self, e):
        _log.exception(e)

    def fire_actors(self, actor_ids=None):
        did_fire = False
        actor_ids = set()

        actors = self.actor_mgr.enabled_actors()
        # Shuffle order since now we stop after executing actors for too long
        random.shuffle(actors)

        start_time = time.time()
        timeout = False
        for actor in actors:
            try:
                _log.debug("Fire actor %s (%s, %s)" % (actor.name, actor._type, actor.id))
                did_fire |= actor.fire()
                actor_ids.add(actor.id)
            except Exception as e:
                self._log_exception_during_fire(e)

            pressure = actor.get_pressure().values()
            pressure_values = [p for _, _, p in pressure]
            if self.actor_pressures.get(actor.id, False) != pressure_values:
                self.actor_pressures[actor.id] = pressure_values

            timeout = time.time() - start_time > 0.100
            if timeout:
                break

        # FIXME: self.idle = not (timeout or did_fire)
        self.idle = False if timeout else not did_fire

        return (did_fire, timeout, actor_ids)

    def maintenance_loop(self):
        # Migrate denied actors
        for actor in self.actor_mgr.migratable_actors():
            self.actor_mgr.migrate(actor.id, actor.migration_info["node_id"],
                                   callback=CalvinCB(actor.remove_migration_info))
        # Enable denied actors again if access is permitted. Will try to migrate if access still denied.
        for actor in self.actor_mgr.denied_actors():
            actor.enable_or_migrate()
        # TODO: try to migrate shadow actors as well.
        self._maintenance_loop = None
        self.trigger_maintenance_loop(delay=True)

    def trigger_maintenance_loop(self, delay=False):
        # Never have more then one maintenance loop.
        if self._maintenance_loop is not None:
            self._maintenance_loop.cancel()
        if delay:
            self._maintenance_loop = async.DelayedCall(self._maintenance_delay, self.maintenance_loop)
        else:
            self._maintenance_loop = async.DelayedCall(0, self.maintenance_loop)

class DebugScheduler(Scheduler):
    """This is an instrumented version of the scheduler for use in debugging runs."""

    def __init__(self, node, actor_mgr, monitor):
        super(DebugScheduler, self).__init__(node, actor_mgr, monitor)

    def trigger_loop(self, actor_ids=None):
        #import inspect
        #import traceback
        super(DebugScheduler, self).trigger_loop(actor_ids=actor_ids)
        #(frame, filename, line_no, fname, lines, index) = inspect.getouterframes(inspect.currentframe())[1]
        #_log.debug("triggered %s by %s in file %s at %s" % (time.time(), fname, filename, line_no))
        #_log.debug("Trigger happend here:\n" + ''.join(traceback.format_stack()[-6:-1]))
        _log.analyze(self.node.id, "+ Triggered", None, tb=True)

    def schedule_tunnel(self, backoff_time=0):
        super(DebugScheduler, self).schedule_tunnel(backoff_time=backoff_time)

    def _log_exception_during_fire(self, e):
        from infi.traceback import format_exception
        _log.error('\n'.join(format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)))

    def fire_actors(self, actor_ids=None):
        from infi.traceback import traceback_context
        traceback_context()
        return super(DebugScheduler, self).fire_actors(actor_ids)
<commit_msg>Removing time-limiting code. Taking out unused idle variable.<commit_after># -*- coding: utf-8 -*-

# Copyright (c) 2015 Ericsson AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sys
import time
import random

from calvin.runtime.south.plugins.async import async
from calvin.utilities.calvin_callback import CalvinCB
from calvin.utilities.calvinlogger import get_logger
from calvin.utilities import calvinconfig

_log = get_logger(__name__)
_conf = calvinconfig.get()

class Scheduler(object):

    """docstring for Scheduler"""

    def __init__(self, node, actor_mgr, monitor):
        super(Scheduler, self).__init__()
        self.actor_mgr = actor_mgr
        self.done = False
        self.node = node
        self.monitor = monitor
        self._loop_once = None
        self._trigger_set = set()
        self._watchdog = None
        self._watchdog_timeout = 1
        self._maintenance_loop = None
        self._maintenance_delay = _conf.get(None, "maintenance_delay") or 300
        self.actor_pressures = {}

    def run(self):
        async.run_ioloop()

    def stop(self):
        if not self.done:
            async.DelayedCall(0, async.stop_ioloop)
        self.done = True

    def loop_once(self, fire_all=False):
        # We don't know how we got here, so cancel both of these (safe thing to do)
        self._cancel_watchdog()
        self._cancel_schedule()

        # Transfer tokens between actors
        activity = self.monitor.communicate(self)

        # Pick which set of actors to fire, None means EVERY actor
        actors_to_fire = None if fire_all else self._trigger_set
        did_fire, timeout, actor_ids = self.fire_actors(actors_to_fire)

        # Reset the set of potential actors
        self._trigger_set = set()

        # FIXME: This is probably not the correct way to compute activity
        activity = did_fire or activity or timeout

        if activity:
            # Something happened - run again
            self._schedule_actors(actor_ids=actor_ids)
        else:
            # No firings, set a watchdog timeout
            self._watchdog = async.DelayedCall(self._watchdog_timeout, self._watchdog_wakeup)

    def trigger_loop(self, actor_ids=None):
        if actor_ids is None:
            self._schedule_all()
        else:
            self._schedule_actors(actor_ids)

    def _cancel_schedule(self):
        if self._loop_once is not None:
            self._loop_once.cancel()
            self._loop_once = None

    def _cancel_watchdog(self):
        if self._watchdog is not None:
            self._watchdog.cancel()
            self._watchdog = None

    def _watchdog_wakeup(self):
        _log.warning("Watchdog wakeup -- this should not really happen...")
        self._schedule_all()

    def _schedule_all(self):
        # If there is a scheduled loop_once then cancel it since it might be
        # scheduled later, and/or with argument set to False.
        self._cancel_watchdog()
        self._cancel_schedule()
        self._loop_once = async.DelayedCall(0, self.loop_once, True)

    def _schedule_actors(self, actor_ids):
        # Update the set of actors that could possibly fire
        self._trigger_set.update(actor_ids)
        # Schedule loop_once if-and-only-if
        #                    it is not already scheduled
        #                    AND
        #                    the set of actors is non-empty
        if self._loop_once is None and self._trigger_set:
            self._cancel_watchdog()
            self._loop_once = async.DelayedCall(0, self.loop_once)

    def schedule_tunnel(self, backoff_time=0):
        # If backoff_time > 0 don't call UNTIL that time has passed.
        # Doesn't work with current scheduler/monitor, so tunnel::communicate has a workaround
        self._cancel_watchdog()
        self._cancel_schedule()
        self._loop_once = async.DelayedCall(backoff_time, self.loop_once, True)

    def _log_exception_during_fire(self, e):
        _log.exception(e)

    def fire_actors(self, actor_ids=None):
        did_fire = False
        actor_ids = set()

        actors = self.actor_mgr.enabled_actors()
        # Shuffle order since now we stop after executing actors for too long
        random.shuffle(actors)

        for actor in actors:
            try:
                _log.debug("Fire actor %s (%s, %s)" % (actor.name, actor._type, actor.id))
                did_fire |= actor.fire()
                actor_ids.add(actor.id)
            except Exception as e:
                self._log_exception_during_fire(e)

            pressure = actor.get_pressure().values()
            pressure_values = [p for _, _, p in pressure]
            if self.actor_pressures.get(actor.id, False) != pressure_values:
                self.actor_pressures[actor.id] = pressure_values

        return (did_fire, False, actor_ids)

    def maintenance_loop(self):
        # Migrate denied actors
        for actor in self.actor_mgr.migratable_actors():
            self.actor_mgr.migrate(actor.id, actor.migration_info["node_id"],
                                   callback=CalvinCB(actor.remove_migration_info))
        # Enable denied actors again if access is permitted. Will try to migrate if access still denied.
        for actor in self.actor_mgr.denied_actors():
            actor.enable_or_migrate()
        # TODO: try to migrate shadow actors as well.
        self._maintenance_loop = None
        self.trigger_maintenance_loop(delay=True)

    def trigger_maintenance_loop(self, delay=False):
        # Never have more then one maintenance loop.
        if self._maintenance_loop is not None:
            self._maintenance_loop.cancel()
        if delay:
            self._maintenance_loop = async.DelayedCall(self._maintenance_delay, self.maintenance_loop)
        else:
            self._maintenance_loop = async.DelayedCall(0, self.maintenance_loop)

class DebugScheduler(Scheduler):
    """This is an instrumented version of the scheduler for use in debugging runs."""

    def __init__(self, node, actor_mgr, monitor):
        super(DebugScheduler, self).__init__(node, actor_mgr, monitor)

    def trigger_loop(self, actor_ids=None):
        #import inspect
        #import traceback
        super(DebugScheduler, self).trigger_loop(actor_ids=actor_ids)
        #(frame, filename, line_no, fname, lines, index) = inspect.getouterframes(inspect.currentframe())[1]
        #_log.debug("triggered %s by %s in file %s at %s" % (time.time(), fname, filename, line_no))
        #_log.debug("Trigger happend here:\n" + ''.join(traceback.format_stack()[-6:-1]))
        _log.analyze(self.node.id, "+ Triggered", None, tb=True)

    def schedule_tunnel(self, backoff_time=0):
        super(DebugScheduler, self).schedule_tunnel(backoff_time=backoff_time)

    def _log_exception_during_fire(self, e):
        from infi.traceback import format_exception
        _log.error('\n'.join(format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)))

    def fire_actors(self, actor_ids=None):
        from infi.traceback import traceback_context
        traceback_context()
        return super(DebugScheduler, self).fire_actors(actor_ids)
<|endoftext|>


<commit_before>import json
from fabric.operations import local
from fabric.colors import red, green
import yaml
from deployerplugin import DeployerPlugin
from fabric.context_managers import hide, warn_only, lcd
from fabric.tasks import execute
from calyptos.chefmanager import ChefManager
import os
from calyptos.rolebuilder import RoleBuilder

class Chef(DeployerPlugin):
    def __init__(self, password, environment_file='etc/environment.yml',
                 config_file='config.yml', debug=False, branch='euca-4.1',
                 cookbook_repo='https://github.com/eucalyptus/eucalyptus-cookbook'):
        self.chef_repo_dir = 'chef-repo'
        self.environment_file = environment_file
        if debug:
            self.hidden_outputs = []
        else:
            self.hidden_outputs = ['running', 'stdout', 'stderr']
        self.role_builder = RoleBuilder(environment_file)
        self.roles = self.role_builder.get_roles()
        self.all_hosts = self.roles['all']
        self._prepare_fs(cookbook_repo, branch, debug)
        self.environment_name = self._write_json_environment()
        self.chef_manager = ChefManager(password, self.environment_name,
                                        self.roles['all'])
        self.config = self.get_chef_config(config_file)

    def _prepare_fs(self, cookbook_repo, branch, debug):
        ChefManager.install_chef_dk()
        ChefManager.create_chef_repo()
        with hide(*self.hidden_outputs):
            local('if [ ! -d eucalyptus-cookbook ]; then '
                  'git clone '
                  '{0} eucalyptus-cookbook;'
                  'fi'.format(cookbook_repo))
            local('cd eucalyptus-cookbook; git checkout {0};'.format(branch))
            local('cd eucalyptus-cookbook; git pull origin {0};'.format(branch))
        ChefManager.download_cookbooks('eucalyptus-cookbook/Berksfile',
                                       os.path.join(self.chef_repo_dir +
                                                    '/cookbooks'),
                                       debug=debug)

    @staticmethod
    def get_chef_config(config_file):
        full_config = yaml.load(open(config_file).read())
        if 'deployer' in full_config:
            if 'chef' in full_config['deployer']:
                return full_config['deployer']['chef']
            else:
                raise IndexError('Unable to find chef config in deployer section of config file')
        else:
            raise IndexError('Unable to find deployer section of config file')

    def _get_recipe_list(self, component):
        for recipe_dict in self.config['roles']:
            if component in recipe_dict:
                return recipe_dict[component]
        raise ValueError('No component found for: ' + component)

    def _write_json_environment(self):
        environment_dict = yaml.load(open(self.environment_file).read())
        current_environment = environment_dict['name']
        environment_dir = self.chef_repo_dir + '/environments/'
        filename = environment_dir + current_environment + '.json'
        with open(filename, 'w') as env_json:
            env_json.write(json.dumps(environment_dict, indent=4,
                                      sort_keys=True, separators=(',', ': ')))
        return current_environment

    def _get_environment(self):
        with open(self.chef_repo_dir + '/environments/' +
                  self.environment_name + '.json') as env_file:
            return json.loads(env_file.read())

    def _run_chef_on_hosts(self, hosts):
        with hide(*self.hidden_outputs):
            execute(self.chef_manager.push_deployment_data, hosts=hosts)
        with warn_only():
            results = execute(self.chef_manager.run_chef_client, hosts=hosts)
        failed = False
        for machine, result in results.iteritems():
            if result.succeeded:
                print green('Success on host: ' + machine)
            if result.failed:
                failed = True
                fail_log_name = 'calyptos-failure-' + machine + '.log'
                print red('Chef Client failed on ' + machine + ' log available at ' +  fail_log_name)
                with open(fail_log_name, 'w') as file:
                    file.write(result.stdout)
        if failed:
            exit(1)
        execute(self.chef_manager.pull_node_info, hosts=hosts)
        return results

    def prepare(self):
        self.chef_manager.sync_ssh_key(self.all_hosts)
        self.chef_manager.clear_run_list(self.all_hosts)
        order = [self.chef_manager.push_deployment_data,
                 self.chef_manager.bootstrap_chef,
                 self.chef_manager.run_chef_client,
                 self.chef_manager.pull_node_info]
        for method in order:
            with hide(*self.hidden_outputs):
                execute(method, hosts=self.all_hosts)
        print green('Prepare has completed successfully. Continue on to the bootstrap phase')

    def bootstrap(self):
        # Install CLC and Initialize DB
        if self.roles['mon-bootstrap']:
            mon_bootstrap = self.roles['mon-bootstrap']
            self.chef_manager.clear_run_list(self.all_hosts)
            self.chef_manager.add_to_run_list(mon_bootstrap, self._get_recipe_list('mon-bootstrap'))
            self._run_chef_on_hosts(mon_bootstrap)

        if self.roles['riak-head']:
            riak_head = self.roles['riak-head']
            self.chef_manager.clear_run_list(self.all_hosts)
            self.chef_manager.add_to_run_list(riak_head, self._get_recipe_list('riak-head'))
            self._run_chef_on_hosts(riak_head)

        if self.roles['midolman']:
            midolman_hosts = self.roles['midolman']
            self.chef_manager.add_to_run_list(midolman_hosts, ['midokura::midolman'])
            self._run_chef_on_hosts(midolman_hosts)

        if self.roles['clc']:
            self.chef_manager.clear_run_list(self.all_hosts)
            clc = self.roles['clc']
            self.chef_manager.add_to_run_list(clc, self._get_recipe_list('clc'))
            self._run_chef_on_hosts(clc)
        print green('Bootstrap has completed successfully. Continue on to the provision phase')

    def _pre_provision_check(self):
        clc_attributes = self.chef_manager.get_node_json(self.roles['clc'].pop())
        clc_euca_attributes = clc_attributes['normal']['eucalyptus']
        if 'cloud-keys' in clc_euca_attributes:
            keys = ['cloud-cert.pem', 'cloud-pk.pem', 'euca.p12']
            for key in keys:
                if key not in clc_euca_attributes['cloud-keys']:
                    print red('Unable to find cloud keys {0} in CLC attributes'.format(clc_euca_attributes[key]))
                    print red('Re-run the bootstrap step and ensure that it is successful')
                    exit(1)
        else:
            print red('Unable to find cloud keys in CLC attributes')
            print red('Re-run the bootstrap step and ensure that it is successful')
            exit(1)

    def provision(self):
        self._pre_provision_check()
        # Install all other components and configure CLC
        self.chef_manager.clear_run_list(self.all_hosts)
        for role_dict in self.config['roles']:
            component_name = role_dict.keys().pop()
            self.chef_manager.add_to_run_list(self.roles[component_name],
                                              self._get_recipe_list(component_name))
        self._run_chef_on_hosts(self.all_hosts)

        if self.roles['riak-head']:
            riak_head = self.roles['riak-head']
            self.chef_manager.add_to_run_list(riak_head, ['riakcs-cluster::plancommit', 'riakcs-cluster::mergecreds'])
            self._run_chef_on_hosts(riak_head)

        if self.roles['clc']:
            clc = self.roles['clc']
            self.chef_manager.add_to_run_list(clc, ['eucalyptus::configure'])
            self._run_chef_on_hosts(clc)
            if self.role_builder.get_euca_attributes()['network']['mode'] == 'VPCMIDO':
                midonet_api = self.roles['midonet-api']
                create_resources = 'midokura::create-first-resources'
                self.chef_manager.add_to_run_list(midonet_api, [create_resources])
                self._run_chef_on_hosts(midonet_api)
        print green('Provision has completed successfully. Your cloud is now configured and ready to use.')

    def uninstall(self):
        self.chef_manager.clear_run_list(self.all_hosts)
        if self.roles['clc']:
            self.chef_manager.add_to_run_list(self.all_hosts, ['eucalyptus::nuke'])
        if self.roles['riak-head']:
            self.chef_manager.add_to_run_list(self.all_hosts, ['riakcs-cluster::nuke'])
        if self.roles['mon-bootstrap']:
            self.chef_manager.add_to_run_list(self.all_hosts, ['ceph-cluster::nuke'])
        if self.roles['haproxy']:
            self.chef_manager.add_to_run_list(self.all_hosts, ['haproxy::nuke'])
        self._run_chef_on_hosts(self.all_hosts)
        with lcd('chef-repo'):
            local('knife node bulk delete -z -E {0} -y ".*"'.format(self.environment_name))
        print green('Uninstall has completed successfully. Your cloud is now torn down.')
<commit_msg>Don't pop CLC from roles<commit_after>import json
from fabric.operations import local
from fabric.colors import red, green
import yaml
from deployerplugin import DeployerPlugin
from fabric.context_managers import hide, warn_only, lcd
from fabric.tasks import execute
from calyptos.chefmanager import ChefManager
import os
from calyptos.rolebuilder import RoleBuilder

class Chef(DeployerPlugin):
    def __init__(self, password, environment_file='etc/environment.yml',
                 config_file='config.yml', debug=False, branch='euca-4.1',
                 cookbook_repo='https://github.com/eucalyptus/eucalyptus-cookbook'):
        self.chef_repo_dir = 'chef-repo'
        self.environment_file = environment_file
        if debug:
            self.hidden_outputs = []
        else:
            self.hidden_outputs = ['running', 'stdout', 'stderr']
        self.role_builder = RoleBuilder(environment_file)
        self.roles = self.role_builder.get_roles()
        self.all_hosts = self.roles['all']
        self._prepare_fs(cookbook_repo, branch, debug)
        self.environment_name = self._write_json_environment()
        self.chef_manager = ChefManager(password, self.environment_name,
                                        self.roles['all'])
        self.config = self.get_chef_config(config_file)

    def _prepare_fs(self, cookbook_repo, branch, debug):
        ChefManager.install_chef_dk()
        ChefManager.create_chef_repo()
        with hide(*self.hidden_outputs):
            local('if [ ! -d eucalyptus-cookbook ]; then '
                  'git clone '
                  '{0} eucalyptus-cookbook;'
                  'fi'.format(cookbook_repo))
            local('cd eucalyptus-cookbook; git checkout {0};'.format(branch))
            local('cd eucalyptus-cookbook; git pull origin {0};'.format(branch))
        ChefManager.download_cookbooks('eucalyptus-cookbook/Berksfile',
                                       os.path.join(self.chef_repo_dir +
                                                    '/cookbooks'),
                                       debug=debug)

    @staticmethod
    def get_chef_config(config_file):
        full_config = yaml.load(open(config_file).read())
        if 'deployer' in full_config:
            if 'chef' in full_config['deployer']:
                return full_config['deployer']['chef']
            else:
                raise IndexError('Unable to find chef config in deployer section of config file')
        else:
            raise IndexError('Unable to find deployer section of config file')

    def _get_recipe_list(self, component):
        for recipe_dict in self.config['roles']:
            if component in recipe_dict:
                return recipe_dict[component]
        raise ValueError('No component found for: ' + component)

    def _write_json_environment(self):
        environment_dict = yaml.load(open(self.environment_file).read())
        current_environment = environment_dict['name']
        environment_dir = self.chef_repo_dir + '/environments/'
        filename = environment_dir + current_environment + '.json'
        with open(filename, 'w') as env_json:
            env_json.write(json.dumps(environment_dict, indent=4,
                                      sort_keys=True, separators=(',', ': ')))
        return current_environment

    def _get_environment(self):
        with open(self.chef_repo_dir + '/environments/' +
                  self.environment_name + '.json') as env_file:
            return json.loads(env_file.read())

    def _run_chef_on_hosts(self, hosts):
        with hide(*self.hidden_outputs):
            execute(self.chef_manager.push_deployment_data, hosts=hosts)
        with warn_only():
            results = execute(self.chef_manager.run_chef_client, hosts=hosts)
        failed = False
        for machine, result in results.iteritems():
            if result.succeeded:
                print green('Success on host: ' + machine)
            if result.failed:
                failed = True
                fail_log_name = 'calyptos-failure-' + machine + '.log'
                print red('Chef Client failed on ' + machine + ' log available at ' +  fail_log_name)
                with open(fail_log_name, 'w') as file:
                    file.write(result.stdout)
        if failed:
            exit(1)
        execute(self.chef_manager.pull_node_info, hosts=hosts)
        return results

    def prepare(self):
        self.chef_manager.sync_ssh_key(self.all_hosts)
        self.chef_manager.clear_run_list(self.all_hosts)
        order = [self.chef_manager.push_deployment_data,
                 self.chef_manager.bootstrap_chef,
                 self.chef_manager.run_chef_client,
                 self.chef_manager.pull_node_info]
        for method in order:
            with hide(*self.hidden_outputs):
                execute(method, hosts=self.all_hosts)
        print green('Prepare has completed successfully. Continue on to the bootstrap phase')

    def bootstrap(self):
        # Install CLC and Initialize DB
        if self.roles['mon-bootstrap']:
            mon_bootstrap = self.roles['mon-bootstrap']
            self.chef_manager.clear_run_list(self.all_hosts)
            self.chef_manager.add_to_run_list(mon_bootstrap, self._get_recipe_list('mon-bootstrap'))
            self._run_chef_on_hosts(mon_bootstrap)

        if self.roles['riak-head']:
            riak_head = self.roles['riak-head']
            self.chef_manager.clear_run_list(self.all_hosts)
            self.chef_manager.add_to_run_list(riak_head, self._get_recipe_list('riak-head'))
            self._run_chef_on_hosts(riak_head)

        if self.roles['midolman']:
            midolman_hosts = self.roles['midolman']
            self.chef_manager.add_to_run_list(midolman_hosts, ['midokura::midolman'])
            self._run_chef_on_hosts(midolman_hosts)

        if self.roles['clc']:
            self.chef_manager.clear_run_list(self.all_hosts)
            clc = self.roles['clc']
            self.chef_manager.add_to_run_list(clc, self._get_recipe_list('clc'))
            self._run_chef_on_hosts(clc)
        print green('Bootstrap has completed successfully. Continue on to the provision phase')

    def _pre_provision_check(self):
        clc_attributes = self.chef_manager.get_node_json(self.roles['clc'][0])
        clc_euca_attributes = clc_attributes['normal']['eucalyptus']
        if 'cloud-keys' in clc_euca_attributes:
            keys = ['cloud-cert.pem', 'cloud-pk.pem', 'euca.p12']
            for key in keys:
                if key not in clc_euca_attributes['cloud-keys']:
                    print red('Unable to find cloud keys {0} in CLC attributes'.format(clc_euca_attributes[key]))
                    print red('Re-run the bootstrap step and ensure that it is successful')
                    exit(1)
        else:
            print red('Unable to find cloud keys in CLC attributes')
            print red('Re-run the bootstrap step and ensure that it is successful')
            exit(1)

    def provision(self):
        self._pre_provision_check()
        # Install all other components and configure CLC
        self.chef_manager.clear_run_list(self.all_hosts)
        for role_dict in self.config['roles']:
            component_name = role_dict.keys().pop()
            self.chef_manager.add_to_run_list(self.roles[component_name],
                                              self._get_recipe_list(component_name))
        self._run_chef_on_hosts(self.all_hosts)

        if self.roles['riak-head']:
            riak_head = self.roles['riak-head']
            self.chef_manager.add_to_run_list(riak_head, ['riakcs-cluster::plancommit', 'riakcs-cluster::mergecreds'])
            self._run_chef_on_hosts(riak_head)

        if self.roles['clc']:
            clc = self.roles['clc']
            self.chef_manager.add_to_run_list(clc, ['eucalyptus::configure'])
            self._run_chef_on_hosts(clc)
            if self.role_builder.get_euca_attributes()['network']['mode'] == 'VPCMIDO':
                midonet_api = self.roles['midonet-api']
                create_resources = 'midokura::create-first-resources'
                self.chef_manager.add_to_run_list(midonet_api, [create_resources])
                self._run_chef_on_hosts(midonet_api)
        print green('Provision has completed successfully. Your cloud is now configured and ready to use.')

    def uninstall(self):
        self.chef_manager.clear_run_list(self.all_hosts)
        if self.roles['clc']:
            self.chef_manager.add_to_run_list(self.all_hosts, ['eucalyptus::nuke'])
        if self.roles['riak-head']:
            self.chef_manager.add_to_run_list(self.all_hosts, ['riakcs-cluster::nuke'])
        if self.roles['mon-bootstrap']:
            self.chef_manager.add_to_run_list(self.all_hosts, ['ceph-cluster::nuke'])
        if self.roles['haproxy']:
            self.chef_manager.add_to_run_list(self.all_hosts, ['haproxy::nuke'])
        self._run_chef_on_hosts(self.all_hosts)
        with lcd('chef-repo'):
            local('knife node bulk delete -z -E {0} -y ".*"'.format(self.environment_name))
        print green('Uninstall has completed successfully. Your cloud is now torn down.')
<|endoftext|>


<commit_before>from metakernel import MetaKernel
from IPython.display import HTML, Javascript
import sys
import re

class SkulptPythonKernel(MetaKernel):
    implementation = 'Skulpt Python'
    implementation_version = '1.0'
    language = 'python'
    language_version = '0.1'
    language_info = {
        'mimetype': 'text/x-python',
        'name': 'python',
        'codemirror_mode': {
            "version": 2,
            "name": "text/x-python"
        },
        # 'pygments_lexer': 'language',
        # 'version'       : "x.y.z",
        'file_extension': '.py',
    }
    banner = "Skulpt Python kernel - evaluates Python programs in the browser"
    canvas_id = 0
    keywords = []

    def get_usage(self):
        return "This is a Skulpt Python kernel"

    def do_execute_direct(self, code):
        """%%processing - run contents of cell as a Skulpt Python script"""
        if code.strip() == "":
            return
        self.canvas_id += 1

        env = {"code": repr(code)[1:] if sys.version.startswith('2') else repr(code),
               "id": self.canvas_id}
        code = """

      Canvas #%(id)s:

      <canvas id='canvas_%(id)s'></canvas>

""" % env
        html = HTML(code)
        self.Display(html)

    def get_completions(self, info):
        token = info["full_obj"]
        self.last_info = info
        return [command for command in self.keywords if command.startswith(token)]

    def get_kernel_help_on(self, info, level=0, none_on_fail=False):
        expr = info["full_obj"]
        self.last_info = info
        url = None
        if expr in self.keywords:
            return "Help on " + expr
        elif none_on_fail:
            return None
        else:
            return "Sorry, no available help for '%s'" % expr

if __name__ == '__main__':
    from IPython.kernel.zmq.kernelapp import IPKernelApp
    IPKernelApp.launch_instance(kernel_class=SkulptPythonKernel)
<commit_msg>Attempting to use Skulpt master; updates to new start up<commit_after>from metakernel import MetaKernel
from IPython.display import HTML, Javascript
import sys
import re

class SkulptPythonKernel(MetaKernel):
    implementation = 'Skulpt Python'
    implementation_version = '1.0'
    language = 'python'
    language_version = '0.1'
    language_info = {
        'mimetype': 'text/x-python',
        'name': 'python',
        'codemirror_mode': {
            "version": 2,
            "name": "text/x-python"
        },
        # 'pygments_lexer': 'language',
        # 'version'       : "x.y.z",
        'file_extension': '.py',
    }
    banner = "Skulpt Python kernel - evaluates Python programs in the browser"
    canvas_id = 0
    keywords = []

    def get_usage(self):
        return "This is a Skulpt Python kernel"

    def do_execute_direct(self, code):
        """%%processing - run contents of cell as a Skulpt Python script"""
        if code.strip() == "":
            return
        self.canvas_id += 1

        env = {"code": repr(code)[1:] if sys.version.startswith('2') else repr(code),
               "id": self.canvas_id}
        code = """

      Canvas #%(id)s:

      <canvas id='canvas_%(id)s'></canvas>

""" % env
        html = HTML(code)
        self.Display(html)

    def get_completions(self, info):
        token = info["full_obj"]
        self.last_info = info
        return [command for command in self.keywords if command.startswith(token)]

    def get_kernel_help_on(self, info, level=0, none_on_fail=False):
        expr = info["full_obj"]
        self.last_info = info
        url = None
        if expr in self.keywords:
            return "Help on " + expr
        elif none_on_fail:
            return None
        else:
            return "Sorry, no available help for '%s'" % expr

if __name__ == '__main__':
    from IPython.kernel.zmq.kernelapp import IPKernelApp
    IPKernelApp.launch_instance(kernel_class=SkulptPythonKernel)
<|endoftext|>