| /* |
| * 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.ignite.internal.processors.hadoop.impl.igfs; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FilenameFilter; |
| import java.io.InputStreamReader; |
| import java.util.ArrayList; |
| import java.util.List; |
| import org.apache.ignite.igfs.IgfsPath; |
| import org.apache.ignite.internal.igfs.common.IgfsLogger; |
| import org.apache.ignite.internal.processors.igfs.IgfsCommonAbstractTest; |
| import org.apache.ignite.internal.util.typedef.internal.SB; |
| import org.apache.ignite.internal.util.typedef.internal.U; |
| import org.junit.Test; |
| |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.DELIM_FIELD; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.DELIM_FIELD_VAL; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.HDR; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_CLOSE_IN; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_CLOSE_OUT; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_DELETE; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_DIR_LIST; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_DIR_MAKE; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_MARK; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_OPEN_IN; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_OPEN_OUT; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_RANDOM_READ; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_RENAME; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_RESET; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_SEEK; |
| import static org.apache.ignite.internal.igfs.common.IgfsLogger.TYPE_SKIP; |
| |
| /** |
| * Grid IGFS client logger test. |
| */ |
| public class IgniteHadoopFileSystemLoggerSelfTest extends IgfsCommonAbstractTest { |
| /** Path string. */ |
| private static final String PATH_STR = "/dir1/dir2/file;test"; |
| |
| /** Path string with escaped semicolons. */ |
| private static final String PATH_STR_ESCAPED = PATH_STR.replace(';', '~'); |
| |
| /** Path. */ |
| private static final IgfsPath PATH = new IgfsPath(PATH_STR); |
| |
| /** IGFS name. */ |
| private static final String IGFS_NAME = "igfs"; |
| |
| /** Log file path. */ |
| private static final String LOG_DIR = U.getIgniteHome(); |
| |
| /** Endpoint address. */ |
| private static final String ENDPOINT = "localhost:10500"; |
| |
| /** Log file name. */ |
| private static final String LOG_FILE = LOG_DIR + File.separator + "igfs-log-" + IGFS_NAME + "-" + U.jvmPid() + |
| ".csv"; |
| |
| /** {@inheritDoc} */ |
| @Override protected void beforeTestsStarted() throws Exception { |
| removeLogs(); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override protected void afterTest() throws Exception { |
| removeLogs(); |
| } |
| |
| /** |
| * Remove existing logs. |
| * |
| * @throws Exception If failed. |
| */ |
| private void removeLogs() throws Exception { |
| File dir = new File(LOG_DIR); |
| |
| File[] logs = dir.listFiles(new FilenameFilter() { |
| @Override public boolean accept(File dir, String name) { |
| return name.startsWith("igfs-log-"); |
| } |
| }); |
| |
| for (File log : logs) |
| log.delete(); |
| } |
| |
| /** |
| * Ensure correct static loggers creation/removal as well as file creation. |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testCreateDelete() throws Exception { |
| IgfsLogger log = IgfsLogger.logger(ENDPOINT, IGFS_NAME, LOG_DIR, 10); |
| |
| IgfsLogger sameLog0 = IgfsLogger.logger(ENDPOINT, IGFS_NAME, LOG_DIR, 10); |
| |
| // Loggers for the same endpoint must be the same object. |
| assert log == sameLog0; |
| |
| IgfsLogger otherLog = IgfsLogger.logger("other" + ENDPOINT, IGFS_NAME, LOG_DIR, 10); |
| |
| // Logger for another endpoint must be different. |
| assert log != otherLog; |
| |
| otherLog.close(); |
| |
| log.logDelete(PATH, false); |
| |
| log.close(); |
| |
| File logFile = new File(LOG_FILE); |
| |
| // When there are multiple loggers, closing one must not force flushing. |
| assert !logFile.exists(); |
| |
| IgfsLogger sameLog1 = IgfsLogger.logger(ENDPOINT, IGFS_NAME, LOG_DIR, 10); |
| |
| assert sameLog0 == sameLog1; |
| |
| sameLog0.close(); |
| |
| assert !logFile.exists(); |
| |
| sameLog1.close(); |
| |
| // When we cloe the last logger, it must flush data to disk. |
| assert logFile.exists(); |
| |
| logFile.delete(); |
| |
| IgfsLogger sameLog2 = IgfsLogger.logger(ENDPOINT, IGFS_NAME, LOG_DIR, 10); |
| |
| // This time we expect new logger instance to be created. |
| assert sameLog0 != sameLog2; |
| |
| sameLog2.close(); |
| |
| // As we do not add any records to the logger, we do not expect flushing. |
| assert !logFile.exists(); |
| } |
| |
| /** |
| * Test read operations logging. |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testLogRead() throws Exception { |
| IgfsLogger log = IgfsLogger.logger(ENDPOINT, IGFS_NAME, LOG_DIR, 10); |
| |
| log.logOpen(1, PATH, 2, 3L); |
| log.logRandomRead(1, 4L, 5); |
| log.logSeek(1, 6L); |
| log.logSkip(1, 7L); |
| log.logMark(1, 8L); |
| log.logReset(1); |
| log.logCloseIn(1, 9L, 10L, 11); |
| |
| log.close(); |
| |
| checkLog( |
| new SB().a(U.jvmPid() + d() + TYPE_OPEN_IN + d() + PATH_STR_ESCAPED + d() + d() + 1 + d() + 2 + |
| d() + 3 + d(14)).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_RANDOM_READ + d(3) + 1 + d(7) + 4 + d() + 5 + d(8)).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_SEEK + d(3) + 1 + d(7) + 6 + d(9)).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_SKIP + d(3) + 1 + d(9) + 7 + d(7)).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_MARK + d(3) + 1 + d(10) + 8 + d(6)).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_RESET + d(3) + 1 + d(16)).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_CLOSE_IN + d(3) + 1 + d(11) + 9 + d() + 10 + d() + 11 + d(3)).toString() |
| ); |
| } |
| |
| /** |
| * Test write operations logging. |
| * |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testLogWrite() throws Exception { |
| IgfsLogger log = IgfsLogger.logger(ENDPOINT, IGFS_NAME, LOG_DIR, 10); |
| |
| log.logCreate(1, PATH, true, 2, new Integer(3).shortValue(), 4L); |
| log.logAppend(2, PATH, 8); |
| log.logCloseOut(2, 9L, 10L, 11); |
| |
| log.close(); |
| |
| checkLog( |
| new SB().a(U.jvmPid() + d() + TYPE_OPEN_OUT + d() + PATH_STR_ESCAPED + d() + d() + 1 + d() + |
| 2 + d(2) + 0 + d() + 1 + d() + 3 + d() + 4 + d(10)).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_OPEN_OUT + d() + PATH_STR_ESCAPED + d() + d() + 2 + d() + |
| 8 + d(2) + 1 + d(13)).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_CLOSE_OUT + d(3) + 2 + d(11) + 9 + d() + 10 + d() + 11 + d(3)) |
| .toString() |
| ); |
| } |
| |
| /** |
| * Test miscellaneous operations logging. |
| * |
| * @throws Exception If failed. |
| */ |
| @SuppressWarnings("TooBroadScope") |
| @Test |
| public void testLogMisc() throws Exception { |
| IgfsLogger log = IgfsLogger.logger(ENDPOINT, IGFS_NAME, LOG_DIR, 10); |
| |
| String newFile = "/dir3/file.test"; |
| String file1 = "/dir3/file1.test"; |
| String file2 = "/dir3/file1.test"; |
| |
| log.logMakeDirectory(PATH); |
| log.logRename(PATH, new IgfsPath(newFile)); |
| log.logListDirectory(PATH, new String[] { file1, file2 }); |
| log.logDelete(PATH, false); |
| |
| log.close(); |
| |
| checkLog( |
| new SB().a(U.jvmPid() + d() + TYPE_DIR_MAKE + d() + PATH_STR_ESCAPED + d() + d(17)).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_RENAME + d() + PATH_STR_ESCAPED + d() + d(15) + newFile + |
| d(2)).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_DIR_LIST + d() + PATH_STR_ESCAPED + d() + d(17) + file1 + |
| DELIM_FIELD_VAL + file2).toString(), |
| new SB().a(U.jvmPid() + d() + TYPE_DELETE + d(1) + PATH_STR_ESCAPED + d() + d(16) + 0 + |
| d()).toString() |
| ); |
| } |
| |
| /** |
| * Ensure that log file has only the following lines. |
| * |
| * @param lines Expected lines. |
| * @throws Exception If failed. |
| */ |
| private void checkLog(String... lines) throws Exception { |
| BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(LOG_FILE))); |
| |
| List<String> logLines = new ArrayList<>(lines.length); |
| |
| String nextLogLine; |
| |
| while ((nextLogLine = br.readLine()) != null) |
| logLines.add(nextLogLine); |
| |
| U.closeQuiet(br); |
| |
| assertEquals(lines.length + 1, logLines.size()); |
| |
| assertEquals(logLines.get(0), HDR); |
| |
| for (int i = 0; i < lines.length; i++) { |
| String logLine = logLines.get(i + 1); |
| |
| logLine = logLine.substring(logLine.indexOf(DELIM_FIELD, logLine.indexOf(DELIM_FIELD) + 1) + 1); |
| |
| assertEquals(lines[i], logLine); |
| } |
| } |
| |
| /** |
| * Return single field delimiter. |
| * |
| * @return Single field delimiter. |
| */ |
| private String d() { |
| return d(1); |
| } |
| |
| /** |
| * Return a bunch of field delimiters. |
| * |
| * @param cnt Amount of field delimiters. |
| * @return Field delimiters. |
| */ |
| private String d(int cnt) { |
| SB buf = new SB(); |
| |
| for (int i = 0; i < cnt; i++) |
| buf.a(DELIM_FIELD); |
| |
| return buf.toString(); |
| } |
| } |