1+ #!/usr/bin/env node
2+ 
3+ const  {  execSync }  =  require ( 'child_process' ) ; 
4+ 
5+ function  runCommand ( command )  { 
6+   try  { 
7+     const  output  =  execSync ( command ,  {  encoding : 'utf8' ,  stdio : 'pipe'  } ) ; 
8+     console . log ( output ) ; 
9+     return  output ; 
10+   }  catch  ( error )  { 
11+     const  errorOutput  =  error . stdout  ||  error . stderr  ||  error . message ; 
12+     console . log ( errorOutput ) ; 
13+     return  errorOutput ; 
14+   } 
15+ } 
16+ 
17+ function  extractValue ( content ,  pattern )  { 
18+   try  { 
19+     const  lines  =  content . split ( '\n' ) ; 
20+     const  matchingLine  =  lines . find ( line  =>  line . includes ( pattern ) ) ; 
21+     if  ( matchingLine )  { 
22+       const  value  =  matchingLine . split ( ':' ) [ 1 ] ?. trim ( ) ; 
23+       return  value  ||  '' ; 
24+     } 
25+     return  '' ; 
26+   }  catch  ( error )  { 
27+     return  '' ; 
28+   } 
29+ } 
30+ 
31+ function  compareNumbers ( a ,  b ,  threshold  =  0.7 )  { 
32+   const  numA  =  parseFloat ( a ) ; 
33+   const  numB  =  parseFloat ( b ) ; 
34+   if  ( isNaN ( numA )  ||  isNaN ( numB ) )  return  false ; 
35+   return  numA  <  ( numB  *  threshold ) ; 
36+ } 
37+ 
38+ function  isBelow ( value ,  target )  { 
39+   const  numValue  =  parseFloat ( value ) ; 
40+   const  numTarget  =  parseFloat ( target ) ; 
41+   if  ( isNaN ( numValue )  ||  isNaN ( numTarget ) )  return  false ; 
42+   return  numValue  <  numTarget ; 
43+ } 
44+ 
45+ // Run performance tests and store outputs in memory 
46+ console . log ( 'Running Confluent Producer/Consumer test...' ) ; 
47+ const  outputConfluentProducerConsumer  =  runCommand ( 'MODE=confluent MESSAGE_COUNT=50000 node performance-consolidated.js --create-topics --consumer --producer' ) ; 
48+ 
49+ console . log ( 'Running KafkaJS Producer/Consumer test...' ) ; 
50+ const  outputKjsProducerConsumer  =  runCommand ( 'MODE=kafkajs MESSAGE_COUNT=50000 node performance-consolidated.js --create-topics --consumer --producer' ) ; 
51+ 
52+ console . log ( 'Running Confluent CTP test...' ) ; 
53+ const  outputConfluentCtp  =  runCommand ( 'MODE=confluent MESSAGE_COUNT=5000 node performance-consolidated.js --create-topics --ctp' ) ; 
54+ 
55+ console . log ( 'Running KafkaJS CTP test...' ) ; 
56+ const  outputKjsCtp  =  runCommand ( 'MODE=kafkajs MESSAGE_COUNT=5000 node performance-consolidated.js --create-topics --ctp' ) ; 
57+ 
58+ // Extract Confluent results 
59+ const  producerConfluent  =  extractValue ( outputConfluentProducerConsumer ,  '=== Producer Rate:' ) ; 
60+ const  consumerConfluentMessage  =  extractValue ( outputConfluentProducerConsumer ,  '=== Consumer Rate (eachMessage):' ) ; 
61+ const  consumerConfluentTime  =  extractValue ( outputConfluentProducerConsumer ,  '=== Consumption time (eachMessage):' ) ; 
62+ const  consumerConfluentBatch  =  extractValue ( outputConfluentProducerConsumer ,  '=== Consumer Rate (eachBatch):' ) ; 
63+ const  consumerConfluentBatchTime  =  extractValue ( outputConfluentProducerConsumer ,  '=== Consumption time (eachBatch):' ) ; 
64+ const  consumerConfluentBatchAverageLag  =  extractValue ( outputConfluentProducerConsumer ,  '=== Average eachBatch lag:' ) ; 
65+ const  consumerConfluentBatchMaxLag  =  extractValue ( outputConfluentProducerConsumer ,  '=== Max eachBatch lag:' ) ; 
66+ const  consumerConfluentAverageRSS  =  extractValue ( outputConfluentProducerConsumer ,  '=== Max Average RSS across tests:' ) ; 
67+ const  consumerConfluentMaxRSS  =  extractValue ( outputConfluentProducerConsumer ,  '=== Max RSS across tests:' ) ; 
68+ const  ctpConfluent  =  extractValue ( outputConfluentCtp ,  '=== Consume-Transform-Produce Rate:' ) ; 
69+ 
70+ // Extract KafkaJS results 
71+ const  producerKjs  =  extractValue ( outputKjsProducerConsumer ,  '=== Producer Rate:' ) ; 
72+ const  consumerKjsMessage  =  extractValue ( outputKjsProducerConsumer ,  '=== Consumer Rate (eachMessage):' ) ; 
73+ const  consumerKjsTime  =  extractValue ( outputKjsProducerConsumer ,  '=== Consumption time (eachMessage):' ) ; 
74+ const  consumerKjsBatch  =  extractValue ( outputKjsProducerConsumer ,  '=== Consumer Rate (eachBatch):' ) ; 
75+ const  consumerKjsBatchTime  =  extractValue ( outputKjsProducerConsumer ,  '=== Consumption time (eachBatch):' ) ; 
76+ const  consumerKjsBatchAverageLag  =  extractValue ( outputKjsProducerConsumer ,  '=== Average eachBatch lag:' ) ; 
77+ const  consumerKjsBatchMaxLag  =  extractValue ( outputKjsProducerConsumer ,  '=== Max eachBatch lag:' ) ; 
78+ const  consumerKjsAverageRSS  =  extractValue ( outputKjsProducerConsumer ,  '=== Max Average RSS across tests:' ) ; 
79+ const  consumerKjsMaxRSS  =  extractValue ( outputKjsProducerConsumer ,  '=== Max RSS across tests:' ) ; 
80+ const  ctpKjs  =  extractValue ( outputKjsCtp ,  '=== Consume-Transform-Produce Rate:' ) ; 
81+ 
82+ // Print results 
83+ console . log ( `Producer rates: confluent ${ producerConfluent }  , kafkajs ${ producerKjs }  ` ) ; 
84+ console . log ( `Consumer rates (eachMessage): confluent ${ consumerConfluentMessage }  , kafkajs ${ consumerKjsMessage }  ` ) ; 
85+ console . log ( `Consumption time (eachMessage): confluent ${ consumerConfluentTime }  , kafkajs ${ consumerKjsTime }  ` ) ; 
86+ console . log ( `Consumer rates (eachBatch): confluent ${ consumerConfluentBatch }  , kafkajs ${ consumerKjsBatch }  ` ) ; 
87+ console . log ( `Consumption time (eachBatch): confluent ${ consumerConfluentBatchTime }  , kafkajs ${ consumerKjsBatchTime }  ` ) ; 
88+ console . log ( `Average eachBatch lag: confluent ${ consumerConfluentBatchAverageLag }  , kafkajs ${ consumerKjsBatchAverageLag }  ` ) ; 
89+ console . log ( `Max eachBatch lag: confluent ${ consumerConfluentBatchMaxLag }  , kafkajs ${ consumerKjsBatchMaxLag }  ` ) ; 
90+ console . log ( `Average RSS: confluent ${ consumerConfluentAverageRSS }  , kafkajs ${ consumerKjsAverageRSS }  ` ) ; 
91+ console . log ( `Max RSS: confluent ${ consumerConfluentMaxRSS }  , kafkajs ${ consumerKjsMaxRSS }  ` ) ; 
92+ console . log ( `CTP rates: confluent ${ ctpConfluent }  , kafkajs ${ ctpKjs }  ` ) ; 
93+ 
94+ let  errcode  =  0 ; 
95+ const  maxPerformanceDifference  =  0.7 ; 
96+ 
97+ // Compare against KJS (30% threshold) 
98+ if  ( compareNumbers ( producerConfluent ,  producerKjs ,  maxPerformanceDifference ) )  { 
99+   console . log ( `Producer rates differ by more than 30%: confluent ${ producerConfluent }  , kafkajs ${ producerKjs }  ` ) ; 
100+   errcode  =  1 ; 
101+ } 
102+ 
103+ if  ( compareNumbers ( consumerConfluentMessage ,  consumerKjsMessage ,  maxPerformanceDifference ) )  { 
104+   console . log ( `Consumer rates (eachMessage) differ by more than 30%: confluent ${ consumerConfluentMessage }  , kafkajs ${ consumerKjsMessage }  ` ) ; 
105+   // FIXME: improve consumer performance at least to KafkaJS level 
106+   errcode  =  0 ; 
107+ } 
108+ 
109+ // Lower is better for time 
110+ if  ( compareNumbers ( consumerKjsTime ,  consumerConfluentTime ,  maxPerformanceDifference ) )  { 
111+   console . log ( `Consumption time (eachMessage) differ by more than 30%: confluent ${ consumerConfluentTime }  , kafkajs ${ consumerKjsTime }  ` ) ; 
112+   errcode  =  0 ; 
113+ } 
114+ 
115+ if  ( compareNumbers ( consumerConfluentBatch ,  consumerKjsBatch ,  maxPerformanceDifference ) )  { 
116+   console . log ( `Consumer rates (eachBatch) differ by more than 30%: confluent ${ consumerConfluentBatch }  , kafkajs ${ consumerKjsBatch }  ` ) ; 
117+   errcode  =  0 ; 
118+ } 
119+ 
120+ // Lower is better for time 
121+ if  ( compareNumbers ( consumerKjsBatchTime ,  consumerConfluentBatchTime ,  maxPerformanceDifference ) )  { 
122+   console . log ( `Consumption time (eachBatch) differ by more than 30%: confluent ${ consumerConfluentBatchTime }  , kafkajs ${ consumerKjsBatchTime }  ` ) ; 
123+   errcode  =  0 ; 
124+ } 
125+ 
126+ if  ( compareNumbers ( ctpConfluent ,  ctpKjs ,  maxPerformanceDifference ) )  { 
127+   console . log ( `CTP rates differ by more than 30%: confluent ${ ctpConfluent }  , kafkajs ${ ctpKjs }  ` ) ; 
128+   errcode  =  1 ; 
129+ } 
130+ 
131+ // Compare against target numbers 
132+ const  TARGET_PRODUCE  =  process . env . TARGET_PRODUCE_PERFORMANCE  ||  '35' ; 
133+ const  TARGET_CONSUME  =  process . env . TARGET_CONSUME_PERFORMANCE  ||  '18' ; 
134+ const  TARGET_CTP  =  process . env . TARGET_CTP_PERFORMANCE  ||  '0.02' ; 
135+ 
136+ if  ( isBelow ( producerConfluent ,  TARGET_PRODUCE ) )  { 
137+   console . log ( `Confluent producer rate is below target: ${ producerConfluent }  ` ) ; 
138+   errcode  =  1 ; 
139+ } 
140+ 
141+ if  ( isBelow ( consumerConfluentMessage ,  TARGET_CONSUME ) )  { 
142+   console . log ( `Confluent consumer rate is below target: ${ consumerConfluentMessage }  ` ) ; 
143+   errcode  =  1 ; 
144+ } 
145+ 
146+ if  ( isBelow ( ctpConfluent ,  TARGET_CTP ) )  { 
147+   console . log ( `Confluent CTP rate is below target: ${ ctpConfluent }  ` ) ; 
148+   errcode  =  1 ; 
149+ } 
150+ 
151+ process . exit ( errcode ) ; 
0 commit comments