Ejemplo n.º 1
0
def main():
    fuck_with_mysql_server()
    render_status()
    while 1:
        # pick a random value which may or may not trigger query timeout
        # remember, the mysql server only stays up for a short while
        wait = random.randrange(3, 7)
        print "About to yield on select sleep(%i)" % wait
        try:
            d1 = conn.runQuery("select sleep(%i)" % wait)
            d2 = conn.runQuery("select sleep(%i)" % (wait + 1))
            d3 = conn.runQuery("select sleep(%i)" % (wait + 2))
            print "============================================================="
            print "I have been promised a result on %s" % str([d1, d2, d3])
            print "============================================================="
            d = defer.DeferredList([d1, d2, d3])
            result = yield d
            print "============================================================="
            print "THIS RESULT IS SACRED AND SHOULD ALWAYS BE RETURNED CORRECTLY %s" % str(
                d)
            print result
            print "============================================================="
            print "about to go under..."
            yield sleep(random.randrange(3, 7))
        except Exception, e:
            print "AAAAAAAAAAAAAARGH I GOT A FAILURE AS AN EXCEPTION"
            print e
            print "AAAAAAAAAAAAAARGH I GOT A FAILURE AS AN EXCEPTION, sleeping..."
            yield sleep(1)
Ejemplo n.º 2
0
def fuck_with_mysql_server():
    print "Stopping MySQL"
    yield AsyncExecCmds(['pkill -9 mysqld; sudo stop mysql'], cmd_prefix='sudo ').getDeferred()
    # The pkill -9 mysqld causes "Lost connection to MySQL server during query"
    # or "MySQL server has gone away" if you try to query on a connection which has died
    while 1:
        if random.choice([0,1]) == 0:
            # Only sometimes will the MySQL server be up for long enough to
            # successfully return a SELECT
            print "Starting MySQL"
            yield AsyncExecCmds(['start mysql'], cmd_prefix='sudo ').getDeferred()
            wait = random.randrange(30, 31)
            yield sleep(wait)
            print "Stopping MySQL"
            yield AsyncExecCmds(['pkill -9 mysqld; sudo stop mysql'], cmd_prefix='sudo ').getDeferred()
            wait = random.randrange(1, 5)
            yield sleep(wait)
        else:
            # And sometimes MySQL will be replaced with an evil daemon
            # which accepts TCP connections for 10-20 seconds but stays silent
            # This causes the official MySQL client to say:
            # Lost connection to MySQL server at 'reading initial communication packet', system error: 0
            # ... when the connection finally dies (i.e. when evildaemon.py stops)
            print "Starting evil daemon"
            yield AsyncExecCmds(['stop mysql; sudo python test/evildaemon.py'], cmd_prefix='sudo ').getDeferred()
            print "Evil daemon stopped"
            wait = random.randrange(1, 5)
            yield sleep(wait)
Ejemplo n.º 3
0
def fuck_with_mysql_server():
    print "Stopping MySQL"
    yield AsyncExecCmds(['pkill -9 mysqld; sudo stop mysql'],
                        cmd_prefix='sudo ').getDeferred()
    # The pkill -9 mysqld causes "Lost connection to MySQL server during query"
    # or "MySQL server has gone away" if you try to query on a connection which has died
    while 1:
        if random.choice([0, 1]) == 0:
            # Only sometimes will the MySQL server be up for long enough to
            # successfully return a SELECT
            print "Starting MySQL"
            yield AsyncExecCmds(['start mysql'],
                                cmd_prefix='sudo ').getDeferred()
            wait = random.randrange(30, 31)
            yield sleep(wait)
            print "Stopping MySQL"
            yield AsyncExecCmds(['pkill -9 mysqld; sudo stop mysql'],
                                cmd_prefix='sudo ').getDeferred()
            wait = random.randrange(1, 5)
            yield sleep(wait)
        else:
            # And sometimes MySQL will be replaced with an evil daemon
            # which accepts TCP connections for 10-20 seconds but stays silent
            # This causes the official MySQL client to say:
            # Lost connection to MySQL server at 'reading initial communication packet', system error: 0
            # ... when the connection finally dies (i.e. when evildaemon.py stops)
            print "Starting evil daemon"
            yield AsyncExecCmds(['stop mysql; sudo python test/evildaemon.py'],
                                cmd_prefix='sudo ').getDeferred()
            print "Evil daemon stopped"
            wait = random.randrange(1, 5)
            yield sleep(wait)
