재미삼아 하는 프로젝트를 golang으로 해볼까 하고 파보고 있던 중 golang에 oracle을 연동하기 위해 삽질한 것이 있어 기록 차원에서 남긴다.

환경
1. go ( version go1.4.2 darwin/amd64 ) with 적절한 golang 환경설정 ( gopath 등 )
2. Oracle Client / SDK
instantclient-sdk-macos.x64-11.2.0.4.0
instantclient-basic-macos.x64-11.2.0.4.0

목표 
goracle( https://github.com/tgulacsi/goracle)을 사용 가능하도록 적절히 설정하자

헤딩 일지
1. 무턱대고 아래와 같이 그냥 해 봤다.

$ go get github.com/tgulacsi/goracle/godrv

"oci.h" 를 찾지 못한다는 에러가 난다. 환경변수가 필요한듯 하다. goracle github에 해당 설명이 있다. 그대로 추가

2. 환경변수 설정후 해 봤다.

ld: library not found for -lclntsh

위와 같은 에러가 발생했다.

lclntsh는 찾아보니 oracle client 드라이버 안쪽에 있는 라이브러리 인듯 하다. 
위 글을 참고로 하여 로컬 라이브러리에 추가 ( 어딘가에 설정이 잘못 된 것 같지만 확인이 어려우니 저기에 심볼릭 링크를 추가하기로 했다.)

$ cd /usr/bin
$ sudo ln -s ~/instantclient_11_2/libclntsh.dylib.11.1 libclntsh.dylib
$ sudo ln -s ~/instantclient_11_2/libocci.dylib.11.1 libocci.dylib

3. 잘 된다!


Posted by 제리곰
,


프로그램을 작성함에 있어 테스트케이스의 중요성은 대부분의 프로그래머가 공감하고 있는 듯 하다. 하지만 테스트케이스를 어떻게 작성하는것이 적당한지에 대해서는 프로그래머 개개인의 철학이나 경험(또는 삽질)한 정도에 따라 다른 생각을 갖고 있는 것 같다.

개인적인 생각으로는 이상적인 테스트케이스는 다음을 만족하면 된다.

  1. 모든 코드를 커버하고 있음 ( Quantity )
  2. 현재 코드의 정상, 예외 경우에 적절히 동작함을 검증함 ( Quality )
  3. 미래의 코드 변화에도 적절히 대응할 수 있는 구조로 되어 있음 ( Well-structured )


이번 글에서 소개하고자 하는 Mutating Testing은 위에서 제시한 이상적인 테스트 케이스의 2번을 만족시키기 위한 방법중 하나로, 테스트케이스 자체를 검증하는 방법이다.


Mutation 이란

Mutating Testing에서 Mutation은 소스코드에 하나의 작은 변화를 발생시킨 것을 말한다. 즉, 아래와 같은 코드 변화를 주는 것을 의미한다.
 
// Original Source Code
if ( amount > THRESHOLD ) { 
  // Do Something
} 

// Mutation
if(amount >= THRESHOLD) {
  // Do Something
}
Mutation Testing

위와 같이 생성한 mutations를 기존 테스트코드로 테스트 하는 것을 Mutation Testing이라고 한다. 이 결과는 다음의 두가지 경우로 나뉠 것이다.

테스트 실패 ( 긍정적 )
mutation에 대해 테스트 코드 수형 결과가 실패이다.(Mutation Testing에서는 Test Killed라고 표현한다.) 이 경우 기존에 작성한 테스트케이스가 적절한 테스트 케이스였음을 의미한다.

테스트 성공 ( 부정적 )
mutation에 대해 테스트 코드 수행 결과가 성공이다.(Mutation Testing에서는 Test Servived라고 표현한다.) 이 경우 기존에 작성한 테스트케이스는 로직 변경을 감지하지 못하고 성공 응답을 주었으므로 적절하지 않은 테스트케이스였음을 의미한다.

생성한 모든 mutants에 대해 테스트가 실패하였다면 테스트케이스가 로직의 변화에 민감하게( 알맞게 ) 짜여져 있는 것이므로 테스트케이스의 Quality가 적절함을 검증했다고 볼 수 있다.

Mutation Testing in Real World

이 방법론에 대해서는 이미 1980년대에 소개되었다.(T. Acree, T. A. Budd, R. A. DeMillo, R. J. Lipton, and F. G. Sayward, "Mutation Analysis," Georgia Institute of Technology, Atlanta, Georgia, Technique Report GIT-ICS-79/08, 1979.) 하지만 코드의 작은 부분 하나하나를 바꾸어 가며 테스트를 수행하면 엄청난 수의 조합이 발생하기에 이를 수행하기에는 너무 오래 걸려서 실무에서 사용되기는 어려웠다고 한다. (밤새 테스트케이스를 돌리고 다음날 확인하는 경우도 있었다고 한다.)

하지만 요즘 컴퓨터의 수행 속도라면 어느정도 "돌릴 만한" 수준까지 올라왔다고 판단되어 다시 주목받고 있다. 최근의 나온 framework 중에서는 code coverage를 이용하여 mutation이 영향을 받는 부분의 테스트 케이스만을 수행하게 하여 속도를 더 향상시킨 경우도 있다고 한다.(PIT)

Java 환경에서 mutant를 생성하고 테스트를 돌리는 framework로는 PIT(http://www.pitest.org), Jumble(http://jumble.sourceforge.net/), Jester(http://jester.sourceforge.net/) 등등 여러 framework가 있다.

새로 시작하거나 간단히 만들어 볼 프로젝트가 있다면 code coverage와 함께 mutation testing을 적용하여 테스트 코드의 품질을 올려보는것도 좋을 것 같다.



Posted by 제리곰
,

Spring Security를 이용해 로그인 페이지를 구현하다가 /favicon.ico 페이지로 리다이렉트 되는 현상을 경험했다. 이 문제의 원인은 Spring Security의 문서에서 찾을 수 있었다.

Spring Security의 ExceptionTranslationFilter의 역할 중 하나는 인증 단계 진입 전에 최초 사용자의 요청을 캐싱 하고 있다가 사용자 인증 절차가 필요하여 인증 페이지로 이동 후 인증에 성공할 경우 캐싱된 페이지로 리다이렉트 시켜 준다.


-- from http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/#request-caching


원래대로라면 사용자가 최초 요청한 url에서 인증 페이지로 리다이렉트 되며 사용자가 요청한 url이 캐싱되어야 하지만 많은 브라우저가 사용자 요청과 동시에 /favicon.ico 을 찾으려고 한번 더 리퀘스트를 하게 되고, 이 때 /favicon.ico에 대한 권한이 없다면 최초 요청한 url에서의 리다이렉트가 아닌 /favicon.ico에 대한 리다이렉트 페이지로 접근하게 되는 현상이었다.


이 문제는 간단하게 아래 처럼 /favicon.ico 리소스에 대해 접근 제한을 해제하면 해결할 수 있었다.


<intercept-url pattern="/favicon.ico" access="ROLE_ANONYMOUS" />

Posted by 제리곰
,