Package org.apache.derbyTesting.system.sttest

Source Code of org.apache.derbyTesting.system.sttest.Sttest

/*
*
* Derby - Class org.apache.derbyTesting.system.sttest.Sttest
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You 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 org.apache.derbyTesting.system.sttest;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Random;

import org.apache.derby.tools.JDBCDisplayUtil;
import org.apache.derby.tools.ij;
import org.apache.derbyTesting.system.sttest.tools.MemCheck;
import org.apache.derbyTesting.system.sttest.utils.Datatypes;
import org.apache.derbyTesting.system.sttest.utils.Setup;
import org.apache.derbyTesting.system.sttest.utils.StStatus;

/*
* * Sttest.java * 'Sttest' is short for 'single table test.' Sttest.java
* supplies * the main entry point and the top level code for controlling the *
* actions of the test, including the ddl for the table and indexes. * The
* purpose of the test is to exercise the store code by running * updates on the
* single table for an indefinitely long time, with * an indefinitely large
* number of user connections, each randomly * executing one of a small number
* of update procedures with random * data. The test sets a minimum and maximum
* number of rows, builds * the table up to the minimum number of rows, and from
* that point * either gradually grows the table to the max size, or gradually *
* shrinks it to the min size. Periodically memory use is reported, * and the
* table is compressed, to keep performance from deteriorating.
*/
public class Sttest extends Thread {

  static int loops = 200;

  static int rowcount = 0;

  static int testcount = 0;

  static int connections_to_make = 250;

  static Random rand;

  static boolean increase = true;

  static boolean not_finished = true;

  static int targetmax = 100000; // build up to 1GB database

  static int targetmin = 90000;

  static int insertsize = 7;

  static int updatesize = 1;

  static int deletesize = 1;

  static boolean fatal = false;

  static int rows = 0;

  static boolean countlock = false;

  static int delete_freq = 1;

  static int locker_id = -1;

  static final int INIT = 0;

  static final int GROW = 1;

  static final int SHRINK = 2;

  static int mode = INIT;

  static int count_timer = 0;

  static int inserts_to_try = 0;

  static final int INITIAL_CONNECTIONS = 2; // initial connections should be

  // low, otherwise deadlock will
  // happen.

  static boolean startByIJ = false;

  static String dbURL = "jdbc:derby:testDB";

  static String driver = "org.apache.derby.jdbc.EmbeddedDriver";

  static StStatus status = null;

  int thread_id;

  int ind = 0;

  public static void main(String[] args) throws SQLException, IOException,
  InterruptedException, Exception, Throwable {
    System.getProperties().put("derby.locks.deadlockTimeout", "60");
    System.getProperties().put("derby.locks.waitTimeout", "200");
    System.out.println("Test Sttest starting");
    System.getProperties().put("derby.infolog.append", "true");
    System.getProperties().put("derby.stream.error.logSeverityLevel", "0");
    // get any properties user may have set in Sttest.properties file
    // these will override any of those set above
    userProperties();
    Class.forName(driver).newInstance();
    if (Setup.doit(dbURL) == false)
      System.exit(1);
    status = new StStatus();
    sttTop();
  }

  static void userProperties() throws Throwable {
    FileInputStream fileIn = null;
    try {
      fileIn = new FileInputStream("Sttest.properties");
    } catch (Exception e) {
      System.out
      .println("user control file 'Sttest.properties' not found; using defaults");
    }
    if (fileIn != null) {
      Properties props = new Properties();
      props.load(fileIn);
      fileIn.close();
      String prop = null;
      prop = props.getProperty("connections");
      if (prop != null)
        connections_to_make = Integer.parseInt(prop);
      prop = props.getProperty("dbURL");
      if (prop != null)
        dbURL = prop;
      prop = props.getProperty("driver");
      if (prop != null)
        driver = prop;
      // allows us to get any other properties into the system
      Properties sysprops = System.getProperties();
      Enumeration list = props.propertyNames();
      String s = null;
      while (list.hasMoreElements()) {
        s = (String) list.nextElement();
        sysprops.put(s, props.getProperty(s));
      }
    }
    System.out.println("driver = " + driver);
    System.out.println("dbURL = " + dbURL);
    System.out.println("connections = " + connections_to_make);
  }

