MigrationTest

package com.truegames.ldapmigration;

import org.junit.After;

import org.junit.Before;

import org.junit.BeforeClass;

import org.junit.Test;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import org.springframework.core.io.FileSystemResource;

import java.io.BufferedReader;

import java.io.File;

import java.io.FileReader;

import java.io.IOException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import static com.truegames.ldapmigration.Group.*;

import static com.truegames.ldapmigration.dao.TGIPersonDao.*;

import static org.junit.Assert.assertEquals;

import static org.junit.Assert.assertTrue;

public class MigrationTest {

private static final String CR = System.getProperty("line.separator");

private static MigrationManager migrationManager;

public static final String[] memberSectionBorders = new String[]{"dn: cn=" + enum1.getGroupName(),

"dn: cn=" + enum2.getGroupName(),

"dn: cn=" + enum3.getGroupName(),

"dn: cn=" + enum4.getGroupName()};

public static final String testList1FileName = "repo/exportedLdifFiles/ldif-list1.txt";

public static final String testList2FileName = "repo/exportedLdifFiles/ldif-list2.txt";

public static final String testList3FileName = "repo/exportedLdifFiles/ldif-list3.txt";

public static final String testList4FileName = "repo/exportedLdifFiles/ldif-list4.txt";

private LineHandler nameCountLineHandler;

private LineHandler fieldCountLineHandler;

private LineHandler doNotIncludeLineHandler;

private LineHandler dnEntryChecker;

private List<LineHandler> handlers;

@BeforeClass

public static void oneSetUp() throws Exception {

BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/config/TestLDAPMigrationApplicationContext.xml");

migrationManager = beanFactory.getBean("migrationManager", MigrationManager.class);

writeLdifFileFor(enum1);

writeLdifFileFor(enum2);

writeLdifFileFor(enum3);

writeLdifFileFor(enum4);

}

@Before

public void setUp() throws Exception {

nameCountLineHandler = new NameCountLineHandler();

doNotIncludeLineHandler = new DoNotIncludeLineHandler();

dnEntryChecker = new DnEntryChecker();

handlers = new ArrayList<LineHandler>();

handlers.add(nameCountLineHandler);

handlers.add(doNotIncludeLineHandler);

handlers.add(dnEntryChecker);

}

@After

public void tearDown() throws Exception {

}

private void setupTth() throws Exception {

fieldCountLineHandler = new FieldCountLineHandler(enum1);

handlers.add(fieldCountLineHandler);

readFile(testList1FileName, handlers);

}

private void readFile(String ldifFileName, List<LineHandler> handlers) throws Exception {

List<String> lines = readLdif(new FileSystemResource(ldifFileName).getFile());

int lineCount = 0;

for (String line : lines) {

lineCount++;

if (startingGroupListing(line)) {

for (LineHandler handler : handlers) {

handler.startGroupEntry(line, lineCount);

}

}

for (LineHandler handler : handlers) {

handler.handleLine(line, lineCount);

}

}

for (LineHandler handler : handlers) {

handler.allDone(lineCount);

}

}

private boolean startingGroupListing(String line) {

for (String border : memberSectionBorders) {

if (line.startsWith(border)) {

return true;

}

}

return false;

}

private static class DnEntryChecker

extends LineHandlerAdapter {

boolean pass = true;

private List<Integer> failedLineNumbers = new ArrayList<Integer>();

@Override

public void handleLine(String line, int lineCount) {

if (line.startsWith("dn: ")) {

if (!line.endsWith("dc=games,dc=truegames,dc=com")) {

pass = false;

failedLineNumbers.add(lineCount);

}

}

}

@Override

public void asserts() {

StringBuffer buf = new StringBuffer();

if (failedLineNumbers.size() > 0) {

for (Integer number : failedLineNumbers) {

buf.append(number).append(",");

}

if (buf.length() > 0) {

buf.setLength(buf.length() - 1);// remove final comma

}

}

assertTrue("There are dn lines that don't have dc=games,dc=truegames,dc=com: " + buf, failedLineNumbers.size() == 0);

}

}

private static class DoNotIncludeLineHandler

extends LineHandlerAdapter {

private List<Integer> failedLineNumbers = new ArrayList<Integer>();

@Override

public void handleLine(String line, int lineCount) {

if (!startedGroupEntries) {

if (line.contains(ou + ":") || line.contains(member + ":")) {

failedLineNumbers.add(lineCount);

}

}

}

@Override

public void asserts() {

StringBuffer buf = new StringBuffer();

if (failedLineNumbers.size() > 0) {

for (Integer number : failedLineNumbers) {

buf.append(number).append(",");

}

if (buf.length() > 0) {

buf.setLength(buf.length() - 1);// remove final comma

}

}

assertTrue("There are lines containing entries we don't want: " + buf, failedLineNumbers.size() == 0);

}

}

private static class NameCountLineHandler

extends LineHandlerAdapter {

private Map<String, Integer> nameCounts = new HashMap<String, Integer>();

private Map<String, Integer> failNameCounts = new HashMap<String, Integer>();

private List<String> memberNameList = new ArrayList<String>();

private boolean nameMemberMatch = true;

private int nameCount = 0;

private int memberNameCount = 0;

@Override

public void handleLine(String line, int lineCount) {

if (!startedGroupEntries) {

String name;

if ((name = getName(line)) != null && !name.equals("aGame")) {

Integer count = nameCounts.get(name);

if (count == null) {

count = 0;

}

nameCounts.put(name, ++count);

nameCount++;

}

}

else {

// get a list of member names

if (line.startsWith(member + ": cn=")) {

String name = line.substring(11, line.indexOf(","));

if (name.equals("default")) {

return; // Ignore the "default" member

}

memberNameList.add(name);

memberNameCount++;

}

}

}

@Override

public void allDone(int totalLines) {

for (String key : nameCounts.keySet()) {

if (nameCounts.get(key) > 1) {

failNameCounts.put(key, nameCounts.get(key));

}

}

// Check member names against the map of names

for (String name : memberNameList) {

if (nameCounts.get(name) == null) {

nameMemberMatch = false;

}

}

for (String name : nameCounts.keySet()) {

if (!memberNameList.contains(name)) {

nameMemberMatch = false;

}

}

System.out.println();

}

@Override

public void asserts() {

StringBuffer buf = new StringBuffer();

if (failNameCounts.size() > 0) {

for (String name : nameCounts.keySet()) {

buf.append(name);

buf.append(":");

buf.append(failNameCounts.get(name));

buf.append(",");

}

}

if (buf.length() > 0) {

buf.setLength(buf.length() - 1);// remove final comma

}

// Should be as many instances of someone's name ("cn: " + name) as there are keys in the map

assertEquals("Too many instances of some names: " + buf, 0, failNameCounts.size());

// Should be the same number of

/*

404 differences.

Looks like most are case-sensitivity issues

*/

assertEquals("Name count and member count unequal.s", nameCounts.size(), memberNameList.size());

assertEquals("Name count and member count unequal.", nameCount, memberNameCount);

// EVERY name in member list should have been found in the main entry list

assertTrue("NOT EVERY name in member list should have been found in the main entry list", nameMemberMatch);

}

}

private static class FieldCountLineHandler

extends LineHandlerAdapter {

int actualRegistrationDateCount = 0;

int actualObjectClassCount = 0;

int birthdayCount = 0;

int expectedObjectClassCount = 0;

private Group group;

public FieldCountLineHandler(Group group) {

this.group = group;

expectedObjectClassCount = group.getNameCount() * 5; // Should be 5 entries for each name

}

@Override

public void handleLine(String line, int lineCount) {

if (startedGroupEntries) {

return;

}

if (line.startsWith(objectClass)) {

actualObjectClassCount++;

}

if (line.startsWith(registrationDate)) {

actualRegistrationDateCount++;

}

if (line.startsWith(birthDay)) {

birthdayCount++;

}

}

@Override

public void asserts() {

assertEquals("Number of registrationDate entries didn't match.s", group.getNameCount(), actualRegistrationDateCount);

assertEquals("Number of objectClass entries didn't match.", expectedObjectClassCount, actualObjectClassCount);

assertEquals("Number of birthday entries didn't match.", group.getNameCount(), birthdayCount);

}

}

private static interface LineHandler {

void handleLine(String line, int lineCount);

void allDone(int totalLines);

void asserts();

void startGroupEntry(String line, int lineCount);

}

private static class LineHandlerAdapter

implements LineHandler {

protected boolean startedGroupEntries;

@Override

public void handleLine(String line, int lineCount) {

}

@Override

public void allDone(int totalLines) {

}

@Override

public void asserts() {

}

@Override

public void startGroupEntry(String line, int lineCount) {

startedGroupEntries = true;

}

protected String getName(String line) {

return line.startsWith("cn: ") ? line.substring(4) : null;

}

}

// =====================================================================================================================

// =====================================================================================================================

// No interesting code beyond here...

// =====================================================================================================================

// =====================================================================================================================

private static void writeLdifFileFor(Group group) throws Exception {

List<String> names = null;

String filename = null;

switch (group) {

case enum1:

names = migrationManager.getTthNames();

filename = testList1FileName;

break;

case enum2:

names = migrationManager.getMmorpgNames();

filename = testList2FileName;

break;

case enum3:

names = migrationManager.getChampsNames();

filename = testList3FileName;

break;

case enum4:

names = migrationManager.getOriginalsNames();

filename = testList4FileName;

migrationManager.writeNamesToLdif(names, filename);

break;

}

migrationManager.processGroupEntry(names, filename, group);

int size = names.size();

if (group.getNameCount() != size) {

throw new IllegalStateException("Name sizes mismatch: " + group.getGroupName());

}

group.setNameCount(size);

}

private List<String> readLdif(File resource) throws IOException {

BufferedReader in = null;

ArrayList<String> names = new ArrayList<String>();

try {

in = new BufferedReader(new FileReader(resource));

String line;

while ((line = in.readLine()) != null) {

names.add(line);

}

} finally {

if (in != null) {

in.close();

}

}

return names;

}

@Test

public void testTthNameCount() throws Exception {

setupTth();

nameCountLineHandler.asserts();

}

@Test

public void testTthFieldCount() throws Exception {

setupTth();

fieldCountLineHandler.asserts();

}

@Test

public void testTthDoNotInclude() throws Exception {

setupTth();

doNotIncludeLineHandler.asserts();

}

@Test

public void testTthDnEntries() throws Exception {

setupTth();

dnEntryChecker.asserts();

}

private void setupMmorpg() throws Exception {

fieldCountLineHandler = new FieldCountLineHandler(enum2);

handlers.add(fieldCountLineHandler);

readFile(testList2FileName, handlers);

}

@Test

public void testMmorpgNameCount() throws Exception {

setupMmorpg();

nameCountLineHandler.asserts();

}

@Test

public void testMmorpgFieldCount() throws Exception {

setupMmorpg();

fieldCountLineHandler.asserts();

}

@Test

public void testMmorpgDoNotInclude() throws Exception {

setupMmorpg();

doNotIncludeLineHandler.asserts();

}

@Test

public void testMmorpgDnEntries() throws Exception {

setupMmorpg();

dnEntryChecker.asserts();

}

private void setupChamps() throws Exception {

fieldCountLineHandler = new FieldCountLineHandler(enum3);

handlers.add(fieldCountLineHandler);

readFile(testList3FileName, handlers);

}

@Test

public void testChampsNameCount() throws Exception {

setupChamps();

nameCountLineHandler.asserts();

}

@Test

public void testChampsFieldCount() throws Exception {

setupChamps();

fieldCountLineHandler.asserts();

}

@Test

public void testChampsDoNotInclude() throws Exception {

setupChamps();

doNotIncludeLineHandler.asserts();

}

@Test

public void testChampsDnEntries() throws Exception {

setupChamps();

dnEntryChecker.asserts();

}

private void setupOriginals() throws Exception {

fieldCountLineHandler = new FieldCountLineHandler(enum4);

handlers.add(fieldCountLineHandler);

readFile(testList4FileName, handlers);

}

@Test

public void testOriginalsNameCount() throws Exception {

setupOriginals();

nameCountLineHandler.asserts();

}

@Test

public void testOriginalsFieldCount() throws Exception {

setupOriginals();

fieldCountLineHandler.asserts();

}

@Test

public void testOriginalsDoNotInclude() throws Exception {

setupOriginals();

doNotIncludeLineHandler.asserts();

}

@Test

public void testOriginalsDnEntries() throws Exception {

setupOriginals();

dnEntryChecker.asserts();

}

/*

* Run against the original lists

*/

@Test

public void testNamesEndingIn1() throws Exception {

checkNamesEndingIn1(migrationManager.getMmorpgNames());

checkNamesEndingIn1(migrationManager.getTthNames());

checkNamesEndingIn1(migrationManager.getChampsNames());

}

/*

* Run against the original lists

*/

private void checkNamesEndingIn1(List<String> names) {

List<String> namesEndingInOne = new ArrayList<String>();

for (String nameWith1 : names) {

if (nameWith1.endsWith("1")) {

for (String name : names) {

if (nameWith1.substring(0, nameWith1.length() - 1).equals(name)) {

namesEndingInOne.add(nameWith1);

}

}

}

}

if (namesEndingInOne.size() > 0) {

System.out.println("-----------------------------");

System.out.println("Some names end in '1':");

}

for (String nameEndingInOne : namesEndingInOne) {

System.out.println(nameEndingInOne);

}

if (namesEndingInOne.size() > 0) {

System.out.println("-----------------------------");

}

assertEquals("We have some names ending in 1", 0, namesEndingInOne.size());

}

}