[ 
https://issues.apache.org/jira/browse/IOTDB-1559?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17397930#comment-17397930
 ] 

Irvine commented on IOTDB-1559:
-------------------------------

It's my fault that didn't make it clear.

> What is the difference between different execution configurations in the pom 
> file? 

In this example, the difference is in section systemPropertyVariables. We set 
<TestEnv>FiveNodeCluster1</TestEnv> in execution 
"integration-test-FiveNodeCluster1IT", and we set 
<TestEnv>FiveNodeCluster2</TestEnv> in execution 
"integration-test-FiveNodeCluster2IT". By passed to Java code, there will be 
different test environments for each execution.

We can also set other sections for every execution, each execution 
configuration is independent, they will run one by one in the maven's 
integration phase. 
For example, we can run test cases of SingleNodeTest's category in OneNodeEnv 
and then run test cases of ClusterTest's category in ThreeNodeClusterEnv and 
then run test cases of ClusterTest's category in FiveNodeClusterEnv.

> Though it is just an example, but what can we benefit from two executions 
> "integration-test-FiveNodeCluster1IT" and 
> "integration-test-FiveNodeCluster2IT" ?

I think the benefit is decoupling and reusing.  Now in the testcontainer 
module,  every environment IT all inherit from the base cases class, but java 
does not support multiple inheritances, so the base cases class will be only 
one, and the IT case from the server module can't be reused in the 
testcontainer environment. With maven execution and category annotation, we can 
decouple the environment from IT cases. We can write IT cases in several 
modules, and we can write environment classes based on the TestEnv interface. 
Finally, IT cases and environment classes are connected by maven.



