/** * personium.io * Copyright 2014 FUJITSU LIMITED * * Licensed 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 com.fujitsu.dc.test.jersey.bar; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.http.HttpHeaders; import org.apache.http.HttpStatus; import org.json.simple.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fujitsu.dc.core.model.progress.ProgressInfo; import com.fujitsu.dc.test.jersey.AbstractCase; import com.fujitsu.dc.test.jersey.DcResponse; import com.fujitsu.dc.test.jersey.ODataCommon; import com.fujitsu.dc.test.setup.Setup; import com.fujitsu.dc.test.utils.Http; import com.fujitsu.dc.test.utils.TResponse; /** * barファイルインストールテスト用ユーティリティクラス. */ public class BarInstallTestUtils { private static final int SIZE_KB = 1024; private static final int READ_BUFFER_SIZE = 4096 * SIZE_KB; /** * ログ用オブジェクト. */ private static Logger log = LoggerFactory.getLogger(BarInstallTestUtils.class); /** * Barインストール対象. */ public static final String INSTALL_TARGET = "installBox"; /** * Barインストール時のタイムアウト(分). */ public static final long BAR_INSTALL_TIMEOUT = 5 * 60 * 1000; // 5分以上かかってしまう場合はエラーとする /** * Barインストール時の問い合わせ間隔(秒). */ public static final long BAR_INSTALL_SLEEP_TIME = 3 * 1000; // 2秒 /** * constructor. */ private BarInstallTestUtils() { } /** * barファイルを読み込む. * @param barFile barファイルのパス * @return 読み込んだbarファイル */ public static byte[] readBarFile(File barFile) { InputStream is = ClassLoader.getSystemResourceAsStream(barFile.getPath()); ByteBuffer buff = ByteBuffer.allocate(READ_BUFFER_SIZE); log.debug(String.valueOf(buff.capacity())); try { byte[] bbuf = new byte[SIZE_KB]; int size; while ((size = is.read(bbuf)) != -1) { buff.put(bbuf, 0, size); } } catch (IOException e) { throw new RuntimeException("failed to load bar file:" + barFile.getPath(), e); } finally { try { is.close(); } catch (IOException e) { throw new RuntimeException("failed to close bar file:" + barFile.getPath(), e); } } int size = buff.position(); buff.flip(); byte[] retv = new byte[size]; buff.get(retv, 0, size); return retv; } /** * barインストール用リクエストを投入する. * @param requestFile Barファイルのパス名 * @param cellName requestCellName * @param path リクエストパス * @param headers 追加のリクエストヘッダ * @param body ボディ * @return レスポンス */ public static TResponse request( String requestFile, String cellName, String path, Map<String, String> headers, byte[] body) { return request(AbstractCase.MASTER_TOKEN_NAME, requestFile, cellName, path, headers, body); } /** * barインストール用リクエストを投入する. * @param token アクセストークン * @param requestFile Barファイルのパス名 * @param cellName requestCellName * @param path リクエストパス * @param headers 追加のリクエストヘッダ * @param body ボディ * @return レスポンス */ public static TResponse request( String token, String requestFile, String cellName, String path, Map<String, String> headers, byte[] body) { Http client = Http.request(requestFile) .with("cellPath", cellName) .with("path", path) .with("token", "Bearer " + token); String contType = headers.get(HttpHeaders.CONTENT_TYPE); if (contType != null) { client = client.with("contType", contType); } String contLength = headers.get(HttpHeaders.CONTENT_LENGTH); if (contLength != null) { client = client.with("contLength", contLength); } String overrideMethod = headers.get("X-HTTP-Method-Override"); if (overrideMethod != null) { client = client.with("method", overrideMethod); } TResponse res = client.setBodyBinary(body) .returns() .debug(); return res; } /** * ボディのリストを取得する. * @param body ボディ文字列 * @return リスト化されたボディ */ public static List<String[]> getListedBody(String body) { assertNotNull(body); List<String[]> list = new ArrayList<String[]>(); String[] lines = body.split("\n"); for (String line : lines) { String[] fields = line.replaceAll("\"", "").split(","); list.add(fields); } return list; } /** * Collection DELETEの実行. * @param colName コレクション名 */ public static void deleteCollection(final String colName) { // Boxの削除 Http.request("box/delete-box-col.txt") .with("cellPath", Setup.TEST_CELL1) .with("box", INSTALL_TARGET) .with("path", colName) .with("token", AbstractCase.MASTER_TOKEN_NAME) .returns() .statusCode(-1) .debug(); } /** * Collection PROPFINDの実行. * @param cell セル名 * @param box ボックス名 * @param path 対象のコレクション名 * @param depth Depthヘッダの値 * @param token 認証用のトークン * @param sc 期待するレスポンスコード * @return TResponse PROPFINDの結果 */ public static TResponse propfind(final String cell, final String box, final String path, final String depth, final String token, final int sc) { return Http.request("box/propfind-col.txt") .with("path", path) .with("depth", depth) .with("token", token) .with("cell", cell) .with("box", box) .returns() .statusCode(sc); } /** * Collection PROPFINDの実行. * @param cell セル名 * @param box ボックス名 * @param path 対象のコレクション名 * @param token 認証用のトークン * @param sc 期待するレスポンスコード * @return TResponse PROPFINDの結果 */ public static TResponse propfind(final String cell, final String box, final String path, final String token, final int sc) { return propfind(cell, box, path, "1", token, sc); } /** * barファイルインストール(非同期)の完了まで待ってからステータスを検証する. * @param location barファイルインストール状況確認APIのURL * @param schemaUrl スキーマURL * @param status 期待するステータス */ public static void assertBarInstallStatus(String location, String schemaUrl, ProgressInfo.STATUS status) { waitBoxInstallCompleted(location); DcResponse res = ODataCommon.getOdataResource(location); assertEquals(HttpStatus.SC_OK, res.getStatusCode()); JSONObject bodyJson = (JSONObject) ((JSONObject) res.bodyAsJson()); assertEquals(status.value(), bodyJson.get("status")); assertEquals(schemaUrl, bodyJson.get("schema")); if (ProgressInfo.STATUS.FAILED == status) { assertNotNull(bodyJson.get("started_at")); assertNull(bodyJson.get("installed_at")); assertNotNull(bodyJson.get("progress")); assertNotNull(bodyJson.get("message")); assertNotNull(((JSONObject) bodyJson.get("message")).get("code")); assertNotNull(((JSONObject) bodyJson.get("message")).get("message")); assertNotNull(((JSONObject) ((JSONObject) bodyJson.get("message")).get("message")).get("value")); assertNotNull(((JSONObject) ((JSONObject) bodyJson.get("message")).get("message")).get("lang")); } else { assertNull(bodyJson.get("started_at")); assertNotNull(bodyJson.get("installed_at")); assertNull(bodyJson.get("progress")); } } /** * Boxインストールの完了を待つ. * @param location Location */ public static void waitBoxInstallCompleted(String location) { DcResponse response = null; JSONObject bodyJson = null; long startTime = System.currentTimeMillis(); while (true) { response = ODataCommon.getOdataResource(location); if (HttpStatus.SC_OK == response.getStatusCode()) { bodyJson = (JSONObject) ((JSONObject) response.bodyAsJson()); if (!ProgressInfo.STATUS.PROCESSING.value().equals(bodyJson.get("status"))) { return; } assertNull(bodyJson.get("installed_at")); assertNotNull(bodyJson.get("progress")); assertNotNull(bodyJson.get("started_at")); } if (System.currentTimeMillis() - startTime > BAR_INSTALL_TIMEOUT) { fail("Failed to bar file install: takes too much time. [" + BAR_INSTALL_TIMEOUT + "millis]"); } try { Thread.sleep(BAR_INSTALL_SLEEP_TIME); } catch (InterruptedException e) { log.info("Interrupted: " + e.getMessage()); } } } /** * Boxインストールの進行状況を取得する. * @param cellName セル名 * @param path 進行状況を取得するBox名 * @param token 認証情報(認証スキーマ付き) * @param code 期待するレスポンスコード * @return レスポンス */ public static TResponse getProgress(final String cellName, final String path, final String token, final int code) { // Boxインストールの進行状況を取得する return Http.request("bar-install-get-progress.txt") .with("cellPath", cellName) .with("path", path) .with("token", token) .returns() .statusCode(code) .debug(); } }