Package org.jscsi.scsi.tasks.lu

Source Code of org.jscsi.scsi.tasks.lu.ModeSenseTaskTest$ModeSenseException

/**
* Copyright (c) 2012, University of Konstanz, Distributed Systems Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the University of Konstanz nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//Cleversafe open-source code header - Version 1.1 - December 1, 2006
//
//Cleversafe Dispersed Storage(TM) is software for secure, private and
//reliable storage of the world's data using information dispersal.
//
//Copyright (C) 2005-2007 Cleversafe, Inc.
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
//USA.
//
//Contact Information:
// Cleversafe, 10 W. 35th Street, 16th Floor #84,
// Chicago IL 60616
// email: licensing@cleversafe.org
//
//END-OF-HEADER
//-----------------------
//@author: John Quigley <jquigley@cleversafe.com>
//@date: January 1, 2008
//---------------------

package org.jscsi.scsi.tasks.lu;

import static org.junit.Assert.fail;

import java.io.DataInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.jscsi.core.scsi.Status;
import org.jscsi.scsi.protocol.Command;
import org.jscsi.scsi.protocol.cdb.CDB;
import org.jscsi.scsi.protocol.cdb.ModeSense6;
import org.jscsi.scsi.protocol.inquiry.InquiryDataRegistry;
import org.jscsi.scsi.protocol.inquiry.StaticInquiryDataRegistry;
import org.jscsi.scsi.protocol.mode.ModePage;
import org.jscsi.scsi.protocol.mode.ModePageRegistry;
import org.jscsi.scsi.protocol.mode.StaticModePageRegistry;
import org.jscsi.scsi.protocol.sense.KCQ;
import org.jscsi.scsi.protocol.sense.SenseData;
import org.jscsi.scsi.protocol.sense.SenseDataFactory;
import org.jscsi.scsi.protocol.util.ByteBufferInputStream;
import org.jscsi.scsi.tasks.Task;
import org.jscsi.scsi.tasks.TaskAttribute;
import org.jscsi.scsi.tasks.management.AbstractTaskSetTest.TestTargetTransportPort;
import org.jscsi.scsi.transport.Nexus;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

//TODO: Describe class or interface
public class ModeSenseTaskTest
{
   private static Logger _logger = Logger.getLogger(ModeSenseTaskTest.class);

   public static class ModeSenseException extends Exception
   {
      private static final long serialVersionUID = -7600550897640999759L;

      private static Logger _logger = Logger.getLogger(ModeSenseException.class);

      private Status status;
      private ByteBuffer senseData;

      public ModeSenseException(Status status, ByteBuffer senseData)
      {
         super("ModeSenseTask returned bad status: " + status.name());
         _logger.error("ModeSenseTask returned bad status: " + status.name());
         this.status = status;
         this.senseData = senseData;
      }

      public ModeSenseException(String message)
      {
         super(message);
         _logger.error(message);
         status = null;
         senseData = null;
      }

      public Status getStatus()
      {
         return status;
      }

      public ByteBuffer getSenseData()
      {
         return senseData;
      }
   }

   @BeforeClass
   public static void setUpBeforeClass() throws Exception
   {
   }

   @AfterClass
   public static void tearDownAfterClass() throws Exception
   {
   }

   @Before
   public void setUp() throws Exception
   {
   }

   @After
   public void tearDown() throws Exception
   {
   }

   private Collection<ModePage> execute6(ModePageRegistry registry, byte pageCode, int subPageCode)
         throws ModeSenseException
   {
      // We allocate 200 bytes for return data
      CDB cdb = new ModeSense6(true, 0, pageCode, subPageCode, 200);

      TestTargetTransportPort port = new TestTargetTransportPort(null, false);
      Command command =
            new Command(new Nexus("initiator", "target", 0, 0), cdb, TaskAttribute.SIMPLE, 0, 0);
      InquiryDataRegistry inqreg = new StaticInquiryDataRegistry();

      _logger.debug("Creating ModeSenseTask from MODE SENSE (6) command");
      Task task = new ModeSenseTask(port, command, registry, inqreg);
      _logger.debug("Running mode sense task");
      task.run();

      if (port.getLastStatus() != Status.GOOD)
      {
         throw new ModeSenseException(port.getLastStatus(), port.getSenseData());
      }

      ByteBuffer data = port.getTransferData();
      if (data == null)
      {
         throw new ModeSenseException("ModeSenseTask returned null");
      }

      try
      {
         DataInputStream in = new DataInputStream(new ByteBufferInputStream(data));

         int modeDataLength = in.readUnsignedByte();
         int mediumType = in.readUnsignedByte();
         in.readUnsignedByte(); // skip DEVICE-SPECIFIC PARAMETER
         int blockDescriptorLength = in.readUnsignedByte();

         if (mediumType != 0x00)
            throw new ModeSenseException("medium type value invalid (expected 0x00, got "
                  + mediumType + ")");

         // TODO: Check device specific parameter

         if (blockDescriptorLength != 0)
            throw new ModeSenseException("block descriptor length non-zero");

         if (data.limit() != modeDataLength + 1)
            throw new ModeSenseException("improper amount of data returned, header says "
                  + modeDataLength + " + 1 bytes, buffer contains " + data.limit());

         List<ModePage> pages = new LinkedList<ModePage>();

         while (data.position() < data.limit())
         {
            try
            {
               pages.add(registry.decode(data));
            }
            catch (IOException e)
            {
               throw new ModeSenseException("Could not decode one or more mode pages: "
                     + e.getMessage());
            }
         }

         return pages;

      }
      catch (IOException e)
      {
         throw new ModeSenseException("Error decoding return data: " + e.getMessage());
      }

   }

   private void matches(ModePage page, byte pageCode, int subPageCode)
   {
      if (page.getPageCode() == pageCode && page.getSubPageCode() == subPageCode)
         return;
      else
         fail(String.format("Mode page does not match: expected (%X,%X), found (%X,%X)", pageCode,
               subPageCode, page.getPageCode(), page.getSubPageCode()));
   }

   public void checkErrorCondition(ModeSenseException exception)
   {
      if (exception.getStatus() == null || exception.getStatus() != Status.CHECK_CONDITION)
         fail("Expected task to return CHECK CONDITION; got "
               + (exception.getStatus() != null ? exception.getStatus().name() : "null"));

      if (exception.getSenseData() == null)
         fail("Task returned CHECK CONDITION but did not return autosense data");

      try
      {
         SenseDataFactory fact = new SenseDataFactory();
         SenseData sense = fact.decode(exception.getSenseData());
         if (sense.getKCQ() != KCQ.INVALID_FIELD_IN_CDB)
            fail("Expected KCQ INVALID FIELD IN CDB; got " + sense.getKCQ().name());
      }
      catch (IOException e)
      {
         fail("Could not decode returned sense data: " + e.getMessage());
      }
   }

   @Test
   public void testRequestAllModePages()
   {
      try
      {
         ModePageRegistry registry = new StaticModePageRegistry();

         Collection<ModePage> pages = execute6(registry, (byte) 0x3F, 0xFF);
         Iterator<ModePage> it = pages.iterator();

         matches(it.next(), (byte) 0x01, 0x00);
         matches(it.next(), (byte) 0x08, 0x00);
         matches(it.next(), (byte) 0x0A, 0x00);
         matches(it.next(), (byte) 0x0A, 0x01);
         matches(it.next(), (byte) 0x1C, 0x00);
      }
      catch (ModeSenseException e)
      {
         fail(e.getMessage());
      }
   }

   @Test
   public void testRequestAllPage0ModePages()
   {
      try
      {
         ModePageRegistry registry = new StaticModePageRegistry();

         Collection<ModePage> pages = execute6(registry, (byte) 0x3F, 0x00);
         Iterator<ModePage> it = pages.iterator();

         matches(it.next(), (byte) 0x01, 0x00);
         matches(it.next(), (byte) 0x08, 0x00);
         matches(it.next(), (byte) 0x0A, 0x00);
         matches(it.next(), (byte) 0x1C, 0x00);
      }
      catch (ModeSenseException e)
      {
         fail(e.getMessage());
      }
   }

   @Test
   public void testRequestInvalidModePage()
   {
      try
      {
         ModePageRegistry registry = new StaticModePageRegistry();

         execute6(registry, (byte) 0x80, 0x00);
         fail("MODE SENSE request succeeded unexpectedly");
      }
      catch (ModeSenseException e)
      {
         checkErrorCondition(e);
      }
   }

   @Test
   public void testRequestValidModePage()
   {
      try
      {
         ModePageRegistry registry = new StaticModePageRegistry();

         Collection<ModePage> pages = execute6(registry, (byte) 0x08, 0x00);
         Iterator<ModePage> it = pages.iterator();

         matches(it.next(), (byte) 0x08, 0x00);

         pages = execute6(registry, (byte) 0x0A, 0x01);
         it = pages.iterator();

         matches(it.next(), (byte) 0x0A, 0x01);
      }
      catch (ModeSenseException e)
      {
         fail(e.getMessage());
      }
   }

}
TOP

Related Classes of org.jscsi.scsi.tasks.lu.ModeSenseTaskTest$ModeSenseException

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.