Package org.apache.avro.specific

Source Code of org.apache.avro.specific.TestSpecificCompiler

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.apache.avro.specific;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;

import org.apache.avro.AvroTestUtil;
import org.apache.avro.Protocol;
import org.apache.avro.Schema;
import org.apache.avro.TestProtocolParsing;
import org.apache.avro.TestSchema;
import org.apache.avro.specific.SpecificCompiler.OutputFile;
import org.junit.Test;


public class TestSpecificCompiler {
  @Test
  public void testEsc() {
    assertEquals("\\\"", SpecificCompiler.esc("\""));
  }

  @Test
  public void testMakePath() {
    assertEquals("foo/bar/Baz.java".replace("/", File.separator), SpecificCompiler.makePath("Baz", "foo.bar"));
    assertEquals("baz.java", SpecificCompiler.makePath("baz", ""));
  }

  @Test
  public void testPrimitiveSchemaGeneratesNothing() {
    assertEquals(0, new SpecificCompiler(Schema.parse("\"double\"")).compile().size());
  }

  @Test
  public void testSimpleEnumSchema() throws IOException {
    Collection<OutputFile> outputs = new SpecificCompiler(Schema.parse(TestSchema.BASIC_ENUM_SCHEMA)).compile();
    assertEquals(1, outputs.size());
    OutputFile o = outputs.iterator().next();
    assertEquals(o.path, "Test.java");
    assertTrue(o.contents.contains("public enum Test"));
    assertCompilesWithJavaCompiler(outputs);
  }

  @Test
  public void testMangleIfReserved() {
    assertEquals("foo", SpecificCompiler.mangle("foo"));
    assertEquals("goto$", SpecificCompiler.mangle("goto"));
  }

  @Test
  public void testManglingForProtocols() throws IOException {
    String protocolDef = "" +
      "{ \"protocol\": \"default\",\n" +
      "  \"types\":\n" +
      "    [\n" +
      "      {\n" +
      "       \"name\": \"finally\",\n" +
      "       \"type\": \"error\",\n" +
      "       \"fields\": [{\"name\": \"catch\", \"type\": \"boolean\"}]\n" +
      "      }\n" +
      "    ],\n" +
      "  \"messages\": { \"goto\":\n" +
      "    { \"request\": [{\"name\": \"break\", \"type\": \"string\"}],\n" +
      "      \"response\": \"string\",\n" +
      "      \"errors\": [\"finally\"]\n" +
      "    }" +
      "   }\n" +
      "}\n";
    Collection<OutputFile> c =
      new SpecificCompiler(Protocol.parse(protocolDef)).compile();
    Iterator<OutputFile> i = c.iterator();
    String errType = i.next().contents;
    String protocol = i.next().contents;

    assertTrue(errType.contains("public class finally$ extends org.apache.avro.specific.SpecificExceptionBase"));
    assertTrue(errType.contains("public boolean catch$;"));

    assertTrue(protocol.contains("java.lang.CharSequence goto$(java.lang.CharSequence break$)"));
    assertTrue(protocol.contains("public interface default$"));
    assertTrue(protocol.contains("throws org.apache.avro.ipc.AvroRemoteException, finally$"));
   
    assertCompilesWithJavaCompiler(c);

  }

  @Test
  public void testManglingForRecords() throws IOException {
    String schema = "" +
      "{ \"name\": \"volatile\", \"type\": \"record\", " +
      "  \"fields\": [ {\"name\": \"package\", \"type\": \"string\" }," +
      "                {\"name\": \"short\", \"type\": \"volatile\" } ] }";
    Collection<OutputFile> c =
      new SpecificCompiler(Schema.parse(schema)).compile();
    assertEquals(1, c.size());
    String contents = c.iterator().next().contents;

    assertTrue(contents.contains("public java.lang.CharSequence package$;"));
    assertTrue(contents.contains("class volatile$ extends"));
    assertTrue(contents.contains("volatile$ short$;"));
   
    assertCompilesWithJavaCompiler(c);
  }

  @Test
  public void testManglingForEnums() throws IOException {
    String enumSchema = "" +
      "{ \"name\": \"instanceof\", \"type\": \"enum\"," +
      "  \"symbols\": [\"new\", \"super\", \"switch\"] }";
    Collection<OutputFile> c =
      new SpecificCompiler(Schema.parse(enumSchema)).compile();
    assertEquals(1, c.size());
    String contents = c.iterator().next().contents;

    assertTrue(contents.contains("new$"));
   
    assertCompilesWithJavaCompiler(c);
  }

