Skip to content

Commit 7577447

Browse files
Add 127-field unit tests for field filtering at scale
Test that ?fields= correctly selects a small subset from a response object with 127 fields (mixed String, double, int, long, boolean). Three new tests: - testFilter127FieldsKeepOne: 126 of 127 fields filtered, 1 kept - testFilter127FieldsKeepFive: 122 filtered, 5 kept across all types - testFilter127FieldsPayloadSizeReduction: >90% payload reduction verified (full response >1KB, filtered <200 bytes) Uses generic field names (s0-s29, d0-d39, i0-i24, l0-l19, b0-b11) with programmatic initialization via reflection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0a1600a commit 7577447

1 file changed

Lines changed: 136 additions & 0 deletions

File tree

modules/json/test/org/apache/axis2/json/streaming/FieldFilteringMessageFormatterTest.java

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,142 @@ public StaticTransientData() {}
440440
public StaticTransientData(String s, int v) { status = s; value = v; }
441441
}
442442

443+
// ── Large-payload field filtering (127-field POJO) ─────────────────
444+
//
445+
// Tests prove that ?fields= can select a small subset from a wide
446+
// response object (127 fields) without breaking serialization or
447+
// losing data. Uses programmatically generated generic field names.
448+
449+
/**
450+
* POJO with 127 fields to exercise field filtering at scale.
451+
* Uses mixed types (String, double, int, long, boolean) across
452+
* all 127 fields to verify that filtering handles every
453+
* primitive and object type correctly.
454+
*/
455+
public static class WideRecord {
456+
// 30 String fields
457+
public String s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
458+
public String s10, s11, s12, s13, s14, s15, s16, s17, s18, s19;
459+
public String s20, s21, s22, s23, s24, s25, s26, s27, s28, s29;
460+
// 40 double fields
461+
public double d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;
462+
public double d10, d11, d12, d13, d14, d15, d16, d17, d18, d19;
463+
public double d20, d21, d22, d23, d24, d25, d26, d27, d28, d29;
464+
public double d30, d31, d32, d33, d34, d35, d36, d37, d38, d39;
465+
// 25 int fields
466+
public int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
467+
public int i10, i11, i12, i13, i14, i15, i16, i17, i18, i19;
468+
public int i20, i21, i22, i23, i24;
469+
// 20 long fields
470+
public long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9;
471+
public long l10, l11, l12, l13, l14, l15, l16, l17, l18, l19;
472+
// 12 boolean fields — total: 30+40+25+20+12 = 127
473+
public boolean b0, b1, b2, b3, b4, b5, b6, b7, b8, b9;
474+
public boolean b10, b11;
475+
476+
public WideRecord() {}
477+
478+
/** Populate all 127 fields with non-default values. */
479+
public static WideRecord createTestRecord() {
480+
WideRecord r = new WideRecord();
481+
for (int n = 0; n < 30; n++) {
482+
try {
483+
r.getClass().getField("s" + n).set(r, "val_" + n);
484+
} catch (Exception e) { throw new RuntimeException(e); }
485+
}
486+
for (int n = 0; n < 40; n++) {
487+
try {
488+
r.getClass().getField("d" + n).setDouble(r, n * 1.1);
489+
} catch (Exception e) { throw new RuntimeException(e); }
490+
}
491+
for (int n = 0; n < 25; n++) {
492+
try {
493+
r.getClass().getField("i" + n).setInt(r, n * 100);
494+
} catch (Exception e) { throw new RuntimeException(e); }
495+
}
496+
for (int n = 0; n < 20; n++) {
497+
try {
498+
r.getClass().getField("l" + n).setLong(r, n * 1000000L);
499+
} catch (Exception e) { throw new RuntimeException(e); }
500+
}
501+
for (int n = 0; n < 12; n++) {
502+
try {
503+
r.getClass().getField("b" + n).setBoolean(r, n % 2 == 0);
504+
} catch (Exception e) { throw new RuntimeException(e); }
505+
}
506+
return r;
507+
}
508+
}
509+
510+
@Test
511+
public void testFilter127FieldsKeepOne() throws Exception {
512+
setReturnObject(WideRecord.createTestRecord());
513+
outMsgContext.setProperty(JsonConstant.FIELD_FILTER,
514+
setOf("s0"));
515+
516+
formatter.writeTo(outMsgContext, outputFormat, outputStream, false);
517+
JsonElement response = parseResponse();
518+
519+
Assert.assertEquals("Should have exactly 1 field", 1,
520+
response.getAsJsonObject().size());
521+
Assert.assertEquals("val_0",
522+
response.getAsJsonObject().get("s0").getAsString());
523+
}
524+
525+
@Test
526+
public void testFilter127FieldsKeepFive() throws Exception {
527+
setReturnObject(WideRecord.createTestRecord());
528+
outMsgContext.setProperty(JsonConstant.FIELD_FILTER,
529+
setOf("s0", "d5", "i10", "l15", "b0"));
530+
531+
formatter.writeTo(outMsgContext, outputFormat, outputStream, false);
532+
JsonElement response = parseResponse();
533+
534+
Assert.assertEquals("Should have exactly 5 fields", 5,
535+
response.getAsJsonObject().size());
536+
Assert.assertEquals("val_0",
537+
response.getAsJsonObject().get("s0").getAsString());
538+
Assert.assertEquals(5.5,
539+
response.getAsJsonObject().get("d5").getAsDouble(), 0.0001);
540+
Assert.assertEquals(1000,
541+
response.getAsJsonObject().get("i10").getAsInt());
542+
Assert.assertEquals(15000000L,
543+
response.getAsJsonObject().get("l15").getAsLong());
544+
Assert.assertTrue(
545+
response.getAsJsonObject().get("b0").getAsBoolean());
546+
}
547+
548+
@Test
549+
public void testFilter127FieldsPayloadSizeReduction() throws Exception {
550+
WideRecord record = WideRecord.createTestRecord();
551+
552+
// Full response (all 127 fields)
553+
setReturnObject(record);
554+
formatter.writeTo(outMsgContext, outputFormat, outputStream, false);
555+
int fullSize = outputStream.size();
556+
557+
// Filtered response (1 field out of 127)
558+
outputStream.reset();
559+
outMsgContext.setProperty(JsonConstant.FIELD_FILTER,
560+
setOf("s0"));
561+
formatter.writeTo(outMsgContext, outputFormat, outputStream, false);
562+
int filteredSize = outputStream.size();
563+
564+
// The filtered response should be dramatically smaller
565+
double reductionPct = (1.0 - (double) filteredSize / fullSize) * 100;
566+
567+
Assert.assertTrue(
568+
"Full response (" + fullSize + " bytes) should be > 1KB",
569+
fullSize > 1000);
570+
Assert.assertTrue(
571+
"Filtered response (" + filteredSize + " bytes) should be < 200 bytes",
572+
filteredSize < 200);
573+
Assert.assertTrue(
574+
"Payload reduction (" + String.format("%.0f", reductionPct)
575+
+ "%) should exceed 90%",
576+
reductionPct > 90.0);
577+
}
578+
443579
static class TestHelper {
444580
static org.apache.axiom.om.OMElement createFaultElement() {
445581
var factory = OMAbstractFactory.getOMFactory();

0 commit comments

Comments
 (0)