rkt-tool-lib 1.5.0__tar.gz → 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: rkt_tool_lib
3
+ Version: 2.0.0
4
+ Summary: RootKit custom tool Lib
5
+ Author-email: RootKit <rootkit@rootkit-lab.org>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.7
@@ -0,0 +1,22 @@
1
+ # rkt_tool_lib
2
+
3
+ Cross-platform file system utilities.
4
+
5
+ ## Features
6
+ - **Path Normalization**: Automatically formats paths (`/` vs `\`) based on the operating system (Windows/Linux).
7
+ - **Recursive Search**: Utilities to find directories deeply nested in the file system.
8
+ - **Singleton Pattern**: (Optional usage via `Singleton` metaclass provided).
9
+
10
+ ## Usage
11
+
12
+ ```python
13
+ from tool import Tool
14
+
15
+ t = Tool()
16
+
17
+ # Get current working directory formatted for OS
18
+ cwd = t.get_cwd()
19
+
20
+ # Find a directory named 'logs' recursively
21
+ log_path = t.get_dir("logs")
22
+ ```
@@ -0,0 +1,21 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "rkt_tool_lib"
7
+ version = "2.0.0"
8
+ description = "RootKit custom tool Lib"
9
+ authors = [
10
+ { name="RootKit", email="rootkit@rootkit-lab.org" },
11
+ ]
12
+ classifiers = [
13
+ "Programming Language :: Python :: 3",
14
+ "License :: OSI Approved :: MIT License",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+ requires-python = ">=3.7"
18
+ dependencies = []
19
+
20
+ [tool.setuptools.packages.find]
21
+ where = ["src"]
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: rkt_tool_lib
3
+ Version: 2.0.0
4
+ Summary: RootKit custom tool Lib
5
+ Author-email: RootKit <rootkit@rootkit-lab.org>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.7
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/rkt_tool_lib.egg-info/PKG-INFO
4
+ src/rkt_tool_lib.egg-info/SOURCES.txt
5
+ src/rkt_tool_lib.egg-info/dependency_links.txt
6
+ src/rkt_tool_lib.egg-info/top_level.txt
7
+ src/tool/__init__.py
8
+ src/tool/py.typed
9
+ src/tool/tool.py
10
+ tests/test_tool.py
@@ -0,0 +1 @@
1
+ from .tool import Singleton, Tool
File without changes
@@ -0,0 +1,84 @@
1
+ import os
2
+ from typing import Any, Optional
3
+
4
+
5
+ class Singleton(type):
6
+ """
7
+ The Singleton class can be implemented in different ways in Python. Some
8
+ possible methods include: base class, decorator, metaclass. We will use the
9
+ metaclass because it is best suited for this purpose.
10
+ """
11
+
12
+ _instances: dict[type, object] = {}
13
+
14
+ def __call__(cls, *args: Any, **kwargs: Any) -> Any:
15
+ """
16
+ Possible changes to the value of the `__init__` argument do not affect
17
+ the returned instance.
18
+ """
19
+ if cls not in cls._instances:
20
+ instance = super().__call__(*args, **kwargs)
21
+ cls._instances[cls] = instance
22
+ return cls._instances[cls]
23
+
24
+
25
+ class Tool:
26
+ """
27
+ Utility class for file system operations.
28
+
29
+ Provides cross-platform methods for path formatting and recursive directory searching.
30
+ """
31
+
32
+ @staticmethod
33
+ def formatted_from_os(path: str) -> str:
34
+ """
35
+ Format a path string to match the current operating system's separator.
36
+
37
+ Args:
38
+ path (str): The path to format.
39
+
40
+ Returns:
41
+ str: The formatted path with correct separators and trailing separator handled.
42
+ """
43
+ if os.name == "nt":
44
+ sep = "\\"
45
+ res = f"{path.replace('/', sep)}{sep if path[-1] != sep else ''}"
46
+ else:
47
+ res = f"{path}{'/' if path[-1] != '/' else ''}"
48
+
49
+ return res
50
+
51
+ def get_cwd(self) -> str:
52
+ """
53
+ Get the current working directory, formatted for the OS.
54
+
55
+ Returns:
56
+ str: Absolute path of the CWD.
57
+ """
58
+ return self.formatted_from_os(os.getcwd())
59
+
60
+ def get_dir(self, folder: str, root: Optional[str] = None) -> Optional[str]:
61
+ """
62
+ Recursively search for a directory by name.
63
+
64
+ Args:
65
+ folder (str): The name of the directory to find.
66
+ root (Optional[str], optional): The root directory to start searching from.
67
+ If None, uses current working directory. Defaults to None.
68
+
69
+ Returns:
70
+ Optional[str]: Absolute path to the found directory, or None if not found.
71
+ """
72
+ root = self.get_cwd() if not root else self.formatted_from_os(root)
73
+
74
+ for element in os.listdir(root):
75
+ if os.path.isdir(f"{root}{element}") and element == folder:
76
+ return self.formatted_from_os(f"{root}{element}")
77
+
78
+ for element in os.listdir(root):
79
+ if os.path.isdir(f"{root}{element}"):
80
+ found = self.get_dir(folder, self.formatted_from_os(f"{root}{element}"))
81
+ if found:
82
+ return found
83
+
84
+ return None
@@ -0,0 +1,86 @@
1
+ import os
2
+ from unittest.mock import patch
3
+
4
+ from tool import Singleton, Tool
5
+
6
+ obj = Tool()
7
+
8
+
9
+ class FakeClass(metaclass=Singleton): # type: ignore[metaclass]
10
+ def __init__(self) -> None:
11
+ self.name = "singleton"
12
+
13
+
14
+ class TestTool:
15
+ def test_formatted_from_os(self) -> None:
16
+ if os.name == "nt":
17
+ excepted = obj.formatted_from_os(os.getcwd()).endswith("\\")
18
+ else:
19
+ excepted = obj.formatted_from_os(os.getcwd()).endswith("/")
20
+ assert excepted
21
+
22
+ def test_get_cwd(self) -> None:
23
+ assert obj.get_cwd() == f"{os.getcwd()}\\" if os.name == "nt" else f"{os.getcwd()}/"
24
+
25
+ def test_get_dir_flat(self) -> None:
26
+ with patch("os.getcwd", return_value="C:\\fake\\root" if os.name == "nt" else "/fake/root"):
27
+ with patch("os.listdir", return_value=["target"]):
28
+ with patch("os.path.isdir", return_value=True):
29
+ # Mock Tool.formatted_from_os to behave simply (it uses os.name, assume consistent)
30
+ # Actually Tool uses os.name real value.
31
+ # If we mock os.getcwd, Tool.get_cwd() calls real Tool.formatted_from_os which uses real path sep.
32
+ # So we should match the format.
33
+
34
+ root_sep = "\\" if os.name == "nt" else "/"
35
+ root = f"C:{root_sep}fake{root_sep}root" if os.name == "nt" else "/fake/root"
36
+
37
+ # We need to simulate get_dir logic:
38
+ # listdir(root) -> ['target']
39
+ # isdir(root/target) -> True
40
+ # element == folder
41
+
42
+ # We search for "target"
43
+ expected = f"{root}{root_sep}target{root_sep}"
44
+
45
+ # We can just test that logic finds it
46
+ # But Tool.get_dir uses os.listdir which we patched.
47
+
48
+ res = obj.get_dir("target")
49
+ assert res == expected
50
+
51
+ def test_get_dir_recursive(self) -> None:
52
+ # Setup: root -> [folder1] -> [target]
53
+ root_sep = "\\" if os.name == "nt" else "/"
54
+ root = f"C:{root_sep}fake{root_sep}root" if os.name == "nt" else "/fake/root"
55
+
56
+ def listdir_side_effect(path: str) -> list[str]:
57
+ # Normalize path for comparison if needed, but let's assume strict basic paths
58
+ # formatted_from_os ensures trailing slash
59
+ # Tool logic: listdir(root).
60
+ if path.startswith(root) and "folder1" not in path:
61
+ return ["folder1"]
62
+ if "folder1" in path:
63
+ return ["target"]
64
+ return []
65
+
66
+ def isdir_side_effect(path: str) -> bool:
67
+ return True
68
+
69
+ with patch("os.getcwd", return_value=root.rstrip(root_sep)): # get_cwd calls formatted_from_os which adds slash
70
+ with patch("os.listdir", side_effect=listdir_side_effect):
71
+ with patch("os.path.isdir", return_value=True):
72
+ expected = f"{root}{root_sep}folder1{root_sep}target{root_sep}"
73
+ res = obj.get_dir("target")
74
+ # Depending on implementation it might find it.
75
+ # Recursion:
76
+ # 1. root listdir -> folder1. folder1 != target.
77
+ # 2. recursive call on root/folder1.
78
+ # 3. root/folder1 listdir -> target. target == target. Return.
79
+ assert res == expected
80
+
81
+
82
+ class TestSingleton:
83
+ def test_singleton(self) -> None:
84
+ obj_1 = FakeClass()
85
+ obj_2 = FakeClass()
86
+ assert obj_1 == obj_2
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2016 Dabo Ross
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,88 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: rkt_tool_lib
3
- Version: 1.5.0
4
- Summary: RootKit custom tool Lib
5
- Author: RootKit
6
- Author-email: rootkit@rootkit-lab.org
7
- Classifier: Development Status :: 5 - Production/Stable
8
- Classifier: Intended Audience :: Developers
9
- Classifier: Intended Audience :: End Users/Desktop
10
- Classifier: Intended Audience :: Information Technology
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Natural Language :: English
13
- Classifier: Natural Language :: French
14
- Classifier: Operating System :: OS Independent
15
- Classifier: Programming Language :: Python :: 3.7
16
- Classifier: Topic :: Utilities
17
- Requires-Python: >=3.7
18
- Description-Content-Type: text/markdown
19
- License-File: LICENSE
20
- Dynamic: author
21
- Dynamic: author-email
22
- Dynamic: classifier
23
- Dynamic: description
24
- Dynamic: description-content-type
25
- Dynamic: requires-python
26
- Dynamic: summary
27
-
28
- # rkt_tool_lib - Python library
29
-
30
- ![Package Version](https://badgen.net/badge/Package%20Version/latest%20-%201.3.0/green?scale=1.2)
31
-
32
- ![quality](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=alert_status)
33
- ![reliability_rating](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=reliability_rating)
34
- ![security_rating](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=security_rating)
35
- ![vulnerabilities](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=vulnerabilities)
36
- ![coverage](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=coverage)
37
- ![maintainability](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=sqale_rating)
38
-
39
- ##### Python minimal Version 3.7
40
-
41
- ----
42
-
43
- ## What is Python?
44
- Python is an interpreted high-level general-purpose programming language. Python's design philosophy emphasizes code readability with its notable use of significant indentation. Its language constructs as well as its object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.
45
-
46
- [source](https://en.wikipedia.org/wiki/Python_(programming_language))
47
-
48
- ## Libraries
49
- * Tool: toolbox library with, you can automatically format the path in your code without worrying about the platform hosting your script
50
-
51
- ## Use it
52
- ### Install
53
- ```bash
54
- (venv) my_project> pip install rkt_tool_lib [--index-url https://gitlab.tprc.ovh/api/v4/groups/python/-/packages/pypi]
55
- ```
56
-
57
- ### Example
58
-
59
- ```python
60
- from rkt_tool_lib import Tool
61
-
62
- t = Tool()
63
-
64
- print(t.get_cwd())
65
- print(t.get_dir('db'))
66
-
67
-
68
- ```
69
-
70
- ### Output (as file, sdtout or both)
71
- windows
72
- ```log
73
- C:\Users\Me\Documents\path\to\my\project\
74
- C:\Users\Me\Documents\path\to\my\project\db\
75
- ```
76
- linux:
77
- ```log
78
- /home/me/path/to/my/project/
79
- /home/me/path/to/my/project/db/
80
- ```
81
-
82
- ## Contributing
83
-
84
- If you find this library useful here's how you can help:
85
-
86
- - Send a merge request with your kickass new features and bug fixes
87
- - Help new users with [issues](https://gitlab.tprc.ovh/python/rkt_lib_toolkit/-/issues) they may encounter
88
- - Support the development of this library and star this repo!
@@ -1,53 +0,0 @@
1
- import os
2
- from typing import Optional
3
-
4
-
5
- class Singleton(type):
6
- """
7
- The Singleton class can be implemented in different ways in Python. Some
8
- possible methods include: base class, decorator, metaclass. We will use the
9
- metaclass because it is best suited for this purpose.
10
- """
11
-
12
- _instances = {}
13
-
14
- def __call__(cls, *args, **kwargs):
15
- """
16
- Possible changes to the value of the `__init__` argument do not affect
17
- the returned instance.
18
- """
19
- if cls not in cls._instances:
20
- instance = super().__call__(*args, **kwargs)
21
- cls._instances[cls] = instance
22
- return cls._instances[cls]
23
-
24
-
25
- class Tool:
26
-
27
- @staticmethod
28
- def formatted_from_os(path) -> str:
29
- if os.name == "nt":
30
- sep = "\\"
31
- res = f'{path.replace("/", sep)}{sep if path[-1] != sep else ""}'
32
- else:
33
- res = f'{path}{"/" if path[-1] != "/" else ""}'
34
-
35
- return res
36
-
37
- def get_cwd(self) -> str:
38
- return self.formatted_from_os(os.getcwd())
39
-
40
- def get_dir(self, folder, root: Optional[str] = None) -> Optional[str]:
41
- root = self.get_cwd() if not root else self.formatted_from_os(root)
42
-
43
- for element in os.listdir(root):
44
- if os.path.isdir(f"{root}{element}") and element == folder:
45
- return self.formatted_from_os(f"{root}{element}")
46
-
47
- for element in os.listdir(root):
48
- if os.path.isdir(f"{root}{element}"):
49
- found = self.get_dir(folder, self.formatted_from_os(f"{root}{element}"))
50
- if found:
51
- return found
52
-
53
- return None
@@ -1 +0,0 @@
1
- from .Tool import Tool, Singleton
@@ -1,88 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: rkt_tool_lib
3
- Version: 1.5.0
4
- Summary: RootKit custom tool Lib
5
- Author: RootKit
6
- Author-email: rootkit@rootkit-lab.org
7
- Classifier: Development Status :: 5 - Production/Stable
8
- Classifier: Intended Audience :: Developers
9
- Classifier: Intended Audience :: End Users/Desktop
10
- Classifier: Intended Audience :: Information Technology
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Natural Language :: English
13
- Classifier: Natural Language :: French
14
- Classifier: Operating System :: OS Independent
15
- Classifier: Programming Language :: Python :: 3.7
16
- Classifier: Topic :: Utilities
17
- Requires-Python: >=3.7
18
- Description-Content-Type: text/markdown
19
- License-File: LICENSE
20
- Dynamic: author
21
- Dynamic: author-email
22
- Dynamic: classifier
23
- Dynamic: description
24
- Dynamic: description-content-type
25
- Dynamic: requires-python
26
- Dynamic: summary
27
-
28
- # rkt_tool_lib - Python library
29
-
30
- ![Package Version](https://badgen.net/badge/Package%20Version/latest%20-%201.3.0/green?scale=1.2)
31
-
32
- ![quality](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=alert_status)
33
- ![reliability_rating](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=reliability_rating)
34
- ![security_rating](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=security_rating)
35
- ![vulnerabilities](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=vulnerabilities)
36
- ![coverage](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=coverage)
37
- ![maintainability](https://sonarqube.tprc.ovh/api/project_badges/measure?project=python_rkt_lib_toolkit_AXqQ32evGCA0VuRY8SuD&metric=sqale_rating)
38
-
39
- ##### Python minimal Version 3.7
40
-
41
- ----
42
-
43
- ## What is Python?
44
- Python is an interpreted high-level general-purpose programming language. Python's design philosophy emphasizes code readability with its notable use of significant indentation. Its language constructs as well as its object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.
45
-
46
- [source](https://en.wikipedia.org/wiki/Python_(programming_language))
47
-
48
- ## Libraries
49
- * Tool: toolbox library with, you can automatically format the path in your code without worrying about the platform hosting your script
50
-
51
- ## Use it
52
- ### Install
53
- ```bash
54
- (venv) my_project> pip install rkt_tool_lib [--index-url https://gitlab.tprc.ovh/api/v4/groups/python/-/packages/pypi]
55
- ```
56
-
57
- ### Example
58
-
59
- ```python
60
- from rkt_tool_lib import Tool
61
-
62
- t = Tool()
63
-
64
- print(t.get_cwd())
65
- print(t.get_dir('db'))
66
-
67
-
68
- ```
69
-
70
- ### Output (as file, sdtout or both)
71
- windows
72
- ```log
73
- C:\Users\Me\Documents\path\to\my\project\
74
- C:\Users\Me\Documents\path\to\my\project\db\
75
- ```
76
- linux:
77
- ```log
78
- /home/me/path/to/my/project/
79
- /home/me/path/to/my/project/db/
80
- ```
81
-
82
- ## Contributing
83
-
84
- If you find this library useful here's how you can help:
85
-
86
- - Send a merge request with your kickass new features and bug fixes
87
- - Help new users with [issues](https://gitlab.tprc.ovh/python/rkt_lib_toolkit/-/issues) they may encounter
88
- - Support the development of this library and star this repo!
@@ -1,12 +0,0 @@
1
- LICENSE
2
- README
3
- rkt_lib_toolkit/rkt_tool_lib/Tool.py
4
- rkt_lib_toolkit/rkt_tool_lib/__init__.py
5
- rkt_lib_toolkit/rkt_tool_lib.egg-info/PKG-INFO
6
- rkt_lib_toolkit/rkt_tool_lib.egg-info/SOURCES.txt
7
- rkt_lib_toolkit/rkt_tool_lib.egg-info/dependency_links.txt
8
- rkt_lib_toolkit/rkt_tool_lib.egg-info/top_level.txt
9
- tests/test_AI.py
10
- tests/test_Config.py
11
- tests/test_Logger.py
12
- tests/test_Tool.py
@@ -1,189 +0,0 @@
1
- import os.path
2
- import time
3
- from unittest import TestCase
4
-
5
- from pandas import DataFrame
6
-
7
- from rkt_lib_toolkit import Logger, Config
8
- from rkt_lib_toolkit.rkt_ai_lib import QLearning
9
-
10
- MODEL = "tests/resources/qlearning/load/load_coverage.gzip"
11
-
12
-
13
- class TestQLearning(TestCase):
14
- def test_me_setter(self):
15
- ql = QLearning(actions=['a', 'b', 'c'])
16
- ql.me = 'me'
17
- assert ql.me == 'me'
18
-
19
- def test_me_getter(self):
20
- ql = QLearning(actions=['a', 'b', 'c'])
21
- assert ql.me == 'QLearning'
22
-
23
- def test_logger_setter(self):
24
- ql = QLearning(actions=['a', 'b', 'c'])
25
- ql.logger = Logger(caller_class=ql.me)
26
- assert isinstance(ql.logger, Logger)
27
-
28
- def test_logger_getter(self):
29
- ql = QLearning(actions=['a', 'b', 'c'])
30
- logger = ql.logger
31
- assert isinstance(logger, Logger)
32
-
33
- def test_config_setter(self):
34
- ql = QLearning(actions=['a', 'b', 'c'])
35
- ql.config = Config()
36
- assert isinstance(ql.config, Config)
37
-
38
- def test_config_getter(self):
39
- ql = QLearning(actions=['a', 'b', 'c'])
40
- config = ql.config
41
- assert isinstance(config, Config)
42
-
43
- def test_learning_rate_setter(self):
44
- ql = QLearning(actions=['a', 'b', 'c'])
45
- original_lr = ql.learning_rate
46
- ql.learning_rate = 1.0
47
- assert ql.learning_rate != original_lr
48
-
49
- def test_learning_rate_getter(self):
50
- ql = QLearning(actions=['a', 'b', 'c'])
51
- original_lr = ql.learning_rate
52
- assert ql.learning_rate == original_lr
53
-
54
- def test_discount_factor_setter(self):
55
- ql = QLearning(actions=['a', 'b', 'c'])
56
- original_df = ql.discount_factor
57
- ql.discount_factor = 1.0
58
- assert ql.discount_factor != original_df
59
-
60
- def test_discount_factor_getter(self):
61
- ql = QLearning(actions=['a', 'b', 'c'])
62
- original_df = ql.discount_factor
63
- assert ql.discount_factor == original_df
64
-
65
- def test_qtable_setter(self):
66
- ql = QLearning(actions=['a', 'b', 'c'])
67
- assert isinstance(ql.qtable, DataFrame)
68
-
69
- def test_qtable_getter(self):
70
- ql = QLearning(actions=['a', 'b', 'c'])
71
- qtable = ql.qtable
72
- assert isinstance(qtable, DataFrame)
73
-
74
- def test_previous_state_setter(self):
75
- ql = QLearning(actions=['a', 'b', 'c'])
76
- ql.previous_state = 's'
77
- assert ql.previous_state == 's'
78
-
79
- def test_previous_state_getter(self):
80
- ql = QLearning(actions=['a', 'b', 'c'])
81
- assert ql.previous_state == 'start'
82
-
83
- def test_previous_action_setter(self):
84
- ql = QLearning(actions=['a', 'b', 'c'])
85
- ql.previous_action = 'a'
86
- assert ql.previous_action == 'a'
87
-
88
- def test_previous_action_getter(self):
89
- ql = QLearning(actions=['a', 'b', 'c'])
90
- assert ql.previous_action == 'do-nothing'
91
-
92
- def test_available_actions_setter(self):
93
- ql = QLearning(actions=['a', 'b', 'c'])
94
- assert ql.available_actions == ['a', 'b', 'c']
95
-
96
- def test_available_actions_getter(self):
97
- ql = QLearning(actions=['a', 'b', 'c'])
98
- actions_list = ql.available_actions
99
- assert actions_list == ['a', 'b', 'c']
100
-
101
- def test00_save(self):
102
- ql = QLearning(actions=['a', 'b', 'c'])
103
- ql.check_state_exist(state='s')
104
- ql.previous_state = "new_action"
105
- ql.check_state_exist(state='s1')
106
- ql.save("tests/resources/qlearning/save/save_coverage.gzip")
107
- ql.save(MODEL)
108
- assert os.path.exists("tests/resources/qlearning/save/save_coverage.gzip")
109
-
110
- def test01_load(self):
111
- ql = QLearning(actions=['a', 'b', 'c'])
112
- ql.load(do_load=True, file_to_load=MODEL)
113
- assert isinstance(ql.qtable, DataFrame)
114
-
115
- def test03_choose_action(self):
116
- time.sleep(1.0)
117
- ql = QLearning(actions=['a', 'b', 'c'], should_load=True,
118
- qtable_file_to_load=MODEL)
119
-
120
- action = ql.choose_action(state='s')
121
- assert action in ['a', 'b', 'c']
122
-
123
- def test_learn(self):
124
- ql = QLearning(actions=['a', 'b', 'c'], should_load=True,
125
- qtable_file_to_load=MODEL)
126
- for i in range(2):
127
- action = ql.choose_action(state=f's{i}')
128
- ql.learn(state=f's{i}', action=action, reward=1.0)
129
- assert ql.qtable.index.tolist() == ['start', 's1']
130
-
131
- def test_check_state_exist(self):
132
- ql = QLearning(actions=['a', 'b', 'c'])
133
- ql.check_state_exist(state='s')
134
- qtable_len = len(ql.qtable.index)
135
- ql.check_state_exist(state='s')
136
- qtable2_len = len(ql.qtable.index)
137
- ql.previous_state = "new_action"
138
- ql.check_state_exist(state='s1')
139
- qtable3_len = len(ql.qtable.index)
140
- assert qtable_len == qtable2_len and qtable_len != qtable3_len
141
-
142
- def test_representation(self):
143
- ql = QLearning(actions=['a', 'b', 'c'])
144
- assert ql.__repr__() == f"QLearning(learning_rate={ql.learning_rate}, discount_factor={ql.discount_factor}, learning_method={ql._learning_method})"
145
-
146
- def test_me_setter_error(self):
147
- ql = QLearning(actions=['a', 'b', 'c'])
148
- with self.assertRaises(TypeError):
149
- ql.me = 1
150
-
151
- def test_logger_setter_error(self):
152
- ql = QLearning(actions=['a', 'b', 'c'])
153
- with self.assertRaises(TypeError):
154
- ql.logger = 1
155
-
156
- def test_config_setter_error(self):
157
- ql = QLearning(actions=['a', 'b', 'c'])
158
- with self.assertRaises(TypeError):
159
- ql.config = 1
160
-
161
- def test_learning_rate_setter_error(self):
162
- ql = QLearning(actions=['a', 'b', 'c'])
163
- with self.assertRaises(TypeError):
164
- ql.learning_rate = "0"
165
-
166
- def test_discount_factor_setter_error(self):
167
- ql = QLearning(actions=['a', 'b', 'c'])
168
- with self.assertRaises(TypeError):
169
- ql.discount_factor = "0"
170
-
171
- def test_qtable_setter_error(self):
172
- ql = QLearning(actions=['a', 'b', 'c'])
173
- with self.assertRaises(TypeError):
174
- ql.qtable = "0"
175
-
176
- def test_previous_state_setter_error(self):
177
- ql = QLearning(actions=['a', 'b', 'c'])
178
- with self.assertRaises(TypeError):
179
- ql.previous_state = 1
180
-
181
- def test_previous_action_setter_error(self):
182
- ql = QLearning(actions=['a', 'b', 'c'])
183
- with self.assertRaises(TypeError):
184
- ql.previous_action = 1
185
-
186
- def test_available_actions_setter_error(self):
187
- ql = QLearning(actions=['a', 'b', 'c'])
188
- with self.assertRaises(TypeError):
189
- ql.available_actions = 1
@@ -1,52 +0,0 @@
1
- import os
2
- import shutil
3
-
4
- from unittest import TestCase
5
-
6
- from yaml.scanner import ScannerError
7
- from rkt_lib_toolkit.rkt_config_lib import Config
8
-
9
-
10
- class TestConfig(TestCase):
11
- def test_get_data(self):
12
- config = Config()
13
- config.data.clear()
14
- config.get_data(_config_dir="valid_config")
15
-
16
- assert config.data == {
17
- 'valid_config': {'key1': {
18
- 'sub_key': 'value',
19
- 'sub_key2': 'value',
20
- 'sub_key3': 'value',
21
- 'sub_key4': 'value'
22
- }
23
- }
24
- }
25
-
26
- def test_get_data_dummy_data(self):
27
- config = Config()
28
- config.data.clear()
29
- try:
30
- config.get_data(_config_dir="dummy_config")
31
- self.fail("ScannerError expected here!")
32
- except ScannerError:
33
- assert config.data == {}
34
-
35
- def test_get_data_dummy_folder(self):
36
- config = Config()
37
- config.data.clear()
38
- config.get_data(_config_dir="missing_folder", create_if_not_exist=True)
39
- assert os.path.exists("missing_folder")
40
- shutil.rmtree("missing_folder")
41
-
42
- def test_get_data_from_specific_file(self):
43
- config = Config()
44
- config.data.clear()
45
- config.get_data(_config_dir="valid_config", needed_file="valid_config.yml")
46
-
47
- assert config.data == {
48
- 'valid_config': {'key1': {
49
- 'sub_key': 'value', 'sub_key2': 'value', 'sub_key3': 'value', 'sub_key4': 'value'
50
- }
51
- }
52
- }
@@ -1,53 +0,0 @@
1
- import os
2
- import shutil
3
- from datetime import datetime
4
- from unittest import TestCase
5
-
6
- from rkt_lib_toolkit.rkt_logger_lib import Logger
7
- from rkt_lib_toolkit.rkt_exception_lib import InvalidLogLevelError, LogIsNotDirError
8
- from rkt_lib_toolkit.rkt_tool_lib import Singleton, Tool
9
-
10
- tool = Tool()
11
-
12
-
13
- class TestLogger(TestCase):
14
-
15
- def test_logger_when_log_is_not_directory(self):
16
- log = f"{tool.formatted_from_os(tool.get_cwd())}log_misstake"
17
- if os.path.exists(log):
18
- if os.path.isdir(log):
19
- shutil.rmtree(log)
20
- else:
21
- os.remove(log)
22
-
23
- open(log, "x").close()
24
- Singleton._instances = {}
25
- with self.assertRaises(LogIsNotDirError) as context:
26
- logger = Logger("coverage", "log_misstake")
27
-
28
- assert str(context.exception) == "\"log\" isn't a directory"
29
- os.remove(log)
30
-
31
- def test_add_without_exiting_log_level(self):
32
- logger = Logger("coverage", "log")
33
- logger.set_logger(caller_class="coverage", output="stream")
34
- with self.assertRaises(InvalidLogLevelError):
35
- logger.add("coverage", "tests coverage", 42)
36
-
37
- def test_add_with_exiting_log_level(self):
38
- logger = Logger("coverage", "log")
39
- logger.set_logger(caller_class="coverage", output="stream")
40
- assert logger.add("coverage", "tests coverage", 20) is None
41
-
42
- def test_set_logger(self):
43
- logger = Logger("coverage", "log")
44
- logger.set_logger(caller_class="coverage", output="both", out_file="coverage", level=10)
45
- logger.add("coverage", "test", 20)
46
- excepted = f"{logger._tool.get_dir(folder='log')}coverage_{datetime.today().date()}.log"
47
- obtained = logger.get_logger_file('coverage')
48
- assert obtained == excepted, print(f"Expected: {excepted}\nObtained: {obtained}")
49
-
50
- def test_no_logger_file(self):
51
- logger = Logger("coverage", "log")
52
- logger.set_logger(caller_class="coverage", output="both", out_file="coverage")
53
- assert logger.get_logger_file('not_exist') is None
@@ -1,45 +0,0 @@
1
- import os
2
-
3
- from rkt_lib_toolkit.rkt_tool_lib import Tool, Singleton
4
-
5
- obj = Tool()
6
-
7
-
8
- class FakeClass(metaclass=Singleton):
9
- def __init__(self):
10
- self.name = "singleton"
11
-
12
-
13
- class TestTool:
14
- def test_formatted_from_os(self):
15
- if os.name == "nt":
16
- excepted = obj.formatted_from_os(os.getcwd()).endswith("\\")
17
- else:
18
- excepted = obj.formatted_from_os(os.getcwd()).endswith("/")
19
- assert excepted
20
-
21
- def test_get_cwd(self):
22
- assert obj.get_cwd() == f"{os.getcwd()}\\" if os.name == "nt" else f"{os.getcwd()}/"
23
-
24
- def test_get_dir_flat(self):
25
- if os.name == "nt":
26
- excepted = f"{os.getcwd()}\\tests\\"
27
- else:
28
- excepted = f"{os.getcwd()}/tests/"
29
- assert obj.get_dir("tests") == excepted
30
-
31
- def test_get_dir_recursive(self):
32
- if os.name == "nt":
33
- excepted = f"{os.getcwd()}\\tests\\resources\\"
34
- else:
35
- excepted = f"{os.getcwd()}/tests/resources/"
36
-
37
- assert obj.get_dir("resources") == excepted
38
-
39
-
40
- class TestSingleton:
41
- def test_singleton(self):
42
- obj_1 = FakeClass()
43
- obj_2 = FakeClass()
44
- assert obj_1 == obj_2
45
-
File without changes