package egovframework.rte.fdl.idgnr; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.math.BigDecimal; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.Properties; import javax.annotation.Resource; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.jdbc.SimpleJdbcTestUtils; import egovframework.rte.fdl.cmmn.exception.FdlException; import egovframework.rte.fdl.idgnr.impl.strategy.EgovIdGnrStrategyImpl; /** * TableId Generation Service Test 클래스 * @author 실행환경 개발팀 김태호 * @since 2009.02.01 * @version 1.0 * @see <pre> * == 개정이력(Modification Information) == * * 수정일 수정자 수정내용 * ------- -------- --------------------------- * 2009.02.01 김태호 최초 생성 * 2013.03.25 한성곤 필드명 속성 처리, JdbcTemplate 방식으로 변경, 초기 id 값 등록(자동 insert 처리), 반복처리 제외 * * </pre> */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath*:/spring/context-common.xml", "classpath*:/spring/context-tableid.xml" }) public class EgovTableIdGnrServiceTest { @Resource(name = "dataSource") private DataSource dataSource; @Resource(name = "schemaProperties") Properties schemaProperties; @Resource(name = "basicService") private EgovIdGnrService basicService; @Resource(name = "Ids-TestSimpleRequestIdsSize1") private EgovIdGnrService idsTestSimpleRequestIdsSize1; @Resource(name = "Ids-TestSimpleRequestIdsSize10") private EgovIdGnrService idsTestSimpleRequestIdsSize10; @Resource(name = "Ids-TestSimpleRequestIdsSize100") private EgovIdGnrService idsTestSimpleRequestIdsSize100; @Resource(name = "Ids-TestBigDecimalRequestIdsSize10") private EgovIdGnrService idsTestBigDecimalRequestIdsSize10; @Resource(name = "Ids-TestMaxByteIds") private EgovIdGnrService idsTestMaxByteIds; @Resource(name = "Ids-TestMaxShortIds") private EgovIdGnrService idsTestMaxShortIds; @Resource(name = "Ids-TestMaxIntegerIds") private EgovIdGnrService idsTestMaxIntegerIds; @Resource(name = "Ids-TestMaxLongIds") private EgovIdGnrService idsTestMaxLongIds; @Resource(name = "Ids-TestNotDefinedTableInfo") private EgovIdGnrService idsTestNotDefinedTableInfo; @Resource(name = "Ids-TestWithGenerationStrategy") private EgovIdGnrService idsTestWithGenerationStrategy; @Resource(name = "Ids-TestNonExistingTableName") private EgovIdGnrService idsTestNonExistingTableName; @Resource(name = "Ids-TestWithColumnName") private EgovIdGnrService idsTestWithColumnName; Log logger = LogFactory.getLog(EgovTableIdGnrServiceTest.class); /** * Test Case 시작 * * @throws Exception fail to initialize */ @Before public void onSetUp() throws Exception { SimpleJdbcTestUtils.executeSqlScript( new SimpleJdbcTemplate(dataSource), new ClassPathResource("testdata/" + schemaProperties.getProperty("tab_sample_create")), true); } @After public void onTearDown() throws Exception { SimpleJdbcTestUtils.executeSqlScript( new SimpleJdbcTemplate(dataSource), new ClassPathResource( "testdata/" + schemaProperties.getProperty("tab_sample_drop")), true); } @Test public void testBasicService() throws Exception { // int assertNotNull(basicService.getNextIntegerId()); // short assertNotNull(basicService.getNextShortId()); // byte assertNotNull(basicService.getNextByteId()); // long assertNotNull(basicService.getNextLongId()); // BigDecimal assertNotNull(basicService.getNextBigDecimalId()); // String assertNotNull(basicService.getNextStringId()); } /** * Int, long Type의 ID 제공 서비스 테스트 Block Size 1 * * @throws Exception ID 생성 실패시 */ @Test public void testSimpleRequestIdsSize1() throws Exception { int testCount = 100; // 1. Initialize the counter in the database. initializeNextLongId("test", 1); // 2. get next integer id until 99 for (int i = 1; i <= testCount; i++) { int id = idsTestSimpleRequestIdsSize1.getNextIntegerId(); assertEquals("The returned id was not what was expected.", i, id); } // 3. get next Long id using query directly. assertEquals("The next_id column in the database did not have the expected value.", testCount + 1, peekNextLongId("test")); } /** * Int,long Type의 ID 제공 서비스 테스트 Block Size 10 * * @throws Exception ID 생성 실패시 */ @Test public void testSimpleRequestIdsSize10() throws Exception { int testCount = 100; // 1. Initialize the counter in the database. initializeNextLongId("test", 1); // 2. get next integer id until 99 for (int i = 1; i <= testCount; i++) { int id = idsTestSimpleRequestIdsSize10.getNextIntegerId(); assertEquals("The returned id was not what was expected.", i, id); } // 3. get next Long id using query directly. assertEquals("The next_id column in the database did not have the expected value.", testCount + 1, peekNextLongId("test")); } /** * Int,long Type의 ID 제공 서비스 테스트 Block Size 100 * * @throws Exception ID 생성 실패시 */ @Test public void testSimpleRequestIdsSize100() throws Exception { int testCount = 100; // 1. Initialize the counter in the database. initializeNextLongId("test", 1); // 2. get next integer id until 99 for (int i = 1; i <= testCount; i++) { int id = idsTestSimpleRequestIdsSize100.getNextIntegerId(); assertEquals("The returned id was not what was expected.", i, id); } // 3. get next Long id using query directly. assertEquals("The next_id column in the database did not have the expected value.", testCount + 1, peekNextLongId("test")); } /** * BigDecimal Id 제공 테스트 * * @throws Exception ID 생성 실패시 */ @Test public void testBigDecimalRequestIdsSize10() throws Exception { if (isBigDecimalImplemented()) { int testCount = 100; BigDecimal initial = new BigDecimal(Long.MAX_VALUE + "00"); // 1. Initialize the counter in the database. initializeNextBigDecimalId("test", initial); // 2. get next bigdecimal id for (int i = 0; i < testCount; i++) { BigDecimal id = idsTestBigDecimalRequestIdsSize10.getNextBigDecimalId(); assertEquals("The returned id was not what was expected.", initial.add(new BigDecimal(i)), id); } // 3. get next integer id using query directly. assertEquals("The next_id column in the database did not have the expected value.", initial.add(new BigDecimal(testCount)), peekNextBigDecimalId("test")); } else { fail("Test failed because BigDecimals are not implemented in current driver."); } } /** * Byte Id 제공 * * @throws Exception ID 생성 실패시 */ @Test public void testMaxByteIds() throws Exception { int testCount = 100; // max = 127 long max = Byte.MAX_VALUE; long initial = max - testCount; // 1. Initialize the counter in the database. initializeNextLongId("test", initial); // 2. get next byte id until limitation of Byte for (int i = 0; i <= testCount; i++) { byte id = idsTestMaxByteIds.getNextByteId(); assertEquals("The returned id was not what was expected.", i + initial, id); } // 3. in case it reached a max value data type allows, get next byte id. try { byte id = idsTestMaxByteIds.getNextByteId(); fail("Should not have gotten an id: " + id); } catch (Exception e) { assertTrue(e instanceof FdlException); } } /** * Short Id 제공 서비스 테스트 & Max Value 체크 테스트 * * @throws Exception ID 생성 실패시 */ @Test public void testMaxShortIds() throws Exception { int testCount = 100; // max is 32767 long max = Short.MAX_VALUE; long initial = max - testCount; // 1. Initialize the counter in the database. initializeNextLongId("test", initial); // 2. get next short id until limitation of Short for (int i = 0; i <= testCount; i++) { short id = idsTestMaxShortIds.getNextShortId(); assertEquals("The returned id was not what was expected.", i + initial, id); } // 3. in case it reached a max value data type allows, get next short id. try { short id = idsTestMaxShortIds.getNextShortId(); fail("Should not have gotten an id: " + id); } catch (Exception e) { assertTrue(e instanceof FdlException); } } /** * int Id 제공 서비스 테스트 & Max Value 체크 테스트 * * @throws Exception ID 생성 실패시 */ @Test public void testMaxIntegerIds() throws Exception { int testCount = 100; // max is 0x7fffffff long max = Integer.MAX_VALUE; long initial = max - testCount; // 1. Initialize the counter in the database. initializeNextLongId("test", initial); // 2. get next integer id until limitation of Integer for (int i = 0; i <= testCount; i++) { int id = idsTestMaxIntegerIds.getNextIntegerId(); assertEquals("The returned id was not what was expected.", i + initial, id); } // 3. in case it reached a max value data type allows, get next integer id. try { int id = idsTestMaxIntegerIds.getNextIntegerId(); fail("Should not have gotten an id: " + id); } catch (Exception e) { assertTrue(e instanceof FdlException); } } /** * long Id 제공 서비스 테스트 & Max Value 체크 테스트 * * @throws Exception ID 생성 실패시 */ @Test public void testMaxLongIds() throws Exception { int testCount = 100; // max is 0x7fffffffffffffffL long max = Long.MAX_VALUE; long initial = max - testCount; // 1. Initialize the counter in the database. initializeNextLongId("test", initial); // 2. get next long id until limitation of Long for (int i = 0; i <= testCount; i++) { long id = idsTestMaxLongIds.getNextLongId(); assertEquals("The returned id was not what was expected.", i + initial, id); } // 3. in case it reached a max value data type allows, get next long id. try { long id = idsTestMaxLongIds.getNextLongId(); fail("Should not have gotten an id: " + id); } catch (Exception e) { assertTrue(e instanceof FdlException); } } /** * BigDecimal ID 제공 서비스 테스트 * * @throws Exception ID 생성 실패시 */ @Test public void testGetBigDecimalfromNonBigDecimal() throws Exception { if (isBigDecimalImplemented()) { int testCount = 100; BigDecimal initial = new BigDecimal("0"); // 1. Initialize the counter in the database. initializeNextBigDecimalId("test", initial); // 2. get next bigdecimal id for (int i = 0; i < testCount; i++) { BigDecimal id = idsTestSimpleRequestIdsSize100.getNextBigDecimalId(); assertEquals("The returned id was not what was expected.", initial.add(new BigDecimal(i)), id); } // 3. get next integer id using query directly. assertEquals("The next_id column in the database did not have the expected value.", initial.add(new BigDecimal(testCount)), peekNextBigDecimalId("test")); } else { fail("Test failed because BigDecimals are not implemented in current driver."); } } /** * String ID 제공 서비스 * * @throws Exception ID 생성 실패시 */ @Test public void testGetStringIdFromLongId() throws Exception { int testCount = 100; initializeNextLongId("test", 1); for (int i = 1; i <= testCount; i++) { String id = idsTestSimpleRequestIdsSize10.getNextStringId(); assertEquals("The returned id was not what was expected.", new Integer(i).toString(), id); } assertEquals("The next_id column in the database did not have the expected value.", testCount + 1, peekNextLongId("test")); } /** * 테이블정보 없을 시 테스트 * * @throws Exception ID 생성 실패시 */ @Test public void testNotDefinedTableInfo() throws Exception { initializeNextLongId("ids", "id", 1); String id = idsTestNotDefinedTableInfo.getNextStringId(); assertEquals("The returned id was not what was expected.", "1", id); } /** * 정책정보를 포함하는 아이디 생성 서비스 테스트 * * @throws Exception ID 생성 실패시 */ @Test public void testIdGenStrategy() throws Exception { initializeNextLongId("test", 1); // prefix : TEST-, cipers : 5, fillChar :*) for (int i = 0; i < 5; i++) { assertEquals("TEST-****" + (i + 1), idsTestWithGenerationStrategy.getNextStringId()); } initializeNextLongId("ids", "id", 0); String id = idsTestNotDefinedTableInfo.getNextStringId(); assertEquals("0", id); id = idsTestNotDefinedTableInfo.getNextStringId("strategy"); assertEquals("TEST-****1", id); EgovIdGnrStrategyImpl strategy = new EgovIdGnrStrategyImpl("SMPL-", 5, '#'); id = idsTestNotDefinedTableInfo.getNextStringId(strategy); assertEquals("SMPL-####2", id); } /** * 테이블 정보가 없는 경우 테스트 * * @throws Exception */ @Test public void testNonExistingTableName() throws Exception { String id = idsTestNonExistingTableName.getNextStringId(); assertEquals("The returned id was not what was expected.", "0", id); } @Test public void testWithColumnName() throws Exception { initializeNextLongId("test", 10); String id = idsTestWithColumnName.getNextStringId(); assertEquals("The returned id was not what was expected.", "10", id); } /** * 초기값 세팅 * @return boolean 초기값 세팅 성공여부 */ private boolean isBigDecimalImplemented() { String tableName = "foorbar_table"; initializeNextLongId(tableName, 1); try { Connection conn = dataSource.getConnection(); try { Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery("SELECT next_id FROM idttest " + "WHERE table_name = '" + tableName + "'"); if (rs.next()) { rs.getBigDecimal(1); } else { fail(tableName + " row not in ids table."); return false; // for compiler } } finally { conn.close(); } return true; } catch (Exception e) { if (e.toString().toLowerCase().indexOf("implemented") > 0) { return false; } fail("Unable to test for BigDecimal support. " + e); return false; // for compiler } } /** * 초기값 세팅 * @param tableName * table name * @param nextId * next id */ private void initializeNextBigDecimalId(String tableName, BigDecimal nextId) { try { Connection conn = dataSource.getConnection(); try { Statement statement = conn.createStatement(); // Need to quote the BigDecimal as it is larger than normal numbers can be. // Was causing problems with MySQL statement.executeUpdate("INSERT INTO idttest (table_name, next_id) VALUES ('" + tableName + "', '" + nextId.toString() + "')"); } finally { conn.close(); } } catch (Exception e) { fail("Unable to initialize next_id. " + e); } } /** * 초기값 세팅 * * @param tableName table name * @param nextId next id */ private void initializeNextLongId(String tableName, long nextId) { try { Connection conn = dataSource.getConnection(); try { Statement statement = conn.createStatement(); statement.executeUpdate("INSERT INTO idttest (table_name, next_id) VALUES ('" + tableName + "', " + nextId + ")"); } finally { conn.close(); } } catch (Exception e) { fail("Unable to initialize next_id. " + e); } } /** * 초기값 세팅 (물리테이블명 지정) * * @param tableName table name * @param nextId next id */ private void initializeNextLongId(String table, String tableName, long nextId) { try { Connection conn = dataSource.getConnection(); try { Statement statement = conn.createStatement(); // IDS 테이블의 경우 이미 존재하고 있음을 가정.. statement.executeUpdate("UPDATE " + table + " SET next_id = " + nextId + " WHERE table_name = '" + tableName + "'"); } finally { conn.close(); } } catch (Exception e) { fail("Unable to initialize next_id. " + e); } } /** * Query를 통해 BigDecimal 타입의 ID 직접 읽기 * * @param tableName table name * @return next BigDecimal Id */ private BigDecimal peekNextBigDecimalId(String tableName) { try { Connection conn = dataSource.getConnection(); try { Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery("SELECT next_id FROM idttest " + "WHERE table_name = '" + tableName + "'"); if (rs.next()) { return rs.getBigDecimal(1); } else { fail(tableName + " row not in ids table."); return null; // for compiler } } finally { conn.close(); } } catch (Exception e) { fail("Unable to peek next_id. " + e); return null; // for compiler } } /** * Query를 통해 long 타입의 ID 직접 읽기 * * @param tableName table name * @return next Long Id */ private long peekNextLongId(String tableName) { try { Connection conn = dataSource.getConnection(); try { Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery("SELECT next_id FROM idttest " + "WHERE table_name = '" + tableName + "'"); if (rs.next()) { return rs.getLong(1); } else { fail(tableName + " row not in ids table."); return -1; // for compiler } } finally { conn.close(); } } catch (Exception e) { fail("Unable to peek next_id. " + e); return -1; // for compiler } } }