Package com.linkedin.ggtest

Source Code of com.linkedin.ggtest.TestParser$SortCheckCallback

package com.linkedin.ggtest;


import java.io.FileNotFoundException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericRecord;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.linkedin.databus.core.util.InvalidConfigException;
import com.linkedin.databus.monitoring.mbean.GGParserStatistics.TransactionInfo;
import com.linkedin.databus2.core.DatabusException;
import com.linkedin.databus2.ggParser.XmlStateMachine.DbUpdateState;
import com.linkedin.databus2.ggParser.XmlStateMachine.TransactionState;
import com.linkedin.databus2.ggParser.XmlStateMachine.TransactionSuccessCallBack;
import com.linkedin.databus2.ggParser.staxparser.StaxBuilderTest;
import com.linkedin.databus2.schemas.FileSystemSchemaRegistryService;


/*
*
*  *
*  * Copyright 2013 LinkedIn Corp. All rights reserved
*  *
*  * Licensed under the Apache License, Version 2.0 (the "License");
*  * you may not use this file except in compliance with the License.
*  * You may obtain a copy of the License at
*  *
*  *   http://www.apache.org/licenses/LICENSE-2.0
*  *
*  * Unless required by applicable law or agreed to in writing,
*  * software distributed under the License is distributed on an
*  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*  * KIND, either express or implied.  See the License for the
*  * specific language governing permissions and limitations
*  * under the License.
*
*/
public class TestParser
{

  // TODO Derive this from properties setting via gradle.
  private static final String dataRootDirPropName = "test.ggTestDataDir";
  private static final String schemaDirName = "SchemaRegistry";
  private static final String xmlDataDirName = "XmlData";
  private static final String defaultRootDirName = "./src/test/TestData";
  private String actualXmlDataDir;
  FileSystemSchemaRegistryService service;
  private static final Logger LOG = Logger.getLogger(TestParser.class.getName());


  public boolean checkNonEmptyFields(List<TransactionState.PerSourceTransactionalUpdate> dbUpdates)
  {
      for(TransactionState.PerSourceTransactionalUpdate dbUpdate : dbUpdates)
      {
        Set<DbUpdateState.DBUpdateImage> DBUpdateImage = dbUpdate.getDbUpdatesSet();
        Iterator<DbUpdateState.DBUpdateImage> it =  DBUpdateImage.iterator();
        while(it.hasNext())
        {
          DbUpdateState.DBUpdateImage image = it.next();
          GenericRecord record = image.getGenericRecord();
          Iterator<Schema.Field> fieldIt =  record.getSchema().getFields().iterator();
          while(fieldIt.hasNext())
          {
            String fieldName = fieldIt.next().name();
            if(record.get(fieldName) == null)
              return false;
          }
        }
      }

      return true;
  }



  @BeforeClass
  public void loadSchema()
      throws InvalidConfigException
  {
    String actualSchemaDirName = System.getProperty(dataRootDirPropName, defaultRootDirName);
    actualXmlDataDir = actualSchemaDirName + "/" + xmlDataDirName + "/";

    BasicConfigurator.configure();
    Logger.getRootLogger().setLevel(Level.DEBUG);
    FileSystemSchemaRegistryService.Config configBuilder = new FileSystemSchemaRegistryService.Config();
    configBuilder.setFallbackToResources(true);
    configBuilder.setSchemaDir(actualSchemaDirName + "/" + schemaDirName + "/");
    FileSystemSchemaRegistryService.StaticConfig config = configBuilder.build();
    service = FileSystemSchemaRegistryService.build(config);
  }


  private class BasicOperationsCheckCallback implements TransactionSuccessCallBack
  {
    int iteration = 0;
    @Override
    public void onTransactionEnd(List<TransactionState.PerSourceTransactionalUpdate> dbUpdates, TransactionInfo ti)
    {
      long fieldValue = ((Long)dbUpdates.get(0).getDbUpdatesSet().iterator().next().getKeyPairs().get(0).getKey()).longValue();
      switch(iteration)
      {
        case 0:
          Assert.assertEquals(dbUpdates.size(),1);
          Assert.assertEquals(fieldValue, 492441);
          Assert.assertEquals(checkNonEmptyFields(dbUpdates), true);
          break;
        case 1:
          Assert.assertEquals(dbUpdates.size(),1);
          Assert.assertEquals(fieldValue, 2);
          Assert.assertEquals(checkNonEmptyFields(dbUpdates), true);
          break;
        case 2:
          Assert.assertEquals(dbUpdates.size(),1);
          Assert.assertEquals(fieldValue, 23);
          Assert.assertEquals(checkNonEmptyFields(dbUpdates), true);
          break;
        default:
          break;
      }

      iteration++;
    }
  }

