1 // Copyright 2022 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 //////////////////////////////////////////////////////////////////////////////// 16 17 package com.google.crypto.tink.internal; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static java.nio.charset.StandardCharsets.UTF_8; 21 import static org.junit.Assert.assertThrows; 22 23 import com.google.crypto.tink.InsecureSecretKeyAccess; 24 import com.google.crypto.tink.Key; 25 import com.google.crypto.tink.Parameters; 26 import com.google.crypto.tink.SecretKeyAccess; 27 import com.google.crypto.tink.util.Bytes; 28 import com.google.errorprone.annotations.Immutable; 29 import java.security.GeneralSecurityException; 30 import javax.annotation.Nullable; 31 import org.junit.Test; 32 import org.junit.runner.RunWith; 33 import org.junit.runners.JUnit4; 34 35 /** Unit tests for {@link SerializationRegistry}. */ 36 @RunWith(JUnit4.class) 37 public final class SerializationRegistryTest { 38 // =============================================================================================== 39 // SETUP: 40 // We create 2 different key classes (TestKey1, TestKey2) and two different serialization classes 41 // (TestSerializationA, TestSerializationB), and provide ways to parse and serialize both keys 42 // with both methods. 43 // 44 // For this, we provide the methods serializeKey{1,2}to{A,B} and parseKey{A,B}to{1,2}. The method 45 // serializeKeyBto1 then uses the constant B_1 in the object identifier. 46 // 47 // Note that calling these multiple times will give different objects (which allows us to test 48 // that registering different objects for the same task fails). 49 // 50 // We pick the object identifiers so that they are unique per serialization type, but *not* 51 // unique globally (since different serialization types may use the same object identifiers for 52 // different key types). 53 // =============================================================================================== 54 55 private static final SecretKeyAccess ACCESS = InsecureSecretKeyAccess.get(); 56 57 private static final Bytes A_1 = Bytes.copyFrom("0".getBytes(UTF_8)); 58 private static final Bytes A_2 = Bytes.copyFrom("1".getBytes(UTF_8)); 59 private static final Bytes B_1 = Bytes.copyFrom("1".getBytes(UTF_8)); 60 private static final Bytes B_2 = Bytes.copyFrom("2".getBytes(UTF_8)); 61 62 @Immutable 63 private static final class TestParameters1 extends Parameters { 64 @Override hasIdRequirement()65 public boolean hasIdRequirement() { 66 return false; 67 } 68 } 69 70 @Immutable 71 private static final class TestParameters2 extends Parameters { 72 @Override hasIdRequirement()73 public boolean hasIdRequirement() { 74 return false; 75 } 76 } 77 78 @Immutable 79 private static final class TestKey1 extends Key { 80 @Override getParameters()81 public Parameters getParameters() { 82 throw new UnsupportedOperationException("Not needed in test"); 83 } 84 85 @Override 86 @Nullable getIdRequirementOrNull()87 public Integer getIdRequirementOrNull() { 88 throw new UnsupportedOperationException("Not needed in test"); 89 } 90 91 @Override equalsKey(Key other)92 public boolean equalsKey(Key other) { 93 throw new UnsupportedOperationException("Not needed in test"); 94 } 95 } 96 97 @Immutable 98 private static final class TestKey2 extends Key { 99 @Override getParameters()100 public Parameters getParameters() { 101 throw new UnsupportedOperationException("Not needed in test"); 102 } 103 104 @Override 105 @Nullable getIdRequirementOrNull()106 public Integer getIdRequirementOrNull() { 107 throw new UnsupportedOperationException("Not needed in test"); 108 } 109 110 @Override equalsKey(Key other)111 public boolean equalsKey(Key other) { 112 throw new UnsupportedOperationException("Not needed in test"); 113 } 114 } 115 116 @Immutable 117 private static final class TestSerializationA implements Serialization { TestSerializationA(Bytes objectIdentifier)118 public TestSerializationA(Bytes objectIdentifier) { 119 this.objectIdentifier = objectIdentifier; 120 } 121 122 private final Bytes objectIdentifier; 123 124 @Override getObjectIdentifier()125 public Bytes getObjectIdentifier() { 126 return objectIdentifier; 127 } 128 } 129 130 @Immutable 131 private static final class TestSerializationB implements Serialization { TestSerializationB(Bytes objectIdentifier)132 public TestSerializationB(Bytes objectIdentifier) { 133 this.objectIdentifier = objectIdentifier; 134 } 135 136 private final Bytes objectIdentifier; 137 138 @Override getObjectIdentifier()139 public Bytes getObjectIdentifier() { 140 return objectIdentifier; 141 } 142 } 143 serializeKey1ToA(TestKey1 key, @Nullable SecretKeyAccess access)144 private static TestSerializationA serializeKey1ToA(TestKey1 key, @Nullable SecretKeyAccess access) 145 throws GeneralSecurityException { 146 SecretKeyAccess.requireAccess(access); 147 return new TestSerializationA(A_1); 148 } 149 serializeKey2ToA(TestKey2 key, @Nullable SecretKeyAccess access)150 private static TestSerializationA serializeKey2ToA(TestKey2 key, @Nullable SecretKeyAccess access) 151 throws GeneralSecurityException { 152 SecretKeyAccess.requireAccess(access); 153 return new TestSerializationA(A_2); 154 } 155 serializeKey1ToB(TestKey1 key, @Nullable SecretKeyAccess access)156 private static TestSerializationB serializeKey1ToB(TestKey1 key, @Nullable SecretKeyAccess access) 157 throws GeneralSecurityException { 158 SecretKeyAccess.requireAccess(access); 159 return new TestSerializationB(B_1); 160 } 161 serializeKey2ToB(TestKey2 key, @Nullable SecretKeyAccess access)162 private static TestSerializationB serializeKey2ToB(TestKey2 key, @Nullable SecretKeyAccess access) 163 throws GeneralSecurityException { 164 SecretKeyAccess.requireAccess(access); 165 return new TestSerializationB(B_2); 166 } 167 parseAToKey1( TestSerializationA serialization, @Nullable SecretKeyAccess access)168 private static Key parseAToKey1( 169 TestSerializationA serialization, @Nullable SecretKeyAccess access) 170 throws GeneralSecurityException { 171 if (!A_1.equals(serialization.getObjectIdentifier())) { 172 throw new GeneralSecurityException("Wrong object identifier"); 173 } 174 SecretKeyAccess.requireAccess(access); 175 return new TestKey1(); 176 } 177 parseAToKey2( TestSerializationA serialization, @Nullable SecretKeyAccess access)178 private static Key parseAToKey2( 179 TestSerializationA serialization, @Nullable SecretKeyAccess access) 180 throws GeneralSecurityException { 181 if (!A_2.equals(serialization.getObjectIdentifier())) { 182 throw new GeneralSecurityException("Wrong object identifier"); 183 } 184 SecretKeyAccess.requireAccess(access); 185 return new TestKey2(); 186 } 187 parseBToKey1( TestSerializationB serialization, @Nullable SecretKeyAccess access)188 private static Key parseBToKey1( 189 TestSerializationB serialization, @Nullable SecretKeyAccess access) 190 throws GeneralSecurityException { 191 if (!B_1.equals(serialization.getObjectIdentifier())) { 192 throw new GeneralSecurityException("Wrong object identifier"); 193 } 194 SecretKeyAccess.requireAccess(access); 195 return new TestKey1(); 196 } 197 parseBToKey2( TestSerializationB serialization, @Nullable SecretKeyAccess access)198 private static Key parseBToKey2( 199 TestSerializationB serialization, @Nullable SecretKeyAccess access) 200 throws GeneralSecurityException { 201 if (!B_2.equals(serialization.getObjectIdentifier())) { 202 throw new GeneralSecurityException("Wrong object identifier"); 203 } 204 SecretKeyAccess.requireAccess(access); 205 return new TestKey2(); 206 } 207 208 // ======================================================================= Key serialization tests 209 @Test test_registerSerializerAndGet()210 public void test_registerSerializerAndGet() throws Exception { 211 SerializationRegistry registry = 212 new SerializationRegistry.Builder() 213 .registerKeySerializer( 214 KeySerializer.create( 215 SerializationRegistryTest::serializeKey1ToA, 216 TestKey1.class, 217 TestSerializationA.class)) 218 .build(); 219 assertThat(registry.hasSerializerForKey(new TestKey1(), TestSerializationA.class)).isTrue(); 220 assertThat(registry.serializeKey(new TestKey1(), TestSerializationA.class, ACCESS)).isNotNull(); 221 } 222 223 @Test test_emptyRegistry_throws()224 public void test_emptyRegistry_throws() throws Exception { 225 SerializationRegistry registry = new SerializationRegistry.Builder().build(); 226 assertThat(registry.hasSerializerForKey(new TestKey1(), TestSerializationA.class)).isFalse(); 227 assertThrows( 228 GeneralSecurityException.class, 229 () -> registry.serializeKey(new TestKey1(), TestSerializationA.class, ACCESS)); 230 } 231 232 @Test test_noAccessSerializer_throws()233 public void test_noAccessSerializer_throws() throws Exception { 234 SerializationRegistry registry = 235 new SerializationRegistry.Builder() 236 .registerKeySerializer( 237 KeySerializer.create( 238 SerializationRegistryTest::serializeKey1ToA, 239 TestKey1.class, 240 TestSerializationA.class)) 241 .build(); 242 assertThrows( 243 GeneralSecurityException.class, 244 () -> registry.serializeKey(new TestKey1(), TestSerializationA.class, /* access= */ null)); 245 } 246 247 @Test test_registerSameSerializerTwice_works()248 public void test_registerSameSerializerTwice_works() throws Exception { 249 KeySerializer<TestKey1, TestSerializationA> testSerializer = 250 KeySerializer.create( 251 SerializationRegistryTest::serializeKey1ToA, TestKey1.class, TestSerializationA.class); 252 SerializationRegistry unused = new SerializationRegistry.Builder() 253 .registerKeySerializer(testSerializer) 254 .registerKeySerializer(testSerializer) 255 .build(); 256 } 257 258 @Test test_registerDifferentSerializerWithSameKeyType_throws()259 public void test_registerDifferentSerializerWithSameKeyType_throws() throws Exception { 260 KeySerializer<TestKey1, TestSerializationA> testSerializer1 = 261 KeySerializer.create( 262 SerializationRegistryTest::serializeKey1ToA, TestKey1.class, TestSerializationA.class); 263 KeySerializer<TestKey1, TestSerializationA> testSerializer2 = 264 KeySerializer.create( 265 SerializationRegistryTest::serializeKey1ToA, TestKey1.class, TestSerializationA.class); 266 SerializationRegistry.Builder builder = new SerializationRegistry.Builder(); 267 builder.registerKeySerializer(testSerializer1); 268 assertThrows( 269 GeneralSecurityException.class, 270 () -> builder.registerKeySerializer(testSerializer2)); 271 } 272 273 @Test test_registerDifferentSerializerWithDifferentKeyType_works()274 public void test_registerDifferentSerializerWithDifferentKeyType_works() throws Exception { 275 KeySerializer<TestKey1, TestSerializationA> testSerializer1 = 276 KeySerializer.create( 277 SerializationRegistryTest::serializeKey1ToA, TestKey1.class, TestSerializationA.class); 278 KeySerializer<TestKey2, TestSerializationA> testSerializer2 = 279 KeySerializer.create( 280 SerializationRegistryTest::serializeKey2ToA, TestKey2.class, TestSerializationA.class); 281 SerializationRegistry unused = new SerializationRegistry.Builder() 282 .registerKeySerializer(testSerializer1) 283 .registerKeySerializer(testSerializer2) 284 .build(); 285 } 286 287 @Test test_registerDifferentSerializerWithDifferentSerializationType_works()288 public void test_registerDifferentSerializerWithDifferentSerializationType_works() 289 throws Exception { 290 KeySerializer<TestKey1, TestSerializationA> testSerializer1 = 291 KeySerializer.create( 292 SerializationRegistryTest::serializeKey1ToA, TestKey1.class, TestSerializationA.class); 293 KeySerializer<TestKey2, TestSerializationA> testSerializer2 = 294 KeySerializer.create( 295 SerializationRegistryTest::serializeKey2ToA, TestKey2.class, TestSerializationA.class); 296 SerializationRegistry unused = new SerializationRegistry.Builder() 297 .registerKeySerializer(testSerializer1) 298 .registerKeySerializer(testSerializer2) 299 .build(); 300 } 301 302 @Test test_registerAll_checkDispatch()303 public void test_registerAll_checkDispatch() throws Exception { 304 SerializationRegistry registry = 305 new SerializationRegistry.Builder() 306 .registerKeySerializer( 307 KeySerializer.create( 308 SerializationRegistryTest::serializeKey1ToA, 309 TestKey1.class, 310 TestSerializationA.class)) 311 .registerKeySerializer( 312 KeySerializer.create( 313 SerializationRegistryTest::serializeKey1ToB, 314 TestKey1.class, 315 TestSerializationB.class)) 316 .registerKeySerializer( 317 KeySerializer.create( 318 SerializationRegistryTest::serializeKey2ToA, 319 TestKey2.class, 320 TestSerializationA.class)) 321 .registerKeySerializer( 322 KeySerializer.create( 323 SerializationRegistryTest::serializeKey2ToB, 324 TestKey2.class, 325 TestSerializationB.class)) 326 .build(); 327 assertThat( 328 registry 329 .serializeKey(new TestKey1(), TestSerializationA.class, ACCESS) 330 .getObjectIdentifier()) 331 .isEqualTo(A_1); 332 assertThat( 333 registry 334 .serializeKey(new TestKey2(), TestSerializationA.class, ACCESS) 335 .getObjectIdentifier()) 336 .isEqualTo(A_2); 337 assertThat( 338 registry 339 .serializeKey(new TestKey1(), TestSerializationB.class, ACCESS) 340 .getObjectIdentifier()) 341 .isEqualTo(B_1); 342 assertThat( 343 registry 344 .serializeKey(new TestKey2(), TestSerializationB.class, ACCESS) 345 .getObjectIdentifier()) 346 .isEqualTo(B_2); 347 } 348 349 @Test test_serializer_copyWorks()350 public void test_serializer_copyWorks() throws Exception { 351 SerializationRegistry registry = 352 new SerializationRegistry.Builder() 353 .registerKeySerializer( 354 KeySerializer.create( 355 SerializationRegistryTest::serializeKey1ToA, 356 TestKey1.class, 357 TestSerializationA.class)) 358 .build(); 359 SerializationRegistry registry2 = new SerializationRegistry.Builder(registry).build(); 360 assertThat(registry2.serializeKey(new TestKey1(), TestSerializationA.class, ACCESS)) 361 .isNotNull(); 362 } 363 364 @Test test_copyDoesNotChangeOldVersion_serializer()365 public void test_copyDoesNotChangeOldVersion_serializer() throws Exception { 366 SerializationRegistry registry1 = new SerializationRegistry.Builder().build(); 367 SerializationRegistry.Builder builder = new SerializationRegistry.Builder(registry1); 368 SerializationRegistry registry2 = builder.build(); 369 builder.registerKeySerializer( 370 KeySerializer.create( 371 SerializationRegistryTest::serializeKey1ToA, TestKey1.class, TestSerializationA.class)); 372 assertThrows( 373 GeneralSecurityException.class, 374 () -> registry1.serializeKey(new TestKey1(), TestSerializationA.class, ACCESS)); 375 assertThrows( 376 GeneralSecurityException.class, 377 () -> registry2.serializeKey(new TestKey1(), TestSerializationA.class, ACCESS)); 378 } 379 380 // ============================================================================= Key parsing tests 381 @Test test_registerParserAndGet()382 public void test_registerParserAndGet() throws Exception { 383 SerializationRegistry registry = 384 new SerializationRegistry.Builder() 385 .registerKeyParser( 386 KeyParser.create( 387 SerializationRegistryTest::parseAToKey1, A_1, TestSerializationA.class)) 388 .build(); 389 assertThat(registry.hasParserForKey(new TestSerializationA(A_1))).isTrue(); 390 assertThat(registry.parseKey(new TestSerializationA(A_1), ACCESS)).isNotNull(); 391 } 392 393 @Test test_registerParser_noAccess_throws()394 public void test_registerParser_noAccess_throws() throws Exception { 395 SerializationRegistry registry = 396 new SerializationRegistry.Builder() 397 .registerKeyParser( 398 KeyParser.create( 399 SerializationRegistryTest::parseAToKey1, A_1, TestSerializationA.class)) 400 .build(); 401 assertThrows( 402 GeneralSecurityException.class, 403 () -> registry.parseKey(new TestSerializationA(A_1), /* access = */ null)); 404 } 405 406 @Test test_parse_emptyRegistry_throws()407 public void test_parse_emptyRegistry_throws() throws Exception { 408 SerializationRegistry registry = new SerializationRegistry.Builder().build(); 409 assertThat(registry.hasParserForKey(new TestSerializationA(A_1))).isFalse(); 410 assertThrows( 411 GeneralSecurityException.class, 412 () -> registry.parseKey(new TestSerializationA(A_1), ACCESS)); 413 } 414 415 @Test test_registerSameParserTwice_works()416 public void test_registerSameParserTwice_works() throws Exception { 417 KeyParser<TestSerializationA> testParser = 418 KeyParser.create(SerializationRegistryTest::parseAToKey1, A_1, TestSerializationA.class); 419 SerializationRegistry unused = new SerializationRegistry.Builder() 420 .registerKeyParser(testParser) 421 .registerKeyParser(testParser) 422 .build(); 423 } 424 425 @Test test_registerDifferentParsersWithSameKeyType_throws()426 public void test_registerDifferentParsersWithSameKeyType_throws() throws Exception { 427 KeyParser<TestSerializationA> testParser1 = 428 KeyParser.create(SerializationRegistryTest::parseAToKey1, A_1, TestSerializationA.class); 429 KeyParser<TestSerializationA> testParser2 = 430 KeyParser.create(SerializationRegistryTest::parseAToKey1, A_1, TestSerializationA.class); 431 SerializationRegistry.Builder builder = new SerializationRegistry.Builder(); 432 builder.registerKeyParser(testParser1); 433 assertThrows( 434 GeneralSecurityException.class, () -> builder.registerKeyParser(testParser2)); 435 } 436 437 @Test test_registerDifferentParsersWithDifferentSerializationType_works()438 public void test_registerDifferentParsersWithDifferentSerializationType_works() throws Exception { 439 KeyParser<TestSerializationA> testParser1 = 440 KeyParser.create(SerializationRegistryTest::parseAToKey1, A_1, TestSerializationA.class); 441 KeyParser<TestSerializationB> testParser2 = 442 KeyParser.create(SerializationRegistryTest::parseBToKey1, B_1, TestSerializationB.class); 443 SerializationRegistry unused = new SerializationRegistry.Builder() 444 .registerKeyParser(testParser1) 445 .registerKeyParser(testParser2) 446 .build(); 447 } 448 449 @Test test_registerDifferentParsersWithDifferentKeyType_works()450 public void test_registerDifferentParsersWithDifferentKeyType_works() throws Exception { 451 KeyParser<TestSerializationA> testParser1 = 452 KeyParser.create(SerializationRegistryTest::parseAToKey1, A_1, TestSerializationA.class); 453 KeyParser<TestSerializationA> testParser2 = 454 KeyParser.create(SerializationRegistryTest::parseAToKey2, A_2, TestSerializationA.class); 455 SerializationRegistry unused = new SerializationRegistry.Builder() 456 .registerKeyParser(testParser1) 457 .registerKeyParser(testParser2) 458 .build(); 459 } 460 461 @Test test_registerAllParsers_checkDispatch()462 public void test_registerAllParsers_checkDispatch() throws Exception { 463 SerializationRegistry registry = 464 new SerializationRegistry.Builder() 465 .registerKeyParser( 466 KeyParser.create( 467 SerializationRegistryTest::parseAToKey1, A_1, TestSerializationA.class)) 468 .registerKeyParser( 469 KeyParser.create( 470 SerializationRegistryTest::parseBToKey1, B_1, TestSerializationB.class)) 471 .registerKeyParser( 472 KeyParser.create( 473 SerializationRegistryTest::parseAToKey2, A_2, TestSerializationA.class)) 474 .registerKeyParser( 475 KeyParser.create( 476 SerializationRegistryTest::parseBToKey2, B_2, TestSerializationB.class)) 477 .build(); 478 assertThat(registry.parseKey(new TestSerializationA(A_1), ACCESS)).isInstanceOf(TestKey1.class); 479 assertThat(registry.parseKey(new TestSerializationA(A_2), ACCESS)).isInstanceOf(TestKey2.class); 480 assertThat(registry.parseKey(new TestSerializationB(B_1), ACCESS)).isInstanceOf(TestKey1.class); 481 assertThat(registry.parseKey(new TestSerializationB(B_2), ACCESS)).isInstanceOf(TestKey2.class); 482 } 483 484 @Test test_copyWorksForParsers()485 public void test_copyWorksForParsers() throws Exception { 486 SerializationRegistry registry = 487 new SerializationRegistry.Builder() 488 .registerKeyParser( 489 KeyParser.create( 490 SerializationRegistryTest::parseAToKey1, A_1, TestSerializationA.class)) 491 .build(); 492 SerializationRegistry registry2 = new SerializationRegistry.Builder(registry).build(); 493 assertThat(registry2.parseKey(new TestSerializationA(A_1), ACCESS)).isNotNull(); 494 } 495 496 @Test test_copyDoesNotChangeOldVersion_parser()497 public void test_copyDoesNotChangeOldVersion_parser() throws Exception { 498 SerializationRegistry registry1 = new SerializationRegistry.Builder().build(); 499 SerializationRegistry.Builder builder = new SerializationRegistry.Builder(registry1); 500 SerializationRegistry registry2 = builder.build(); 501 502 SerializationRegistry unused = builder 503 .registerKeyParser( 504 KeyParser.create( 505 SerializationRegistryTest::parseAToKey1, A_1, TestSerializationA.class)) 506 .build(); 507 assertThrows( 508 GeneralSecurityException.class, 509 () -> registry1.parseKey(new TestSerializationA(A_1), ACCESS)); 510 assertThrows( 511 GeneralSecurityException.class, 512 () -> registry2.parseKey(new TestSerializationA(A_1), ACCESS)); 513 } 514 515 // ================================================================================================ 516 // PARAMETERS TESTS 517 // ================================================================================================ serializeParameters1ToA(TestParameters1 parameters)518 private static TestSerializationA serializeParameters1ToA(TestParameters1 parameters) 519 throws GeneralSecurityException { 520 return new TestSerializationA(A_1); 521 } 522 serializeParameters2ToA(TestParameters2 parameters)523 private static TestSerializationA serializeParameters2ToA(TestParameters2 parameters) 524 throws GeneralSecurityException { 525 return new TestSerializationA(A_2); 526 } 527 serializeParameters1ToB(TestParameters1 parameters)528 private static TestSerializationB serializeParameters1ToB(TestParameters1 parameters) 529 throws GeneralSecurityException { 530 return new TestSerializationB(B_1); 531 } 532 serializeParameters2ToB(TestParameters2 parameters)533 private static TestSerializationB serializeParameters2ToB(TestParameters2 parameters) 534 throws GeneralSecurityException { 535 return new TestSerializationB(B_2); 536 } 537 parseAToParameters1(TestSerializationA serialization)538 private static Parameters parseAToParameters1(TestSerializationA serialization) 539 throws GeneralSecurityException { 540 if (!A_1.equals(serialization.getObjectIdentifier())) { 541 throw new GeneralSecurityException("Wrong object identifier"); 542 } 543 return new TestParameters1(); 544 } 545 parseAToParameters2(TestSerializationA serialization)546 private static Parameters parseAToParameters2(TestSerializationA serialization) 547 throws GeneralSecurityException { 548 if (!A_2.equals(serialization.getObjectIdentifier())) { 549 throw new GeneralSecurityException("Wrong object identifier"); 550 } 551 return new TestParameters2(); 552 } 553 parseBToParameters1(TestSerializationB serialization)554 private static Parameters parseBToParameters1(TestSerializationB serialization) 555 throws GeneralSecurityException { 556 if (!B_1.equals(serialization.getObjectIdentifier())) { 557 throw new GeneralSecurityException("Wrong object identifier"); 558 } 559 return new TestParameters1(); 560 } 561 parseBToParameters2(TestSerializationB serialization)562 private static Parameters parseBToParameters2(TestSerializationB serialization) 563 throws GeneralSecurityException { 564 if (!B_2.equals(serialization.getObjectIdentifier())) { 565 throw new GeneralSecurityException("Wrong object identifier"); 566 } 567 return new TestParameters2(); 568 } 569 570 // ParametersSerialization tests 571 @Test test_registerParametersSerializerAndGet()572 public void test_registerParametersSerializerAndGet() throws Exception { 573 SerializationRegistry registry = 574 new SerializationRegistry.Builder() 575 .registerParametersSerializer( 576 ParametersSerializer.create( 577 SerializationRegistryTest::serializeParameters1ToA, 578 TestParameters1.class, 579 TestSerializationA.class)) 580 .build(); 581 assertThat(registry.hasSerializerForParameters(new TestParameters1(), TestSerializationA.class)) 582 .isTrue(); 583 assertThat(registry.serializeParameters(new TestParameters1(), TestSerializationA.class)) 584 .isNotNull(); 585 } 586 587 @Test test_emptyRegistrySerializeParameters_throws()588 public void test_emptyRegistrySerializeParameters_throws() throws Exception { 589 SerializationRegistry registry = new SerializationRegistry.Builder().build(); 590 assertThat(registry.hasSerializerForParameters(new TestParameters1(), TestSerializationA.class)) 591 .isFalse(); 592 assertThrows( 593 GeneralSecurityException.class, 594 () -> registry.serializeParameters(new TestParameters1(), TestSerializationA.class)); 595 } 596 597 @Test test_registerSameParametersSerializerTwice_works()598 public void test_registerSameParametersSerializerTwice_works() throws Exception { 599 ParametersSerializer<TestParameters1, TestSerializationA> testSerializer = 600 ParametersSerializer.create( 601 SerializationRegistryTest::serializeParameters1ToA, 602 TestParameters1.class, 603 TestSerializationA.class); 604 SerializationRegistry unused = new SerializationRegistry.Builder() 605 .registerParametersSerializer(testSerializer) 606 .registerParametersSerializer(testSerializer) 607 .build(); 608 } 609 610 @Test test_registerDifferentSerializerWithSameParametersType_throws()611 public void test_registerDifferentSerializerWithSameParametersType_throws() throws Exception { 612 ParametersSerializer<TestParameters1, TestSerializationA> testSerializer1 = 613 ParametersSerializer.create( 614 SerializationRegistryTest::serializeParameters1ToA, 615 TestParameters1.class, 616 TestSerializationA.class); 617 ParametersSerializer<TestParameters1, TestSerializationA> testSerializer2 = 618 ParametersSerializer.create( 619 SerializationRegistryTest::serializeParameters1ToA, 620 TestParameters1.class, 621 TestSerializationA.class); 622 SerializationRegistry.Builder builder = new SerializationRegistry.Builder(); 623 builder.registerParametersSerializer(testSerializer1); 624 assertThrows( 625 GeneralSecurityException.class, 626 () -> builder.registerParametersSerializer(testSerializer2)); 627 } 628 629 @Test test_registerDifferentSerializerWithDifferentParametersType_works()630 public void test_registerDifferentSerializerWithDifferentParametersType_works() throws Exception { 631 ParametersSerializer<TestParameters1, TestSerializationA> testSerializer1 = 632 ParametersSerializer.create( 633 SerializationRegistryTest::serializeParameters1ToA, 634 TestParameters1.class, 635 TestSerializationA.class); 636 ParametersSerializer<TestParameters2, TestSerializationA> testSerializer2 = 637 ParametersSerializer.create( 638 SerializationRegistryTest::serializeParameters2ToA, 639 TestParameters2.class, 640 TestSerializationA.class); 641 SerializationRegistry unused = new SerializationRegistry.Builder() 642 .registerParametersSerializer(testSerializer1) 643 .registerParametersSerializer(testSerializer2) 644 .build(); 645 } 646 647 @Test test_registerDifferentSerializerWithDifferentFormatSerializationType_works()648 public void test_registerDifferentSerializerWithDifferentFormatSerializationType_works() 649 throws Exception { 650 ParametersSerializer<TestParameters1, TestSerializationA> testSerializer1 = 651 ParametersSerializer.create( 652 SerializationRegistryTest::serializeParameters1ToA, 653 TestParameters1.class, 654 TestSerializationA.class); 655 ParametersSerializer<TestParameters2, TestSerializationA> testSerializer2 = 656 ParametersSerializer.create( 657 SerializationRegistryTest::serializeParameters2ToA, 658 TestParameters2.class, 659 TestSerializationA.class); 660 SerializationRegistry unused = new SerializationRegistry.Builder() 661 .registerParametersSerializer(testSerializer1) 662 .registerParametersSerializer(testSerializer2) 663 .build(); 664 } 665 666 @Test test_registerAllParametersSerializers_checkDispatch()667 public void test_registerAllParametersSerializers_checkDispatch() throws Exception { 668 SerializationRegistry registry = 669 new SerializationRegistry.Builder() 670 .registerParametersSerializer( 671 ParametersSerializer.create( 672 SerializationRegistryTest::serializeParameters1ToA, 673 TestParameters1.class, 674 TestSerializationA.class)) 675 .registerParametersSerializer( 676 ParametersSerializer.create( 677 SerializationRegistryTest::serializeParameters1ToB, 678 TestParameters1.class, 679 TestSerializationB.class)) 680 .registerParametersSerializer( 681 ParametersSerializer.create( 682 SerializationRegistryTest::serializeParameters2ToA, 683 TestParameters2.class, 684 TestSerializationA.class)) 685 .registerParametersSerializer( 686 ParametersSerializer.create( 687 SerializationRegistryTest::serializeParameters2ToB, 688 TestParameters2.class, 689 TestSerializationB.class)) 690 .build(); 691 assertThat( 692 registry 693 .serializeParameters(new TestParameters1(), TestSerializationA.class) 694 .getObjectIdentifier()) 695 .isEqualTo(A_1); 696 assertThat( 697 registry 698 .serializeParameters(new TestParameters2(), TestSerializationA.class) 699 .getObjectIdentifier()) 700 .isEqualTo(A_2); 701 assertThat( 702 registry 703 .serializeParameters(new TestParameters1(), TestSerializationB.class) 704 .getObjectIdentifier()) 705 .isEqualTo(B_1); 706 assertThat( 707 registry 708 .serializeParameters(new TestParameters2(), TestSerializationB.class) 709 .getObjectIdentifier()) 710 .isEqualTo(B_2); 711 } 712 713 @Test test_formatSerializer_copyWorks()714 public void test_formatSerializer_copyWorks() throws Exception { 715 SerializationRegistry registry = 716 new SerializationRegistry.Builder() 717 .registerParametersSerializer( 718 ParametersSerializer.create( 719 SerializationRegistryTest::serializeParameters1ToA, 720 TestParameters1.class, 721 TestSerializationA.class)) 722 .build(); 723 SerializationRegistry registry2 = new SerializationRegistry.Builder(registry).build(); 724 assertThat(registry2.serializeParameters(new TestParameters1(), TestSerializationA.class)) 725 .isNotNull(); 726 } 727 728 @Test test_copyDoesNotChangeOldVersion_formatSerializer()729 public void test_copyDoesNotChangeOldVersion_formatSerializer() throws Exception { 730 SerializationRegistry registry1 = new SerializationRegistry.Builder().build(); 731 SerializationRegistry.Builder builder = new SerializationRegistry.Builder(registry1); 732 SerializationRegistry registry2 = builder.build(); 733 builder.registerParametersSerializer( 734 ParametersSerializer.create( 735 SerializationRegistryTest::serializeParameters1ToA, 736 TestParameters1.class, 737 TestSerializationA.class)); 738 assertThrows( 739 GeneralSecurityException.class, 740 () -> registry1.serializeParameters(new TestParameters1(), TestSerializationA.class)); 741 assertThrows( 742 GeneralSecurityException.class, 743 () -> registry2.serializeParameters(new TestParameters1(), TestSerializationA.class)); 744 } 745 746 // ====================================================================== Parameters parsing tests 747 @Test test_registerParametersParserAndGet()748 public void test_registerParametersParserAndGet() throws Exception { 749 SerializationRegistry registry = 750 new SerializationRegistry.Builder() 751 .registerParametersParser( 752 ParametersParser.create( 753 SerializationRegistryTest::parseAToParameters1, A_1, TestSerializationA.class)) 754 .build(); 755 assertThat(registry.hasParserForParameters(new TestSerializationA(A_1))).isTrue(); 756 assertThat(registry.parseParameters(new TestSerializationA(A_1))).isNotNull(); 757 } 758 759 @Test test_formatParse_emptyRegistry_throws()760 public void test_formatParse_emptyRegistry_throws() throws Exception { 761 SerializationRegistry registry = new SerializationRegistry.Builder().build(); 762 assertThat(registry.hasParserForParameters(new TestSerializationA(A_1))).isFalse(); 763 assertThrows( 764 GeneralSecurityException.class, 765 () -> registry.parseParameters(new TestSerializationA(A_1))); 766 } 767 768 @Test test_registerSameParametersParserTwice_works()769 public void test_registerSameParametersParserTwice_works() throws Exception { 770 ParametersParser<TestSerializationA> testParser = 771 ParametersParser.create( 772 SerializationRegistryTest::parseAToParameters1, A_1, TestSerializationA.class); 773 SerializationRegistry unused = new SerializationRegistry.Builder() 774 .registerParametersParser(testParser) 775 .registerParametersParser(testParser) 776 .build(); 777 } 778 779 @Test test_registerDifferentParsersWithSameParametersType_throws()780 public void test_registerDifferentParsersWithSameParametersType_throws() throws Exception { 781 ParametersParser<TestSerializationA> testParser1 = 782 ParametersParser.create( 783 SerializationRegistryTest::parseAToParameters1, A_1, TestSerializationA.class); 784 ParametersParser<TestSerializationA> testParser2 = 785 ParametersParser.create( 786 SerializationRegistryTest::parseAToParameters1, A_1, TestSerializationA.class); 787 SerializationRegistry.Builder builder = new SerializationRegistry.Builder(); 788 builder.registerParametersParser(testParser1); 789 assertThrows( 790 GeneralSecurityException.class, 791 () -> builder.registerParametersParser(testParser2)); 792 } 793 794 @Test test_registerDifferentParametersParsersWithDifferentSerializationType_works()795 public void test_registerDifferentParametersParsersWithDifferentSerializationType_works() 796 throws Exception { 797 ParametersParser<TestSerializationA> testParser1 = 798 ParametersParser.create( 799 SerializationRegistryTest::parseAToParameters1, A_1, TestSerializationA.class); 800 ParametersParser<TestSerializationB> testParser2 = 801 ParametersParser.create( 802 SerializationRegistryTest::parseBToParameters1, B_1, TestSerializationB.class); 803 SerializationRegistry unused = new SerializationRegistry.Builder() 804 .registerParametersParser(testParser1) 805 .registerParametersParser(testParser2) 806 .build(); 807 } 808 809 @Test test_registerDifferentParametersParsersWithDifferentKeyType_works()810 public void test_registerDifferentParametersParsersWithDifferentKeyType_works() throws Exception { 811 ParametersParser<TestSerializationA> testParser1 = 812 ParametersParser.create( 813 SerializationRegistryTest::parseAToParameters1, A_1, TestSerializationA.class); 814 ParametersParser<TestSerializationA> testParser2 = 815 ParametersParser.create( 816 SerializationRegistryTest::parseAToParameters2, A_2, TestSerializationA.class); 817 SerializationRegistry unused = new SerializationRegistry.Builder() 818 .registerParametersParser(testParser1) 819 .registerParametersParser(testParser2) 820 .build(); 821 } 822 823 @Test test_registerAllParametersParsers_checkDispatch()824 public void test_registerAllParametersParsers_checkDispatch() throws Exception { 825 SerializationRegistry registry = 826 new SerializationRegistry.Builder() 827 .registerParametersParser( 828 ParametersParser.create( 829 SerializationRegistryTest::parseAToParameters1, A_1, TestSerializationA.class)) 830 .registerParametersParser( 831 ParametersParser.create( 832 SerializationRegistryTest::parseBToParameters1, B_1, TestSerializationB.class)) 833 .registerParametersParser( 834 ParametersParser.create( 835 SerializationRegistryTest::parseAToParameters2, A_2, TestSerializationA.class)) 836 .registerParametersParser( 837 ParametersParser.create( 838 SerializationRegistryTest::parseBToParameters2, B_2, TestSerializationB.class)) 839 .build(); 840 assertThat(registry.parseParameters(new TestSerializationA(A_1))) 841 .isInstanceOf(TestParameters1.class); 842 assertThat(registry.parseParameters(new TestSerializationA(A_2))) 843 .isInstanceOf(TestParameters2.class); 844 assertThat(registry.parseParameters(new TestSerializationB(B_1))) 845 .isInstanceOf(TestParameters1.class); 846 assertThat(registry.parseParameters(new TestSerializationB(B_2))) 847 .isInstanceOf(TestParameters2.class); 848 } 849 850 @Test test_copyWorksForParametersParsers()851 public void test_copyWorksForParametersParsers() throws Exception { 852 SerializationRegistry registry = 853 new SerializationRegistry.Builder() 854 .registerParametersParser( 855 ParametersParser.create( 856 SerializationRegistryTest::parseAToParameters1, A_1, TestSerializationA.class)) 857 .build(); 858 SerializationRegistry registry2 = new SerializationRegistry.Builder(registry).build(); 859 assertThat(registry2.parseParameters(new TestSerializationA(A_1))).isNotNull(); 860 } 861 862 @Test test_copyDoesNotChangeOldVersion_formatParser()863 public void test_copyDoesNotChangeOldVersion_formatParser() throws Exception { 864 SerializationRegistry registry1 = new SerializationRegistry.Builder().build(); 865 SerializationRegistry.Builder builder = new SerializationRegistry.Builder(registry1); 866 SerializationRegistry registry2 = builder.build(); 867 868 SerializationRegistry unused = builder 869 .registerParametersParser( 870 ParametersParser.create( 871 SerializationRegistryTest::parseAToParameters1, A_1, TestSerializationA.class)) 872 .build(); 873 assertThrows( 874 GeneralSecurityException.class, 875 () -> registry1.parseParameters(new TestSerializationA(A_1))); 876 assertThrows( 877 GeneralSecurityException.class, 878 () -> registry2.parseParameters(new TestSerializationA(A_1))); 879 } 880 } 881