Package org.kiji.schema.impl

Source Code of org.kiji.schema.impl.TestDeveloperValidation

/**
* (c) Copyright 2013 WibiData, Inc.
*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
*/

package org.kiji.schema.impl;

import java.util.Collections;
import java.util.List;

import com.google.common.collect.Lists;
import org.apache.avro.Schema;
import org.apache.avro.Schema.Field;
import org.apache.avro.Schema.Type;
import org.apache.avro.generic.GenericData;
import org.codehaus.jackson.node.IntNode;
import org.codehaus.jackson.node.TextNode;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.kiji.schema.EntityId;
import org.kiji.schema.Kiji;
import org.kiji.schema.KijiClientTest;
import org.kiji.schema.KijiColumnName;
import org.kiji.schema.KijiTable;
import org.kiji.schema.KijiTableWriter;
import org.kiji.schema.avro.AvroSchema;
import org.kiji.schema.avro.CellSchema;
import org.kiji.schema.avro.TableLayoutDesc;
import org.kiji.schema.avro.TestRecord1;
import org.kiji.schema.layout.InvalidLayoutSchemaException;
import org.kiji.schema.layout.KijiTableLayouts;

/**
* Tests layout validation in developer mode.
*/
public class TestDeveloperValidation extends KijiClientTest {
  private static final Logger LOG = LoggerFactory.getLogger(TestDeveloperValidation.class);

  public static final String LAYOUT_DEVELOPER =
      "org/kiji/schema/layout/layout-developer.json";

  private static final Schema SCHEMA_STRING = Schema.create(Type.STRING);
  private static final Schema INT_SCHEMA = Schema.create(Type.INT);
  private static final Schema SCHEMA_LONG = Schema.create(Type.LONG);

  private static final Schema EMPTY_RECORD1 =
      Schema.createRecord("Record1", null, null, false);
  private static final Schema INT_RECORD1 =
      Schema.createRecord("Record1", null, null, false);
  private static final Schema INT_TEXT_RECORD1 =
      Schema.createRecord("Record1", null, null, false);
  private static final Schema INT_ANOTHER_TEXT_RECORD1 =
      Schema.createRecord("Record1", null, null, false);
  static {
    EMPTY_RECORD1.setFields(Collections.<Field>emptyList());
    INT_RECORD1.setFields(Lists.newArrayList(
        new Field("integer", INT_SCHEMA, null, IntNode.valueOf(-1))));
    INT_TEXT_RECORD1.setFields(Lists.newArrayList(
        new Field("integer", INT_SCHEMA, null, IntNode.valueOf(-2)),
        new Field("text", SCHEMA_STRING, null, TextNode.valueOf("record2"))));
    INT_ANOTHER_TEXT_RECORD1.setFields(Lists.newArrayList(
        new Field("integer", INT_SCHEMA, null, IntNode.valueOf(-3)),
        new Field("another_text", SCHEMA_STRING, null, TextNode.valueOf("record3"))));
  }

  /** Tests writer schema registration with no reader schema, ie. no constraint. */
  @Test
  public void testNoReaderSchema() throws Exception {
    final Kiji kiji = getKiji();
    kiji.createTable(KijiTableLayouts.getLayout(LAYOUT_DEVELOPER));
    final KijiTable table = kiji.openTable("dev");
    try {
      final EntityId eid = table.getEntityId("row");
      final KijiTableWriter writer = table.getWriterFactory().openTableWriter();
      try {
        // Registers writer schema 'long':
        writer.put(eid, "info", "user_id", (Long) 1L);

        // Should not need to register writer schema 'long':
        {
          final String layoutIdBefore = table.getLayout().getDesc().getLayoutId();
          writer.put(eid, "info", "user_id", (Long) 2L);
          final String layoutIdAfter = table.getLayout().getDesc().getLayoutId();
          Assert.assertEquals(layoutIdBefore, layoutIdAfter);
        }

        // Register writer schema 'string':
        writer.put(eid, "info", "user_id", "string");

        // Register writer schema for TestRecord1:
        final TestRecord1 record1 = TestRecord1.newBuilder().setInteger(314).build();
        writer.put(eid, "info", "user_id", record1);
      } finally {
        writer.close();
      }

      final List<AvroSchema> expectedIds = Lists.newArrayList(
          AvroSchema.newBuilder()
              .setUid(kiji.getSchemaTable().getOrCreateSchemaId(SCHEMA_LONG))
              .build(),
          AvroSchema.newBuilder()
              .setUid(kiji.getSchemaTable().getOrCreateSchemaId(SCHEMA_STRING))
              .build(),
          AvroSchema.newBuilder()
              .setUid(kiji.getSchemaTable().getOrCreateSchemaId(TestRecord1.SCHEMA$))
              .build());

      final List<AvroSchema> writerSchemaIds =
          table.getLayout().getCellSchema(KijiColumnName.create("info:user_id")).getWriters();
      Assert.assertEquals(expectedIds, writerSchemaIds);

      final List<AvroSchema> writtenSchemaIds =
          table.getLayout().getCellSchema(KijiColumnName.create("info:user_id")).getWritten();
      Assert.assertEquals(expectedIds, writtenSchemaIds);

    } finally {
      table.release();
    }
  }

