@enbox/dwn-sdk-js 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.mjs +7 -16
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/src/utils/hd-key.js +1 -1
- package/dist/esm/src/utils/hd-key.js.map +1 -1
- package/dist/esm/src/utils/protocols.js +2 -2
- package/dist/esm/src/utils/protocols.js.map +1 -1
- package/dist/esm/tests/fuzz/arbitraries/dwn-message.arbitrary.js +72 -0
- package/dist/esm/tests/fuzz/arbitraries/dwn-message.arbitrary.js.map +1 -0
- package/dist/esm/tests/fuzz/arbitraries/filter.arbitrary.js +53 -0
- package/dist/esm/tests/fuzz/arbitraries/filter.arbitrary.js.map +1 -0
- package/dist/esm/tests/fuzz/arbitraries/jws.arbitrary.js +55 -0
- package/dist/esm/tests/fuzz/arbitraries/jws.arbitrary.js.map +1 -0
- package/dist/esm/tests/fuzz/arbitraries/protocol-definition.arbitrary.js +106 -0
- package/dist/esm/tests/fuzz/arbitraries/protocol-definition.arbitrary.js.map +1 -0
- package/dist/esm/tests/fuzz/arbitraries/store.arbitrary.js +139 -0
- package/dist/esm/tests/fuzz/arbitraries/store.arbitrary.js.map +1 -0
- package/dist/esm/tests/fuzz/cid.fuzz.spec.js +74 -0
- package/dist/esm/tests/fuzz/cid.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/compound-index.fuzz.spec.js +203 -0
- package/dist/esm/tests/fuzz/compound-index.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/data-store.fuzz.spec.js +146 -0
- package/dist/esm/tests/fuzz/data-store.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/data-stream.fuzz.spec.js +44 -0
- package/dist/esm/tests/fuzz/data-stream.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/encoder.fuzz.spec.js +76 -0
- package/dist/esm/tests/fuzz/encoder.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/encryption.fuzz.spec.js +132 -0
- package/dist/esm/tests/fuzz/encryption.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/filter.fuzz.spec.js +149 -0
- package/dist/esm/tests/fuzz/filter.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/get-rule-set-at-path.fuzz.spec.js +82 -0
- package/dist/esm/tests/fuzz/get-rule-set-at-path.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/hd-key.fuzz.spec.js +77 -0
- package/dist/esm/tests/fuzz/hd-key.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/immutable-properties.fuzz.spec.js +86 -0
- package/dist/esm/tests/fuzz/immutable-properties.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/index-level.fuzz.spec.js +195 -0
- package/dist/esm/tests/fuzz/index-level.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/jws.fuzz.spec.js +100 -0
- package/dist/esm/tests/fuzz/jws.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/message-store.fuzz.spec.js +154 -0
- package/dist/esm/tests/fuzz/message-store.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/object.fuzz.spec.js +82 -0
- package/dist/esm/tests/fuzz/object.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/process-message.fuzz.spec.js +85 -0
- package/dist/esm/tests/fuzz/process-message.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/protocol-definition.fuzz.spec.js +145 -0
- package/dist/esm/tests/fuzz/protocol-definition.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/protocol-validation.fuzz.spec.js +160 -0
- package/dist/esm/tests/fuzz/protocol-validation.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/protocols-utils.fuzz.spec.js +41 -0
- package/dist/esm/tests/fuzz/protocols-utils.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/records-utils.fuzz.spec.js +81 -0
- package/dist/esm/tests/fuzz/records-utils.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/resumable-task-store.fuzz.spec.js +106 -0
- package/dist/esm/tests/fuzz/resumable-task-store.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/schema-validation.fuzz.spec.js +126 -0
- package/dist/esm/tests/fuzz/schema-validation.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/secp256k1.fuzz.spec.js +74 -0
- package/dist/esm/tests/fuzz/secp256k1.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/secp256r1.fuzz.spec.js +60 -0
- package/dist/esm/tests/fuzz/secp256r1.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/time.fuzz.spec.js +82 -0
- package/dist/esm/tests/fuzz/time.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/fuzz/url.fuzz.spec.js +118 -0
- package/dist/esm/tests/fuzz/url.fuzz.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-subscribe.spec.js +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
- package/dist/types/generated/precompiled-validators.d.ts +0 -70
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/types/messages-types.d.ts +0 -4
- package/dist/types/src/types/messages-types.d.ts.map +1 -1
- package/dist/types/src/types/records-types.d.ts +0 -4
- package/dist/types/src/types/records-types.d.ts.map +1 -1
- package/dist/types/tests/fuzz/arbitraries/dwn-message.arbitrary.d.ts +31 -0
- package/dist/types/tests/fuzz/arbitraries/dwn-message.arbitrary.d.ts.map +1 -0
- package/dist/types/tests/fuzz/arbitraries/filter.arbitrary.d.ts +27 -0
- package/dist/types/tests/fuzz/arbitraries/filter.arbitrary.d.ts.map +1 -0
- package/dist/types/tests/fuzz/arbitraries/jws.arbitrary.d.ts +26 -0
- package/dist/types/tests/fuzz/arbitraries/jws.arbitrary.d.ts.map +1 -0
- package/dist/types/tests/fuzz/arbitraries/protocol-definition.arbitrary.d.ts +31 -0
- package/dist/types/tests/fuzz/arbitraries/protocol-definition.arbitrary.d.ts.map +1 -0
- package/dist/types/tests/fuzz/arbitraries/store.arbitrary.d.ts +71 -0
- package/dist/types/tests/fuzz/arbitraries/store.arbitrary.d.ts.map +1 -0
- package/dist/types/tests/fuzz/cid.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/cid.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/compound-index.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/compound-index.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/data-store.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/data-store.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/data-stream.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/data-stream.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/encoder.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/encoder.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/encryption.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/encryption.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/filter.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/filter.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/get-rule-set-at-path.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/get-rule-set-at-path.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/hd-key.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/hd-key.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/immutable-properties.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/immutable-properties.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/index-level.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/index-level.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/jws.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/jws.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/message-store.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/message-store.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/object.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/object.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/process-message.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/process-message.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/protocol-definition.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/protocol-definition.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/protocol-validation.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/protocol-validation.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/protocols-utils.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/protocols-utils.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/records-utils.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/records-utils.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/resumable-task-store.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/resumable-task-store.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/schema-validation.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/schema-validation.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/secp256k1.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/secp256k1.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/secp256r1.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/secp256r1.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/time.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/time.fuzz.spec.d.ts.map +1 -0
- package/dist/types/tests/fuzz/url.fuzz.spec.d.ts +2 -0
- package/dist/types/tests/fuzz/url.fuzz.spec.d.ts.map +1 -0
- package/package.json +24 -25
- package/src/index.ts +2 -2
- package/src/types/messages-types.ts +0 -5
- package/src/types/records-types.ts +0 -5
- package/src/utils/hd-key.ts +2 -2
- package/src/utils/protocols.ts +2 -2
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import fc from 'fast-check';
|
|
3
|
+
import { SortDirection } from '../../src/types/query-types.js';
|
|
4
|
+
import { buildCompoundKey, buildCompoundPrefix, COMPOUND_SEGMENT_SEPARATOR, selectCompoundIndex } from '../../src/store/index-level-compound.js';
|
|
5
|
+
const numRuns = Number(process.env.FAST_CHECK_NUM_RUNS) || 100;
|
|
6
|
+
/**
|
|
7
|
+
* The IndexLevel.encodeValue implementation for string values:
|
|
8
|
+
* strings are left as-is in the real code. We use this simplified
|
|
9
|
+
* version since we only generate string index values.
|
|
10
|
+
*/
|
|
11
|
+
function encodeValue(value) {
|
|
12
|
+
return String(value);
|
|
13
|
+
}
|
|
14
|
+
const DELIMITER = '\x00';
|
|
15
|
+
describe('Compound index — fuzz', () => {
|
|
16
|
+
/**
|
|
17
|
+
* Object.prototype property names that would collide with plain-object property lookups.
|
|
18
|
+
*/
|
|
19
|
+
const prototypeNames = new Set(Object.getOwnPropertyNames(Object.prototype));
|
|
20
|
+
/**
|
|
21
|
+
* Arbitrary for a property name (no special chars that collide with separators,
|
|
22
|
+
* no Object.prototype names like __proto__, toString, valueOf).
|
|
23
|
+
*/
|
|
24
|
+
const arbPropName = fc.string({ minLength: 1, maxLength: 10 })
|
|
25
|
+
.filter((s) => !s.includes('\x00') && !s.includes('\x01') && !s.includes('/') && !prototypeNames.has(s));
|
|
26
|
+
/**
|
|
27
|
+
* Arbitrary for a messageCid-like string.
|
|
28
|
+
*/
|
|
29
|
+
const arbMessageCid = fc.stringMatching(/^[a-z0-9]{10,20}$/);
|
|
30
|
+
describe('buildCompoundKey/buildCompoundPrefix consistency', () => {
|
|
31
|
+
it('should produce a key that starts with the corresponding prefix', () => {
|
|
32
|
+
fc.assert(fc.property(fc.array(arbPropName, { minLength: 1, maxLength: 4 })
|
|
33
|
+
.filter((props) => new Set(props).size === props.length), arbPropName.filter((s) => s.length > 0), arbMessageCid, (properties, sortProperty, messageCid) => {
|
|
34
|
+
// Ensure sortProperty is not in properties
|
|
35
|
+
if (properties.includes(sortProperty)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const compoundIndex = {
|
|
39
|
+
name: 'test',
|
|
40
|
+
properties,
|
|
41
|
+
sortProperty,
|
|
42
|
+
};
|
|
43
|
+
// Build indexes that satisfy all properties + sort
|
|
44
|
+
const indexes = {};
|
|
45
|
+
for (const prop of properties) {
|
|
46
|
+
indexes[prop] = `val_${prop}`;
|
|
47
|
+
}
|
|
48
|
+
indexes[sortProperty] = 'sortval';
|
|
49
|
+
// Also build a filter with the same equality values
|
|
50
|
+
const filter = {};
|
|
51
|
+
for (const prop of properties) {
|
|
52
|
+
filter[prop] = `val_${prop}`;
|
|
53
|
+
}
|
|
54
|
+
const key = buildCompoundKey(messageCid, indexes, compoundIndex, encodeValue, DELIMITER);
|
|
55
|
+
const prefix = buildCompoundPrefix(filter, compoundIndex, encodeValue);
|
|
56
|
+
expect(key).toBeDefined();
|
|
57
|
+
expect(prefix).toBeDefined();
|
|
58
|
+
expect(key.startsWith(prefix)).toBe(true);
|
|
59
|
+
}), { numRuns });
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe('buildCompoundKey — returns undefined for missing properties', () => {
|
|
63
|
+
it('should return undefined when a required property is missing from indexes', () => {
|
|
64
|
+
fc.assert(fc.property(fc.array(arbPropName, { minLength: 2, maxLength: 4 })
|
|
65
|
+
.filter((props) => new Set(props).size === props.length), arbPropName, arbMessageCid, fc.nat(), (properties, sortProperty, messageCid, dropSeed) => {
|
|
66
|
+
if (properties.includes(sortProperty)) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const compoundIndex = {
|
|
70
|
+
name: 'test',
|
|
71
|
+
properties,
|
|
72
|
+
sortProperty,
|
|
73
|
+
};
|
|
74
|
+
// Build indexes but omit one required property
|
|
75
|
+
const indexes = {};
|
|
76
|
+
const dropIndex = dropSeed % properties.length;
|
|
77
|
+
for (let i = 0; i < properties.length; i++) {
|
|
78
|
+
if (i !== dropIndex) {
|
|
79
|
+
indexes[properties[i]] = `val_${properties[i]}`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
indexes[sortProperty] = 'sortval';
|
|
83
|
+
const key = buildCompoundKey(messageCid, indexes, compoundIndex, encodeValue, DELIMITER);
|
|
84
|
+
expect(key).toBeUndefined();
|
|
85
|
+
}), { numRuns });
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
describe('buildCompoundPrefix — returns undefined for non-equality filters', () => {
|
|
89
|
+
it('should return undefined when a property has an object filter (range)', () => {
|
|
90
|
+
fc.assert(fc.property(fc.array(arbPropName, { minLength: 1, maxLength: 3 })
|
|
91
|
+
.filter((props) => new Set(props).size === props.length), arbPropName, fc.nat(), (properties, sortProperty, rangeSeed) => {
|
|
92
|
+
if (properties.includes(sortProperty)) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const compoundIndex = {
|
|
96
|
+
name: 'test',
|
|
97
|
+
properties,
|
|
98
|
+
sortProperty,
|
|
99
|
+
};
|
|
100
|
+
// Set one property to an object (range filter) instead of equality
|
|
101
|
+
const filter = {};
|
|
102
|
+
const rangeIndex = rangeSeed % properties.length;
|
|
103
|
+
for (let i = 0; i < properties.length; i++) {
|
|
104
|
+
if (i === rangeIndex) {
|
|
105
|
+
filter[properties[i]] = { gte: 'a', lte: 'z' }; // range filter
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
filter[properties[i]] = `val_${properties[i]}`;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const prefix = buildCompoundPrefix(filter, compoundIndex, encodeValue);
|
|
112
|
+
expect(prefix).toBeUndefined();
|
|
113
|
+
}), { numRuns });
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
describe('selectCompoundIndex — correctness', () => {
|
|
117
|
+
it('should select the compound index with the most matching properties', () => {
|
|
118
|
+
fc.assert(fc.property(arbPropName, arbPropName, arbPropName, arbPropName, (prop1, prop2, prop3, sortProp) => {
|
|
119
|
+
// Ensure all distinct
|
|
120
|
+
const allNames = [prop1, prop2, prop3, sortProp];
|
|
121
|
+
if (new Set(allNames).size !== allNames.length) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const smallIndex = {
|
|
125
|
+
name: 'small',
|
|
126
|
+
properties: [prop1],
|
|
127
|
+
sortProperty: sortProp,
|
|
128
|
+
};
|
|
129
|
+
const largeIndex = {
|
|
130
|
+
name: 'large',
|
|
131
|
+
properties: [prop1, prop2],
|
|
132
|
+
sortProperty: sortProp,
|
|
133
|
+
};
|
|
134
|
+
const wrongSort = {
|
|
135
|
+
name: 'wrongSort',
|
|
136
|
+
properties: [prop1, prop2, prop3],
|
|
137
|
+
sortProperty: 'nonexistent_sort',
|
|
138
|
+
};
|
|
139
|
+
const filter = {
|
|
140
|
+
[prop1]: 'v1',
|
|
141
|
+
[prop2]: 'v2',
|
|
142
|
+
[prop3]: 'v3',
|
|
143
|
+
};
|
|
144
|
+
const queryOptions = {
|
|
145
|
+
sortProperty: sortProp,
|
|
146
|
+
sortDirection: SortDirection.Ascending,
|
|
147
|
+
};
|
|
148
|
+
const selected = selectCompoundIndex(filter, queryOptions, [smallIndex, largeIndex, wrongSort]);
|
|
149
|
+
expect(selected).toBe(largeIndex); // largeIndex has more matching properties
|
|
150
|
+
}), { numRuns });
|
|
151
|
+
});
|
|
152
|
+
it('should return undefined when no compound index matches sort property', () => {
|
|
153
|
+
fc.assert(fc.property(arbPropName, arbPropName, (prop, sortProp) => {
|
|
154
|
+
if (prop === sortProp) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const idx = {
|
|
158
|
+
name: 'idx',
|
|
159
|
+
properties: [prop],
|
|
160
|
+
sortProperty: 'other_sort',
|
|
161
|
+
};
|
|
162
|
+
const filter = { [prop]: 'val' };
|
|
163
|
+
const queryOptions = {
|
|
164
|
+
sortProperty: sortProp,
|
|
165
|
+
sortDirection: SortDirection.Ascending,
|
|
166
|
+
};
|
|
167
|
+
const selected = selectCompoundIndex(filter, queryOptions, [idx]);
|
|
168
|
+
expect(selected).toBeUndefined();
|
|
169
|
+
}), { numRuns });
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
describe('buildCompoundKey — key contains all segments in order', () => {
|
|
173
|
+
it('should encode property values in the compound key in definition order', () => {
|
|
174
|
+
fc.assert(fc.property(fc.array(arbPropName, { minLength: 1, maxLength: 4 })
|
|
175
|
+
.filter((props) => new Set(props).size === props.length), arbPropName, arbMessageCid, (properties, sortProperty, messageCid) => {
|
|
176
|
+
if (properties.includes(sortProperty)) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const compoundIndex = {
|
|
180
|
+
name: 'test',
|
|
181
|
+
properties,
|
|
182
|
+
sortProperty,
|
|
183
|
+
};
|
|
184
|
+
const indexes = {};
|
|
185
|
+
const values = [];
|
|
186
|
+
for (const prop of properties) {
|
|
187
|
+
const val = `v_${prop}`;
|
|
188
|
+
indexes[prop] = val;
|
|
189
|
+
values.push(val);
|
|
190
|
+
}
|
|
191
|
+
const sortVal = 'sort_val';
|
|
192
|
+
indexes[sortProperty] = sortVal;
|
|
193
|
+
const key = buildCompoundKey(messageCid, indexes, compoundIndex, encodeValue, DELIMITER);
|
|
194
|
+
expect(key).toBeDefined();
|
|
195
|
+
// Verify: key should be values joined by \x01, then \x01sortVal\x00messageCid
|
|
196
|
+
const expected = values.join(COMPOUND_SEGMENT_SEPARATOR) +
|
|
197
|
+
COMPOUND_SEGMENT_SEPARATOR + sortVal + DELIMITER + messageCid;
|
|
198
|
+
expect(key).toBe(expected);
|
|
199
|
+
}), { numRuns });
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
//# sourceMappingURL=compound-index.fuzz.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compound-index.fuzz.spec.js","sourceRoot":"","sources":["../../../../tests/fuzz/compound-index.fuzz.spec.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAEhD,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAEjJ,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,GAAG,CAAC;AAE/D;;;;GAIG;AACH,SAAS,WAAW,CAAC,KAAgC;IACnD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,SAAS,GAAG,MAAM,CAAC;AAEzB,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IAErC;;OAEG;IACH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IAE7E;;;OAGG;IACH,MAAM,WAAW,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;SAC3D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3G;;OAEG;IACH,MAAM,aAAa,GAAG,EAAE,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC;IAE7D,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAChE,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;YACxE,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CACT,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;iBAClD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC,EAC1D,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EACvC,aAAa,EACb,CAAC,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE;gBACvC,2CAA2C;gBAC3C,IAAI,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;oBACtC,OAAO;gBACT,CAAC;gBAED,MAAM,aAAa,GAA4B;oBAC7C,IAAI,EAAE,MAAM;oBACZ,UAAU;oBACV,YAAY;iBACb,CAAC;gBAEF,mDAAmD;gBACnD,MAAM,OAAO,GAAc,EAAE,CAAC;gBAC9B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;oBAC9B,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,IAAI,EAAE,CAAC;gBAChC,CAAC;gBACD,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;gBAElC,oDAAoD;gBACpD,MAAM,MAAM,GAAW,EAAE,CAAC;gBAC1B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;oBAC9B,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,IAAI,EAAE,CAAC;gBAC/B,CAAC;gBAED,MAAM,GAAG,GAAG,gBAAgB,CAAC,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;gBACzF,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;gBAEvE,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC1B,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC7B,MAAM,CAAC,GAAI,CAAC,UAAU,CAAC,MAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9C,CAAC,CACF,EACD,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,6DAA6D,EAAE,GAAG,EAAE;QAC3E,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;YAClF,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CACT,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;iBAClD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC,EAC1D,WAAW,EACX,aAAa,EACb,EAAE,CAAC,GAAG,EAAE,EACR,CAAC,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE;gBACjD,IAAI,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;oBACtC,OAAO;gBACT,CAAC;gBAED,MAAM,aAAa,GAA4B;oBAC7C,IAAI,EAAE,MAAM;oBACZ,UAAU;oBACV,YAAY;iBACb,CAAC;gBAEF,+CAA+C;gBAC/C,MAAM,OAAO,GAAc,EAAE,CAAC;gBAC9B,MAAM,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC;gBAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC3C,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;wBACpB,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;oBAClD,CAAC;gBACH,CAAC;gBACD,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;gBAElC,MAAM,GAAG,GAAG,gBAAgB,CAAC,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;gBACzF,MAAM,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,CAAC;YAC9B,CAAC,CACF,EACD,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAChF,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;YAC9E,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CACT,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;iBAClD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC,EAC1D,WAAW,EACX,EAAE,CAAC,GAAG,EAAE,EACR,CAAC,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE;gBACtC,IAAI,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;oBACtC,OAAO;gBACT,CAAC;gBAED,MAAM,aAAa,GAA4B;oBAC7C,IAAI,EAAE,MAAM;oBACZ,UAAU;oBACV,YAAY;iBACb,CAAC;gBAEF,mEAAmE;gBACnE,MAAM,MAAM,GAAW,EAAE,CAAC;gBAC1B,MAAM,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC;gBACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC3C,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;wBACrB,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,eAAe;oBACjE,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjD,CAAC;gBACH,CAAC;gBAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;gBACvE,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;YACjC,CAAC,CACF,EACD,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACjD,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;YAC5E,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CACT,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;gBAChC,sBAAsB;gBACtB,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBACjD,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;oBAC/C,OAAO;gBACT,CAAC;gBAED,MAAM,UAAU,GAA4B;oBAC1C,IAAI,EAAW,OAAO;oBACtB,UAAU,EAAK,CAAC,KAAK,CAAC;oBACtB,YAAY,EAAG,QAAQ;iBACxB,CAAC;gBACF,MAAM,UAAU,GAA4B;oBAC1C,IAAI,EAAW,OAAO;oBACtB,UAAU,EAAK,CAAC,KAAK,EAAE,KAAK,CAAC;oBAC7B,YAAY,EAAG,QAAQ;iBACxB,CAAC;gBACF,MAAM,SAAS,GAA4B;oBACzC,IAAI,EAAW,WAAW;oBAC1B,UAAU,EAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;oBACpC,YAAY,EAAG,kBAAkB;iBAClC,CAAC;gBAEF,MAAM,MAAM,GAAW;oBACrB,CAAC,KAAK,CAAC,EAAG,IAAI;oBACd,CAAC,KAAK,CAAC,EAAG,IAAI;oBACd,CAAC,KAAK,CAAC,EAAG,IAAI;iBACf,CAAC;gBACF,MAAM,YAAY,GAAiB;oBACjC,YAAY,EAAI,QAAQ;oBACxB,aAAa,EAAG,aAAa,CAAC,SAAS;iBACxC,CAAC;gBAEF,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;gBAChG,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,0CAA0C;YAC/E,CAAC,CACF,EACD,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;YAC9E,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CACT,WAAW,EACX,WAAW,EACX,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE;gBACjB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACtB,OAAO;gBACT,CAAC;gBAED,MAAM,GAAG,GAA4B;oBACnC,IAAI,EAAW,KAAK;oBACpB,UAAU,EAAK,CAAC,IAAI,CAAC;oBACrB,YAAY,EAAG,YAAY;iBAC5B,CAAC;gBAEF,MAAM,MAAM,GAAW,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC;gBACzC,MAAM,YAAY,GAAiB;oBACjC,YAAY,EAAI,QAAQ;oBACxB,aAAa,EAAG,aAAa,CAAC,SAAS;iBACxC,CAAC;gBAEF,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBAClE,MAAM,CAAC,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;YACnC,CAAC,CACF,EACD,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uDAAuD,EAAE,GAAG,EAAE;QACrE,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;YAC/E,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CACT,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;iBAClD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC,EAC1D,WAAW,EACX,aAAa,EACb,CAAC,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE;gBACvC,IAAI,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;oBACtC,OAAO;gBACT,CAAC;gBAED,MAAM,aAAa,GAA4B;oBAC7C,IAAI,EAAE,MAAM;oBACZ,UAAU;oBACV,YAAY;iBACb,CAAC;gBAEF,MAAM,OAAO,GAAc,EAAE,CAAC;gBAC9B,MAAM,MAAM,GAAa,EAAE,CAAC;gBAC5B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;oBAC9B,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE,CAAC;oBACxB,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;oBACpB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACnB,CAAC;gBACD,MAAM,OAAO,GAAG,UAAU,CAAC;gBAC3B,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC;gBAEhC,MAAM,GAAG,GAAG,gBAAgB,CAAC,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;gBACzF,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;gBAE1B,8EAA8E;gBAC9E,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC;oBACtD,0BAA0B,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAC;gBAChE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC,CACF,EACD,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { afterAll, afterEach, beforeAll, describe, expect, it } from 'bun:test';
|
|
2
|
+
import fc from 'fast-check';
|
|
3
|
+
import { Cid } from '../../src/utils/cid.js';
|
|
4
|
+
import { DataStoreLevel } from '../../src/store/data-store-level.js';
|
|
5
|
+
import { dataBlob, recordId, tenantDid } from './arbitraries/store.arbitrary.js';
|
|
6
|
+
const numRuns = Number(process.env.FAST_CHECK_NUM_RUNS) || 100;
|
|
7
|
+
/** Helper to create a ReadableStream from a Uint8Array. */
|
|
8
|
+
function streamFrom(data) {
|
|
9
|
+
return new ReadableStream({
|
|
10
|
+
start(controller) {
|
|
11
|
+
controller.enqueue(data);
|
|
12
|
+
controller.close();
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/** Helper to read all bytes from a ReadableStream. */
|
|
17
|
+
async function readStream(stream) {
|
|
18
|
+
const reader = stream.getReader();
|
|
19
|
+
const chunks = [];
|
|
20
|
+
let done = false;
|
|
21
|
+
while (!done) {
|
|
22
|
+
const result = await reader.read();
|
|
23
|
+
done = result.done;
|
|
24
|
+
if (result.value) {
|
|
25
|
+
chunks.push(result.value);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);
|
|
29
|
+
const result = new Uint8Array(totalLength);
|
|
30
|
+
let offset = 0;
|
|
31
|
+
for (const chunk of chunks) {
|
|
32
|
+
result.set(chunk, offset);
|
|
33
|
+
offset += chunk.length;
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
describe('DataStoreLevel — fuzz', () => {
|
|
38
|
+
let dataStore;
|
|
39
|
+
const testDataPath = '__TESTDATA__/fuzz-data-store';
|
|
40
|
+
const tenant = 'did:example:fuzz-data-tenant';
|
|
41
|
+
beforeAll(async () => {
|
|
42
|
+
dataStore = new DataStoreLevel({ blockstoreLocation: `${testDataPath}/blocks` });
|
|
43
|
+
await dataStore.open();
|
|
44
|
+
});
|
|
45
|
+
afterEach(async () => {
|
|
46
|
+
await dataStore.clear();
|
|
47
|
+
});
|
|
48
|
+
afterAll(async () => {
|
|
49
|
+
await dataStore.close();
|
|
50
|
+
});
|
|
51
|
+
describe('binary data roundtrip', () => {
|
|
52
|
+
it('should store and retrieve arbitrary binary data with correct size', async () => {
|
|
53
|
+
await fc.assert(fc.asyncProperty(dataBlob({ minSize: 1, maxSize: 2048 }), async (data) => {
|
|
54
|
+
await dataStore.clear();
|
|
55
|
+
const dataCid = await Cid.computeDagPbCidFromBytes(data);
|
|
56
|
+
const recId = 'rec_roundtrip';
|
|
57
|
+
const putResult = await dataStore.put(tenant, recId, dataCid, streamFrom(data));
|
|
58
|
+
expect(putResult.dataSize).toBe(data.length);
|
|
59
|
+
const getResult = await dataStore.get(tenant, recId, dataCid);
|
|
60
|
+
expect(getResult).toBeDefined();
|
|
61
|
+
expect(getResult.dataSize).toBe(data.length);
|
|
62
|
+
const retrieved = await readStream(getResult.dataStream);
|
|
63
|
+
expect(retrieved).toEqual(data);
|
|
64
|
+
}), { numRuns: Math.min(numRuns, 30) });
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
describe('get returns undefined for missing data', () => {
|
|
68
|
+
it('should return undefined for non-existent records', async () => {
|
|
69
|
+
await fc.assert(fc.asyncProperty(recordId(), async (recId) => {
|
|
70
|
+
const result = await dataStore.get(tenant, recId, 'bafkreinonexistent');
|
|
71
|
+
expect(result).toBeUndefined();
|
|
72
|
+
}), { numRuns: Math.min(numRuns, 30) });
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('idempotent put', () => {
|
|
76
|
+
it('should return the same dataSize when putting the same data twice', async () => {
|
|
77
|
+
await fc.assert(fc.asyncProperty(dataBlob({ minSize: 10, maxSize: 512 }), async (data) => {
|
|
78
|
+
await dataStore.clear();
|
|
79
|
+
const dataCid = await Cid.computeDagPbCidFromBytes(data);
|
|
80
|
+
const recId = 'rec_idempotent';
|
|
81
|
+
const result1 = await dataStore.put(tenant, recId, dataCid, streamFrom(data));
|
|
82
|
+
const result2 = await dataStore.put(tenant, recId, dataCid, streamFrom(data));
|
|
83
|
+
expect(result1.dataSize).toBe(result2.dataSize);
|
|
84
|
+
expect(result1.dataSize).toBe(data.length);
|
|
85
|
+
}), { numRuns: Math.min(numRuns, 20) });
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
describe('tenant isolation', () => {
|
|
89
|
+
it('should not allow one tenant to read another tenant\'s data', async () => {
|
|
90
|
+
await fc.assert(fc.asyncProperty(tenantDid(), tenantDid(), dataBlob({ minSize: 10, maxSize: 256 }), async (tenant1, tenant2, data) => {
|
|
91
|
+
// Skip if tenants are the same
|
|
92
|
+
if (tenant1 === tenant2) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
await dataStore.clear();
|
|
96
|
+
const dataCid = await Cid.computeDagPbCidFromBytes(data);
|
|
97
|
+
const recId = 'rec_isolation';
|
|
98
|
+
await dataStore.put(tenant1, recId, dataCid, streamFrom(data));
|
|
99
|
+
// Tenant 2 should not be able to get tenant 1's data
|
|
100
|
+
const result = await dataStore.get(tenant2, recId, dataCid);
|
|
101
|
+
expect(result).toBeUndefined();
|
|
102
|
+
}), { numRuns: Math.min(numRuns, 20) });
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe('delete removes data', () => {
|
|
106
|
+
it('should return undefined after deleting a record', async () => {
|
|
107
|
+
await fc.assert(fc.asyncProperty(dataBlob({ minSize: 10, maxSize: 512 }), async (data) => {
|
|
108
|
+
await dataStore.clear();
|
|
109
|
+
const dataCid = await Cid.computeDagPbCidFromBytes(data);
|
|
110
|
+
const recId = 'rec_delete';
|
|
111
|
+
await dataStore.put(tenant, recId, dataCid, streamFrom(data));
|
|
112
|
+
await dataStore.delete(tenant, recId, dataCid);
|
|
113
|
+
const result = await dataStore.get(tenant, recId, dataCid);
|
|
114
|
+
expect(result).toBeUndefined();
|
|
115
|
+
}), { numRuns: Math.min(numRuns, 20) });
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe('reference counting — shared blocks survive partial deletion', () => {
|
|
119
|
+
it('should retain data while at least one reference exists', async () => {
|
|
120
|
+
await fc.assert(fc.asyncProperty(dataBlob({ minSize: 10, maxSize: 256 }), fc.integer({ min: 2, max: 4 }), async (data, refCount) => {
|
|
121
|
+
await dataStore.clear();
|
|
122
|
+
const dataCid = await Cid.computeDagPbCidFromBytes(data);
|
|
123
|
+
// Create multiple references to the same data
|
|
124
|
+
const refs = [];
|
|
125
|
+
for (let i = 0; i < refCount; i++) {
|
|
126
|
+
const t = `did:example:tenant${i}`;
|
|
127
|
+
const r = `rec_ref${i}`;
|
|
128
|
+
await dataStore.put(t, r, dataCid, streamFrom(data));
|
|
129
|
+
refs.push({ tenant: t, recId: r });
|
|
130
|
+
}
|
|
131
|
+
// Delete all but the last reference
|
|
132
|
+
for (let i = 0; i < refCount - 1; i++) {
|
|
133
|
+
await dataStore.delete(refs[i].tenant, refs[i].recId, dataCid);
|
|
134
|
+
}
|
|
135
|
+
// The last reference should still be retrievable
|
|
136
|
+
const lastRef = refs[refCount - 1];
|
|
137
|
+
const result = await dataStore.get(lastRef.tenant, lastRef.recId, dataCid);
|
|
138
|
+
expect(result).toBeDefined();
|
|
139
|
+
expect(result.dataSize).toBe(data.length);
|
|
140
|
+
const retrieved = await readStream(result.dataStream);
|
|
141
|
+
expect(retrieved).toEqual(data);
|
|
142
|
+
}), { numRuns: Math.min(numRuns, 15) });
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
//# sourceMappingURL=data-store.fuzz.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-store.fuzz.spec.js","sourceRoot":"","sources":["../../../../tests/fuzz/data-store.fuzz.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import fc from 'fast-check';
|
|
3
|
+
import { DataStream } from '../../src/utils/data-stream.js';
|
|
4
|
+
const numRuns = Number(process.env.FAST_CHECK_NUM_RUNS) || 100;
|
|
5
|
+
describe('DataStream — fuzz', () => {
|
|
6
|
+
describe('fromBytes/toBytes roundtrip', () => {
|
|
7
|
+
it('should return identical bytes for any Uint8Array', async () => {
|
|
8
|
+
await fc.assert(fc.asyncProperty(fc.uint8Array({ minLength: 0, maxLength: 4096 }), async (bytes) => {
|
|
9
|
+
const stream = DataStream.fromBytes(bytes);
|
|
10
|
+
const result = await DataStream.toBytes(stream);
|
|
11
|
+
expect(result).toEqual(bytes);
|
|
12
|
+
}), { numRuns: Math.min(numRuns, 50) });
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
describe('duplicateDataStream — count invariant', () => {
|
|
16
|
+
it('should return exactly N streams for N >= 1', async () => {
|
|
17
|
+
await fc.assert(fc.asyncProperty(fc.uint8Array({ minLength: 1, maxLength: 256 }), fc.integer({ min: 1, max: 5 }), async (bytes, count) => {
|
|
18
|
+
const stream = DataStream.fromBytes(bytes);
|
|
19
|
+
const copies = DataStream.duplicateDataStream(stream, count);
|
|
20
|
+
expect(copies.length).toBe(count);
|
|
21
|
+
}), { numRuns: Math.min(numRuns, 30) });
|
|
22
|
+
});
|
|
23
|
+
it('should return empty array for count < 1', () => {
|
|
24
|
+
fc.assert(fc.property(fc.uint8Array({ minLength: 1, maxLength: 64 }), fc.integer({ min: -10, max: 0 }), (bytes, count) => {
|
|
25
|
+
const stream = DataStream.fromBytes(bytes);
|
|
26
|
+
const copies = DataStream.duplicateDataStream(stream, count);
|
|
27
|
+
expect(copies.length).toBe(0);
|
|
28
|
+
}), { numRuns: Math.min(numRuns, 20) });
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
describe('duplicateDataStream — content equality', () => {
|
|
32
|
+
it('should produce identical bytes from each duplicate', async () => {
|
|
33
|
+
await fc.assert(fc.asyncProperty(fc.uint8Array({ minLength: 1, maxLength: 1024 }), fc.integer({ min: 2, max: 4 }), async (bytes, count) => {
|
|
34
|
+
const stream = DataStream.fromBytes(bytes);
|
|
35
|
+
const copies = DataStream.duplicateDataStream(stream, count);
|
|
36
|
+
const results = await Promise.all(copies.map((s) => DataStream.toBytes(s)));
|
|
37
|
+
for (const result of results) {
|
|
38
|
+
expect(result).toEqual(bytes);
|
|
39
|
+
}
|
|
40
|
+
}), { numRuns: Math.min(numRuns, 20) });
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=data-stream.fuzz.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-stream.fuzz.spec.js","sourceRoot":"","sources":["../../../../tests/fuzz/data-stream.fuzz.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import fc from 'fast-check';
|
|
3
|
+
import { Encoder } from '../../src/utils/encoder.js';
|
|
4
|
+
const numRuns = Number(process.env.FAST_CHECK_NUM_RUNS) || 200;
|
|
5
|
+
describe('Encoder — fuzz', () => {
|
|
6
|
+
describe('bytes <-> base64url roundtrip', () => {
|
|
7
|
+
it('should roundtrip arbitrary byte arrays through base64url encoding', () => {
|
|
8
|
+
fc.assert(fc.property(fc.uint8Array({ minLength: 0, maxLength: 1024 }), (bytes) => {
|
|
9
|
+
const encoded = Encoder.bytesToBase64Url(bytes);
|
|
10
|
+
const decoded = Encoder.base64UrlToBytes(encoded);
|
|
11
|
+
expect(decoded).toEqual(bytes);
|
|
12
|
+
}), { numRuns });
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
describe('object <-> bytes roundtrip', () => {
|
|
16
|
+
it('should roundtrip JSON-serializable objects through bytes encoding', () => {
|
|
17
|
+
fc.assert(fc.property(fc.dictionary(fc.string({ minLength: 1, maxLength: 20 }), fc.oneof(fc.string(), fc.integer(), fc.boolean(), fc.constant(null)), { minKeys: 0, maxKeys: 10 }), (obj) => {
|
|
18
|
+
const bytes = Encoder.objectToBytes(obj);
|
|
19
|
+
const decoded = Encoder.bytesToObject(bytes);
|
|
20
|
+
expect(decoded).toEqual(obj);
|
|
21
|
+
}), { numRuns });
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('string <-> base64url roundtrip', () => {
|
|
25
|
+
it('should roundtrip arbitrary strings through base64url encoding', () => {
|
|
26
|
+
fc.assert(fc.property(fc.string({ minLength: 0, maxLength: 500 }), (str) => {
|
|
27
|
+
const encoded = Encoder.stringToBase64Url(str);
|
|
28
|
+
const bytes = Encoder.base64UrlToBytes(encoded);
|
|
29
|
+
const decoded = Encoder.bytesToString(bytes);
|
|
30
|
+
expect(decoded).toBe(str);
|
|
31
|
+
}), { numRuns });
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe('string <-> bytes roundtrip', () => {
|
|
35
|
+
it('should roundtrip arbitrary strings through bytes encoding', () => {
|
|
36
|
+
fc.assert(fc.property(fc.string({ minLength: 0, maxLength: 500 }), (str) => {
|
|
37
|
+
const bytes = Encoder.stringToBytes(str);
|
|
38
|
+
const decoded = Encoder.bytesToString(bytes);
|
|
39
|
+
expect(decoded).toBe(str);
|
|
40
|
+
}), { numRuns });
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('base64UrlToObject — crash resistance', () => {
|
|
44
|
+
it('should throw on arbitrary non-base64url strings without crashing', () => {
|
|
45
|
+
fc.assert(fc.property(fc.string({ minLength: 0, maxLength: 200 }), (str) => {
|
|
46
|
+
try {
|
|
47
|
+
Encoder.base64UrlToObject(str);
|
|
48
|
+
// If it doesn't throw, the result should be a defined value
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
// Any error is acceptable — we just verify no unhandled crash
|
|
52
|
+
expect(error).toBeDefined();
|
|
53
|
+
}
|
|
54
|
+
}), { numRuns });
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe('bytesToBase64Url output validity', () => {
|
|
58
|
+
it('should produce strings containing only base64url characters', () => {
|
|
59
|
+
const base64urlPattern = /^[A-Za-z0-9_-]*$/;
|
|
60
|
+
fc.assert(fc.property(fc.uint8Array({ minLength: 0, maxLength: 256 }), (bytes) => {
|
|
61
|
+
const encoded = Encoder.bytesToBase64Url(bytes);
|
|
62
|
+
expect(base64urlPattern.test(encoded)).toBe(true);
|
|
63
|
+
}), { numRuns });
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('objectToBytes — determinism', () => {
|
|
67
|
+
it('should produce identical bytes for the same object', () => {
|
|
68
|
+
fc.assert(fc.property(fc.dictionary(fc.string({ minLength: 1, maxLength: 10 }), fc.oneof(fc.string(), fc.integer(), fc.boolean()), { minKeys: 1, maxKeys: 5 }), (obj) => {
|
|
69
|
+
const bytes1 = Encoder.objectToBytes(obj);
|
|
70
|
+
const bytes2 = Encoder.objectToBytes(obj);
|
|
71
|
+
expect(bytes1).toEqual(bytes2);
|
|
72
|
+
}), { numRuns });
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=encoder.fuzz.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoder.fuzz.spec.js","sourceRoot":"","sources":["../../../../tests/fuzz/encoder.fuzz.spec.ts"],"names":[],"mappings":"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"}
|