  /**
   * Makes sure there are no exceptions is thrown on parsing xml, verify the keys processed.
   * @throws DatabusException
   * @throws FileNotFoundException
   */
  @Test
  public void basicOperationsTest()
      throws Exception
  {
    BasicOperationsCheckCallback callback = new BasicOperationsCheckCallback();
    StaxBuilderTest test = new StaxBuilderTest(actualXmlDataDir+"basicprocessing.xml",service, callback);
    test.processXml();
  }


  //TODO pending test to complete to capture insert/deletes
  /**
   *  Verify if the parser is able to capture the type of event (UPDATE, DELETE, INSERT)
   */
  @Test
  public void OperationsCheck(){

  }

  /**
   *  Verify if the parser is able to capture all oracle data types
   */
  @Test
  public void verifyAllOracleDataTypes(){

  }

  /**
   *  Checks if the parser it able to construct events with extra fields
   */
  @Test
  public void extraFieldsTest()
      throws Exception
  {
    BasicOperationsCheckCallback callback = new BasicOperationsCheckCallback();
    StaxBuilderTest test = new StaxBuilderTest(actualXmlDataDir+"extrafields.xml",service, callback);
    test.processXml();
  }

  /**
   *  Check if the parser is able to construct event if there spaces, new lines between elements/tags
   */
  @Test
  public void formattingTest()
      throws Exception
  {
    BasicOperationsCheckCallback callback = new BasicOperationsCheckCallback();
    StaxBuilderTest test = new StaxBuilderTest(actualXmlDataDir+"extraspaces.xml",service, callback);
    test.processXml();
  }


  private class keyCompressionCallback implements TransactionSuccessCallBack
  {
    int iteration = 0;
    @Override
    public void onTransactionEnd(List<TransactionState.PerSourceTransactionalUpdate> dbUpdates, TransactionInfo ti)
    {
      long fieldValue = ((Long)dbUpdates.get(0).getDbUpdatesSet().iterator().next().getKeyPairs().get(0).getKey()).longValue();
      switch(iteration)
      {
        case 0:
          Assert.assertEquals(dbUpdates.size(),1);
          Assert.assertEquals(fieldValue, 492441);
          Assert.assertEquals(checkNonEmptyFields(dbUpdates), true);
          break;
        case 1:
          Assert.assertEquals(dbUpdates.size(),1);
          Assert.assertEquals(fieldValue, 2);
          Assert.assertEquals(checkNonEmptyFields(dbUpdates), true);
          Assert.assertEquals(dbUpdates.get(0).getDbUpdatesSet().iterator().next().getGenericRecord().get("lname"), "lastmodified");
          Assert.assertEquals(dbUpdates.get(0).getDbUpdatesSet().size(),1);
          break;
        case 2:
          Assert.assertEquals(dbUpdates.size(),1);
          Assert.assertEquals(fieldValue, 23);
          Assert.assertEquals(checkNonEmptyFields(dbUpdates), true);
          break;
        default:
          break;
      }

      iteration++;
    }
  }

  /**
   * Check key compression. If there are multiple updates on the same key, choose the last one
   */
  @Test
  public void keyCompressionTest()
      throws Exception
  {
    keyCompressionCallback callback = new keyCompressionCallback();
    StaxBuilderTest test = new StaxBuilderTest(actualXmlDataDir+"keyCompression.xml",service, callback);
    test.processXml();
  }

  /**
   * Missing scn should throw an exception
   */
  @Test
  public void missingScnCheck()
      throws Exception
  {
    BasicOperationsCheckCallback callback = new BasicOperationsCheckCallback();
    try{
      StaxBuilderTest test = new StaxBuilderTest(actualXmlDataDir+"missingscn.xml",service, callback);
      test.processXml();
      Assert.fail("Test has not detected failure on missing scn");
    }
    catch(DatabusException e)
    {
      LOG.info("Caught databus exception, verifying if it's for missing scn..");
      String error = e.getMessage();
      String expected = "Unable to find scn for the given dbUpdate, terminating the parser";
      Assert.assertEquals(error, expected);
    }
  }

  /**
   * Missing tokens fields, this should terminate the parser
   */
  @Test
  public void missingTokensCheck()
      throws Exception
  {
    BasicOperationsCheckCallback callback = new BasicOperationsCheckCallback();
    try{
      StaxBuilderTest test = new StaxBuilderTest(actualXmlDataDir+"missingtokens.xml",service, callback);
      test.processXml();
      Assert.fail("Test has not detected failure on missing tokens");
    }
    catch(DatabusException e)
    {
      LOG.info("Caught databus exception, verifying if it's for missing tokens..");
      String error = e.getMessage();
      String expected = "The current state is : columns(ENDELEMENT) the expected state was: [tokens(STARTELEMENT)]. The next state found was: dbupdate(ENDELEMENT)";
      Assert.assertEquals(error,expected);
    }
  }


