2020package org .apache .iotdb .db .queryengine .execution .fragment ;
2121
2222import org .apache .iotdb .commons .concurrent .IoTDBThreadPoolFactory ;
23+ import org .apache .iotdb .db .conf .IoTDBDescriptor ;
2324import org .apache .iotdb .db .queryengine .common .FragmentInstanceId ;
2425import org .apache .iotdb .db .queryengine .common .PlanFragmentId ;
2526import org .apache .iotdb .db .queryengine .exception .CpuNotEnoughException ;
2930import org .apache .iotdb .db .queryengine .execution .exchange .sink .ISink ;
3031import org .apache .iotdb .db .queryengine .execution .schedule .IDriverScheduler ;
3132import org .apache .iotdb .db .storageengine .dataregion .DataRegion ;
33+ import org .apache .iotdb .db .utils .datastructure .AlignedTVList ;
34+ import org .apache .iotdb .db .utils .datastructure .TVList ;
3235
36+ import com .google .common .collect .ImmutableMap ;
37+ import org .apache .tsfile .enums .TSDataType ;
3338import org .junit .Test ;
3439import org .mockito .Mockito ;
3540
41+ import java .io .ByteArrayOutputStream ;
42+ import java .io .PrintStream ;
43+ import java .util .ArrayList ;
3644import java .util .Collections ;
3745import java .util .List ;
46+ import java .util .concurrent .Executor ;
3847import java .util .concurrent .ExecutorService ;
3948
4049import static org .apache .iotdb .db .queryengine .common .QueryId .MOCK_QUERY_ID ;
4150import static org .apache .iotdb .db .queryengine .execution .fragment .FragmentInstanceContext .createFragmentInstanceContext ;
4251import static org .junit .Assert .assertEquals ;
52+ import static org .junit .Assert .assertFalse ;
4353import static org .junit .Assert .assertTrue ;
4454import static org .junit .Assert .fail ;
4555
@@ -50,32 +60,11 @@ public void testFragmentInstanceExecution() {
5060 ExecutorService instanceNotificationExecutor =
5161 IoTDBThreadPoolFactory .newFixedThreadPool (1 , "test-instance-notification" );
5262 try {
53- IDriverScheduler scheduler = Mockito .mock (IDriverScheduler .class );
54- FragmentInstanceId instanceId =
55- new FragmentInstanceId (new PlanFragmentId (MOCK_QUERY_ID , 0 ), "0" );
56- FragmentInstanceStateMachine stateMachine =
57- new FragmentInstanceStateMachine (instanceId , instanceNotificationExecutor );
58- DataRegion dataRegion = Mockito .mock (DataRegion .class );
59- FragmentInstanceContext fragmentInstanceContext =
60- createFragmentInstanceContext (instanceId , stateMachine );
61- fragmentInstanceContext .initializeNumOfDrivers (1 );
62- fragmentInstanceContext .setMayHaveTmpFile (true );
63- fragmentInstanceContext .setDataRegion (dataRegion );
64- List <IDriver > drivers = Collections .emptyList ();
65- ISink sinkHandle = Mockito .mock (ISink .class );
66- long timeOut = -1 ;
67- MPPDataExchangeManager exchangeManager = Mockito .mock (MPPDataExchangeManager .class );
6863 FragmentInstanceExecution execution =
69- FragmentInstanceExecution .createFragmentInstanceExecution (
70- scheduler ,
71- instanceId ,
72- fragmentInstanceContext ,
73- drivers ,
74- sinkHandle ,
75- stateMachine ,
76- timeOut ,
77- false ,
78- exchangeManager );
64+ createFragmentInstanceExecution (0 , instanceNotificationExecutor );
65+ FragmentInstanceContext fragmentInstanceContext = execution .getFragmentInstanceContext ();
66+ FragmentInstanceStateMachine stateMachine = execution .getStateMachine ();
67+
7968 assertEquals (FragmentInstanceState .RUNNING , execution .getInstanceState ());
8069 FragmentInstanceInfo instanceInfo = execution .getInstanceInfo ();
8170 assertEquals (FragmentInstanceState .RUNNING , instanceInfo .getState ());
@@ -84,7 +73,7 @@ public void testFragmentInstanceExecution() {
8473 assertEquals (fragmentInstanceContext .getFailureInfoList (), instanceInfo .getFailureInfoList ());
8574
8675 assertEquals (fragmentInstanceContext .getStartTime (), execution .getStartTime ());
87- assertEquals (timeOut , execution .getTimeoutInMs ());
76+ assertEquals (- 1 , execution .getTimeoutInMs ());
8877 assertEquals (stateMachine , execution .getStateMachine ());
8978
9079 fragmentInstanceContext .decrementNumOfUnClosedDriver ();
@@ -107,4 +96,112 @@ public void testFragmentInstanceExecution() {
10796 instanceNotificationExecutor .shutdown ();
10897 }
10998 }
99+
100+ @ Test
101+ public void testTVListOwnerTransfer () throws InterruptedException {
102+ // Capture System.err to check for warning messages
103+ PrintStream systemOut = System .out ;
104+ ByteArrayOutputStream logPrint = new ByteArrayOutputStream ();
105+ System .setOut (new PrintStream (logPrint ));
106+
107+ try {
108+ IoTDBDescriptor .getInstance ().getConfig ().setDataNodeId (1 );
109+
110+ ExecutorService instanceNotificationExecutor =
111+ IoTDBThreadPoolFactory .newFixedThreadPool (1 , "test-instance-notification" );
112+ try {
113+ // TVList
114+ TVList tvList = buildTVList ();
115+
116+ // FragmentInstance Context & Execution
117+ FragmentInstanceExecution execution1 =
118+ createFragmentInstanceExecution (1 , instanceNotificationExecutor );
119+ FragmentInstanceContext fragmentInstanceContext1 = execution1 .getFragmentInstanceContext ();
120+ fragmentInstanceContext1 .addTVListToSet (ImmutableMap .of (tvList , 0 ));
121+ tvList .getQueryContextSet ().add (fragmentInstanceContext1 );
122+
123+ FragmentInstanceExecution execution2 =
124+ createFragmentInstanceExecution (2 , instanceNotificationExecutor );
125+ FragmentInstanceContext fragmentInstanceContext2 = execution2 .getFragmentInstanceContext ();
126+ fragmentInstanceContext2 .addTVListToSet (ImmutableMap .of (tvList , 0 ));
127+ tvList .getQueryContextSet ().add (fragmentInstanceContext2 );
128+
129+ // mock flush's behavior
130+ fragmentInstanceContext1
131+ .getMemoryReservationContext ()
132+ .reserveMemoryCumulatively (tvList .calculateRamSize ());
133+ tvList .setOwnerQuery (fragmentInstanceContext1 );
134+
135+ fragmentInstanceContext1 .decrementNumOfUnClosedDriver ();
136+ fragmentInstanceContext2 .decrementNumOfUnClosedDriver ();
137+
138+ fragmentInstanceContext1 .getStateMachine ().finished ();
139+ Thread .sleep (100 );
140+ fragmentInstanceContext2 .getStateMachine ().finished ();
141+
142+ assertTrue (execution1 .getInstanceState ().isDone ());
143+ assertTrue (execution2 .getInstanceState ().isDone ());
144+ Thread .sleep (100 );
145+ } catch (CpuNotEnoughException | MemoryNotEnoughException | IllegalArgumentException e ) {
146+ fail (e .getMessage ());
147+ } finally {
148+ instanceNotificationExecutor .shutdown ();
149+ }
150+ } finally {
151+ // Restore original System.out
152+ System .setErr (systemOut );
153+
154+ // should not contain warn message: "The memory cost to be released is larger than the memory
155+ // cost of memory block"
156+ String capturedOutput = logPrint .toString ();
157+ assertFalse (
158+ "Should not contain warning message" ,
159+ capturedOutput .contains ("The memory cost to be released is larger than the memory" ));
160+ }
161+ }
162+
163+ private FragmentInstanceExecution createFragmentInstanceExecution (int id , Executor executor )
164+ throws CpuNotEnoughException {
165+ IDriverScheduler scheduler = Mockito .mock (IDriverScheduler .class );
166+ FragmentInstanceId instanceId =
167+ new FragmentInstanceId (new PlanFragmentId (MOCK_QUERY_ID , id ), String .valueOf (id ));
168+ FragmentInstanceStateMachine stateMachine =
169+ new FragmentInstanceStateMachine (instanceId , executor );
170+ DataRegion dataRegion = Mockito .mock (DataRegion .class );
171+ FragmentInstanceContext fragmentInstanceContext =
172+ createFragmentInstanceContext (instanceId , stateMachine );
173+ fragmentInstanceContext .initializeNumOfDrivers (1 );
174+ fragmentInstanceContext .setMayHaveTmpFile (true );
175+ fragmentInstanceContext .setDataRegion (dataRegion );
176+ List <IDriver > drivers = Collections .emptyList ();
177+ ISink sinkHandle = Mockito .mock (ISink .class );
178+ long timeOut = -1 ;
179+ MPPDataExchangeManager exchangeManager = Mockito .mock (MPPDataExchangeManager .class );
180+ return FragmentInstanceExecution .createFragmentInstanceExecution (
181+ scheduler ,
182+ instanceId ,
183+ fragmentInstanceContext ,
184+ drivers ,
185+ sinkHandle ,
186+ stateMachine ,
187+ timeOut ,
188+ false ,
189+ exchangeManager );
190+ }
191+
192+ private TVList buildTVList () {
193+ int columns = 200 ;
194+ int rows = 1000 ;
195+ List <TSDataType > dataTypes = new ArrayList <>();
196+ Object [] values = new Object [columns ];
197+ for (int i = 0 ; i < columns ; i ++) {
198+ dataTypes .add (TSDataType .INT64 );
199+ values [i ] = 1L ;
200+ }
201+ AlignedTVList tvList = AlignedTVList .newAlignedList (dataTypes );
202+ for (long t = 1 ; t < rows ; t ++) {
203+ tvList .putAlignedValue (t , values );
204+ }
205+ return tvList ;
206+ }
110207}
0 commit comments