팀 릴리즈 서버 준비

지지난 주에 적당한 CPU 파워의 잉여 머신이 하나 생겨서, 시험 삼아(?) 릴리즈 서버를 하나 구축해봤다. 근데 이게 OS 새로 올리고 프로그램 좀 설치하다 보면 부팅도 안되더라고 Orz

그래서 지난 주에 머신을 교체하고 (E8400이 Q8300이 되었다?), 이번 주 목요일에 설정을 끝냈다. 대략 다음의 툴을 깔아야 했다.

개발 도구 위주로 쓰면,

  • VS 2005/2008/2010 (…) 및 여기에 해당하는 Service Pack과 hotfix
  • Collabnet Subversion Server (Client 모듈만)
  • Debugging Tools For Windows (x64)
  • ActivePerl[1]
  • CruiseControl.NET 1.5[2]

…이 대부분은 Azyu 군이 수고해줬음. Azyu ㄳㄳ(…)

릴리즈 서버라고 거창하게 써놓긴 했지만 하는 일은 매우 단순하다. 모든 작업은 CCNet에 forced-build trigger로만 일어나게 하고, 다음 작업을 한다.

  1. 변경 없는 저장소 – 팀 내 기준으로는 주로 subersion – 코드를 가지고 release 할 설정으로 빌드하고 (msbuild 혹은 .bat 사용)
  2. 이에 대해서 소스 코드 인덱싱을 하고 (ssindex.cmd)
  3. 이 정보를 포함한 .pdb 및 바이너리 정보를 심볼 서버에 저장하고 (symstore)
  4. 적당한 디렉터리에 배포할 파일들을 모으거나 / 파일 목록을 받아서 이를 묶어 배포할 형태로 만들어, 적당한 레이블을 붙여서 .zip 형태로 다운로드 할 수 있게 만들기

…로 끝?

변경사항 마다 빌드하지 않는 건, 일단 release 빌드는 시간이 오래 걸리고, symstore를 압축 옵션을 주고 해도 하드 디스크 용량이 좀 빨리 줄어드는 문제가 있어서. 예전에도 한 번 당했고(…). 그리고 빌드에는 기능이 하나 더 들어갈 예정인데 – 특정 형태의 .rc와 .h를 조작해서 svn revision 정보를 넣을 예정; 코드 테스트는 끝났고 적용만 남은 상태 – 여하튼 변경 없는 코드를 clean;build 하는 형태로 동작하게 했다.

그리고 이에 대해서 소스 서버 정보와 심볼 서버 정보를 남기고 묶는다는 것.

.zip 형태로 묶는 기능을 CCNet의 Package publisher가 처리해줘서 매우 간단히 했음. 다만 이게 1.6에서 바뀌는 거긴 한데, <file>???</file> 하는 식으로 파일 목록을 받는데, 이게 특정 디렉터리와 그 하위 디렉터리를 전부 포함하라는 문법이 dir-name\**\*.* 이라서 (백 슬래시인가?) 좀 헤맸다.

Subversion revision을 label로 붙이려 했더니 CCNet 자체 기능으론 없더라. 대략 major#.minor#.patch#.rev 정도로 하려고 했는데 안되더라고; 하지만 CCNet 용으로 이런 기능을 하는 모듈을 svnrevisionlabeller라는 이름의 오픈 소스로 만들고 있더라. 원저자는 요즘 작업을 안 하는 듯 하지만 다른 사람들이 이슈에 패치 달고 있는 거 보니 재미있음(…). 이 모듈 써서 label 달고, 패키지 이름도 이걸로 처리되게 했다.

의외로 오래 안 걸리고 설정이 끝나서 흡족한 상태 XD

  1. 소스 인덱싱에서 사용함 []
  2. 1.6이 Release가 있긴 한데, 뉴스 페이지엔 없어서 일단 1.5 []

프로그래머의 일상: 업그레이드의 때

하드웨어 업그레이드가 아니긴 하지만. 아래는 몇 일 된  SW 업그레이드 기록들.

Firefox 3.5

