Add more unit tests for Pi* classes

Change-Id: Idaee25730bd39f10f2f3e66f9e3d2a29061d5b30
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupIdTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupIdTest.java
new file mode 100644
index 0000000..4c18f18
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupIdTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.onosproject.net.pi.runtime;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Unit tests for PiActionGroupId class.
+ */
+public class PiActionGroupIdTest {
+
+    final PiActionGroupId piActionGroupId1 = PiActionGroupId.of(10);
+    final PiActionGroupId sameAsPiActionGroupId1 = PiActionGroupId.of(10);
+    final PiActionGroupId piActionGroupId2 = PiActionGroupId.of(20);
+
+    /**
+     * Checks that the PiActionGroupId class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+
+        assertThatClassIsImmutable(PiActionGroupId.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+
+        new EqualsTester()
+                .addEqualityGroup(piActionGroupId1, sameAsPiActionGroupId1)
+                .addEqualityGroup(piActionGroupId2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the methods of PiActionGroupId.
+     */
+    @Test
+    public void testMethods() {
+
+        assertThat(piActionGroupId1, is(notNullValue()));
+        assertThat(piActionGroupId1.type(), is(PiTableAction.Type.ACTION_GROUP_ID));
+        assertThat(piActionGroupId1.id(), is(10));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupMemberIdTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupMemberIdTest.java
new file mode 100644
index 0000000..008a74e
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupMemberIdTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.onosproject.net.pi.runtime;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Unit tests for PiActionGroupMemberId class.
+ */
+public class PiActionGroupMemberIdTest {
+
+    final PiActionGroupMemberId piActionGroupMemberId1 = PiActionGroupMemberId.of(10);
+    final PiActionGroupMemberId sameAsPiActionGroupMemberId1 = PiActionGroupMemberId.of(10);
+    final PiActionGroupMemberId piActionGroupMemberId2 = PiActionGroupMemberId.of(20);
+
+    /**
+     * Checks that the PiActionGroupMemberId class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+
+        assertThatClassIsImmutable(PiActionGroupMemberId.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+
+        new EqualsTester()
+                .addEqualityGroup(piActionGroupMemberId1, sameAsPiActionGroupMemberId1)
+                .addEqualityGroup(piActionGroupMemberId2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the methods of PiActionGroupMemberId.
+     */
+    @Test
+    public void testMethods() {
+
+        assertThat(piActionGroupMemberId1, is(notNullValue()));
+        assertThat(piActionGroupMemberId1.type(), is(PiTableAction.Type.GROUP_MEMBER_ID));
+        assertThat(piActionGroupMemberId1.id(), is(10));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupMemberTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupMemberTest.java
new file mode 100644
index 0000000..c9e53ee
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupMemberTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.onosproject.net.pi.runtime;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DST_ADDR;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.MOD_NW_DST;
+
+/**
+ * Unit tests for PiActionGroupMember class.
+ */
+public class PiActionGroupMemberTest {
+
+    final PiActionGroupMemberId piActionGroupMemberId = PiActionGroupMemberId.of(10);
+    final PiAction piAction = PiAction.builder().withId(PiActionId.of(MOD_NW_DST))
+            .withParameter(new PiActionParam(PiActionParamId.of(DST_ADDR), copyFrom(0x0a010101)))
+            .build();
+
+    final PiActionGroupMember piActionGroupMember1 = PiActionGroupMember.builder()
+            .withId(piActionGroupMemberId)
+            .withAction(piAction)
+            .withWeight(10)
+            .build();
+    final PiActionGroupMember sameAsPiActionGroupMember1 = PiActionGroupMember.builder()
+            .withId(piActionGroupMemberId)
+            .withAction(piAction)
+            .withWeight(10)
+            .build();
+    final PiActionGroupMember piActionGroupMember2 = PiActionGroupMember.builder()
+            .withId(piActionGroupMemberId)
+            .withAction(piAction)
+            .withWeight(20)
+            .build();
+
+    /**
+     * Checks that the PiActionGroupMember class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+
+        assertThatClassIsImmutable(PiActionGroupMember.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+
+        new EqualsTester()
+                .addEqualityGroup(piActionGroupMember1, sameAsPiActionGroupMember1)
+                .addEqualityGroup(piActionGroupMember2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the methods of PiActionGroupMember.
+     */
+    @Test
+    public void testMethods() {
+
+        assertThat(piActionGroupMember1, is(notNullValue()));
+        assertThat(piActionGroupMember1.weight(), is(10));
+        assertThat(piActionGroupMember1.id(), is(piActionGroupMemberId));
+        assertThat(piActionGroupMember1.action(), is(piAction));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupTest.java
new file mode 100644
index 0000000..e9b736b
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.onosproject.net.pi.runtime;
+
+import com.google.common.collect.Lists;
+import com.google.common.testing.EqualsTester;
+import org.apache.commons.collections.CollectionUtils;
+import org.junit.Test;
+
+import java.util.Collection;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DST_ADDR;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.MOD_NW_DST;
+
+/**
+ * Unit tests for PiActionGroup class.
+ */
+public class PiActionGroupTest {
+
+    final PiActionGroupMemberId piActionGroupMemberId = PiActionGroupMemberId.of(10);
+    final PiAction piAction = PiAction.builder().withId(PiActionId.of(MOD_NW_DST))
+            .withParameter(new PiActionParam(PiActionParamId.of(DST_ADDR), copyFrom(0x0a010101)))
+            .build();
+
+    final PiActionGroupMember piActionGroupMember = PiActionGroupMember.builder()
+            .withId(piActionGroupMemberId)
+            .withAction(piAction)
+            .withWeight(10)
+            .build();
+    PiActionGroupId piActionGroupId = PiActionGroupId.of(10);
+    PiActionGroup piActionGroup1 = PiActionGroup.builder()
+            .addMember(piActionGroupMember)
+            .withId(piActionGroupId)
+            .withType(PiActionGroup.Type.SELECT)
+            .build();
+
+    PiActionGroup sameAsPiActionGroup1 = PiActionGroup.builder()
+            .addMember(piActionGroupMember)
+            .withId(piActionGroupId)
+            .withType(PiActionGroup.Type.SELECT)
+            .build();
+
+    PiActionGroupId piActionGroupId2 = PiActionGroupId.of(20);
+    PiActionGroup piActionGroup2 = PiActionGroup.builder()
+            .addMember(piActionGroupMember)
+            .withId(piActionGroupId2)
+            .withType(PiActionGroup.Type.SELECT)
+            .build();
+
+    /**
+     * Checks that the PiActionGroup class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+
+        assertThatClassIsImmutable(PiActionGroup.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+
+        new EqualsTester()
+                .addEqualityGroup(piActionGroup1, sameAsPiActionGroup1)
+                .addEqualityGroup(piActionGroup2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the methods of PiActionGroup.
+     */
+    @Test
+    public void testMethods() {
+
+        Collection<PiActionGroupMember> piActionGroupMembers = Lists.newArrayList();
+
+        piActionGroupMembers.add(piActionGroupMember);
+        assertThat(piActionGroup1, is(notNullValue()));
+        assertThat(piActionGroup1.id(), is(piActionGroupId));
+        assertThat(piActionGroup1.type(), is(PiActionGroup.Type.SELECT));
+        assertThat("Incorrect members value",
+                   CollectionUtils.isEqualCollection(piActionGroup1.members(), piActionGroupMembers));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiConstantsTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiConstantsTest.java
index 4212acc..b2bda37 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiConstantsTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiConstantsTest.java
@@ -35,4 +35,7 @@
     public static final String SRC_ADDR = "srcAddr";
     public static final String VID = "vid";
     public static final String PORT = "port";
+
+    public static final String EGRESS_PORT = "egress_port";
+    public static final String INGRESS_PORT = "ingress_port";
 }
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java
new file mode 100644
index 0000000..ea866fa
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.onosproject.net.pi.runtime;
+
+import com.google.common.collect.Lists;
+import com.google.common.testing.EqualsTester;
+import org.apache.commons.collections.CollectionUtils;
+import org.junit.Test;
+import org.onlab.util.ImmutableByteSequence;
+
+import java.util.Collection;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DST_ADDR;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.IPV4_HEADER_NAME;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.SRC_ADDR;
+
+/**
+ * Unit tests for PiMatchKey class.
+ */
+public class PiMatchKeyTest {
+
+    final ImmutableByteSequence value1 = copyFrom(0x0a010101);
+    final ImmutableByteSequence value2 = copyFrom(0x0a010102);
+    int prefixLength = 24;
+    final PiHeaderFieldId piHeaderField1 = PiHeaderFieldId.of(IPV4_HEADER_NAME, SRC_ADDR);
+    final PiHeaderFieldId piHeaderField2 = PiHeaderFieldId.of(IPV4_HEADER_NAME, DST_ADDR);
+    PiLpmFieldMatch piLpmFieldMatch1 = new PiLpmFieldMatch(piHeaderField1, value1, prefixLength);
+    PiLpmFieldMatch piLpmFieldMatch2 = new PiLpmFieldMatch(piHeaderField2, value2, prefixLength);
+
+    final PiMatchKey piMatchKey1 = PiMatchKey.builder()
+            .addFieldMatch(piLpmFieldMatch1)
+            .build();
+    final PiMatchKey sameAsPiMatchKey1 = PiMatchKey.builder()
+            .addFieldMatch(piLpmFieldMatch1)
+            .build();
+    final PiMatchKey piMatchKey2 = PiMatchKey.builder()
+            .addFieldMatch(piLpmFieldMatch2)
+            .build();
+
+    /**
+     * Checks that the PiMatchKey class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+
+        assertThatClassIsImmutable(PiMatchKey.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+
+        new EqualsTester()
+                .addEqualityGroup(piMatchKey1, sameAsPiMatchKey1)
+                .addEqualityGroup(piMatchKey2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the methods of PiMatchKey.
+     */
+    @Test
+    public void testMethods() {
+
+        Collection<PiFieldMatch> piFieldMatches = Lists.newArrayList();
+        piFieldMatches.add(piLpmFieldMatch1);
+        piFieldMatches.add(piLpmFieldMatch2);
+
+        final PiMatchKey piMatchKey = PiMatchKey.builder()
+                .addFieldMatches(piFieldMatches)
+                .build();
+
+        assertThat(piMatchKey, is(notNullValue()));
+        assertThat("Incorrect members value",
+                   CollectionUtils.isEqualCollection(piMatchKey.fieldMatches(), piFieldMatches));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataIdTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataIdTest.java
new file mode 100644
index 0000000..a2ee50f
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataIdTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.onosproject.net.pi.runtime;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.EGRESS_PORT;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.INGRESS_PORT;
+
+/**
+ * Unit tests for PiPacketMetadataId class.
+ */
+public class PiPacketMetadataIdTest {
+
+    final PiPacketMetadataId piPacketMetadataId1 = PiPacketMetadataId.of(EGRESS_PORT);
+    final PiPacketMetadataId sameAsPiPacketMetadataId1 = PiPacketMetadataId.of(EGRESS_PORT);
+    final PiPacketMetadataId piPacketMetadataId2 = PiPacketMetadataId.of(INGRESS_PORT);
+
+    /**
+     * Checks that the PiPacketMetadataId class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+
+        assertThatClassIsImmutable(PiPacketMetadataId.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+
+        new EqualsTester()
+                .addEqualityGroup(piPacketMetadataId1, sameAsPiPacketMetadataId1)
+                .addEqualityGroup(piPacketMetadataId2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the methods of PiPacketMetadataId.
+     */
+    @Test
+    public void testMethods() {
+
+        assertThat(piPacketMetadataId1, is(notNullValue()));
+        assertThat(piPacketMetadataId1.name(), is(EGRESS_PORT));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataTest.java
new file mode 100644
index 0000000..8ba4d4e
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.onosproject.net.pi.runtime;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.EGRESS_PORT;
+
+/**
+ * Unit tests for PiPacketMetadata class.
+ */
+public class PiPacketMetadataTest {
+
+    final PiPacketMetadataId piPacketMetadataId = PiPacketMetadataId.of(EGRESS_PORT);
+
+    final PiPacketMetadata piPacketMetadata1 = PiPacketMetadata.builder()
+            .withId(piPacketMetadataId)
+            .withValue(copyFrom(0x10))
+            .build();
+    final PiPacketMetadata sameAsPiPacketMetadata1 = PiPacketMetadata.builder()
+            .withId(piPacketMetadataId)
+            .withValue(copyFrom(0x10))
+            .build();
+    final PiPacketMetadata piPacketMetadata2 = PiPacketMetadata.builder()
+            .withId(piPacketMetadataId)
+            .withValue(copyFrom(0x20))
+            .build();
+
+    /**
+     * Checks that the PiPacketMetadata class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+
+        assertThatClassIsImmutable(PiPacketMetadata.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+
+        new EqualsTester()
+                .addEqualityGroup(piPacketMetadata1, sameAsPiPacketMetadata1)
+                .addEqualityGroup(piPacketMetadata2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the methods of PiPacketMetadata.
+     */
+    @Test
+    public void testMethods() {
+
+        assertThat(piPacketMetadata1, is(notNullValue()));
+        assertThat(piPacketMetadata1.id(), is(PiPacketMetadataId.of(EGRESS_PORT)));
+        assertThat(piPacketMetadata1.value(), is(copyFrom(0x10)));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketOperationTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketOperationTest.java
new file mode 100644
index 0000000..619099f
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketOperationTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.onosproject.net.pi.runtime;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.testing.EqualsTester;
+import org.apache.commons.collections.CollectionUtils;
+import org.junit.Test;
+import org.onlab.util.ImmutableByteSequence;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.EGRESS_PORT;
+import static org.onosproject.net.pi.runtime.PiPacketOperation.Type.PACKET_OUT;
+
+/**
+ * Unit tests for PiPacketOperation class.
+ */
+public class PiPacketOperationTest {
+
+    final PiPacketOperation piPacketOperation1 = PiPacketOperation.builder()
+            .withData(ImmutableByteSequence.ofOnes(512))
+            .withType(PACKET_OUT)
+            .withMetadata(PiPacketMetadata.builder()
+                                  .withId(PiPacketMetadataId.of(EGRESS_PORT))
+                                  .withValue(copyFrom((short) 255))
+                                  .build())
+            .build();
+
+    final PiPacketOperation sameAsPiPacketOperation1 = PiPacketOperation.builder()
+            .withData(ImmutableByteSequence.ofOnes(512))
+            .withType(PACKET_OUT)
+            .withMetadata(PiPacketMetadata.builder()
+                                  .withId(PiPacketMetadataId.of(EGRESS_PORT))
+                                  .withValue(copyFrom((short) 255))
+                                  .build())
+            .build();
+
+    final PiPacketOperation piPacketOperation2 = PiPacketOperation.builder()
+            .withData(ImmutableByteSequence.ofOnes(512))
+            .withType(PACKET_OUT)
+            .withMetadata(PiPacketMetadata.builder()
+                                  .withId(PiPacketMetadataId.of(EGRESS_PORT))
+                                  .withValue(copyFrom((short) 200))
+                                  .build())
+            .build();
+
+    /**
+     * Checks that the PiPacketOperation class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+
+        assertThatClassIsImmutable(PiPacketOperation.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+
+        new EqualsTester()
+                .addEqualityGroup(piPacketOperation1, sameAsPiPacketOperation1)
+                .addEqualityGroup(piPacketOperation2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the methods of PiPacketOperation.
+     */
+    @Test
+    public void testMethods() {
+
+        final PiPacketOperation piPacketOperation = PiPacketOperation.builder()
+                .withData(ImmutableByteSequence.ofOnes(512))
+                .withType(PACKET_OUT)
+                .withMetadata(PiPacketMetadata.builder()
+                                      .withId(PiPacketMetadataId.of(EGRESS_PORT))
+                                      .withValue(copyFrom((short) 10))
+                                      .build())
+                .build();
+
+        assertThat(piPacketOperation, is(notNullValue()));
+        assertThat(piPacketOperation.type(), is(PACKET_OUT));
+        assertThat(piPacketOperation.data(), is(ImmutableByteSequence.ofOnes(512)));
+        assertThat("Incorrect metadatas value",
+                   CollectionUtils.isEqualCollection(piPacketOperation.metadatas(),
+                                                     ImmutableList.of(PiPacketMetadata.builder()
+                                                                              .withId(PiPacketMetadataId
+                                                                                              .of(EGRESS_PORT))
+                                                                              .withValue(copyFrom((short) 10))
+                                                                              .build())));
+    }
+}