  private class NullFieldsCallback implements TransactionSuccessCallBack
  {
    int iteration = 0;
    @Override
    public void onTransactionEnd(List<TransactionState.PerSourceTransactionalUpdate> dbUpdates, TransactionInfo ti)
    {
      long fieldValue = ((Long)dbUpdates.get(0).getDbUpdatesSet().iterator().next().getKeyPairs().get(0).getKey()).longValue();
      switch(iteration)
      {
        case 0:
          Assert.assertEquals(dbUpdates.size(),1);
          Assert.assertEquals(fieldValue, 492441);
          Assert.assertEquals(dbUpdates.get(0).getDbUpdatesSet().iterator().next().getGenericRecord().get("X1"), null);
          //Assert.assertEquals(checkNonEmptyFields(dbUpdates), true);
          break;
        case 1:
          Assert.assertEquals(dbUpdates.size(),1);
          Assert.assertEquals(fieldValue, 2);
          //Assert.assertEquals(checkNonEmptyFields(dbUpdates), true);
          break;
        default:
          break;
      }

      iteration++;
    }
  }


  /**
   * Test for null/empty fields, this should not terminate the parser. The test will verify is the field returns null
   */
  @Test
  public void nullFieldsCheck()
      throws Exception
  {
    NullFieldsCallback callback = new NullFieldsCallback();
    StaxBuilderTest test = new StaxBuilderTest(actualXmlDataDir+"nullfields.xml",service, callback);
    test.processXml();
  }

  private class SortCheckCallback implements TransactionSuccessCallBack
  {

    private boolean checkIfSetContainsKey(Set<DbUpdateState.DBUpdateImage> dbUpdatesSet, Long[] keys){

      if(dbUpdatesSet.size() == 0)
        return false;

      for(int i = 0 ; i< keys.length; i++)
      {
        boolean foundCurrentKey = false;
        Iterator<DbUpdateState.DBUpdateImage> it = dbUpdatesSet.iterator();
        while(it.hasNext())                           //Search all updates for the current key
        {
           if(it.next().getKeyPairs().get(0).getKey().equals(keys[i]))   //TODO change on introducting composite keys
              foundCurrentKey = true;
        }

        if(!foundCurrentKey) return false;
      }

      return true;
   }

    @Override
    public void onTransactionEnd(List<TransactionState.PerSourceTransactionalUpdate> dbUpdates, TransactionInfo ti)
    {
      Assert.assertEquals(dbUpdates.size(),3);
      Assert.assertEquals(dbUpdates.get(0).getSourceId(), 401);
      Assert.assertEquals(dbUpdates.get(1).getSourceId(), 402);
      Assert.assertEquals(dbUpdates.get(2).getSourceId(), 403);
      Set<DbUpdateState.DBUpdateImage> dbUpdatesSet = dbUpdates.get(0).getDbUpdatesSet();
      Assert.assertTrue(dbUpdatesSet.size() == 2 && checkIfSetContainsKey(dbUpdatesSet,new Long[]{Long.valueOf(10), Long.valueOf(
          11)}));
      dbUpdatesSet = dbUpdates.get(1).getDbUpdatesSet();
      Assert.assertTrue(dbUpdatesSet.size() == 2 && checkIfSetContainsKey(dbUpdatesSet,new Long[]{Long.valueOf(20), Long.valueOf(
          21)}));
      dbUpdatesSet = dbUpdates.get(2).getDbUpdatesSet();
      Assert.assertTrue(dbUpdatesSet.size() == 1 && checkIfSetContainsKey(dbUpdatesSet,new Long[]{Long.valueOf(30)}));

    }
  }

  /**
   * Test to see if all the updates within a given transaction are clubbed to together by source, and is sorted by source.
   */
  @Test
  public void sortMultipleSourcesCheck()
      throws Exception
  {
    SortCheckCallback callback = new SortCheckCallback();
    StaxBuilderTest test = new StaxBuilderTest(actualXmlDataDir+"sortMultipleSources.xml",service, callback);
    test.processXml();
  }

  /**
   *  Checks if the parser it able to advance SCNs when there are no events for the current source
   */
  @Test
  public void nullTransactionsTest()
      throws Exception
  {
    BasicOperationsCheckCallback callback = new BasicOperationsCheckCallback();
    StaxBuilderTest test = new StaxBuilderTest(actualXmlDataDir+"nullTransactions.xml",service, callback);
    test.processXml();
  }

}



//TODO Unit test to peek into the primary key type (verify it's non null and NOT of type schema)
//TODO test addToBuffer Method
TOP

Related Classes of com.linkedin.ggtest.TestParser$SortCheckCallback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.