Skip to content

Commit 08ca701

Browse files
google-genai-botcopybara-github
authored andcommitted
test: cover inline data metadata on session reloads
PiperOrigin-RevId: 1008101726
1 parent 9949265 commit 08ca701

2 files changed

Lines changed: 60 additions & 41 deletions

File tree

‎core/src/test/java/com/google/adk/sessions/SessionJsonConverterTest.java‎

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,8 @@ public void convertEventToJson_thenFromApiEvent_roundTripsWholeEvent() throws Ex
744744
}
745745

746746
@Test
747-
public void convertEventToJson_thenFromApiEvent_roundTripsInlineBytes() throws Exception {
747+
public void convertEventToJson_thenFromApiEventWithoutTypedContent_readsInlineDataFromRawEvent()
748+
throws Exception {
748749
byte[] data = {(byte) 0xfb, (byte) 0xff, 0x01};
749750
Event event =
750751
Event.builder()
@@ -753,9 +754,12 @@ public void convertEventToJson_thenFromApiEvent_roundTripsInlineBytes() throws E
753754
.timestamp(1_700_000_000_123L)
754755
.content(Content.fromParts(Part.fromBytes(data, "image/png")))
755756
.build();
757+
Map<String, Object> storedEvent = asStoredEvent(event);
758+
// Without the typed content, only rawEvent can supply the bytes and MIME type.
759+
storedEvent.remove("content");
756760

757761
Blob reloaded =
758-
SessionJsonConverter.fromApiEvent(asStoredEvent(event))
762+
SessionJsonConverter.fromApiEvent(storedEvent)
759763
.content()
760764
.get()
761765
.parts()
@@ -765,10 +769,41 @@ public void convertEventToJson_thenFromApiEvent_roundTripsInlineBytes() throws E
765769
.get();
766770

767771
assertThat(reloaded.data().get()).isEqualTo(data);
768-
// Only rawEvent keeps the MIME type, so this proves the bytes came from it.
769772
assertThat(reloaded.mimeType()).hasValue("image/png");
770773
}
771774

775+
@Test
776+
public void convertEventToJson_thenFromApiEventWithoutRawEvent_keepsInlineData()
777+
throws Exception {
778+
byte[] data = {(byte) 0xfb, (byte) 0xff, 0x01};
779+
Blob inlineData =
780+
Blob.builder().data(data).mimeType("image/png").displayName("cat.png").build();
781+
Event event =
782+
Event.builder()
783+
.author("user")
784+
.invocationId("inv-1")
785+
.timestamp(1_700_000_000_123L)
786+
.content(Content.fromParts(Part.builder().inlineData(inlineData).build()))
787+
.build();
788+
Map<String, Object> storedEvent = asStoredEvent(event);
789+
// An event stored without rawEvent reloads from the typed fields.
790+
storedEvent.remove("rawEvent");
791+
792+
Blob reloaded =
793+
SessionJsonConverter.fromApiEvent(storedEvent)
794+
.content()
795+
.get()
796+
.parts()
797+
.get()
798+
.get(0)
799+
.inlineData()
800+
.get();
801+
802+
assertThat(reloaded.data().get()).isEqualTo(data);
803+
assertThat(reloaded.mimeType()).hasValue("image/png");
804+
assertThat(reloaded.displayName()).hasValue("cat.png");
805+
}
806+
772807
@Test
773808
public void fromApiEvent_pythonWrittenRawEvent_readsFieldsJavaModels() {
774809
// As Python ADK dumps it: float seconds, URL-safe base64 and keys Java does not model.

‎core/src/test/java/com/google/adk/sessions/SessionUtilsTest.java‎

Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,77 +17,61 @@
1717
package com.google.adk.sessions;
1818

1919
import static com.google.common.truth.Truth.assertThat;
20+
import static java.nio.charset.StandardCharsets.UTF_8;
2021

21-
import com.fasterxml.jackson.databind.JsonNode;
22-
import com.fasterxml.jackson.databind.ObjectMapper;
23-
import com.google.adk.JsonBaseModel;
24-
import com.google.adk.events.Event;
2522
import com.google.genai.types.Blob;
2623
import com.google.genai.types.Content;
2724
import com.google.genai.types.Part;
28-
import java.nio.charset.StandardCharsets;
29-
import java.time.Instant;
25+
import java.util.Base64;
3026
import org.junit.Test;
3127
import org.junit.runner.RunWith;
3228
import org.junit.runners.JUnit4;
3329

3430
@RunWith(JUnit4.class)
3531
public class SessionUtilsTest {
3632

37-
private static final ObjectMapper objectMapper = JsonBaseModel.getMapper();
38-
private static final byte[] PAYLOAD = "payload".getBytes(StandardCharsets.UTF_8);
33+
private static final byte[] payload = "payload".getBytes(UTF_8);
3934

40-
private static Content contentWithInlineData() {
35+
private static Content contentWithInlineData(byte[] data) {
4136
return Content.builder()
4237
.role("user")
4338
.parts(
4439
Part.builder()
45-
.inlineData(Blob.builder().mimeType("image/png").data(PAYLOAD).build())
40+
.inlineData(
41+
Blob.builder().mimeType("image/png").displayName("cat.png").data(data).build())
4642
.build())
4743
.build();
4844
}
4945

5046
@Test
51-
public void encodeContent_inlineData_preservesMimeType() {
52-
Content encoded = SessionUtils.encodeContent(contentWithInlineData());
47+
public void encodeContent_inlineData_encodesDataAndKeepsMetadata() {
48+
Content encoded = SessionUtils.encodeContent(contentWithInlineData(payload));
5349

54-
Blob encodedBlob = encoded.parts().get().get(0).inlineData().get();
55-
assertThat(encodedBlob.mimeType()).hasValue("image/png");
50+
Blob blob = encoded.parts().get().get(0).inlineData().get();
51+
assertThat(Base64.getDecoder().decode(blob.data().get())).isEqualTo(payload);
52+
assertThat(blob.mimeType()).hasValue("image/png");
53+
assertThat(blob.displayName()).hasValue("cat.png");
5654
}
5755

5856
@Test
59-
public void decodeContent_inlineData_preservesMimeType() {
60-
Content decoded = SessionUtils.decodeContent(contentWithInlineData());
57+
public void decodeContent_base64InlineData_decodesDataAndKeepsMetadata() {
58+
Content decoded =
59+
SessionUtils.decodeContent(contentWithInlineData(Base64.getEncoder().encode(payload)));
6160

62-
Blob decodedBlob = decoded.parts().get().get(0).inlineData().get();
63-
assertThat(decodedBlob.mimeType()).hasValue("image/png");
61+
Blob blob = decoded.parts().get().get(0).inlineData().get();
62+
assertThat(blob.data().get()).isEqualTo(payload);
63+
assertThat(blob.mimeType()).hasValue("image/png");
64+
assertThat(blob.displayName()).hasValue("cat.png");
6465
}
6566

6667
@Test
6768
public void decodeContent_encodeContent_roundTripsInlineData() {
6869
Content roundTripped =
69-
SessionUtils.decodeContent(SessionUtils.encodeContent(contentWithInlineData()));
70+
SessionUtils.decodeContent(SessionUtils.encodeContent(contentWithInlineData(payload)));
7071

7172
Blob blob = roundTripped.parts().get().get(0).inlineData().get();
73+
assertThat(blob.data().get()).isEqualTo(payload);
7274
assertThat(blob.mimeType()).hasValue("image/png");
73-
assertThat(blob.data().get()).isEqualTo(PAYLOAD);
74-
}
75-
76-
/** The MIME type has to survive the JSON the Vertex AI Sessions API stores the event in. */
77-
@Test
78-
public void convertEventToJson_inlineData_persistsMimeType() throws Exception {
79-
Event event =
80-
Event.builder()
81-
.author("user")
82-
.invocationId("inv-123")
83-
.timestamp(Instant.parse("2023-01-01T00:00:00Z").toEpochMilli())
84-
.content(contentWithInlineData())
85-
.build();
86-
87-
JsonNode jsonNode = objectMapper.readTree(SessionJsonConverter.convertEventToJson(event));
88-
89-
JsonNode inlineData = jsonNode.get("content").get("parts").get(0).get("inlineData");
90-
assertThat(inlineData.has("mimeType")).isTrue();
91-
assertThat(inlineData.get("mimeType").asText()).isEqualTo("image/png");
75+
assertThat(blob.displayName()).hasValue("cat.png");
9276
}
9377
}

0 commit comments

Comments
 (0)