1# Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2# This source code is licensed under both the GPLv2 (found in the 3# COPYING file in the root directory) and Apache 2.0 License 4# (found in the LICENSE.Apache file in the root directory). 5 6from advisor.db_log_parser import DatabaseLogs, Log, NO_COL_FAMILY 7from advisor.rule_parser import Condition, LogCondition 8import os 9import unittest 10 11 12class TestLog(unittest.TestCase): 13 def setUp(self): 14 self.column_families = ['default', 'col_fam_A'] 15 16 def test_get_column_family(self): 17 test_log = ( 18 "2018/05/25-14:34:21.047233 7f82ba72e700 [db/flush_job.cc:371] " + 19 "[col_fam_A] [JOB 44] Level-0 flush table #84: 1890780 bytes OK" 20 ) 21 db_log = Log(test_log, self.column_families) 22 self.assertEqual('col_fam_A', db_log.get_column_family()) 23 24 test_log = ( 25 "2018/05/25-14:34:21.047233 7f82ba72e700 [db/flush_job.cc:371] " + 26 "[JOB 44] Level-0 flush table #84: 1890780 bytes OK" 27 ) 28 db_log = Log(test_log, self.column_families) 29 db_log.append_message('[default] some remaining part of log') 30 self.assertEqual(NO_COL_FAMILY, db_log.get_column_family()) 31 32 def test_get_methods(self): 33 hr_time = "2018/05/25-14:30:25.491635" 34 context = "7f82ba72e700" 35 message = ( 36 "[db/flush_job.cc:331] [default] [JOB 10] Level-0 flush table " + 37 "#23: started" 38 ) 39 test_log = hr_time + " " + context + " " + message 40 db_log = Log(test_log, self.column_families) 41 self.assertEqual(db_log.get_message(), message) 42 remaining_message = "[col_fam_A] some more logs" 43 db_log.append_message(remaining_message) 44 self.assertEqual( 45 db_log.get_human_readable_time(), "2018/05/25-14:30:25.491635" 46 ) 47 self.assertEqual(db_log.get_context(), "7f82ba72e700") 48 self.assertEqual(db_log.get_timestamp(), 1527258625) 49 self.assertEqual( 50 db_log.get_message(), str(message + '\n' + remaining_message) 51 ) 52 53 def test_is_new_log(self): 54 new_log = "2018/05/25-14:34:21.047233 context random new log" 55 remaining_log = "2018/05/25 not really a new log" 56 self.assertTrue(Log.is_new_log(new_log)) 57 self.assertFalse(Log.is_new_log(remaining_log)) 58 59 60class TestDatabaseLogs(unittest.TestCase): 61 def test_check_and_trigger_conditions(self): 62 this_path = os.path.abspath(os.path.dirname(__file__)) 63 logs_path_prefix = os.path.join(this_path, 'input_files/LOG-0') 64 column_families = ['default', 'col-fam-A', 'col-fam-B'] 65 db_logs = DatabaseLogs(logs_path_prefix, column_families) 66 # matches, has 2 col_fams 67 condition1 = LogCondition.create(Condition('cond-A')) 68 condition1.set_parameter('regex', 'random log message') 69 # matches, multiple lines message 70 condition2 = LogCondition.create(Condition('cond-B')) 71 condition2.set_parameter('regex', 'continuing on next line') 72 # does not match 73 condition3 = LogCondition.create(Condition('cond-C')) 74 condition3.set_parameter('regex', 'this should match no log') 75 db_logs.check_and_trigger_conditions( 76 [condition1, condition2, condition3] 77 ) 78 cond1_trigger = condition1.get_trigger() 79 self.assertEqual(2, len(cond1_trigger.keys())) 80 self.assertSetEqual( 81 {'col-fam-A', NO_COL_FAMILY}, set(cond1_trigger.keys()) 82 ) 83 self.assertEqual(2, len(cond1_trigger['col-fam-A'])) 84 messages = [ 85 "[db/db_impl.cc:563] [col-fam-A] random log message for testing", 86 "[db/db_impl.cc:653] [col-fam-A] another random log message" 87 ] 88 self.assertIn(cond1_trigger['col-fam-A'][0].get_message(), messages) 89 self.assertIn(cond1_trigger['col-fam-A'][1].get_message(), messages) 90 self.assertEqual(1, len(cond1_trigger[NO_COL_FAMILY])) 91 self.assertEqual( 92 cond1_trigger[NO_COL_FAMILY][0].get_message(), 93 "[db/db_impl.cc:331] [unknown] random log message no column family" 94 ) 95 cond2_trigger = condition2.get_trigger() 96 self.assertEqual(['col-fam-B'], list(cond2_trigger.keys())) 97 self.assertEqual(1, len(cond2_trigger['col-fam-B'])) 98 self.assertEqual( 99 cond2_trigger['col-fam-B'][0].get_message(), 100 "[db/db_impl.cc:234] [col-fam-B] log continuing on next line\n" + 101 "remaining part of the log" 102 ) 103 self.assertIsNone(condition3.get_trigger()) 104