Java tutorial
/* * Copyright 2014 Alexey Plotnik * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.stem.domain.topology; import com.fasterxml.jackson.databind.type.ArrayType; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.junit.Assert; import org.junit.Test; import org.stem.RestUtils; import org.stem.api.REST; import org.stem.coordination.Codecs; import org.stem.utils.BBUtils; import org.stem.utils.JsonUtils; import org.stem.utils.Mappings; import org.stem.utils.TopologyUtils; import java.net.InetSocketAddress; import java.util.*; import static org.stem.utils.Mappings.Encoder.prepareFormat; import static org.stem.utils.Mappings.NumberFormat.*; public class TopologyCoderTest { @Test public void jsonPackAndUnpackEquality() throws Exception { DataMapping mapping = prepareMapping(100000, 1); REST.Mapping original = RestUtils.packMapping(mapping); String encoded = JsonUtils.encode(original); REST.Mapping decoded = JsonUtils.decode(encoded, REST.Mapping.class); // Assert Set<Integer> diskObjIds = new HashSet<>(); for (Long bucket : decoded.getBuckets()) { REST.ReplicaSet originalReplicas = original.getReplicaSet(bucket); REST.ReplicaSet decodedReplicas = decoded.getReplicaSet(bucket); for (REST.Disk disk : decodedReplicas.getReplicas()) { int originalId = System.identityHashCode(disk); diskObjIds.add(originalId); } validateReplicasEquality(originalReplicas, decodedReplicas); } System.out.println("Length of encoded json: " + encoded.length() + " symbols"); // Validate we have only 3 unique disk objects Assert.assertEquals(3, diskObjIds.size()); } @Test public void byteToJson() throws Exception { Byte[] original = new Byte[] { 1, 2, 3 }; String encoded = JsonUtils.encode(original); ArrayType type = JsonUtils.getTypeFactory().constructArrayType(Byte.class); Byte[] decoded = (Byte[]) JsonUtils.decode(encoded, type); Assert.assertArrayEquals(original, decoded); } @Test public void fitFormatFromBits() throws Exception { for (int i = 0; i <= 16; i++) Assert.assertEquals("bits=" + i, SHORT, minimalFormat(i)); for (int i = 17; i <= 32; i++) Assert.assertEquals("bits=" + i, INT, minimalFormat(i)); for (int i = 33; i <= 64; i++) Assert.assertEquals("bits=" + i, LONG, minimalFormat(i)); } @Test public void prepareFormatFromNumber() throws Exception { Assert.assertEquals(SHORT, prepareFormat(1l)); Assert.assertEquals(SHORT, prepareFormat(65536l - 1)); Assert.assertEquals(INT, prepareFormat(65536l)); Assert.assertEquals(INT, prepareFormat(65536l + 1)); Assert.assertEquals(INT, prepareFormat(4l * 1024 * 1024 * 1024 - 1)); Assert.assertEquals(LONG, prepareFormat(4l * 1024 * 1024 * 1024 + 1)); } @Test public void codeUuid() throws Exception { ByteBuf buf = Unpooled.buffer(); UUID val = UUID.randomUUID(); BBUtils.writeUuid(val, buf); Assert.assertEquals(buf.readableBytes(), 16); Assert.assertEquals(val, BBUtils.readUuid(buf)); } @Test public void binaryCoderDecoderRfOne() throws Exception { REST.Mapping original = RestUtils.packMapping(prepareMapping(100000, 1)); Mappings.Encoder encoder = new Mappings.Encoder(original); byte[] encoded = encoder.encode(); REST.Mapping decoded = new Mappings.Decoder(encoded).decode(); assertMappingsEquality(original, decoded); } @Test public void binaryCoderDecoderRfThree() throws Exception { REST.Mapping original = RestUtils.packMapping(prepareMapping(100000, 3)); Mappings.Encoder encoder = new Mappings.Encoder(original); byte[] encoded = encoder.encode(); REST.Mapping decoded = new Mappings.Decoder(encoded).decode(); assertMappingsEquality(original, decoded); } @Test public void binaryCoderDecoderLarge() throws Exception { REST.Mapping original = RestUtils.packMapping(prepareMapping(1000000, 3)); Mappings.Encoder encoder = new Mappings.Encoder(original); byte[] encoded = encoder.encode(); REST.Mapping decoded = new Mappings.Decoder(encoded).decode(); assertMappingsEquality(original, decoded); } @Test public void binaryCoderDecoderEmpty() throws Exception { REST.Mapping original = new REST.Mapping(); Mappings.Encoder encoder = new Mappings.Encoder(original); byte[] encoded = encoder.encode(); Assert.assertEquals(0, encoded.length); REST.Mapping decoded = new Mappings.Decoder(encoded).decode(); Assert.assertTrue(decoded.isEmpty()); assertMappingsEquality(original, decoded); } @Test public void packUnpack() throws Exception { Topology topology = createTopology(); REST.Mapping mapping = RestUtils.packMapping(prepareMapping(topology, 100000, 3)); REST.TopologySnapshot original = new REST.TopologySnapshot(RestUtils.packTopology(topology), mapping); byte[] snapshotEncoded = original.encode(); REST.TopologySnapshot decoded = Codecs.TOPOLOGY_SNAPSHOT.decode(snapshotEncoded, REST.TopologySnapshot.class); assertMappingsEquality(original.getMapping(), decoded.getMapping()); // TODO: compare topologies } private void assertMappingsEquality(REST.Mapping m1, REST.Mapping m2) { Assert.assertEquals(m1.size(), m2.size()); for (Long b : m1.getBuckets()) Assert.assertEquals(m2.getReplicaSet(b), m1.getReplicaSet(b)); for (Long b : m2.getBuckets()) Assert.assertEquals(m1.getReplicaSet(b), m2.getReplicaSet(b)); } private void validateReplicasEquality(REST.ReplicaSet original, REST.ReplicaSet decoded) { Assert.assertEquals(original.getReplicas(), decoded.getReplicas()); } private DataMapping prepareMapping(int buckets, int rf) { return prepareMapping(createTopology(), buckets, rf); } private DataMapping prepareMapping(Topology topology, int buckets, int rf) { Partitioner partitioner = Partitioner.Type.CRUSH.builder.build(); List<Long> bucketsArray = TopologyUtils.prepareBucketsArray(buckets); Map<Long, Topology.ReplicaSet> map = ((CrushAdapter) partitioner.algorithm()).computeMapping(bucketsArray, rf, topology); return new DataMapping(map); } private Topology createTopology() { Topology topology = Topology.Factory.create(); Topology.Datacenter dc = new Topology.Datacenter("DC1"); topology.addDatacenter(dc); Topology.Rack rack1 = new Topology.Rack("RACK1"); Topology.Rack rack2 = new Topology.Rack("RACK2"); Topology.Rack rack3 = new Topology.Rack("RACK3"); dc.addRack(rack1); dc.addRack(rack2); dc.addRack(rack3); Topology.StorageNode node1 = createStorageNode("127.0.0.1", 9997); rack1.addStorageNode(node1); Topology.StorageNode node2 = createStorageNode("127.0.0.2", 9997); rack2.addStorageNode(node2); Topology.StorageNode node3 = createStorageNode("127.0.0.3", 9997); rack3.addStorageNode(node3); Topology.Disk d1 = createDisk("/dev/sda1", 0, 4); node1.addDisk(d1); Topology.Disk d2 = createDisk("/dev/sda2", 0, 4); node2.addDisk(d2); Topology.Disk d3 = createDisk("/dev/sda3", 0, 4); node3.addDisk(d3); return topology; } private Topology.StorageNode createStorageNode(String host, int port) { return new Topology.StorageNode(new InetSocketAddress(host, port)); } private Topology.Disk createDisk(String path, int used, int total) { Topology.Disk disk = new Topology.Disk(); disk.setPath(path); disk.setState(Topology.DiskState.RUNNING); disk.setUsedBytes(used); disk.setTotalBytes(total * 1024 * 1024 * 1024); return disk; } }