  @Test
  public void testSchemaWithDocs() {
    Collection<OutputFile> outputs = new SpecificCompiler(
        Schema.parse(TestSchema.SCHEMA_WITH_DOC_TAGS)).compile();
    assertEquals(3, outputs.size());
    int count = 0;
    for (OutputFile o : outputs) {
      if (o.path.endsWith("outer_record.java")) {
        count++;
        assertTrue(o.contents.contains("/** This is not a world record. */"));
        assertTrue(o.contents.contains("/** Inner Fixed */"));
        assertTrue(o.contents.contains("/** Inner Enum */"));
        assertTrue(o.contents.contains("/** Inner String */"));
      }
      if (o.path.endsWith("very_inner_fixed.java")) {
        count++;
        assertTrue(o.contents.contains("/** Very Inner Fixed */"));
        assertTrue(o.contents.contains("@org.apache.avro.specific.FixedSize(1)"));
      }
      if (o.path.endsWith("very_inner_enum.java")) {
        count++;
        assertTrue(o.contents.contains("/** Very Inner Enum */"));
      }
    }
    assertEquals(3, count);
  }
 
  @Test
  public void testProtocolWithDocs() throws IOException {
    Protocol protocol = TestProtocolParsing.getSimpleProtocol();
    Collection<OutputFile> out = new SpecificCompiler(protocol).compile();
    assertEquals(5, out.size());
    int count = 0;
    for (OutputFile o : out) {
      if (o.path.endsWith("Simple.java")) {
        count++;
        assertTrue(o.contents.contains("/** Protocol used for testing. */"));
        assertTrue(o.contents.contains("/** Send a greeting */"));
      }
    }
    assertEquals("Missed generated protocol!", 1, count);
  }
 
  @Test
  public void testNeedCompile() throws IOException, InterruptedException {
    String schema = "" +
      "{ \"name\": \"Foo\", \"type\": \"record\", " +
      "  \"fields\": [ {\"name\": \"package\", \"type\": \"string\" }," +
      "                {\"name\": \"short\", \"type\": \"Foo\" } ] }";
    File inputFile = File.createTempFile("input", "avsc");
    FileWriter fw = new FileWriter(inputFile);
    fw.write(schema);
    fw.close();
   
    File outputDir = new File(System.getProperty("test.dir") +
      System.getProperty("file.separator") + "test_need_compile");
    File outputFile = new File(outputDir, "Foo.java");
    outputFile.delete();
    assertTrue(!outputFile.exists());
    outputDir.delete();
    assertTrue(!outputDir.exists());
    SpecificCompiler.compileSchema(inputFile, outputDir);
    assertTrue(outputDir.exists());
    assertTrue(outputFile.exists());

    long lastModified = outputFile.lastModified();
    Thread.sleep(1000)//granularity of JVM doesn't seem to go below 1 sec
    SpecificCompiler.compileSchema(inputFile, outputDir);
    assertEquals(lastModified, outputFile.lastModified());
   
    fw = new FileWriter(inputFile);
    fw.write(schema);
    fw.close();
    SpecificCompiler.compileSchema(inputFile, outputDir);
    assertTrue(lastModified != outputFile.lastModified());
  }

  /**
   * Checks that a schema passes through the SpecificCompiler, and,
   * optionally, uses the system's Java compiler to check
   * that the generated code is valid.
   */
  public static void
      assertCompiles(Schema schema, boolean useJavaCompiler)
  throws IOException {
    Collection<OutputFile> outputs = new SpecificCompiler(schema).compile();
    assertTrue(null != outputs);
    if (useJavaCompiler) {
      assertCompilesWithJavaCompiler(outputs);
    }
  }
 
  /**
   * Checks that a protocol passes through the SpecificCompiler,
   * and, optionally, uses the system's Java compiler to check
   * that the generated code is valid.
   */
  public static void assertCompiles(Protocol protocol, boolean useJavaCompiler)
  throws IOException {
    Collection<OutputFile> outputs = new SpecificCompiler(protocol).compile();
    assertTrue(null != outputs);
    if (useJavaCompiler) {
      assertCompilesWithJavaCompiler(outputs);
    }
  }
 
  /** Uses the system's java compiler to actually compile the generated code. */
  static void assertCompilesWithJavaCompiler(Collection<OutputFile> outputs)
  throws IOException {
    if (outputs.isEmpty()) {
      return;               // Nothing to compile!
    }
    File dstDir = AvroTestUtil.tempFile("realCompiler");
    List<File> javaFiles = new ArrayList<File>();
    for (OutputFile o : outputs) {
      javaFiles.add(o.writeToDestination(null, dstDir));
    }

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager =
      compiler.getStandardFileManager(null, null, null);
   
    CompilationTask cTask = compiler.getTask(null, fileManager, null, null,
        null,
        fileManager.getJavaFileObjects(
            javaFiles.toArray(new File[javaFiles.size()])));
    assertTrue(cTask.call());
  }
}
TOP

Related Classes of org.apache.avro.specific.TestSpecificCompiler

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.