1515// specific language governing permissions and limitations
1616// under the License.
1717
18+ import org.apache.doris.regression.util.RoutineLoadTestUtils
1819import org.apache.kafka.clients.admin.AdminClient
19- import org.apache.kafka.clients.producer.KafkaProducer
20- import org.apache.kafka.clients.producer.ProducerRecord
20+ import org.apache.kafka.clients.admin.NewTopic
2121import org.apache.kafka.clients.producer.ProducerConfig
2222
2323suite(" test_routine_load_error_info" ," nonConcurrent" ) {
@@ -30,52 +30,19 @@ suite("test_routine_load_error_info","nonConcurrent") {
3030 " test_error_info" ,
3131 ]
3232
33- String enabled = context. config. otherConfigs. get(" enableKafkaTest" )
34- String kafka_port = context. config. otherConfigs. get(" kafka_port" )
35- String externalEnvIp = context. config. otherConfigs. get(" externalEnvIp" )
36- def kafka_broker = " ${ externalEnvIp} :${ kafka_port} "
33+ def kafkaTestEnabled = RoutineLoadTestUtils . isKafkaTestEnabled(context)
34+ def kafka_broker = RoutineLoadTestUtils . getKafkaBroker(context)
3735
3836 // send data to kafka
39- if (enabled != null && enabled. equalsIgnoreCase(" true" )) {
40- def props = new Properties ()
41- props. put(ProducerConfig . BOOTSTRAP_SERVERS_CONFIG , " ${ kafka_broker} " . toString())
42- props. put(ProducerConfig . KEY_SERIALIZER_CLASS_CONFIG , " org.apache.kafka.common.serialization.StringSerializer" )
43- props. put(ProducerConfig . VALUE_SERIALIZER_CLASS_CONFIG , " org.apache.kafka.common.serialization.StringSerializer" )
44- // add timeout config
45- props. put(ProducerConfig . MAX_BLOCK_MS_CONFIG , " 10000" )
46- props. put(ProducerConfig . REQUEST_TIMEOUT_MS_CONFIG , " 10000" )
47-
48- // check conenction
49- def verifyKafkaConnection = { prod ->
50- try {
51- logger. info(" =====try to connect Kafka========" )
52- def partitions = prod. partitionsFor(" __connection_verification_topic" )
53- return partitions != null
54- } catch (Exception e) {
55- throw new Exception (" Kafka connect fail: ${ e.message} " . toString())
56- }
57- }
58- // Create kafka producer
59- def producer = new KafkaProducer<> (props)
37+ if (kafkaTestEnabled) {
38+ def producer = RoutineLoadTestUtils . createKafkaProducer(kafka_broker)
6039 try {
61- logger . info( " Kafka connecting: ${ kafka_broker } " )
62- if ( ! verifyKafkaConnection(producer)) {
63- throw new Exception ( " can't get any kafka info " )
40+ for ( String kafkaCsvTopic in kafkaCsvTpoics) {
41+ def txt = new File ( """ ${ context.file.parent } /data/ ${ kafkaCsvTopic } .csv """ ) . text
42+ RoutineLoadTestUtils . sendTestDataToKafka(producer, [kafkaCsvTopic], txt . readLines() )
6443 }
65- } catch (Exception e) {
66- logger. error(" FATAL: " + e. getMessage())
44+ } finally {
6745 producer. close()
68- throw e
69- }
70- logger. info(" Kafka connect success" )
71- for (String kafkaCsvTopic in kafkaCsvTpoics) {
72- def txt = new File (""" ${ context.file.parent} /data/${ kafkaCsvTopic} .csv""" ). text
73- def lines = txt. readLines()
74- lines. each { line ->
75- logger. info(" =====${ line} ========" )
76- def record = new ProducerRecord<> (kafkaCsvTopic, null , line)
77- producer. send(record)
78- }
7946 }
8047 }
8148
@@ -165,15 +132,47 @@ suite("test_routine_load_error_info","nonConcurrent") {
165132 )
166133 FROM KAFKA
167134 (
168- "kafka_broker_list" = "${ externalEnvIp } : ${ kafka_port } ",
135+ "kafka_broker_list" = "${ kafka_broker } ",
169136 "kafka_topic" = "${ kafkaTopic} ",
170137 "property.kafka_default_offsets" = "OFFSET_BEGINNING"
171138 );
172139 """
173140 }
174141
142+ def createReadCommittedJob = {jobName , tableName , kafkaTopic ->
143+ sql """
144+ CREATE ROUTINE LOAD ${ jobName} on ${ tableName}
145+ COLUMNS(k00,k01,k02,k03,k04,k05,k06,k07,k08,k09,k10,k11,k12,k13,k14,k15,k16,k17,k18),
146+ COLUMNS TERMINATED BY "|"
147+ PROPERTIES
148+ (
149+ "max_batch_interval" = "5",
150+ "max_batch_rows" = "300000",
151+ "max_batch_size" = "209715200"
152+ )
153+ FROM KAFKA
154+ (
155+ "kafka_broker_list" = "${ kafka_broker} ",
156+ "kafka_topic" = "${ kafkaTopic} ",
157+ "property.kafka_default_offsets" = "OFFSET_BEGINNING",
158+ "property.isolation.level" = "read_committed"
159+ );
160+ """
161+ }
162+
163+ def createKafkaTopic = {kafkaTopic ->
164+ def adminProps = new Properties ()
165+ adminProps. put(ProducerConfig . BOOTSTRAP_SERVERS_CONFIG , " ${ kafka_broker} " . toString())
166+ def adminClient = AdminClient . create(adminProps)
167+ try {
168+ adminClient. createTopics([new NewTopic (kafkaTopic, 1 , (short ) 1 )]). all(). get()
169+ } finally {
170+ adminClient. close()
171+ }
172+ }
173+
175174 // case 1: task failed
176- if (enabled != null && enabled . equalsIgnoreCase( " true " ) ) {
175+ if (kafkaTestEnabled ) {
177176 // create table
178177 def jobName = " test_error_info"
179178 def tableName = " test_routine_error_info"
@@ -209,7 +208,7 @@ suite("test_routine_load_error_info","nonConcurrent") {
209208 }
210209
211210 // case 2: reschedule job
212- if (enabled != null && enabled . equalsIgnoreCase( " true " ) ) {
211+ if (kafkaTestEnabled ) {
213212 def jobName = " test_error_info"
214213 def tableName = " test_routine_error_info"
215214 try {
@@ -242,7 +241,7 @@ suite("test_routine_load_error_info","nonConcurrent") {
242241 }
243242
244243 // case 3: memory limit
245- if (enabled != null && enabled . equalsIgnoreCase( " true " ) ) {
244+ if (kafkaTestEnabled ) {
246245 def jobName = " test_memory_limit_error_info"
247246 def tableName = " test_routine_memory_limit_error_info"
248247
@@ -276,4 +275,50 @@ suite("test_routine_load_error_info","nonConcurrent") {
276275 sql " DROP TABLE IF EXISTS ${ tableName} "
277276 }
278277 }
279- }
278+
279+ // case 4: read_committed lag hint
280+ if (kafkaTestEnabled) {
281+ def jobName = " test_read_committed_lag_error_info"
282+ def tableName = " test_routine_read_committed_lag_error_info"
283+ def kafkaTopic = " test_read_committed_lag_error_info_${ System.currentTimeMillis()} "
284+ def debugPoint = " KafkaRoutineLoadJob.hasPositiveLagForTask"
285+
286+ try {
287+ createKafkaTopic(kafkaTopic)
288+ def producer = RoutineLoadTestUtils . createKafkaProducer(kafka_broker)
289+ try {
290+ def txt = new File (""" ${ context.file.parent} /data/${ kafkaCsvTpoics[0]} .csv""" ). text
291+ RoutineLoadTestUtils . sendTestDataToKafka(producer, [kafkaTopic], txt. readLines())
292+ } finally {
293+ producer. close()
294+ }
295+ createTable(tableName)
296+ sql " sync"
297+ GetDebugPoint (). enableDebugPointForAllFEs(debugPoint)
298+ createReadCommittedJob(jobName, tableName, kafkaTopic)
299+ sql " sync"
300+
301+ // check error info
302+ def count = 0
303+ while (true ) {
304+ def res = sql " show routine load for ${ jobName} "
305+ log. info(" show routine load: ${ res[0].toString()} " . toString())
306+ log. info(" other msg: ${ res[0][19].toString()} " . toString())
307+ if (res[0 ][19 ]. toString() != " " ) {
308+ assertTrue (res[0 ][19 ]. toString(). contains(" some records may be in uncommitted transactions" ))
309+ break ;
310+ }
311+ count++
312+ if (count > 60 ) {
313+ assertEquals (1 , 2 )
314+ break ;
315+ }
316+ sleep(1000 )
317+ }
318+ } finally {
319+ GetDebugPoint (). disableDebugPointForAllFEs(debugPoint)
320+ sql " stop routine load for ${ jobName} "
321+ sql " DROP TABLE IF EXISTS ${ tableName} "
322+ }
323+ }
324+ }
0 commit comments