mirror of https://github.com/apache/kafka.git
				
				
				
			
		
			
				
	
	
		
			257 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
| #!/usr/bin/env python
 | |
| 
 | |
| # ===================================
 | |
| # replica_basic_test.py
 | |
| # ===================================
 | |
| 
 | |
| import inspect
 | |
| import logging
 | |
| import os
 | |
| import signal
 | |
| import subprocess
 | |
| import sys
 | |
| import time
 | |
| 
 | |
| from   system_test_env    import SystemTestEnv
 | |
| sys.path.append(SystemTestEnv.SYSTEM_TEST_UTIL_DIR)
 | |
| from   setup_utils        import SetupUtils
 | |
| import system_test_utils
 | |
| from   testcase_env       import TestcaseEnv
 | |
| 
 | |
| # product specific: Kafka
 | |
| import kafka_system_test_utils
 | |
| 
 | |
| class ReplicaBasicTest(SetupUtils):
 | |
| 
 | |
|     testModuleAbsPathName = os.path.realpath(__file__)
 | |
|     testSuiteAbsPathName  = os.path.abspath(os.path.dirname(testModuleAbsPathName))
 | |
|     isLeaderLogPattern    = "Completed the leader state transition"
 | |
| 
 | |
|     def __init__(self, systemTestEnv):
 | |
| 
 | |
|         # SystemTestEnv - provides cluster level environment settings
 | |
|         #     such as entity_id, hostname, kafka_home, java_home which
 | |
|         #     are available in a list of dictionary named 
 | |
|         #     "clusterEntityConfigDictList"
 | |
|         self.systemTestEnv = systemTestEnv
 | |
| 
 | |
|         # dict to pass user-defined attributes to logger argument: "extra"
 | |
|         d = {'name_of_class': self.__class__.__name__}
 | |
| 
 | |
|     def signal_handler(self, signal, frame):
 | |
|         self.log_message("Interrupt detected - User pressed Ctrl+c")
 | |
| 
 | |
|         for entityId, parentPid in self.testcaseEnv.entityParentPidDict.items():
 | |
|             kafka_system_test_utils.stop_remote_entity(self.systemTestEnv, self.testcaseEnv, entityId, parentPid)
 | |
| 
 | |
|         sys.exit(1) 
 | |
| 
 | |
|     def runTest(self):
 | |
| 
 | |
|         # get all testcase directories under this testsuite
 | |
|         testCasePathNameList = system_test_utils.get_dir_paths_with_prefix(
 | |
|             self.testSuiteAbsPathName, SystemTestEnv.SYSTEM_TEST_CASE_PREFIX)
 | |
|         testCasePathNameList.sort()
 | |
| 
 | |
|         # =============================================================
 | |
|         # launch each testcase one by one: testcase_1, testcase_2, ...
 | |
|         # =============================================================
 | |
|         for testCasePathName in testCasePathNameList:
 | |
|    
 | |
|             try: 
 | |
|                 # create a new instance of TestcaseEnv to keep track of this testcase's environment variables
 | |
|                 self.testcaseEnv = TestcaseEnv(self.systemTestEnv, self)
 | |
|                 self.testcaseEnv.testSuiteBaseDir = self.testSuiteAbsPathName
 | |
|     
 | |
|                 # initialize self.testcaseEnv with user-defined environment
 | |
|                 self.testcaseEnv.userDefinedEnvVarDict["LEADER_ELECTION_COMPLETED_MSG"] = \
 | |
|                     ReplicaBasicTest.isLeaderLogPattern
 | |
|                 self.testcaseEnv.userDefinedEnvVarDict["REGX_LEADER_ELECTION_PATTERN"]  = \
 | |
|                     "\[(.*?)\] .* Broker (.*?): " + \
 | |
|                     self.testcaseEnv.userDefinedEnvVarDict["LEADER_ELECTION_COMPLETED_MSG"] + \
 | |
|                     " for topic (.*?) partition (.*?) \(.*"
 | |
|                 self.testcaseEnv.userDefinedEnvVarDict["zkConnectStr"] = ""
 | |
|     
 | |
|                 # find testcase properties json file
 | |
|                 testcasePropJsonPathName = system_test_utils.get_testcase_prop_json_pathname(testCasePathName)
 | |
|                 self.logger.debug("testcasePropJsonPathName : " + testcasePropJsonPathName, extra=self.d)
 | |
|     
 | |
|                 # get the dictionary that contains the testcase arguments and description
 | |
|                 testcaseNonEntityDataDict = system_test_utils.get_json_dict_data(testcasePropJsonPathName)
 | |
|     
 | |
|                 testcaseDirName = os.path.basename(testCasePathName)
 | |
|                 self.testcaseEnv.testcaseResultsDict["test_case_name"] = testcaseDirName
 | |
|     
 | |
|                 #### => update testcaseEnv
 | |
|                 self.testcaseEnv.testCaseBaseDir = testCasePathName
 | |
|                 self.testcaseEnv.testCaseLogsDir = self.testcaseEnv.testCaseBaseDir + "/logs"
 | |
|     
 | |
|                 # get testcase description
 | |
