Skip to content

Commit 6332ffe

Browse files
Merge pull request #994 from acamacho82/issues984-985
Fix for #984 #985 - Ability to order multiple GPU cards on a server
2 parents 474e338 + b04a046 commit 6332ffe

File tree

3 files changed

+58
-23
lines changed

3 files changed

+58
-23
lines changed

SoftLayer/managers/ordering.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,11 @@ def get_price_id_list(self, package_keyname, item_keynames):
334334
keynames in the given package
335335
336336
"""
337-
mask = 'id, keyName, prices'
337+
mask = 'id, itemCategory, keyName, prices[categories]'
338338
items = self.list_items(package_keyname, mask=mask)
339339

340340
prices = []
341+
gpu_number = -1
341342
for item_keyname in item_keynames:
342343
try:
343344
# Need to find the item in the package that has a matching
@@ -353,8 +354,17 @@ def get_price_id_list(self, package_keyname, item_keynames):
353354
# because that is the most generic price. verifyOrder/placeOrder
354355
# can take that ID and create the proper price for us in the location
355356
# in which the order is made
356-
price_id = [p['id'] for p in matching_item['prices']
357-
if not p['locationGroupId']][0]
357+
if matching_item['itemCategory']['categoryCode'] != "gpu0":
358+
price_id = [p['id'] for p in matching_item['prices']
359+
if not p['locationGroupId']][0]
360+
else:
361+
# GPU items has two generic prices and they are added to the list
362+
# according to the number of gpu items added in the order.
363+
gpu_number += 1
364+
price_id = [p['id'] for p in matching_item['prices']
365+
if not p['locationGroupId']
366+
and p['categories'][0]['categoryCode'] == "gpu" + str(gpu_number)][0]
367+
358368
prices.append(price_id)
359369

360370
return prices

tests/CLI/modules/order_tests.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,13 @@ def test_location_list(self):
210210

211211
def _get_order_items(self):
212212
item1 = {'keyName': 'ITEM1', 'description': 'description1',
213-
'prices': [{'id': 1111, 'locationGroupId': None}]}
213+
'itemCategory': {'categoryCode': 'cat1'},
214+
'prices': [{'id': 1111, 'locationGroupId': None,
215+
'categories': [{'categoryCode': 'cat1'}]}]}
214216
item2 = {'keyName': 'ITEM2', 'description': 'description2',
215-
'prices': [{'id': 2222, 'locationGroupId': None}]}
217+
'itemCategory': {'categoryCode': 'cat2'},
218+
'prices': [{'id': 2222, 'locationGroupId': None,
219+
'categories': [{'categoryCode': 'cat2'}]}]}
216220

217221
return [item1, item2]
218222

tests/managers/ordering_tests.py

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -283,32 +283,49 @@ def test_get_preset_by_key_preset_not_found(self):
283283
self.assertEqual('Preset {} does not exist in package {}'.format(keyname, 'PACKAGE_KEYNAME'), str(exc))
284284

285285
def test_get_price_id_list(self):
286-
price1 = {'id': 1234, 'locationGroupId': None}
287-
item1 = {'id': 1111, 'keyName': 'ITEM1', 'prices': [price1]}
288-
price2 = {'id': 5678, 'locationGroupId': None}
289-
item2 = {'id': 2222, 'keyName': 'ITEM2', 'prices': [price2]}
286+
category1 = {'categoryCode': 'cat1'}
287+
price1 = {'id': 1234, 'locationGroupId': None, 'itemCategory': [category1]}
288+
item1 = {'id': 1111, 'keyName': 'ITEM1', 'itemCategory': category1, 'prices': [price1]}
289+
category2 = {'categoryCode': 'cat2'}
290+
price2 = {'id': 5678, 'locationGroupId': None, 'categories': [category2]}
291+
item2 = {'id': 2222, 'keyName': 'ITEM2', 'itemCategory': category2, 'prices': [price2]}
290292

291293
with mock.patch.object(self.ordering, 'list_items') as list_mock:
292294
list_mock.return_value = [item1, item2]
293295

294296
prices = self.ordering.get_price_id_list('PACKAGE_KEYNAME', ['ITEM1', 'ITEM2'])
295297

296-
list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, keyName, prices')
298+
list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, itemCategory, keyName, prices[categories]')
297299
self.assertEqual([price1['id'], price2['id']], prices)
298300

299301
def test_get_price_id_list_item_not_found(self):
300-
price1 = {'id': 1234, 'locationGroupId': ''}
301-
item1 = {'id': 1111, 'keyName': 'ITEM1', 'prices': [price1]}
302+
category1 = {'categoryCode': 'cat1'}
303+
price1 = {'id': 1234, 'locationGroupId': '', 'categories': [category1]}
304+
item1 = {'id': 1111, 'keyName': 'ITEM1', 'itemCategory': category1, 'prices': [price1]}
302305

303306
with mock.patch.object(self.ordering, 'list_items') as list_mock:
304307
list_mock.return_value = [item1]
305308

306309
exc = self.assertRaises(exceptions.SoftLayerError,
307310
self.ordering.get_price_id_list,
308311
'PACKAGE_KEYNAME', ['ITEM2'])
309-
list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, keyName, prices')
312+
list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, itemCategory, keyName, prices[categories]')
310313
self.assertEqual("Item ITEM2 does not exist for package PACKAGE_KEYNAME", str(exc))
311314

315+
def test_get_price_id_list_gpu_items_with_two_categories(self):
316+
# Specific for GPU prices which are differentiated by their category (gpu0, gpu1)
317+
price1 = {'id': 1234, 'locationGroupId': None, 'categories': [{'categoryCode': 'gpu1'}]}
318+
price2 = {'id': 5678, 'locationGroupId': None, 'categories': [{'categoryCode': 'gpu0'}]}
319+
item1 = {'id': 1111, 'keyName': 'ITEM1', 'itemCategory': {'categoryCode': 'gpu0'}, 'prices': [price1, price2]}
320+
321+
with mock.patch.object(self.ordering, 'list_items') as list_mock:
322+
list_mock.return_value = [item1, item1]
323+
324+
prices = self.ordering.get_price_id_list('PACKAGE_KEYNAME', ['ITEM1', 'ITEM1'])
325+
326+
list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, itemCategory, keyName, prices[categories]')
327+
self.assertEqual([price2['id'], price1['id']], prices)
328+
312329
def test_generate_no_complex_type(self):
313330
pkg = 'PACKAGE_KEYNAME'
314331
items = ['ITEM1', 'ITEM2']
@@ -460,30 +477,34 @@ def test_get_location_id_int(self):
460477

461478
def test_location_group_id_none(self):
462479
# RestTransport uses None for empty locationGroupId
463-
price1 = {'id': 1234, 'locationGroupId': None}
464-
item1 = {'id': 1111, 'keyName': 'ITEM1', 'prices': [price1]}
465-
price2 = {'id': 5678, 'locationGroupId': None}
466-
item2 = {'id': 2222, 'keyName': 'ITEM2', 'prices': [price2]}
480+
category1 = {'categoryCode': 'cat1'}
481+
price1 = {'id': 1234, 'locationGroupId': None, 'categories': [category1]}
482+
item1 = {'id': 1111, 'keyName': 'ITEM1', 'itemCategory': category1, 'prices': [price1]}
483+
category2 = {'categoryCode': 'cat2'}
484+
price2 = {'id': 5678, 'locationGroupId': None, 'categories': [category2]}
485+
item2 = {'id': 2222, 'keyName': 'ITEM2', 'itemCategory': category2, 'prices': [price2]}
467486

468487
with mock.patch.object(self.ordering, 'list_items') as list_mock:
469488
list_mock.return_value = [item1, item2]
470489

471490
prices = self.ordering.get_price_id_list('PACKAGE_KEYNAME', ['ITEM1', 'ITEM2'])
472491

473-
list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, keyName, prices')
492+
list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, itemCategory, keyName, prices[categories]')
474493
self.assertEqual([price1['id'], price2['id']], prices)
475494

476495
def test_location_groud_id_empty(self):
477496
# XMLRPCtransport uses '' for empty locationGroupId
478-
price1 = {'id': 1234, 'locationGroupId': ''}
479-
item1 = {'id': 1111, 'keyName': 'ITEM1', 'prices': [price1]}
480-
price2 = {'id': 5678, 'locationGroupId': ""}
481-
item2 = {'id': 2222, 'keyName': 'ITEM2', 'prices': [price2]}
497+
category1 = {'categoryCode': 'cat1'}
498+
price1 = {'id': 1234, 'locationGroupId': '', 'categories': [category1]}
499+
item1 = {'id': 1111, 'keyName': 'ITEM1', 'itemCategory': category1, 'prices': [price1]}
500+
category2 = {'categoryCode': 'cat2'}
501+
price2 = {'id': 5678, 'locationGroupId': "", 'categories': [category2]}
502+
item2 = {'id': 2222, 'keyName': 'ITEM2', 'itemCategory': category2, 'prices': [price2]}
482503

483504
with mock.patch.object(self.ordering, 'list_items') as list_mock:
484505
list_mock.return_value = [item1, item2]
485506

486507
prices = self.ordering.get_price_id_list('PACKAGE_KEYNAME', ['ITEM1', 'ITEM2'])
487508

488-
list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, keyName, prices')
509+
list_mock.assert_called_once_with('PACKAGE_KEYNAME', mask='id, itemCategory, keyName, prices[categories]')
489510
self.assertEqual([price1['id'], price2['id']], prices)

0 commit comments

Comments
 (0)