|
7 | 7 | import com.microsoft.durabletask.implementation.protobuf.OrchestratorService.*; |
8 | 8 | import org.junit.jupiter.api.Test; |
9 | 9 |
|
| 10 | +import java.util.List; |
| 11 | +import java.util.Map; |
| 12 | + |
10 | 13 | import static org.junit.jupiter.api.Assertions.*; |
11 | 14 |
|
12 | 15 | /** |
@@ -152,4 +155,113 @@ void fromProto_timestampConversion_isCorrect() { |
152 | 155 | assertEquals(1704067200, event.getTimestamp().getEpochSecond()); |
153 | 156 | assertEquals(500000000, event.getTimestamp().getNano()); |
154 | 157 | } |
| 158 | + |
| 159 | + @SuppressWarnings("unchecked") |
| 160 | + @Test |
| 161 | + void fromProto_taskScheduledWithTags_mapsTagsAsMap() { |
| 162 | + HistoryEvent proto = HistoryEvent.newBuilder() |
| 163 | + .setEventId(10) |
| 164 | + .setTimestamp(Timestamp.newBuilder().setSeconds(1704067200).build()) |
| 165 | + .setTaskScheduled(TaskScheduledEvent.newBuilder() |
| 166 | + .setName("MyActivity") |
| 167 | + .putTags("env", "production") |
| 168 | + .putTags("region", "westus2") |
| 169 | + .build()) |
| 170 | + .build(); |
| 171 | + |
| 172 | + OrchestrationHistoryEvent event = OrchestrationHistoryEventMapper.fromProto(proto); |
| 173 | + |
| 174 | + assertEquals("TaskScheduled", event.getEventType()); |
| 175 | + Object tags = event.getData().get("tags"); |
| 176 | + assertNotNull(tags, "tags should be present in data"); |
| 177 | + assertInstanceOf(Map.class, tags, "tags should be a Map"); |
| 178 | + Map<String, Object> tagsMap = (Map<String, Object>) tags; |
| 179 | + assertEquals("production", tagsMap.get("env")); |
| 180 | + assertEquals("westus2", tagsMap.get("region")); |
| 181 | + } |
| 182 | + |
| 183 | + @SuppressWarnings("unchecked") |
| 184 | + @Test |
| 185 | + void fromProto_entityLockRequested_mapsLockSetAsList() { |
| 186 | + HistoryEvent proto = HistoryEvent.newBuilder() |
| 187 | + .setEventId(11) |
| 188 | + .setTimestamp(Timestamp.newBuilder().setSeconds(1704067200).build()) |
| 189 | + .setEntityLockRequested(EntityLockRequestedEvent.newBuilder() |
| 190 | + .setCriticalSectionId("cs-1") |
| 191 | + .addLockSet("entity1") |
| 192 | + .addLockSet("entity2") |
| 193 | + .addLockSet("entity3") |
| 194 | + .build()) |
| 195 | + .build(); |
| 196 | + |
| 197 | + OrchestrationHistoryEvent event = OrchestrationHistoryEventMapper.fromProto(proto); |
| 198 | + |
| 199 | + assertEquals("EntityLockRequested", event.getEventType()); |
| 200 | + Object lockSet = event.getData().get("lockSet"); |
| 201 | + assertNotNull(lockSet, "lockSet should be present in data"); |
| 202 | + assertInstanceOf(List.class, lockSet, "lockSet should be a List"); |
| 203 | + List<Object> lockList = (List<Object>) lockSet; |
| 204 | + assertEquals(3, lockList.size()); |
| 205 | + assertEquals("entity1", lockList.get(0)); |
| 206 | + assertEquals("entity2", lockList.get(1)); |
| 207 | + assertEquals("entity3", lockList.get(2)); |
| 208 | + } |
| 209 | + |
| 210 | + @SuppressWarnings("unchecked") |
| 211 | + @Test |
| 212 | + void fromProto_executionStartedWithTags_mapsTagsAsMap() { |
| 213 | + HistoryEvent proto = HistoryEvent.newBuilder() |
| 214 | + .setEventId(12) |
| 215 | + .setTimestamp(Timestamp.newBuilder().setSeconds(1704067200).build()) |
| 216 | + .setExecutionStarted(ExecutionStartedEvent.newBuilder() |
| 217 | + .setName("MyOrch") |
| 218 | + .putTags("owner", "team-a") |
| 219 | + .build()) |
| 220 | + .build(); |
| 221 | + |
| 222 | + OrchestrationHistoryEvent event = OrchestrationHistoryEventMapper.fromProto(proto); |
| 223 | + |
| 224 | + assertEquals("ExecutionStarted", event.getEventType()); |
| 225 | + Object tags = event.getData().get("tags"); |
| 226 | + assertNotNull(tags, "tags should be present"); |
| 227 | + assertInstanceOf(Map.class, tags); |
| 228 | + Map<String, Object> tagsMap = (Map<String, Object>) tags; |
| 229 | + assertEquals("team-a", tagsMap.get("owner")); |
| 230 | + } |
| 231 | + |
| 232 | + @Test |
| 233 | + void fromProto_emptyRepeatedField_notIncludedInData() { |
| 234 | + // Proto repeated fields with no elements are not included in getAllFields() |
| 235 | + HistoryEvent proto = HistoryEvent.newBuilder() |
| 236 | + .setEventId(13) |
| 237 | + .setTimestamp(Timestamp.newBuilder().setSeconds(1704067200).build()) |
| 238 | + .setEntityLockRequested(EntityLockRequestedEvent.newBuilder() |
| 239 | + .setCriticalSectionId("cs-empty") |
| 240 | + .build()) |
| 241 | + .build(); |
| 242 | + |
| 243 | + OrchestrationHistoryEvent event = OrchestrationHistoryEventMapper.fromProto(proto); |
| 244 | + |
| 245 | + // lockSet should not be present since it's empty (proto omits default-valued fields) |
| 246 | + assertFalse(event.getData().containsKey("lockSet"), |
| 247 | + "Empty repeated field should not appear in data"); |
| 248 | + } |
| 249 | + |
| 250 | + @SuppressWarnings("unchecked") |
| 251 | + @Test |
| 252 | + void fromProto_emptyMapField_notIncludedInData() { |
| 253 | + // Proto map fields with no entries are not included in getAllFields() |
| 254 | + HistoryEvent proto = HistoryEvent.newBuilder() |
| 255 | + .setEventId(14) |
| 256 | + .setTimestamp(Timestamp.newBuilder().setSeconds(1704067200).build()) |
| 257 | + .setTaskScheduled(TaskScheduledEvent.newBuilder() |
| 258 | + .setName("NoTagsActivity") |
| 259 | + .build()) |
| 260 | + .build(); |
| 261 | + |
| 262 | + OrchestrationHistoryEvent event = OrchestrationHistoryEventMapper.fromProto(proto); |
| 263 | + |
| 264 | + assertFalse(event.getData().containsKey("tags"), |
| 265 | + "Empty map field should not appear in data"); |
| 266 | + } |
155 | 267 | } |
0 commit comments