Skip to content

Commit

Permalink
More generative testing, include extension values
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Dec 22, 2024
1 parent c1eba8c commit 2292512
Show file tree
Hide file tree
Showing 17 changed files with 152 additions and 52 deletions.
12 changes: 1 addition & 11 deletions convex-core/src/main/java/convex/core/cvm/Address.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,9 @@ public final class Address extends AExtensionValue {
* The maximum possible Address
*/
public static final Address MAX_VALUE = Address.create(Long.MAX_VALUE);

/**
* 64-bit address value
*/
private long value;

private Address(long value) {
this.value=value;
super(value);
}

/**
Expand Down Expand Up @@ -265,11 +260,6 @@ public final int getBytes(byte[] bs, int pos) {
return pos;
}

@Override
public long longValue() {
return value;
}

@Override
public boolean equalsBytes(ABlob b) {
if (b.count()!=LENGTH) return false;
Expand Down
10 changes: 9 additions & 1 deletion convex-core/src/main/java/convex/core/cvm/ops/Local.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import convex.core.data.IRefFunction;
import convex.core.data.util.BlobBuilder;
import convex.core.exceptions.InvalidDataException;
import convex.core.util.Bits;
import convex.core.util.ErrorMessages;

/**
Expand Down Expand Up @@ -62,7 +63,7 @@ public byte getTag() {

@Override
public int encodeRaw(byte[] bs, int pos) {
pos=Format.writeVLQLong(bs, pos, position);
pos=Format.writeVLQCount(bs, pos, position);
return pos;
}

Expand All @@ -82,6 +83,13 @@ public void validateCell() throws InvalidDataException {
throw new InvalidDataException("Invalid Local position "+position, this);
}
}

@Override
public final int hashCode() {
// Needed for hashCode equivalence with extension values
return Bits.hash32(position);
}


@Override
public int getRefCount() {
Expand Down
7 changes: 7 additions & 0 deletions convex-core/src/main/java/convex/core/cvm/ops/Special.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import convex.core.data.util.BlobBuilder;
import convex.core.exceptions.BadFormatException;
import convex.core.exceptions.InvalidDataException;
import convex.core.util.Bits;
import convex.core.util.ErrorMessages;
import convex.core.util.Utils;

Expand Down Expand Up @@ -206,6 +207,12 @@ public static <R extends ACell> Special<R> forSymbol(Symbol sym) {
public static <R extends ACell> Special<R> get(String string) {
return forSymbol(Symbol.create(string));
}

@Override
public final int hashCode() {
// Needed for hashCode equivalence with extension values
return Bits.hash32((long)specialCode);
}


@SuppressWarnings("unchecked")
Expand Down
17 changes: 17 additions & 0 deletions convex-core/src/main/java/convex/core/data/AExtensionValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import convex.core.data.impl.LongBlob;
import convex.core.data.prim.CVMLong;
import convex.core.util.Bits;
import convex.core.util.ErrorMessages;
import convex.core.util.Utils;

Expand All @@ -14,7 +15,13 @@ public abstract class AExtensionValue extends ABlobLike<CVMLong> {
* Length of an extension value in bytes (when considered as a Blob)
*/
protected static final int BYTE_LENGTH = 8;

protected final long value;

protected AExtensionValue(long value) {
this.value=value;
}

@Override
public final long count() {
return BYTE_LENGTH;
Expand All @@ -36,6 +43,11 @@ public ABlob toBlob() {
return LongBlob.create(longValue());
}

@Override
public final long longValue() {
return value;
}

protected static void checkIndex(long i) {
if ((i < 0) || (i >= BYTE_LENGTH)) throw new IndexOutOfBoundsException(ErrorMessages.badIndex(i));
}
Expand Down Expand Up @@ -88,6 +100,11 @@ public AExtensionValue empty() {
return null;
}

@Override
public final int hashCode() {
return Bits.hash32(value);
}

@Override
public boolean isEmbedded() {
return true;
Expand Down
12 changes: 1 addition & 11 deletions convex-core/src/main/java/convex/core/data/ExtensionValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@
import convex.core.data.util.BlobBuilder;
import convex.core.exceptions.InvalidDataException;
import convex.core.lang.RT;
import convex.core.util.Bits;
import convex.core.util.Utils;

public class ExtensionValue extends AExtensionValue {

protected final byte tag;
protected final long value;

protected ExtensionValue(byte tag,long value) {
super(value);
this.tag=tag;
this.value=value;
}

/**
Expand All @@ -37,10 +35,6 @@ public void validateCell() throws InvalidDataException {
}
}

@Override
public int hashCode() {
return Bits.hash32(value);
}

@Override
public final byte byteAt(long i) {
Expand All @@ -59,10 +53,6 @@ public final int getBytes(byte[] bs, int pos) {
return pos;
}

@Override
public long longValue() {
return value;
}

@Override
public byte getTag() {
Expand Down
11 changes: 10 additions & 1 deletion convex-core/src/main/java/convex/core/lang/impl/CoreFn.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import convex.core.cvm.CVMTag;
import convex.core.cvm.Context;
import convex.core.data.ACell;
import convex.core.data.Cells;
import convex.core.data.Format;
import convex.core.data.IRefFunction;
import convex.core.data.Ref;
import convex.core.data.Symbol;
import convex.core.data.util.BlobBuilder;
import convex.core.exceptions.InvalidDataException;
import convex.core.util.Bits;

/**
* Abstract base class for core language functions implemented in the Runtime
Expand Down Expand Up @@ -110,6 +112,12 @@ public int getRefCount() {
return 0;
}

@Override
public final int hashCode() {
// This is needed to match hash behaviour of extension values
return Bits.hash32(code);
}

@Override
public <R extends ACell> Ref<R> getRef(int i) {
throw new IndexOutOfBoundsException("Bad ref index: "+i);
Expand Down Expand Up @@ -145,7 +153,8 @@ protected final long calcMemorySize() {
@Override
public boolean equals(ACell o) {
// This is OK since these are guaranteed to be singleton instances!
return o==this;
if (o instanceof CoreFn) return o==this;
return Cells.equalsGeneric(this, o);
}

@Override
Expand Down
1 change: 0 additions & 1 deletion convex-core/src/main/java/convex/core/message/Message.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import convex.core.lang.RT;
import convex.core.lang.Reader;
import convex.core.store.AStore;
import convex.core.text.PrintUtils;
import convex.core.util.Utils;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ public void dataRoundTrip(@From(ValueGen.class) ACell o) throws BadFormatExcepti

// equality checks
assertEquals(o,o2);
if (o!=null) assertEquals(o.hashCode(),o2.hashCode());
assertEquals(hash,Hash.get(o2));
if (o!=null) assertEquals(o.hashCode(),o2.hashCode());

// re-encoding
AArrayBlob data2=Cells.encode(o2);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package convex.core.data;
package convex.core.message;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand All @@ -11,9 +11,10 @@
import com.pholser.junit.quickcheck.Property;
import com.pholser.junit.quickcheck.runner.JUnitQuickcheck;

import convex.core.data.ACell;
import convex.core.data.Blob;
import convex.core.data.Format;
import convex.core.exceptions.BadFormatException;
import convex.core.message.Message;
import convex.core.message.MessageType;
import convex.test.generators.ValueGen;

@RunWith(JUnitQuickcheck.class)
Expand All @@ -29,8 +30,11 @@ public void messageLengthVLQ(Integer a) throws BadFormatException {
assertEquals(bb.remaining(), Format.getVLQCountLength(a));
}

// @When(seed = -1436059931257127601l)
// @From(ValueGen.class)
@Property
public void testCAD3Message(@From(ValueGen.class) ACell a) throws BadFormatException {
// Any CAD3 object should encode as a complete message
Message m=Message.create(null,a);

MessageType mtype=m.getType();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package convex.net;
package convex.core.message;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand All @@ -9,15 +9,16 @@
import static org.junit.jupiter.api.Assertions.fail;

import java.io.IOException;
import convex.core.data.Format;

import java.util.Arrays;
import java.util.Random;

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.Test;

import convex.core.Result;
import convex.core.cpos.Belief;
import convex.core.cpos.Block;
import convex.core.cpos.CPoSConstants;
import convex.core.cpos.Order;

import convex.core.crypto.AKeyPair;
import convex.core.cvm.Address;
import convex.core.cvm.Symbols;
Expand All @@ -28,20 +29,15 @@
import convex.core.data.Blob;
import convex.core.data.Blobs;
import convex.core.data.Cells;
import convex.core.data.Format;
import convex.core.data.Hash;
import convex.core.data.SignedData;
import convex.core.data.Vectors;
import convex.core.data.prim.CVMLong;
import convex.core.exceptions.BadFormatException;
import convex.core.lang.RT;
import convex.core.message.Message;
import convex.core.message.MessageTag;
import convex.core.message.MessageType;
import convex.core.lang.Reader;
import convex.core.store.Stores;
import convex.core.Result;
import convex.core.cpos.Belief;
import convex.core.cpos.Block;
import convex.core.cpos.CPoSConstants;

public class MessageTest {
static Hash BAD_HASH=Hash.EMPTY_HASH;
Expand Down Expand Up @@ -181,6 +177,12 @@ public void testStatusMessage() {
doMessageTest(m);
}

@Test public void testCoreDefExtension() throws BadFormatException {
// This was a regression at one point where Local was badly re-encoded
Message m=Message.create(null,Reader.read("#[e645]"));
doMessageTest(m);
}

/**
* Generic tests for any valid message
* @param m
Expand Down
28 changes: 26 additions & 2 deletions convex-core/src/test/java/convex/test/generators/AnyMapGen.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package convex.test.generators;

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

import com.pholser.junit.quickcheck.generator.GenerationStatus;
import com.pholser.junit.quickcheck.random.SourceOfRandomness;

Expand All @@ -26,7 +30,7 @@ public AnyMapGen() {
public AMap generate(SourceOfRandomness r, GenerationStatus status) {

int type = r.nextInt();
switch (type % 8) {
switch (type % 10) {
case 0:
return Maps.empty();
case 1:
Expand All @@ -48,12 +52,32 @@ public AMap generate(SourceOfRandomness r, GenerationStatus status) {
return Index.create(o1, o2);
}

default: {
case 7: {
AVector<?> vec = gen().make(VectorGen.class).generate(r, status);
vec = (AVector<?>) vec.subList(0, vec.size() & (~1));
Object[] os = vec.toArray();
return Maps.of(os);
}

default:
return Gen.HASHMAP.generate(r, status);
}
}

@SuppressWarnings("unchecked")
@Override
public List<AMap> doShrink(SourceOfRandomness r, AMap m) {
long n=m.count();
if (n==0) return Collections.EMPTY_LIST;
if (n==1) return Collections.singletonList(Maps.empty());
ArrayList<AMap> al=new ArrayList<>();

for (int i=0; i<n; i++) {
al.add(m.dissoc(m.entryAt(i).getKey()));
}

Collections.sort(al,Cells.countComparator);

return al;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package convex.test.generators;

import com.pholser.junit.quickcheck.generator.ComponentizedGenerator;
import com.pholser.junit.quickcheck.generator.GenerationStatus;
import com.pholser.junit.quickcheck.random.SourceOfRandomness;

Expand All @@ -10,7 +9,7 @@
/**
* Generator for arbitrary collections
*/
public class CollectionGen extends ComponentizedGenerator<ACollection<ACell>> {
public class CollectionGen extends AGenerator<ACollection<ACell>> {
@SuppressWarnings("rawtypes")
private static final Class cls = (Class) ACollection.class;

Expand Down
Loading

0 comments on commit 2292512

Please sign in to comment.