def _transform_graphics_summary(facets): # Augment graphics adapter with data from another service. if 'adapter_vendor_id' in facets: vendor_hexes = [] adapter_hexes = [] for vendor in facets['adapter_vendor_id']: for adapter in vendor['facets']['adapter_device_id']: vendor_hexes.append(vendor['term']) adapter_hexes.append(adapter['term']) devices_api = models.GraphicsDevices() all_names = devices_api.get_pairs(adapter_hexes, vendor_hexes) graphics = [] for vendor in facets['adapter_vendor_id']: for adapter in vendor['facets']['adapter_device_id']: entry = { 'vendor': vendor['term'], 'adapter': adapter['term'], 'count': adapter['count'], } key = (adapter['term'], vendor['term']) names = all_names.get(key) if names and names[0]: entry['adapter'] = '{} ({})'.format( names[0], adapter['term'], ) if names and names[1]: entry['vendor'] = '{} ({})'.format( names[1], vendor['term'], ) graphics.append(entry) # By default, results are sorted by vendor count then adapter count. # We instead need to sort them by adapter count only. That cannot be # done in SuperSearch directly, so we do it here. facets['adapter_vendor_id'] = sorted( graphics, key=lambda x: x['count'], reverse=True )
def test_graphics_devices(self): api = models.GraphicsDevices() def mocked_get(**options): return { 'hits': [ { 'vendor_hex': 'vhex2', 'vendor_name': 'V 2', 'adapter_hex': 'ahex2', 'adapter_name': 'A 2', }, { 'vendor_hex': 'vhex1', 'vendor_name': 'V 1', 'adapter_hex': 'ahex1', 'adapter_name': 'A 1', }, ], 'total': 2 } models.GraphicsDevices.implementation().get.side_effect = ( mocked_get ) r = api.get( vendor_hex=['vhex1', 'vhex2'], adapter_hex=['ahex1', 'ahex2'], ) assert r['total'] == 2 expected = { 'vendor_hex': 'vhex2', 'vendor_name': 'V 2', 'adapter_hex': 'ahex2', 'adapter_name': 'A 2', } assert r['hits'][0] == expected
def test_graphics_devices_get_pairs(self): """The GraphicsDevices.get_pairs() is an abstraction of GraphicsDevices.get() on steroids. The input is similar as GraphicsDevices.get() but instead it returns a dict where each key is a (adapter hex, vendor hex) tuple and each key is (adapter name, vendor name) tuple. Internally it does some smart caching. """ api = models.GraphicsDevices() params_called = [] def mocked_get(**params): params_called.append(params) if 'vhex3' in params['vendor_hex']: return { 'hits': [ { 'vendor_hex': 'vhex3', 'vendor_name': 'V 3', 'adapter_hex': 'ahex3', 'adapter_name': 'A 3', }, ], 'total': 1 } else: return { 'hits': [ { 'vendor_hex': 'vhex2', 'vendor_name': 'V 2', 'adapter_hex': 'ahex2', 'adapter_name': 'A 2', }, { 'vendor_hex': 'vhex1', 'vendor_name': 'V 1', 'adapter_hex': 'ahex1', 'adapter_name': 'A 1', }, ], 'total': 2 } models.GraphicsDevices.implementation().get.side_effect = (mocked_get) r = api.get_pairs( ['ahex1', 'ahex2'], ['vhex1', 'vhex2'], ) eq_( r, { ('ahex1', 'vhex1'): ('A 1', 'V 1'), ('ahex2', 'vhex2'): ('A 2', 'V 2'), }) r = api.get_pairs( ['ahex2', 'ahex3'], ['vhex2', 'vhex3'], ) assert len(r) == 2 eq_( r, { ('ahex2', 'vhex2'): ('A 2', 'V 2'), ('ahex3', 'vhex3'): ('A 3', 'V 3'), }) # In the second call to `api.get_pairs()` we repeated the # (ahex2, vhex2) combo, so that second time, we could benefit from # caching and only need to query for the (ahex3, vhex3) combo. assert len(params_called) == 2 eq_( params_called[0], { 'adapter_hex': set(['ahex1', 'ahex2']), 'vendor_hex': set(['vhex2', 'vhex1']), }) eq_(params_called[1], { 'adapter_hex': set(['ahex3']), 'vendor_hex': set(['vhex3']), })
def _transform_graphics_summary(facets): # Augment graphics adapter with data from another service. if 'adapter_vendor_id' in facets: vendor_hexes = [] adapter_hexes = [] for vendor in facets['adapter_vendor_id']: for adapter in vendor['facets']['adapter_device_id']: vendor_hexes.append(vendor['term']) adapter_hexes.append(adapter['term']) devices_api = models.GraphicsDevices() devices_results = { 'hits': [], 'total': 0, } # In order to avoid hitting the maximum URL size limit, we split the # query in smaller chunks, and then we reconstruct the results. max_number_of_hexes = 50 for i in range(0, len(vendor_hexes), max_number_of_hexes): vendors = set(vendor_hexes[i:i + max_number_of_hexes]) adapters = set(adapter_hexes[i:i + max_number_of_hexes]) res = devices_api.get( vendor_hex=vendors, adapter_hex=adapters, ) devices_results['hits'].extend(res['hits']) devices_results['total'] += res['total'] hexes = {} for hit in devices_results['hits']: key = '{}:{}'.format(hit['vendor_hex'], hit['adapter_hex']) hexes[key] = (hit['vendor_name'], hit['adapter_name']) graphics = [] for vendor in facets['adapter_vendor_id']: for adapter in vendor['facets']['adapter_device_id']: entry = { 'vendor': vendor['term'], 'adapter': adapter['term'], 'count': adapter['count'], } key = '{}:{}'.format(vendor['term'], adapter['term']) names = hexes.get(key) if names and names[0]: entry['vendor'] = '{} ({})'.format( names[0], vendor['term'], ) if names and names[1]: entry['adapter'] = '{} ({})'.format( names[1], adapter['term'], ) graphics.append(entry) # By default, results are sorted by vendor count then adapter count. # We instead need to sort them by adapter count only. That cannot be # done in SuperSearch directly, so we do it here. facets['adapter_vendor_id'] = sorted( graphics, key=lambda x: x['count'], reverse=True )