def test_sscreator_as_mod(self): owner_id = uuid.uuid4() dashboard_id = uuid.uuid4() tile_config = { 'series_spec_list': [ SeriesSpec(1, 0, dict(op='eq', args=['label1'])), ], 'tile_options': { 'sscs': SeriesSpec(1, 0, dict(op='eq', args=['label1'])) } } r = Report.insert(owner_id, 'r') tile = Tile.insert(owner_id, r.report_id, dashboard_id, tile_config) layouts.place_tile(tile) ri1 = r.process_input('label1 1', handle_sscreator=False).report_instance ri2 = r.process_input('label11 11\nlabel12 12', handle_sscreator=False).report_instance ri3 = r.process_input('label21 21\nlabel22 22', handle_sscreator=False).report_instance layout_rows = c.dao.LayoutDAO.select_layout_by_report_multi(owner_id, r.report_id, [], 'sscs', 100) mods = [sscreator.sscreator_mod(ri1, layout_rows[0]), sscreator.sscreator_mod(ri2, layout_rows[0]), sscreator.sscreator_mod(ri3, layout_rows[0])] layouts.apply_mods(mods, owner_id, dashboard_id, None) layout = Layout.select(owner_id, dashboard_id) tile = layout.tile_dict.keys()[0]
def test_promote_first_as_master_multiple_masters_one_apply_mods_run(self): rd = self.test_repack_dont_put_master_first() tile_config = { 'tags': ['q1:10'], 'series_spec_list': [ dataseries.SeriesSpec(0, -1, dict(op='eq', args=['0'])), ], 'tile_options': { 'tpcreator_uispec': [{ 'tag': 'q1:10', 'prefix': 'q1:' }], } } r2 = Report.insert(rd.owner_id, 'r2') master_tile2 = Tile.insert(rd.owner_id, r2.report_id, rd.dashboard_id, tile_config) layouts.place_tile(master_tile2) ri1 = r2.process_input('0', tags=['q1:8'], handle_tpcreator=False).report_instance ri2 = r2.process_input('0', tags=['q1:12'], handle_tpcreator=False).report_instance ri3 = r2.process_input('0', tags=['q1:6'], handle_tpcreator=False).report_instance ri4 = rd.report.process_input('0', tags=['p1:2'], handle_tpcreator=False).report_instance layout_rows_tpcreator = c.dao.LayoutDAO.select_layout_by_report_multi( rd.owner_id, rd.report_id, [], 'tpcreator', 100) mods = [ tpcreator.tpcreator_mod(ri1, layout_rows_tpcreator[0]), tpcreator.tpcreator_mod(ri2, layout_rows_tpcreator[0]), tpcreator.tpcreator_mod(ri3, layout_rows_tpcreator[0]), tpcreator.tpcreator_mod(ri4, layout_rows_tpcreator[0]), layouts.repack_mod(put_master_first=False), layouts.promote_first_as_master_mod(), layouts.if_mod(lambda layout_mod: layout_mod.tile_replacement, layouts.repack_mod()) ] layouts.apply_mods(mods, rd.owner_id, rd.dashboard_id, None) self.assertEqual([['p1:2'], ['p1:6'], ['p1:8'], ['p1:10'], ['p1:12'], ['q1:6'], ['q1:8'], ['q1:10'], ['q1:12']], [tile.tags for tile in rd.tiles_sorted_by_vo()]) master1 = rd.get_tile_by_tags(['p1:2']) master2 = rd.get_tile_by_tags(['q1:6']) self.assertTrue(master1.is_master_tile()) self.assertTrue(master2.is_master_tile()) for tile in rd.tiles_sorted_by_vo(): if tile.tags[0].startswith( 'p') and tile.tile_id != master1.tile_id: self.assertEqual(master1.tile_id, tile.get_master_tile_id()) elif tile.tags[0].startswith( 'q') and tile.tile_id != master2.tile_id: self.assertEqual(master2.tile_id, tile.get_master_tile_id())
def test_repack(self): rd = self.test_no_repack() layouts.apply_mods([layouts.repack_mod()], rd.owner_id, rd.dashboard_id, None) self.assertEqual([['p1:10'], ['p1:6'], ['p1:8'], ['p1:12']], [tile.tags for tile in rd.tiles_sorted_by_vo()])
def test_repack_dont_put_master_first(self): rd = self.test_no_repack() layouts.apply_mods([layouts.repack_mod(put_master_first=False)], rd.owner_id, rd.dashboard_id, None) self.assertEqual([['p1:6'], ['p1:8'], ['p1:10'], ['p1:12']], [tile.tags for tile in rd.tiles_sorted_by_vo()]) self.assertFalse(rd.tiles_sorted_by_vo()[0].is_master_tile()) self.assertTrue(rd.tiles_sorted_by_vo()[2].is_master_tile()) return rd
def synchronize_sizes_of_tpcreated(master_tile, for_layout_id): """Changes the sizes of tpcreated tiles to match the size of the master tile. Returns :class:`~mqe.layouts.LayoutModificationResult`. """ return layouts.apply_mods( [synchronize_sizes_of_tpcreated_mod(master_tile)], master_tile.owner_id, master_tile.dashboard_id, for_layout_id)
def handle_tpcreator(owner_id, report_id, report_instance): """The method calls the TPCreator (see :ref:`guide_tpcreator`) for the given report instance, possibly creating new tiles from a master tile and altering dashboards' layouts. The signal :attr:`~mqe.signals.layout_modified` is issued for each modification.""" layout_rows = c.dao.LayoutDAO.select_layout_by_report_multi( owner_id, report_id, [], 'tpcreator', mqeconfig.MAX_TPCREATORS_PER_REPORT) if not layout_rows: log.debug('No layout_by_report tpcreator rows') return log.info( 'tpcreator is processing %s rows for owner_id=%s report_id=%s report_instance_id=%s', len(layout_rows), owner_id, report_id, report_instance.report_instance_id) for row in layout_rows: mods = [ tpcreator_mod(report_instance, row), layouts.if_mod(lambda layout_mod: layout_mod.new_tiles, layouts.repack_mod()) ] lmr = layouts.apply_mods(mods, owner_id, row['dashboard_id'], for_layout_id=None, max_tries=MAX_TPCREATE_TRIES) if lmr and lmr.new_layout.layout_id != lmr.old_layout.layout_id: fire_signal(layout_modified, reason='tpcreator', layout_modification_result=lmr)
def test_tpcreator_as_mod_performance(self): owner_id = uuid.uuid4() dashboard_id = uuid.uuid4() tile_config = { 'tags': ['str:sample_string'], 'series_spec_list': [ dataseries.SeriesSpec(0, -1, dict(op='eq', args=['0'])), ], 'tile_options': { 'tpcreator_uispec': [{ 'tag': 'str:sample_string', 'prefix': 'str:' }], } } r = reports.Report.insert(owner_id, 'r') master_tile = Tile.insert(owner_id, r.report_id, dashboard_id, tile_config) layouts.place_tile(master_tile) strs = [random_string() for _ in xrange(199)] mods = [] layout_rows = c.dao.LayoutDAO.select_layout_by_report_multi( owner_id, r.report_id, [], 'tpcreator', 100) start = time() for str in strs: res = r.process_input('1', tags=['str:%s' % str], handle_tpcreator=False) mods.append( tpcreator.tpcreator_mod(res.report_instance, layout_rows[0], 200)) print 'Creating report instances took %.1f' % ((time() - start) * 1000) start = time() layouts.apply_mods(mods, owner_id, dashboard_id, None) print 'Applying tpcreator_mods took %.1f' % ((time() - start) * 1000) layout = Layout.select(owner_id, dashboard_id) self.assertEqual(200, len(layout.layout_dict)) tags_set = {tile.tags[0].split(':')[1] for tile in layout.tile_dict} self.assertEqual(200, len(tags_set)) self.assertEqual(tags_set, set(strs + ['sample_string']))
def test_promote_first_as_master(self): rd = self.test_repack_dont_put_master_first() layouts.apply_mods( [layouts.promote_first_as_master_mod(), layouts.repack_mod()], rd.owner_id, rd.dashboard_id, None) #for tile in rd.tiles_sorted_by_vo(): # print tile.tile_id, tile.tags, tile.get_master_tile_id() self.assertEqual([['p1:6'], ['p1:8'], ['p1:10'], ['p1:12']], [tile.tags for tile in rd.tiles_sorted_by_vo()]) first_tile = rd.tiles_sorted_by_vo()[0] self.assertTrue(first_tile.is_master_tile()) for tile in rd.tiles_sorted_by_vo()[1:]: self.assertFalse(tile.is_master_tile()) self.assertEqual(first_tile.tile_id, tile.get_master_tile_id()) return rd
def test_no_repack(self): tile_config = { 'tags': ['p1:10'], 'series_spec_list': [ dataseries.SeriesSpec(0, -1, dict(op='eq', args=['0'])), ], 'tile_options': { 'tpcreator_uispec': [{ 'tag': 'p1:10', 'prefix': 'p1:' }], } } rd = ReportData('r') master_tile = Tile.insert(rd.owner_id, rd.report_id, rd.dashboard_id, tile_config) layouts.place_tile(master_tile) ri1 = rd.report.process_input('0', tags=['p1:8'], handle_tpcreator=False).report_instance ri2 = rd.report.process_input('0', tags=['p1:12'], handle_tpcreator=False).report_instance ri3 = rd.report.process_input('0', tags=['p1:6'], handle_tpcreator=False).report_instance layout_rows_tpcreator = c.dao.LayoutDAO.select_layout_by_report_multi( rd.owner_id, rd.report_id, [], 'tpcreator', 100) mods = [ tpcreator.tpcreator_mod(ri1, layout_rows_tpcreator[0]), tpcreator.tpcreator_mod(ri2, layout_rows_tpcreator[0]), tpcreator.tpcreator_mod(ri3, layout_rows_tpcreator[0]), ] layouts.apply_mods(mods, rd.owner_id, rd.dashboard_id, None) self.assertEqual([['p1:10'], ['p1:8'], ['p1:12'], ['p1:6']], [tile.tags for tile in rd.tiles_sorted_by_vo()]) return rd
def test_tpcreator_as_mod(self): owner_id = uuid.uuid4() dashboard_id = uuid.uuid4() tile_config = { 'tags': ['p1:10'], 'series_spec_list': [ dataseries.SeriesSpec(0, -1, dict(op='eq', args=['0'])), ], 'tile_options': { 'tpcreator_uispec': [{ 'tag': 'p1:10', 'prefix': 'p1:' }], } } r = reports.Report.insert(owner_id, 'r') master_tile = Tile.insert(owner_id, r.report_id, dashboard_id, tile_config) layouts.place_tile(master_tile) ri1 = r.process_input('0', tags=['p1:11'], handle_tpcreator=False).report_instance ri2 = r.process_input('0', tags=['p1:12'], handle_tpcreator=False).report_instance ri3 = r.process_input('0', tags=['p1:12'], handle_tpcreator=False).report_instance layout_rows = c.dao.LayoutDAO.select_layout_by_report_multi( owner_id, r.report_id, [], 'tpcreator', 100) mods = [ tpcreator.tpcreator_mod(ri1, layout_rows[0]), tpcreator.tpcreator_mod(ri2, layout_rows[0]), tpcreator.tpcreator_mod(ri3, layout_rows[0]) ] layouts.apply_mods(mods, owner_id, dashboard_id, None) layout = Layout.select(owner_id, dashboard_id) self.assertEqual(3, len(layout.layout_dict)) self.assertEqual([['p1:10'], ['p1:11'], ['p1:12']], sorted(tile.tags for tile in layout.tile_dict))
def test_layout_mod_nop_single_try(self): def nop(layout_mod): return tiles = call(TilePlacingDetachingTest.test_place_multiple) orig_layout = layouts.Layout.select(tiles[0].owner_id, tiles[0].dashboard_id) lmr = layouts.apply_mods([nop], tiles[0].owner_id, tiles[0].dashboard_id, orig_layout.layout_id) self.assertTrue(lmr) self.assertEqual(orig_layout.layout_dict, lmr.old_layout.layout_dict) self.assertEqual(orig_layout.layout_dict, lmr.new_layout.layout_dict) self.assertEqual(orig_layout.layout_id, lmr.old_layout.layout_id) self.assertEqual(orig_layout.layout_id, lmr.new_layout.layout_id)
def test_layout_mod_modify_vo_single_try(self): def modify_vo(layout_mod): layout_mod.layout.layout_dict.items()[0][1]['x'] = 100 tiles = call(TilePlacingDetachingTest.test_place_multiple) orig_layout = layouts.Layout.select(tiles[0].owner_id, tiles[0].dashboard_id) lmr = layouts.apply_mods([modify_vo], tiles[0].owner_id, tiles[0].dashboard_id, orig_layout.layout_id) self.assertTrue(lmr) self.assertEqual(orig_layout.layout_dict, lmr.old_layout.layout_dict) self.assertNotEqual(orig_layout.layout_dict, lmr.new_layout.layout_dict) self.assertEqual(orig_layout.layout_id, lmr.old_layout.layout_id) self.assertNotEqual(orig_layout.layout_id, lmr.new_layout.layout_id)
def handle_sscreator(owner_id, report_id, report_instance): """The method calls the SSCS (see :ref:`guide_sscreator`) for the given report instance, possibly creating new series definitions for tiles and altering dashboards' layouts. The signal :attr:`~mqe.signals.layout_modified` is issued for each modification.""" layout_rows = c.dao.LayoutDAO.select_layout_by_report_multi(owner_id, report_id, [], 'sscs', mqeconfig.MAX_DASHBOARDS_WITH_SSCS_PER_REPORT) if not layout_rows: log.debug('No layout_by_report sscs rows') return log.info('sscreator is processing %s rows for owner_id=%s report_id=%s report_instance_id=%s', len(layout_rows), owner_id, report_id, report_instance.report_instance_id) for row in layout_rows: mods = [sscreator_mod(report_instance, row)] lmr = layouts.apply_mods(mods, owner_id, row['dashboard_id'], for_layout_id=None, max_tries=MAX_SSCS_TRIES) if lmr and lmr.new_layout.layout_id != lmr.old_layout.layout_id: fire_signal(layout_modified, reason='sscreator', layout_modification_result=lmr)
def handle_tpcreator(owner_id, report_id, report_instance, make_first_master=False): """The method calls the TPCreator (see :ref:`guide_tpcreator`) for the given report instance, possibly creating new tiles from a master tile and altering dashboards' layouts. The signal :attr:`~mqe.signals.layout_modified` is issued for each modification. :param bool make_first_master: whether to promote the first tile wrt. ordering of tag values to a master tile. The default is ``False``, which means that a new master tile will not be promoted. """ layout_rows = c.dao.LayoutDAO.select_layout_by_report_multi(owner_id, report_id, [], 'tpcreator', mqeconfig.MAX_TPCREATORS_PER_REPORT) if not layout_rows: log.debug('No layout_by_report tpcreator rows') return log.info('tpcreator is processing %s rows for owner_id=%s report_id=%s report_instance_id=%s', len(layout_rows), owner_id, report_id, report_instance.report_instance_id) for row in layout_rows: mods = [tpcreator_mod(report_instance, row), # run the repacking only if tpcreator created a new tile layouts.if_mod(lambda layout_mod: layout_mod.new_tiles, layouts.repack_mod(put_master_first=(not make_first_master)))] if make_first_master: mods.extend([ # run the promote_first... mod only if tpcreator created a new tile layouts.if_mod(lambda layout_mod: layout_mod.new_tiles, layouts.promote_first_as_master_mod()), # another repacking is needed if the promote_first... mod made replacements, # because the mod doesn't preserve ordering layouts.if_mod(lambda layout_mod: layout_mod.tile_replacement, layouts.repack_mod()), ]) lmr = layouts.apply_mods(mods, owner_id, row['dashboard_id'], for_layout_id=None, max_tries=MAX_TPCREATE_TRIES) if lmr and lmr.new_layout.layout_id != lmr.old_layout.layout_id: fire_signal(layout_modified, reason='tpcreator', layout_modification_result=lmr)
def main(): vars = tutorial.main() points_report = vars['points_report'] tile = vars['tile'] owner_id = vars['owner_id'] owner_dashboards = vars['owner_dashboards'] dashboard = vars['dashboard'] SECTION('Placing, detaching, replacing tiles') from mqe.layouts import Layout, place_tile layout = Layout.select(owner_id, dashboard.dashboard_id) new_tile = tile.copy(dashboard.dashboard_id) # we decided that new_tile should be put in the current layout res = place_tile(new_tile, for_layout_id=layout.layout_id) if not res: raise ValueError('Placing the tile unsuccessful') else: print 'New tile placed with visual_options', res.new_tiles[new_tile] from mqe.layouts import replace_tiles from mqe.tiles import Tile layout = Layout.select(owner_id, dashboard.dashboard_id) tile = Tile.select(dashboard.dashboard_id, layout.layout_dict.keys()[0]) tile_config = tile.get_tile_config() tile_config['tile_options']['tile_title'] = 'New Title' repl_tile = tile.insert_similar(tile_config) res = replace_tiles({tile: repl_tile}, for_layout_id=layout.layout_id) if not res: raise ValueError('Replacement of tiles unsuccessful') else: print 'Tiles replaced:', res.tile_replacement SECTION('Setting a custom layout') layout = Layout.select(owner_id, dashboard.dashboard_id) for visual_options in layout.layout_dict.values(): visual_options['height'] += 1 new_layout_id = layout.set() if not new_layout_id: raise ValueError('Updating the layout failed') SECTION('Layout mods') from mqe.layouts import replace_tiles_mod, place_tile_mod, apply_mods tile = repl_tile tile1 = tile.copy(dashboard.dashboard_id) tile2 = tile.copy(dashboard.dashboard_id) tile3 = tile.copy(dashboard.dashboard_id) layout = Layout.select(owner_id, dashboard.dashboard_id) mods = [ replace_tiles_mod({tile: tile1}), place_tile_mod(tile2), place_tile_mod(tile3), ] res = apply_mods(mods, owner_id, dashboard.dashboard_id, for_layout_id=layout.layout_id) if not res: raise ValueError('Operation failed') else: print res from mqe.layouts import LayoutModificationImpossible def detach_top_tiles_mod(): def do(layout_mod): tile_ids = [ tile_id for tile_id, visual_options in layout_mod.layout.layout_dict.items() if visual_options['y'] == 0 ] if not tile_ids: raise LayoutModificationImpossible() for tile_id in tile_ids: del layout_mod.layout.layout_dict[tile_id] layout_mod.detached_tiles.append( Tile.select(layout_mod.layout.dashboard_id, tile_id)) return do res = apply_mods([detach_top_tiles_mod()], owner_id, dashboard.dashboard_id, None) if not res: raise ValueError('Operation failed') else: print res def detach_top_tiles_using_replacement_mod(): def do(layout_mod): tiles = [ tile for tile, visual_options in layout_mod.layout.tile_dict.items() if visual_options['y'] == 0 ] if not tiles: raise LayoutModificationImpossible() replace_tiles_mod({tile: None for tile in tiles})(layout_mod) return do