Endgadget Korea에서 보고 업데이트. Firefox는 회사 출근해서 켜고, 퇴근할 때나 꺼지기 때문에(…), 이런 기사를 보고 업데이트하면 내가 더 빠르다(???). 메모리 사용량은 조금 줄어들었나? 이건 잘 알 수 없긴한데[1] 속도는 좀 더 올라간 느낌.

하지만 이건 플러그인이 전부 활성화 안되서 일 수도 있다는 생각이 불현듯 든다(…).

TortoiseSVN

1.5.x 를 천년만년 쓰다가 1.6.x으로 버전업. 일종의 staging? 기능이 생긴 것 같다. 이게 없어서 git branch 로 관리했는데 일단 좀 써봐야 할듯하다. 다만 퍼포스 작업 관리나 git branch 처럼 편한지는 잘(이건 익숙한 정도의 문제도 있겠다)

CruiseControl.net

1.3.0 쓰다가 1.4.4로 넘어왔다. 이거 완전 신세계네?

  • MSBuild 출력을 제대로 해석한다. 예전에는 MSBuild에 별도의 로거를 붙여서 이걸 해석해서 올리도록 했다.
  • 대쉬 보드가 쓸만해졌다. 예전엔 각 빌드별 링크 수준의 페이지였는데 이젠 좀 더 상세한 정보를 제공한다.
  • 각 프로젝트 별 페이지에 일별 빌드 성공/실패 내역을 간략히 보여준다
  • 소스 저장소 변경 사항 추적 — 이건 사실 trac / redmine 같은 류의 이슈 트랙커에서도 지원하는거라 그냥 feature-creep 같은 느낌인데 …
  • 예전에 UnitTest++ 테스트 케이스를 추적(?)하려고하면 꽤나 귀찮은 xsl 수정을 거쳐야 했는데 + 두 개 이상의 UnitTest++ 테스트 케이스가 있으면 또 고쳐야하기도 하고. 그래서 아예 Google-Test로 전부 옮겨 버렸다. 이건 제대로 파싱도 하고(XSL 수정없이), 보기도 쉽게 되더라.
  • 빌드 통계 페이지가 그래프 수준의 뭔가를 제공한다. 빌드 시간 등등을 그래프로 볼 수 있긴한데, 실제 용도는 좀 불명.

eclipse galileo

이클립스가 3.5(갈릴레오) 버젼으로 올라갔다. 회사나 집에서 파이썬 개발툴(…)로 사명을 다하고 있는데, 집 컴(…중에 맥북)에 설치한 이클립스는 버젼이 세 개가 있더라. 코코아 32/64, 카본 32. 근데 코코아 버젼이랑 카본 버젼 차이가 뭐지? GUI 라이브러리가 다른 이상의 사용성의 차이가 있나?

맥용 프로그램들이 예쁘고 쓰기 좋은게 꽤 많긴하지만, 그런 프로그램의 수준으로 이클립스를 수정하면 크로스 플랫폼 개발툴로의 가치가 범용성 면에선 줄어들 것 같은데?

사실 정말 해야할 업데이트는 소스 저장소 서버의 SVN 서버 버젼 올리기 같지만 이건 언제 하지 Orz

  1. 회사에서 쓰는 빌어먹을 삼성 SDS의 인캅스(한 단어) 덕분에 메모리 사용량은 알기 힘들다. 이 뭣 같은 프로그램은 자기 멋대로 DLL을 링크해서 메모리 사용량도 올리고, 시스템 콜 링크 주소도 고친다 []

코드 정적 분석: CI 툴에 추가할만한듯?

VS 2005를 쓰고 있긴하지만, 팀 시스템이 아니라서 static code analysis 기능은 없다. 정정 분석(static code analysis)은 *nix 시절의 lint 비슷한 툴을 생각하면 된다. 소스 코드를 입력으로 받아서 실제 실행없이 *버그가 있음직한* 곳을 찾아서 경고해주는 기능을 하는 도구다. 

예전에 팀 동료인 Azyu 군이 VS 2005 (w/o TS)에서도 정적 분석이 된다고 해서,  좀 찾아봤는데 이건 뭔가 좀 불충분(?)해보여서 관뒀는데, cppcheck 란 툴을 발견하고 좀 써보기로 했다.

