/* * Copyright (c) 2008-2015 by Christoph Kleineweber, * Zuse Institute Berlin * * Licensed under the BSD License, see LICENSE file for details. * */ package org.xtreemfs.test.osd; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.xtreemfs.common.libxtreemfs.*; import org.xtreemfs.foundation.logging.Logging; import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC; import org.xtreemfs.osd.tracing.TraceInfo; import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes; import org.xtreemfs.pbrpc.generatedinterfaces.MRC; import org.xtreemfs.test.TestEnvironment; import org.xtreemfs.test.TestHelper; import java.io.*; import java.net.Socket; import java.util.concurrent.atomic.AtomicLong; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * @author Christoph Kleineweber <kleineweber@zib.de> */ public class TracingTest { @Rule public final TestRule testLog = TestHelper.testLog; private TestEnvironment env; private Client client; private RPC.UserCredentials uc; private RPC.Auth auth = RPCAuthentication.authNone; private final String SOURCE_VOLUME = "traceSource"; private final String FILE_BASED_TRACING_POLICY = "6001"; private final String SOCKET_BASED_TRACING_POLICY = "6002"; private final String FILE_BASED_TRACING_CONFIG = "/tmp/XtreemFS-Log-" + System.currentTimeMillis(); private final int SOCKET_BASED_TRACING_PORT = 9999; private final String TEST_FILE ="/test"; private final int MAX_WRITES = 100; private AtomicLong tracedLines; @Before public void setUp() throws Exception { deleteTraceFile(); Logging.start(Logging.LEVEL_ERROR, Logging.Category.all); env = new TestEnvironment(new TestEnvironment.Services[]{TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.DIR_SERVICE, TestEnvironment.Services.MRC, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD}); env.start(); uc = RPC.UserCredentials.newBuilder().setUsername("service") .addGroups("service").build(); client = ClientFactory.createClient(env.getDIRAddress().getHostName() + ":" + env.getDIRAddress().getPort(), uc, null, new Options()); client.start(true); } @After public void tearDown() throws Exception { client.shutdown(); env.shutdown(); deleteTraceFile(); } private void deleteTraceFile() { File f = new File(FILE_BASED_TRACING_CONFIG); if (f.exists()) { f.delete(); } } private void writeFile(Volume volume) throws IOException { FileHandle f = volume.openFile(uc, TEST_FILE, GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() | GlobalTypes.SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_WRONLY.getNumber()); byte[] writeBuffer = new byte[256]; for (long i=0; i<=MAX_WRITES; i++) f.write(uc, writeBuffer, writeBuffer.length, i * writeBuffer.length); f.close(); volume.unlink(uc, TEST_FILE); client.deleteVolume(auth, uc, SOURCE_VOLUME); } private Volume createVolume(String tracingPolicy, String tracingPolicyConfig, boolean useStriping) throws IOException { client.createVolume(env.getMRCAddress().getHostName() + ":" + env.getMRCAddress().getPort(), auth, uc, SOURCE_VOLUME); Volume volume = client.openVolume(SOURCE_VOLUME, null, new Options()); volume.setXAttr(uc, auth, "/", "xtreemfs.tracing_enabled", "1", MRC.XATTR_FLAGS.XATTR_FLAGS_CREATE); if(tracingPolicyConfig != null) { volume.setXAttr(uc, auth, "/", "xtreemfs.tracing_policy_config", tracingPolicyConfig, MRC.XATTR_FLAGS.XATTR_FLAGS_CREATE); } if(tracingPolicy != null) { volume.setXAttr(uc, auth, "/", "xtreemfs.tracing_policy", tracingPolicy, MRC.XATTR_FLAGS.XATTR_FLAGS_CREATE); } if(useStriping) { volume.setXAttr(uc, auth, "/", "xtreemfs.default_sp", "{\"pattern\":\"STRIPING_POLICY_RAID0\",\"width\":3,\"size\":128}", MRC.XATTR_FLAGS.XATTR_FLAGS_REPLACE); } return volume; } private void checkTraceFile() throws IOException { File traceFile = new File(FILE_BASED_TRACING_CONFIG); assertTrue(traceFile.exists()); int lines = 0; FileInputStream fstream = new FileInputStream(traceFile); BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); String line; while ((line = br.readLine()) != null) { System.out.println(line); lines++; } assertTrue(lines >= MAX_WRITES); } @Test public void testFileBasedTracing() throws Exception { Volume sourceVolume = createVolume(FILE_BASED_TRACING_POLICY, FILE_BASED_TRACING_CONFIG, false); writeFile(sourceVolume); checkTraceFile(); } @Test public void testFileBasedTracingWithStriping() throws Exception { Volume sourceVolume = createVolume(FILE_BASED_TRACING_POLICY, FILE_BASED_TRACING_CONFIG, true); String dsp = sourceVolume.getXAttr(uc, "/", "xtreemfs.default_sp"); assertTrue(dsp.contains("3")); writeFile(sourceVolume); checkTraceFile(); } @Test public void testSocketBasedTracing() throws Exception { tracedLines = new AtomicLong(); Runnable reader = new Runnable() { @Override public void run() { try { String line; Thread.sleep(1000); Socket s = new Socket("localhost", SOCKET_BASED_TRACING_PORT); BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); while((line = in.readLine()) != null) { System.out.println(line); if(!line.equals("")) tracedLines.incrementAndGet(); try { TraceInfo traceInfo = new TraceInfo(line); assertTrue(traceInfo.getOperation().equals("w")); assertTrue(traceInfo.getLength() > 0); } catch (IllegalArgumentException ex) { fail(); } } s.close(); } catch(Exception ex) { System.out.println(ex.getMessage()); } } }; Thread t = new Thread(reader); t.start(); Volume sourceVolume = createVolume(SOCKET_BASED_TRACING_POLICY, null, false); writeFile(sourceVolume); Thread.sleep(1000); assertTrue(tracedLines.get() > 0L); } }