  public static void sttTop() throws SQLException, IOException,
  InterruptedException, Exception, Throwable {
    rand = new Random();

    Datatypes.Rn = rand;
    // harder to actually delete rows when there are
    // more connections, so repeat operation more often
    delete_freq = 1 + connections_to_make % 5;
    initial_data();
    Date d = new Date();
    status.firstMessage(connections_to_make, d);
    // check memory in separate thread-- allows us to monitor
    // usage during database calls
    // 200,000 msec = 3min, 20 sec delay between checks
    MemCheck mc = new MemCheck(200000);
    mc.start();
    Sttest testsessions[] = new Sttest[connections_to_make];
    for (int i = 0; i < connections_to_make; i++) {
      testsessions[i] = new Sttest(i);
      testsessions[i].start();
      sleep(3000);
    }
    for (int i = 0; i < connections_to_make; i++) {
      testsessions[i].join();
    }
    try {
      mc.stopNow = true;
      mc.join();
    } catch (Throwable t) {
      throw (t);
    }
  }

  Sttest(int num) throws SQLException {
    this.thread_id = num;
  }

  static synchronized void reset_loops(int myloopcount) {
    if (myloopcount == loops)
      loops--;
    // otherwise some other thread got there first and reset it
  }

  // available to force synchronization of get_countlock(), ...
  static synchronized void locksync() {
    return;
  }

  static synchronized boolean get_countlock() {
    locksync();
    return (countlock);
  }

  static synchronized boolean set_countlock(boolean state) {
    locksync();
    if (state == true && countlock == true)
      return (false);
    countlock = state;
    return (true);
  }

  static synchronized void changerowcount(int in) {
    rowcount += in;
  }

  static synchronized void changerowcount2zero() {
    rowcount = 0;
  }

  static void initial_data() throws Exception, Throwable {
    Connection conn = null;
    int rows = 0;
    try {
      conn = mystartJBMS();
    } catch (Throwable t) {
      throw (t);
    }
    // our goal is to get up to minimum table size
    int x = Datatypes.get_table_count(conn);
    if (x != -1) {
      rows = x;
    }
    if (conn != null) {
      conn.commit();
      conn.close();
    }
    rowcount = rows;
    if (rows >= targetmin) {
      mode = GROW;
      System.out.println("initial data not needed");
      return;
    }
    inserts_to_try = targetmin - rows;
    Sttest testthreads[] = new Sttest[INITIAL_CONNECTIONS];
    for (int i = 0; i < INITIAL_CONNECTIONS; i++) {
      testthreads[i] = new Sttest(i);
      testthreads[i].start();
    }
    for (int i = 0; i < INITIAL_CONNECTIONS; i++) {
      testthreads[i].join();
    }
    mode = GROW;
    System.out.println("complete initial data");
    return;
  }