|                 testcaseDescription = ""
 | |
|                 for k,v in testcaseNonEntityDataDict.items():
 | |
|                     if ( k == "description" ): testcaseDescription = v
 | |
|     
 | |
|                 #### => update testcaseEnv
 | |
|                 # TestcaseEnv.testcaseArgumentsDict initialized, this dictionary keeps track of the
 | |
|                 # "testcase_args" in the testcase_properties.json such as replica_factor, num_partition, ...
 | |
|                 self.testcaseEnv.testcaseArgumentsDict = testcaseNonEntityDataDict["testcase_args"]
 | |
|     
 | |
|                 # =================================================================
 | |
|                 # TestcaseEnv environment settings initialization are completed here
 | |
|                 # =================================================================
 | |
|                 # self.testcaseEnv.systemTestBaseDir
 | |
|                 # self.testcaseEnv.testSuiteBaseDir
 | |
|                 # self.testcaseEnv.testCaseBaseDir
 | |
|                 # self.testcaseEnv.testCaseLogsDir
 | |
|                 # self.testcaseEnv.testcaseArgumentsDict
 | |
|     
 | |
|                 # display testcase name and arguments
 | |
|                 self.log_message("Test Case : " + testcaseDirName)
 | |
|                 for k,v in self.testcaseEnv.testcaseArgumentsDict.items():
 | |
|                     self.anonLogger.info("    " + k + " : " + v)
 | |
|                 self.log_message("Description : " + testcaseDescription)
 | |
|     
 | |
|     
 | |
|                 # ================================================================ #
 | |
|                 # ================================================================ #
 | |
|                 #            Product Specific Testing Code Starts Here:            #
 | |
|                 # ================================================================ #
 | |
|                 # ================================================================ #
 | |
|     
 | |
|                 # initialize signal handler
 | |
|                 signal.signal(signal.SIGINT, self.signal_handler)
 | |
|     
 | |
|                 # create "LOCAL" log directories for metrics, dashboards for each entity under this testcase
 | |
|                 # for collecting logs from remote machines
 | |
|                 kafka_system_test_utils.generate_testcase_log_dirs(self.systemTestEnv, self.testcaseEnv)
 | |
|     
 | |
|                 # TestcaseEnv.testcaseConfigsList initialized by reading testcase properties file:
 | |
|                 #   system_test/<suite_name>_testsuite/testcase_<n>/testcase_<n>_properties.json
 | |
|                 self.testcaseEnv.testcaseConfigsList = system_test_utils.get_json_list_data(testcasePropJsonPathName)
 | |
|     
 | |
|                 # TestcaseEnv - initialize producer & consumer config / log file pathnames
 | |
|                 kafka_system_test_utils.init_entity_props(self.systemTestEnv, self.testcaseEnv)
 | |
|     
 | |
|                 # clean up data directories specified in zookeeper.properties and kafka_server_<n>.properties
 | |
|                 kafka_system_test_utils.cleanup_data_at_remote_hosts(self.systemTestEnv, self.testcaseEnv)
 | |
|     
 | |
|                 # generate remote hosts log/config dirs if not exist
 | |
|                 kafka_system_test_utils.generate_testcase_log_dirs_in_remote_hosts(self.systemTestEnv, self.testcaseEnv)
 | |
|     
 | |
|                 # generate properties files for zookeeper, kafka, producer, consumer:
 | |
|                 # 1. copy system_test/<suite_name>_testsuite/config/*.properties to 
 | |
|                 #    system_test/<suite_name>_testsuite/testcase_<n>/config/
 | |
|                 # 2. update all properties files in system_test/<suite_name>_testsuite/testcase_<n>/config
 | |
|                 #    by overriding the settings specified in:
 | |
|                 #    system_test/<suite_name>_testsuite/testcase_<n>/testcase_<n>_properties.json
 | |
|                 kafka_system_test_utils.generate_overriden_props_files(self.testSuiteAbsPathName, self.testcaseEnv, self.systemTestEnv)
 | |
|     
 | |
|                 # =============================================
 | |
|                 # preparing all entities to start the test
 | |
|                 # =============================================
 | |
|                 self.log_message("starting zookeepers")
 | |
|                 kafka_system_test_utils.start_zookeepers(self.systemTestEnv, self.testcaseEnv)
 | |
|                 self.anonLogger.info("sleeping for 2s")
 | |
|                 time.sleep(2)
 | |
|     
 | |
|                 self.log_message("starting brokers")
 | |
|                 kafka_system_test_utils.start_brokers(self.systemTestEnv, self.testcaseEnv)
 | |
|                 self.anonLogger.info("sleeping for 5s")
 | |
|                 time.sleep(5)
 | |
|     
 | |
|                 self.log_message("creating topics")
 | |
|                 kafka_system_test_utils.create_topic(self.systemTestEnv, self.testcaseEnv)
 | |
|                 self.anonLogger.info("sleeping for 5s")
 | |
|                 time.sleep(5)
 | |
|     
 | |
|                 self.log_message("looking up leader")
 | |
|                 leaderDict = kafka_system_test_utils.get_leader_elected_log_line(self.systemTestEnv, self.testcaseEnv)
 | |