  /** Tests writer schema compatibility with a LONG reader schema. */
  @Test
  public void testReaderSchemaLong() throws Exception {
    final Kiji kiji = getKiji();
    final TableLayoutDesc desc = KijiTableLayouts.getLayout(LAYOUT_DEVELOPER);
    final CellSchema cellSchema = desc.getLocalityGroups().get(0)
        .getFamilies().get(0)
        .getColumns().get(0)
        .getColumnSchema();
    cellSchema.setReaders(Lists.newArrayList(
        AvroSchema.newBuilder()
            .setUid(kiji.getSchemaTable().getOrCreateSchemaId(SCHEMA_LONG))
            .build()));

    kiji.createTable(desc);
    final KijiTable table = kiji.openTable("dev");
    try {
      final EntityId eid = table.getEntityId("row");
      final KijiTableWriter writer = table.getWriterFactory().openTableWriter();
      try {
        // Registering 'long' as a writer schema: compatible with 'long' reader schema:
        writer.put(eid, "info", "user_id", (Long) 1L);

        // Should not require additional registration:
        {
          final String layoutIdBefore = table.getLayout().getDesc().getLayoutId();
          writer.put(eid, "info", "user_id", (Long) 2L);
          final String layoutIdAfter = table.getLayout().getDesc().getLayoutId();
          Assert.assertEquals(layoutIdBefore, layoutIdAfter);
        }

        // Registering 'int' as a writer schema: compatible with 'long' reader schema:
        writer.put(eid, "info", "user_id", (Integer) 1);

        // Register writer schema 'string' must fail: incompatible with 'long':
        try {
          writer.put(eid, "info", "user_id", "1");
          Assert.fail("Registering writer schema 'string' should fail.");
        } catch (InvalidLayoutSchemaException ilse) {
          LOG.info("Expected error: {}", ilse.toString());
          Assert.assertTrue(ilse.toString().contains(
              "column: 'info:user_id' "
              + "Reader schema: \"long\" is incompatible with writer schema: \"string\""));
        }
      } finally {
        writer.close();
      }

    } finally {
      table.release();
    }
  }

  /** Tests writer schema compatibility with record schemas. */
  @Test
  public void testReaderSchemaTestRecord2() throws Exception {
    final Kiji kiji = getKiji();
    final TableLayoutDesc desc = KijiTableLayouts.getLayout(LAYOUT_DEVELOPER);
    final CellSchema cellSchema = desc.getLocalityGroups().get(0)
        .getFamilies().get(0)
        .getColumns().get(0)
        .getColumnSchema();
    cellSchema.setReaders(Lists.newArrayList(
        AvroSchema.newBuilder()
            .setUid(kiji.getSchemaTable().getOrCreateSchemaId(INT_TEXT_RECORD1))
            .build()));

    kiji.createTable(desc);
    final KijiTable table = kiji.openTable("dev");
    try {
      final EntityId eid = table.getEntityId("row");
      final KijiTableWriter writer = table.getWriterFactory().openTableWriter();
      try {
        // Register writer schema TestRecord1, compatible with reader TestRecord2:
        final GenericData.Record record1 = new GenericData.Record(INT_RECORD1);
        record1.put("integer", 314);
        writer.put(eid, "info", "user_id", record1);

        // Register writer schema TestRecord2, is exactly reader TestRecord2:
        final GenericData.Record record2 = new GenericData.Record(INT_TEXT_RECORD1);
        record2.put("integer", 314);
        record2.put("text", "text");
        writer.put(eid, "info", "user_id", record2);

        // Register writer schema TestRecord3, compatible with reader TestRecord2:
        final GenericData.Record record3 = new GenericData.Record(INT_ANOTHER_TEXT_RECORD1);
        record3.put("integer", 314);
        record3.put("another_text", "text");
        writer.put(eid, "info", "user_id", record3);

        // Any primitive type is incompatible with reader schema TestRecord1:
        try {
          writer.put(eid, "info", "user_id", "1");
          Assert.fail("Registering writer schema 'string' should fail.");
        } catch (InvalidLayoutSchemaException ilse) {
          LOG.info("Expected error: {}", ilse.toString());
          Assert.assertTrue(
              ilse.getMessage(),
              ilse.getMessage().contains("In column: 'info:user_id'"));
          Assert.assertTrue(
              ilse.getMessage(),
              ilse.getMessage().contains("is incompatible with writer schema"));
        }

      } finally {
        writer.close();
      }

    } finally {
      table.release();
    }
  }
}
TOP

Related Classes of org.kiji.schema.impl.TestDeveloperValidation

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.