Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/undo-ransomware/ransomware_detection.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Held <ilovemilk@wusa.io>2018-06-18 15:14:17 +0300
committerMatthias Held <ilovemilk@wusa.io>2018-06-18 15:14:17 +0300
commit0d4208bd4934d83654fc3893867b2557546b404a (patch)
treeb6db2416bb0da30e119fdf8ff2120dea7d086481 /tests/Unit/Db
parent7a756a94ab887209f7ad7ffc6a01e2d16d01bfd4 (diff)
Add Nextcloud application
Diffstat (limited to 'tests/Unit/Db')
-rw-r--r--tests/Unit/Db/FileOperationMapperTest.php245
-rw-r--r--tests/Unit/Db/FileOperationTest.php93
-rw-r--r--tests/Unit/Db/MapperTestUtility.php227
3 files changed, 565 insertions, 0 deletions
diff --git a/tests/Unit/Db/FileOperationMapperTest.php b/tests/Unit/Db/FileOperationMapperTest.php
new file mode 100644
index 0000000..20fb584
--- /dev/null
+++ b/tests/Unit/Db/FileOperationMapperTest.php
@@ -0,0 +1,245 @@
+<?php
+
+/**
+ * @copyright Copyright (c) 2017 Matthias Held <matthias.held@uni-konstanz.de>
+ * @author Matthias Held <matthias.held@uni-konstanz.de>
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+namespace OCA\RansomwareDetection\tests\Unit\Db;
+
+use OCA\RansomwareDetection\Db\FileOperation;
+use OCA\RansomwareDetection\Db\FileOperationMapper;
+
+class FileOperationMapperTest extends MapperTestUtility
+{
+ /** @var FileOperationMapper */
+ protected $mapper;
+
+ /** @var array */
+ protected $fileOperations;
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->mapper = new FileOperationMapper($this->db);
+
+ // create mock FileOperation
+ $fileOperation1 = new FileOperation();
+ $fileOperation2 = new FileOperation();
+
+ $this->fileOperations = [$fileOperation1, $fileOperation2];
+
+ $this->twoRows = [
+ ['id' => $this->fileOperations[0]->getId()],
+ ['id' => $this->fileOperations[1]->getId()],
+ ];
+ }
+
+ public function testFind()
+ {
+ $userId = 'john';
+ $id = 3;
+ $rows = [['id' => $this->fileOperations[0]->getId()]];
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` '.
+ 'WHERE `id` = ? AND `user_id` = ?';
+
+ $this->setMapperResult($sql, [$id, $userId], $rows);
+
+ $result = $this->mapper->find($id, $userId);
+ $this->assertEquals($this->fileOperations[0], $result);
+ }
+
+ public function testFindNotFound()
+ {
+ $userId = 'john';
+ $id = 3;
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` '.
+ 'WHERE `id` = ? AND `user_id` = ?';
+
+ $this->setMapperResult($sql, [$id, $userId]);
+ $this->setExpectedException(
+ '\OCP\AppFramework\Db\DoesNotExistException'
+ );
+ $this->mapper->find($id, $userId);
+ }
+
+ public function testFindMoreThanOneResultFound()
+ {
+ $userId = 'john';
+ $id = 3;
+ $rows = $this->twoRows;
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` '.
+ 'WHERE `id` = ? AND `user_id` = ?';
+
+ $this->setMapperResult($sql, [$id, $userId], $rows);
+ $this->setExpectedException(
+ '\OCP\AppFramework\Db\MultipleObjectsReturnedException'
+ );
+ $this->mapper->find($id, $userId);
+ }
+
+ public function testFindOneByFileName()
+ {
+ $userId = 'john';
+ $name = 'test';
+ $rows = [['id' => $this->fileOperations[0]->getId()]];
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` '.
+ 'WHERE `original_name` = ? AND `user_id` = ?';
+
+ $this->setMapperResult($sql, [$name, $userId], $rows);
+
+ $result = $this->mapper->findOneByFileName($name, $userId);
+ $this->assertEquals($this->fileOperations[0], $result);
+ }
+
+ public function testFindOneByFileNameNotFound()
+ {
+ $userId = 'john';
+ $name = 'test';
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` '.
+ 'WHERE `original_name` = ? AND `user_id` = ?';
+
+ $this->setMapperResult($sql, [$name, $userId]);
+ $this->setExpectedException(
+ '\OCP\AppFramework\Db\DoesNotExistException'
+ );
+ $this->mapper->findOneByFileName($name, $userId);
+ }
+
+ public function testFindOneByFileNameMoreThanOneResultFound()
+ {
+ $userId = 'john';
+ $name = 'test';
+ $rows = $this->twoRows;
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` '.
+ 'WHERE `original_name` = ? AND `user_id` = ?';
+
+ $this->setMapperResult($sql, [$name, $userId], $rows);
+ $this->setExpectedException(
+ '\OCP\AppFramework\Db\MultipleObjectsReturnedException'
+ );
+ $this->mapper->findOneByFileName($name, $userId);
+ }
+
+ public function testFindOneWithHighestId()
+ {
+ $userId = 'john';
+ $rows = [['id' => $this->fileOperations[0]->getId()]];
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` WHERE `user_id` = ?'.
+ 'ORDER BY id DESC LIMIT 1';
+
+ $this->setMapperResult($sql, [$userId], $rows);
+
+ $result = $this->mapper->findOneWithHighestId($userId);
+ $this->assertEquals($this->fileOperations[0], $result);
+ }
+
+ public function testFindOneWithHighestIdNotFound()
+ {
+ $userId = 'john';
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` WHERE `user_id` = ?'.
+ 'ORDER BY id DESC LIMIT 1';
+
+ $this->setMapperResult($sql, [$userId]);
+ $this->setExpectedException(
+ '\OCP\AppFramework\Db\DoesNotExistException'
+ );
+ $this->mapper->findOneWithHighestId($userId);
+ }
+
+ public function testFindOneWithHighestIdMoreThanOneResultFound()
+ {
+ $userId = 'john';
+ $rows = $this->twoRows;
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` WHERE `user_id` = ?'.
+ 'ORDER BY id DESC LIMIT 1';
+
+ $this->setMapperResult($sql, [$userId], $rows);
+ $this->setExpectedException(
+ '\OCP\AppFramework\Db\MultipleObjectsReturnedException'
+ );
+ $this->mapper->findOneWithHighestId($userId);
+ }
+
+ public function testFindAll()
+ {
+ $userId = 'john';
+ $rows = $this->twoRows;
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` WHERE `user_id` = ?';
+
+ $this->setMapperResult($sql, [$userId], $rows);
+ $result = $this->mapper->findAll([$userId]);
+ $this->assertEquals($this->fileOperations, $result);
+ }
+
+ public function testFindSequenceById()
+ {
+ $userId = 'john';
+ $sequence = '1';
+ $rows = $this->twoRows;
+ $sql = 'SELECT * FROM `*PREFIX*ransomware_detection_file_operation` WHERE `sequence` = ? AND `user_id` = ?';
+
+ $this->setMapperResult($sql, [$sequence, $userId], $rows);
+ $result = $this->mapper->findSequenceById([$sequence, $userId]);
+ $this->assertEquals($this->fileOperations, $result);
+ }
+
+ public function testDelete()
+ {
+ $fileOperation = new FileOperation();
+ $fileOperation->setId(3);
+
+ $sql = 'DELETE FROM `*PREFIX*ransomware_detection_file_operation` WHERE `id` = ?';
+ $arguments = [$fileOperation->getId()];
+
+ $this->setMapperResult($sql, $arguments, [], null, null, true);
+
+ $this->mapper->delete($fileOperation);
+ }
+
+ public function testDeleteById()
+ {
+ $userId = 'john';
+ $fileOperation = new FileOperation();
+ $fileOperation->setUserId($userId);
+ $fileOperation->setId(3);
+
+ $sql = 'DELETE FROM `*PREFIX*ransomware_detection_file_operation` WHERE `id` = ? AND `user_id` = ?';
+ $arguments = [$fileOperation->getId(), $userId];
+
+ $this->setMapperResult($sql, $arguments, [], null, null, true);
+
+ $this->mapper->deleteById($fileOperation->getId(), $userId);
+ }
+
+ public function testDeleteSequenceById()
+ {
+ $userId = 'john';
+ $fileOperation = new FileOperation();
+ $fileOperation->setId(3);
+ $fileOperation->setUserId($userId);
+ $fileOperation->setSequence(1);
+
+ $sql = 'DELETE FROM `*PREFIX*ransomware_detection_file_operation` WHERE `sequence` = ? AND `user_id` = ?';
+ $arguments = [$fileOperation->getSequence(), $userId];
+
+ $this->setMapperResult($sql, $arguments, [], null, null, true);
+
+ $this->mapper->deleteSequenceById($fileOperation->getSequence(), $userId);
+ }
+}
diff --git a/tests/Unit/Db/FileOperationTest.php b/tests/Unit/Db/FileOperationTest.php
new file mode 100644
index 0000000..9a86ea9
--- /dev/null
+++ b/tests/Unit/Db/FileOperationTest.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * @copyright Copyright (c) 2017 Matthias Held <matthias.held@uni-konstanz.de>
+ * @author Matthias Held <matthias.held@uni-konstanz.de>
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+namespace OCA\RansomwareDetection\tests\Unit\Db;
+
+use OCA\RansomwareDetection\Monitor;
+use OCA\RansomwareDetection\Analyzer\EntropyResult;
+use OCA\RansomwareDetection\Analyzer\FileNameResult;
+use OCA\RansomwareDetection\Classifier;
+use OCA\RansomwareDetection\Db\FileOperation;
+use Test\TestCase;
+
+class FileOperationTest extends TestCase
+{
+ /** @var FileOperation */
+ protected $entity;
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->entity = new FileOperation();
+ }
+
+ public function dataFileOperation()
+ {
+ $data = [
+ ['field' => 'userId', 'value' => 'john'],
+ ['field' => 'path', 'value' => 'files/'],
+ ['field' => 'originalName', 'value' => 'test.jpg'],
+ ['field' => 'newName', 'value' => 'test.jpg'],
+ ['field' => 'type', 'value' => 'file'],
+ ['field' => 'mimeType', 'value' => 'image/jpg'],
+ ['field' => 'size', 'value' => 123],
+ ['field' => 'corrupted', 'value' => true],
+ ['field' => 'timestamp', 'value' => new \DateTime()],
+ ['field' => 'command', 'value' => Monitor::WRITE],
+ ['field' => 'command', 'value' => Monitor::READ],
+ ['field' => 'command', 'value' => Monitor::RENAME],
+ ['field' => 'command', 'value' => Monitor::DELETE],
+ ['field' => 'sequence', 'value' => 1],
+ ['field' => 'entropy', 'value' => 7.99],
+ ['field' => 'standardDeviation', 'value' => 0.004],
+ ['field' => 'fileNameEntropy', 'value' => 4.0],
+ ['field' => 'fileClass', 'value' => EntropyResult::NORMAL],
+ ['field' => 'fileClass', 'value' => EntropyResult::ENCRYPTED],
+ ['field' => 'fileClass', 'value' => EntropyResult::COMPRESSED],
+ ['field' => 'fileNameClass', 'value' => FileNameResult::NORMAL],
+ ['field' => 'fileNameClass', 'value' => FileNameResult::SUSPICIOUS_FILE_EXTENSION],
+ ['field' => 'fileNameClass', 'value' => FileNameResult::SUSPICIOUS_FILE_NAME],
+ ['field' => 'fileNameClass', 'value' => FileNameResult::SUSPICIOUS],
+ ['field' => 'suspicionClass', 'value' => Classifier::NO_INFORMATION],
+ ['field' => 'suspicionClass', 'value' => Classifier::NOT_SUSPICIOUS],
+ ['field' => 'suspicionClass', 'value' => Classifier::MIDDLE_LEVEL_OF_SUSPICION],
+ ['field' => 'suspicionClass', 'value' => Classifier::LOW_LEVEL_OF_SUSPICION],
+ ['field' => 'suspicionClass', 'value' => Classifier::HIGH_LEVEL_OF_SUSPICION],
+ ];
+
+ return $data;
+ }
+
+ /**
+ * @dataProvider dataFileOperation
+ *
+ * @param string $field
+ * @param mixed $value
+ */
+ public function testFileOperation($field, $value)
+ {
+ $setMethod = 'set'.ucfirst($field);
+ $this->entity->$setMethod($value);
+ $getMethod = 'get'.ucfirst($field);
+ $this->assertEquals($this->entity->$getMethod(), $value);
+ }
+}
diff --git a/tests/Unit/Db/MapperTestUtility.php b/tests/Unit/Db/MapperTestUtility.php
new file mode 100644
index 0000000..fc4bff6
--- /dev/null
+++ b/tests/Unit/Db/MapperTestUtility.php
@@ -0,0 +1,227 @@
+<?php
+
+/**
+ * ownCloud - App Framework.
+ *
+ * @author Bernhard Posselt
+ * @author Matthias Held <matthias.held@uni-konstanz.de>
+ * @copyright 2012 Bernhard Posselt dev@bernhard-posselt.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OCA\RansomwareDetection\Tests\Unit\Db;
+
+use Test\TestCase;
+
+/**
+ * Simple utility class for testing mappers.
+ */
+abstract class MapperTestUtility extends TestCase
+{
+ protected $db;
+ private $query;
+ private $queryAt;
+ private $prepareAt;
+ private $fetchAt;
+ private $iterators;
+
+ /**
+ * Run this function before the actual test to either set or initialize the
+ * db. After this the db can be accessed by using $this->db.
+ */
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->db = $this->getMockBuilder(
+ '\OCP\IDBConnection'
+ )
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->query = $this->createMock('\PDOStatement');
+ $this->queryAt = 0;
+ $this->prepareAt = 0;
+ $this->iterators = [];
+ $this->fetchAt = 0;
+ }
+
+ /**
+ * Checks if an array is associative.
+ *
+ * @param array $array
+ *
+ * @return bool true if associative
+ */
+ private function isAssocArray(array $array)
+ {
+ return array_values($array) !== $array;
+ }
+
+ /**
+ * Returns the correct PDO constant based on the value type.
+ *
+ * @param $value
+ *
+ * @return PDO constant
+ */
+ private function getPDOType($value)
+ {
+ switch (gettype($value)) {
+ case 'integer':
+ return \PDO::PARAM_INT;
+ case 'boolean':
+ return \PDO::PARAM_BOOL;
+ default:
+ return \PDO::PARAM_STR;
+ }
+ }
+
+ /**
+ * Create mocks and set expected results for database queries.
+ *
+ * @param string $sql the sql query that you expect to receive
+ * @param array $arguments the expected arguments for the prepare query
+ * method
+ * @param array $returnRows the rows that should be returned for the result
+ * of the database query. If not provided, it wont be assumed that fetch
+ * will be called on the result
+ */
+ protected function setMapperResult(
+ $sql,
+ $arguments = array(),
+ $returnRows = array(),
+ $limit = null,
+ $offset = null,
+ $expectClose = false
+ ) {
+ if ($limit === null && $offset === null) {
+ $this->db->expects($this->at($this->prepareAt))
+ ->method('prepare')
+ ->with($this->equalTo($sql))
+ ->will(($this->returnValue($this->query)));
+ } elseif ($limit !== null && $offset === null) {
+ $this->db->expects($this->at($this->prepareAt))
+ ->method('prepare')
+ ->with($this->equalTo($sql), $this->equalTo($limit))
+ ->will(($this->returnValue($this->query)));
+ } elseif ($limit === null && $offset !== null) {
+ $this->db->expects($this->at($this->prepareAt))
+ ->method('prepare')
+ ->with(
+ $this->equalTo($sql),
+ $this->equalTo(null),
+ $this->equalTo($offset)
+ )
+ ->will(($this->returnValue($this->query)));
+ } else {
+ $this->db->expects($this->at($this->prepareAt))
+ ->method('prepare')
+ ->with(
+ $this->equalTo($sql),
+ $this->equalTo($limit),
+ $this->equalTo($offset)
+ )
+ ->will(($this->returnValue($this->query)));
+ }
+
+ $this->iterators[] = new ArgumentIterator($returnRows);
+
+ $iterators = $this->iterators;
+ $fetchAt = $this->fetchAt;
+
+ $this->query->expects($this->any())
+ ->method('fetch')
+ ->will($this->returnCallback(
+ function () use ($iterators, $fetchAt) {
+ $iterator = $iterators[$fetchAt];
+ $result = $iterator->next();
+
+ if ($result === false) {
+ $fetchAt++;
+ }
+
+ $this->queryAt++;
+
+ return $result;
+ }
+ ));
+
+ if ($this->isAssocArray($arguments)) {
+ foreach ($arguments as $key => $argument) {
+ $pdoConstant = $this->getPDOType($argument);
+ $this->query->expects($this->at($this->queryAt))
+ ->method('bindValue')
+ ->with(
+ $this->equalTo($key),
+ $this->equalTo($argument),
+ $this->equalTo($pdoConstant)
+ );
+ $this->queryAt++;
+ }
+ } else {
+ $index = 1;
+ foreach ($arguments as $argument) {
+ $pdoConstant = $this->getPDOType($argument);
+ $this->query->expects($this->at($this->queryAt))
+ ->method('bindValue')
+ ->with(
+ $this->equalTo($index),
+ $this->equalTo($argument),
+ $this->equalTo($pdoConstant)
+ );
+ $index++;
+ $this->queryAt++;
+ }
+ }
+
+ $this->query->expects($this->at($this->queryAt))
+ ->method('execute')
+ ->will($this->returnCallback(function ($sql, $p = null, $o = null, $s = null) {
+ }));
+ $this->queryAt++;
+
+ if ($expectClose) {
+ $closing = $this->at($this->queryAt);
+ } else {
+ $closing = $this->any();
+ }
+ $this->query->expects($closing)->method('closeCursor');
+ $this->queryAt++;
+
+ $this->prepareAt++;
+ $this->fetchAt++;
+ }
+}
+
+class ArgumentIterator
+{
+ private $arguments;
+
+ public function __construct($arguments)
+ {
+ $this->arguments = $arguments;
+ }
+
+ public function next()
+ {
+ $result = array_shift($this->arguments);
+ if ($result === null) {
+ return false;
+ } else {
+ return $result;
+ }
+ }
+}