From 1b7e566683d13906530a2218791bb5f48b6425ec Mon Sep 17 00:00:00 2001
From: Sergei Golubchik <sergii@pisem.net>
Date: Tue, 4 Oct 2011 16:51:39 +0200
Subject: [PATCH] tests for feedback plugin, bugfix: garbage in PLUGIN_VAR_STR
 variables when INSTALL'ing a plugin

mysql-test/include/default_mysqld.cnf:
  disable feedback plugin by default.
  when enabled - tag is as a test run
---
 mysql-test/include/default_mysqld.cnf       |  2 ++
 mysql-test/r/feedback_plugin_install.result | 13 +++++++++++
 mysql-test/r/feedback_plugin_load.result    | 11 ++++++++++
 mysql-test/r/feedback_plugin_send.result    | 15 +++++++++++++
 mysql-test/t/feedback_plugin_install.opt    |  1 +
 mysql-test/t/feedback_plugin_install.test   | 14 ++++++++++++
 mysql-test/t/feedback_plugin_load.opt       |  2 ++
 mysql-test/t/feedback_plugin_load.test      |  9 ++++++++
 mysql-test/t/feedback_plugin_send.test      | 24 +++++++++++++++++++++
 sql/sql_plugin.cc                           | 13 +++++++++++
 10 files changed, 104 insertions(+)
 create mode 100644 mysql-test/r/feedback_plugin_install.result
 create mode 100644 mysql-test/r/feedback_plugin_load.result
 create mode 100644 mysql-test/r/feedback_plugin_send.result
 create mode 100644 mysql-test/t/feedback_plugin_install.opt
 create mode 100644 mysql-test/t/feedback_plugin_install.test
 create mode 100644 mysql-test/t/feedback_plugin_load.opt
 create mode 100644 mysql-test/t/feedback_plugin_load.test
 create mode 100644 mysql-test/t/feedback_plugin_send.test

diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf
index e46c3bc3c1..a1b477c51d 100644
--- a/mysql-test/include/default_mysqld.cnf
+++ b/mysql-test/include/default_mysqld.cnf
@@ -15,6 +15,8 @@ max_heap_table_size=        1M
 
 loose-skip-innodb
 loose-skip-pbxt
+loose-skip-feedback
+loose-feedback-user-info=  mysql-test
 
 loose-innodb_data_file_path=      ibdata1:10M:autoextend
 
