Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Derived codec can't decode after binary serde of encoded data #351

Closed
catostrophe opened this issue May 18, 2021 · 0 comments
Closed

Derived codec can't decode after binary serde of encoded data #351

catostrophe opened this issue May 18, 2021 · 0 comments
Labels
bug Something isn't working

Comments

@catostrophe
Copy link

Failing test:

import cats.data.NonEmptyList
import org.apache.avro.generic.GenericData
import org.scalacheck.ScalacheckShapeless
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
import org.apache.avro.Schema
import org.apache.avro.generic.{GenericDatumReader, GenericDatumWriter}
import org.apache.avro.io.{DecoderFactory, EncoderFactory}
import vulcan.Codec
import vulcan.generic._

import java.io.ByteArrayOutputStream

class Test extends AnyFlatSpec with Matchers with ScalaCheckDrivenPropertyChecks with ScalacheckShapeless {

  case class Abracadabra(qwe: Option[NonEmptyList[Int]])

  it should "decode after encoding and binary serde" in {

    def serde(schema: Schema)(a: Any): Any = {
      val writer = new GenericDatumWriter[Any](schema)
      val out = new ByteArrayOutputStream
      val encoder = EncoderFactory.get.binaryEncoder(out, null)
      val ba =
        try {
          writer.write(a, encoder)
          encoder.flush()
          out.toByteArray
        } finally out.close()

      val reader = new GenericDatumReader[Any](schema)
      val decoder = DecoderFactory.get.binaryDecoder(ba, null)
      val record = reader.read(null, decoder)

      record
    }

    val codec: Codec[Abracadabra] = Codec.derive[Abracadabra]
    val schema = codec.schema.toOption.get

    forAll { (x: Abracadabra) =>
      val encoded = codec.encode(x).toOption.get
      val serded = serde(schema)(encoded)

      val b1 = encoded.asInstanceOf[GenericData.Record] == serded.asInstanceOf[GenericData.Record]

      val r1 = codec.decode(encoded, schema)
      val r2 = codec.decode(serded, schema)

      println(x)
      println(b1)
      println(r1)
      println(r2)
      assert(r1 == r2)
    }
  }

}

It fails with:

AvroError(Error decoding Test.Abracadabra: Error decoding Option: Error decoding union: Missing alternative array in union)

The type of data that causes error is: Option[NonEmptyList[Int]]

@bplommer bplommer added the bug Something isn't working label May 18, 2021
bplommer added a commit that referenced this issue May 18, 2021
bplommer added a commit that referenced this issue May 18, 2021
bplommer added a commit that referenced this issue May 18, 2021
bplommer added a commit that referenced this issue May 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

2 participants