Ejemplo n.º 4
0
def main():
    fuck_with_mysql_server()
    render_status()
    while 1:
        # pick a random value which may or may not trigger query timeout
        # remember, the mysql server only stays up for a short while
        wait = random.randrange(3, 7)
        print "About to yield on select sleep(%i)" % wait
        try:
            d1 = conn.runQuery("select sleep(%i)" % wait)
            d2 = conn.runQuery("select sleep(%i)" % (wait + 1))
            d3 = conn.runQuery("select sleep(%i)" % (wait + 2))
            print "============================================================="
            print "I have been promised a result on %s" % str([d1,d2,d3])
            print "============================================================="
            d = defer.DeferredList([d1, d2, d3])
            result = yield d
            print "============================================================="
            print "THIS RESULT IS SACRED AND SHOULD ALWAYS BE RETURNED CORRECTLY %s" % str(d)
            print result
            print "============================================================="
            print "about to go under..."
            yield sleep(random.randrange(3, 7))
        except Exception, e:
            print "AAAAAAAAAAAAAARGH I GOT A FAILURE AS AN EXCEPTION"
            print e
            print "AAAAAAAAAAAAAARGH I GOT A FAILURE AS AN EXCEPTION, sleeping..."
            yield sleep(1)
Ejemplo n.º 5
0
    def test_0040_thrash(self):
        yield self._start_mysql()
        conn = self._connect_mysql(retry_on_error=True)
        yield conn.runOperation("drop table if exists thrashtest")
        yield conn.runOperation("create table thrashtest (id int)")

        dlist = []
        for i in range(100):
            dlist.append(conn.runOperation("insert into thrashtest values (%s)", [i]))
        yield defer.DeferredList(dlist)

        dlist = []
        for i in range(50):
            print "Appending %i" % i
            dlist.append(conn.runQuery("select sleep(0.1)"))
            dlist.append(conn.runQuery("select * from thrashtest where id=%s", [i]))

        yield sleep(3)

        print "About to stop MySQL"
        dstop = self._stop_mysql()
        def and_start(data):
            print "About to start MySQL"
            return self._start_mysql()
        dstop.addCallback(and_start)
        
        for i in range(50,100):
            print "Appending %i" % i
            dlist.append(conn.runQuery("select sleep(0.1)"))
            dlist.append(conn.runQuery("select * from thrashtest where id=%s", [i]))

        results = yield defer.DeferredList(dlist)
        print results

        conn.disconnect()
Ejemplo n.º 6
0
 def test_0020_start_query_restart(self):
     yield self._start_mysql()
     conn = self._connect_mysql(retry_on_error=True, idle_timeout=2)
     result = yield conn.runQuery("select 2")
     #yield self._stop_mysql()
     #yield self._start_mysql()
     yield sleep(10)
     conn.disconnect()
     self.assertEquals(result, [[2]])
Ejemplo n.º 7
0
 def test_0020_start_query_restart(self):
     yield self._start_mysql()
     conn = self._connect_mysql(retry_on_error=True, idle_timeout=2)
     result = yield conn.runQuery("select 2")
     #yield self._stop_mysql()
     #yield self._start_mysql()
     yield sleep(10)
     conn.disconnect()
     self.assertEquals(result, [[2]])
Ejemplo n.º 8
0
    def test_0600_error_strings_test(self):
        """
        This test causes MySQL to return what we consider a temporary local
        error.  We do this by starting MySQL, querying a table, then physically
        removing MySQL's data files.

        This triggers MySQL to return a certain error code which we want to
        consider a temporary local error, which should result in a reconnection
        to MySQL.

        This is arguably the most application-specific behaviour in the txMySQL
        client library.

        """
        res = yield AsyncExecCmds([
            """sh -c '
            cd /var/lib/mysql/foo;
            chmod 0660 *;
            chown mysql:mysql *
            '"""], cmd_prefix="sudo ").getDeferred()
        yield self._start_mysql()
        conn = self._connect_mysql(retry_on_error=True,
            temporary_error_strings=[
                "Can't find file: './foo/foo.frm' (errno: 13)",
            ])
        yield conn.selectDb("foo")
        yield conn.runOperation("create database if not exists foo")
        yield conn.runOperation("create database if not exists foo")
        yield conn.runOperation("drop table if exists foo")
        yield conn.runOperation("create table foo (id int)")
        yield conn.runOperation("insert into foo set id=1")
        result = yield conn.runQuery("select * from foo")
        self.assertEquals(result, [[1]])

        # Now the tricky bit, we have to force MySQL to yield the error message.
        res = yield AsyncExecCmds([
            """sh -c '
            cd /var/lib/mysql/foo;
            chmod 0600 *;
            chown root:root *'
            """], cmd_prefix="sudo ").getDeferred()
        print res
        
        yield conn.runOperation("flush tables") # cause the files to get re-opened
        d = conn.runQuery("select * from foo") # This will spin until we fix the files, so do that pronto
        yield sleep(1)
        res = yield AsyncExecCmds([
            """sh -c '
            cd /var/lib/mysql/foo;
            chmod 0660 *;
            chown mysql:mysql *
            '"""], cmd_prefix="sudo ").getDeferred()
        print res
        result = yield d
        self.assertEquals(result, [[1]])
        conn.disconnect()
