You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by GitBox <gi...@apache.org> on 2020/02/24 11:52:24 UTC

[GitHub] [incubator-shardingsphere] menghaoranss commented on issue #4438: Orchestration unit test development guide for new contributors

menghaoranss commented on issue #4438: Orchestration unit test development guide for new contributors
URL: https://github.com/apache/incubator-shardingsphere/issues/4438#issuecomment-590284904
 
 
   以下是对于新贡献者的一些提示信息。
   
   ### 环境准备
   
   Apache ShardingSphere 是基于Java平台的,所以你需要相关的环境工具:
   
   - JDK8版本,
   - Java开发工具IDE,推荐IDEA或Eclipse,安装lombok插件
   - Git,或者IDE里集成的git
   - Maven3.5
   
   如果本地运行Sharding-Proxy,还需要:
   
   - MySQL 5.6 或 5.7 server,如果要验证PostGreSQL或其他数据库相关功能,需要安装对应的数据库软件。
   - Zookeeper 3.5.6 或其他版本,如果要验证Apollo或Nacos的配置中心,也需要安装对应的软件。
   
   如果要调试和运行UI相关项目,需要安装:
   
   - Node 8.11.1以上版本以及对应的NPM 5.6.0以上版本。
   
   ### 项目说明
   
   #### 下载源码
   
   项目地址:https://github.com/apache/incubator-shardingsphere
   
   #### 源码说明
   
   源码包括以下几个部分:
   
   - 主项目:SQL Engine,Sharding-jdbc,Sharding-proxy,Orchestration等等
   
   - ShardingSphere-UI:frontend(NodeJS/VUE),backend(Java)
   
   - doc项目:文档,同时也是官方网站。需要使用基于go的Hugo工具编译成静态内容。
   - examples项目:使用示例。
   
   #### 分支说明
   
   我们提倡在专用分支上进行修改和提交,最后通过PR(Pull Request)方式要求合并到主干。
   
   目前apache/incubator-shardingsphere的主干是master,版本为5.0.0-RC[N]-SNAPSHOT。
   
   还有一个4.0.1的分支是在维护中的4.x版本,目前发布的最新版本是4.0.0,(注意,不是4.0.0-RC3)。整个官网和文档,都是基于这个版本的。
   
   新拉了一个doc5.x的分支,为了重新编写5.x的文档,以及生成新版本的网站。
   
   > 完善单元测试的工作,可以直接PR到master上。
   
   ##### 克隆项目
   
   首先,你需要在github上,点击右上角的star,为项目增加一个星。
   
   然后,点击fork,这样就会在你的id路径下,产生一个新的复制版本。
   
   例如,我的就是:
   
   > https://github.com/kimmking/incubator-shardingsphere
   
   ##### 下载源码
   
   目前如果从github整个项目 git clone下来,大概240M,(因为要下载所有的提交记录)。
   
   可以使用以下方式将首次下载数据降低到20M:
   
   > git clone https://github.com/{你的id}/incubator-shardingsphere --depth 1
   
   这样只会保留最后2次提交记录,和当前的源码。
   
   这时你的当前目录会生成一个新的文件夹incubator-shardingsphere,这里面就是整个项目源码。
   
   你可以通过以下命令看当前的分支:
   
   > git branch -vv
   
   带星号的就是当前分支。
   
   ##### 添加远程分支
   
   然后我们可以通过命令
   
   > git remote add apache https://github.com/apache/incubator-shardingsphere
   
   将apache下的项目添加为我们的一个远程项目。
   
   后面可以使用
   
   > git fetch apache master:amaster
   
   将apache/master远程分支,拉倒本地成为一个叫amaster的新分支。
   
   也可以使用
   
   > git checkout -b bmaster
   
   从当前分支拉一个新的叫bmaster的分支。
   
   然后我们可以在这个分支上进行修改和调试。
   
   修改完成以后,可以通过
   
   > git add .
   >
   > git commit -a
   
   来提交修改。
   
   最后我们可以通过
   
   > git push 
   
   或者按照提示,使用set-upstream的方式,将本地新分支push到我们自己空间的远程同名分支。
   
   ##### 提交PR
   
   此时我们就可以在github上提交PR了。
   
   将我们的分支,PR到apache/master分支上。
   
   #### 编译说明
   
   我们一般用
   
   > mvn clean package install
   
   来编译项目。
   
   也可以使用
   
   >  mvn clean package install -Prelease
   
   来打包项目。
   
   ##### 代码风格
   
   由于目前为了兼容前面的版本,整个项目编译级别一直为Java1.7,所以Java8的类和特性,目前不能使用,例如LocalDatetime或者Stream API等。
   
   整个项目需要编译时执行checkstyle,代码规范在checkstyle规则里约定。例如:
   
   - 不能引入未使用的import
   - 在公开的方法和类上必须添加javadoc,且第一句大写开头,英文句号结尾
   - 缩进使用4个空格,所以我们可以把IDE里显示空格选项打开
   - 逗号后需要有空格
   - if等语句以后需要有空格
   - 文件最后保留一个空行
   - 方法内不允许空行
   
   有些是需要单元测试代码一样遵守的。
   
   ##### 编译时间
   
   目前整个项目编译大概需要22分钟所有。
   
   可以通过一些技巧,减少这个时间。
   
   ##### 依赖下载
   
   我们的项目使用maven下载依赖,如果你的机器访问maven中央库较慢,可以考虑配置使用国内的aliyun镜像。具体方法可以网上搜索。
   
   如果当天第一次下载了依赖性,后续可以使用原有的下载,需要在mvn参数里加`- o`表示离线编译。
   
   对于UI项目,可以先在本地安装NodeJS环境,然后使用cnpm代替原来的npm命令。能减少2/3的编译时间。
   
   ##### 任务分支
   
   建议每次为一个项目,从apache/master上新拉一个专用分支,名称为这个项目的名称,比如我常用的`issue3402` 或者 `config-path-resolver` 之类的。
   
   因为主干一直在变化,有其他伙伴在不断的维护和提交,如果自己的任务分支没有在新拉分支的当天提交,建议第二天开始修改之前,先拉一边apache/master,并将其同步到自己的任务分支,及早发现冲突问题,保证自己的分支是随时可以跟主干合并的。参考如下命令:
   
   > git checkout amaster
   >
   > git pull
   >
   > git checkout issue3402
   >
   > git merge amaster
   
   任务完成后(即PR以及被merge到apache/master),可以直接删除掉分支:
   
   >  git branch -D issue3402
   
   #### 持续集成
   
   目前项目里使用了两个持续集成,一个是apache jenkins,一个是travis-ci,都是在apache/incubator-shardingsphere有PR提交时自动触发的。
   
   因为环境的关系,如果其中有一个报错不用慌张,有一个成功一般就可以了,否则看详细日志进行排查。
   
   ### 单元测试DEMO
   
   #### 示例一
   
   开发工具以IDEA为例,为以下类编写单元测试:
   
   `org.apache.shardingsphere.orchestration.center.yaml.swapper.OrchestrationConfigurationYamlSwapper`
   
   + 在IDEA中使用快捷键 Ctrl+Shift+T 为当前类添加单元测试类,测试类名默认如 `OrchestrationConfigurationYamlSwapperTest`
   
   + 覆盖类中自己编写的方法,如以上类中有2个方法
   
     ```java
     /**
          * Swap from InstanceConfiguration to YamlInstanceConfiguration.
          *
          * @param data data to be swapped
          * @return YAML instance configuration
          */
         @Override
         public YamlOrchestrationConfiguration swap(final OrchestrationConfiguration data) {
             Map<String, YamlInstanceConfiguration> yamlInstanceConfigurationMap = new HashMap();
             Map<String, InstanceConfiguration> instanceConfigurationMap = data.getInstanceConfigurationMap();
             for (Entry<String, InstanceConfiguration> each : instanceConfigurationMap.entrySet()) {
                 InstanceConfigurationYamlSwapper swapper = new InstanceConfigurationYamlSwapper();
                 yamlInstanceConfigurationMap.put(each.getKey(), swapper.swap(each.getValue()));
             }
             YamlOrchestrationConfiguration result = new YamlOrchestrationConfiguration();
             result.setInstanceConfigurationMap(yamlInstanceConfigurationMap);
             return result;
         }
         
         /**
          * Swap from YamlInstanceConfiguration to InstanceConfiguration.
          *
          * @param yamlConfiguration YAML instance configuration
          * @return swapped object
          */
         @Override
         public OrchestrationConfiguration swap(final YamlOrchestrationConfiguration yamlConfiguration) {
             Map<String, InstanceConfiguration> instanceConfigurationMap = new HashMap();
             Map<String, YamlInstanceConfiguration> yamlInstanceConfigurationMap = yamlConfiguration.getInstanceConfigurationMap();
             for (Entry<String, YamlInstanceConfiguration> each : yamlInstanceConfigurationMap.entrySet()) {
                 InstanceConfigurationYamlSwapper swapper = new InstanceConfigurationYamlSwapper();
                 instanceConfigurationMap.put(each.getKey(), swapper.swap(each.getValue()));
             }
             OrchestrationConfiguration result = new OrchestrationConfiguration(instanceConfigurationMap);
             return result;
         }
     ```
   
   + 单元测试方法名以assert开头,尽量能清楚描述此方法测试的内容,测试代码需遵循代码规范,并尽量保证覆盖,以上类单元测试方法如下:
   
     ```java
     	@Test
         public void assertSwapToYamlOrchestrationConfiguration() {
             OrchestrationConfiguration data = getOrchestrationConfiguration();
             YamlOrchestrationConfiguration result = new OrchestrationConfigurationYamlSwapper().swap(data);
             for (String each : result.getInstanceConfigurationMap().keySet()) {
                 assertNotNull(result.getInstanceConfigurationMap().get(each));
                 assertThat(result.getInstanceConfigurationMap().get(each).getOrchestrationType(),
                         is(data.getInstanceConfigurationMap().get(each).getOrchestrationType()));
                 assertThat(result.getInstanceConfigurationMap().get(each).getInstanceType(),
                         is(data.getInstanceConfigurationMap().get(each).getType()));
                 assertThat(result.getInstanceConfigurationMap().get(each).getNamespace(),
                         is(data.getInstanceConfigurationMap().get(each).getNamespace()));
                 assertThat(result.getInstanceConfigurationMap().get(each).getServerLists(),
                         is(data.getInstanceConfigurationMap().get(each).getServerLists()));
                 assertThat(result.getInstanceConfigurationMap().get(each).getProps(),
                         is(data.getInstanceConfigurationMap().get(each).getProperties()));
             }
         }
         
         @Test
         public void assertSwapToOrchestrationConfiguration() {
             YamlOrchestrationConfiguration data = getYamlOrchestrationConfiguration();
             OrchestrationConfiguration result = new OrchestrationConfigurationYamlSwapper().swap(data);
             for (String each : result.getInstanceConfigurationMap().keySet()) {
                 assertNotNull(result.getInstanceConfigurationMap().get(each));
                 assertThat(result.getInstanceConfigurationMap().get(each).getOrchestrationType(),
                         is(data.getInstanceConfigurationMap().get(each).getOrchestrationType()));
                 assertThat(result.getInstanceConfigurationMap().get(each).getType(),
                         is(data.getInstanceConfigurationMap().get(each).getInstanceType()));
                 assertThat(result.getInstanceConfigurationMap().get(each).getNamespace(),
                         is(data.getInstanceConfigurationMap().get(each).getNamespace()));
                 assertThat(result.getInstanceConfigurationMap().get(each).getServerLists(),
                         is(data.getInstanceConfigurationMap().get(each).getServerLists()));
                 assertThat(result.getInstanceConfigurationMap().get(each).getProperties(),
                         is(data.getInstanceConfigurationMap().get(each).getProps()));
             }
         }
     ```
   
   + 了解详细开发规范请参考[ShardingShphere开发规范](https://shardingsphere.apache.org/community/cn/contribute/code-conduct/)
   
   
   
   ### 其他
   
   欢迎大家贡献代码和文档,期间有任何问题,都可以随时在issue board或群里交流。
   
   最后,祝大家有一个愉快的ShardingSphere之旅。
   
   
   
   :)

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services