org.stem.domain.topology.TopologyCoderTest.java Source code

Java tutorial

Introduction

Here is the source code for org.stem.domain.topology.TopologyCoderTest.java

Source

/*
 * 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;
    }
}