From 147a1c19c1f7bfe8d0939618d3c8dc2bb4e59fb7 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sun, 10 Dec 2023 20:54:33 +0100 Subject: Add more property-based tests and fix more bugs. Change-Id: I8deb1a7d75078c037714541d8f6f656052c2476c --- .../ostree/OstreeDecoderPropertyTest.java | 225 ++++++++++++++++++++- 1 file changed, 222 insertions(+), 3 deletions(-) (limited to 'jgvariant-ostree/src/test') diff --git a/jgvariant-ostree/src/test/java/eu/mulk/jgvariant/ostree/OstreeDecoderPropertyTest.java b/jgvariant-ostree/src/test/java/eu/mulk/jgvariant/ostree/OstreeDecoderPropertyTest.java index acd11c4..da15ff2 100644 --- a/jgvariant-ostree/src/test/java/eu/mulk/jgvariant/ostree/OstreeDecoderPropertyTest.java +++ b/jgvariant-ostree/src/test/java/eu/mulk/jgvariant/ostree/OstreeDecoderPropertyTest.java @@ -1,6 +1,9 @@ package eu.mulk.jgvariant.ostree; +import static org.junit.jupiter.api.Assertions.assertEquals; + import eu.mulk.jgvariant.core.Decoder; +import java.util.List; import java.util.Map; import net.jqwik.api.*; @@ -21,14 +24,88 @@ class OstreeDecoderPropertyTest { } } + @Group + class DeltaSuperblockRoundtripLaw implements RoundtripLaw { + + @Override + public Decoder decoder() { + return DeltaSuperblock.decoder(); + } + + @Override + public Arbitrary anyT() { + return anyDeltaSuperblock(); + } + } + + @Group + @Disabled( + "Not implemented correctly: Requires enough file entries to parse all the delta operations.") + class DeltaPartPayloadRoundtripLaw implements RoundtripLaw { + + @Override + public Decoder decoder() { + // FIXME + var deltaMetaEntry = new DeltaMetaEntry(0, Checksum.zero(), 0, 0, List.of()); + return DeltaPartPayload.decoder(deltaMetaEntry); + } + + @Override + public Arbitrary anyT() { + return anyDeltaPartPayload(); + } + } + + @Group + class DirTreeRoundtripLaw implements RoundtripLaw { + + @Override + public Decoder decoder() { + return DirTree.decoder(); + } + + @Override + public Arbitrary anyT() { + return anyDirTree(); + } + } + + @Group + class DirMetaRoundtripLaw implements RoundtripLaw { + + @Override + public Decoder decoder() { + return DirMeta.decoder(); + } + + @Override + public Arbitrary anyT() { + return anyDirMeta(); + } + } + + @Group + class CommitRoundtripLaw implements RoundtripLaw { + + @Override + public Decoder decoder() { + return Commit.decoder(); + } + + @Override + public Arbitrary anyT() { + return anyCommit(); + } + } + interface RoundtripLaw { @Property - default boolean roundtripsWell(@ForAll(value = "anyT") T entityLeft) { + default void roundtripsWell(@ForAll(value = "anyT") T entityLeft) { var decoder = decoder(); var bytes = decoder.encode(entityLeft); var entityRight = decoder.decode(bytes); - return entityLeft.equals(entityRight); + assertEquals(entityLeft, entityRight); } Decoder decoder(); @@ -61,6 +138,148 @@ class OstreeDecoderPropertyTest { @Provide Arbitrary anyChecksum() { - return Arbitraries.of(new Checksum(new ByteString(new byte[32]))); + return Arbitraries.bytes() + .array(byte[].class) + .ofSize(32) + .map(ByteString::new) + .map(Checksum::new); + } + + @Provide + Arbitrary anyDeltaSuperblock() { + return Combinators.combine( + anyMetadata(), + Arbitraries.longs(), + anyChecksum(), + anyChecksum(), + anyCommit(), + anyDeltaName().list(), + anyDeltaMetaEntry().list(), + anyDeltaFallback().list()) + .as(DeltaSuperblock::new); + } + + @Provide + Arbitrary anyDeltaPartPayload() { + return Combinators.combine( + anyFileMode().list(), + anyXattr().list().list(), + anyByteString(), + anyDeltaOperation().list()) + .as(DeltaPartPayload::new); + } + + @Provide + Arbitrary anyDeltaOperation() { + return Arbitraries.oneOf( + Combinators.combine(Arbitraries.longs(), Arbitraries.longs()) + .as(DeltaOperation.OpenSpliceAndCloseMeta::new), + Combinators.combine( + Arbitraries.longs(), Arbitraries.longs(), Arbitraries.longs(), Arbitraries.longs()) + .as(DeltaOperation.OpenSpliceAndCloseReal::new), + Combinators.combine(Arbitraries.longs(), Arbitraries.longs(), Arbitraries.longs()) + .as(DeltaOperation.Open::new), + Combinators.combine(Arbitraries.longs(), Arbitraries.longs()).as(DeltaOperation.Write::new), + Arbitraries.longs().map(DeltaOperation.SetReadSource::new), + Arbitraries.of(new DeltaOperation.UnsetReadSource()), + Arbitraries.of(new DeltaOperation.Close()), + Combinators.combine(Arbitraries.longs(), Arbitraries.longs()) + .as(DeltaOperation.BsPatch::new)); + } + + @Provide + Arbitrary anyFileMode() { + return Combinators.combine( + Arbitraries.integers(), Arbitraries.integers(), Arbitraries.integers()) + .as(DeltaPartPayload.FileMode::new); + } + + @Provide + Arbitrary anyXattr() { + return Combinators.combine(anyByteString(), anyByteString()).as(Xattr::new); + } + + @Provide + Arbitrary anyByteString() { + return Arbitraries.bytes().array(byte[].class).map(ByteString::new); + } + + @Provide + Arbitrary anyDirTree() { + return Combinators.combine(anyDirTreeFile().list(), anyDirTreeDirectory().list()) + .as(DirTree::new); + } + + @Provide + Arbitrary anyDirMeta() { + return Combinators.combine( + Arbitraries.integers(), + Arbitraries.integers(), + Arbitraries.integers(), + anyXattr().list()) + .as(DirMeta::new); + } + + @Provide + Arbitrary anyCommit() { + return Combinators.combine( + anyMetadata(), + anyChecksum(), + anyRelatedObject().list(), + Arbitraries.strings(), + Arbitraries.strings(), + Arbitraries.longs(), + anyChecksum(), + anyChecksum()) + .as(Commit::new); + } + + @Provide + Arbitrary anyRelatedObject() { + return Combinators.combine(Arbitraries.strings(), anyChecksum()).as(Commit.RelatedObject::new); + } + + @Provide + Arbitrary anyDeltaName() { + return Combinators.combine(anyChecksum(), anyChecksum()).as(DeltaSuperblock.DeltaName::new); + } + + @Provide + Arbitrary anyDeltaMetaEntry() { + return Combinators.combine( + Arbitraries.integers(), + anyChecksum(), + Arbitraries.longs(), + Arbitraries.longs(), + anyDeltaObject().list()) + .as(DeltaMetaEntry::new); + } + + @Provide + Arbitrary anyDeltaObject() { + return Combinators.combine(anyObjectType(), anyChecksum()).as(DeltaMetaEntry.DeltaObject::new); + } + + @Provide + Arbitrary anyObjectType() { + return Arbitraries.of(ObjectType.values()); + } + + @Provide + Arbitrary anyDeltaFallback() { + return Combinators.combine( + anyObjectType(), anyChecksum(), Arbitraries.longs(), Arbitraries.longs()) + .as(DeltaFallback::new); + } + + @Provide + Arbitrary anyDirTreeDirectory() { + return Combinators.combine(Arbitraries.strings(), anyChecksum(), anyChecksum()) + .as(DirTree.Directory::new); + } + + @Provide + Arbitrary anyDirTreeFile() { + return Combinators.combine(Arbitraries.strings(), anyChecksum()).as(DirTree.File::new); } } -- cgit v1.2.3