ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Sonarqube - 정적 분석, Coverage
    기록해야 기억한다/OSS(Open Source Software) 2020. 12. 1. 14:40
    SMALL

    코드 품질의 확보

    흔히 지속적인 코드 품질을 확보하기 위해서는 시큐어 코딩(Secure Coding) 이란 명명아래 소스 코드에 존재할 수 있는 잠재적인 불안요소(보안 취약점)를 제거하나, 그런 것들을 고려하여 기능을 설계 및 구현하는 등의 행위가 확보되어야 한다. 

     

    미국은 일찍이 시큐어 코딩을 의무화했고, 우리나라도 2012년부터 의무제로 시행되어 공공기관의 정보화 사업 중 일부를 대상으로 시행되고 있다. 

     

    https://owasp.org/#

     

    OWASP Foundation | Open Source Foundation for Application Security

    OWASP Foundation, the Open Source Foundation for Application Security on the main website for The OWASP Foundation. OWASP is a nonprofit foundation that works to improve the security of software.

    owasp.org

    OWASP(Open Web Application Security Project) 에서 매해 웹 어플리케이션의 취약점에 대한 리뷰를 하고 가이드를 배포한다. 이를 기준으로 저마다의 rule-set 을 만들고 그에 따른 보안기준으로 코드를 점검하는데 아래는 국가에서 가이드되는 소프트웨어 개발보안 가이드, 공개SW를 활용한 소프트웨어 개발보안 점검가이드이다.

     

     

    https://www.kisa.or.kr/public/laws/laws3_View.jsp?cPage=6&mode=view&p_No=259&b_No=259&d_No=88&ST=T&SV=

     

    기술안내서 가이드 < 관련법령·기술안내서 < 자료실 : 한국인터넷진흥원

    기술안내서 가이드 기술안내서 가이드 상세보기 제목 소프트웨어 개발 보안 가이드 담당자 전자정부보호팀  박지연  전화 061-820-1647 이메일 등록일 2019-11-29 조회수 61154 첨부파일 소프트웨어

    www.kisa.or.kr

     

    https://www.kisa.or.kr/public/laws/laws3_View.jsp?mode=view&p_No=259&b_No=259&d_No=50&ST=T&SV=

     

    기술안내서 가이드 < 관련법령·기술안내서 < 자료실 : 한국인터넷진흥원

    기술안내서 가이드 기술안내서 가이드 상세보기 제목 공개SW를 활용한 소프트웨어 개발보안 검증가이드 담당자 전자정부보호팀  박지연  전화 061-820-1647 이메일 등록일 2019-06-28 조회수 32610 첨

    www.kisa.or.kr


    SonarQube

    앞서 말한 시큐어코딩은 IDE 제품별 저마다의 플러그인을 지원하여 쉽게 확인할 수 있다. 여기에서는 그 결과를 UI 적으로 확인하여 정보를 공유할 수 있도록 하는 가시화 툴인 sonarqube 에 대해 설명한다.

     

    sonarqube 는 지속적인 코드 품질을 확보하기 위한 UI 기반의 가시화 툴이다.

     

    [주요기능]

    • 지속적인 코드의 Inspection
    • 다양한 언어의 지원으로 단일 Point에서 확인(UI)
    • 다양한 빌드 시스템 지원(Jenkins 등)
    • 품질 요구사항 반영 가능(Test Coverage 비율, Bug 레벨 등)

    이 글에서는 Java(11) + gradle(6.6. + jenkins(일부) 를 활용하여 SonarQube 를 이용하는 케이스에 대해 설명한다.

     

    https://www.sonarqube.org/downloads/

     

    Download | SonarQube

    Maximum Application Security Maximum value across branches & PRs Download License key will be needed to activate docker pull sonarqube:8.5.1-developer

    www.sonarqube.org

    기본적으로 SonarQube 는 elasticsearch, Embedded database 를 사용하며 안정적인 사용을 위해 DB 는 별도의 엔진을 사용하도록 권고된다. 그리고 안정적인 사용을 위해 LTS 버전으로 테스트를 했고, 다운로드 후 아래의 순서에 따라 준비할 수있다.

     

    InstallNTService.bat > StartNTService.bat > StartSonar.bat 순서로 실행한다.

    연결정보는 http://localhost:9000 이고 admin/admin 으로 접속한다.

    기본 접속화면이고 로그인 후 새로운 프로젝트를 생성하면 튜토리얼에 따라 몇가지 작업(토큰생성 등) 을 진행한 후에 ready 상태가 된다. 해당 토큰은 추후 연동을 위한 값으로 사용되므로 기억해야한다.(재발급 가능)

     

    새로운 프로젝트를 생성하고 `Set Up` 이 되면 token 을 생성하고, 프로젝트의 언어 및 build 기술을 선택한다.

    해당 진행결과에 따라 gradle 설정 방법이 나오고 해당 부분을 프로젝트에 적용해야 한다.

     

    gradle 에서 sonarqube 플러그인 사용을 위한 선언 추가

    # build.gradle 파일의 내용
    plugins {
    	id "org.sonarqube" version "2.7"
    }

    플러그인을 통한 sonarqube 에 결과 올리는 명령어

    ./gradlew sonarqube \
      -Dsonar.projectKey=sonarqube_test_project \
      -Dsonar.host.url=http://localhost:9000 \
      -Dsonar.login=위에서 발급받은 token 값 입력

    build.gradle 을 통해 sonarqube 플러그인을 실행하는 경우의 gradle task

    sonarqube {
        properties {
            property "sonar.host.url", "http://localhost:9000"
            property "sonar.login", "token 설정값"
            property "sonar.projectKey", "sonarqube_test_project"

            // optional
            property "sonar.sourceEncoding", "UTF-8"
        }
    }

     

    sonarqube 실행

     IDE 에 있는 sonarqube 플러그인은 품질측정을 위해 upload 하는게 아닌 sonarqube 의 체크 룰을 local 에 적용하기 위한 기능을 제공한다.

    해당 플러그인 이나 명령어를 실행하면 UI 를 통해 결과를 확인할 수 있는데 아래와 같다.

    gradle task 를 실행시킨 모습

     

    기본적으로 gradle task 를 타고 실행하게 되어 있고 main/test 에 대한 java, resources 에 대한 compile, process, classes task 를 실행한다. 그 이후 Coverage 를 위한 test Task 를 수행하여 sonarqube 에 반영하게 되는 절차를 거친다.

     

    아래는 실행 결과가 반영된 sonarqube 화면이다.

    실제로 해당 프로젝트의 상세화면에서 New Code, Overall Code 를 확인할 수 있는데 이는 지속적인 품질관리를 위해 기존과 달리 새로 반영된 Code 에 대한 측정결과에 전체 코드에 대한 측정결과를 확인할 수 있게 해준다.

     

    전체코드 품질 측정 결과 화면

     

    'Overall Code'  에서는 각 항목별 내용에 대한 결과를 전체적으로 확인할 수 있고 각 항목의 내용은 아래와 같이 구성된다.

    • Bugs(버그) - 코드의 신뢰성. 코드에서 잘못된 것을 나타냄
    • Vulnerabilities(취약점)
    • Security Hotspots(보안 핫스팟) - 취약성이 존재하는지 여부를 평가하기 위해 수동 검토가 필요한 보안에 민감한 코드에 대한 정보
    • Code Coverage 비율 및 전체 단위 테스트 수
    • 전체 라인중 중복된 라인 및 블럭에 대한 비율
    • Code Smells - 유지관리에 관련해서 코드에서 더 심오한 문제를 일으킬 가능성이 있는 프로그램 소스 코드

    Issues

    Issues 메뉴는 현재 프로젝트 기준으로 모든 issue 를 확인할 수 있는데 Filter 를 통해 원하는 항목에 대한 품질을 확인할 때 사용할 수 있다.

    이중 Bug, Code Smell 등의 항목은 IDE 에서 지원하는 FindBug, SonarLint 등의 inspection 도구를 통해도 확인할 수 있는데 각 Inspection 도구마다 필수체크 룰 외의 항목은 상이할 수 있으니, 프로젝트의 기준에 맞게 설정하여 진행하여야 한다. 보통 Major 이상의 이슈는 없이 가는게 보통이다.

     

    위의 화면은 Issues 항목 중 하나이며 Code Smell 기준 Blocker 로 측정된 항목이다. 해당 화면에 표출된 분석 지표를 통해서 코드의 품질을 확보해야 하며 위의 예는 test case 에서의 assertion 이 없을 경우에 나타난다. 

    실제 코드의 추적(Coverage)

    spring-boot 기준으로 간단한 컨트롤러를 작성한다. 아래의 코드 작성 후 sonarqube 를 수행하면 위에 설명한 각종 정보를 확인할 수 있는데 신뢰성이나 보안 역시 중요하지만 커버리지는 branch coverage 를 우선하여 품질을 검토한다.

     

    Sonarqube 에서는 Branch coverage 를 Condition coverage 라 표현한다.

    @RestController
    @RequestMapping("/sample")
    public class SampleController {
    
        @GetMapping("test")
        public String test1(@RequestParam String param1) {
            if("test".equals(param1)) {
                return "test";
            } else {
                return "no test";
            }
        }
    }

    위의 경우 2건의 conditions cover 가 필요한데 하나는 param1 이 "test" 인 경우와 또 하나는 그렇지 않은 경우이다. 해당 2건의 조건에 대한 Test 가 작성되어 있으면 Cover 가 되었다고 판단되며 커버율이 올라간다.

    아래는 위의 조건 중 if("test".equals(param1)) 에 대한 Cover Test 케이스이다. 

    class SampleControllerTest {
    
        @Test
        void whenParam1Equal_Test_ThenReturn_Test() {
            SampleController sampleController = new SampleController();
            Assertions.assertEquals("test", sampleController.test1("test"));
        }
    }

    해당 결과를 sonarqube 에 반영하기 위해서는 추가로 jacoco 라는 플러그인을 사용해야 하며 build.gradle 에 관련 정보를 추가하여 아래처럼 구성해야 한다. 

    plugins {

        id 'org.springframework.boot' version '2.4.0'

        id 'io.spring.dependency-management' version '1.0.10.RELEASE'

        id 'java'

        // sonarqube 플러그인 지정

        id 'org.sonarqube' version '2.7'

        // jacoco 플러그인 지정

        id 'jacoco'

    }

     

    // jacoco의 기본설정은 html 만 생성하게 되어있으나 xml 추가를 위한 설정

    jacocoTestReport {

        dependsOn tasks.test

        reports {

            xml.enabled(true)

            html.enabled(true)

            xml.destination(new File("build/reports/jacoco.xml"))

        }

    }

     

    sonarqube {

        properties {

            property "sonar.host.url", "http://localhost:9000"

            property "sonar.projectKey", "sonarqube_test_project"

            property "sonar.login", "b933f78a65f288ecbd7a159a41dd2eb205594685"

            // jacoco 에서 생성된 xml 을 report 로 올리기 위한 설정

            property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco.xml"

        }

    }

    // sonarqube task 수행시 clean, jacocoTestReport 를 우선 실행하기 위한 설정

    tasks["sonarqube"].dependsOn(clean, jacocoTestReport)

     

    구성 후에 sonarqube task 를 실행하면 clean, jacocoTestReport 를 선 수행한 후 해당 결과로 생성된 jacoco.xml 파일이 sonarqube 에 반영되어 아래와 같은 결과를 확인할 수 있다.

     

     

    앞서 실행한 단위 테스트 결과에 따라 Coverage 가 50.0% 로 변경되었고 상세화면은 아래처럼 확인 가능하다. 아래화면은 Coverage 중 Condition Coverage(Branch coverage) 의 상세 화면이며 앞서 작성한 Test 코드가 커버한 main 의 소스코드가 표현되어 어느 condition 이 테스트가 되었는지 확인할 수 있다.

    화면상에 라인별 색을 통해 판단된 내용을 확인할 수 있는데 녹색은 테스트가 된 항목, 빨간색은 테스트가 되지 않은 항목, 빗금으로 섞인 색은 여러 건의 조건에 대해 일부 통과된 것을 나타낸다.

     

    이처럼 조건절에 대한 커버리지 우선으로 확인하되 조건에 대한 커버리지가 확보되면 자연스레 라인커버리지도 올라가는데 라인 커버리지나 클래스 커버리지 같은 항목은 우선순위가 낮다.

     


    정리

    코드의 품질을 확보하는 과정은 개발자의 지속적인 노력이 필요하며 이 노력은 개발팀의 전체적인 규약이나 약속에 따라 방향성이 좌우된다. Test 코드를 작성하는 과정은 일반적인 개발 과정의 배수만큼 노력이 들지만 이를 일반적인 개발 과정의 일부로 받아들여야 그 만큼의 코드 품질이 확보된다고 생각한다. 리펙토링이나 클린코드나 결국 코드 품질 이슈에 대한 대응을 위한 방법들이며 Sonarqube 의 공식 홈페이지에 따르면 아래와 같은 방법으로 Clean Code 를 권고하고 있다. (Clean as You Code | SonarQube Docs)

     

    • Focus on New Code - 새로 추가된 코드 기준으로 우선 검증
    • Personal Responsibility - 개인의 책임. 개인이 현재 작업 중인 새로운 코드의 품질 확보
    • Quality Gate - 출시할 준비가 되었을 경우
    • Pull Request Analysis - 풀 리퀘스트 분석 및 데코레이션을 사용하여 병합하기 전에 코드가 표준을 충족하는지 확인

     

    코드 품질은 프로젝트 마무리 때에 몰아서 하면 프로젝트의 실패로 이어질 수 있으니 초기부터 지속적인 관리가 필요하다. 

     

     

    반응형
    LIST

    댓글

Designed by Tistory.