Server IP : 172.67.216.182 / Your IP : 172.70.189.105 Web Server : Apache System : Linux krdc-ubuntu-s-2vcpu-4gb-amd-blr1-01.localdomain 5.15.0-142-generic #152-Ubuntu SMP Mon May 19 10:54:31 UTC 2025 x86_64 User : www ( 1000) PHP Version : 7.4.33 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /www/server/mysql/src/rapid/unittest/gunit/xplugin/ |
Upload File : |
/* Copyright (c) 2015, 2023, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is also distributed with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have included with MySQL. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <gtest/gtest.h> #include "expect.h" #include "xpl_error.h" #include "ngs_common/protocol_protobuf.h" static const int EXPECT_NO_ERROR = 1; namespace xpl { namespace test { static ngs::Error_code success; static ngs::Error_code simulate_instruction(Expectation_stack &xs, int8_t mid, ngs::Error_code fail) { ngs::Error_code err = xs.pre_client_stmt(mid); if (!err) { // execution would come here err = fail; xs.post_client_stmt(mid, fail); } return err; } static ngs::Error_code simulate_close(Expectation_stack &xs) { ngs::Error_code err = xs.pre_client_stmt(Mysqlx::ClientMessages::EXPECT_CLOSE); if (!err) { err = xs.close(); xs.post_client_stmt(Mysqlx::ClientMessages::EXPECT_CLOSE, err); } return err; } static ngs::Error_code simulate_open(Expectation_stack &xs, const Mysqlx::Expect::Open &open) { ngs::Error_code err = xs.pre_client_stmt(Mysqlx::ClientMessages::EXPECT_OPEN); if (!err) { err = xs.open(open); xs.post_client_stmt(Mysqlx::ClientMessages::EXPECT_OPEN, err); } return err; } static Mysqlx::Expect::Open Inherit() { Mysqlx::Expect::Open open; open.set_op(Mysqlx::Expect::Open::EXPECT_CTX_COPY_PREV); return open; } static Mysqlx::Expect::Open Noerror() { Mysqlx::Expect::Open open; open.set_op(Mysqlx::Expect::Open::EXPECT_CTX_EMPTY); Mysqlx::Expect::Open::Condition *cond = open.mutable_cond()->Add(); cond->set_condition_key(EXPECT_NO_ERROR); cond->set_op(Mysqlx::Expect::Open::Condition::EXPECT_OP_SET); return open; } static Mysqlx::Expect::Open Plain() { Mysqlx::Expect::Open open; open.set_op(Mysqlx::Expect::Open::EXPECT_CTX_EMPTY); return open; } static Mysqlx::Expect::Open Inherit_and_clear_noerror() { Mysqlx::Expect::Open open = Inherit(); Mysqlx::Expect::Open::Condition *cond = open.mutable_cond()->Add(); cond->set_condition_key(EXPECT_NO_ERROR); cond->set_op(Mysqlx::Expect::Open::Condition::EXPECT_OP_UNSET); return open; } static Mysqlx::Expect::Open Inherit_and_add_noerror() { Mysqlx::Expect::Open open = Inherit(); Mysqlx::Expect::Open::Condition *cond = open.mutable_cond()->Add(); cond->set_condition_key(EXPECT_NO_ERROR); cond->set_op(Mysqlx::Expect::Open::Condition::EXPECT_OP_SET); return open; } #define EXPECT_ok_cmd() ASSERT_EQ(success, simulate_instruction(xs, 1, ngs::Error_code())) #define EXPECT_error_cmd() ASSERT_EQ(ngs::Error_code(1234, "whatever"), simulate_instruction(xs, 2, ngs::Error_code(1234, "whatever"))) #define EXPECT_fail(exp) ASSERT_EQ(ngs::Error_code(ER_X_EXPECT_FAILED, "Expectation failed: " exp), simulate_instruction(xs, 3, ngs::Error_code())) #define EXPECT_open_ok(msg) ASSERT_EQ(success, simulate_open(xs, msg)) #define EXPECT_open_fail(msg, exp) ASSERT_EQ(ngs::Error_code(ER_X_EXPECT_FAILED, "Expectation failed: " exp), simulate_open(xs, msg)) #define EXPECT_close_ok() ASSERT_EQ(success, simulate_close(xs)) #define EXPECT_close_fail(exp) ASSERT_EQ(ngs::Error_code(ER_X_EXPECT_FAILED, "Expectation failed: " exp), simulate_close(xs)) TEST(expect, plain) { Expectation_stack xs; // open expect block EXPECT_open_ok(Plain()); // ok command 1 EXPECT_ok_cmd(); EXPECT_ok_cmd(); // error command 2 EXPECT_error_cmd(); // subsequent cmds succeed normally EXPECT_ok_cmd(); EXPECT_error_cmd(); // now close the block EXPECT_close_ok(); EXPECT_ok_cmd(); // close too much should fail EXPECT_EQ(ngs::Error_code(ER_X_EXPECT_NOT_OPEN, "Expect block currently not open"), xs.close()); } TEST(expect, noerror) { Expectation_stack xs; // open expect block EXPECT_open_ok(Noerror()); // ok command 1 EXPECT_ok_cmd(); // error command 2 EXPECT_error_cmd(); // now everything fails EXPECT_fail("no_error"); EXPECT_fail("no_error"); // now close the block EXPECT_close_fail("no_error"); // now commands should succeed again EXPECT_ok_cmd(); } TEST(expect, noerror_in_noerror) { Expectation_stack xs; // fail in the inner block EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); { EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); } EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); EXPECT_ok_cmd(); EXPECT_EQ(ngs::Error_code(ER_X_EXPECT_NOT_OPEN, "Expect block currently not open"), xs.close()); // fail in the outer block EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); { EXPECT_open_fail(Noerror(), "no_error"); EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); } EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); EXPECT_ok_cmd(); EXPECT_EQ(ngs::Error_code(ER_X_EXPECT_NOT_OPEN, "Expect block currently not open"), xs.close()); // fail in inner block again EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); { EXPECT_open_ok(Inherit()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); } EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); EXPECT_ok_cmd(); } TEST(expect, plain_in_noerror) { Expectation_stack xs; // fail in the inner block EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); { EXPECT_open_ok(Plain()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_ok_cmd(); EXPECT_close_ok(); } EXPECT_close_ok(); EXPECT_ok_cmd(); EXPECT_EQ(ngs::Error_code(ER_X_EXPECT_NOT_OPEN, "Expect block currently not open"), xs.close()); // fail in the outer block EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); { EXPECT_open_fail(Plain(), "no_error"); EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); } EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); EXPECT_ok_cmd(); EXPECT_EQ(ngs::Error_code(ER_X_EXPECT_NOT_OPEN, "Expect block currently not open"), xs.close()); // fail in inner block again EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); { EXPECT_open_ok(Inherit()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); } EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); { EXPECT_open_ok(Inherit_and_add_noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); } EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); { EXPECT_open_ok(Inherit_and_clear_noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_ok_cmd(); EXPECT_close_ok(); } EXPECT_close_ok(); EXPECT_ok_cmd(); } TEST(expect, noerror_in_plain) { Expectation_stack xs; // fail in the inner block EXPECT_open_ok(Plain()); EXPECT_ok_cmd(); { EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); } EXPECT_ok_cmd(); EXPECT_close_ok(); EXPECT_ok_cmd(); EXPECT_EQ(ngs::Error_code(ER_X_EXPECT_NOT_OPEN, "Expect block currently not open"), xs.close()); // fail in the outer block EXPECT_open_ok(Plain()); EXPECT_ok_cmd(); EXPECT_error_cmd(); { EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); EXPECT_close_ok(); } EXPECT_ok_cmd(); EXPECT_close_ok(); EXPECT_ok_cmd(); EXPECT_EQ(ngs::Error_code(ER_X_EXPECT_NOT_OPEN, "Expect block currently not open"), xs.close()); // fail in inner block again EXPECT_open_ok(Plain()); EXPECT_ok_cmd(); { EXPECT_open_ok(Inherit()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_ok_cmd(); EXPECT_close_ok(); } EXPECT_close_ok(); EXPECT_open_ok(Plain()); EXPECT_ok_cmd(); { EXPECT_open_ok(Inherit_and_add_noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); } EXPECT_ok_cmd(); EXPECT_close_ok(); EXPECT_ok_cmd(); } TEST(expect, nested_inheriting) { Expectation_stack xs; EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); { EXPECT_open_ok(Inherit_and_add_noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); } EXPECT_close_fail("no_error"); EXPECT_open_ok(Noerror()); EXPECT_ok_cmd(); { EXPECT_open_ok(Inherit_and_clear_noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_ok_cmd(); EXPECT_close_ok(); } EXPECT_close_ok(); EXPECT_open_ok(Plain()); EXPECT_ok_cmd(); { EXPECT_open_ok(Inherit_and_add_noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_fail("no_error"); EXPECT_close_fail("no_error"); } EXPECT_close_ok(); EXPECT_open_ok(Plain()); EXPECT_ok_cmd(); { EXPECT_open_ok(Inherit_and_clear_noerror()); EXPECT_ok_cmd(); EXPECT_error_cmd(); EXPECT_ok_cmd(); EXPECT_close_ok(); } EXPECT_close_ok(); } TEST(expect, invalid) { { Expectation exp; EXPECT_EQ(ngs::Error_code(ER_X_EXPECT_BAD_CONDITION, "Unknown condition key"), exp.set(1234, "1")); } { Expectation exp; EXPECT_EQ(ngs::Error_code(), exp.set(1, "")); EXPECT_EQ(true, exp.fail_on_error()); EXPECT_EQ(ngs::Error_code(), exp.set(1, "1")); EXPECT_EQ(true, exp.fail_on_error()); EXPECT_EQ(ngs::Error_code(), exp.set(1, "0")); EXPECT_FALSE(exp.fail_on_error()); EXPECT_EQ(ngs::Error_code(ER_X_EXPECT_BAD_CONDITION_VALUE, "Invalid value 'bla' for expectation no_error"), exp.set(1, "bla")); EXPECT_FALSE(exp.fail_on_error()); } } class Expect_surprise : public xpl::Expect_condition { public: Expect_surprise(bool v) : m_value(v) {} virtual Expect_condition *copy() { Expect_surprise *exp = new Expect_surprise(m_value); return exp; } virtual ngs::Error_code check() { if (m_value) return ngs::Error_code(1, "surprise"); return ngs::Error_code(); } void set(bool flag) { m_value = flag; } private: bool m_value; }; TEST(expect, condition) { Expectation expect; Expect_surprise *surp; ASSERT_EQ(ngs::Error_code(), expect.check()); expect.add_condition(surp = new Expect_surprise(false)); surp->set_key(1234); ASSERT_EQ(ngs::Error_code(), expect.check()); surp->set(true); ASSERT_EQ(ngs::Error_code(1, "surprise"), expect.check()); { Expectation copy(expect); ASSERT_EQ(ngs::Error_code(1, "surprise"), expect.check()); ASSERT_EQ(ngs::Error_code(1, "surprise"), copy.check()); expect.unset(1234); ASSERT_EQ(ngs::Error_code(), expect.check()); ASSERT_EQ(ngs::Error_code(1, "surprise"), copy.check()); } } } // namespace test } // namespace xpl