Ejemplo n.º 9
0
 def test_0005_query_timeout_stay_disconnected(self):
     """
     Checks that when there are no pending or current operations that we
     disconnect and stay disconnected
     """
     yield self._start_mysql()
     conn = self._connect_mysql(retry_on_error=True, idle_timeout=2)
     res = yield conn.runQuery("select 1")
     yield sleep(6)
     self.assertIdentical(conn.client, None)
     conn.disconnect()
Ejemplo n.º 10
0
 def test_0005_query_timeout_stay_disconnected(self):
     """
     Checks that when there are no pending or current operations that we
     disconnect and stay disconnected
     """
     yield self._start_mysql()
     conn = self._connect_mysql(retry_on_error=True, idle_timeout=2)
     res = yield conn.runQuery("select 1")
     yield sleep(6)
     self.assertIdentical(conn.client, None)
     conn.disconnect()
Ejemplo n.º 11
0
 def test_0010_two_queries_disconnected(self):
     yield self._start_mysql()
     conn = self._connect_mysql(retry_on_error=True, idle_timeout=1)
     yield conn.runQuery("select 1")
     yield sleep(2)
     a = conn.runQuery("select 2")
     b = conn.runQuery("select 3")
     a, b = yield defer.gatherResults([a, b])
     self.assertEquals(a, [[2]])
     self.assertEquals(b, [[3]])
     self.assertEquals((yield conn.runQuery("select 4")), [[4]])
     conn.disconnect()
Ejemplo n.º 12
0
 def test_0010_two_queries_disconnected(self):
     yield self._start_mysql()
     conn = self._connect_mysql(retry_on_error=True, idle_timeout=1)
     yield conn.runQuery("select 1")
     yield sleep(2)
     a = conn.runQuery("select 2")
     b = conn.runQuery("select 3")
     a, b = yield defer.gatherResults([a, b])
     self.assertEquals(a, [[2]])
     self.assertEquals(b, [[3]])
     self.assertEquals((yield conn.runQuery("select 4")), [[4]])
     conn.disconnect()
Ejemplo n.º 13
0
def render_status():
    while 1:
        fp = open("status.tmp", "w")
        yield sleep(0.1)
        fp.write("Operations:\n\n")
        fp.write(pprint.pformat(conn._pending_operations) + "\n\n")
        fp.write("Current operation;\n\n")
        fp.write(pprint.pformat(conn._current_operation) + "\n\n")
        fp.write("Current operation deferred:\n\n")
        fp.write(pprint.pformat(conn._current_operation_dfr) + "\n\n")
        fp.write("Current user deferred:\n\n")
        fp.write(pprint.pformat(conn._current_user_dfr) + "\n\n")
        fp.close()
        shutil.move("status.tmp", "status.txt")
Ejemplo n.º 14
0
def render_status():
    while 1:
        fp = open("status.tmp", "w")
        yield sleep(0.1)
        fp.write("Operations:\n\n")
        fp.write(pprint.pformat(conn._pending_operations) + "\n\n")
        fp.write("Current operation;\n\n")
        fp.write(pprint.pformat(conn._current_operation) + "\n\n")
        fp.write("Current operation deferred:\n\n")
        fp.write(pprint.pformat(conn._current_operation_dfr) + "\n\n")
        fp.write("Current user deferred:\n\n")
        fp.write(pprint.pformat(conn._current_user_dfr) + "\n\n")
        fp.close()
        shutil.move("status.tmp", "status.txt")
