Commit 0bd3b314 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen
Browse files

Split filesystem mocks in separate files

parent c870ffc3
......@@ -24,10 +24,8 @@
#define FILESYSTEM_H
#include <string>
#include <unordered_map>
#include <memory>
#include <algorithm>
#include <cassert>
#include "filesystem/IDirectory.h"
#include "filesystem/IFile.h"
......@@ -35,355 +33,13 @@
#include "factory/IFileSystem.h"
#include "utils/Filename.h"
//REMOVE ME
#include "logging/Logger.h"
#include "mocks/filesystem/MockDevice.h"
#include "mocks/filesystem/MockDirectory.h"
#include "mocks/filesystem/MockFile.h"
namespace mock
{
class File : public fs::IFile
{
public:
File( const std::string& filePath )
: m_name( utils::file::fileName( filePath ) )
, m_path( utils::file::directory( filePath ) )
, m_fullPath( filePath )
, m_extension( utils::file::extension( filePath ) )
, m_lastModification( 0 )
{
}
File( const File& ) = default;
virtual const std::string& name() const override
{
return m_name;
}
virtual const std::string& path() const override
{
return m_path;
}
virtual const std::string& fullPath() const override
{
return m_fullPath;
}
virtual const std::string& extension() const override
{
return m_extension;
}
virtual unsigned int lastModificationDate() const override
{
return m_lastModification;
}
void markAsModified()
{
m_lastModification++;
}
std::string m_name;
std::string m_path;
std::string m_fullPath;
std::string m_extension;
unsigned int m_lastModification;
};
class Device;
class Directory : public fs::IDirectory
{
public:
Directory( const std::string& path, std::shared_ptr<Device> device )
: m_path( path )
, m_device( device )
{
if ( ( *m_path.crbegin() ) != '/' )
m_path += '/';
}
virtual const std::string& path() const override
{
return m_path;
}
virtual const std::vector<std::shared_ptr<fs::IFile>>& files() const override
{
m_filePathes.clear();
for ( auto& f : m_files )
m_filePathes.push_back( f.second );
return m_filePathes;
}
virtual const std::vector<std::shared_ptr<fs::IDirectory>>& dirs() const override
{
m_dirPathes.clear();
for ( const auto& d : m_dirs )
m_dirPathes.push_back( d.second );
return m_dirPathes;
}
virtual std::shared_ptr<fs::IDevice> device() const override
{
return std::static_pointer_cast<fs::IDevice>( m_device.lock() );
}
void addFile( const std::string& filePath )
{
auto subFolder = utils::file::firstFolder( filePath );
if ( subFolder.empty() == true )
{
m_files[filePath] = std::make_shared<File>( m_path + filePath );
}
else
{
auto it = m_dirs.find( subFolder );
assert( it != end( m_dirs ) );
auto remainingPath = utils::file::removePath( filePath, subFolder );
it->second->addFile( remainingPath );
}
}
void addFolder( const std::string& folder )
{
auto subFolder = utils::file::firstFolder( folder );
auto remainingPath = utils::file::removePath( folder, subFolder );
if ( remainingPath.empty() == true )
{
auto dir = std::make_shared<Directory>( m_path + subFolder, m_device.lock() );
m_dirs[subFolder] = dir;
}
else
{
auto it = m_dirs.find( subFolder );
assert( it != end( m_dirs ) );
it->second->addFolder( remainingPath );
}
}
void removeFile( const std::string& filePath )
{
auto subFolder = utils::file::firstFolder( filePath );
if ( subFolder.empty() == true )
{
auto it = m_files.find( filePath );
assert( it != end( m_files ) );
m_files.erase( it );
}
else
{
auto it = m_dirs.find( subFolder );
assert( it != end( m_dirs ) );
auto remainingPath = utils::file::removePath( filePath, subFolder );
it->second->removeFile( remainingPath );
}
}
std::shared_ptr<File> file( const std::string& filePath )
{
auto subFolder = utils::file::firstFolder( filePath );
if ( subFolder.empty() == true )
{
auto it = m_files.find( filePath );
assert( it != end( m_files ) );
return it->second;
}
else
{
auto it = m_dirs.find( subFolder );
assert( it != end( m_dirs ) );
auto remainingPath = utils::file::removePath( filePath, subFolder );
return it->second->file( remainingPath );
}
}
std::shared_ptr<Directory> directory( const std::string& path )
{
auto subFolder = utils::file::firstFolder( path );
auto remainingPath = utils::file::removePath( path, subFolder );
if ( remainingPath.empty() == true )
{
auto it = m_dirs.find( subFolder );
if ( it == end( m_dirs ) )
return nullptr;
return it->second;
}
else
{
auto it = m_dirs.find( subFolder );
assert( it != end( m_dirs ) );
return it->second->directory( remainingPath );
}
}
void removeFolder( const std::string& path )
{
auto subFolder = utils::file::firstFolder( path );
auto remainingPath = utils::file::removePath( path, subFolder );
if ( remainingPath.empty() == true )
{
auto it = m_dirs.find( subFolder );
assert( it != end( m_dirs ) );
m_dirs.erase( it );
}
else
{
auto it = m_dirs.find( subFolder );
assert( it != end( m_dirs ) );
it->second->removeFolder( remainingPath );
}
}
void setMountpointRoot( const std::string& path, std::shared_ptr<Directory> root )
{
auto subFolder = utils::file::firstFolder( path );
auto remainingPath = utils::file::removePath( path, subFolder );
if ( remainingPath.empty() == true )
{
m_dirs[subFolder] = root;
}
else
{
auto it = m_dirs.find( subFolder );
assert( it != end( m_dirs ) );
it->second->setMountpointRoot( remainingPath, root );
}
}
void invalidateMountpoint( const std::string& path )
{
auto subFolder = utils::file::firstFolder( path );
auto remainingPath = utils::file::removePath( path, subFolder );
if ( remainingPath.empty() == true )
{
m_dirs[subFolder] = std::make_shared<Directory>( m_path + subFolder, m_device.lock() );
}
else
{
auto it = m_dirs.find( subFolder );
assert( it != end( m_dirs ) );
it->second->invalidateMountpoint( remainingPath );
}
}
private:
std::string m_path;
std::unordered_map<std::string, std::shared_ptr<File>> m_files;
std::unordered_map<std::string, std::shared_ptr<Directory>> m_dirs;
mutable std::vector<std::shared_ptr<fs::IFile>> m_filePathes;
mutable std::vector<std::shared_ptr<fs::IDirectory>> m_dirPathes;
std::weak_ptr<Device> m_device;
};
class Device : public fs::IDevice, public std::enable_shared_from_this<Device>
{
public:
Device( const std::string& mountpoint, const std::string& uuid )
: m_uuid( uuid )
, m_removable( false )
, m_present( true )
, m_mountpoint( mountpoint )
{
if ( ( *m_mountpoint.crbegin() ) != '/' )
m_mountpoint += '/';
}
// We need at least one existing shared ptr before calling shared_from_this.
// Let the device be initialized and stored in a shared_ptr by the FileSystemFactory, and then
// initialize our fake root folder
void setupRoot()
{
m_root = std::make_shared<Directory>( m_mountpoint, shared_from_this() );
}
std::shared_ptr<Directory> root()
{
return m_root;
}
virtual const std::string& uuid() const override { return m_uuid; }
virtual bool isRemovable() const override { return m_removable; }
virtual bool isPresent() const override { return m_present; }
virtual const std::string& mountpoint() const override { return m_mountpoint; }
void setRemovable( bool value ) { m_removable = value; }
void setPresent( bool value ) { m_present = value; }
std::string relativePath( const std::string& path )
{
auto res = path.substr( m_mountpoint.length() );
while ( res[0] == '/' )
res.erase( res.begin() );
return res;
}
void addFile( const std::string& filePath )
{
m_root->addFile( relativePath( filePath ) );
}
void addFolder( const std::string& path )
{
m_root->addFolder( relativePath( path ) );
}
void removeFile( const std::string& filePath )
{
m_root->removeFile( relativePath( filePath ) );
}
void removeFolder( const std::string& filePath )
{
auto relPath = relativePath( filePath );
if ( relPath.empty() == true )
m_root = nullptr;
else
m_root->removeFolder( relPath );
}
std::shared_ptr<File> file( const std::string& filePath )
{
if ( m_root == nullptr || m_present == false )
return nullptr;
return m_root->file( relativePath( filePath ) );
}
std::shared_ptr<Directory> directory( const std::string& path )
{
if ( m_root == nullptr || m_present == false )
return nullptr;
const auto relPath = relativePath( path );
if ( relPath.empty() == true )
return m_root;
return m_root->directory( relPath );
}
void setMountpointRoot( const std::string& path, std::shared_ptr<Directory> root )
{
auto relPath = relativePath( path );
// m_root is already a mountpoint, we can't add a mountpoint to it.
assert( relPath.empty() == false );
m_root->setMountpointRoot( relPath, root );
}
void invalidateMountpoint( const std::string& path )
{
auto relPath = relativePath( path );
assert( relPath.empty() == false );
m_root->invalidateMountpoint( relPath );
}
private:
std::string m_uuid;
bool m_removable;
bool m_present;
std::string m_mountpoint;
std::shared_ptr<Directory> m_root;
};
struct FileSystemFactory : public factory::IFileSystem
{
static const std::string Root;
......
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*****************************************************************************/
#include <cassert>
#include "MockDevice.h"
#include "MockDirectory.h"
namespace mock
{
Device::Device(const std::string& mountpoint, const std::string& uuid)
: m_uuid( uuid )
, m_removable( false )
, m_present( true )
, m_mountpoint( mountpoint )
{
if ( ( *m_mountpoint.crbegin() ) != '/' )
m_mountpoint += '/';
}
void Device::setupRoot()
{
m_root = std::make_shared<Directory>( m_mountpoint, shared_from_this() );
}
std::shared_ptr<Directory> Device::root()
{
return m_root;
}
const std::string&Device::uuid() const { return m_uuid; }
bool Device::isRemovable() const { return m_removable; }
bool Device::isPresent() const { return m_present; }
const std::string&Device::mountpoint() const { return m_mountpoint; }
void Device::setRemovable(bool value) { m_removable = value; }
void Device::setPresent(bool value) { m_present = value; }
std::string Device::relativePath(const std::string& path)
{
auto res = path.substr( m_mountpoint.length() );
while ( res[0] == '/' )
res.erase( res.begin() );
return res;
}
void Device::addFile(const std::string& filePath)
{
m_root->addFile( relativePath( filePath ) );
}
void Device::addFolder(const std::string& path)
{
m_root->addFolder( relativePath( path ) );
}
void Device::removeFile(const std::string& filePath)
{
m_root->removeFile( relativePath( filePath ) );
}
void Device::removeFolder(const std::string& filePath)
{
auto relPath = relativePath( filePath );
if ( relPath.empty() == true )
m_root = nullptr;
else
m_root->removeFolder( relPath );
}
std::shared_ptr<File> Device::file(const std::string& filePath)
{
if ( m_root == nullptr || m_present == false )
return nullptr;
return m_root->file( relativePath( filePath ) );
}
std::shared_ptr<Directory> Device::directory(const std::string& path)
{
if ( m_root == nullptr || m_present == false )
return nullptr;
const auto relPath = relativePath( path );
if ( relPath.empty() == true )
return m_root;
return m_root->directory( relPath );
}
void Device::setMountpointRoot(const std::string& path, std::shared_ptr<Directory> root)
{
auto relPath = relativePath( path );
// m_root is already a mountpoint, we can't add a mountpoint to it.
assert( relPath.empty() == false );
m_root->setMountpointRoot( relPath, root );
}
void Device::invalidateMountpoint(const std::string& path)
{
auto relPath = relativePath( path );
assert( relPath.empty() == false );
m_root->invalidateMountpoint( relPath );
}
}
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*****************************************************************************/
#pragma once
#include <string>
#include <memory>
#include "filesystem/IDevice.h"
namespace mock
{
class Directory;
class File;
class Device : public fs::IDevice, public std::enable_shared_from_this<Device>
{
public:
Device( const std::string& mountpoint, const std::string& uuid );
// We need at least one existing shared ptr before calling shared_from_this.
// Let the device be initialized and stored in a shared_ptr by the FileSystemFactory, and then
// initialize our fake root folder
void setupRoot();
std::shared_ptr<Directory> root();
virtual const std::string& uuid() const override;
virtual bool isRemovable() const override;
virtual bool isPresent() const override;
virtual const std::string& mountpoint() const override;
void setRemovable( bool value );
void setPresent( bool value );
std::string relativePath( const std::string& path );
void addFile( const std::string& filePath );
void addFolder( const std::string& path );
void removeFile( const std::string& filePath );
void removeFolder( const std::string& filePath );
std::shared_ptr<File> file( const std::string& filePath );
std::shared_ptr<Directory> directory( const std::string& path );
void setMountpointRoot( const std::string& path, std::shared_ptr<Directory> root );
void invalidateMountpoint( const std::string& path );
private:
std::string m_uuid;
bool m_removable;
bool m_present;
std::string m_mountpoint;
std::shared_ptr<Directory> m_root;
};
}
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*****************************************************************************/
#include <cassert>
#include "MockDirectory.h"
#include "MockFile.h"
#include "MockDevice.h"
#include "utils/Filename.h"
namespace mock
{
Directory::Directory(const std::string& path, std::shared_ptr<Device> device)
: m_path( path )
, m_device( device )
{