■ ミュートとその解除
# ミュート(消音) amixer set Master off # ミュート解除(音を出す) amixer set Master on
参考文献
http://www.st.itc.keio.ac.jp/ja/faq_linux_audio_mute_st.html■ 音声ファイル再生
aplay 【音声ファイル】aplay test.wav
# ミュート(消音) amixer set Master off # ミュート解除(音を出す) amixer set Master on
aplay test.wav
[1] インデックス [2] ユニークインデックス [3] 複合インデックス [4] 部分インデックス ... 何バイト目までをインデックス対象とするかを指定。最大「255」まで指定。
[A] CREATE TABLE テーブル名(カラム名1 型1,カラム名2 型2, ... INDEX(カラム名1); [B] CREATE INDEX インデックス名 ON テーブル名(カラム名1, カラム名2, ...); [C] ALTER TABLE テーブル名 ADD INDEX(カラム名);
CREATE TABLE `employee` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `employee_no` VARCHAR(10) NOT NULL, `first_name` VARCHAR(50) NULL DEFAULT NULL, `family_name` VARCHAR(50) NULL DEFAULT NULL, `sex` CHAR(1) NULL DEFAULT NULL, `birth_date` DATE NOT NULL, `position_type` CHAR(1) NOT NULL, `remarks` VARCHAR(200) NULL DEFAULT NULL, PRIMARY KEY (`id`), INDEX(`birth_date`) -- ★ ) COMMENT='従業員' COLLATE='utf8_general_ci' ENGINE=InnoDB;[B] CREATE INDEX インデックス名 ON テーブル名(カラム名1, カラム名2, ...);
CREATE INDEX `position_type_INDEX` ON `employee`(`position_type`); -- ★複合インデックス★ CREATE INDEX `full_name_INDEX` ON `employee`(`first_name`, `family_name`);[C] ALTER TABLE テーブル名 ADD INDEX(カラム名);
-- ★ユニークインデックス★ ALTER TABLE `employee` ADD UNIQUE INDEX(`employee_no`); -- ★部分インデックス★(指定したカラムの20バイト目までをインデックス対象とする) ALTER TABLE `employee` ADD INDEX(`remarks`(20));
[a] DROP INDEX インデックス名 ON テーブル名;
-- [a] DROP INDEX インデックス名 ON テーブル名; DROP INDEX `birth_date_INDEX` ON `employee`;
[i] SHOW INDEX FROM [データベース名.]テーブル名; [ii] SHOW INDEX FROM テーブル名 FROM データベース名;
-- [i] SHOW INDEX FROM [データベース名.]テーブル名; SHOW INDEX FROM employee; -- [ii] SHOW INDEX FROM テーブル名 FROM データベース名; SHOW INDEX FROM employee FROM sampledb;
* EXPLAINステートメントを使用する
* SQLの実行計画に関する情報を取得するためのステートメント * 見方は、以下のサイトを参照のこと。https://qiita.com/joji/items/35ba09cf2bf2fecb2269
EXPLAIN SELECT * FROM employee AS e WHERE e.birth_date BETWEEN '1980-01-01' AND '1989-12-31';
の続き。 今回は、音声認識の精度を上げるために、 音声認識キットを使って、ルールベースの認識を行う。
yomiファイル == 変換(yomi2voca.pl) ==> vocaファイル | dfaファイル | == コンパイル(mkdfa.pl) ==> term ファイル | dict ファイル grammar ファイル
【1】読みファイル作成 (yomi ファイル) 【2】読みファイルを語彙ファイル (voca ファイル)に変換 【3】文法ファイル作成(grammar ファイル) 【4】コンパイル
ねぇ ねぇ ハロー はろー ラズパイ らずぱい
iconv -f utf8 -t eucjp ~/sample.yomi | yomi2voca.pl | iconv -f eucjp -t utf8 | ~/sample.voca
* 構文制約を行うための grammar ファイルを作成sample.grammar
S : NS_B CALL NAME NS_E
まだ未完成。。。ソースも滅茶苦茶。。。
-- DB CREATE DATABASE sampledb01; CREATE DATABASE sampledb02; CREATE DATABASE sampledb03; -- Table CREATE TABLE sampledb01.person(id INT NOT NULL AUTO_INCREMENT, name VARCHAR(20), birthdate DATE, PRIMARY KEY (`id`)); CREATE TABLE sampledb02.person(id INT NOT NULL AUTO_INCREMENT, name VARCHAR(20), birthdate DATE, PRIMARY KEY (`id`)); CREATE TABLE sampledb03.person(id INT NOT NULL AUTO_INCREMENT, name VARCHAR(20), birthdate DATE, PRIMARY KEY (`id`)); -- Sample Data INSERT INTO sampledb01.person (`name`, `birthdate`) VALUES ('Mike', '2018-01-01'); INSERT INTO sampledb01.person (`name`, `birthdate`) VALUES ('Tom', '2018-01-02'); INSERT INTO sampledb01.person (`name`, `birthdate`) VALUES ('Kevin', '2018-01-03'); INSERT INTO sampledb02.person (`name`, `birthdate`) VALUES ('Kim', '2018-02-01'); INSERT INTO sampledb02.person (`name`, `birthdate`) VALUES ('Ken', '2018-02-02'); INSERT INTO sampledb02.person (`name`, `birthdate`) VALUES ('Chan', '2018-02-03'); INSERT INTO sampledb03.person (`name`, `birthdate`) VALUES ('Ichiro', '2018-03-01'); INSERT INTO sampledb03.person (`name`, `birthdate`) VALUES ('Giro', '2018-03-02'); INSERT INTO sampledb03.person (`name`, `birthdate`) VALUES ('Taro', '2018-03-03'); INSERT INTO sampledb03.person (`name`, `birthdate`) VALUES ('Saburo', '2018-03-04');
import java.io.Closeable; import com.zaxxer.hikari.HikariDataSource; public class MultiDataSource implements Closeable { private HikariDataSource dataSource; public MultiDataSource(String dbUrl) { // 接続 this.dataSource = new HikariDataSource(); } public void setDbDataSource(HikariDataSource dataSource) { this.dataSource.setDataSource(dataSource); } @Override public void close() { if (this.dataSource != null) { this.dataSource.close(); } } public HikariDataSource getDataSource() { return this.dataSource; } }DbDataSourceFactory.java
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; public class DbDataSourceFactory { public static HikariDataSource createDbConfig(String dbUrl) { HikariConfig config = new HikariConfig(); // MySQL用ドライバを設定 config.setDriverClassName("com.mysql.jdbc.Driver"); // URL指定 config.setJdbcUrl(dbUrl); // ユーザ名、パスワード指定 config.addDataSourceProperty("user", "root"); config.addDataSourceProperty("password", "password"); // キャッシュ系の設定(任意) config.addDataSourceProperty("cachePrepStmts", "true"); config.addDataSourceProperty("prepStmtCacheSize", "250"); config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); // サーバサイドプリペアードステートメントを使用する(任意) config.addDataSourceProperty("useServerPrepStmts", "true"); // 接続をテストするためのクエリ config.setConnectionInitSql("SELECT 1"); return new HikariDataSource(config); } }MaltiDbDemo.java
import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import com.zaxxer.hikari.HikariDataSource; public class MaltiDbDemo { public static void main(String[] args) { try (MultiDataSource dataSource = new MultiDataSource("jdbc:mysql://localhost:3306/sampledb01?useSSL=false");) { String[] dbUrls = new String[] { "jdbc:mysql://localhost:3306/sampledb01?useSSL=false", "jdbc:mysql://localhost:3306/sampledb02?useSSL=false", "jdbc:mysql://localhost:3306/sampledb03?useSSL=false" }; for (String dbUrl : dbUrls) { System.out.println("DB Url : " + dbUrl); HikariDataSource dbDataSource = DbDataSourceFactory.createDbConfig(dbUrl); dataSource.setDbDataSource(dbDataSource); try (Connection connection = dataSource.getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("select * from person");) { while (resultSet.next()) { System.out.println("Id:" + resultSet.getString("id") + " Name:" + resultSet.getString("name") + resultSet.getString("birthdate")); } System.out.println("***************"); } catch (SQLException ex) { ex.printStackTrace(); } } } } }出力結果
DB Url : jdbc:mysql://localhost:3306/sampledb01?useSSL=false [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting... [main] INFO com.zaxxer.hikari.pool.PoolBase - HikariPool-1 - Driver does not support get/set network timeout for connections. (com.mysql.jdbc.JDBC4Connection.getNetworkTimeout()I) [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed. [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Starting... [main] INFO com.zaxxer.hikari.pool.PoolBase - HikariPool-2 - Driver does not support get/set network timeout for connections. (com.mysql.jdbc.JDBC4Connection.getNetworkTimeout()I) [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Start completed. Id:1 Name:Mike2018-01-01 Id:2 Name:Tom2018-01-02 Id:3 Name:Kevin2018-01-03 *************** DB Url : jdbc:mysql://localhost:3306/sampledb02?useSSL=false [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-3 - Starting... [main] INFO com.zaxxer.hikari.pool.PoolBase - HikariPool-3 - Driver does not support get/set network timeout for connections. (null) [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-3 - Start completed. [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Shutdown initiated... [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Shutdown completed. Exception in thread "main" java.lang.IllegalStateException: The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes. at com.zaxxer.hikari.HikariConfig.setDataSource(HikariConfig.java:426) at com.sample.db.dbpool.MultiDataSource.setDbDataSource(MultiDataSource.java:16) at com.sample.db.dbpool.MaltiDbDemo.main(MaltiDbDemo.java:22)
の続き。 更に、以下の関連記事で行ったOpen JTalkを組み合わせて 非ネット環境でのなんちゃってAIスピーカー的なことをやってみる。https://blogs.yahoo.co.jp/dk521123/37367963.html
* 環境作成や作り方は、以下の関連記事を参照のこと。https://blogs.yahoo.co.jp/dk521123/37451114.html
% CALL ねぇ ねぇ ハロー はろー % NAME ラズパイ らずぱい % ASK 何時 なんじ 何日 なんにち % NS_B [s] silB % NS_E [s] silE
S : NS_B CALL NAME NS_E S : NS_B ASK NS_E
* 以下の関連記事を参照のこと。https://blogs.yahoo.co.jp/dk521123/37367963.html
#!/bin/sh # -module : juliusをモジュールモードで実行 julius -C ~/julius-4.4.2/julius-kits/grammar-kit-4.3.1/hmm_mono.jconf -input mic -gram hello_raspi -module > /dev/null & #プロセスIDを出力 echo $! sleep 2
# coding:utf-8 #! /usr/bin/env phython3 import os import socket import subprocess import time import datetime import openJTalk julius_host = '127.0.0.1' julius_port = 10500 has_recongized = False def process_query(sentence): global has_recongized if has_recongized == False: if sentence in ["ねぇラズパイ", "ハローラズパイ"]: print ("Tell me, Ras-pi") openJTalk.openJTalk("御用でしょうか?") has_recongized = True else: if sentence in ["ねぇラズパイ", "ハローラズパイ"]: print ("Hey Ras-pi") openJTalk.openJTalk("はい") elif sentence == "何時": print ("What time?") openJTalk.openJTalk(datetime.datetime.strptime(datetime.datetime.today(), '%H時%M分') + "です") elif sentence == "何日": print ("What date?") openJTalk.openJTalk(datetime.datetime.strptime(datetime.datetime.today(), '%Y年%m月%d日') + "です") else: print ("do not understand...") openJTalk.openJTalk("すみません。良く分かりません。") # Main関数 def main(): # julius起動スクリプトを実行 process = subprocess.Popen(["./start-julius.sh"], stdout=subprocess.PIPE, shell=True) # juliusのプロセスIDを取得 pid = str(process.stdout.read().decode('utf-8')) # 3秒間スリープ time.sleep(3) client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # サーバモードで起動したjuliusに接続 client.connect((julius_host, julius_port)) try: data = '' sentence ='' while 1: if '</RECOGOUT>\n.' in data: word = "" for line in data.split('\n'): index = line.find('WORD="') if index != -1: line = line[index + 6:line.find('"', index + 6)] word += str(line) if word == '[s]': sentence += word print ('"' + sentence + '"') process_query(sentence) sentence ='' data = '' print ("<<<please speak>>>") else: data += str(client.recv(1024).decode('utf-8')) except KeyboardInterrupt: # 起動スクリプトのプロセスを終了 process.kill() subprocess.call(["kill " + pid], shell=True)# juliusのプロセスを終了する。 client.close() if __name__ == "__main__": main()
JDBC URL(例えば「jdbc:mysql://localhost:3306/sampledb」)を、 ホスト、ポート、DB名などのようにパースしたい。 はじめ、以下の関連記事にある正規表現でパースすることを考えた。https://blogs.yahoo.co.jp/dk521123/36604177.html
しかし、以下のサイトの回答をみたところ、もっと楽に実装できそうなので、 実装を試みるhttps://stackoverflow.com/questions/9287052/how-to-parse-a-jdbc-url-to-get-hostname-port-etc?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
import java.net.URI; public class Main { public static void main(String[] args) { try { String url = "jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8"; String cleanURI = url.substring(5); // 「jdbc:」を差っ引く URI uri = URI.create(cleanURI); System.out.println("Scheme : " + uri.getScheme()); System.out.println("Host : " + uri.getHost()); System.out.println("Port : " + uri.getPort()); System.out.println("Authority : " + uri.getAuthority()); System.out.println("RawAuthority : " + uri.getRawAuthority()); System.out.println("Fragment : " + uri.getFragment()); System.out.println("RawFragment : " + uri.getRawFragment()); System.out.println("Path : " + uri.getPath()); System.out.println("RawPath : " + uri.getRawPath()); System.out.println("Query : " + uri.getQuery()); System.out.println("RawQuery : " + uri.getRawQuery()); System.out.println("SchemeSpecificPart : " + uri.getSchemeSpecificPart()); System.out.println("RawSchemeSpecificPart : " + uri.getRawSchemeSpecificPart()); System.out.println("UserInfo : " + uri.getUserInfo()); System.out.println("RawUserInfo : " + uri.getRawUserInfo()); } catch (Exception ex) { ex.printStackTrace(); } } }出力結果
Scheme : mysql Host : localhost Port : 3306 Authority : localhost:3306 RawAuthority : localhost:3306 Fragment : null RawFragment : null Path : /sampledb01 RawPath : /sampledb01 Query : useSSL=false&characterEncoding=UTF-8 RawQuery : useSSL=false&characterEncoding=UTF-8 SchemeSpecificPart : //localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8 RawSchemeSpecificPart : //localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8 UserInfo : null RawUserInfo : null
* MySQL用のパースを作成 * その他のDBは、自分でカスタマイズする必要がありそうhttp://www.codejava.net/java-se/jdbc/jdbc-database-connection-url-for-common-databases
import java.net.URI; import java.text.MessageFormat; public class JdbcUrl { private static int DEFAULT_PORT = 3306; private String db; private String dbHost; private int dbPort; private String dbName; private String dbQuery; private JdbcUrl(String db, String dbHost, int dbPort, String dbName, String dbQuery) { this.db = db; this.dbHost = dbHost; this.dbPort = dbPort; this.dbName = dbName; this.dbQuery = dbQuery; } public static JdbcUrl parse(String url) { if (url == null) { throw new IllegalArgumentException("null"); } String cleanUri = url.substring(5); URI uri = URI.create(cleanUri); return new JdbcUrl(uri.getScheme(), uri.getHost(), uri.getPort(), uri.getPath().replaceAll("/", ""), uri.getQuery()); } public String getDb() { return this.db; } public String getDbHost() { return this.dbHost; } public int getDbPort() { if (this.dbPort == -1) { return DEFAULT_PORT; } return this.dbPort; } public String getDbPortString() { return String.valueOf(this.getDbPort()); } public String getDbName() { return this.dbName; } public String getDbQuery() { return this.dbQuery; } @Override public String toString() { if (this.getDbQuery() == null) { return MessageFormat.format("jdbc:{0}://{1}:{2}/{3}", this.getDb(), this.getDbHost(), this.getDbPortString(), this.getDbName()); } else { return MessageFormat.format("jdbc:{0}://{1}:{2}/{3}?{4}", this.getDb(), this.getDbHost(), this.getDbPortString(), this.getDbName(), this.getDbQuery()); } } }
public class Main { public static void main(String[] args) { try { JdbcUrl jdbcUrl1 = JdbcUrl.parse("jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8"); print(jdbcUrl1); JdbcUrl jdbcUrl2 = JdbcUrl.parse("jdbc:mysql://127.0.0.1:13306/sampledb02"); print(jdbcUrl2); JdbcUrl jdbcUrl3 = JdbcUrl.parse("jdbc:mysql://sample.co.jp/sampledb03"); print(jdbcUrl3); } catch (Exception ex) { ex.printStackTrace(); } } private static void print(JdbcUrl jdbcUrl) { System.out.println(jdbcUrl.getDbHost()); System.out.println(jdbcUrl.getDbPort()); System.out.println(jdbcUrl.getDbName()); System.out.println(jdbcUrl.getDbQuery()); System.out.println(jdbcUrl.toString()); System.out.println("**************************"); } }出力結果
localhost 3306 sampledb01 useSSL=false&characterEncoding=UTF-8 jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8 ************************** 127.0.0.1 13306 sampledb02 null jdbc:mysql://127.0.0.1:13306/sampledb02 ************************** sample.co.jp 3306 sampledb03 null jdbc:mysql://sample.co.jp:3306/sampledb03 **************************
* python実行後、以下「エラー内容」が表示される
Error: failed to bind socket failed to begin input stream
* ポート「10500」を掴んでいるプロセスがいる解決案
# ポート10500のPIDを探す sudo netstat -anp | grep 10500 tcp 0 0 0.0.0.0:10500 0.0.0.0:* LISTEN 1821/julius # kill -9 【PID】でプロセスをキルする kill -9 1821
* str(client.recv(1024).decode('utf-8'))で読み取り時に、以下のエラー内容が表示される
Traceback (most recent call last): File "hello_raspi.py", line 99, in <module> main() File "hello_raspi.py", line 89, in main data += str(client.recv(1024).decode('utf-8')) UnicodeEncodeError: 'ascii' codec can't encode characters in position 360-362: ordinal not in range(128)
* Pythonの文字コードを utf-8 に設定する。 => sitecustomize.py に utf-8 を設定確認方法
$ python Python 2.7.13 (default, Jan 19 2017, 14:48:08) [GCC 6.3.0 20170124] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.getdefaultencoding() 'ascii' << これを utf-8 に変更する必要がある >>> exit();
# 念のため、バックアップ sudo cp /usr/lib/python2.7/sitecustomize.py /usr/lib/python2.7/sitecustomize.py.orig sudo vi /usr/lib/python2.7/sitecustomize.py -=[全面的に書き換え]-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= import sys sys.setdefaultencoding('utf-8') -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= $ python >>> import sys >>> sys.getdefaultencoding() 'utf-8' << utf-8 に変更されたことを確認 >>> exit();
SELECT * FROM user LIMIT 5出力結果
"1" "1" "Kim" "1983-12-11" "2" "1" "Mike" "2018-02-02" "3" "1" "Sam" "1922-12-30" "4" "1" "Smith" "2006-07-14" "5" "1" "Nancy" "2003-08-19"
-- テーブル作成 CREATE TABLE IF NOT EXISTS `user` ( `id` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, `user_category` INT(11) DEFAULT 1, `name` VARCHAR(20) NULL DEFAULT NULL, `birthdate` DATE NULL DEFAULT NULL ) COLLATE='utf8_general_ci' ENGINE=InnoDB; -- テストデータ(REPLACE構文:ユニーク値が重複した場合、古いレコードを削除し、新しいレコードを挿入) REPLACE INTO `user` (`id`, `user_category`, `name`, `birthdate`) VALUES (1, 1, 'Kim', '1983-12-11'), (2, 1, 'Mike', '2018-02-02'), (3, 1, 'Sam', '1922-12-30'), (4, 1, 'Smith', '2006-07-14'), (5, 1, 'Nancy', '2003-08-19'), (6, 1, 'Kachy', '2001-12-01'), (7, 2, 'Ken', '1936-05-10'), (8, 2, 'Coco', '1979-04-02'), (9, 2, 'Tom', '1999-03-17'), (10, 2, 'Son', '2000-09-22'), (11, 2, 'Tommy', '1929-05-02'), (12, 3, 'Carry', '1892-11-23'), (13, 3, 'Chan', '1977-11-03');
* 「SQL_CALC_FOUND_ROWS」と「FOUND_ROWS()」を使う公式サイト
SELECT SQL_CALC_FOUND_ROWS * FROM user LIMIT 5; 5行データが出力(略) SELECT FOUND_ROWS(); 13
CREATE TABLE `person` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(50) NULL DEFAULT NULL, `sex` CHAR(1) NULL DEFAULT 'f', `birth_date` DATE NOT NULL, `createdate` DATETIME NULL DEFAULT CURRENT_TIMESTAMP, `updatedate` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX(`name`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
* PreparedStatement.addBatch() / executeBatch() を使う => PreparedStatement.addBatch() で貯めて、PreparedStatement.executeBatch()で実行するhttps://docs.oracle.com/javase/jp/8/docs/api/java/sql/PreparedStatement.html
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class InsertDemo { private final static String URL = "jdbc:mysql://localhost:3306/sampledb01?useSSL=false&characterEncoding=UTF-8"; private final static String USERNAME = "root"; private final static String PASSWORD = "password"; private final static String SQL = "INSERT INTO person(name, sex, birth_date) VALUES (?, ?, ?);"; public static void main(String[] args) { String[][] samplePeople = { { "Mike", "m", "2001-01-09" }, { "Tom", "m", "1982-11-29" }, { "Smith", "m", "1976-03-14" }, { "Ken", "m", "1982-11-29" }, { "Naomi", "f", "1962-06-11" }, { "Sam", "m", "1982-01-30" }, { "Amy", "f", "1933-09-23" }, { "Cathy", "f", "1921-07-12" }, { "Bob", "m", "1956-12-29" }, { "Tommy", "m", "1999-02-21" }, }; System.out.println("Start"); long start = System.currentTimeMillis(); try (Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);) { try (PreparedStatement preparedStatement = connection.prepareStatement(SQL);) { connection.setAutoCommit(false); for (int i = 0; i < samplePeople.length; i++) { preparedStatement.setString(1, samplePeople[i][0]); preparedStatement.setString(2, samplePeople[i][1]); preparedStatement.setString(3, samplePeople[i][2]); preparedStatement.addBatch(); System.out.println(preparedStatement.toString()); } int[] result = preparedStatement.executeBatch(); System.out.println("Count : " + result.length); connection.commit(); } catch (SQLException ex) { ex.printStackTrace(); connection.rollback(); } } catch (SQLException ex) { ex.printStackTrace(); } finally { long end = System.currentTimeMillis(); System.out.println("[Done]" + (end - start)); } } }出力結果
Start com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Mike', 'm', '2001-01-09'); com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Tom', 'm', '1982-11-29'); com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Smith', 'm', '1976-03-14'); com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Ken', 'm', '1982-11-29'); com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Naomi', 'f', '1962-06-11'); com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Sam', 'm', '1982-01-30'); com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Amy', 'f', '1933-09-23'); com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Cathy', 'f', '1921-07-12'); com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Bob', 'm', '1956-12-29'); com.mysql.jdbc.JDBC42PreparedStatement@45ff54e6: INSERT INTO person(name, sex, birth_date) VALUES ('Tommy', 'm', '1999-02-21'); Count : 10 [Done]431
* 以下の「System Rules」を使うと実現可能。http://stefanbirkner.github.io/system-rules/
に記載。今回は、Gradleを使う。
dependencies { // Use JUnit test framework testImplementation 'junit:junit:4.12' // System Rules testCompile 'com.github.stefanbirkner:system-rules:1.17.0' }
import static org.junit.Assert.*; import org.junit.Rule; import org.junit.Test; import org.junit.contrib.java.lang.system.EnvironmentVariables; public class SampleTest { @Rule public final EnvironmentVariables environmentVariables = new EnvironmentVariables(); @Test public void test() { environmentVariables.set("ENV_KEY", "dummy01"); assertEquals("dummy01", System.getenv("ENV_KEY")); } }
* 環境変数を設定したら、別のテストメソッドにも反映される(以下の「サンプル」参照)
import static org.junit.Assert.*; import org.junit.Test; import org.junit.contrib.java.lang.system.EnvironmentVariables; public class SampleTest { @Test public void test1() { EnvironmentVariables environmentVariables = new EnvironmentVariables(); environmentVariables.set("ENV_KEY", "dummy01"); assertEquals("dummy01", System.getenv("ENV_KEY")); } @Test public void test2() { assertNull(System.getenv("ENV_KEY")); // ★エラー★(test1()で設定した値「dummy01」が返ってくる) } }
* PowerMockito で行うことができることもネットでは書いてあるが、 エラー「MissingMethodInvocationException」になった
* 以下の通り。(足りない点があるかもしれないが...)build.gradle
dependencies { // PowerMockito testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.7.3' testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '1.7.3' }JUnitコード
import static org.junit.Assert.*; import org.junit.Test; import org.powermock.api.mockito.PowerMockito; public class SampleTest { @Test public void test() { PowerMockito.mockStatic(System.class); PowerMockito.when(System.getenv("ENV_KEY")).thenReturn("dummy01"); assertEquals("dummy01", System.getenv("ENV_KEY")); } }エラー内容
org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. For example: when(mock.getArticles()).thenReturn(articles); Also, this error might show up because: 1. you stub either of: final/private/equals()/hashCode() methods. Those methods *cannot* be stubbed/verified. Mocking methods declared on non-public parent classes is not supported. 2. inside when() you don't call method on mock but on some other object. at com.sample.db.SampleTest.test(SampleTest.java:13) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)https://stackoverflow.com/questions/8168884/how-to-test-code-dependent-on-environment-variables-using-junit?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
より抜粋 ~~~~~ when(System.getenv("FOO_VAR_1")).thenReturn("test-foo-var-1") causes org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. error – Andremoniy Oct 24 '17 at 13:14 ~~~~~ 同じ現象...
* Gradleを使う
dependencies { // Use JUnit test framework testImplementation 'junit:junit:4.12' // SubEthaMail testCompile group: 'org.subethamail', name: 'subethasmtp', version: '3.1.7' // JavaMail(以下の「サンプル」を実行したい場合は、以下のコメントを外す) //compile group: 'com.sun.mail', name: 'javax.mail', version: '1.6.1' }
import static org.junit.Assert.*; import java.io.IOException; import java.util.Arrays; import java.util.List; import javax.mail.MessagingException; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.subethamail.wiser.Wiser; import org.subethamail.wiser.WiserMessage; import com.sample.mails.EmailHandler; public class SampleTest { private static Wiser wiser; private final static String HOSTNAME = "localhost"; private final static Integer PORT = 12500; @BeforeClass public static void setUpBeforeClass() throws Exception { // メールサーバを立てる wiser = new Wiser(); wiser.setPort(PORT); wiser.setHostname(HOSTNAME); wiser.start(); } @AfterClass public static void tearDownAfterClass() throws Exception { // メールサーバを落とす wiser.stop(); } @Test public void test() throws MessagingException { final String expectTo = "to@sample.co.jp"; final String expectFrom = "from@sample.co.jp"; final String expectSubject = "タイトルです。"; final String expectBody = "メール本文です。\\r\\n以上です。"; EmailHandler target = new EmailHandler(); target.setHost(HOSTNAME); target.setPort(PORT.toString()); target.setToAddresses(Arrays.asList(expectTo)); target.setFromAddress(expectFrom); target.setMailSubject(expectSubject); target.setMailBody(expectBody); target.send(); // メール内容を検査 List<WiserMessage> messages = wiser.getMessages(); for (WiserMessage wiserMessage : messages) { assertEquals(expectFrom, wiserMessage.getEnvelopeSender()); assertEquals(expectTo, wiserMessage.getEnvelopeReceiver()); try { assertEquals(expectSubject, wiserMessage.getMimeMessage().getSubject()); } catch (MessagingException e) { fail("題名が取得できない"); } try { assertEquals(expectBody, wiserMessage.getMimeMessage().getContent()); } catch (MessagingException | IOException e) { fail("本文が取得できない"); } } } }
import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; public class EmailHandler { private final static String DEFAULT_TIMEOUT = "10000"; private final static String DEFAULT_HOST = "localhost"; private final static String DEFAULT_POST = "25"; private String fromAddress; private List<String> toAddresses; private String mailSubject; private String mailBody; private String host; private String port; private String timeout; private boolean isOnDebugMode; /** * Default Contractor. */ public EmailHandler() { this.fromAddress = null; this.toAddresses = new ArrayList<>(); this.mailSubject = null; this.mailBody = null; this.host = DEFAULT_HOST; this.port = DEFAULT_POST; this.timeout = DEFAULT_TIMEOUT; this.isOnDebugMode = false; } public void setFromAddress(String fromAddress) { this.fromAddress = fromAddress; } public void setToAddresses(List<String> toAddresses) { this.toAddresses = toAddresses; } public void addToAddress(String toAddress) { this.toAddresses.add(toAddress); } public void setMailSubject(String mailSubject) { this.mailSubject = mailSubject; } public void setMailBody(String mailBody) { this.mailBody = mailBody; } public void setHost(String host) { this.host = host; } public void setPort(String port) { this.port = port; } public void setOnDebugMode(boolean isOnDebugMode) { this.isOnDebugMode = isOnDebugMode; } public void send() throws MessagingException { if (this.toAddresses == null || this.host == null) { throw new InvalidParameterException(); } Properties props = new Properties(); props.put("mail.smtp.host", this.host); props.put("mail.smtp.port", this.port); props.put("mail.debug", this.isOnDebugMode); props.put("mail.smtp.connectiontimeout", this.timeout); props.put("mail.smtp.timeout", this.timeout); Session session = Session.getInstance(props, null); Message mimeMessage = new MimeMessage(session); mimeMessage.setFrom(this.toInternetAddress(this.fromAddress)); InternetAddress[] addresses = this.toInternetAddresses(this.toAddresses); mimeMessage.setRecipients(Message.RecipientType.TO, addresses); mimeMessage.setSubject(this.mailSubject); mimeMessage.setSentDate(new Date()); mimeMessage.setText(this.mailBody); Transport.send(mimeMessage); } private InternetAddress[] toInternetAddresses(List<String> addresses) throws AddressException { InternetAddress[] returnValues = new InternetAddress[addresses.size()]; int index = 0; for (String address : addresses) { returnValues[index] = this.toInternetAddress(address); index++; } return returnValues; } private InternetAddress toInternetAddress(String address) throws AddressException { return new InternetAddress(address); } /** * 【使用例】 * * @param args */ public static void main(String[] args) { try { EmailHandler email = new EmailHandler(); email.setFromAddress("sample@yahoo.com"); email.addToAddress("sample@gmail.com"); email.setMailSubject("タイトルです。"); email.setMailBody("メール本文です。\r\n以上です。"); email.setOnDebugMode(true); email.send(); } catch (Exception ex) { ex.printStackTrace(); } } }
* Tomcatのログを見たら、Tomcat終了時に以下の「エラー内容」が表示された
SEVERE: A web application registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
* OS : CentOS7 * Tomcat : Tomcat8.5 * Java :JDK1.8
* システム終了後(※)に、以下の「サンプル」の処理(DriverManager.deregisterDriver())を行うサンプル
Enumeration<Driver> drivers = DriverManager.getDrivers(); while (drivers.hasMoreElements()) { Driver driver = drivers.nextElement(); try { DriverManager.deregisterDriver(driver); System.out.println(String.format("deregistering jdbc driver: %s", driver)); } catch (SQLException ex) { System.out.println(String.format("Error deregistering driver %s", driver)); ex.printStackTrace(); } }
Tomcatであれば、ServletContextListener.contextDestroyed 内で行う。 Webサービスのシステム終了のイベントについては、以下の関連記事を参照のこと。JAX-WS / Metro
* 【1】とは、別のシステムの単体試験時に、以下の「エラー内容」が表示された * 単体テストクラスには、3つのテストメソッドがあり、結果は以下の通り。 + 1つ目は、問題なし + 2・3つ目のメソッドは、以下の「エラー内容」 * ネットにある「JDBCドライバがない」「Class.forName()を呼び出す」「DBのURLの指定が誤っている」は 調査した結果、問題なかった(仮にこれらが原因の場合、1つのメソッドが問題なかった説明ができない) ~~~~~~~ // ダメだった @Before public void setUp() throws Exception { Class.forName("com.mysql.jdbc.Driver"); } ~~~~~~~
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/dbname
* OS : CentOS7 * Java :JDK1.8 * JUnit : JUnit4
* 【1】の「解決案」のコードを1つ目の最後に呼び出され、 以降の単体試験に影響してしまっていた。
* JUnitの場合、@AfterClassのタイミングで、【1】の「解決案」のコードを呼び出すようにする ~~~~~~~ @AfterClass public static void tearDownAfterClass() throws Exception { // このタイミングで、【1】の「解決案」のコードを呼び出すようにする } ~~~~~~~
で扱った ansible の続き。 おおよその流れは、以下の通り。 [1] ゲストOS(管理マシン) から ゲストOS(構築サーバ) にssh通信できるようにする [2] ゲストOS(管理マシン)にansible をインストールする [3] (Hello World的なこととして)ゲストOS(構築サーバ)にApacheをインストール
* 作業OS : Windows10 * 仮想環境 : VirtualBox v5.2.8 * ゲストOS(管理マシン) : CentOS7 (IP : 192.168.56.1) * ゲストOS(構築サーバ) : CentOS7 (IP : 192.168.56.2) <= 管理対象
* VirtualBoxおよびゲストOS(CentOS7)のインストールは行っているものとする => それぞれの作業自体は、以下の関連記事を参照のこと。VirtualBox
+--------------+ +--------------+ | 管理マシン | | 構築サーバ | | CentOS7 | | CentOS7 | | 192.168.56.1 | | 192.168.56.2 | | | | | | Ansible | | Apache | +--------------+ +--------------+ +-------------------------------+ | VirtualBox | +-------------------------------+ | Windows10 | +-------------------------------+
/home/【ユーザ名】 + helloworld + hosts ... インベントリファイル(管理対象(構築サーバ)のネットワーク情報を定義) + main.yml ... プレイブック(設定内容(ここではApache)を定義)main.yml の内容
1) yumでlibselinux-pythonのインストール(SELinux対策) 2) yumでApacheのインストール 3) Apache起動と自動起動化 4) ファイアウォールでHTTP/SSLをあける 5) Apacheの起動確認
[a] 「Oracle VM VirtualBox マネージャー」を立ち上げて、 「ゲストOS(管理マシン)」を右クリックし、「設定」を選択 [b] 設定画面において、[ネットワーク]-[アダプター2]を選択し、 以下を設定し、「OK」ボタン押下 + ネットワークアダプターを有効化:チェック入れる + 割り当て:内部ネットワーク + 名前:intnet[1-2] ゲストOS のネットワーク設定
を参考。 [a] 以下のコマンドで、 NetworkManager Text User Interfaceを立ち上げる ~~~~~~ sudo nmtui ~~~~~~ [b] [Edit a connection]-[enp0s8(文字化けしている可能性あり)]を選択 [c] 以下を設定し、<OK>押下。。 + IPv4 CONFIGURATION : <Manual> + Addresses : 192.168.56.【1~255の任意値】/24(ここでは、「192.168.56.1/24」) [d] <Back>押下。<Quit>押下。 [e] 以下のコマンドで、 NetworkManager Text User Interfaceを再起動 ~~~~~~ sudo systemctl restart NetworkManager ~~~~~~[1-3] 「ゲストOS(構築サーバ)」に対しても、[1-1]~[1-2]を行う
IPアドレスは、ここでは、「192.168.56.2/24」にする。
sudo yum install epel-release -y sudo yum install ansible -y # 確認1:バージョン確認 ansible --version # 確認2:[WARNING]が2つほどでるが、エラーがでなければOK ansible localhost -m ping
* [3-1]は必須ではないが、[3-1] 構築サーバから、以下のコマンドで、ansible用の実行ユーザ作成
# sudo useradd 【任意のユーザ名】で、ansible用の実行ユーザ作成 sudo useradd ansible # sudo passwd 【任意のユーザ名】で、ansible用の実行ユーザのパスワードを設定 sudo passwd ansible # パスワードを設定 # 実行ユーザのsudo権限付与(「 #!!ADD!!」を追記) sudo visudo -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # Defaults specification Defaults:ansible !requiretty #!!ADD!! root ALL=(ALL) ALL ansible ALL=(ALL) NOPASSWD:ALL #!!ADD!! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[3-2] 管理サーバから、以下のコマンドでSSH接続できるか確認する
sudo ssh -l ansible 192.168.56.2
mkdir -p ~/helloworld cd ~/helloworld vi hosts -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= [localhost] 192.168.56.12 [all:vars] ansible_ssh_user=ansible ansible_ssh_pass=password -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[4-2] プレイブック「main.yml」を作成する
vi main.yml -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - hosts: all become: yes tasks: - name: Install libselinux-python yum: name=libselinux-python state=present - name: Install Apache yum: name=httpd state=latest - name: Start Apache service: name=httpd state=started enabled=yes - name: firewall-cmd allow Apachei(HTTP) firewalld: service=http permanent=true state=enabled immediate=true - name: firewall-cmd allow Apache(SSL) firewalld: service=https permanent=true state=enabled immediate=true - name: Check to start Apache shell: ps aux | grep httpd register: ps_result changed_when: false - debug: var=ps_result.stdout_lines when: ps_result | success -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=[4-3] プレイブックを実行
ansible-playbook -i hosts main.yml
# Apacheサービスの状態確認 sudo systemctl status httpd # curlでの確認 (GUIであればブラウザからアクセスでもいい) curl http://localhost[5-2] 管理サーバから、以下のコマンドを実行する
# curlでの確認 (GUIであればブラウザからアクセスでもいい) curl hhttp://192.168.56.12
* テストを実行した際に、以下の「エラー内容」が表示される
org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. For example: when(mock.getArticles()).thenReturn(articles); Also, this error might show up because: 1. you stub either of: final/private/equals()/hashCode() methods. Those methods *cannot* be stubbed/verified. Mocking methods declared on non-public parent classes is not supported. 2. inside when() you don't call method on mock but on some other object. at com.sample.SampleTest.test(SampleTest.java:12) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)
import static org.junit.Assert.*; import org.junit.Test; import org.powermock.api.mockito.PowerMockito; public class SampleTest { @Test public void test() { PowerMockito.mockStatic(System.class); PowerMockito.when(System.getenv("ENV_KEY")).thenReturn("dummy01"); assertEquals("dummy01", System.getenv("ENV_KEY")); } }
* クラスの頭に「@RunWith」「@PrepareForTest」を追記する ~~~~ @RunWith(PowerMockRunner.class) // ★重要★ @PrepareForTest({System.class}) // ★重要★ public class SampleTest { // ...略... ~~~~ 詳細のサンプルは、以下の関連記事を参照のこと。https://blogs.yahoo.co.jp/dk521123/37484564.html
* Gradleを使う
dependencies { // PowerMock testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.7.3' testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '1.7.3' }
* Calendar.getInstance()をモック化する
import java.util.Calendar; import java.util.Date; public class DateUtil { public static Date getCurrentDate() { // 内部で、Calendar.getInstance()を呼んでいる Calendar calendar = Calendar.getInstance(); return calendar.getTime(); } }
import static org.junit.Assert.*; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) // ★重要★ @PrepareForTest({Calendar.class, DateUtil.class}) // ★重要★ public class DateUtilTest { @Test public void getCurrentDateTest() { Calendar mockCalendar = Calendar.getInstance(); mockCalendar.set(2018, 1, 9, 22, 20, 9); mockCalendar.set(Calendar.MILLISECOND, 0); PowerMockito.mockStatic(Calendar.class); PowerMockito.when(Calendar.getInstance()).thenReturn(mockCalendar); Date result = DateUtil.getCurrentDate(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); System.out.println("Date : " + simpleDateFormat.format(result)); assertEquals("2018/02/09 22:20:09", simpleDateFormat.format(result)); } }
* 環境変数の取得 System.getenv()をモック化する * 以下の関連記事「JUnit で環境変数を変更するテストを行うには...」で行ったことを PowerMock を使って行うhttps://blogs.yahoo.co.jp/dk521123/37474828.html
import static org.junit.Assert.*; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) // ★重要★ @PrepareForTest({System.class}) // ★重要★ public class SampleTest { @Test public void test() { PowerMockito.mockStatic(System.class); PowerMockito.when(System.getenv("ENV_KEY")).thenReturn("dummy01"); assertEquals("dummy01", System.getenv("ENV_KEY")); } }
[1] Docker のインストール [2] Docker の起動及び自動起動
sudo yum -y update sudo yum -y install docker docker --version # 「Docker version 1.13.1, build 774336d/1.13.1」が表示
# ★起動 sudo systemctl start docker # 確認1 sudo systemctl status docker # 確認2 sudo docker search centos | more # ★自動起動 sudo systemctl enable docker # 確認1 sudo systemctl is-enabled docker
# image検索 sudo docker search centos | more # image取得 sudo docker pull centos # 取得したimage一覧表示 sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos latest e934aafc2206 3 days ago 199 MB # imageの詳細設定表示 sudo docker inspect e934aafc2206 # image削除(rmi = remove image) sudo docker rmi e934aafc2206
# Container作成 (Container上で「echo "Hello World"」を実行) sudo docker run centos echo "Hello World" # 実行中のContainer一覧表示 sudo docker ps # Container一覧表示(実行完了後を表示。「Exited (0)」は正常終了) sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3c38d46e852d centos "echo 'Hello World'" 5 minutes ago Exited (0) 5 minutes ago gallant_yonath # Container一覧表示(実行完了後の最新3履歴を表示) sudo docker ps -a -n=3 # Container削除(「sudo docker ps -a」で確認するとなくなっているはず) sudo docker rm 3c38d46e852d
CREATE TABLE `message` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `message_text` TEXT NULL, PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
INSERT INTO `message` (`id`, `message_text`) VALUES (1, 'Thank you for your attention.'); INSERT INTO `message` (`id`, `message_text`) VALUES (2, 'Thank you for asking'); INSERT INTO `message` (`id`, `message_text`) VALUES (3, 'Sorry to be late.'); INSERT INTO `message` (`id`, `message_text`) VALUES (4, 'Thank you for your advise.'); INSERT INTO `message` (`id`, `message_text`) VALUES (5, 'Sorry...');
* テーブルのBOOL(BIT)項目に対して、GROUP BYした後に論理演算 OR をしたかったので調べてみた
* BIT_OR() ってのがある公式サイト
* トイレ掃除チェックリストで考える。 => 一日中のうち、一回でもダメ(NG=true)だったらアウト
-- トイレ掃除チェックリスト CREATE TABLE `toilet_clean_checklist` ( `check_datetime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'チェック日時', `ng` BIT(1) NOT NULL DEFAULT b'0' COMMENT 'NG:ダメだったら 1(true)', `inspector` VARCHAR(10) NULL DEFAULT NULL COMMENT 'チェックした人' ) ENGINE=InnoDB ;
REPLACE INTO `toilet_clean_checklist` (`check_datetime`, `ng`, `inspector`) VALUES ('2018-04-10 09:30:37', b'0', 'Mike'), ('2018-04-10 17:31:08', b'0', 'Tom'), ('2018-04-10 21:31:29', b'0', 'Sam'), ('2018-04-11 08:21:52', b'0', 'Mike'), ('2018-04-11 11:12:34', b'0', 'Tom'), ('2018-04-11 21:33:35', b'1', 'Sam'), ('2018-04-12 08:33:48', b'1', 'Tom'), ('2018-04-12 11:12:17', b'1', 'Mike');データ表示
check_datetime | ng | inspector -------------------+----+----------- 2018-04-10 09:30:37| 0 | Mike 2018-04-10 17:31:08| 0 | Tom 2018-04-10 21:31:29| 0 | Sam ------------------------------------- 2018-04-11 08:21:52| 0 | Mike 2018-04-11 11:12:34| 0 | Tom 2018-04-11 21:33:35| 1 | Sam ------------------------------------- 2018-04-12 08:33:48| 1 | Tom 2018-04-12 11:12:17| 1 | Mike