> Thoughts on reusing the IT cases
> --------------------------------
>
>                 Key: IOTDB-1559
>                 URL: https://issues.apache.org/jira/browse/IOTDB-1559
>             Project: Apache IoTDB
>          Issue Type: Improvement
>            Reporter: Irvine
>            Assignee: Irvine
>            Priority: Major
>
> - Background
> Today iotdb has many IT cases, some are in the server module, some are in the 
> cluster module, and some cluster test cases are in the testcontainer module.
> The test case structure causes developers to sometimes write test cases 
> repeatedly to ensure running correctly of the single-node mode and the 
> cluster mode.
>  - Suggestion
> At present, the test cases of single-node mode and cluster mode are 
> separated, but they have intersections, and they can be classified for reuse 
> by using JUnit's category annotation.
> In the testcontainer module, test cases are based on the test environment, 
> but the test environment is relatively fixed, we can use maven to configure 
> multiple environments to test the classified test cases.
>  - Example
>  * The pom.xml of testcontainer module
> {code:xml}
> <plugin>
>     <groupId>org.apache.maven.plugins</groupId>
>     <artifactId>maven-failsafe-plugin</artifactId>
>     <executions>
>         <execution>
>             <id>integration-test-FiveNodeCluster1IT</id>
>             <goals>
>                 <goal>integration-test</goal>
>             </goals>
>             <configuration>
>                 
> <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
>                 
> <testSourceDirectory>${basedir}/../server/src/test/java/org/apache/iotdb/db/integration</testSourceDirectory>
>                 <groups>${test.includedGroups}</groups>
>                 <excludedGroups>${test.excludedGroups}</excludedGroups>
>                 <useSystemClassLoader>false</useSystemClassLoader>
>                 <threadCount>1</threadCount>
>                 <forkCount>1</forkCount>
>                 <reuseForks>false</reuseForks>
>                 <systemPropertyVariables>
>                     <TestEnv>FiveNodeCluster1</TestEnv>
>                 </systemPropertyVariables>
>                 
> <summaryFile>target/failsafe-reports/failsafe-summary-FiveNodeCluster1IT.xml</summaryFile>
>             </configuration>
>         </execution>
>         <execution>
>             <id>integration-test-FiveNodeCluster2IT</id>
>             <goals>
>                 <goal>integration-test</goal>
>             </goals>
>             <configuration>
>                 
> <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
>                 
> <testSourceDirectory>${basedir}/../server/src/test/java/org/apache/iotdb/db/integration</testSourceDirectory>
>                 <groups>${test.includedGroups}</groups>
>                 <excludedGroups>${test.excludedGroups}</excludedGroups>
>                 <useSystemClassLoader>false</useSystemClassLoader>
>                 <threadCount>1</threadCount>
>                 <forkCount>1</forkCount>
>                 <reuseForks>false</reuseForks>
>                 <systemPropertyVariables>
>                     <TestEnv>FiveNodeCluster2</TestEnv>
>                 </systemPropertyVariables>
>                 
> <summaryFile>target/failsafe-reports/failsafe-summary-FiveNodeCluster2IT.xml</summaryFile>
>             </configuration>
>         </execution>
>         <execution>
>             <id>verify</id>
>             <goals>
>                 <goal>verify</goal>
>             </goals>
>             <configuration>
>                 <summaryFiles>
>                     
> <summaryFile>target/failsafe-reports/failsafe-summary-FiveNodeCluster1IT.xml</summaryFile>
>                     
> <summaryFile>target/failsafe-reports/failsafe-summary-FiveNodeCluster2IT.xml</summaryFile>
>                 </summaryFiles>
>             </configuration>
>         </execution>
>     </executions>
> </plugin>
> {code}
> We configure multiple environments by section 
> {color:#0747a6}<executions>{color}, it will like:
>  {color:#0747a6}<executions>{color}
>  {color:#0747a6}  <execution>...the first env...</execution>{color}
>  {color:#0747a6}  <execution>...the second env...</execution>{color}
>  {color:#0747a6} </executions>{color} 
>  It can run multiple environments in one "mvn verify" cmd.
> In each execution, we configure {color:#0747a6}<testSourceDirectory>{color} 
> for the dir of IT case which can from different modules, 
>  {color:#0747a6}<groups>{color} for the category of IT case that can invoke 
> the IT case with JUnit's category annotation, 
>  and {color:#0747a6}<systemPropertyVariables>{color} to pass parameters, 
> which can get by java code, to choose the init environment class.
>  * IT case example
> {code:java}
> public class TestCategoryIT {
>   private static String[] sqls =
>       new String[] {
>         "CREATE TIMESERIES root.sg1.d1.s1 with datatype=INT32,encoding=RLE",
>         "CREATE TIMESERIES root.sg1.d1.s1.s1 with 
> datatype=INT32,encoding=RLE",
>         "CREATE TIMESERIES root.sg1.d1.s1.s2 with datatype=INT32,encoding=RLE"
>       };
>   @BeforeClass
>   public static void setUp() throws Exception {
>     ExampleEnvUtil.init();
>     insertData();
>   }
>   @AfterClass
>   public static void tearDown() throws Exception {
>     ExampleEnvUtil.clean();
>   }
>   private static void insertData() {
>     try (Connection connection = ExampleEnvUtil.getConnection();
>         Statement statement = connection.createStatement()) {
>       for (String sql : sqls) {
>         statement.execute(sql);
>       }
>     } catch (Exception e) {
>       e.printStackTrace();
>     }
>   }
>   @Test
>   @Category({SingleNodeTest.class, ClusterTest.class})
>   public void test1() throws ClassNotFoundException {
>     try (Connection connection = ExampleEnvUtil.getConnection();
>         Statement statement = connection.createStatement()) {
>       ...
>     } catch (Exception e) {
>       e.printStackTrace();
>     }
>     ...
>   }
>   @Test
>   @Category(SingleNodeTest.class)
>   public void test2() throws ClassNotFoundException {
>     ...
>   }
>   @Test
>   @Category(ClusterTest.class)
>   public void test3() throws ClassNotFoundException {
>     ...
>   }
> }
> {code}
> All we change is:
>  to add Category annotation for test or class, 
>  to change the connection of every case to assign by 
> ExampleEnvUtil.getConnection(), which depend on parameters passed by maven, 
>  and to use the external init and clean code in the setUp and tearDown 
> method, which also depends on parameters passed by maven.
>  * ExampleEnvUtil.java
> It invokes the interface method depends on parameters passed by maven. It has 
> many implement way. I can give a very simple way.
> {code:java}
> public class ExampleEnvUtil {
>   private static TestEnv env;
>   static {
>     switch (System.getProperty("TestEnv", "FiveNodeCluster")) {
>       case "FiveNodeCluster":
>         env = new CusterEnv();
>         break;
>     }
>   }
>   public static void init() throws InterruptedException {
>     env.init();
>   }
>   public static void clean() {
>     env.clean();
>   }
>   public static Connection getConnection() throws SQLException, 
> ClassNotFoundException {
>     return env.getConnection();
>   }
> }
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to