slapgrid.py 5.36 KB
Newer Older
Łukasz Nowak's avatar
Łukasz Nowak committed
1
from slapos.grid import slapgrid
Łukasz Nowak's avatar
Łukasz Nowak committed
2 3
import httplib
import logging
Łukasz Nowak's avatar
Łukasz Nowak committed
4 5
import os
import shutil
6
import signal
7
import slapos.slap.slap
Łukasz Nowak's avatar
Łukasz Nowak committed
8
import socket
9 10
import tempfile
import unittest
Łukasz Nowak's avatar
Łukasz Nowak committed
11
import urlparse
12
import xml_marshaller
Łukasz Nowak's avatar
Łukasz Nowak committed
13

Łukasz Nowak's avatar
Łukasz Nowak committed
14
class BasicMixin:
15 16 17
  def assertSortedListEqual(self, list1, list2, msg=None):
    self.assertListEqual(sorted(list1), sorted(list2), msg)

Łukasz Nowak's avatar
Łukasz Nowak committed
18 19 20 21
  def setUp(self):
    self._tempdir = tempfile.mkdtemp()
    self.software_root = os.path.join(self._tempdir, 'software')
    self.instance_root = os.path.join(self._tempdir, 'instance')
22 23
    if getattr(self, 'master_url', None) is None:
      self.master_url = 'http://127.0.0.1:0/'
Łukasz Nowak's avatar
Łukasz Nowak committed
24 25 26 27 28 29
    self.computer_id = 'computer'
    self.supervisord_socket = os.path.join(self._tempdir, 'supervisord.sock')
    self.supervisord_configuration_path = os.path.join(self._tempdir,
      'supervisord')
    self.usage_report_periodicity = 1
    self.buildout = None
Łukasz Nowak's avatar
Łukasz Nowak committed
30
    logging.basicConfig(level=logging.DEBUG)
Łukasz Nowak's avatar
Łukasz Nowak committed
31 32 33 34 35 36
    self.grid = slapgrid.Slapgrid(self.software_root, self.instance_root,
      self.master_url, self.computer_id, self.supervisord_socket,
      self.supervisord_configuration_path, self.usage_report_periodicity,
      self.buildout)

  def tearDown(self):
37
    shutil.rmtree(self._tempdir, True)
Łukasz Nowak's avatar
Łukasz Nowak committed
38

39
class TestBasicSlapgridCP(BasicMixin, unittest.TestCase):
Łukasz Nowak's avatar
Łukasz Nowak committed
40 41 42 43 44 45 46 47 48 49 50
  def test_no_software_root(self):
    self.assertRaises(OSError, self.grid.processComputerPartitionList)

  def test_no_instance_root(self):
    os.mkdir(self.software_root)
    self.assertRaises(OSError, self.grid.processComputerPartitionList)

  def test_no_master(self):
    os.mkdir(self.software_root)
    os.mkdir(self.instance_root)
    self.assertRaises(socket.error, self.grid.processComputerPartitionList)
51 52

class MasterMixin(BasicMixin):
53

54
  def _patchHttplib(self):
55
    """Overrides httplib"""
56 57 58 59 60 61 62
    import mock.httplib

    self.saved_httplib = dict()

    for fake in vars(mock.httplib):
      self.saved_httplib[fake] = getattr(httplib, fake, None)
      setattr(httplib, fake, getattr(mock.httplib, fake))
63

64
  def _unpatchHttplib(self):
65
    """Restores httplib overriding"""
66 67 68 69
    import httplib
    for name, original_value in self.saved_httplib.items():
      setattr(httplib, name, original_value)
    del self.saved_httplib
70 71

  def setUp(self):
72
    self._patchHttplib()
73
    BasicMixin.setUp(self)
74 75

  def tearDown(self):
76
    self._unpatchHttplib()
77 78 79 80 81 82 83 84 85
    # XXX: Hardcoded pid, as it is not configurable in slapos
    svc = os.path.join(self.instance_root, 'var', 'run', 'supervisord.pid')
    if os.path.exists(svc):
      try:
        pid = int(open(svc).read().strip())
      except ValueError:
        pass
      else:
        os.kill(pid, signal.SIGTERM)
86 87 88
    BasicMixin.tearDown(self)

class TestSlapgridCPWithMaster(MasterMixin, unittest.TestCase):
89

90
  def test_nothing_to_do(self):
91 92

    def server_response(self, path, method, body, header):
93
      parsed_url = urlparse.urlparse(path.lstrip('/'))
94
      parsed_qs = urlparse.parse_qs(parsed_url.query)
95
      if parsed_url.path == 'getComputerInformation' and \
96 97 98 99 100 101 102 103 104
         'computer_id' in parsed_qs:
        slap_computer = slapos.slap.Computer(parsed_qs['computer_id'])
        slap_computer._software_release_list = []
        slap_computer._computer_partition_list = []
        return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer))
      else:
        return (404, {}, '')

    httplib.HTTPConnection._callback = server_response
105 106
    os.mkdir(self.software_root)
    os.mkdir(self.instance_root)
107
    self.assertTrue(self.grid.processComputerPartitionList())
108 109
    self.assertSortedListEqual(os.listdir(self.instance_root), ['etc', 'var'])
    self.assertSortedListEqual(os.listdir(self.software_root), [])
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

  def test_one_partition(self):

    def server_response(self, path, method, body, header):
      parsed_url = urlparse.urlparse('/' + path)
      parsed_qs = urlparse.parse_qs(parsed_url.query)
      if parsed_url.path == '/getComputerInformation' and \
         'computer_id' in parsed_qs:
        slap_computer = slapos.slap.Computer(parsed_qs['computer_id'])
        slap_computer._software_release_list = []
        partition = slapos.slap.ComputerPartition(parsed_qs['computer_id'],
            '0')
        partition._need_modification = True
        sr = slapos.slap.SoftwareRelease()
        sr._software_release = 'http://sr/'
        partition._software_release_document = sr
        partition._requested_state = 'stopped'
        slap_computer._computer_partition_list = [partition]
        return (200, {}, xml_marshaller.xml_marshaller.dumps(slap_computer))
      else:
        return (404, {}, '')

    httplib.HTTPConnection._callback = server_response
    os.mkdir(self.software_root)
    os.mkdir(self.instance_root)
    partition_path = os.path.join(self.instance_root, '0')
    os.mkdir(partition_path, 0750)
137 138
    software_hash = slapos.grid.utils.getSoftwareUrlHash('http://sr/')
    srdir = os.path.join(self.software_root, software_hash)
139 140 141 142 143 144 145 146 147
    os.mkdir(srdir)
    open(os.path.join(srdir, 'template.cfg'), 'w').write(
      """[buildout]""")
    srbindir = os.path.join(srdir, 'bin')
    os.mkdir(srbindir)
    open(os.path.join(srbindir, 'buildout'), 'w').write("""#!/bin/sh
touch worked""")
    os.chmod(os.path.join(srbindir, 'buildout'), 0755)
    self.assertTrue(self.grid.processComputerPartitionList())
148 149 150 151
    self.assertSortedListEqual(os.listdir(self.instance_root), ['0', 'etc',
      'var'])
    self.assertSortedListEqual(os.listdir(self.software_root),
      [software_hash])