Adds integration test that measures VPP API coverage 71/5971/3
authorMarek Gradzki <[email protected]>
Mon, 6 Mar 2017 09:42:47 +0000 (10:42 +0100)
committerMarek Gradzki <[email protected]>
Wed, 10 May 2017 12:42:56 +0000 (12:42 +0000)
Run using:

mvn test -pl it/api-coverage -Papi-coverage

Change-Id: I6d708ca867a83e49522947b571304c4666bf65b5
Signed-off-by: Marek Gradzki <[email protected]>
it/api-coverage/asciidoc/Readme.adoc [new file with mode: 0644]
it/api-coverage/pom.xml [new file with mode: 0644]
it/api-coverage/src/test/java/io/fd/hc2vpp/it/JVppCoverageTest.java [new file with mode: 0644]
it/pom.xml

diff --git a/it/api-coverage/asciidoc/Readme.adoc b/it/api-coverage/asciidoc/Readme.adoc
new file mode 100644 (file)
index 0000000..51cb2c0
--- /dev/null
@@ -0,0 +1,8 @@
+= api-coverage
+
+Provides integration test that measures VPP API coverage.
+To run the test, invoke:
+
+mvn test -pl it/api-coverage -Papi-coverage
+
+The test counts number of usages of each api method defined in jvpp jars.
\ No newline at end of file
diff --git a/it/api-coverage/pom.xml b/it/api-coverage/pom.xml
new file mode 100644 (file)
index 0000000..4c939ff
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2017 Cisco and/or its affiliates.
+  ~
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>io.fd.hc2vpp.common</groupId>
+        <artifactId>impl-parent</artifactId>
+        <version>1.17.07-SNAPSHOT</version>
+        <relativePath>../../common/impl-parent</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>io.fd.hc2vpp.it</groupId>
+    <artifactId>api-coverage</artifactId>
+    <version>1.17.07-SNAPSHOT</version>
+    <name>${project.artifactId}</name>
+
+    <properties>
+        <jvpp.version>17.07-SNAPSHOT</jvpp.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.fd.vpp</groupId>
+            <artifactId>jvpp-registry</artifactId>
+            <version>${jvpp.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.vpp</groupId>
+            <artifactId>jvpp-core</artifactId>
+            <version>${jvpp.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.vpp</groupId>
+            <artifactId>jvpp-acl</artifactId>
+            <version>${jvpp.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.vpp</groupId>
+            <artifactId>jvpp-snat</artifactId>
+            <version>${jvpp.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.vpp</groupId>
+            <artifactId>jvpp-ioamtrace</artifactId>
+            <version>${jvpp.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.vpp</groupId>
+            <artifactId>jvpp-ioamexport</artifactId>
+            <version>${jvpp.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.vpp</groupId>
+            <artifactId>jvpp-ioampot</artifactId>
+            <version>${jvpp.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.skinny-framework</groupId>
+            <artifactId>skinny-logback</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/it/api-coverage/src/test/java/io/fd/hc2vpp/it/JVppCoverageTest.java b/it/api-coverage/src/test/java/io/fd/hc2vpp/it/JVppCoverageTest.java
new file mode 100644 (file)
index 0000000..406cd01
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * 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 io.fd.hc2vpp.it;
+
+import io.fd.vpp.jvpp.acl.JVppAcl;
+import io.fd.vpp.jvpp.core.JVppCore;
+import io.fd.vpp.jvpp.ioamexport.JVppIoamexport;
+import io.fd.vpp.jvpp.ioampot.JVppIoampot;
+import io.fd.vpp.jvpp.ioamtrace.JVppIoamtrace;
+import io.fd.vpp.jvpp.snat.JVppSnat;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Scanner;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JVppCoverageTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JVppCoverageTest.class);
+
+    @Test
+    public void coverageTest() throws IOException {
+        final Class[] apis = new Class[] {
+            JVppCore.class,
+            JVppAcl.class,
+            JVppSnat.class,
+            JVppIoamtrace.class,
+            JVppIoamexport.class,
+            JVppIoampot.class
+        };
+        int covered = 0;
+        int methods = 0;
+        for (Class api : apis) {
+            final Method[] declaredMethods = api.getDeclaredMethods();
+            methods += declaredMethods.length - 1; // excluding send method
+            covered += coverage(api, declaredMethods);
+        }
+        LOG.info("#methods={} covered={} ({}%)", methods, covered, (100.0 * covered) / methods);
+    }
+
+    private static int coverage(final Class api, final Method[] methods) throws IOException {
+        int covered = 0;
+        int nMethods = methods.length - 1; // excluding send method
+        for (Method method : methods) {
+            LOG.info(method.getName());
+            if (isMethodCovered(method.getName())) {
+                covered++;
+            }
+        }
+        covered--; // excluding send
+        LOG.info("{}: #methods={} covered={} ({}%)", api, nMethods, covered, (100.0 * covered) / nMethods);
+        return covered;
+    }
+
+    private static boolean isMethodCovered(final String name) throws IOException {
+        final Runtime rt = Runtime.getRuntime();
+        // TODO (grep per api name is slow):
+        // scan all java files for jvpp invocations, make a set/map and use it for usage lookup
+        final String[] cmd =
+            {"/bin/sh", "-c", "grep -rn /home/m/hc2vpp --include *.java -rn . -e \"" + name + "\" | wc -l"};
+        final Process proc = rt.exec(cmd);
+        final Scanner sc = new Scanner(proc.getInputStream());
+        final int nRefs = sc.nextInt();
+        LOG.info("Method {} was referenced {}", name, nRefs);
+        return nRefs > 0;
+    }
+}
index 833f20f..998d29c 100644 (file)
         <module>api-test</module>
     </modules>
 
+    <profiles>
+        <!-- Activate from command line with mvn <goals> -Papi-coverage -->
+        <profile>
+            <id>api-coverage</id>
+            <modules>
+                <module>api-coverage</module>
+            </modules>
+        </profile>
+    </profiles>
+
     <build>
         <plugins>
             <plugin>