대략,

  • 커맨드라인 툴이고
  • 실행 속도는 적당히 빠른 편 – CPP 소스 94개 정도의 파일 공유 웹서버 프로젝트를 분석하는데 1분 미만.
  • XML 출력이 됨 — CI 툴에 곁들이기가 좋아보인다
  • *nix / Win32 모두 지원 — linux distro. 들은 직접 팩키지를 제공하는 경우가 많고 Win32 설치용 바이너리도 있다

정도의 장점이 있음.

내가 일하는 데 사용하는 CI 툴에 통합해본 건 아니지만, 이 정도면 통합하는데 오래걸리진 않을 듯 하다 + 기존 오픈소스 프로젝트에서도 몇 가지 버그를 찾은걸 보면 나름대로 도움은 될듯?

CruiseControl.NET에서 2개 이상의 UnitTest++ ‘프로그램’을 실행하려면?

제목이 좀 애매하게 된 것 같은데, CruiseControl.NET에서 관리하는 하나의 프로젝트 안에 테스트를 실행시키는 것이 2개 이상일 수 있다. 간단히 생각해보니

  • 2 개 이상의 단위 테스트;unit-test 프레임웍이 사용된다 – 단위 테스트마다 사실 상 서로 다른 바이너리가 있게 된다 이 경우는 해당 사항이 없다. XSL 에서 각각을 최종적으로 통합해주기만 하면 OK.
  • 하나의 단위 테스트 프레임웍만 사용되지만 링크 문제나 연관성 문제로 2개 이상의 실행 바이너리가 존재한다
  • 단위 테스트 자체의 개념과는 좀 어긋나지만, 약간 큰 컴퍼넌트들의 결합을 테스트할 때 "프로그램 자체를 재시작"해야하는 객체들이 있으면 바이너리가 1개라도 비슷한 현상(?)이 나타난다.

이런 경우가 있을 수 있을 것 같다. 근데 문제는 두 개의 바이너리가 실행되고나면,

  1. 2개의 UnitTest++ — CruiseControl.NET은 특정 XML 형태[1] 의 출력만 제대로 알 수 있다 — 결과파일이 나온다
  2. 내가 사용했던 방법 — 결과 파일을 빌드 로그에 통합;merge 하는 방식으로는 XML의 root-node 에 해당하는 것[2] 이 2개 이상이 존재하게 된다
  3. 결과 파일을 최종적으로 해석하는 unittest.xsl[3]첫 XML node 만 해석하게 된다 모든 결과를 보기는 하지만 시간 등등에서 통합된 값을 내놓지 못한다.

즉, 모든 테스트 결과가 하나의 통일된 view로 제공되지 못하게 되는 것.

정정

정확히 말하면, 모든 테스트 결과가 보이기는 한다. 다만 통합되어서 보여야할 일부 정보(실행 시간/실패 갯수 등등)이 제대로 보이지 않는다.

Continue reading “CruiseControl.NET에서 2개 이상의 UnitTest++ ‘프로그램’을 실행하려면?”

  1. UnitTest.xsl에서 인식하는 것만 []
  2. UnitTest++의 경우 <unittest-results tests="24" failedtests="0" failures="0" time="1.3"> 하는 식의 root-node가 생긴다. 그리고 각각의 test-suite들과 실제 test들의 결과(성공/실패+실패 이유)들이 나열된다. nunit을 쓰거나 junit을 쓰면 조금 다른 노드가 생긴다. []
  3. unittest-result 라는 node를 찾아 거기에서 테스트 수나 실패한 테스트에 대한 정보를 찾아서 최종 출력용 페이지를 만들게 된다 []

CruiseControl.NET 삽질 (2)

…밑의 글에서 정리 못한 얘기 몇 가지.

