package link.roadio.riff.userstate import link.roadio.riff.userstate.model.CheckpointModel import link.roadio.riff.userstate.model.FileHeaderModel import link.roadio.riff.userstate.model.MediaKeyModel import link.roadio.riff.userstate.model.ProfileStateModel import link.roadio.riff.userstate.model.QueueItemModel import link.roadio.riff.userstate.model.QueueRevisionModel import link.roadio.riff.userstate.model.QueueStateModel import link.roadio.riff.userstate.model.UserStateCodec import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Assert.fail import org.junit.Test import java.nio.ByteBuffer class UserStateMappedReadTest { @Test fun maximumQueuePassesWireAndSemanticValidationWithoutMaterializingVectors() { for (count in listOf(125_000, 125_001, 200_000, 200_001)) { val items = BoundedReadList(count) { QueueItemModel(it.toLong(), MediaKeyModel(it.toLong(), 0, true)) } val revision = QueueRevisionModel(42, items) val profile = ProfileStateModel( header = FileHeaderModel(formatVersion = 1, profileSlot = 1), dynamicQueue = QueueStateModel( definition = revision, execution = revision, checkpoint = CheckpointModel(revisionId = 42, occurrenceId = count.toLong() - 1), ), ) val bytes = UserStateCodec.encode(profile) val buffer = ByteBuffer.wrap(bytes).asReadOnlyBuffer() val start = System.nanoTime() val actual = UserStateCodec.readProfileState(buffer) UserStateValidation.profile(actual) println("PROFILE_READ count=$count bytes=${bytes.size} millis=${(System.nanoTime() - start) / 1_000_000}") assertTrue(actual.dynamicQueue.execution.items is BoundedReadList<*>) assertEquals( items.last(), actual.dynamicQueue.execution.items .last(), ) assertEquals(0, buffer.position()) } } @Test fun decodedValuesOwnTheirBytesAndReadViewsRejectMutableStorage() { val bytes = UserStateCodec.encode(ProfileStateModel()) val decoded = UserStateCodec.decodeProfileState(bytes) bytes.fill(0) assertEquals(emptyList(), decoded.dynamicQueue.definition.items) try { UserStateCodec.readProfileState(ByteBuffer.wrap(bytes)) fail("Mutable backing") } catch (_: IllegalArgumentException) { } } @Test fun readCacheIsBoundedAndChecksNegativeAndEndIndices() { var reads = 0 val values = BoundedReadList(1000) { reads++ it } assertEquals(0, values[0]) assertEquals(0, values[0]) assertEquals(1, reads) (1..999).forEach { values[it] } assertEquals(0, values[0]) assertEquals(1001, reads) for (index in listOf(-1, 1000)) { try { values[index] fail("Outside vector") } catch (_: IndexOutOfBoundsException) { } } } }