  public void run() {
    Connection conn = null;
    Date d = null;
    try {
      conn = mystartJBMS();
    } catch (Throwable t) {
      return;
    }
    int ind2 = 0;
    int myloops = loops;
    while (not_finished) {
      if (loops <= 0)
        break;// done
      // thread-private copy to be checked against global copy
      // before attempting to update
      myloops = loops;
      if (fatal == true)
        break;
      if (mode == INIT && inserts_to_try <= 0) {
        break;
      }
      // test rowcount
      if (mode == GROW && rowcount > targetmax) {
        System.out.println("hit targetmax with " + rowcount + " " + d);
        d = new Date();
        mode = SHRINK;
        reset_loops(myloops);
        insertsize = 1;
        deletesize = 12;
        if (set_countlock(true) == true) {
          try {
            checkrowcount(conn);
            MemCheck.showmem();
            status.updateStatus();
          } catch (Exception e) {
            System.out.println("unexpected exception in rowcount");
            set_countlock(false);
            System.exit(1);
          }
          MemCheck.showmem();
        }
        set_countlock(false);
        yield();
      } else if (mode == GROW && rowcount >= targetmax) {
        d = new Date();
        System.out.println("hit targetmax with " + rowcount + " " + d);
        mode = SHRINK;
        insertsize = 1;
        deletesize = 12;
      } else if (mode == SHRINK && rowcount <= targetmin) {
        d = new Date();
        System.out.println("hit targetmin with " + rowcount + " " + d);
        mode = GROW;
        reset_loops(myloops);
        insertsize = 8;
        deletesize = 1;
        if (set_countlock(true) == true) {
          try {
            checkrowcount(conn);
            MemCheck.showmem();
            status.updateStatus();
          } catch (Exception e) {
            System.out.println("unexpected exception in rowcount");
            set_countlock(false);
            System.exit(1);
          }
          MemCheck.showmem();
          // compress
          try {
            compress(conn);
          } catch  (Exception e) {
            System.out.println("unexpected exception during compress");
          }
        }
        set_countlock(false);
        yield();
      }
      // don't interfere with count query
      while (get_countlock() == true) {
        try {
          sleep(1000);
        } catch (java.lang.InterruptedException ex) {
          System.out.println("unexpected sleep interruption");
          break;
        }
      }
      try {
        if (mode == INIT)
          ind = 0;
        else
          ind = Math.abs(rand.nextInt() % 3);
        switch (ind) {
        case 0:
          ind2 = Math.abs(rand.nextInt() % insertsize);
          int addrows = 0;
          for (int i = 0; i <= ind2; i++) {
            Datatypes.add_one_row(conn, thread_id);
            addrows++;
            conn.commit();
            if (mode == INIT) {
              inserts_to_try--;
            }
            yield();
            changerowcount(1);
          }
          System.out.println(addrows + "  Rows inserted");
          break;
        case 1:
          ind2 = Math.abs(rand.nextInt() % updatesize);
          int updaterow = 0;
          for (int i = 0; i <= ind2; i++) {
            Datatypes.update_one_row(conn, thread_id);
            updaterow++;
            conn.commit();
            yield();
          }
          System.out.println(updaterow + "  rows updated");
          break;
        case 2:
          ind2 = Math.abs(rand.nextInt() % deletesize);
          int del_rows = 0;
          del_rows = Datatypes.delete_some(conn, thread_id, ind2 + 1);
          yield();
          changerowcount(-1 * del_rows);
          // commits are done inside delete_some()
          System.out.println(del_rows + " rows deleted");
          break;
        } // end switch

      } catch (SQLException se) {
        if (se.getSQLState() == null)
          se.printStackTrace();
        if (se.getSQLState().equals("40001")) {
          System.out.println("t" + thread_id + " deadlock op = "
              + ind);
          continue;
        }
        if (se.getSQLState().equals("40XL1")) {
          System.out
          .println("t" + thread_id + " timeout op = " + ind);
          continue;
        }
        if (se.getSQLState().equals("23500")) {
          System.out.println("t" + thread_id
              + " duplicate key violation\n");
          continue;
        }
        if (se.getSQLState().equals("23505")) {
          System.out.println("t" + thread_id
              + " duplicate key violation\n");
          continue;
        }
        System.out.println("t" + thread_id
            + " FAIL -- unexpected exception:");
        JDBCDisplayUtil.ShowException(System.out, se);
        fatal = true;
        break;
      } catch (Throwable e) {
        e.printStackTrace();
        if (e.getMessage().equals("java.lang.ThreadDeath")) {
          System.out.println("caught threaddeath and continuing\n");
        } else {
          fatal = true;
          e.printStackTrace();
        }
      }
    }// end while
    try {
      conn.close();
    } catch (Throwable e) {
      e.printStackTrace();
    }
    System.out.println("Thread finished: " + thread_id);
  }

  static synchronized void checkrowcount(Connection conn)
  throws java.lang.Exception {
    int x = Datatypes.get_table_count(conn);
    if (x == -1) { // count timed itself out
      System.out.println("table count timed out");
    } else {
      System.out.println("rowcount by select: " + x
          + " client rowcount = " + rowcount);
      changerowcount(x - rowcount);
    }
    conn.commit();
  }

  static public Connection mystartJBMS() throws Throwable {
    Connection conn = null;
    if (startByIJ == true) {
      conn = ij.startJBMS();
    } else
      try {
        conn = DriverManager.getConnection(dbURL + ";create=false");
        conn.setAutoCommit(false);
        conn.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
      } catch (SQLException se) {
        System.out.println("connect failed  for " + dbURL);
        JDBCDisplayUtil.ShowException(System.out, se);
      }
      return (conn);
  }

  static synchronized void compress(Connection conn)
  throws java.lang.Exception {
    System.out.println("compressing table");
    boolean autocom = conn.getAutoCommit();
    try {
      conn.setAutoCommit(true);
      CallableStatement cs = conn.prepareCall(
        "CALL SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE(?, ?, ?, ?, ?)");
      cs.setString(1, "APP");
      cs.setString(2, "DATATYPES");
      cs.setShort(3, (short) 1);
      cs.setShort(4, (short) 1);
      cs.setShort(5, (short) 1);
      cs.execute();
      cs.close();
    } catch (SQLException se) {
      System.out.println("compress table: FAIL -- unexpected exception:");
      JDBCDisplayUtil.ShowException(System.out, se);
      se.printStackTrace();
    }
    conn.setAutoCommit(autocom);
  }
}
TOP

Related Classes of org.apache.derbyTesting.system.sttest.Sttest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.