diff --git a/mysql-test/r/feedback_plugin_install.result b/mysql-test/r/feedback_plugin_install.result
new file mode 100644
index 0000000000..e017276b61
--- /dev/null
+++ b/mysql-test/r/feedback_plugin_install.result
@@ -0,0 +1,13 @@
+install plugin feedback soname 'feedback.so';
+select plugin_status from information_schema.plugins where plugin_name='feedback';
+plugin_status
+ACTIVE
+select * from information_schema.feedback where variable_name like 'feed%'
+       and variable_name not like  '%_uid';
+VARIABLE_NAME	VARIABLE_VALUE
+FEEDBACK_SEND_RETRY_WAIT	60
+FEEDBACK_USER_INFO	mysql-test
+FEEDBACK_SEND_TIMEOUT	60
+FEEDBACK_URL	http://mariadb.org/feedback_plugin/post
+FEEDBACK	1.0
+uninstall plugin feedback;
diff --git a/mysql-test/r/feedback_plugin_load.result b/mysql-test/r/feedback_plugin_load.result
new file mode 100644
index 0000000000..f097c5d9a9
--- /dev/null
+++ b/mysql-test/r/feedback_plugin_load.result
@@ -0,0 +1,11 @@
+select plugin_status from information_schema.plugins where plugin_name='feedback';
+plugin_status
+ACTIVE
+select * from information_schema.feedback where variable_name like 'feed%'
+       and variable_name not like  '%_uid';
+VARIABLE_NAME	VARIABLE_VALUE
+FEEDBACK_SEND_RETRY_WAIT	60
+FEEDBACK_USER_INFO	mysql-test
+FEEDBACK_SEND_TIMEOUT	60
+FEEDBACK_URL	http://mariadb.org/feedback_plugin/post
+FEEDBACK	1.0
diff --git a/mysql-test/r/feedback_plugin_send.result b/mysql-test/r/feedback_plugin_send.result
new file mode 100644
index 0000000000..e7d3238146
--- /dev/null
+++ b/mysql-test/r/feedback_plugin_send.result
@@ -0,0 +1,15 @@
+select plugin_status from information_schema.plugins where plugin_name='feedback';
+plugin_status
+ACTIVE
+select * from information_schema.feedback where variable_name like 'feed%'
+       and variable_name not like  '%_uid';
+VARIABLE_NAME	VARIABLE_VALUE
+FEEDBACK_SEND_RETRY_WAIT	60
+FEEDBACK_USER_INFO	mysql-test
+FEEDBACK_SEND_TIMEOUT	60
+FEEDBACK_URL	http://mariadb.org/feedback_plugin/post
+FEEDBACK	1.0
+feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent
+feedback plugin: server replied 'ok'
+feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent
+feedback plugin: server replied 'ok'
diff --git a/mysql-test/t/feedback_plugin_install.opt b/mysql-test/t/feedback_plugin_install.opt
new file mode 100644
index 0000000000..a711ae94e6
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_install.opt
@@ -0,0 +1 @@
+--loose-feedback
diff --git a/mysql-test/t/feedback_plugin_install.test b/mysql-test/t/feedback_plugin_install.test
new file mode 100644
index 0000000000..f2bbe0b9e5
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_install.test
@@ -0,0 +1,14 @@
+--source include/not_embedded.inc
+
+if (`select length('$FEEDBACK_SO') = 0`) {
+  skip No feedback plugin;
+}
+
+--replace_regex /\.dll/.so/
+eval install plugin feedback soname '$FEEDBACK_SO';
+select plugin_status from information_schema.plugins where plugin_name='feedback';
+--replace_result https http
+select * from information_schema.feedback where variable_name like 'feed%'
+       and variable_name not like  '%_uid';
+uninstall plugin feedback;
+
diff --git a/mysql-test/t/feedback_plugin_load.opt b/mysql-test/t/feedback_plugin_load.opt
new file mode 100644
index 0000000000..5fbb2f8395
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_load.opt
@@ -0,0 +1,2 @@
+--loose-feedback
+--plugin-load=$FEEDBACK_SO
diff --git a/mysql-test/t/feedback_plugin_load.test b/mysql-test/t/feedback_plugin_load.test
new file mode 100644
index 0000000000..a395052daf
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_load.test
@@ -0,0 +1,9 @@
+if (`select count(*) = 0 from information_schema.plugins where plugin_name = 'feedback' and plugin_status='active'`)
+{
+  --skip Feedback plugin is not active
+}
+
+select plugin_status from information_schema.plugins where plugin_name='feedback';
+--replace_result https http
+select * from information_schema.feedback where variable_name like 'feed%'
+       and variable_name not like  '%_uid';
diff --git a/mysql-test/t/feedback_plugin_send.test b/mysql-test/t/feedback_plugin_send.test
new file mode 100644
index 0000000000..b49c0d0e25
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_send.test
@@ -0,0 +1,24 @@
+source t/feedback_plugin_load.test;
+source include/big_test.inc;
+
+if (!$MTR_FEEDBACK_PLUGIN) {
+  skip MTR_FEEDBACK_PLUGIN is not set;
+}
+
+#
+# Yep. The plugin waits 5 minutes before sending anything,
+# and there's no way to force it to send anything sooner.
+# Let's wait, and hope that mtr is started with --parallel and
+# is doing some work in other workers.
+#
+sleep 310;
+source include/restart_mysqld.inc;
+
+replace_result https http;
+perl;
+  $log_error= $ENV{'MYSQLTEST_VARDIR'} . '/log/mysqld.1.err';
+  open(LOG, '<', $log_error) or die "open(< $log_error): $!";
+  /feedback plugin:.*/ && print "$&\n" while $_=<LOG>;
+  close LOG;
+EOF
+
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index dbbcd7e8c8..8fc02f4b19 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -3176,6 +3176,19 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
                             opt->name, plugin_name);
         }
       }
+      /*
+        PLUGIN_VAR_STR command-line options without PLUGIN_VAR_MEMALLOC, point
+        directly to values in the argv[] array. For plugins started at the
+        server startup, argv[] array is allocated with load_defaults(), and
+        freed when the server is shut down.  But for plugins loaded with
+        INSTALL PLUGIN, the memory allocated with load_defaults() is freed with
+        freed() at the end of mysql_install_plugin(). Which means we cannot
+        allow any pointers into that area.
+        Thus, for all plugins loaded after the server was started,
+        we force all command-line options to be PLUGIN_VAR_MEMALLOC
+      */
+      if (mysqld_server_started && !(opt->flags & PLUGIN_VAR_NOCMDOPT))
+        opt->flags|= PLUGIN_VAR_MEMALLOC;
       break;
     case PLUGIN_VAR_ENUM:
       if (!opt->check)
-- 
2.30.9