text: # 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.
  
  import fixtures
  import logging
  import testtools
  
  from diskimage_builder import block_device
  from diskimage_builder.block_device.level0 import localloop
  from diskimage_builder.logging_config import setup
  from diskimage_builder import utils as dib_utils
  
  
  # Setup Logging
  setup()
  
  
  class StateSavingBlockDevice(block_device.BlockDevice):
      def cmd_create(self):
          logging.info("StateSavingBlockDevice cmd_create()")
          super(StateSavingBlockDevice, self).cmd_create()
          _, _, self.state = self.load_state()
  
  
  class BlockDeviceFixture(fixtures.Fixture):
      def __init__(self, *args, **kwargs):
          logging.info("BlockDeviceFixture constructor")
          self.args = args
          self.kwargs = kwargs
          self.bd = None
  
      def _setUp(self):
          logging.info("BlockDeviceFixture _setUp()")
          self.bd = StateSavingBlockDevice(*self.args, **self.kwargs)
          self.addCleanup(self.cleanup_loopbacks)
  
      def _assert_loopback_detatched(self, loopback):
          if localloop.LocalLoop.loopdev_is_attached(loopback):
              localloop.LocalLoop.loopdev_detach(loopback)
  
      def cleanup_loopbacks(self):
          for lb_dev in self.bd.state.get('loopback_devices', []):
              self._assert_loopback_detatched(lb_dev)
  
  
  class TestBlockDevice(testtools.TestCase):
      def _assert_loopbacks_cleaned(self, blockdevice):
          for lb_dev in blockdevice.state.get('loopback_devices', []):
              self.assertEqual(False,
                               localloop.LocalLoop.loopdev_is_attached(lb_dev))
  
      # ToDo: This calls sudo to setup the loop device - which is not allowed.
      # Currently no idea how to continue here...
      def _DONT_test_create_default_config(self):
          logging.info("test_create_default_config called")
          builddir = self.useFixture(fixtures.TempDir()).path
          imagedir = self.useFixture(fixtures.TempDir()).path
          logging.info("builddir [%s]" % builddir)
          logging.info("imagedir [%s]" % imagedir)
  
          logging.info("Calling BlockDevice constructor")
          bd = self.useFixture(BlockDeviceFixture(
              None, builddir, '%dKiB' % (1024 * 1024), imagedir
          )).bd
          logging.info("Calling BlockDevice cmd_create()")
          bd.cmd_create()
  
          logging.info("Check result")
          logging.info("State [%s]" % bd.state)
          self.assertTrue('device' in bd.state['image0'])
          lb_dev = bd.state['image0']['device']
          # partprobe loopback so we can get partition info
          args = ['sudo', 'partprobe', lb_dev]
          subp, rval = dib_utils.await_popen_cmd(logging, args)
          self.assertEqual(0, rval)
  
          bd.cmd_cleanup()
          self._assert_loopbacks_cleaned(bd)
  