Ejemplo n.º 15
0
 def test_0500_retry_on_error(self):
     """
     Start a couple of queries in parallel.
     Both of them should take 10 seconds, but restart the MySQL
     server after 5 seconds.
     Setting the connection and idle timeouts allows bad connections
     to fail.
     """
     yield self._start_mysql()
     conn = self._connect_mysql(retry_on_error=True)
     d1 = conn.runQuery("select sleep(7)")
     d2 = conn.runQuery("select sleep(7)")
     yield sleep(2)
     yield self._stop_mysql()
     yield self._start_mysql()
     result = yield defer.DeferredList([d1, d2])
     conn.disconnect()
     self.assertEquals(result, [(True, [[0]]), (True, [[0]])])
Ejemplo n.º 16
0
 def test_0500_retry_on_error(self):
     """
     Start a couple of queries in parallel.
     Both of them should take 10 seconds, but restart the MySQL
     server after 5 seconds.
     Setting the connection and idle timeouts allows bad connections
     to fail.
     """
     yield self._start_mysql()
     conn = self._connect_mysql(retry_on_error=True)
     d1 = conn.runQuery("select sleep(7)")
     d2 = conn.runQuery("select sleep(7)")
     yield sleep(2)
     yield self._stop_mysql()
     yield self._start_mysql()
     result = yield defer.DeferredList([d1, d2])
     conn.disconnect()
     self.assertEquals(result, [(True, [[0]]), (True, [[0]])])
Ejemplo n.º 17
0
    def test_0040_thrash(self):
        yield self._start_mysql()
        conn = self._connect_mysql(retry_on_error=True)
        yield conn.runOperation("drop table if exists thrashtest")
        yield conn.runOperation("create table thrashtest (id int)")

        dlist = []
        for i in range(100):
            dlist.append(
                conn.runOperation("insert into thrashtest values (%s)", [i]))
        yield defer.DeferredList(dlist)

        dlist = []
        for i in range(50):
            print "Appending %i" % i
            dlist.append(conn.runQuery("select sleep(0.1)"))
            dlist.append(
                conn.runQuery("select * from thrashtest where id=%s", [i]))

        yield sleep(3)

        print "About to stop MySQL"
        dstop = self._stop_mysql()

        def and_start(data):
            print "About to start MySQL"
            return self._start_mysql()

        dstop.addCallback(and_start)

        for i in range(50, 100):
            print "Appending %i" % i
            dlist.append(conn.runQuery("select sleep(0.1)"))
            dlist.append(
                conn.runQuery("select * from thrashtest where id=%s", [i]))

        results = yield defer.DeferredList(dlist)
        print results

        conn.disconnect()
Ejemplo n.º 18
0
    def test_0600_error_strings_test(self):
        """
        This test causes MySQL to return what we consider a temporary local
        error.  We do this by starting MySQL, querying a table, then physically
        removing MySQL's data files.

        This triggers MySQL to return a certain error code which we want to
        consider a temporary local error, which should result in a reconnection
        to MySQL.

        This is arguably the most application-specific behaviour in the txMySQL
        client library.

        """
        res = yield AsyncExecCmds([
            """sh -c '
            cd /var/lib/mysql/foo;
            chmod 0660 *;
            chown mysql:mysql *
            '"""
        ],
                                  cmd_prefix="sudo ").getDeferred()
        yield self._start_mysql()
        conn = self._connect_mysql(
            retry_on_error=True,
            temporary_error_strings=[
                "Can't find file: './foo/foo.frm' (errno: 13)",
            ])
        yield conn.selectDb("foo")
        yield conn.runOperation("create database if not exists foo")
        yield conn.runOperation("create database if not exists foo")
        yield conn.runOperation("drop table if exists foo")
        yield conn.runOperation("create table foo (id int)")
        yield conn.runOperation("insert into foo set id=1")
        result = yield conn.runQuery("select * from foo")
        self.assertEquals(result, [[1]])

        # Now the tricky bit, we have to force MySQL to yield the error message.
        res = yield AsyncExecCmds([
            """sh -c '
            cd /var/lib/mysql/foo;
            chmod 0600 *;
            chown root:root *'
            """
        ],
                                  cmd_prefix="sudo ").getDeferred()
        print res

        yield conn.runOperation(
            "flush tables")  # cause the files to get re-opened
        d = conn.runQuery(
            "select * from foo"
        )  # This will spin until we fix the files, so do that pronto
        yield sleep(1)
        res = yield AsyncExecCmds([
            """sh -c '
            cd /var/lib/mysql/foo;
            chmod 0660 *;
            chown mysql:mysql *
            '"""
        ],
                                  cmd_prefix="sudo ").getDeferred()
        print res
        result = yield d
        self.assertEquals(result, [[1]])
        conn.disconnect()