|     
 | |
|                 # ==========================
 | |
|                 # leaderDict looks like this:
 | |
|                 # ==========================
 | |
|                 #{'entity_id': u'3',
 | |
|                 # 'partition': '0',
 | |
|                 # 'timestamp': 1345050255.8280001,
 | |
|                 # 'hostname': u'localhost',
 | |
|                 # 'topic': 'test_1',
 | |
|                 # 'brokerid': '3'}
 | |
|     
 | |
|                 # validate to see if leader election is successful
 | |
|                 self.log_message("validating leader election")
 | |
|                 result = kafka_system_test_utils.validate_leader_election_successful( \
 | |
|                              self.testcaseEnv, leaderDict, self.testcaseEnv.validationStatusDict)
 | |
|     
 | |
|                 # checking to see if leader bouncing is required in this testcase
 | |
|                 bounceLeaderFlag = self.testcaseEnv.testcaseArgumentsDict["bounce_leader"]
 | |
|                 self.log_message("bounce_leader flag : " + bounceLeaderFlag)
 | |
|     
 | |
|                 if (bounceLeaderFlag.lower() == "true"):
 | |
|                     if self.testcaseEnv.validationStatusDict["Validate leader election successful"] == "FAILED":
 | |
|                         # no leader available for testing => skip this round
 | |
|                         self.log_message("stopping all entities")
 | |
|                         for entityId, parentPid in self.testcaseEnv.entityParentPidDict.items():
 | |
|                             kafka_system_test_utils.stop_remote_entity(self.systemTestEnv, entityId, parentPid)
 | |
|     
 | |
|                         continue
 | |
|                     else:
 | |
|                         # leader elected => stop leader
 | |
|                         try:
 | |
|                             leaderEntityId = leaderDict["entity_id"]
 | |
|                             leaderBrokerId = leaderDict["brokerid"]
 | |
|                             leaderPPid     = self.testcaseEnv.entityParentPidDict[leaderEntityId]
 | |
|                         except:
 | |
|                             self.log_message("leader details unavailable")
 | |
|     
 | |
|                         self.log_message("stopping leader in entity "+leaderEntityId+" with pid "+leaderPPid)
 | |
|                  
 | |
|                         kafka_system_test_utils.stop_remote_entity(self.systemTestEnv, leaderEntityId, leaderPPid)
 | |
|                         self.testcaseEnv.entityParentPidDict[leaderEntityId] = ""
 | |
|     
 | |
|                     self.logger.info("sleeping for 5s for leader re-election to complete", extra=self.d)
 | |
|                     time.sleep(5)
 | |
|     
 | |
|                 # starting producer 
 | |
|                 self.log_message("starting producer")
 | |
|                 kafka_system_test_utils.start_producer_performance(self.systemTestEnv, self.testcaseEnv)
 | |
|                 self.anonLogger.info("sleeping for 5s")
 | |
|                 time.sleep(5)
 | |
|     
 | |
|                 # starting previously terminated broker 
 | |
|                 if (bounceLeaderFlag.lower() == "true" and not self.testcaseEnv.entityParentPidDict[leaderEntityId]):
 | |
|                     self.log_message("starting the previously terminated broker")
 | |
|     
 | |
|                     stoppedLeaderEntityId = leaderDict["entity_id"]
 | |
|                     kafka_system_test_utils.start_entity_in_background(
 | |
|                         self.systemTestEnv, self.testcaseEnv, stoppedLeaderEntityId)
 | |
|     
 | |
|                     self.anonLogger.info("sleeping for 5s")
 | |
|                     time.sleep(5)
 | |
| 
 | |
|                 # starting consumer
 | |
|                 self.log_message("starting consumer")
 | |
|                 kafka_system_test_utils.start_console_consumer(self.systemTestEnv, self.testcaseEnv)
 | |
|     
 | |
|                 # this testcase is completed - so stopping all entities
 | |
|                 self.log_message("stopping all entities")
 | |
|                 for entityId, parentPid in self.testcaseEnv.entityParentPidDict.items():
 | |
|                     kafka_system_test_utils.stop_remote_entity(self.systemTestEnv, entityId, parentPid)
 | |
|     
 | |
|                 # validate the data matched
 | |
|                 self.log_message("validating data matched")
 | |
|                 result = kafka_system_test_utils.validate_data_matched(self.systemTestEnv, self.testcaseEnv)
 | |
|     
 | |
|                 # =============================================
 | |
|                 # collect logs from remote hosts
 | |
|                 # =============================================
 | |
|                 kafka_system_test_utils.collect_logs_from_remote_hosts(self.systemTestEnv, self.testcaseEnv)
 | |
|     
 | |
|             except Exception as e:
 | |
|                 self.log_message("Exception caught : ")
 | |
|                 print e
 | |
|                 self.log_message("stopping all entities")
 | |
|                 for entityId, parentPid in self.testcaseEnv.entityParentPidDict.items():
 | |
|                     kafka_system_test_utils.stop_remote_entity(self.systemTestEnv, entityId, parentPid)
 | |
| 
 | |
|  
 |