MSXML 버젼 문제인듯도한데, MSBuild 의 출력을 해석하는 경우(compile-msbuild.xsl 과 msbuild.xsl 활용) xsl 파싱 에러를 몇 가지 낸다.

  • DTD 를 사용할 수 없다는 문제 – &nbsp;를 재정의한 부분이 있는데, 적당히 고쳐주자(&#160;으로)
  • <xsl:choose> 가 비어있다는 문제 – 해당 줄을 지우면 해결

사실 이걸 찾아서 고치는 것보다 이걸 수정하고나면 반영이 안되서 IIS와 CruiseControl.NET으로 등록된 서비스를 재시작하는게 좀 더 귀찮았다. (내 방법에 문제가 있는 것인지는 모르겠지만 제대로 반영이 안된다)

 

MSBuild 출력 해석 문제. 전체적으로 출력이 좀 난잡하고 잘 정의된 순서없이 출력된다. 그래서 다시 배치파일로 갈아탈까를 심사숙고하다가(…), 최종적으로는 변형된 MSBuild 해석 dll을 구해서 설치했다. (http://confluence.public.thoughtworks.org/display/CCNETCOMM/Improved+MSBuild+Integration 참조)

여기에 ccnet.config이외에 웹 대쉬보드 설정(dashboard.config) 수정 문제 같은 것도 잘 기술되어 있으니 따라가자. (이걸 모르면 한동안 MSBuild 출력을 대쉬보드에서 볼 수 없다)

ps. 근데 CC.NET에서 설정해주는 값을 MSbuild.xml 에서 쓰고 있었더니 MSbuild.exe를 이용한 빌드 설정 유효성 확인(validation)이 동작하지 않는다. 뭔가 아시는 분?

CruiseControl.NET 삽질 정리

대충 어제를 기점으로 삽질은 완전히 끝난듯한데, 그 동안 CruiseControl.NET을 처음 깔아보는 프로그래머(=rein)가 할만한 삽질들을 정리해보겠다. 우선 설치 과정 전체는 KAISTIZEN 님의 CruiseControl.NET 설치 일지 를 따라 갔다. 전체 과정이 잘 정리되어있으니 매우 유용한 페이지다.

IIS 설정 삽질

IIS 설정에서 ASP.net 의 버젼을 1.1.x 대신에 2.0.x 이상을 사용해야 한다. 그렇지 않으면 IIS에 등록한 파일 형식이 이상하다는 식의 에러를 뱉는다(그것도 로컬 접속에서만 볼 수 있는 형태로 -_-;; )

통계 기능 사용하기

기본적으로 이 기능이 꺼져있는데,, 이 기능을 통해서 구현되는 페이지 – 각 프로젝트(ccnet.config의 Project 섹션에 대응)의 Statistics 페이지 – 의 경우 예쁘지 않은(…) 예외;exception을 던지면서 죽는다. 프로젝트 설정에

<publishers>
  <
xmllogger/>  <!–for CC.NET–>
  <
statistics/> <!–for statistics page–>
</
publishers>

이런 부분이 들어가 줘야 한다.  문제는 작업할 때 메일링 리스트만 보고 <statistics /> 항목만 추가 해줬더니 이젠 전체 히스토리 페이지에서 예외가 발생하는 것(…).  xmlloger 를 발행하는 부분이 CC.NET 전체의 히스토리나 로그 뷰를 제공하기 때문에 저 부분이 빠지면 제대로 안되는 것에 주의.

UnitTest++ 연동

이 부분은 전혀 감이 안잡혔는데, 이 역시 KAISTIZEN 님의 UnitTest++ 연동 부분을 따라했다. 여기서도 삽질한 부분이 있다. 위의 연속이긴 한데, 로그 파일 합치는 부분(merger)을 나중에 추가 했다고 publishers 부분의 뒷부분에 붙였더니 제대로 출력이 되질 않는다. 즉, 다음과 같은 순서가 되야 한다.

<publishers>
    <merge>
        <files>
            <file>Path_To_UnitTest++\Output\XmlFile.xml</file>
        </files>
    </merge> <!-- merge가 xmllogger보다 앞임 -->
    <xmllogger/>
    <statistics/>
</publishers>

 

실제 xmllogger가 처리하는 부분이 우리가 실제로 보게되는 페이지 – 에 해당하는 xml 출력이 – 라서 그 부분 이전에 빌드 결과가 xmllogger에 의해 처리되어버리면 UnitTest++결과를 볼 수 없게 된다(…). 그러니 순서에 주의.

다만 전체 통계 페이지에서도 통계를 보고싶은데 오늘 수정한 xsl이 제대로 동작하지 못하는 것인지 통계를 제대로 못 얻어내더라(테스트 결과에 대한 것들에 대해서).  이건 해결하게되면 다시 포스팅을 하던가 해야.

C++ 빌드 방식에 대한 첨언

이건 삽질했다기보단 Visual C++ 기반으로로 빌드를 해야해서 좀 선택하거나 고민할게 많아서 써보는 얘기다. CruiseControl.NET이 C#을 위해서는 정말 완벽한 지원 – 특히 NAnt와 NUnit 지원이 멋짐 – 이지만 C++의 경우엔 저렇게 널리 쓰인다고 할만한 빌드 팩키지가 없다. 그래서 그런지 몇 가지 대안으로 쓸만한 것들이 존재한다.

  • <exec> task – 말그대로 커맨드라인에서 뭔가 실행시켜주는 태스크다. 처음엔 batch 파일을 이걸 이용해서 실행시켜서 빌드했다 – 이전에 trc / svn / XML-RPC를 모두 결합시켜서(…) post-commit 훅으로 빌드했었기에. Batch 파일 하나 실행시키면 되는 거기 때문에 상대적으로 빌드를 테스트하기도 쉽고 설정 부담도 적지만, 언제나 그렇듯 batch 파일은 유지보수가 힘들다[…].
  • <devenv> task – DevEnv.com은 VisualStuiod.Net 을 실행시켜주는 비슷한 녀석이다. 이놈을 직접 호출해서 빌드하는 방식 – 예를 들어 devenv.com some_solution.sln /build DEBUG – 을 쓸 수 있게 해준다. 다만 이 녀석은 기본값이 rebuid 라서 빌드 트리 일부에 있는 라이브러리 부분 등을 모두 다시 빌드하는건 좀 짜증나기도하고 nightly-build도 아닌 CI로만 활용할 때엔 좀 괴롭기 떄문에 잘 취사 선택해야한다.

    별로 설정할게 없어서 편하긴한데, ccnet.config 에 추가해야할 줄이 무지 많다. 솔루션이 추가될 때마다 CruiseControl의 설정을 건드려야 하는 것도 문제고, 빌드 자체가 안될 때 디버깅 하기도 좀 난감하다.

  • <MSBuild> task – devenv를 좀 찔러보다가(…) 일단 현재 도착한 장소가 여기. MSbuild 는 .NET 프레임웍에 포함되어있는 툴인데 XML 기반 메이크 파일(…보다는 좀 더 MS Windows 스러운)이다. C# 같은 것은 소스 기반에서도 빌드할 수 있는 룰들을 제공한다. 그리고 이 안의 설정들의 경우 CruiseControl.NET에서 지정할 수 있는 것보다 좀 더 유연한 룰들을 제공하는데다가(조건부 컴파일이라거나…), 상대적으로 테스트하기가 쉽다. (MSBuild 의 메이크파일에 해당하는 XML 파일만 시험해보면 되니) 그리고 문서화가 잘되어있는 XML 형식이라 배치 파일보다 유지/관리가 쉽다.

뭐 이 정도가 지금 당장(…) 생각나는 설정 삽질이다. 이 이후에도 뭔가 삽질을 하면 포스팅 해보도록 하겠다(…).

빌드 자동화 하기 – CruiseControl.net

현재 개발하는데 사용하는 환경이 svn+trac이고 Windows 서버를 사용하고 있다(물론 XP이후의 Win32 환경이면 다 사용할 수 있는 상태지만…).

빌드가 자동으로 이루어지기 위해서 다음과 같은 구성을 쓰고 있다 (가장 효율적인 집합이랑은 거리가 좀 멀 것 같지만 )

  • Machine A : svn 서버. trac 도 같은 서버를 사용한다 – trac 서버가 svn과 원격으로 있게 하는건 좀 어렵다.
  • Machine B : 빌드를 수행한다. 

이런 개념으로 접근했었다. 실제로 빌드가 이뤄지는 시나리오는,

  1. 누군가 소스를 수정하고 svn commit
  2. A의 svn 서버의 post-commit 에 걸려있는 훅;hook 이 실행
  3. 훅은 Machine B의 XML-RPC 서비스에 빌드 요청을 전달
  4. Machine B에서 빌드를 시작
  5. …미래의 어느 시점엔가 Machine A의 trac wiki의 빌드 상태 페이지를 누군가 열면 현재 상태를 B의 XML-RPC 서비스에 요청하고 현재까지 알려진 최신 빌드의 정보를 출력한다.

라는 것이다. 만약 강제 리빌드를 실행하게 되면 trac wiki에서 특정 페이지를 열면 해당 페이지의 trac-macro가 실행되고 그 매크로에서 forced-build라는 메시지를 XML-RPC로 전달하게 했다. 그 이후는 4~5의 반복.

여기서 문제는 바로 3~4의 연결문제와 5의 과정이 사람이 직접 접근해서 확인해야하는 과정이라는 것. 즉, 저 부분은 자동화가 이루어지지 않았다.

원하는 것.

  • XML-RPC 같이 내가 직접 수정해야하는 – 지금은 trac macro와 빌드 서버 밑단이 python 코드 – 부분이 없거나 나 이외의 사람도 관리하기 쉬울 것 (명확한 문서화, 예제 등등)
  • 실패한 빌드에 대해서 명시적으로  알려줄 것 (trac-wiki를 일일이 열어봐야하는 것 같은 것 말고)
  • 전체 빌드를 기술할 때 Visual C++ 기반 프로젝트의 설정을 바꾸거나 추가하거나 제거하는게 쉬울 것
  • svn에서 다른 SCM을 사용해도 쉽게 전환할 수 있을 것 (가능하면 SCM 계층과 커플링이 적을 것)

과 같은 조건이었는데 Rica 네 팀에서 설치해봤다는 CruiseControl.net 을 써보기로 하고 설치. 잘 알려진 오픈소스 Continuous Integration 툴인 CruiseControl의 .net framework 포트다† .

설치 과정 자체는  IIS, 빌드툴(이 경우엔 Visual Studio 2005), svn 그리고 CruiseControl.net 자체만 설치하면 끝.

IIS에 등록하는 과정도 CC.net이 알아서 해주는지라 쉬웠다 (다만 IIS 에러 메시지를 하나도 해석할 수가 없어서 ASP 1.1.x대신에 2.0.x로 설정하면 끝날 문제를 반나절 헤맸다…). 띄우고나서는 CC.net에 동봉된 문서를 따라서 설정을 하고 빌드가 이루어지는 것을 볼 수 있었다. CC-Tray라는 Win32용 태스크 바에 뜨는 트레이 프로그램을 제공하는데 현재 등록된 빌드들이 빌드성공/실패 여부를 알려주고 + 실패한 경우 누군가 자원해서 고치나를 알려주기 때문에 유용할 것 같다.

그리고 툴 자체가 Win32환경(특히 .net framework)에 최적화 되어있고, VS 200x의 솔루션 파일을 바로 빌드할 수 있는 태스크를 제공하기 때문에, 스크립트로 빌드하던 시절에서 좀 더 편한 방식으로(아무나 설정하기 쉬운) 옮겨갈 수 있게 된 듯하다.

실제 사용 경험은 팀에 좀 적용된 이후에 글로 써보도록 하겠다.

ps. 이걸로 하루 일과 종료(…)

*

† 비슷하게 로깅 라이브러리 log4j의 포트인 log4net, 빌드툴 ant의 포트인 Nant, 유닛테스트 프레임웍인 JUnit 포트인 NUnit 같은 툴들을 쓴다(…). 뭐 그래봐야 C++이라서 테스트 툴은 UnitTest++을 쓸 듯 하지만…