blob: da15ff2df6e6bbf634cdf13bafe2c4759a20b724 [file] [log] [blame]
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +01001package eu.mulk.jgvariant.ostree;
2
Matthias Andreas Benkard147a1c12023-12-10 20:54:33 +01003import static org.junit.jupiter.api.Assertions.assertEquals;
4
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +01005import eu.mulk.jgvariant.core.Decoder;
Matthias Andreas Benkard147a1c12023-12-10 20:54:33 +01006import java.util.List;
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +01007import java.util.Map;
8import net.jqwik.api.*;
9
10@SuppressWarnings("java:S2187")
11class OstreeDecoderPropertyTest {
12
13 @Group
14 class SummaryRoundtripLaw implements RoundtripLaw<Summary> {
15
16 @Override
17 public Decoder<Summary> decoder() {
18 return Summary.decoder();
19 }
20
21 @Override
22 public Arbitrary<Summary> anyT() {
23 return anySummary();
24 }
25 }
26
Matthias Andreas Benkard147a1c12023-12-10 20:54:33 +010027 @Group
28 class DeltaSuperblockRoundtripLaw implements RoundtripLaw<DeltaSuperblock> {
29
30 @Override
31 public Decoder<DeltaSuperblock> decoder() {
32 return DeltaSuperblock.decoder();
33 }
34
35 @Override
36 public Arbitrary<DeltaSuperblock> anyT() {
37 return anyDeltaSuperblock();
38 }
39 }
40
41 @Group
42 @Disabled(
43 "Not implemented correctly: Requires enough file entries to parse all the delta operations.")
44 class DeltaPartPayloadRoundtripLaw implements RoundtripLaw<DeltaPartPayload> {
45
46 @Override
47 public Decoder<DeltaPartPayload> decoder() {
48 // FIXME
49 var deltaMetaEntry = new DeltaMetaEntry(0, Checksum.zero(), 0, 0, List.of());
50 return DeltaPartPayload.decoder(deltaMetaEntry);
51 }
52
53 @Override
54 public Arbitrary<DeltaPartPayload> anyT() {
55 return anyDeltaPartPayload();
56 }
57 }
58
59 @Group
60 class DirTreeRoundtripLaw implements RoundtripLaw<DirTree> {
61
62 @Override
63 public Decoder<DirTree> decoder() {
64 return DirTree.decoder();
65 }
66
67 @Override
68 public Arbitrary<DirTree> anyT() {
69 return anyDirTree();
70 }
71 }
72
73 @Group
74 class DirMetaRoundtripLaw implements RoundtripLaw<DirMeta> {
75
76 @Override
77 public Decoder<DirMeta> decoder() {
78 return DirMeta.decoder();
79 }
80
81 @Override
82 public Arbitrary<DirMeta> anyT() {
83 return anyDirMeta();
84 }
85 }
86
87 @Group
88 class CommitRoundtripLaw implements RoundtripLaw<Commit> {
89
90 @Override
91 public Decoder<Commit> decoder() {
92 return Commit.decoder();
93 }
94
95 @Override
96 public Arbitrary<Commit> anyT() {
97 return anyCommit();
98 }
99 }
100
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +0100101 interface RoundtripLaw<T> {
102
103 @Property
Matthias Andreas Benkard147a1c12023-12-10 20:54:33 +0100104 default void roundtripsWell(@ForAll(value = "anyT") T entityLeft) {
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +0100105 var decoder = decoder();
106 var bytes = decoder.encode(entityLeft);
107 var entityRight = decoder.decode(bytes);
Matthias Andreas Benkard147a1c12023-12-10 20:54:33 +0100108 assertEquals(entityLeft, entityRight);
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +0100109 }
110
111 Decoder<T> decoder();
112
113 @Provide
114 Arbitrary<T> anyT();
115 }
116
117 @Provide
118 Arbitrary<Summary> anySummary() {
119 return Combinators.combine(anySummaryEntry().list(), anyMetadata()).as(Summary::new);
120 }
121
122 @Provide
123 Arbitrary<Metadata> anyMetadata() {
124 return Arbitraries.of(new Metadata(Map.of()));
125 }
126
127 @Provide
128 Arbitrary<Summary.Entry> anySummaryEntry() {
129 return Combinators.combine(Arbitraries.strings(), anySummaryEntryValue())
130 .as(Summary.Entry::new);
131 }
132
133 @Provide
134 Arbitrary<Summary.Entry.Value> anySummaryEntryValue() {
135 return Combinators.combine(Arbitraries.integers(), anyChecksum(), anyMetadata())
136 .as(Summary.Entry.Value::new);
137 }
138
139 @Provide
140 Arbitrary<Checksum> anyChecksum() {
Matthias Andreas Benkard147a1c12023-12-10 20:54:33 +0100141 return Arbitraries.bytes()
142 .array(byte[].class)
143 .ofSize(32)
144 .map(ByteString::new)
145 .map(Checksum::new);
146 }
147
148 @Provide
149 Arbitrary<DeltaSuperblock> anyDeltaSuperblock() {
150 return Combinators.combine(
151 anyMetadata(),
152 Arbitraries.longs(),
153 anyChecksum(),
154 anyChecksum(),
155 anyCommit(),
156 anyDeltaName().list(),
157 anyDeltaMetaEntry().list(),
158 anyDeltaFallback().list())
159 .as(DeltaSuperblock::new);
160 }
161
162 @Provide
163 Arbitrary<DeltaPartPayload> anyDeltaPartPayload() {
164 return Combinators.combine(
165 anyFileMode().list(),
166 anyXattr().list().list(),
167 anyByteString(),
168 anyDeltaOperation().list())
169 .as(DeltaPartPayload::new);
170 }
171
172 @Provide
173 Arbitrary<DeltaOperation> anyDeltaOperation() {
174 return Arbitraries.oneOf(
175 Combinators.combine(Arbitraries.longs(), Arbitraries.longs())
176 .as(DeltaOperation.OpenSpliceAndCloseMeta::new),
177 Combinators.combine(
178 Arbitraries.longs(), Arbitraries.longs(), Arbitraries.longs(), Arbitraries.longs())
179 .as(DeltaOperation.OpenSpliceAndCloseReal::new),
180 Combinators.combine(Arbitraries.longs(), Arbitraries.longs(), Arbitraries.longs())
181 .as(DeltaOperation.Open::new),
182 Combinators.combine(Arbitraries.longs(), Arbitraries.longs()).as(DeltaOperation.Write::new),
183 Arbitraries.longs().map(DeltaOperation.SetReadSource::new),
184 Arbitraries.of(new DeltaOperation.UnsetReadSource()),
185 Arbitraries.of(new DeltaOperation.Close()),
186 Combinators.combine(Arbitraries.longs(), Arbitraries.longs())
187 .as(DeltaOperation.BsPatch::new));
188 }
189
190 @Provide
191 Arbitrary<DeltaPartPayload.FileMode> anyFileMode() {
192 return Combinators.combine(
193 Arbitraries.integers(), Arbitraries.integers(), Arbitraries.integers())
194 .as(DeltaPartPayload.FileMode::new);
195 }
196
197 @Provide
198 Arbitrary<Xattr> anyXattr() {
199 return Combinators.combine(anyByteString(), anyByteString()).as(Xattr::new);
200 }
201
202 @Provide
203 Arbitrary<ByteString> anyByteString() {
204 return Arbitraries.bytes().array(byte[].class).map(ByteString::new);
205 }
206
207 @Provide
208 Arbitrary<DirTree> anyDirTree() {
209 return Combinators.combine(anyDirTreeFile().list(), anyDirTreeDirectory().list())
210 .as(DirTree::new);
211 }
212
213 @Provide
214 Arbitrary<DirMeta> anyDirMeta() {
215 return Combinators.combine(
216 Arbitraries.integers(),
217 Arbitraries.integers(),
218 Arbitraries.integers(),
219 anyXattr().list())
220 .as(DirMeta::new);
221 }
222
223 @Provide
224 Arbitrary<Commit> anyCommit() {
225 return Combinators.combine(
226 anyMetadata(),
227 anyChecksum(),
228 anyRelatedObject().list(),
229 Arbitraries.strings(),
230 Arbitraries.strings(),
231 Arbitraries.longs(),
232 anyChecksum(),
233 anyChecksum())
234 .as(Commit::new);
235 }
236
237 @Provide
238 Arbitrary<Commit.RelatedObject> anyRelatedObject() {
239 return Combinators.combine(Arbitraries.strings(), anyChecksum()).as(Commit.RelatedObject::new);
240 }
241
242 @Provide
243 Arbitrary<DeltaSuperblock.DeltaName> anyDeltaName() {
244 return Combinators.combine(anyChecksum(), anyChecksum()).as(DeltaSuperblock.DeltaName::new);
245 }
246
247 @Provide
248 Arbitrary<DeltaMetaEntry> anyDeltaMetaEntry() {
249 return Combinators.combine(
250 Arbitraries.integers(),
251 anyChecksum(),
252 Arbitraries.longs(),
253 Arbitraries.longs(),
254 anyDeltaObject().list())
255 .as(DeltaMetaEntry::new);
256 }
257
258 @Provide
259 Arbitrary<DeltaMetaEntry.DeltaObject> anyDeltaObject() {
260 return Combinators.combine(anyObjectType(), anyChecksum()).as(DeltaMetaEntry.DeltaObject::new);
261 }
262
263 @Provide
264 Arbitrary<ObjectType> anyObjectType() {
265 return Arbitraries.of(ObjectType.values());
266 }
267
268 @Provide
269 Arbitrary<DeltaFallback> anyDeltaFallback() {
270 return Combinators.combine(
271 anyObjectType(), anyChecksum(), Arbitraries.longs(), Arbitraries.longs())
272 .as(DeltaFallback::new);
273 }
274
275 @Provide
276 Arbitrary<DirTree.Directory> anyDirTreeDirectory() {
277 return Combinators.combine(Arbitraries.strings(), anyChecksum(), anyChecksum())
278 .as(DirTree.Directory::new);
279 }
280
281 @Provide
282 Arbitrary<DirTree.File> anyDirTreeFile() {
283 return Combinators.combine(Arbitraries.strings(), anyChecksum()).as(DirTree.File::new);
Matthias Andreas Benkarddf853ef2023-12-10 20:29:35 +0100284 }
285}