/******************************************************************************* * Copyright (c) 2016 École Polytechnique de Montréal * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.eclipse.tracecompass.tmf.ctf.core.tests.event; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.nio.ByteBuffer; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.tracecompass.ctf.core.CTFException; import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer; import org.eclipse.tracecompass.ctf.core.event.types.Encoding; import org.eclipse.tracecompass.ctf.core.event.types.EnumDeclaration; import org.eclipse.tracecompass.ctf.core.event.types.IDefinition; import org.eclipse.tracecompass.ctf.core.event.types.IntegerDeclaration; import org.eclipse.tracecompass.ctf.core.event.types.StringDeclaration; import org.eclipse.tracecompass.ctf.core.event.types.StructDeclaration; import org.eclipse.tracecompass.ctf.core.event.types.StructDefinition; import org.eclipse.tracecompass.ctf.core.event.types.VariantDeclaration; import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEventField; import org.junit.Before; import org.junit.Test; /** * Add some unit tests specific for variant fields * * @author Geneviève Bastien */ public class CtfTmfEventFieldVariantTest { /* * Same string content, but not the same object, as the any variant selected * string */ private static final @NonNull String ENUM_ANY = new String(CtfTmfEventField.FIELD_VARIANT_SELECTED); private static final @NonNull String ENUM_NAME2 = "choice2"; private static final @NonNull String ENUM_NAME3 = "choice3"; private static final int ENUM_VAL1 = 0; private static final int ENUM_VAL2 = 1; private static final int ENUM_VAL3 = 2; private static final @NonNull String ENUM = "enum"; private static final @NonNull String FIELD1 = "Fiedl1"; private static final @NonNull String FIELD2 = "Field2"; private static final @NonNull String FIELD3 = "Field3"; private static final @NonNull String VARIANT = "variant"; private static final @NonNull String ROOT = "root"; private StructDeclaration fDeclaration; /** * Create the declaration for the variant field */ @Before public void createDeclaration() { /** * Create a variant field based on the following metadata * * <pre> * enum : integer { size = 8; } { * "_Any" = 0, * "_var2" = 1, * "_var3" = 2, * } _tag; * variant <_tag> { * struct { * integer { size = 8; } _field1; * integer { size = 8; } _field2; * } _Any; * struct { * integer { size = 8; } _field1; * string _field2; * integer { size = 8; } _field3; * } _var2; * integer { size = 8; } _var3; * } _mainVariant; * </pre> */ StructDeclaration sDec = new StructDeclaration(0); /* Create enum field */ EnumDeclaration enumDec = new EnumDeclaration(IntegerDeclaration.INT_8_DECL); enumDec.add(ENUM_VAL1, ENUM_VAL1, ENUM_ANY); enumDec.add(ENUM_VAL2, ENUM_VAL2, ENUM_NAME2); enumDec.add(ENUM_VAL3, ENUM_VAL3, ENUM_NAME3); sDec.addField(ENUM, enumDec); /* Create structure for first choice */ StructDeclaration choice1Dec = new StructDeclaration(0); choice1Dec.addField(FIELD1, IntegerDeclaration.INT_8_DECL); choice1Dec.addField(FIELD2, IntegerDeclaration.INT_8_DECL); /* Create structure for second choice */ StructDeclaration choice2Dec = new StructDeclaration(0); choice2Dec.addField(FIELD1, IntegerDeclaration.INT_8_DECL); choice2Dec.addField(FIELD2, StringDeclaration.getStringDeclaration(Encoding.UTF8)); choice2Dec.addField(FIELD3, IntegerDeclaration.INT_8_DECL); /* Create variant field */ VariantDeclaration varDec = new VariantDeclaration(); varDec.setTag(ENUM); varDec.addField(ENUM_ANY, choice1Dec); varDec.addField(ENUM_NAME2, choice2Dec); varDec.addField(ENUM_NAME3, IntegerDeclaration.INT_8_DECL); sDec.addField(VARIANT, varDec); fDeclaration = sDec; } /** * Test variant field getters * * @throws CTFException * exception occurring when reading a field */ @Test public void testVariantGetField() throws CTFException { StructDeclaration decl = fDeclaration; StructDefinition sDef = null; /* Obtain a field with the first variant choice */ ByteBuffer bb = ByteBuffer.allocateDirect(1024); bb.put((byte) ENUM_VAL1); bb.put((byte) 3); bb.put((byte) 4); sDef = decl.createDefinition(null, ROOT, new BitBuffer(bb)); IDefinition definition = sDef.getDefinition(VARIANT); CtfTmfEventField result = CtfTmfEventField.parseField(definition, VARIANT); /** Assert it returns a value only for the correct enum */ assertNotNull(result.getField(ENUM_ANY)); assertNull(result.getField(ENUM_NAME2)); assertNull(result.getField(ENUM_NAME3)); /** * Assert the subfields can be reached through the current enum and have * the right value */ assertNotNull(result.getField(ENUM_ANY, FIELD1)); assertEquals(3L, result.getField(ENUM_ANY, FIELD1).getValue()); assertNotNull(result.getField(ENUM_ANY, FIELD2)); assertEquals(4L, result.getField(ENUM_ANY, FIELD2).getValue()); assertNull(result.getField(ENUM_ANY, FIELD3)); /** * Assert the subfields can be reached through the * {@link CtfTmfEventField#FIELD_VARIANT_SELECTED} constant and have the * right value */ assertNotNull(result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD1)); assertEquals(3L, result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD1).getValue()); assertNotNull(result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD2)); assertEquals(4L, result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD2).getValue()); assertNull(result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD3)); /* Obtain a field with the second variant choice */ String testString = "My Test string"; bb = ByteBuffer.allocateDirect(1024); bb.put((byte) ENUM_VAL2); bb.put((byte) 3); bb.put(testString.getBytes()); bb.put((byte) 0); bb.put((byte) 4); sDef = decl.createDefinition(null, ROOT, new BitBuffer(bb)); definition = sDef.getDefinition(VARIANT); result = CtfTmfEventField.parseField(definition, VARIANT); /** Assert it returns a value only for the correct enum */ assertNull(result.getField(ENUM_ANY)); assertNotNull(result.getField(ENUM_NAME2)); assertNull(result.getField(ENUM_NAME3)); /** * Assert the subfields can be reached through the current enum and have * the right value */ assertNotNull(result.getField(ENUM_NAME2, FIELD1)); assertEquals(3L, result.getField(ENUM_NAME2, FIELD1).getValue()); assertNotNull(result.getField(ENUM_NAME2, FIELD2)); assertEquals(testString, result.getField(ENUM_NAME2, FIELD2).getValue()); assertNotNull(result.getField(ENUM_NAME2, FIELD3)); assertEquals(4L, result.getField(ENUM_NAME2, FIELD3).getValue()); /** * Assert the subfields can be reached through the * {@link CtfTmfEventField#FIELD_VARIANT_SELECTED} constant and have the * right value */ assertNotNull(result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD1)); assertEquals(3L, result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD1).getValue()); assertNotNull(result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD2)); assertEquals(testString, result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD2).getValue()); assertNotNull(result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD3)); assertEquals(4L, result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD3).getValue()); /** * Assert that trying to reach a field of this choice with the same name * as the current selection field will not return the field */ assertNull(result.getField(ENUM_ANY, FIELD1)); /* Obtain a field with the third variant choice */ bb = ByteBuffer.allocateDirect(1024); bb.put((byte) ENUM_VAL3); bb.put((byte) 3); sDef = decl.createDefinition(null, ROOT, new BitBuffer(bb)); definition = sDef.getDefinition(VARIANT); result = CtfTmfEventField.parseField(definition, VARIANT); /** Assert it returns a value only for the correct enum */ assertNull(result.getField(ENUM_ANY)); assertNull(result.getField(ENUM_NAME2)); assertNotNull(result.getField(ENUM_NAME3)); /** * Assert the subfields return null */ assertNull(result.getField(ENUM_NAME3, FIELD1)); assertNull(result.getField(ENUM_NAME3, FIELD2)); assertEquals(3L, result.getField(ENUM_NAME3).getValue()); /** * Assert the subfields can be reached through the * {@link CtfTmfEventField#FIELD_VARIANT_SELECTED} constant and have the * right value */ assertNotNull(result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED)); assertEquals(3L, result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED).getValue()); assertNull(result.getField(CtfTmfEventField.FIELD_VARIANT_SELECTED, FIELD1)); } }