Commit 4d8fccfa authored by Cédric de Saint Martin's avatar Cédric de Saint Martin Committed by Rafael Monnerat

proxy: add multi-nodes support.

parent 82f2b511
--version:10 --version:11
CREATE TABLE IF NOT EXISTS software%(version)s (url VARCHAR(255) UNIQUE); CREATE TABLE IF NOT EXISTS software%(version)s (
url VARCHAR(255),
computer_reference VARCHAR(255) DEFAULT 'computer',
CONSTRAINT uniq PRIMARY KEY (url, computer_reference)
);
CREATE TABLE IF NOT EXISTS computer%(version)s ( CREATE TABLE IF NOT EXISTS computer%(version)s (
reference VARCHAR(255),
address VARCHAR(255), address VARCHAR(255),
netmask VARCHAR(255), netmask VARCHAR(255),
CONSTRAINT uniq PRIMARY KEY (address, netmask)); CONSTRAINT uniq PRIMARY KEY (reference)
);
CREATE TABLE IF NOT EXISTS partition%(version)s ( CREATE TABLE IF NOT EXISTS partition%(version)s (
reference VARCHAR(255) UNIQUE, reference VARCHAR(255),
computer_reference VARCHAR(255) DEFAULT 'computer',
slap_state VARCHAR(255) DEFAULT 'free', slap_state VARCHAR(255) DEFAULT 'free',
software_release VARCHAR(255), software_release VARCHAR(255),
xml TEXT, xml TEXT,
...@@ -16,11 +24,13 @@ CREATE TABLE IF NOT EXISTS partition%(version)s ( ...@@ -16,11 +24,13 @@ CREATE TABLE IF NOT EXISTS partition%(version)s (
partition_reference VARCHAR(255), partition_reference VARCHAR(255),
requested_by VARCHAR(255), -- only used for debugging, requested_by VARCHAR(255), -- only used for debugging,
-- slapproxy does not support proper scope -- slapproxy does not support proper scope
requested_state VARCHAR(255) NOT NULL DEFAULT 'started' requested_state VARCHAR(255) NOT NULL DEFAULT 'started',
CONSTRAINT uniq PRIMARY KEY (reference, computer_reference)
); );
CREATE TABLE IF NOT EXISTS slave%(version)s ( CREATE TABLE IF NOT EXISTS slave%(version)s (
reference VARCHAR(255) UNIQUE, reference VARCHAR(255),
computer_reference VARCHAR(255),
connection_xml TEXT, connection_xml TEXT,
hosted_by VARCHAR(255), hosted_by VARCHAR(255),
asked_by VARCHAR(255) -- only used for debugging, asked_by VARCHAR(255) -- only used for debugging,
...@@ -29,6 +39,7 @@ CREATE TABLE IF NOT EXISTS slave%(version)s ( ...@@ -29,6 +39,7 @@ CREATE TABLE IF NOT EXISTS slave%(version)s (
CREATE TABLE IF NOT EXISTS partition_network%(version)s ( CREATE TABLE IF NOT EXISTS partition_network%(version)s (
partition_reference VARCHAR(255), partition_reference VARCHAR(255),
computer_reference VARCHAR(255),
reference VARCHAR(255), reference VARCHAR(255),
address VARCHAR(255), address VARCHAR(255),
netmask VARCHAR(255) netmask VARCHAR(255)
......
...@@ -76,12 +76,12 @@ def partitiondict2partition(partition): ...@@ -76,12 +76,12 @@ def partitiondict2partition(partition):
for key, value in partition.iteritems(): for key, value in partition.iteritems():
if type(value) is unicode: if type(value) is unicode:
partition[key] = value.encode() partition[key] = value.encode()
slap_partition = ComputerPartition(app.config['computer_id'], slap_partition = ComputerPartition(partition['computer_reference'],
partition['reference']) partition['reference'])
slap_partition._software_release_document = None slap_partition._software_release_document = None
slap_partition._requested_state = 'destroyed' slap_partition._requested_state = 'destroyed'
slap_partition._need_modification = 0 slap_partition._need_modification = 0
slap_partition._instance_guid = partition['reference'] slap_partition._instance_guid = '%s-%s' % (partition['computer_reference'], partition['reference'])
if partition['software_release']: if partition['software_release']:
slap_partition._need_modification = 1 slap_partition._need_modification = 1
...@@ -89,8 +89,8 @@ def partitiondict2partition(partition): ...@@ -89,8 +89,8 @@ def partitiondict2partition(partition):
slap_partition._parameter_dict = xml2dict(partition['xml']) slap_partition._parameter_dict = xml2dict(partition['xml'])
address_list = [] address_list = []
for address in execute_db('partition_network', for address in execute_db('partition_network',
'SELECT * FROM %s WHERE partition_reference=?', 'SELECT * FROM %s WHERE partition_reference=? AND computer_reference=?',
[partition['reference']]): [partition['reference'], partition['computer_reference']]):
address_list.append((address['reference'], address['address'])) address_list.append((address['reference'], address['address']))
slap_partition._parameter_dict['ip_list'] = address_list slap_partition._parameter_dict['ip_list'] = address_list
slap_partition._parameter_dict['slap_software_type'] = \ slap_partition._parameter_dict['slap_software_type'] = \
...@@ -103,7 +103,7 @@ def partitiondict2partition(partition): ...@@ -103,7 +103,7 @@ def partitiondict2partition(partition):
slap_partition._connection_dict = xml2dict(partition['connection_xml']) slap_partition._connection_dict = xml2dict(partition['connection_xml'])
slap_partition._software_release_document = SoftwareRelease( slap_partition._software_release_document = SoftwareRelease(
software_release=partition['software_release'], software_release=partition['software_release'],
computer_guid=app.config['computer_id']) computer_guid=partition['computer_reference'])
return slap_partition return slap_partition
...@@ -146,37 +146,39 @@ def getComputerInformation(): ...@@ -146,37 +146,39 @@ def getComputerInformation():
@app.route('/getFullComputerInformation', methods=['GET']) @app.route('/getFullComputerInformation', methods=['GET'])
def getFullComputerInformation(): def getFullComputerInformation():
computer_id = request.args['computer_id'] computer_id = request.args['computer_id']
if app.config['computer_id'] == computer_id: computer_list = execute_db('computer', 'SELECT * FROM %s WHERE reference=?', [computer_id])
if len(computer_list) != 1:
# Backward compatibility
if computer_id != app.config['computer_id']:
raise NotFoundError('%s is not registered.' % computer_id)
slap_computer = Computer(computer_id) slap_computer = Computer(computer_id)
slap_computer._software_release_list = [] slap_computer._software_release_list = []
for sr in execute_db('software', 'select * from %s'): for sr in execute_db('software', 'select * from %s WHERE computer_reference=?', [computer_id]):
slap_computer._software_release_list.append(SoftwareRelease( slap_computer._software_release_list.append(SoftwareRelease(
software_release=sr['url'], computer_guid=computer_id)) software_release=sr['url'], computer_guid=computer_id))
slap_computer._computer_partition_list = [] slap_computer._computer_partition_list = []
for partition in execute_db('partition', 'SELECT * FROM %s'): for partition in execute_db('partition', 'SELECT * FROM %s WHERE computer_reference=?', [computer_id]):
slap_computer._computer_partition_list.append(partitiondict2partition( slap_computer._computer_partition_list.append(partitiondict2partition(
partition)) partition))
return xml_marshaller.xml_marshaller.dumps(slap_computer) return xml_marshaller.xml_marshaller.dumps(slap_computer)
else:
raise NotFoundError('Only accept request for: %s' % app.config['computer_id'])
@app.route('/setComputerPartitionConnectionXml', methods=['POST']) @app.route('/setComputerPartitionConnectionXml', methods=['POST'])
def setComputerPartitionConnectionXml(): def setComputerPartitionConnectionXml():
slave_reference = request.form['slave_reference'].encode() slave_reference = request.form['slave_reference'].encode()
computer_partition_id = request.form['computer_partition_id'] computer_partition_id = request.form['computer_partition_id'].encode()
connection_xml = request.form['connection_xml'] computer_id = request.form['computer_id'].encode()
connection_xml = request.form['connection_xml'].encode()
connection_dict = xml_marshaller.xml_marshaller.loads( connection_dict = xml_marshaller.xml_marshaller.loads(
connection_xml.encode()) connection_xml)
connection_xml = dict2xml(connection_dict) connection_xml = dict2xml(connection_dict)
if slave_reference == 'None': if slave_reference == 'None':
query = 'UPDATE %s SET connection_xml=? WHERE reference=?' query = 'UPDATE %s SET connection_xml=? WHERE reference=? AND computer_reference=?'
argument_list = [connection_xml, computer_partition_id.encode()] argument_list = [connection_xml, computer_partition_id, computer_id]
execute_db('partition', query, argument_list) execute_db('partition', query, argument_list)
return 'done' return 'done'
else: else:
query = 'UPDATE %s SET connection_xml=? , hosted_by=? WHERE reference=?' query = 'UPDATE %s SET connection_xml=? , hosted_by=? WHERE reference=?'
argument_list = [connection_xml, computer_partition_id.encode(), argument_list = [connection_xml, computer_partition_id, slave_reference]
slave_reference]
execute_db('slave', query, argument_list) execute_db('slave', query, argument_list)
return 'done' return 'done'
...@@ -228,47 +230,40 @@ def useComputer(): ...@@ -228,47 +230,40 @@ def useComputer():
def loadComputerConfigurationFromXML(): def loadComputerConfigurationFromXML():
xml = request.form['xml'] xml = request.form['xml']
computer_dict = xml_marshaller.xml_marshaller.loads(str(xml)) computer_dict = xml_marshaller.xml_marshaller.loads(str(xml))
if app.config['computer_id'] == computer_dict['reference']: execute_db('computer', 'INSERT OR REPLACE INTO %s values(:reference, :address, :netmask)',
execute_db('computer', 'INSERT OR REPLACE INTO %s values(:address, :netmask)',
computer_dict) computer_dict)
for partition in computer_dict['partition_list']: for partition in computer_dict['partition_list']:
partition['computer_reference'] = computer_dict['reference']
execute_db('partition', 'INSERT OR IGNORE INTO %s (reference) values(:reference)', partition) execute_db('partition', 'INSERT OR IGNORE INTO %s (reference, computer_reference) values(:reference, :computer_reference)', partition)
execute_db('partition_network', 'DELETE FROM %s WHERE partition_reference = ?', [partition['reference']]) execute_db('partition_network', 'DELETE FROM %s WHERE partition_reference = ? AND computer_reference = ?',
[partition['reference'], partition['computer_reference']])
for address in partition['address_list']: for address in partition['address_list']:
address['reference'] = partition['tap']['name'] address['reference'] = partition['tap']['name']
address['partition_reference'] = partition['reference'] address['partition_reference'] = partition['reference']
execute_db('partition_network', 'INSERT OR REPLACE INTO %s (reference, partition_reference, address, netmask) values(:reference, :partition_reference, :addr, :netmask)', address) execute_db('partition_network', 'INSERT OR REPLACE INTO %s (reference, partition_reference, computer_reference, address, netmask) values(:reference, :partition_reference, :computer_reference, :addr, :netmask)', address)
return 'done' return 'done'
else:
raise UnauthorizedError('Only accept request for: %s' % app.config['computer_id'])
@app.route('/registerComputerPartition', methods=['GET']) @app.route('/registerComputerPartition', methods=['GET'])
def registerComputerPartition(): def registerComputerPartition():
computer_reference = request.args['computer_reference'] computer_reference = request.args['computer_reference'].encode()
computer_partition_reference = request.args['computer_partition_reference'] computer_partition_reference = request.args['computer_partition_reference'].encode()
if app.config['computer_id'] == computer_reference: partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=? and computer_reference=?',
partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=?', [computer_partition_reference, computer_reference], one=True)
[computer_partition_reference.encode()], one=True)
if partition is None: if partition is None:
raise UnauthorizedError raise UnauthorizedError
return xml_marshaller.xml_marshaller.dumps( return xml_marshaller.xml_marshaller.dumps(
partitiondict2partition(partition)) partitiondict2partition(partition))
else:
raise UnauthorizedError('Only accept request for: %s' % app.config['computer_id'])
@app.route('/supplySupply', methods=['POST']) @app.route('/supplySupply', methods=['POST'])
def supplySupply(): def supplySupply():
url = request.form['url'] url = request.form['url']
computer_id = request.form['computer_id'] computer_id = request.form['computer_id']
if app.config['computer_id'] == computer_id:
if request.form['state'] == 'destroyed': if request.form['state'] == 'destroyed':
execute_db('software', 'DELETE FROM %s WHERE url = ?', [url]) execute_db('software', 'DELETE FROM %s WHERE url = ? AND computer_reference=?',
else: [url, computer_id])
execute_db('software', 'INSERT OR REPLACE INTO %s VALUES(?)', [url])
else: else:
raise UnauthorizedError('Only accept request for: %s' % app.config['computer_id']) execute_db('software', 'INSERT OR REPLACE INTO %s VALUES(?, ?)', [url, computer_id])
return '%r added' % url return '%r added' % url
...@@ -286,21 +281,22 @@ def requestComputerPartition(): ...@@ -286,21 +281,22 @@ def requestComputerPartition():
def softwareInstanceRename(): def softwareInstanceRename():
new_name = request.form['new_name'].encode() new_name = request.form['new_name'].encode()
computer_partition_id = request.form['computer_partition_id'].encode() computer_partition_id = request.form['computer_partition_id'].encode()
computer_id = request.form['computer_id'].encode()
q = 'UPDATE %s SET partition_reference = ? WHERE reference = ?' q = 'UPDATE %s SET partition_reference = ? WHERE reference = ? AND computer_reference = ?'
execute_db('partition', q, [new_name, computer_partition_id]) execute_db('partition', q, [new_name, computer_partition_id, computer_id])
return 'done' return 'done'
@app.route('/getComputerPartitionStatus', methods=['GET']) @app.route('/getComputerPartitionStatus', methods=['GET'])
def getComputerPartitionStatus(): def getComputerPartitionStatus():
# XXX: not implemented return xml_marshaller.xml_marshaller.dumps('Not implemented.')
return xml_marshaller.xml_marshaller.dumps('')
def request_not_shared(): def request_not_shared():
software_release = request.form['software_release'].encode() software_release = request.form['software_release'].encode()
# some supported parameters # some supported parameters
software_type = request.form.get('software_type').encode() software_type = request.form.get('software_type').encode()
partition_reference = request.form.get('partition_reference', '').encode() partition_reference = request.form.get('partition_reference', '').encode()
filter_kw = request.form.get('filter_xml', None)
partition_id = request.form.get('computer_partition_id', '').encode() partition_id = request.form.get('computer_partition_id', '').encode()
partition_parameter_kw = request.form.get('partition_parameter_xml', None) partition_parameter_kw = request.form.get('partition_parameter_xml', None)
requested_state = xml_marshaller.xml_marshaller.loads(request.form.get('state').encode()) requested_state = xml_marshaller.xml_marshaller.loads(request.form.get('state').encode())
...@@ -309,6 +305,11 @@ def request_not_shared(): ...@@ -309,6 +305,11 @@ def request_not_shared():
partition_parameter_kw.encode()) partition_parameter_kw.encode())
else: else:
partition_parameter_kw = {} partition_parameter_kw = {}
if filter_kw:
filter_kw = xml_marshaller.xml_marshaller.loads(filter_kw.encode())
requested_computer_id = filter_kw.get('computer_guid', app.config['computer_id'])
else:
requested_computer_id = app.config['computer_id']
instance_xml = dict2xml(partition_parameter_kw) instance_xml = dict2xml(partition_parameter_kw)
args = [] args = []
...@@ -327,9 +328,12 @@ def request_not_shared(): ...@@ -327,9 +328,12 @@ def request_not_shared():
a(requested_state) a(requested_state)
# If partition doesn't exist: create it and insert parameters # If partition doesn't exist: create it and insert parameters
# XXX add support for automatic deployment on specific node depending on available SR and partitions on each Node.
# Note: only deploy on default node if SLA not specified
if partition is None: if partition is None:
partition = execute_db('partition', partition = execute_db('partition',
'SELECT * FROM %s WHERE slap_state="free"', (), one=True) 'SELECT * FROM %s WHERE slap_state="free" and computer_reference=?',
[requested_computer_id], one=True)
if partition is None: if partition is None:
app.logger.warning('No more free computer partition') app.logger.warning('No more free computer partition')
abort(404) abort(404)
...@@ -355,12 +359,14 @@ def request_not_shared(): ...@@ -355,12 +359,14 @@ def request_not_shared():
if instance_xml: if instance_xml:
q += ' ,xml=?' q += ' ,xml=?'
a(instance_xml) a(instance_xml)
q += ' WHERE reference=?' q += ' WHERE reference=? AND computer_reference=?'
a(partition['reference'].encode()) a(partition['reference'].encode())
a(partition['computer_reference'].encode())
execute_db('partition', q, args) execute_db('partition', q, args)
args = [] args = []
partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=?', partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=? and computer_reference=?',
[partition['reference'].encode()], one=True) [partition['reference'].encode(), partition['computer_reference'].encode()], one=True)
address_list = [] address_list = []
for address in execute_db('partition_network', 'SELECT * FROM %s WHERE partition_reference=?', [partition['reference']]): for address in execute_db('partition_network', 'SELECT * FROM %s WHERE partition_reference=?', [partition['reference']]):
address_list.append((address['reference'], address['address'])) address_list.append((address['reference'], address['address']))
...@@ -371,15 +377,14 @@ def request_not_shared(): ...@@ -371,15 +377,14 @@ def request_not_shared():
software_instance = SoftwareInstance(_connection_dict=xml2dict(partition['connection_xml']), software_instance = SoftwareInstance(_connection_dict=xml2dict(partition['connection_xml']),
_parameter_dict=xml2dict(partition['xml']), _parameter_dict=xml2dict(partition['xml']),
connection_xml=partition['connection_xml'], connection_xml=partition['connection_xml'],
slap_computer_id=app.config['computer_id'], slap_computer_id=partition['computer_reference'].encode(),
slap_computer_partition_id=partition['reference'], slap_computer_partition_id=partition['reference'],
slap_software_release_url=partition['software_release'], slap_software_release_url=partition['software_release'],
slap_server_url='slap_server_url', slap_server_url='slap_server_url',
slap_software_type=partition['software_type'], slap_software_type=partition['software_type'],
_instance_guid=partition['reference'], _instance_guid='%s-%s' % (partition['computer_reference'].encode(), partition['reference']),
_requested_state=requested_state, _requested_state=requested_state,
ip_list=address_list) ip_list=address_list)
return xml_marshaller.xml_marshaller.dumps(software_instance) return xml_marshaller.xml_marshaller.dumps(software_instance)
...@@ -407,14 +412,20 @@ def request_slave(): ...@@ -407,14 +412,20 @@ def request_slave():
else: else:
partition_parameter_kw = {} partition_parameter_kw = {}
filter_kw = xml_marshaller.xml_marshaller.loads(request.form.get('filter_xml').encode()) filter_kw = request.form.get('filter_xml', None)
if filter_kw:
filter_kw = xml_marshaller.xml_marshaller.loads(filter_kw.encode())
requested_computer_id = filter_kw.get('computer_guid', app.config['computer_id'])
else:
requested_computer_id = app.config['computer_id']
instance_xml = dict2xml(partition_parameter_kw) instance_xml = dict2xml(partition_parameter_kw)
# We will search for a master corresponding to request # We will search for a master corresponding to request
args = [] args = []
a = args.append a = args.append
q = 'SELECT * FROM %s WHERE software_release=?' q = 'SELECT * FROM %s WHERE software_release=? and computer_reference=?'
a(software_release) a(software_release)
a(requested_computer_id)
if software_type: if software_type:
q += ' AND software_type=?' q += ' AND software_type=?'
a(software_type) a(software_type)
...@@ -455,33 +466,34 @@ def request_slave(): ...@@ -455,33 +466,34 @@ def request_slave():
a = args.append a = args.append
q = 'UPDATE %s SET slave_instance_list=?' q = 'UPDATE %s SET slave_instance_list=?'
a(xml_marshaller.xml_marshaller.dumps(slave_instance_list)) a(xml_marshaller.xml_marshaller.dumps(slave_instance_list))
q += ' WHERE reference=?' q += ' WHERE reference=? and computer_reference=?'
a(partition['reference'].encode()) a(partition['reference'].encode())
a(requested_computer_id)
execute_db('partition', q, args) execute_db('partition', q, args)
args = [] args = []
partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=?', partition = execute_db('partition', 'SELECT * FROM %s WHERE reference=? and computer_reference=?',
[partition['reference'].encode()], one=True) [partition['reference'].encode(), requested_computer_id], one=True)
# Add slave to slave table if not there # Add slave to slave table if not there
slave = execute_db('slave', 'SELECT * FROM %s WHERE reference=?', slave = execute_db('slave', 'SELECT * FROM %s WHERE reference=? and computer_reference=?',
[slave_reference], one=True) [slave_reference, requested_computer_id], one=True)
if slave is None: if slave is None:
execute_db('slave', execute_db('slave',
'INSERT OR IGNORE INTO %s (reference,asked_by,hosted_by) values(:reference,:asked_by,:hosted_by)', 'INSERT OR IGNORE INTO %s (reference,computer_reference,asked_by,hosted_by) values(:reference,:computer_reference,:asked_by,:hosted_by)',
[slave_reference, partition_id, partition['reference']]) [slave_reference, requested_computer_id, partition_id, partition['reference']])
slave = execute_db('slave', 'SELECT * FROM %s WHERE reference=?', slave = execute_db('slave', 'SELECT * FROM %s WHERE reference=? and computer_reference=?',
[slave_reference], one=True) [slave_reference, requested_computer_id], one=True)
address_list = [] address_list = []
for address in execute_db('partition_network', for address in execute_db('partition_network',
'SELECT * FROM %s WHERE partition_reference=?', 'SELECT * FROM %s WHERE partition_reference=? and computer_reference=?',
[partition['reference']]): [partition['reference'], partition['computer_reference']]):
address_list.append((address['reference'], address['address'])) address_list.append((address['reference'], address['address']))
# XXX it should be ComputerPartition, not a SoftwareInstance # XXX it should be ComputerPartition, not a SoftwareInstance
software_instance = SoftwareInstance(_connection_dict=xml2dict(slave['connection_xml']), software_instance = SoftwareInstance(_connection_dict=xml2dict(slave['connection_xml']),
_parameter_dict=xml2dict(instance_xml), _parameter_dict=xml2dict(instance_xml),
slap_computer_id=app.config['computer_id'], slap_computer_id=partition['computer_reference'],
slap_computer_partition_id=slave['hosted_by'], slap_computer_partition_id=slave['hosted_by'],
slap_software_release_url=partition['software_release'], slap_software_release_url=partition['software_release'],
slap_server_url='slap_server_url', slap_server_url='slap_server_url',
...@@ -505,5 +517,6 @@ def getSoftwareReleaseListFromSoftwareProduct(): ...@@ -505,5 +517,6 @@ def getSoftwareReleaseListFromSoftwareProduct():
software_release_url_list =\ software_release_url_list =\
[app.config['software_product_list'][software_product_reference]] [app.config['software_product_list'][software_product_reference]]
else: else:
software_release_url_list =[] software_release_url_list = []
return xml_marshaller.xml_marshaller.dumps(software_release_url_list) return xml_marshaller.xml_marshaller.dumps(software_release_url_list)
...@@ -34,6 +34,7 @@ import shutil ...@@ -34,6 +34,7 @@ import shutil
import tempfile import tempfile
import unittest import unittest
import xml_marshaller import xml_marshaller
from xml_marshaller.xml_marshaller import loads, dumps
import slapos.proxy import slapos.proxy
import slapos.proxy.views as views import slapos.proxy.views as views
...@@ -104,13 +105,15 @@ database_uri = %(tempdir)s/lib/proxy.db ...@@ -104,13 +105,15 @@ database_uri = %(tempdir)s/lib/proxy.db
self.app_config = views.app.config self.app_config = views.app.config
self.app = views.app.test_client() self.app = views.app.test_client()
def add_free_partition(self, partition_amount): def add_free_partition(self, partition_amount, computer_id=None):
""" """
Will simulate a slapformat first run Will simulate a slapformat first run
and create "partition_amount" partitions and create "partition_amount" partitions
""" """
if not computer_id:
computer_id = self.computer_id
computer_dict = { computer_dict = {
'reference': self.computer_id, 'reference': computer_id,
'address': '123.456.789', 'address': '123.456.789',
'netmask': 'fffffffff', 'netmask': 'fffffffff',
'partition_list': [], 'partition_list': [],
...@@ -243,18 +246,16 @@ class TestInformation(BasicMixin, unittest.TestCase): ...@@ -243,18 +246,16 @@ class TestInformation(BasicMixin, unittest.TestCase):
) )
class MasterMixin(BasicMixin): class MasterMixin(BasicMixin, unittest.TestCase):
""" """
Define advanced tool for test proxy simulating behavior slap library tools Define advanced tool for test proxy simulating behavior slap library tools
""" """
def _requestComputerPartition(self, software_release, software_type, partition_reference,
def request(self, software_release, software_type, partition_reference,
partition_id, partition_id,
shared=False, partition_parameter_kw=None, filter_kw=None, shared=False, partition_parameter_kw=None, filter_kw=None,
state=None): state=None):
""" """
Simulate a request with above parameters Check parameters, call requestComputerPartition server method and return result
Return response by server (a computer partition or an error)
""" """
if partition_parameter_kw is None: if partition_parameter_kw is None:
partition_parameter_kw = {} partition_parameter_kw = {}
...@@ -276,13 +277,17 @@ class MasterMixin(BasicMixin): ...@@ -276,13 +277,17 @@ class MasterMixin(BasicMixin):
'filter_xml': xml_marshaller.xml_marshaller.dumps(filter_kw), 'filter_xml': xml_marshaller.xml_marshaller.dumps(filter_kw),
'state': xml_marshaller.xml_marshaller.dumps(state), 'state': xml_marshaller.xml_marshaller.dumps(state),
} }
rv = self.app.post('/requestComputerPartition', return self.app.post('/requestComputerPartition', data=request_dict)
data=request_dict)
def request(self, *args, **kwargs):
"""
Simulate a request with above parameters
Return response by server (a computer partition or an error)
"""
rv = self._requestComputerPartition(*args, **kwargs)
self.assertEqual(rv._status_code, 200)
xml = rv.data xml = rv.data
try:
software_instance = xml_marshaller.xml_marshaller.loads(xml) software_instance = xml_marshaller.xml_marshaller.loads(xml)
except:
raise WrongFormat("Could not be parsed by xml_marshaller")
computer_partition = slapos.slap.ComputerPartition( computer_partition = slapos.slap.ComputerPartition(
software_instance.slap_computer_id, software_instance.slap_computer_id,
...@@ -291,6 +296,14 @@ class MasterMixin(BasicMixin): ...@@ -291,6 +296,14 @@ class MasterMixin(BasicMixin):
computer_partition.__dict__.update(software_instance.__dict__) computer_partition.__dict__.update(software_instance.__dict__)
return computer_partition return computer_partition
def supply(self, url, computer_id=None, state=''):
if not computer_id:
computer_id = self.computer_id
request_dict = {'url':url, 'computer_id': computer_id, 'state':state}
rv = self.app.post('/supplySupply',
data=request_dict)
# XXX return a Software Release
def setConnectionDict(self, partition_id, def setConnectionDict(self, partition_id,
connection_dict, slave_reference=None): connection_dict, slave_reference=None):
self.app.post('/setComputerPartitionConnectionXml', data={ self.app.post('/setComputerPartitionConnectionXml', data={
...@@ -310,7 +323,7 @@ class MasterMixin(BasicMixin): ...@@ -310,7 +323,7 @@ class MasterMixin(BasicMixin):
return instance return instance
class TestRequest(MasterMixin, unittest.TestCase): class TestRequest(MasterMixin):
""" """
Set of tests for requests Set of tests for requests
""" """
...@@ -320,9 +333,9 @@ class TestRequest(MasterMixin, unittest.TestCase): ...@@ -320,9 +333,9 @@ class TestRequest(MasterMixin, unittest.TestCase):
Check that all different parameters related to requests (like instance_guid, state) are set and consistent Check that all different parameters related to requests (like instance_guid, state) are set and consistent
""" """
self.add_free_partition(1) self.add_free_partition(1)
partition = self.request('http://sr//', None, 'Maria', 'slappart0') partition = self.request('http://sr//', None, 'MyFirstInstance', 'slappart0')
self.assertEqual(partition.getState(), 'started') self.assertEqual(partition.getState(), 'started')
self.assertEqual(partition.getInstanceGuid(), 'slappart0') # XXX define me self.assertEqual(partition.getInstanceGuid(), 'computer-slappart0')
def test_two_request_one_partition_free(self): def test_two_request_one_partition_free(self):
""" """
...@@ -331,10 +344,10 @@ class TestRequest(MasterMixin, unittest.TestCase): ...@@ -331,10 +344,10 @@ class TestRequest(MasterMixin, unittest.TestCase):
""" """
self.add_free_partition(1) self.add_free_partition(1)
self.assertIsInstance(self.request('http://sr//', None, self.assertIsInstance(self.request('http://sr//', None,
'Maria', 'slappart2'), 'MyFirstInstance', 'slappart2'),
slapos.slap.ComputerPartition) slapos.slap.ComputerPartition)
self.assertIsInstance(self.request('http://sr//', None, self.assertIsInstance(self.request('http://sr//', None,
'Maria', 'slappart3'), 'MyFirstInstance', 'slappart3'),
slapos.slap.ComputerPartition) slapos.slap.ComputerPartition)
def test_two_request_two_partition_free(self): def test_two_request_two_partition_free(self):
...@@ -344,10 +357,10 @@ class TestRequest(MasterMixin, unittest.TestCase): ...@@ -344,10 +357,10 @@ class TestRequest(MasterMixin, unittest.TestCase):
""" """
self.add_free_partition(2) self.add_free_partition(2)
self.assertIsInstance(self.request('http://sr//', None, self.assertIsInstance(self.request('http://sr//', None,
'Maria', 'slappart2'), 'MyFirstInstance', 'slappart2'),
slapos.slap.ComputerPartition) slapos.slap.ComputerPartition)
self.assertIsInstance(self.request('http://sr//', None, self.assertIsInstance(self.request('http://sr//', None,
'Maria', 'slappart3'), 'MyFirstInstance', 'slappart3'),
slapos.slap.ComputerPartition) slapos.slap.ComputerPartition)
def test_two_same_request_from_one_partition(self): def test_two_same_request_from_one_partition(self):
...@@ -356,8 +369,8 @@ class TestRequest(MasterMixin, unittest.TestCase): ...@@ -356,8 +369,8 @@ class TestRequest(MasterMixin, unittest.TestCase):
""" """
self.add_free_partition(2) self.add_free_partition(2)
self.assertEqual( self.assertEqual(
self.request('http://sr//', None, 'Maria', 'slappart2').__dict__, self.request('http://sr//', None, 'MyFirstInstance', 'slappart2').__dict__,
self.request('http://sr//', None, 'Maria', 'slappart2').__dict__) self.request('http://sr//', None, 'MyFirstInstance', 'slappart2').__dict__)
def test_two_requests_with_different_parameters_but_same_reference(self): def test_two_requests_with_different_parameters_but_same_reference(self):
""" """
...@@ -368,12 +381,12 @@ class TestRequest(MasterMixin, unittest.TestCase): ...@@ -368,12 +381,12 @@ class TestRequest(MasterMixin, unittest.TestCase):
wanted_domain1 = 'fou.org' wanted_domain1 = 'fou.org'
wanted_domain2 = 'carzy.org' wanted_domain2 = 'carzy.org'
request1 = self.request('http://sr//', None, 'Maria', 'slappart2', request1 = self.request('http://sr//', None, 'MyFirstInstance', 'slappart2',
partition_parameter_kw={'domain': wanted_domain1}) partition_parameter_kw={'domain': wanted_domain1})
request1_dict = request1.__dict__ request1_dict = request1.__dict__
requested_result1 = self.getPartitionInformation( requested_result1 = self.getPartitionInformation(
request1_dict['_partition_id']) request1_dict['_partition_id'])
request2 = self.request('http://sr1//', 'Papa', 'Maria', 'slappart2', request2 = self.request('http://sr1//', 'Papa', 'MyFirstInstance', 'slappart2',
partition_parameter_kw={'domain': wanted_domain2}) partition_parameter_kw={'domain': wanted_domain2})
request2_dict = request2.__dict__ request2_dict = request2.__dict__
requested_result2 = self.getPartitionInformation( requested_result2 = self.getPartitionInformation(
...@@ -403,8 +416,8 @@ class TestRequest(MasterMixin, unittest.TestCase): ...@@ -403,8 +416,8 @@ class TestRequest(MasterMixin, unittest.TestCase):
""" """
self.add_free_partition(2) self.add_free_partition(2)
self.assertEqual( self.assertEqual(
self.request('http://sr//', None, 'Maria', 'slappart2').__dict__, self.request('http://sr//', None, 'MyFirstInstance', 'slappart2').__dict__,
self.request('http://sr//', None, 'Maria', 'slappart3').__dict__) self.request('http://sr//', None, 'MyFirstInstance', 'slappart3').__dict__)
def test_two_different_request_from_one_partition(self): def test_two_different_request_from_one_partition(self):
""" """
...@@ -413,11 +426,11 @@ class TestRequest(MasterMixin, unittest.TestCase): ...@@ -413,11 +426,11 @@ class TestRequest(MasterMixin, unittest.TestCase):
""" """
self.add_free_partition(2) self.add_free_partition(2)
self.assertNotEqual( self.assertNotEqual(
self.request('http://sr//', None, 'Maria', 'slappart2').__dict__, self.request('http://sr//', None, 'MyFirstInstance', 'slappart2').__dict__,
self.request('http://sr//', None, 'frontend', 'slappart2').__dict__) self.request('http://sr//', None, 'frontend', 'slappart2').__dict__)
class TestSlaveRequest(TestRequest): class TestSlaveRequest(MasterMixin):
""" """
Test requests related to slave instances. Test requests related to slave instances.
""" """
...@@ -426,8 +439,8 @@ class TestSlaveRequest(TestRequest): ...@@ -426,8 +439,8 @@ class TestSlaveRequest(TestRequest):
Slave instance request will fail if no corresponding are found Slave instance request will fail if no corresponding are found
""" """
self.add_free_partition(2) self.add_free_partition(2)
with self.assertRaises(WrongFormat): rv = self._requestComputerPartition('http://sr//', None, 'MyFirstInstance', 'slappart2', shared=True)
self.request('http://sr//', None, 'Maria', 'slappart2', shared=True) self.assertEqual(rv._status_code, 404)
def test_slave_request_set_parameters(self): def test_slave_request_set_parameters(self):
""" """
...@@ -440,10 +453,10 @@ class TestSlaveRequest(TestRequest): ...@@ -440,10 +453,10 @@ class TestSlaveRequest(TestRequest):
self.add_free_partition(6) self.add_free_partition(6)
# Provide partition # Provide partition
master_partition_id = self.request('http://sr//', None, master_partition_id = self.request('http://sr//', None,
'Maria', 'slappart4')._partition_id 'MyFirstInstance', 'slappart4')._partition_id
# First request of slave instance # First request of slave instance
wanted_domain = 'fou.org' wanted_domain = 'fou.org'
self.request('http://sr//', None, 'Maria', 'slappart2', shared=True, self.request('http://sr//', None, 'MyFirstInstance', 'slappart2', shared=True,
partition_parameter_kw={'domain': wanted_domain}) partition_parameter_kw={'domain': wanted_domain})
# Get updated information for master partition # Get updated information for master partition
master_partition = self.getPartitionInformation(master_partition_id) master_partition = self.getPartitionInformation(master_partition_id)
...@@ -476,10 +489,10 @@ class TestSlaveRequest(TestRequest): ...@@ -476,10 +489,10 @@ class TestSlaveRequest(TestRequest):
self.add_free_partition(6) self.add_free_partition(6)
# Provide partition # Provide partition
master_partition_id = self.request('http://sr//', None, master_partition_id = self.request('http://sr//', None,
'Maria', 'slappart4')._partition_id 'MyFirstInstance', 'slappart4')._partition_id
# First request of slave instance # First request of slave instance
wanted_domain_1 = 'crazy.org' wanted_domain_1 = 'crazy.org'
self.request('http://sr//', None, 'Maria', 'slappart2', shared=True, self.request('http://sr//', None, 'MyFirstInstance', 'slappart2', shared=True,
partition_parameter_kw={'domain': wanted_domain_1}) partition_parameter_kw={'domain': wanted_domain_1})
# Get updated information for master partition # Get updated information for master partition
master_partition = self.getPartitionInformation(master_partition_id) master_partition = self.getPartitionInformation(master_partition_id)
...@@ -488,7 +501,7 @@ class TestSlaveRequest(TestRequest): ...@@ -488,7 +501,7 @@ class TestSlaveRequest(TestRequest):
# Second request of slave instance # Second request of slave instance
wanted_domain_2 = 'maluco.org' wanted_domain_2 = 'maluco.org'
self.request('http://sr//', None, 'Maria', 'slappart2', shared=True, self.request('http://sr//', None, 'MyFirstInstance', 'slappart2', shared=True,
partition_parameter_kw={'domain': wanted_domain_2}) partition_parameter_kw={'domain': wanted_domain_2})
# Get updated information for master partition # Get updated information for master partition
master_partition = self.getPartitionInformation(master_partition_id) master_partition = self.getPartitionInformation(master_partition_id)
...@@ -511,6 +524,7 @@ class TestSlaveRequest(TestRequest): ...@@ -511,6 +524,7 @@ class TestSlaveRequest(TestRequest):
self.request('http://sr//', None, 'MySlaveInstance', 'slappart2', shared=True) self.request('http://sr//', None, 'MySlaveInstance', 'slappart2', shared=True)
# Set connection parameter # Set connection parameter
master_partition = self.getPartitionInformation(master_partition_id) master_partition = self.getPartitionInformation(master_partition_id)
# XXX change slave reference to be compatible with multiple nodes
self.setConnectionDict(partition_id=master_partition._partition_id, self.setConnectionDict(partition_id=master_partition._partition_id,
connection_dict={'foo': 'bar'}, connection_dict={'foo': 'bar'},
slave_reference=master_partition._parameter_dict['slave_instance_list'][0]['slave_reference']) slave_reference=master_partition._parameter_dict['slave_instance_list'][0]['slave_reference'])
...@@ -533,9 +547,9 @@ class TestSlaveRequest(TestRequest): ...@@ -533,9 +547,9 @@ class TestSlaveRequest(TestRequest):
self.add_free_partition(6) self.add_free_partition(6)
# Provide partition # Provide partition
master_partition_id = self.request('http://sr//', None, master_partition_id = self.request('http://sr//', None,
'Maria', 'slappart4')._partition_id 'MyFirstInstance', 'slappart4')._partition_id
# First request of slave instance # First request of slave instance
name = 'Maria' name = 'MyFirstInstance'
requester = 'slappart2' requester = 'slappart2'
our_slave = self.request('http://sr//', None, our_slave = self.request('http://sr//', None,
name, requester, shared=True) name, requester, shared=True)
...@@ -555,3 +569,275 @@ class TestSlaveRequest(TestRequest): ...@@ -555,3 +569,275 @@ class TestSlaveRequest(TestRequest):
self.assertIsInstance(our_slave, slapos.slap.ComputerPartition) self.assertIsInstance(our_slave, slapos.slap.ComputerPartition)
self.assertEqual(slave_address, our_slave._connection_dict) self.assertEqual(slave_address, our_slave._connection_dict)
class TestMultiNodeSupport(MasterMixin):
def test_multi_node_support_different_software_release_list(self):
"""
Test that two different registered computers have their own
Software Release list.
"""
self.add_free_partition(6, computer_id='COMP-0')
self.add_free_partition(6, computer_id='COMP-1')
software_release_1_url = 'http://sr1'
software_release_2_url = 'http://sr2'
software_release_3_url = 'http://sr3'
self.supply(software_release_1_url, 'COMP-0')
self.supply(software_release_2_url, 'COMP-1')
self.supply(software_release_3_url, 'COMP-0')
self.supply(software_release_3_url, 'COMP-1')
computer_default = loads(self.app.get('/getFullComputerInformation?computer_id=%s' % self.computer_id).data)
computer_0 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-0').data)
computer_1 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-1').data)
self.assertEqual(len(computer_default._software_release_list), 0)
self.assertEqual(len(computer_0._software_release_list), 2)
self.assertEqual(len(computer_1._software_release_list), 2)
self.assertEqual(
computer_0._software_release_list[0]._software_release,
software_release_1_url
)
self.assertEqual(
computer_0._software_release_list[0]._computer_guid,
'COMP-0'
)
self.assertEqual(
computer_0._software_release_list[1]._software_release,
software_release_3_url
)
self.assertEqual(
computer_0._software_release_list[1]._computer_guid,
'COMP-0'
)
self.assertEqual(
computer_1._software_release_list[0]._software_release,
software_release_2_url
)
self.assertEqual(
computer_1._software_release_list[0]._computer_guid,
'COMP-1'
)
self.assertEqual(
computer_1._software_release_list[1]._software_release,
software_release_3_url
)
self.assertEqual(
computer_1._software_release_list[1]._computer_guid,
'COMP-1'
)
def test_multi_node_support_remove_software_release(self):
"""
Test that removing a software from a Computer doesn't
affect other computer
"""
software_release_url = 'http://sr'
self.add_free_partition(6, computer_id='COMP-0')
self.add_free_partition(6, computer_id='COMP-1')
self.supply(software_release_url, 'COMP-0')
self.supply(software_release_url, 'COMP-1')
self.supply(software_release_url, 'COMP-0', state='destroyed')
computer_0 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-0').data)
computer_1 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-1').data)
self.assertEqual(len(computer_0._software_release_list), 0)
self.assertEqual(len(computer_1._software_release_list), 1)
self.assertEqual(
computer_1._software_release_list[0]._software_release,
software_release_url
)
self.assertEqual(
computer_1._software_release_list[0]._computer_guid,
'COMP-1'
)
def test_multi_node_support_instance_default_computer(self):
"""
Test that instance request behaves correctly with default computer
"""
software_release_url = 'http://sr'
computer_0_id = 'COMP-0'
computer_1_id = 'COMP-1'
self.add_free_partition(6, computer_id=computer_0_id)
self.add_free_partition(6, computer_id=computer_1_id)
# Request without SLA -> goes to default computer only.
# It should fail if we didn't registered partitions for default computer
# (default computer is always registered)
rv = self._requestComputerPartition('http://sr//', None, 'MyFirstInstance', 'slappart2')
self.assertEqual(rv._status_code, 404)
rv = self._requestComputerPartition('http://sr//', None, 'MyFirstInstance', 'slappart2',
filter_kw={'computer_guid':self.computer_id})
self.assertEqual(rv._status_code, 404)
# Register default computer: deployment works
self.add_free_partition(1)
self.request('http://sr//', None, 'MyFirstInstance', 'slappart0')
computer_default = loads(self.app.get(
'/getFullComputerInformation?computer_id=%s' % self.computer_id).data)
self.assertEqual(len(computer_default._software_release_list), 0)
# No free space on default computer: request without SLA fails
rv = self._requestComputerPartition('http://sr//', None, 'CanIHasPartition', 'slappart2',
filter_kw={'computer_guid':self.computer_id})
self.assertEqual(rv._status_code, 404)
def test_multi_node_support_instance(self):
"""
Test that instance request behaves correctly with several
registered computers
"""
software_release_url = 'http://sr'
computer_0_id = 'COMP-0'
computer_1_id = 'COMP-1'
software_release_1 = 'http://sr//'
software_release_2 = 'http://othersr//'
self.add_free_partition(2, computer_id=computer_1_id)
# Deploy to first non-default computer using SLA
# It should fail since computer is not registered
rv = self._requestComputerPartition(software_release_1, None, 'MyFirstInstance', 'slappart2', filter_kw={'computer_guid':computer_0_id})
self.assertEqual(rv._status_code, 404)
self.add_free_partition(2, computer_id=computer_0_id)
# Deploy to first non-default computer using SLA
partition = self.request(software_release_1, None, 'MyFirstInstance', 'slappart0', filter_kw={'computer_guid':computer_0_id})
self.assertEqual(partition.getState(), 'started')
self.assertEqual(partition._partition_id, 'slappart0')
self.assertEqual(partition._computer_id, computer_0_id)
# All other instances should be empty
computer_0 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-0').data)
computer_1 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-1').data)
self.assertEqual(computer_0._computer_partition_list[0]._software_release_document._software_release, software_release_1)
self.assertTrue(computer_0._computer_partition_list[1]._software_release_document == None)
self.assertTrue(computer_1._computer_partition_list[0]._software_release_document == None)
self.assertTrue(computer_1._computer_partition_list[1]._software_release_document == None)
# Deploy to second non-default computer using SLA
partition = self.request(software_release_2, None, 'MySecondInstance', 'slappart0', filter_kw={'computer_guid':computer_1_id})
self.assertEqual(partition.getState(), 'started')
self.assertEqual(partition._partition_id, 'slappart0')
self.assertEqual(partition._computer_id, computer_1_id)
# The two remaining instances should be free, and MyfirstInstance should still be there
computer_0 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-0').data)
computer_1 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-1').data)
self.assertEqual(computer_0._computer_partition_list[0]._software_release_document._software_release, software_release_1)
self.assertTrue(computer_0._computer_partition_list[1]._software_release_document == None)
self.assertEqual(computer_1._computer_partition_list[0]._software_release_document._software_release, software_release_2)
self.assertTrue(computer_1._computer_partition_list[1]._software_release_document == None)
def test_multi_node_support_change_instance_state(self):
"""
Test that destroying an instance (i.e change state) from a Computer doesn't
affect other computer
"""
software_release_url = 'http://sr'
computer_0_id = 'COMP-0'
computer_1_id = 'COMP-1'
self.add_free_partition(6, computer_id=computer_0_id)
self.add_free_partition(6, computer_id=computer_1_id)
partition_first = self.request('http://sr//', None, 'MyFirstInstance', 'slappart0', filter_kw={'computer_guid':computer_0_id})
partition_second = self.request('http://sr//', None, 'MySecondInstance', 'slappart0', filter_kw={'computer_guid':computer_1_id})
partition_first = self.request('http://sr//', None, 'MyFirstInstance', 'slappart0', filter_kw={'computer_guid':computer_0_id}, state='stopped')
computer_0 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-0').data)
computer_1 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-1').data)
self.assertEqual(computer_0._computer_partition_list[0].getState(), 'stopped')
self.assertEqual(computer_0._computer_partition_list[1].getState(), 'destroyed')
self.assertEqual(computer_1._computer_partition_list[0].getState(), 'started')
self.assertEqual(computer_1._computer_partition_list[1].getState(), 'destroyed')
def test_multi_node_support_same_reference(self):
"""
Test that requesting an instance with same reference to two
different nodes behaves like master: once an instance is assigned to a node,
changing SLA will not change node.
"""
software_release_url = 'http://sr'
computer_0_id = 'COMP-0'
computer_1_id = 'COMP-1'
self.add_free_partition(2, computer_id=computer_0_id)
self.add_free_partition(2, computer_id=computer_1_id)
partition = self.request('http://sr//', None, 'MyFirstInstance', 'slappart0', filter_kw={'computer_guid':computer_0_id})
partition = self.request('http://sr//', None, 'MyFirstInstance', 'slappart0', filter_kw={'computer_guid':computer_1_id})
self.assertEqual(partition._computer_id, computer_0_id)
computer_1 = loads(self.app.get('/getFullComputerInformation?computer_id=COMP-1').data)
self.assertTrue(computer_1._computer_partition_list[0]._software_release_document == None)
self.assertTrue(computer_1._computer_partition_list[1]._software_release_document == None)
def test_multi_node_support_slave_instance(self):
"""
Test that slave instances are correctly deployed if SLA is specified
but deployed only on default computer if not specified (i.e not deployed
if default computer doesn't have corresponding master instance).
"""
computer_0_id = 'COMP-0'
computer_1_id = 'COMP-1'
self.add_free_partition(2, computer_id=computer_0_id)
self.add_free_partition(2, computer_id=computer_1_id)
self.add_free_partition(2)
self.request('http://sr2//', None, 'MyFirstInstance', 'slappart0', filter_kw={'computer_guid':computer_0_id})
self.request('http://sr//', None, 'MyOtherInstance', 'slappart0', filter_kw={'computer_guid':computer_1_id})
# Request slave without SLA: will fail
rv = self._requestComputerPartition('http://sr//', None, 'MySlaveInstance', 'slappart2', shared=True)
self.assertEqual(rv._status_code, 404)
# Request slave with SLA on incorrect computer: will fail
rv = self._requestComputerPartition('http://sr//', None, 'MySlaveInstance', 'slappart2', shared=True, filter_kw={'computer_guid':computer_0_id})
self.assertEqual(rv._status_code, 404)
# Request computer on correct computer: will succeed
partition = self.request('http://sr//', None, 'MySlaveInstance', 'slappart2', shared=True, filter_kw={'computer_guid':computer_1_id})
self.assertEqual(partition._computer_id, computer_1_id)
def test_multi_node_support_instance_guid(self):
"""
Test that instance_guid support behaves correctly with multiple nodes.
Warning: proxy doesn't gives unique id of instance, but gives instead unique id
of partition.
"""
computer_0_id = 'COMP-0'
computer_1_id = 'COMP-1'
self.add_free_partition(2, computer_id=computer_0_id)
self.add_free_partition(2, computer_id=computer_1_id)
self.add_free_partition(2)
partition_computer_0 = self.request('http://sr2//', None, 'MyFirstInstance', 'slappart0', filter_kw={'computer_guid':computer_0_id})
partition_computer_1 = self.request('http://sr//', None, 'MyOtherInstance', 'slappart0', filter_kw={'computer_guid':computer_1_id})
partition_computer_default = self.request('http://sr//', None, 'MyThirdInstance', 'slappart0')
self.assertEqual(partition_computer_0.getInstanceGuid(), 'COMP-0-slappart0')
self.assertEqual(partition_computer_1.getInstanceGuid(), 'COMP-1-slappart0')
self.assertEqual(partition_computer_default.getInstanceGuid(), 'computer-slappart0')
def test_multi_node_support_getComputerInformation(self):
"""
Test that computer information will not be given if computer is not registered.
Test that it still should work for the 'default' computer specified in slapos config
even if not yet registered.
Test that computer information is given if computer is registered.
"""
new_computer_id = '%s42' % self.computer_id
with self.assertRaises(slapos.slap.NotFoundError):
self.app.get('/getComputerInformation?computer_id=%s42' % new_computer_id)
try:
self.app.get('/getComputerInformation?computer_id=%s' % self.computer_id)
except slapos.slap.NotFoundError:
self.fail('Could not fetch informations for default computer.')
self.add_free_partition(1, computer_id=new_computer_id)
try:
self.app.get('/getComputerInformation?computer_id=%s' % new_computer_id)
except slapos.slap.NotFoundError:
self.fail('Could not fetch informations for registered computer.')
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment