diff --git a/mysql-plugin/pom.xml b/mysql-plugin/pom.xml
index 7b047c9f5..d4458dd78 100644
--- a/mysql-plugin/pom.xml
+++ b/mysql-plugin/pom.xml
@@ -26,7 +26,7 @@
Mysql plugin
mysql-plugin
4.0.0
-
+
io.cdap.cdap
@@ -89,6 +89,7 @@
+ ${testSourceLocation}
io.cdap
@@ -96,4 +97,93 @@
+
+
+ e2e-tests
+
+ src/e2e-test/java
+
+
+
+
+ src/e2e-test/resources
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+ TestRunner.java
+
+
+
+
+
+ integration-test
+
+
+
+
+
+
+ net.masterthought
+ maven-cucumber-reporting
+ 5.5.0
+
+
+
+ execution
+ verify
+
+ generate
+
+
+ Cucumber Reports
+ target/cucumber-reports/advanced-reports
+ 1
+ false
+ ${project.build.directory}/cucumber-reports
+
+ **/*.json
+
+ ${project.build.directory}/cucumber-reports
+ true
+
+
+
+
+
+
+
+
+
+ io.cdap.tests.e2e
+ cdap-e2e-framework
+ 0.0.1-SNAPSHOT
+ test
+
+
+ ch.qos.logback
+ logback-core
+ 1.2.8
+ runtime
+
+
+ com.google.guava
+ guava
+ 27.0.1-jre
+
+
+
+
diff --git a/mysql-plugin/src/e2e-test/features/mysql/MySql.feature b/mysql-plugin/src/e2e-test/features/mysql/MySql.feature
new file mode 100644
index 000000000..f1668859c
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/features/mysql/MySql.feature
@@ -0,0 +1,63 @@
+#
+# Copyright © 2022 Cask Data, Inc.
+#
+# 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.
+#
+
+@Mysql
+Feature: Mysql - Verify Mysql source data transfer
+ @MYSQL_SOURCE_TEST @MYSQL_SINK_TEST
+ Scenario: To verify data is getting transferred from Mysql to Mysql successfully
+ Given Open Datafusion Project to configure pipeline
+ When Expand Plugin group in the LHS plugins list: "Source"
+ When Select plugin: "MySQL" from the plugins list as: "Source"
+ When Expand Plugin group in the LHS plugins list: "Sink"
+ When Select plugin: "MySQL" from the plugins list as: "Sink"
+ Then Connect plugins: "MySQL" and "MySQL2" to establish connection
+ Then Navigate to the properties page of plugin: "MySQL"
+ Then Select dropdown plugin property: "select-jdbcPluginName" with option value: "driver"
+ Then Replace input plugin property: "host" with value: "host"
+ Then Replace input plugin property: "port" with value: "port"
+ Then Replace input plugin property: "user" with value: "username"
+ Then Replace input plugin property: "password" with value: "password"
+ Then Enter input plugin property: "referenceName" with value: "sourceRef"
+ Then Replace input plugin property: "database" with value: "database"
+ Then Enter textarea plugin property: "importQuery" with value: "selectQuery"
+ Then Click on the Get Schema button
+ Then Verify the Output Schema matches the Expected Schema: "outputSchema"
+ Then Validate "MySQL" plugin properties
+ Then Close the Plugin Properties page
+ Then Navigate to the properties page of plugin: "MySQL2"
+ Then Select dropdown plugin property: "select-jdbcPluginName" with option value: "driver"
+ Then Replace input plugin property: "host" with value: "host"
+ Then Replace input plugin property: "port" with value: "port"
+ Then Replace input plugin property: "database" with value: "database"
+ Then Replace input plugin property: "tableName" with value: "targetTable"
+ Then Replace input plugin property: "user" with value: "username"
+ Then Replace input plugin property: "password" with value: "password"
+ Then Enter input plugin property: "referenceName" with value: "targetRef"
+ Then Validate "MySQL2" plugin properties
+ Then Close the Plugin Properties page
+ Then Save the pipeline
+ Then Preview and run the pipeline
+ Then Verify the preview of pipeline is "success"
+ Then Click on preview data for MySQL sink
+ Then Verify preview output schema matches the outputSchema captured in properties
+ Then Close the preview data
+ Then Deploy the pipeline
+ Then Run the Pipeline in Runtime
+ Then Wait till pipeline is in running state
+ Then Open and capture logs
+ Then Verify the pipeline status is "Succeeded"
+ Then Get count of no of records transferred to target MySQL Table
+ Then Validate records transferred to target table is equal to number of records from source table
diff --git a/mysql-plugin/src/e2e-test/java/io/cdap/plugin/MysqlClient.java b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/MysqlClient.java
new file mode 100644
index 000000000..c45c6eb22
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/MysqlClient.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.cdap.plugin;
+
+import io.cdap.e2e.utils.PluginPropertyUtils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * MySQL client.
+ */
+public class MysqlClient {
+ private static final String host = PluginPropertyUtils.pluginProp("host");
+ private static final int port = Integer.parseInt(PluginPropertyUtils.pluginProp("port"));
+ private static final String database = PluginPropertyUtils.pluginProp("database");
+
+ private static Connection getMysqlConnection() throws SQLException, ClassNotFoundException {
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ String username = PluginPropertyUtils.pluginProp("username");
+ String password = PluginPropertyUtils.pluginProp("password");
+ return DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, username, password);
+ }
+
+ public static int countRecord(String table) throws SQLException, ClassNotFoundException {
+ String countQuery = "SELECT COUNT(*) as total FROM " + table;
+ try (Connection connect = getMysqlConnection(); Statement statement = connect.createStatement();
+ ResultSet rs = statement.executeQuery(countQuery)) {
+ int num = 0;
+ while (rs.next()) {
+ num = (rs.getInt(1));
+ }
+ return num;
+ }
+ }
+
+ public static void createSourceTable(String sourceTable) throws SQLException, ClassNotFoundException {
+ try (Connection connect = getMysqlConnection(); Statement statement = connect.createStatement()) {
+ String createSourceTableQuery = "CREATE TABLE IF NOT EXISTS " + sourceTable +
+ "(id int, lastName varchar(255), PRIMARY KEY (id))";
+ statement.executeUpdate(createSourceTableQuery);
+
+ // Truncate table to clean the data of last failure run.
+ String truncateSourceTableQuery = "TRUNCATE TABLE " + sourceTable;
+ statement.executeUpdate(truncateSourceTableQuery);
+
+ // Insert dummy data.
+ statement.executeUpdate("INSERT INTO " + sourceTable + " (id, lastName)" +
+ "VALUES (1, 'Simpson')");
+ statement.executeUpdate("INSERT INTO " + sourceTable + " (id, lastName)" +
+ "VALUES (2, 'McBeal')");
+ statement.executeUpdate("INSERT INTO " + sourceTable + " (id, lastName)" +
+ "VALUES (3, 'Flinstone')");
+ }
+ }
+
+ public static void createTargetTable(String targetTable) throws SQLException, ClassNotFoundException {
+ try (Connection connect = getMysqlConnection(); Statement statement = connect.createStatement()) {
+ String createTargetTableQuery = "CREATE TABLE IF NOT EXISTS " + targetTable +
+ "(id int, lastName varchar(255), PRIMARY KEY (id))";
+ statement.executeUpdate(createTargetTableQuery);
+ // Truncate table to clean the data of last failure run.
+ String truncateTargetTableQuery = "TRUNCATE TABLE " + targetTable;
+ statement.executeUpdate(truncateTargetTableQuery);
+ }
+ }
+
+ public static void dropTables(String[] tables) throws SQLException, ClassNotFoundException {
+ try (Connection connect = getMysqlConnection(); Statement statement = connect.createStatement()) {
+ for (String table : tables) {
+ String dropTableQuery = "Drop Table " + table;
+ statement.executeUpdate(dropTableQuery);
+ }
+ }
+ }
+}
diff --git a/mysql-plugin/src/e2e-test/java/io/cdap/plugin/common/stepsdesign/TestSetupHooks.java b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/common/stepsdesign/TestSetupHooks.java
new file mode 100644
index 000000000..76dc7a17c
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/common/stepsdesign/TestSetupHooks.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.cdap.plugin.common.stepsdesign;
+
+import io.cdap.e2e.utils.PluginPropertyUtils;
+import io.cdap.plugin.MysqlClient;
+import io.cucumber.java.After;
+import io.cucumber.java.Before;
+
+import java.sql.SQLException;
+
+/**
+ * MYSQL test hooks.
+ */
+public class TestSetupHooks {
+
+ @Before(order = 1)
+ public static void overrideUserAndPasswordIfProvided() {
+ String username = System.getenv("username");
+ if (username != null && !username.isEmpty()) {
+ PluginPropertyUtils.addPluginProp("username", username);
+ }
+ String password = System.getenv("password");
+ if (password != null && !password.isEmpty()) {
+ PluginPropertyUtils.addPluginProp("password", password);
+ }
+ }
+
+ @Before(order = 1, value = "@MYSQL_SOURCE_TEST")
+ public static void setSelectQuery() {
+ String sourceTable = PluginPropertyUtils.pluginProp("sourceTable");
+ PluginPropertyUtils.addPluginProp("selectQuery",
+ PluginPropertyUtils.pluginProp("selectQuery").
+ replace("${table}", sourceTable));
+ }
+
+ @Before(order = 2, value = "@MYSQL_SOURCE_TEST")
+ public static void createTables() throws SQLException, ClassNotFoundException {
+ MysqlClient.createSourceTable(PluginPropertyUtils.pluginProp("sourceTable"));
+ MysqlClient.createTargetTable(PluginPropertyUtils.pluginProp("targetTable"));
+ }
+
+ @After(order = 2, value = "@MYSQL_SINK_TEST")
+ public static void dropTables() throws SQLException, ClassNotFoundException {
+ MysqlClient.dropTables(new String[]{PluginPropertyUtils.pluginProp("sourceTable"),
+ PluginPropertyUtils.pluginProp("targetTable")});
+ }
+
+}
diff --git a/mysql-plugin/src/e2e-test/java/io/cdap/plugin/common/stepsdesign/package-info.java b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/common/stepsdesign/package-info.java
new file mode 100644
index 000000000..e9eeafc4f
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/common/stepsdesign/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright © 2022 Cask Data, Inc.
+ *
+ * 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 contains the locators for the Joiner plugin.
+ */
+package io.cdap.plugin.common.stepsdesign;
diff --git a/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/runners/TestRunner.java b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/runners/TestRunner.java
new file mode 100644
index 000000000..8fc4f2a1b
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/runners/TestRunner.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2022 Cask Data, Inc.
+ *
+ * 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.cdap.plugin.mysql.runners;
+
+import io.cucumber.junit.Cucumber;
+import io.cucumber.junit.CucumberOptions;
+import org.junit.runner.RunWith;
+
+/**
+ * Test Runner to execute Mysql plugin test cases.
+ */
+@RunWith(Cucumber.class)
+@CucumberOptions(
+ features = {"src/e2e-test/features"},
+ glue = {"stepsdesign", "io.cdap.plugin.common.stepsdesign", "io.cdap.plugin.mysql.stepsdesign"},
+ tags = {"@Mysql"},
+ plugin = {"pretty", "html:target/cucumber-html-report/mysql",
+ "json:target/cucumber-reports/cucumber-mysql.json",
+ "junit:target/cucumber-reports/cucumber-mysql.xml"}
+)
+public class TestRunner {
+}
diff --git a/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/runners/package-info.java b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/runners/package-info.java
new file mode 100644
index 000000000..cf473460a
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/runners/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright © 2022 Cask Data, Inc.
+ *
+ * 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 contains the locators for the Joiner plugin.
+ */
+package io.cdap.plugin.mysql.runners;
diff --git a/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/stepsdesign/Mysql.java b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/stepsdesign/Mysql.java
new file mode 100644
index 000000000..78e29a154
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/stepsdesign/Mysql.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.cdap.plugin.mysql.stepsdesign;
+
+import io.cdap.e2e.utils.CdfHelper;
+import io.cdap.e2e.utils.PluginPropertyUtils;
+import io.cdap.plugin.MysqlClient;
+import io.cucumber.java.en.Then;
+import org.junit.Assert;
+import stepsdesign.BeforeActions;
+
+import java.sql.SQLException;
+
+/**
+ * MYSQL Plugin related step design.
+ */
+public class Mysql implements CdfHelper {
+
+ @Then("Click on preview data for MySQL sink")
+ public void clickOnPreviewDataForBigQuerySink() {
+ openSinkPluginPreviewData("Mysql");
+ }
+
+
+ @Then("Get count of no of records transferred to target MySQL Table")
+ public void getCountOfNoOfRecordsTransferredToTargetMysqlTable() throws SQLException, ClassNotFoundException {
+ int countRecords = MysqlClient.countRecord(PluginPropertyUtils.pluginProp("targetTable"));
+ BeforeActions.scenario.write("**********No of Records Transferred******************:" + countRecords);
+ Assert.assertEquals("Number of records transferred should be equal to records out ",
+ countRecords, recordOut());
+ }
+
+ @Then("Validate records transferred to target table is equal to number of records from source table")
+ public void validateRecordsTransferredToTargetTableIsEqualToNumberOfRecordsFromSourceTable()
+ throws SQLException, ClassNotFoundException {
+ int countRecordsTarget = MysqlClient.countRecord(PluginPropertyUtils.pluginProp("targetTable"));
+ int countRecordsSource = MysqlClient.countRecord(PluginPropertyUtils.pluginProp("sourceTable"));
+ BeforeActions.scenario.write("Number of records transferred:" + countRecordsSource);
+ Assert.assertEquals(countRecordsSource, countRecordsTarget);
+ }
+}
diff --git a/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/stepsdesign/package-info.java b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/stepsdesign/package-info.java
new file mode 100644
index 000000000..2ff0ef270
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/mysql/stepsdesign/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright © 2022 Cask Data, Inc.
+ *
+ * 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 contains the locators for the Joiner plugin.
+ */
+package io.cdap.plugin.mysql.stepsdesign;
diff --git a/mysql-plugin/src/e2e-test/java/io/cdap/plugin/package-info.java b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/package-info.java
new file mode 100644
index 000000000..06587e463
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/java/io/cdap/plugin/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright © 2022 Cask Data, Inc.
+ *
+ * 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 contains the locators for the Joiner plugin.
+ */
+package io.cdap.plugin;
diff --git a/mysql-plugin/src/e2e-test/resources/errorMessage.properties b/mysql-plugin/src/e2e-test/resources/errorMessage.properties
new file mode 100644
index 000000000..87c823507
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/resources/errorMessage.properties
@@ -0,0 +1 @@
+validationSuccessMessage=No errors found.
diff --git a/mysql-plugin/src/e2e-test/resources/pluginParameters.properties b/mysql-plugin/src/e2e-test/resources/pluginParameters.properties
new file mode 100644
index 000000000..7371fbff7
--- /dev/null
+++ b/mysql-plugin/src/e2e-test/resources/pluginParameters.properties
@@ -0,0 +1,12 @@
+driver=mysql
+host=34.105.111.83
+username=dummy
+password=dummy
+database=sakila
+port=3306
+selectQuery=select * from ${table}
+sourceRef=source
+targetRef=target
+sourceTable=sourceTable
+targetTable=targetTable
+outputSchema=[{"key":"id","value":"int"},{"key":"lastName","value":"string"}]